Merge branch 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 7 Apr 2014 22:20:10 +0000 (15:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 7 Apr 2014 22:20:10 +0000 (15:20 -0700)
Pull cgroup fixes from Tejun Heo:
 "Two patches to fix fallouts from the kernfs conversion:

  Li's patch to stop leaking cgroup_root refs across multiple mounts and
  the other fixes the 90s hang during shutdown caused by always using
  root's uid/gid for new cgroup dirs and files."

* 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cgroup: newly created dirs and files should be owned by the creator
  cgroup: fix top cgroup refcnt leak

2380 files changed:
CREDITS
Documentation/ABI/testing/sysfs-class-rc [new file with mode: 0644]
Documentation/ABI/testing/sysfs-fs-f2fs
Documentation/ABI/testing/sysfs-module
Documentation/DocBook/kernel-hacking.tmpl
Documentation/DocBook/media/dvb/demux.xml
Documentation/DocBook/media/dvb/dvbapi.xml
Documentation/DocBook/media/dvb/frontend.xml
Documentation/DocBook/media/v4l/common.xml
Documentation/DocBook/media/v4l/compat.xml
Documentation/DocBook/media/v4l/controls.xml
Documentation/DocBook/media/v4l/dev-osd.xml
Documentation/DocBook/media/v4l/dev-sdr.xml [new file with mode: 0644]
Documentation/DocBook/media/v4l/io.xml
Documentation/DocBook/media/v4l/pixfmt-nv16m.xml
Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
Documentation/DocBook/media/v4l/pixfmt-sdr-cu08.xml [new file with mode: 0644]
Documentation/DocBook/media/v4l/pixfmt-sdr-cu16le.xml [new file with mode: 0644]
Documentation/DocBook/media/v4l/pixfmt.xml
Documentation/DocBook/media/v4l/remote_controllers.xml
Documentation/DocBook/media/v4l/v4l2.xml
Documentation/DocBook/media/v4l/vidioc-enum-freq-bands.xml
Documentation/DocBook/media/v4l/vidioc-g-edid.xml [new file with mode: 0644]
Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
Documentation/DocBook/media/v4l/vidioc-querycap.xml
Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
Documentation/DocBook/media/v4l/vidioc-streamon.xml
Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml [deleted file]
Documentation/DocBook/media_api.tmpl
Documentation/arm/Marvell/README
Documentation/clk.txt
Documentation/cpu-hotplug.txt
Documentation/device-mapper/era.txt [new file with mode: 0644]
Documentation/devices.txt
Documentation/devicetree/bindings/arm/armada-375.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/armada-38x.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/atmel-adc.txt [deleted file]
Documentation/devicetree/bindings/arm/bcm/bcm21664.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/bcm/kona-resetmgr.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/bcm4708.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/cpus.txt
Documentation/devicetree/bindings/arm/gic.txt
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
Documentation/devicetree/bindings/arm/keystone/keystone.txt
Documentation/devicetree/bindings/arm/mrvl/feroceon.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mvebu-system-controller.txt
Documentation/devicetree/bindings/arm/omap/crossbar.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/omap/dmm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/omap/omap.txt
Documentation/devicetree/bindings/arm/pmu.txt
Documentation/devicetree/bindings/arm/rockchip/pmu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/samsung/pmu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/ata/exynos-sata-phy.txt [deleted file]
Documentation/devicetree/bindings/ata/exynos-sata.txt
Documentation/devicetree/bindings/bus/imx-weim.txt
Documentation/devicetree/bindings/clock/altr_socfpga.txt
Documentation/devicetree/bindings/clock/arm-integrator.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/axi-clkgen.txt
Documentation/devicetree/bindings/clock/clock-bindings.txt
Documentation/devicetree/bindings/clock/exynos4-clock.txt
Documentation/devicetree/bindings/clock/exynos5250-clock.txt
Documentation/devicetree/bindings/clock/exynos5420-clock.txt
Documentation/devicetree/bindings/clock/exynos5440-clock.txt
Documentation/devicetree/bindings/clock/hi3620-clock.txt
Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,quadfs.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/sunxi.txt
Documentation/devicetree/bindings/clock/zynq-7000.txt
Documentation/devicetree/bindings/i2c/trivial-devices.txt
Documentation/devicetree/bindings/iio/adc/at91_adc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iommu/arm,smmu.txt
Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/img-ir-rev1.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/samsung-fimc.txt
Documentation/devicetree/bindings/media/samsung-s5c73m3.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/samsung-s5k6a3.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/arizona.txt
Documentation/devicetree/bindings/mfd/bcm590xx.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/da9055.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/omap-usb-host.txt
Documentation/devicetree/bindings/mfd/omap-usb-tll.txt
Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/s2mps11.txt
Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/nand.txt
Documentation/devicetree/bindings/mtd/st-fsm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/socfpga-dwmac.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/stmmac.txt
Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
Documentation/devicetree/bindings/phy/samsung-phy.txt
Documentation/devicetree/bindings/power_supply/qnap-poweroff.txt
Documentation/devicetree/bindings/pwm/cirrus,clps711x-pwm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/reset/sirf,rstc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/reset/st,sti-powerdown.txt [new file with mode: 0644]
Documentation/devicetree/bindings/reset/st,sti-softreset.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/atmel-usart.txt
Documentation/devicetree/bindings/usb/atmel-usb.txt
Documentation/devicetree/bindings/usb/ehci-omap.txt
Documentation/devicetree/bindings/usb/ohci-omap3.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/video/analog-tv-connector.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/dvi-connector.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/fsl,imx-fb.txt
Documentation/devicetree/bindings/video/hdmi-connector.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/panel-dsi-cm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/sony,acx565akm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/ti,omap-dss.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/ti,omap2-dss.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/ti,omap3-dss.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/ti,omap4-dss.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/ti,tfp410.txt [new file with mode: 0644]
Documentation/devicetree/bindings/video/ti,tpd12s015.txt [new file with mode: 0644]
Documentation/devicetree/bindings/watchdog/marvel.txt
Documentation/dvb/get_dvb_firmware
Documentation/dvb/it9137.txt [deleted file]
Documentation/edac.txt
Documentation/filesystems/Locking
Documentation/filesystems/f2fs.txt
Documentation/filesystems/vfs.txt
Documentation/hwmon/it87
Documentation/module-signing.txt
Documentation/oops-tracing.txt
Documentation/sysctl/kernel.txt
Documentation/video4linux/CARDLIST.bttv
Documentation/video4linux/CARDLIST.cx23885
Documentation/video4linux/CARDLIST.em28xx
Documentation/video4linux/fimc.txt
Documentation/video4linux/gspca.txt
Documentation/video4linux/v4l2-framework.txt
Documentation/video4linux/v4l2-pci-skeleton.c [new file with mode: 0644]
MAINTAINERS
arch/Kconfig
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am3517-craneboard.dts [new file with mode: 0644]
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-gp-evm.dts [new file with mode: 0644]
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/armada-370-db.dts
arch/arm/boot/dts/armada-370-mirabox.dts
arch/arm/boot/dts/armada-370-rd.dts
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-370.dtsi
arch/arm/boot/dts/armada-375-db.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-375.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-380.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-385-db.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-385-rd.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-385.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-38x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-xp-axpwifiap.dts
arch/arm/boot/dts/armada-xp-db.dts
arch/arm/boot/dts/armada-xp-gp.dts
arch/arm/boot/dts/armada-xp-matrix.dts
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/at91-ariag25.dts
arch/arm/boot/dts/at91-cosino.dtsi
arch/arm/boot/dts/at91-cosino_mega2560.dts
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9261.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91sam9261ek.dts [new file with mode: 0644]
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9rl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91sam9rlek.dts [new file with mode: 0644]
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/atlas6.dtsi
arch/arm/boot/dts/bcm11351-brt.dts [deleted file]
arch/arm/boot/dts/bcm11351.dtsi
arch/arm/boot/dts/bcm21664-garnet.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm21664.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm28155-ap.dts
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/bcm4708-netgear-r6250.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm4708.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm5301x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm59056.dtsi [new file with mode: 0644]
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/efm32gg-dk3750.dts
arch/arm/boot/dts/efm32gg.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210-origen.dts
arch/arm/boot/dts/exynos4210-smdkv310.dts
arch/arm/boot/dts/exynos4210-trats.dts
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4212.dtsi
arch/arm/boot/dts/exynos4412-odroidx.dts
arch/arm/boot/dts/exynos4412-origen.dts
arch/arm/boot/dts/exynos4412-smdk4412.dts
arch/arm/boot/dts/exynos4412-tiny4412.dts
arch/arm/boot/dts/exynos4412-trats2.dts
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos4x12.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250-snow.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5420-arndale-octa.dts
arch/arm/boot/dts/exynos5420-smdk5420.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5440-sd5v1.dts
arch/arm/boot/dts/exynos5440-ssdk5440.dts
arch/arm/boot/dts/exynos5440.dtsi
arch/arm/boot/dts/imx23-evk.dts
arch/arm/boot/dts/imx23-olinuxino.dts
arch/arm/boot/dts/imx23-stmp378x_devb.dts
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts [new file with mode: 0644]
arch/arm/boot/dts/imx25-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx27-apf27.dts
arch/arm/boot/dts/imx27-apf27dev.dts
arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
arch/arm/boot/dts/imx27-phytec-phycard-s-som.dts [deleted file]
arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts
arch/arm/boot/dts/imx27-phytec-phycore-som.dts [deleted file]
arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx27-pinfunc.h [new file with mode: 0644]
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-cfa10037.dts
arch/arm/boot/dts/imx28-cfa10049.dts
arch/arm/boot/dts/imx28-cfa10057.dts
arch/arm/boot/dts/imx28-cfa10058.dts
arch/arm/boot/dts/imx28-duckbill.dts [new file with mode: 0644]
arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts [new file with mode: 0644]
arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts [new file with mode: 0644]
arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi [new file with mode: 0644]
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-tx28.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts [new file with mode: 0644]
arch/arm/boot/dts/imx35.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx50-evk.dts [new file with mode: 0644]
arch/arm/boot/dts/imx50-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx50.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx51-apf51.dts
arch/arm/boot/dts/imx51-apf51dev.dts
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts [new file with mode: 0644]
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-ard.dts
arch/arm/boot/dts/imx53-evk.dts [deleted file]
arch/arm/boot/dts/imx53-m53evk.dts
arch/arm/boot/dts/imx53-mba53.dts
arch/arm/boot/dts/imx53-qsb-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx53-qsb.dts
arch/arm/boot/dts/imx53-qsrb.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-smd.dts
arch/arm/boot/dts/imx53-tqma53.dtsi
arch/arm/boot/dts/imx53-tx53-x03x.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-tx53-x13x.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-tx53.dtsi
arch/arm/boot/dts/imx53-voipac-bsb.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw51xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw52xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw53xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw54xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-nitrogen6x.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-pinfunc.h
arch/arm/boot/dts/imx6dl-sabrelite.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl.dtsi
arch/arm/boot/dts/imx6q-arm2.dts
arch/arm/boot/dts/imx6q-cm-fx6.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gk802.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw51xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw52xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw53xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw5400-a.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw54xx.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-nitrogen6x.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-phytec-pbab01.dts
arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
arch/arm/boot/dts/imx6q-pinfunc.h
arch/arm/boot/dts/imx6q-sabrelite.dts
arch/arm/boot/dts/imx6q-sbc6x.dts
arch/arm/boot/dts/imx6q-udoo.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw51xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw54xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/imx6qdl-sabrelite.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/imx6qdl-wandboard.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6sl-evk.dts
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/integratorap.dts
arch/arm/boot/dts/integratorcp.dts
arch/arm/boot/dts/k2e-clocks.dtsi [new file with mode: 0644]
arch/arm/boot/dts/k2e-evm.dts [new file with mode: 0644]
arch/arm/boot/dts/k2e.dtsi [new file with mode: 0644]
arch/arm/boot/dts/k2hk-clocks.dtsi [new file with mode: 0644]
arch/arm/boot/dts/k2hk-evm.dts
arch/arm/boot/dts/k2hk.dtsi [new file with mode: 0644]
arch/arm/boot/dts/k2l-clocks.dtsi [new file with mode: 0644]
arch/arm/boot/dts/k2l-evm.dts [new file with mode: 0644]
arch/arm/boot/dts/k2l.dtsi [new file with mode: 0644]
arch/arm/boot/dts/keystone-clocks.dtsi
arch/arm/boot/dts/keystone.dtsi
arch/arm/boot/dts/kirkwood-b3.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds109.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds110jv10.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds111.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds112.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds209.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds210.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds212.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds212j.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds409.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds409slim.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds411.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds411j.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ds411slim.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
arch/arm/boot/dts/kirkwood-rd88f6192.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-rd88f6281-a0.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-rd88f6281-a1.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-rd88f6281.dtsi [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-rs212.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-rs409.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-rs411.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-synology.dtsi [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-t5325.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ts419-6281.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ts419-6282.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood-ts419.dtsi [new file with mode: 0644]
arch/arm/boot/dts/kirkwood.dtsi
arch/arm/boot/dts/marco.dtsi
arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap2.dtsi
arch/arm/boot/dts/omap2420.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-cm-t3517.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-cm-t3530.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-cm-t3730.dts
arch/arm/boot/dts/omap3-cm-t3x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-cm-t3x30.dtsi
arch/arm/boot/dts/omap3-devkit8000.dts
arch/arm/boot/dts/omap3-gta04.dts
arch/arm/boot/dts/omap3-igep.dtsi
arch/arm/boot/dts/omap3-igep0020.dts
arch/arm/boot/dts/omap3-lilly-a83x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-lilly-dbb056.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/omap3-overo-alto35-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-alto35.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-base.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-chestnut43.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-gallop43.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-palo43-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-palo43.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-storm-alto35.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-storm-gallop43.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-storm-palo43.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-storm-summit.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-storm-tobi.dts
arch/arm/boot/dts/omap3-overo-storm.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-summit-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-summit.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
arch/arm/boot/dts/omap3-overo-tobi.dts
arch/arm/boot/dts/omap3-overo.dtsi
arch/arm/boot/dts/omap3-sb-t35.dtsi
arch/arm/boot/dts/omap3-sbc-t3517.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-sbc-t3530.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-sbc-t3730.dts
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap3430-sdp.dts
arch/arm/boot/dts/omap3430es1-clocks.dtsi
arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi
arch/arm/boot/dts/omap36xx-clocks.dtsi
arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi
arch/arm/boot/dts/omap36xx.dtsi
arch/arm/boot/dts/omap3xxx-clocks.dtsi
arch/arm/boot/dts/omap4-duovero-parlor.dts [new file with mode: 0644]
arch/arm/boot/dts/omap4-duovero.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap4-panda-common.dtsi
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap443x.dtsi
arch/arm/boot/dts/omap4460.dtsi
arch/arm/boot/dts/omap5-uevm.dts
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/prima2.dtsi
arch/arm/boot/dts/qcom-msm8660-surf.dts
arch/arm/boot/dts/qcom-msm8660.dtsi [new file with mode: 0644]
arch/arm/boot/dts/qcom-msm8960-cdp.dts
arch/arm/boot/dts/qcom-msm8960.dtsi [new file with mode: 0644]
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/r7s72100-genmai-reference.dts
arch/arm/boot/dts/r7s72100.dtsi
arch/arm/boot/dts/r8a7778-bockw-reference.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-koelsch-reference.dts [deleted file]
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/rk3066a.dtsi
arch/arm/boot/dts/rk3188.dtsi
arch/arm/boot/dts/rk3xxx.dtsi
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d3xdm.dtsi
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria5.dtsi
arch/arm/boot/dts/socfpga_arria5_socdk.dts
arch/arm/boot/dts/socfpga_cyclone5.dtsi
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
arch/arm/boot/dts/socfpga_vt.dts
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href-ab8500.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-href-ab8505.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefprev60.dtsi
arch/arm/boot/dts/ste-hrefv60plus.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/ste-u300.dts
arch/arm/boot/dts/stih415-clock.dtsi
arch/arm/boot/dts/stih415-pinctrl.dtsi
arch/arm/boot/dts/stih415.dtsi
arch/arm/boot/dts/stih416-clock.dtsi
arch/arm/boot/dts/stih416-pinctrl.dtsi
arch/arm/boot/dts/stih416.dtsi
arch/arm/boot/dts/stih41x-b2000.dtsi
arch/arm/boot/dts/stih41x-b2020.dtsi
arch/arm/boot/dts/stih41x-b2020x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10-a1000.dts
arch/arm/boot/dts/sun4i-a10-cubieboard.dts
arch/arm/boot/dts/sun4i-a10-hackberry.dts
arch/arm/boot/dts/sun4i-a10-inet97fv2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10-pcduino.dts [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
arch/arm/boot/dts/sun5i-a10s.dtsi
arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
arch/arm/boot/dts/sun5i-a13-olinuxino.dts
arch/arm/boot/dts/sun5i-a13.dtsi
arch/arm/boot/dts/sun6i-a31-colombus.dts
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
arch/arm/boot/dts/sun7i-a20-cubietruck.dts
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sunxi-common-regulators.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra114-dalmore.dts
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124-venice2.dts
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/tegra20-seaboard.dts
arch/arm/boot/dts/tegra20-ventana.dts
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30-cardhu.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/tps65910.dtsi
arch/arm/boot/dts/twl4030.dtsi
arch/arm/boot/dts/vf610-cosmic.dts
arch/arm/boot/dts/vf610-twr.dts
arch/arm/boot/dts/vf610.dtsi
arch/arm/boot/dts/zynq-7000.dtsi
arch/arm/common/Makefile
arch/arm/common/scoop.c
arch/arm/common/timer-sp.c
arch/arm/configs/ape6evm_defconfig
arch/arm/configs/armadillo800eva_defconfig
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/at91sam9260_9g20_defconfig
arch/arm/configs/at91sam9rl_defconfig
arch/arm/configs/bcm2835_defconfig
arch/arm/configs/bcm_defconfig
arch/arm/configs/bockw_defconfig
arch/arm/configs/clps711x_defconfig
arch/arm/configs/da8xx_omapl_defconfig [deleted file]
arch/arm/configs/davinci_all_defconfig
arch/arm/configs/dove_defconfig
arch/arm/configs/exynos_defconfig
arch/arm/configs/genmai_defconfig
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/keystone_defconfig
arch/arm/configs/koelsch_defconfig
arch/arm/configs/kzm9d_defconfig [deleted file]
arch/arm/configs/kzm9g_defconfig
arch/arm/configs/lager_defconfig
arch/arm/configs/mackerel_defconfig
arch/arm/configs/marzen_defconfig
arch/arm/configs/multi_v5_defconfig [new file with mode: 0644]
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mvebu_defconfig [deleted file]
arch/arm/configs/mvebu_v5_defconfig [new file with mode: 0644]
arch/arm/configs/mvebu_v7_defconfig [new file with mode: 0644]
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/shmobile_defconfig [new file with mode: 0644]
arch/arm/configs/socfpga_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/firmware/Kconfig
arch/arm/firmware/trusted_foundations.c
arch/arm/include/asm/assembler.h
arch/arm/include/asm/atomic.h
arch/arm/include/asm/cmpxchg.h
arch/arm/include/asm/cputype.h
arch/arm/include/asm/firmware.h
arch/arm/include/asm/floppy.h
arch/arm/include/asm/futex.h
arch/arm/include/asm/hardware/cache-feroceon-l2.h [new file with mode: 0644]
arch/arm/include/asm/hw_breakpoint.h
arch/arm/include/asm/hwcap.h
arch/arm/include/asm/jump_label.h
arch/arm/include/asm/kprobes.h
arch/arm/include/asm/memory.h
arch/arm/include/asm/pgtable-2level.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/pmu.h
arch/arm/include/asm/probes.h [new file with mode: 0644]
arch/arm/include/asm/ptrace.h
arch/arm/include/asm/smp.h
arch/arm/include/asm/sync_bitops.h
arch/arm/include/asm/system.h [deleted file]
arch/arm/include/asm/thread_info.h
arch/arm/include/asm/timex.h
arch/arm/include/asm/trusted_foundations.h
arch/arm/include/asm/uaccess.h
arch/arm/include/asm/unistd.h
arch/arm/include/asm/uprobes.h [new file with mode: 0644]
arch/arm/include/debug/samsung.S
arch/arm/include/debug/tegra.S
arch/arm/include/debug/zynq.S
arch/arm/include/uapi/asm/hwcap.h
arch/arm/kernel/Makefile
arch/arm/kernel/armksyms.c
arch/arm/kernel/bios32.c
arch/arm/kernel/devtree.c
arch/arm/kernel/head.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/kprobes-arm.c
arch/arm/kernel/kprobes-common.c
arch/arm/kernel/kprobes-test-arm.c
arch/arm/kernel/kprobes-test.c
arch/arm/kernel/kprobes-thumb.c
arch/arm/kernel/kprobes.c
arch/arm/kernel/kprobes.h
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_cpu.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/probes-arm.c [new file with mode: 0644]
arch/arm/kernel/probes-arm.h [new file with mode: 0644]
arch/arm/kernel/probes-thumb.c [new file with mode: 0644]
arch/arm/kernel/probes-thumb.h [new file with mode: 0644]
arch/arm/kernel/probes.c [new file with mode: 0644]
arch/arm/kernel/probes.h [new file with mode: 0644]
arch/arm/kernel/process.c
arch/arm/kernel/setup.c
arch/arm/kernel/signal.c
arch/arm/kernel/sys_oabi-compat.c
arch/arm/kernel/unwind.c
arch/arm/kernel/uprobes-arm.c [new file with mode: 0644]
arch/arm/kernel/uprobes.c [new file with mode: 0644]
arch/arm/kernel/uprobes.h [new file with mode: 0644]
arch/arm/kvm/arm.c
arch/arm/lib/bitops.h
arch/arm/lib/copy_template.S
arch/arm/lib/csumpartialcopygeneric.S
arch/arm/lib/io-readsl.S
arch/arm/lib/io-writesl.S
arch/arm/lib/memmove.S
arch/arm/lib/uaccess.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Kconfig.non_dt
arch/arm/mach-at91/at91rm9200.c
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91rm9200_time.c
arch/arm/mach-at91/at91sam9260.c
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/at91sam9261.c
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9263.c
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam926x_time.c
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9n12.c
arch/arm/mach-at91/at91sam9rl.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/at91sam9x5.c
arch/arm/mach-at91/at91x40.c
arch/arm/mach-at91/at91x40_time.c
arch/arm/mach-at91/board-dt-sam9.c
arch/arm/mach-at91/board-gsia18s.c
arch/arm/mach-at91/board-pcontrol-g20.c
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-at91/include/mach/at91x40.h
arch/arm/mach-at91/include/mach/timex.h [deleted file]
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/sam9_smc.c
arch/arm/mach-at91/setup.c
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/bcm_5301x.c [new file with mode: 0644]
arch/arm/mach-bcm/board_bcm21664.c [new file with mode: 0644]
arch/arm/mach-bcm/board_bcm281xx.c
arch/arm/mach-bcm/board_bcm2835.c [new file with mode: 0644]
arch/arm/mach-bcm/kona.c
arch/arm/mach-bcm/kona.h
arch/arm/mach-bcm2835/Kconfig [deleted file]
arch/arm/mach-bcm2835/Makefile [deleted file]
arch/arm/mach-bcm2835/bcm2835.c [deleted file]
arch/arm/mach-berlin/Kconfig
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-clps711x/board-autcpu12.c
arch/arm/mach-clps711x/board-cdb89712.c
arch/arm/mach-clps711x/board-clep7312.c
arch/arm/mach-clps711x/board-edb7211.c
arch/arm/mach-clps711x/board-p720t.c
arch/arm/mach-clps711x/common.c
arch/arm/mach-clps711x/common.h
arch/arm/mach-clps711x/include/mach/clps711x.h
arch/arm/mach-clps711x/include/mach/hardware.h
arch/arm/mach-clps711x/include/mach/timex.h [deleted file]
arch/arm/mach-cns3xxx/Kconfig
arch/arm/mach-cns3xxx/cns3420vb.c
arch/arm/mach-cns3xxx/core.c
arch/arm/mach-cns3xxx/pcie.c
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/Makefile.boot
arch/arm/mach-davinci/aemif.c
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-mityomapl138.c
arch/arm/mach-davinci/board-tnetv107x-evm.c [deleted file]
arch/arm/mach-davinci/davinci.h
arch/arm/mach-davinci/devices-tnetv107x.c [deleted file]
arch/arm/mach-davinci/devices.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/include/mach/cputype.h
arch/arm/mach-davinci/include/mach/irqs.h
arch/arm/mach-davinci/include/mach/mux.h
arch/arm/mach-davinci/include/mach/psc.h
arch/arm/mach-davinci/include/mach/serial.h
arch/arm/mach-davinci/include/mach/timex.h [deleted file]
arch/arm/mach-davinci/include/mach/tnetv107x.h [deleted file]
arch/arm/mach-davinci/include/mach/uncompress.h
arch/arm/mach-davinci/tnetv107x.c [deleted file]
arch/arm/mach-dove/Kconfig
arch/arm/mach-dove/Makefile
arch/arm/mach-dove/board-dt.c [deleted file]
arch/arm/mach-dove/include/mach/bridge-regs.h
arch/arm/mach-dove/include/mach/timex.h [deleted file]
arch/arm/mach-ebsa110/core.c
arch/arm/mach-ebsa110/include/mach/timex.h [deleted file]
arch/arm/mach-efm32/include/mach/entry-macro.S [deleted file]
arch/arm/mach-efm32/include/mach/timex.h [deleted file]
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/include/mach/timex.h [deleted file]
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/common.c [deleted file]
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/cpuidle.c
arch/arm/mach-exynos/exynos.c [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/hardware.h [deleted file]
arch/arm/mach-exynos/include/mach/pm-core.h [deleted file]
arch/arm/mach-exynos/include/mach/timex.h [deleted file]
arch/arm/mach-exynos/include/mach/uncompress.h [deleted file]
arch/arm/mach-exynos/mach-exynos4-dt.c [deleted file]
arch/arm/mach-exynos/mach-exynos5-dt.c [deleted file]
arch/arm/mach-exynos/mfc.h [new file with mode: 0644]
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pm.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/regs-pmu.h
arch/arm/mach-exynos/sleep.S [new file with mode: 0644]
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-footbridge/Makefile
arch/arm/mach-footbridge/cats-hw.c
arch/arm/mach-footbridge/dc21285-timer.c
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-footbridge/include/mach/timex.h [deleted file]
arch/arm/mach-footbridge/isa-timer.c
arch/arm/mach-gemini/idle.c
arch/arm/mach-gemini/include/mach/timex.h [deleted file]
arch/arm/mach-highbank/Kconfig
arch/arm/mach-hisi/Kconfig
arch/arm/mach-hisi/Makefile
arch/arm/mach-hisi/hotplug.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/clk-imx21.c
arch/arm/mach-imx/clk-imx25.c
arch/arm/mach-imx/clk-imx27.c
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/clk-imx6sl.c
arch/arm/mach-imx/clk-vf610.c
arch/arm/mach-imx/common.h
arch/arm/mach-imx/cpuidle-imx6q.c
arch/arm/mach-imx/cpuidle-imx6sl.c [new file with mode: 0644]
arch/arm/mach-imx/cpuidle.h
arch/arm/mach-imx/devices-imx25.h
arch/arm/mach-imx/devices-imx51.h
arch/arm/mach-imx/devices/Kconfig
arch/arm/mach-imx/devices/Makefile
arch/arm/mach-imx/devices/devices-common.h
arch/arm/mach-imx/devices/platform-mxc_pwm.c [deleted file]
arch/arm/mach-imx/hardware.h
arch/arm/mach-imx/headsmp.S
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-imx6sl.c
arch/arm/mach-imx/mach-mx27ads.c
arch/arm/mach-imx/pm-imx6.c [new file with mode: 0644]
arch/arm/mach-imx/pm-imx6q.c [deleted file]
arch/arm/mach-imx/suspend-imx6.S [new file with mode: 0644]
arch/arm/mach-imx/time.c
arch/arm/mach-integrator/Kconfig
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/hardware.h [new file with mode: 0644]
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/impd1.h [new file with mode: 0644]
arch/arm/mach-integrator/include/mach/hardware.h [deleted file]
arch/arm/mach-integrator/include/mach/impd1.h [deleted file]
arch/arm/mach-integrator/include/mach/lm.h [deleted file]
arch/arm/mach-integrator/include/mach/platform.h [deleted file]
arch/arm/mach-integrator/include/mach/timex.h [deleted file]
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-integrator/leds.c
arch/arm/mach-integrator/lm.c
arch/arm/mach-integrator/lm.h [new file with mode: 0644]
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-iop13xx/include/mach/timex.h [deleted file]
arch/arm/mach-iop32x/include/mach/timex.h [deleted file]
arch/arm/mach-iop33x/include/mach/timex.h [deleted file]
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/dsmg600-setup.c
arch/arm/mach-ixp4xx/fsg-setup.c
arch/arm/mach-ixp4xx/goramo_mlr.c
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-ixp4xx/include/mach/timex.h [deleted file]
arch/arm/mach-ixp4xx/nas100d-setup.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/arm/mach-ixp4xx/omixp-setup.c
arch/arm/mach-keystone/Kconfig
arch/arm/mach-keystone/keystone.c
arch/arm/mach-kirkwood/Kconfig
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c [deleted file]
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-kirkwood/include/mach/bridge-regs.h
arch/arm/mach-kirkwood/include/mach/timex.h [deleted file]
arch/arm/mach-kirkwood/pm.c
arch/arm/mach-kirkwood/pm.h [new file with mode: 0644]
arch/arm/mach-ks8695/board-og.c
arch/arm/mach-ks8695/include/mach/timex.h [deleted file]
arch/arm/mach-ks8695/time.c
arch/arm/mach-lpc32xx/common.c
arch/arm/mach-lpc32xx/include/mach/timex.h [deleted file]
arch/arm/mach-lpc32xx/timer.c
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/devices.c
arch/arm/mach-mmp/include/mach/timex.h [deleted file]
arch/arm/mach-mmp/time.c
arch/arm/mach-mmp/ttc_dkb.c
arch/arm/mach-moxart/Kconfig
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/board-dt.c [deleted file]
arch/arm/mach-msm/common.h
arch/arm/mach-msm/dma.c
arch/arm/mach-msm/headsmp.S [deleted file]
arch/arm/mach-msm/hotplug.c [deleted file]
arch/arm/mach-msm/include/mach/timex.h [deleted file]
arch/arm/mach-msm/io.c
arch/arm/mach-msm/platsmp.c [deleted file]
arch/arm/mach-msm/scm-boot.c [deleted file]
arch/arm/mach-msm/scm-boot.h [deleted file]
arch/arm/mach-msm/scm.c [deleted file]
arch/arm/mach-msm/scm.h [deleted file]
arch/arm/mach-msm/timer.c [deleted file]
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
arch/arm/mach-mv78xx0/include/mach/timex.h [deleted file]
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/armada-370-xp.c [deleted file]
arch/arm/mach-mvebu/board-t5325.c [new file with mode: 0644]
arch/arm/mach-mvebu/board-v7.c [new file with mode: 0644]
arch/arm/mach-mvebu/board.h [new file with mode: 0644]
arch/arm/mach-mvebu/dove.c [new file with mode: 0644]
arch/arm/mach-mvebu/kirkwood-pm.c [new file with mode: 0644]
arch/arm/mach-mvebu/kirkwood-pm.h [new file with mode: 0644]
arch/arm/mach-mvebu/kirkwood.c [new file with mode: 0644]
arch/arm/mach-mvebu/kirkwood.h [new file with mode: 0644]
arch/arm/mach-mvebu/mvebu-soc-id.c
arch/arm/mach-mvebu/system-controller.c
arch/arm/mach-mxs/Kconfig
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-netx/include/mach/timex.h [deleted file]
arch/arm/mach-netx/time.c
arch/arm/mach-nomadik/Kconfig
arch/arm/mach-nspire/Kconfig
arch/arm/mach-nspire/nspire.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/dma.c
arch/arm/mach-omap1/include/mach/timex.h [deleted file]
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/am35xx-emac.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/cclock3xxx_data.c
arch/arm/mach-omap2/clkt_dpll.c
arch/arm/mach-omap2/clockdomains3xxx_data.c
arch/arm/mach-omap2/cminst44xx.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/display.h
arch/arm/mach-omap2/dma.c
arch/arm/mach-omap2/dpll3xxx.c
arch/arm/mach-omap2/dss-common.c
arch/arm/mach-omap2/gpmc-nand.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/include/mach/timex.h [deleted file]
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/mux.h
arch/arm/mach-omap2/omap-iommu.c
arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_43xx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_54xx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/prminst44xx.c
arch/arm/mach-omap2/soc.h
arch/arm/mach-omap2/timer.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/include/mach/bridge-regs.h
arch/arm/mach-orion5x/include/mach/timex.h [deleted file]
arch/arm/mach-picoxcell/Kconfig
arch/arm/mach-prima2/Kconfig
arch/arm/mach-prima2/common.c
arch/arm/mach-prima2/common.h
arch/arm/mach-prima2/l2x0.c
arch/arm/mach-prima2/platsmp.c
arch/arm/mach-prima2/rstc.c
arch/arm/mach-prima2/rtciobrg.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/colibri-evalboard.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/include/mach/timex.h [deleted file]
arch/arm/mach-qcom/Kconfig [new file with mode: 0644]
arch/arm/mach-qcom/Makefile [new file with mode: 0644]
arch/arm/mach-qcom/board.c [new file with mode: 0644]
arch/arm/mach-qcom/platsmp.c [new file with mode: 0644]
arch/arm/mach-qcom/scm-boot.c [new file with mode: 0644]
arch/arm/mach-qcom/scm-boot.h [new file with mode: 0644]
arch/arm/mach-qcom/scm.c [new file with mode: 0644]
arch/arm/mach-qcom/scm.h [new file with mode: 0644]
arch/arm/mach-realview/include/mach/memory.h
arch/arm/mach-realview/include/mach/timex.h [deleted file]
arch/arm/mach-rockchip/Kconfig
arch/arm/mach-rockchip/Makefile
arch/arm/mach-rockchip/core.h [new file with mode: 0644]
arch/arm/mach-rockchip/headsmp.S [new file with mode: 0644]
arch/arm/mach-rockchip/platsmp.c [new file with mode: 0644]
arch/arm/mach-rockchip/rockchip.c
arch/arm/mach-rpc/dma.c
arch/arm/mach-rpc/include/mach/timex.h [deleted file]
arch/arm/mach-rpc/time.c
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c24xx/clock-s3c2410.c
arch/arm/mach-s3c24xx/clock-s3c2412.c
arch/arm/mach-s3c24xx/clock-s3c2440.c
arch/arm/mach-s3c24xx/common.c
arch/arm/mach-s3c24xx/dma-s3c2410.c
arch/arm/mach-s3c24xx/dma-s3c2412.c
arch/arm/mach-s3c24xx/dma-s3c2440.c
arch/arm/mach-s3c24xx/dma-s3c2443.c
arch/arm/mach-s3c24xx/include/mach/debug-macro.S
arch/arm/mach-s3c24xx/include/mach/hardware.h
arch/arm/mach-s3c24xx/include/mach/rtc-core.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/tick.h [deleted file]
arch/arm/mach-s3c24xx/include/mach/timex.h [deleted file]
arch/arm/mach-s3c24xx/include/mach/uncompress.h [deleted file]
arch/arm/mach-s3c24xx/mach-amlm5900.c
arch/arm/mach-s3c24xx/mach-anubis.c
arch/arm/mach-s3c24xx/mach-at2440evb.c
arch/arm/mach-s3c24xx/mach-bast.c
arch/arm/mach-s3c24xx/mach-gta02.c
arch/arm/mach-s3c24xx/mach-h1940.c
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm/mach-s3c24xx/mach-mini2440.c
arch/arm/mach-s3c24xx/mach-n30.c
arch/arm/mach-s3c24xx/mach-nexcoder.c
arch/arm/mach-s3c24xx/mach-osiris.c
arch/arm/mach-s3c24xx/mach-otom.c
arch/arm/mach-s3c24xx/mach-qt2410.c
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c24xx/mach-rx3715.c
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
arch/arm/mach-s3c24xx/mach-smdk2410.c
arch/arm/mach-s3c24xx/mach-smdk2413.c
arch/arm/mach-s3c24xx/mach-smdk2416.c
arch/arm/mach-s3c24xx/mach-smdk2440.c
arch/arm/mach-s3c24xx/mach-smdk2443.c
arch/arm/mach-s3c24xx/mach-tct_hammer.c
arch/arm/mach-s3c24xx/mach-vr1000.c
arch/arm/mach-s3c24xx/mach-vstms.c
arch/arm/mach-s3c24xx/pm.c
arch/arm/mach-s3c24xx/s3c2410.c
arch/arm/mach-s3c24xx/s3c2412.c
arch/arm/mach-s3c24xx/s3c2416.c
arch/arm/mach-s3c24xx/s3c2443.c
arch/arm/mach-s3c24xx/s3c244x.c
arch/arm/mach-s3c24xx/sleep-s3c2410.S
arch/arm/mach-s3c24xx/sleep.S
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/common.c
arch/arm/mach-s3c64xx/include/mach/debug-macro.S
arch/arm/mach-s3c64xx/include/mach/pm-core.h
arch/arm/mach-s3c64xx/include/mach/tick.h [deleted file]
arch/arm/mach-s3c64xx/include/mach/timex.h [deleted file]
arch/arm/mach-s3c64xx/include/mach/uncompress.h [deleted file]
arch/arm/mach-s3c64xx/irq-pm.c
arch/arm/mach-s3c64xx/mach-anw6410.c
arch/arm/mach-s3c64xx/mach-crag6410-module.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-ncp.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/pm.c
arch/arm/mach-s3c64xx/s3c6400.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s5p64x0/common.c
arch/arm/mach-s5p64x0/common.h
arch/arm/mach-s5p64x0/include/mach/debug-macro.S
arch/arm/mach-s5p64x0/include/mach/pm-core.h
arch/arm/mach-s5p64x0/include/mach/timex.h [deleted file]
arch/arm/mach-s5p64x0/include/mach/uncompress.h [deleted file]
arch/arm/mach-s5p64x0/irq-pm.c
arch/arm/mach-s5p64x0/mach-smdk6440.c
arch/arm/mach-s5p64x0/mach-smdk6450.c
arch/arm/mach-s5p64x0/pm.c
arch/arm/mach-s5pc100/common.c
arch/arm/mach-s5pc100/include/mach/debug-macro.S
arch/arm/mach-s5pc100/include/mach/tick.h [deleted file]
arch/arm/mach-s5pc100/include/mach/timex.h [deleted file]
arch/arm/mach-s5pc100/include/mach/uncompress.h [deleted file]
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/common.c
arch/arm/mach-s5pv210/include/mach/debug-macro.S
arch/arm/mach-s5pv210/include/mach/timex.h [deleted file]
arch/arm/mach-s5pv210/include/mach/uncompress.h [deleted file]
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/mach-torbreck.c
arch/arm/mach-sa1100/collie.c
arch/arm/mach-sa1100/h3100.c
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/h3xxx.c
arch/arm/mach-sa1100/include/mach/collie.h
arch/arm/mach-sa1100/include/mach/h3xxx.h
arch/arm/mach-sa1100/include/mach/timex.h [deleted file]
arch/arm/mach-sa1100/time.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/board-armadillo800eva.c
arch/arm/mach-shmobile/board-bockw.c
arch/arm/mach-shmobile/board-genmai.c
arch/arm/mach-shmobile/board-koelsch-reference.c
arch/arm/mach-shmobile/board-koelsch.c
arch/arm/mach-shmobile/board-kzm9d-reference.c [deleted file]
arch/arm/mach-shmobile/board-lager-reference.c
arch/arm/mach-shmobile/board-lager.c
arch/arm/mach-shmobile/clock-r7s72100.c
arch/arm/mach-shmobile/clock-r8a7778.c
arch/arm/mach-shmobile/clock-r8a7779.c
arch/arm/mach-shmobile/clock-r8a7790.c
arch/arm/mach-shmobile/clock-r8a7791.c
arch/arm/mach-shmobile/include/mach/common.h
arch/arm/mach-shmobile/include/mach/head-kzm9g.txt [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/pm-rcar.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/r8a7779.h
arch/arm/mach-shmobile/include/mach/r8a7790.h
arch/arm/mach-shmobile/include/mach/timex.h [deleted file]
arch/arm/mach-shmobile/include/mach/zboot.h
arch/arm/mach-shmobile/include/mach/zboot_macros.h
arch/arm/mach-shmobile/platsmp-apmu.c
arch/arm/mach-shmobile/pm-r8a7779.c
arch/arm/mach-shmobile/pm-r8a7790.c [new file with mode: 0644]
arch/arm/mach-shmobile/pm-rcar.c [new file with mode: 0644]
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-shmobile/setup-r8a7790.c
arch/arm/mach-shmobile/setup-rcar-gen2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-r8a7790.c
arch/arm/mach-socfpga/Kconfig
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-spear/Kconfig
arch/arm/mach-spear/include/mach/timex.h [deleted file]
arch/arm/mach-spear/time.c
arch/arm/mach-sti/Kconfig
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-sunxi/Makefile
arch/arm/mach-sunxi/headsmp.S [deleted file]
arch/arm/mach-sunxi/platsmp.c
arch/arm/mach-sunxi/sunxi.c
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/cpuidle-tegra114.c
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/powergate.c
arch/arm/mach-tegra/tegra2_emc.c [deleted file]
arch/arm/mach-tegra/tegra2_emc.h [deleted file]
arch/arm/mach-u300/Kconfig
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/Makefile
arch/arm/mach-ux500/board-mop500-audio.c
arch/arm/mach-ux500/board-mop500-pins.c [deleted file]
arch/arm/mach-ux500/board-mop500.h
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/irqs-board-mop500.h [deleted file]
arch/arm/mach-ux500/irqs-db8500.h [deleted file]
arch/arm/mach-ux500/irqs.h [deleted file]
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/include/mach/timex.h [deleted file]
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-vexpress/Makefile
arch/arm/mach-virt/Kconfig [deleted file]
arch/arm/mach-virt/Makefile [deleted file]
arch/arm/mach-virt/virt.c [deleted file]
arch/arm/mach-vt8500/Kconfig
arch/arm/mach-w90x900/include/mach/timex.h [deleted file]
arch/arm/mach-w90x900/time.c
arch/arm/mach-zynq/Kconfig
arch/arm/mach-zynq/common.c
arch/arm/mach-zynq/common.h
arch/arm/mach-zynq/slcr.c
arch/arm/mm/Kconfig
arch/arm/mm/cache-feroceon-l2.c
arch/arm/mm/cache-tauros2.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-macros.S
arch/arm/mm/proc-v7-2level.S
arch/arm/mm/proc-v7.S
arch/arm/plat-iop/time.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/include/plat/timex.h [deleted file]
arch/arm/plat-orion/common.c
arch/arm/plat-orion/include/plat/cache-feroceon-l2.h [deleted file]
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/clock.c
arch/arm/plat-samsung/cpu.c
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/mfc.h
arch/arm/plat-samsung/include/plat/pm-common.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/pm.h
arch/arm/plat-samsung/include/plat/regs-serial.h [deleted file]
arch/arm/plat-samsung/include/plat/rtc-core.h [deleted file]
arch/arm/plat-samsung/include/plat/uncompress.h [deleted file]
arch/arm/plat-samsung/init.c
arch/arm/plat-samsung/pm-check.c
arch/arm/plat-samsung/pm-common.c [new file with mode: 0644]
arch/arm/plat-samsung/pm-debug.c [new file with mode: 0644]
arch/arm/plat-samsung/pm-gpio.c
arch/arm/plat-samsung/pm.c
arch/arm/plat-samsung/s5p-dev-mfc.c
arch/arm/plat-samsung/s5p-dev-uart.c
arch/arm/plat-samsung/s5p-irq-pm.c
arch/arm/plat-samsung/s5p-sleep.S
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/hw_breakpoint.c
arch/hexagon/Kconfig
arch/hexagon/include/asm/Kbuild
arch/hexagon/include/asm/atomic.h
arch/hexagon/include/asm/delay.h
arch/hexagon/include/asm/dma-mapping.h
arch/hexagon/include/asm/elf.h
arch/hexagon/include/asm/hexagon_vm.h
arch/hexagon/include/asm/io.h
arch/hexagon/include/asm/kgdb.h
arch/hexagon/include/asm/pgalloc.h
arch/hexagon/include/asm/smp.h
arch/hexagon/include/uapi/asm/registers.h
arch/hexagon/include/uapi/asm/setup.h
arch/hexagon/kernel/Makefile
arch/hexagon/kernel/hexagon_ksyms.c
arch/hexagon/kernel/kgdb.c
arch/hexagon/kernel/ptrace.c
arch/hexagon/kernel/reset.c
arch/hexagon/kernel/screen_info.c [new file with mode: 0644]
arch/hexagon/kernel/smp.c
arch/hexagon/kernel/time.c
arch/ia64/kernel/err_inject.c
arch/ia64/kernel/palinfo.c
arch/ia64/kernel/salinfo.c
arch/ia64/kernel/topology.c
arch/m68k/configs/m5208evb_defconfig
arch/m68k/configs/m5249evb_defconfig
arch/m68k/configs/m5272c3_defconfig
arch/m68k/configs/m5275evb_defconfig
arch/m68k/configs/m5307c3_defconfig
arch/m68k/configs/m5407c3_defconfig
arch/m68k/include/asm/io_no.h
arch/powerpc/include/asm/archrandom.h
arch/powerpc/kernel/sysfs.c
arch/s390/kernel/cache.c
arch/s390/kernel/smp.c
arch/sparc/kernel/sysfs.c
arch/tile/Kconfig
arch/tile/include/asm/perf_event.h [new file with mode: 0644]
arch/tile/include/asm/pmc.h [new file with mode: 0644]
arch/tile/kernel/Makefile
arch/tile/kernel/intvec_32.S
arch/tile/kernel/intvec_64.S
arch/tile/kernel/irq.c
arch/tile/kernel/messaging.c
arch/tile/kernel/pci.c
arch/tile/kernel/perf_event.c [new file with mode: 0644]
arch/tile/kernel/pmc.c [new file with mode: 0644]
arch/tile/kernel/time.c
arch/tile/kernel/vdso/Makefile
arch/x86/include/asm/archrandom.h
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/perf_event_amd_ibs.c
arch/x86/kernel/cpu/perf_event_amd_uncore.c
arch/x86/kernel/cpu/perf_event_intel_rapl.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/hpet.c
arch/x86/kernel/msr.c
arch/x86/kernel/vsyscall_64.c
arch/x86/kvm/x86.c
arch/x86/oprofile/nmi_int.c
arch/x86/pci/amd_bus.c
arch/x86/syscalls/syscall_64.tbl
drivers/amba/bus.c
drivers/amba/tegra-ahb.c
drivers/base/topology.c
drivers/block/rbd.c
drivers/bus/arm-cci.c
drivers/bus/imx-weim.c
drivers/bus/mvebu-mbus.c
drivers/char/hw_random/Kconfig
drivers/char/random.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/clk-programmable.c
drivers/clk/at91/clk-system.c
drivers/clk/bcm/Kconfig [new file with mode: 0644]
drivers/clk/bcm/Makefile [new file with mode: 0644]
drivers/clk/bcm/clk-bcm281xx.c [new file with mode: 0644]
drivers/clk/bcm/clk-kona-setup.c [new file with mode: 0644]
drivers/clk/bcm/clk-kona.c [new file with mode: 0644]
drivers/clk/bcm/clk-kona.h [new file with mode: 0644]
drivers/clk/clk-axi-clkgen.c
drivers/clk/clk-divider.c
drivers/clk/clk-moxart.c [new file with mode: 0644]
drivers/clk/clk-ppc-corenet.c
drivers/clk/clk-s2mps11.c
drivers/clk/clk.c
drivers/clk/clkdev.c
drivers/clk/hisilicon/Makefile
drivers/clk/hisilicon/clk-hi3620.c
drivers/clk/hisilicon/clk-hip04.c [new file with mode: 0644]
drivers/clk/hisilicon/clk.c
drivers/clk/hisilicon/clk.h
drivers/clk/mmp/clk-frac.c
drivers/clk/mvebu/Kconfig
drivers/clk/mvebu/Makefile
drivers/clk/mvebu/armada-375.c [new file with mode: 0644]
drivers/clk/mvebu/armada-38x.c [new file with mode: 0644]
drivers/clk/mvebu/clk-corediv.c
drivers/clk/samsung/clk-exynos-audss.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5440.c
drivers/clk/samsung/clk-s3c64xx.c
drivers/clk/samsung/clk.c
drivers/clk/samsung/clk.h
drivers/clk/shmobile/Makefile
drivers/clk/shmobile/clk-div6.c
drivers/clk/shmobile/clk-mstp.c
drivers/clk/shmobile/clk-rcar-gen2.c
drivers/clk/shmobile/clk-rz.c [new file with mode: 0644]
drivers/clk/sirf/clk-atlas6.c
drivers/clk/sirf/clk-common.c
drivers/clk/sirf/clk-prima2.c
drivers/clk/socfpga/Makefile
drivers/clk/socfpga/clk-gate.c [new file with mode: 0644]
drivers/clk/socfpga/clk-periph.c [new file with mode: 0644]
drivers/clk/socfpga/clk-pll.c [new file with mode: 0644]
drivers/clk/socfpga/clk.c
drivers/clk/socfpga/clk.h [new file with mode: 0644]
drivers/clk/st/Makefile [new file with mode: 0644]
drivers/clk/st/clkgen-fsyn.c [new file with mode: 0644]
drivers/clk/st/clkgen-mux.c [new file with mode: 0644]
drivers/clk/st/clkgen-pll.c [new file with mode: 0644]
drivers/clk/st/clkgen.h [new file with mode: 0644]
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/tegra/clk-periph.c
drivers/clk/ti/clk-33xx.c
drivers/clk/ti/clk-3xxx.c
drivers/clk/ti/clk-44xx.c
drivers/clk/ti/clk-54xx.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/divider.c
drivers/clk/ux500/u8500_of_clk.c
drivers/clk/versatile/clk-icst.c
drivers/clk/versatile/clk-icst.h
drivers/clk/versatile/clk-impd1.c
drivers/clk/versatile/clk-integrator.c
drivers/clk/versatile/clk-realview.c
drivers/clk/zynq/clkc.c
drivers/clk/zynq/pll.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/dummy_timer.c
drivers/clocksource/exynos_mct.c
drivers/clocksource/qcom-timer.c [new file with mode: 0644]
drivers/clocksource/timer-marco.c
drivers/clocksource/timer-prima2.c
drivers/clocksource/timer-u300.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/acpi-cpufreq.c
drivers/cpuidle/Kconfig.arm
drivers/dma/omap-dma.c
drivers/edac/edac_mc_sysfs.c
drivers/edac/ghes_edac.c
drivers/edac/i5400_edac.c
drivers/edac/i7300_edac.c
drivers/edac/i7core_edac.c
drivers/edac/sb_edac.c
drivers/gpio/Kconfig
drivers/gpio/gpio-ich.c
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/omapdrm/omap_connector.c
drivers/hid/hid-picolcd_cir.c
drivers/hwmon/adm1021.c
drivers/hwmon/asc7621.c
drivers/hwmon/atxp1.c
drivers/hwmon/coretemp.c
drivers/hwmon/f71805f.c
drivers/hwmon/it87.c
drivers/hwmon/lm63.c
drivers/hwmon/lm77.c
drivers/hwmon/lm80.c
drivers/hwmon/lm83.c
drivers/hwmon/lm87.c
drivers/hwmon/lm90.c
drivers/hwmon/lm92.c
drivers/hwmon/lm93.c
drivers/hwmon/max1619.c
drivers/hwmon/pc87360.c
drivers/hwmon/via-cputemp.c
drivers/hwmon/w83792d.c
drivers/hwmon/w83l785ts.c
drivers/idle/intel_idle.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/twl4030-madc.c [new file with mode: 0644]
drivers/input/misc/Kconfig
drivers/input/misc/ixp4xx-beeper.c
drivers/iommu/Kconfig
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_types.h
drivers/iommu/arm-smmu.c
drivers/iommu/dmar.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel_irq_remapping.c
drivers/iommu/iova.c
drivers/iommu/omap-iommu.c
drivers/iommu/omap-iommu.h
drivers/iommu/omap-iommu2.c
drivers/irqchip/Kconfig
drivers/irqchip/Makefile
drivers/irqchip/exynos-combiner.c
drivers/irqchip/irq-clps711x.c [new file with mode: 0644]
drivers/irqchip/irq-crossbar.c [new file with mode: 0644]
drivers/irqchip/irq-gic.c
drivers/irqchip/irq-mmp.c
drivers/irqchip/irq-vic.c
drivers/leds/Kconfig
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/dm-cache-block-types.h
drivers/md/dm-cache-metadata.c
drivers/md/dm-cache-metadata.h
drivers/md/dm-cache-target.c
drivers/md/dm-era-target.c [new file with mode: 0644]
drivers/md/dm-mpath.c
drivers/md/dm-table.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/persistent-data/dm-bitset.c
drivers/md/persistent-data/dm-bitset.h
drivers/md/persistent-data/dm-block-manager.c
drivers/md/persistent-data/dm-block-manager.h
drivers/md/persistent-data/dm-transaction-manager.c
drivers/md/persistent-data/dm-transaction-manager.h
drivers/media/common/siano/smsdvb-debugfs.c
drivers/media/common/siano/smsir.c
drivers/media/dvb-core/dvb-usb-ids.h
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-frontends/Kconfig
drivers/media/dvb-frontends/Makefile
drivers/media/dvb-frontends/af9033.c
drivers/media/dvb-frontends/af9033.h
drivers/media/dvb-frontends/drx39xyj/Kconfig [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/Makefile [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drx39xxj.h [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drx_dap_fasi.h [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drx_driver.h [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drx_driver_version.h [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drxj.c [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drxj.h [new file with mode: 0644]
drivers/media/dvb-frontends/drx39xyj/drxj_map.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxd_hard.c
drivers/media/dvb-frontends/ds3000.c
drivers/media/dvb-frontends/it913x-fe-priv.h [deleted file]
drivers/media/dvb-frontends/it913x-fe.c [deleted file]
drivers/media/dvb-frontends/it913x-fe.h [deleted file]
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/dvb-frontends/m88rs2000.c
drivers/media/dvb-frontends/mb86a20s.c
drivers/media/dvb-frontends/mb86a20s.h
drivers/media/dvb-frontends/rtl2832.c
drivers/media/dvb-frontends/rtl2832.h
drivers/media/dvb-frontends/rtl2832_priv.h
drivers/media/dvb-frontends/s921.c
drivers/media/dvb-frontends/s921.h
drivers/media/dvb-frontends/stb6100.c
drivers/media/dvb-frontends/stv0900_sw.c
drivers/media/dvb-frontends/tda10071.c
drivers/media/dvb-frontends/tda10071.h
drivers/media/i2c/Kconfig
drivers/media/i2c/Makefile
drivers/media/i2c/ad9389b.c
drivers/media/i2c/adv7180.c
drivers/media/i2c/adv7511.c
drivers/media/i2c/adv7604.c
drivers/media/i2c/adv7842.c
drivers/media/i2c/ir-kbd-i2c.c
drivers/media/i2c/lm3560.c
drivers/media/i2c/lm3646.c [new file with mode: 0644]
drivers/media/i2c/mt9p031.c
drivers/media/i2c/mt9t001.c
drivers/media/i2c/mt9v011.c
drivers/media/i2c/mt9v032.c
drivers/media/i2c/s5c73m3/s5c73m3-core.c
drivers/media/i2c/s5c73m3/s5c73m3-spi.c
drivers/media/i2c/s5c73m3/s5c73m3.h
drivers/media/i2c/s5k6a3.c [new file with mode: 0644]
drivers/media/i2c/sr030pc30.c
drivers/media/i2c/ths8200.c
drivers/media/i2c/tvp5150.c
drivers/media/parport/bw-qcam.c
drivers/media/pci/bt8xx/bttv-cards.c
drivers/media/pci/bt8xx/bttv-input.c
drivers/media/pci/bt8xx/bttv.h
drivers/media/pci/cx23885/cx23885-dvb.c
drivers/media/pci/cx23885/cx23885-input.c
drivers/media/pci/cx88/cx88-input.c
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/saa7134/saa7134-cards.c
drivers/media/pci/sta2x11/sta2x11_vip.c
drivers/media/pci/ttpci/av7110_hw.c
drivers/media/platform/Kconfig
drivers/media/platform/arv.c
drivers/media/platform/blackfin/bfin_capture.c
drivers/media/platform/coda.c
drivers/media/platform/davinci/vpbe_display.c
drivers/media/platform/davinci/vpif_capture.c
drivers/media/platform/davinci/vpif_display.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/exynos4-is/Kconfig
drivers/media/platform/exynos4-is/Makefile
drivers/media/platform/exynos4-is/fimc-capture.c
drivers/media/platform/exynos4-is/fimc-is-param.c
drivers/media/platform/exynos4-is/fimc-is-param.h
drivers/media/platform/exynos4-is/fimc-is-regs.c
drivers/media/platform/exynos4-is/fimc-is-regs.h
drivers/media/platform/exynos4-is/fimc-is-sensor.c
drivers/media/platform/exynos4-is/fimc-is-sensor.h
drivers/media/platform/exynos4-is/fimc-is.c
drivers/media/platform/exynos4-is/fimc-is.h
drivers/media/platform/exynos4-is/fimc-isp-video.c [new file with mode: 0644]
drivers/media/platform/exynos4-is/fimc-isp-video.h [new file with mode: 0644]
drivers/media/platform/exynos4-is/fimc-isp.c
drivers/media/platform/exynos4-is/fimc-isp.h
drivers/media/platform/exynos4-is/fimc-lite.c
drivers/media/platform/exynos4-is/fimc-m2m.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/exynos4-is/media-dev.h
drivers/media/platform/m2m-deinterlace.c
drivers/media/platform/marvell-ccic/mcam-core.c
drivers/media/platform/mem2mem_testdev.c
drivers/media/platform/mx2_emmaprp.c
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/omap/omap_vout_vrfb.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/omap3isp/isp.h
drivers/media/platform/omap3isp/ispccdc.c
drivers/media/platform/omap3isp/ispccdc.h
drivers/media/platform/omap3isp/ispccp2.c
drivers/media/platform/omap3isp/isphist.c
drivers/media/platform/omap3isp/isppreview.c
drivers/media/platform/omap3isp/ispqueue.c
drivers/media/platform/omap3isp/ispresizer.c
drivers/media/platform/omap3isp/ispresizer.h
drivers/media/platform/omap3isp/ispstat.c
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/s3c-camif/camif-capture.c
drivers/media/platform/s5p-g2d/g2d.c
drivers/media/platform/s5p-jpeg/jpeg-core.c
drivers/media/platform/s5p-jpeg/jpeg-regs.h
drivers/media/platform/s5p-mfc/regs-mfc-v6.h
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/s5p-mfc/s5p_mfc_common.h
drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
drivers/media/platform/s5p-tv/mixer_video.c
drivers/media/platform/soc_camera/atmel-isi.c
drivers/media/platform/soc_camera/mx2_camera.c
drivers/media/platform/soc_camera/mx3_camera.c
drivers/media/platform/soc_camera/rcar_vin.c
drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
drivers/media/platform/ti-vpe/vpe.c
drivers/media/platform/vivi.c
drivers/media/platform/vsp1/vsp1.h
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_entity.c
drivers/media/platform/vsp1/vsp1_entity.h
drivers/media/platform/vsp1/vsp1_lif.c
drivers/media/platform/vsp1/vsp1_lif.h
drivers/media/platform/vsp1/vsp1_rpf.c
drivers/media/platform/vsp1/vsp1_rwpf.c
drivers/media/platform/vsp1/vsp1_rwpf.h
drivers/media/platform/vsp1/vsp1_uds.c
drivers/media/platform/vsp1/vsp1_uds.h
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/vsp1/vsp1_video.h
drivers/media/platform/vsp1/vsp1_wpf.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-keene.c
drivers/media/radio/si4713/Kconfig
drivers/media/radio/si4713/radio-usb-si4713.c
drivers/media/rc/Kconfig
drivers/media/rc/Makefile
drivers/media/rc/ati_remote.c
drivers/media/rc/ene_ir.c
drivers/media/rc/fintek-cir.c
drivers/media/rc/gpio-ir-recv.c
drivers/media/rc/iguanair.c
drivers/media/rc/img-ir/Kconfig [new file with mode: 0644]
drivers/media/rc/img-ir/Makefile [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-core.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-hw.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-hw.h [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-jvc.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-nec.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-raw.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-raw.h [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-sanyo.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-sharp.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir-sony.c [new file with mode: 0644]
drivers/media/rc/img-ir/img-ir.h [new file with mode: 0644]
drivers/media/rc/imon.c
drivers/media/rc/ir-jvc-decoder.c
drivers/media/rc/ir-lirc-codec.c
drivers/media/rc/ir-mce_kbd-decoder.c
drivers/media/rc/ir-nec-decoder.c
drivers/media/rc/ir-raw.c
drivers/media/rc/ir-rc5-decoder.c
drivers/media/rc/ir-rc5-sz-decoder.c
drivers/media/rc/ir-rc6-decoder.c
drivers/media/rc/ir-sanyo-decoder.c
drivers/media/rc/ir-sharp-decoder.c [new file with mode: 0644]
drivers/media/rc/ir-sony-decoder.c
drivers/media/rc/ite-cir.c
drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
drivers/media/rc/keymaps/rc-apac-viewcomp.c
drivers/media/rc/keymaps/rc-asus-pc39.c
drivers/media/rc/keymaps/rc-asus-ps3-100.c
drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
drivers/media/rc/keymaps/rc-avermedia-a16d.c
drivers/media/rc/keymaps/rc-avermedia-cardbus.c
drivers/media/rc/keymaps/rc-avermedia-dvbt.c
drivers/media/rc/keymaps/rc-avermedia-m135a.c
drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
drivers/media/rc/keymaps/rc-avermedia.c
drivers/media/rc/keymaps/rc-avertv-303.c
drivers/media/rc/keymaps/rc-behold-columbus.c
drivers/media/rc/keymaps/rc-behold.c
drivers/media/rc/keymaps/rc-budget-ci-old.c
drivers/media/rc/keymaps/rc-cinergy-1400.c
drivers/media/rc/keymaps/rc-cinergy.c
drivers/media/rc/keymaps/rc-dib0700-nec.c
drivers/media/rc/keymaps/rc-dib0700-rc5.c
drivers/media/rc/keymaps/rc-dm1105-nec.c
drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
drivers/media/rc/keymaps/rc-em-terratec.c
drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
drivers/media/rc/keymaps/rc-encore-enltv.c
drivers/media/rc/keymaps/rc-encore-enltv2.c
drivers/media/rc/keymaps/rc-evga-indtube.c
drivers/media/rc/keymaps/rc-eztv.c
drivers/media/rc/keymaps/rc-flydvb.c
drivers/media/rc/keymaps/rc-flyvideo.c
drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
drivers/media/rc/keymaps/rc-gadmei-rm008z.c
drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
drivers/media/rc/keymaps/rc-gotview7135.c
drivers/media/rc/keymaps/rc-hauppauge.c
drivers/media/rc/keymaps/rc-iodata-bctv7e.c
drivers/media/rc/keymaps/rc-kaiomy.c
drivers/media/rc/keymaps/rc-kworld-315u.c
drivers/media/rc/keymaps/rc-kworld-pc150u.c
drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
drivers/media/rc/keymaps/rc-manli.c
drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
drivers/media/rc/keymaps/rc-msi-tvanywhere.c
drivers/media/rc/keymaps/rc-nebula.c
drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
drivers/media/rc/keymaps/rc-norwood.c
drivers/media/rc/keymaps/rc-npgtech.c
drivers/media/rc/keymaps/rc-pctv-sedna.c
drivers/media/rc/keymaps/rc-pinnacle-color.c
drivers/media/rc/keymaps/rc-pinnacle-grey.c
drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
drivers/media/rc/keymaps/rc-pixelview-002t.c
drivers/media/rc/keymaps/rc-pixelview-mk12.c
drivers/media/rc/keymaps/rc-pixelview-new.c
drivers/media/rc/keymaps/rc-pixelview.c
drivers/media/rc/keymaps/rc-powercolor-real-angel.c
drivers/media/rc/keymaps/rc-proteus-2309.c
drivers/media/rc/keymaps/rc-purpletv.c
drivers/media/rc/keymaps/rc-pv951.c
drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
drivers/media/rc/keymaps/rc-tbs-nec.c
drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
drivers/media/rc/keymaps/rc-tevii-nec.c
drivers/media/rc/keymaps/rc-tivo.c
drivers/media/rc/keymaps/rc-tt-1500.c
drivers/media/rc/keymaps/rc-videomate-s350.c
drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
drivers/media/rc/keymaps/rc-winfast.c
drivers/media/rc/mceusb.c
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/nuvoton-cir.h
drivers/media/rc/rc-core-priv.h
drivers/media/rc/rc-loopback.c
drivers/media/rc/rc-main.c
drivers/media/rc/redrat3.c
drivers/media/rc/st_rc.c
drivers/media/rc/streamzap.c
drivers/media/rc/ttusbir.c
drivers/media/rc/winbond-cir.c
drivers/media/tuners/Kconfig
drivers/media/tuners/e4000.c
drivers/media/tuners/e4000.h
drivers/media/tuners/e4000_priv.h
drivers/media/tuners/mt2063.c
drivers/media/tuners/r820t.c
drivers/media/tuners/tda18212.c
drivers/media/tuners/tda18212.h
drivers/media/tuners/tuner-xc2028.c
drivers/media/usb/au0828/au0828-cards.c
drivers/media/usb/cx231xx/cx231xx-input.c
drivers/media/usb/dvb-usb-v2/Kconfig
drivers/media/usb/dvb-usb-v2/Makefile
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/af9035.h
drivers/media/usb/dvb-usb-v2/az6007.c
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
drivers/media/usb/dvb-usb-v2/it913x.c [deleted file]
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.h
drivers/media/usb/dvb-usb/dvb-usb-remote.c
drivers/media/usb/em28xx/Kconfig
drivers/media/usb/em28xx/em28xx-audio.c
drivers/media/usb/em28xx/em28xx-camera.c
drivers/media/usb/em28xx/em28xx-cards.c
drivers/media/usb/em28xx/em28xx-core.c
drivers/media/usb/em28xx/em28xx-dvb.c
drivers/media/usb/em28xx/em28xx-i2c.c
drivers/media/usb/em28xx/em28xx-input.c
drivers/media/usb/em28xx/em28xx-video.c
drivers/media/usb/em28xx/em28xx.h
drivers/media/usb/gspca/kinect.c
drivers/media/usb/gspca/sn9c20x.c
drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
drivers/media/usb/gspca/topro.c
drivers/media/usb/pwc/pwc-if.c
drivers/media/usb/s2255/Kconfig
drivers/media/usb/s2255/s2255drv.c
drivers/media/usb/siano/smsusb.c
drivers/media/usb/stk1160/stk1160-v4l.c
drivers/media/usb/tm6000/tm6000-alsa.c
drivers/media/usb/tm6000/tm6000-dvb.c
drivers/media/usb/tm6000/tm6000-input.c
drivers/media/usb/tm6000/tm6000-stds.c
drivers/media/usb/usbtv/Makefile
drivers/media/usb/usbtv/usbtv-core.c [new file with mode: 0644]
drivers/media/usb/usbtv/usbtv-video.c [new file with mode: 0644]
drivers/media/usb/usbtv/usbtv.c [deleted file]
drivers/media/usb/usbtv/usbtv.h [new file with mode: 0644]
drivers/media/usb/usbvision/usbvision.h
drivers/media/usb/uvc/uvc_driver.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/usb/uvc/uvc_v4l2.c
drivers/media/usb/uvc/uvc_video.c
drivers/media/usb/uvc/uvcvideo.h
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-dv-timings.c
drivers/media/v4l2-core/v4l2-ioctl.c
drivers/media/v4l2-core/v4l2-subdev.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/mfd/88pm800.c
drivers/mfd/88pm860x-core.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab8500-core.c
drivers/mfd/adp5520.c
drivers/mfd/as3722.c
drivers/mfd/bcm590xx.c [new file with mode: 0644]
drivers/mfd/cs5535-mfd.c
drivers/mfd/da9052-core.c
drivers/mfd/da9052-i2c.c
drivers/mfd/da9052-spi.c
drivers/mfd/da9055-i2c.c
drivers/mfd/da9063-core.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/janz-cmodio.c
drivers/mfd/kempld-core.c
drivers/mfd/lpc_ich.c
drivers/mfd/lpc_sch.c
drivers/mfd/max14577.c
drivers/mfd/max77686.c
drivers/mfd/max77693.c
drivers/mfd/max8925-i2c.c
drivers/mfd/max8997.c
drivers/mfd/max8998.c
drivers/mfd/mc13xxx-spi.c
drivers/mfd/mcp-sa11x0.c
drivers/mfd/omap-usb-host.c
drivers/mfd/omap-usb-tll.c
drivers/mfd/pcf50633-adc.c
drivers/mfd/pm8921-core.c
drivers/mfd/pm8xxx-irq.c [deleted file]
drivers/mfd/rc5t583-irq.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/retu-mfd.c
drivers/mfd/rtsx_usb.c [new file with mode: 0644]
drivers/mfd/sec-core.c
drivers/mfd/smsc-ece1099.c
drivers/mfd/stmpe.c
drivers/mfd/stw481x.c
drivers/mfd/syscon.c
drivers/mfd/tc3589x.c
drivers/mfd/ti-ssp.c [deleted file]
drivers/mfd/ti_am335x_tscadc.c
drivers/mfd/timberdale.c
drivers/mfd/tps65218.c [new file with mode: 0644]
drivers/mfd/tps65910.c
drivers/mfd/tps65912-core.c
drivers/mfd/tps65912-irq.c
drivers/mfd/twl-core.c
drivers/mfd/twl4030-irq.c
drivers/mfd/twl4030-madc.c [deleted file]
drivers/mfd/twl6030-irq.c
drivers/mfd/twl6040.c
drivers/mfd/ucb1x00-core.c
drivers/mfd/vexpress-config.c
drivers/mfd/vexpress-sysreg.c
drivers/mfd/wm5102-tables.c
drivers/mfd/wm5110-tables.c
drivers/mfd/wm8350-core.c
drivers/mfd/wm8350-irq.c
drivers/mfd/wm8400-core.c
drivers/mmc/host/mmci.h
drivers/mtd/Kconfig
drivers/mtd/bcm47xxpart.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/cfi_cmdset_0020.c
drivers/mtd/chips/cfi_probe.c
drivers/mtd/chips/cfi_util.c
drivers/mtd/chips/gen_probe.c
drivers/mtd/devices/Kconfig
drivers/mtd/devices/Makefile
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/elm.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/devices/phram.c
drivers/mtd/devices/pmc551.c
drivers/mtd/devices/serial_flash_cmds.h [new file with mode: 0644]
drivers/mtd/devices/spear_smi.c
drivers/mtd/devices/sst25l.c
drivers/mtd/devices/st_spi_fsm.c [new file with mode: 0644]
drivers/mtd/inftlmount.c
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/lpddr/qinfo_probe.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/lantiq-flash.c
drivers/mtd/maps/latch-addr-flash.c
drivers/mtd/maps/pci.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/rbtx4939-flash.c
drivers/mtd/maps/scb2_flash.c
drivers/mtd/maps/sun_uflash.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/ams-delta.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali_dt.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/gpio.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nuc900_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/pasemi_nand.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/onenand/generic.c
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/samsung.c
drivers/mtd/rfd_ftl.c
drivers/mtd/sm_ftl.c
drivers/mtd/tests/mtd_test.c
drivers/mtd/ubi/Kconfig
drivers/mtd/ubi/Makefile
drivers/mtd/ubi/block.c [new file with mode: 0644]
drivers/mtd/ubi/build.c
drivers/mtd/ubi/cdev.c
drivers/mtd/ubi/ubi.h
drivers/of/base.c
drivers/of/of_mtd.c
drivers/oprofile/nmi_timer_int.c
drivers/pci/slot.c
drivers/phy/Kconfig
drivers/power/reset/Kconfig
drivers/power/reset/qnap-poweroff.c
drivers/powercap/intel_rapl.c
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/pwm-atmel.c
drivers/pwm/pwm-clps711x.c [new file with mode: 0644]
drivers/pwm/pwm-fsl-ftm.c [new file with mode: 0644]
drivers/pwm/pwm-lpss.c [new file with mode: 0644]
drivers/pwm/pwm-pxa.c
drivers/pwm/pwm-samsung.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/core.c
drivers/reset/sti/Kconfig [new file with mode: 0644]
drivers/reset/sti/Makefile [new file with mode: 0644]
drivers/reset/sti/reset-stih415.c [new file with mode: 0644]
drivers/reset/sti/reset-stih416.c [new file with mode: 0644]
drivers/reset/sti/reset-syscfg.c [new file with mode: 0644]
drivers/reset/sti/reset-syscfg.h [new file with mode: 0644]
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-isl12057.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-pxa.c
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/bnx2i/bnx2i_init.c
drivers/scsi/fcoe/fcoe.c
drivers/sh/clk/cpg.c
drivers/sh/intc/Kconfig
drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
drivers/staging/lustre/lustre/lvfs/lvfs_linux.c
drivers/staging/media/Kconfig
drivers/staging/media/Makefile
drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c
drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
drivers/staging/media/davinci_vpfe/vpfe_video.c
drivers/staging/media/dt3155v4l/dt3155v4l.c
drivers/staging/media/go7007/go7007-v4l2.c
drivers/staging/media/msi3101/Kconfig
drivers/staging/media/msi3101/Makefile
drivers/staging/media/msi3101/msi001.c [new file with mode: 0644]
drivers/staging/media/msi3101/sdr-msi3101.c
drivers/staging/media/omap4iss/iss_video.c
drivers/staging/media/rtl2832u_sdr/Kconfig [new file with mode: 0644]
drivers/staging/media/rtl2832u_sdr/Makefile [new file with mode: 0644]
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c [new file with mode: 0644]
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h [new file with mode: 0644]
drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
drivers/staging/media/solo6x10/solo6x10-v4l2.c
drivers/staging/speakup/kobjects.c
drivers/staging/speakup/speakup.h
drivers/staging/speakup/speakup_acntpc.c
drivers/staging/speakup/speakup_acntsa.c
drivers/staging/speakup/speakup_apollo.c
drivers/staging/speakup/speakup_audptr.c
drivers/staging/speakup/speakup_bns.c
drivers/staging/speakup/speakup_decext.c
drivers/staging/speakup/speakup_decpc.c
drivers/staging/speakup/speakup_dectlk.c
drivers/staging/speakup/speakup_dtlk.c
drivers/staging/speakup/speakup_dummy.c
drivers/staging/speakup/speakup_keypc.c
drivers/staging/speakup/speakup_ltlk.c
drivers/staging/speakup/speakup_soft.c
drivers/staging/speakup/speakup_spkout.c
drivers/staging/speakup/speakup_txprt.c
drivers/thermal/Kconfig
drivers/thermal/x86_pkg_temp_thermal.c
drivers/tty/serial/Kconfig
drivers/tty/serial/atmel_serial.c
drivers/usb/gadget/lpc32xx_udc.c
drivers/video/Kconfig
drivers/video/atmel_lcdfb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/mach64_accel.c
drivers/video/aty/mach64_cursor.c
drivers/video/cfbcopyarea.c
drivers/video/console/fbcon.c
drivers/video/da8xx-fb.c
drivers/video/efifb.c
drivers/video/exynos/Kconfig
drivers/video/exynos/s6e8ax0.c
drivers/video/fbmem.c
drivers/video/imxfb.c
drivers/video/matrox/matroxfb_accel.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_base.h
drivers/video/omap2/displays-new/connector-analog-tv.c
drivers/video/omap2/displays-new/connector-dvi.c
drivers/video/omap2/displays-new/connector-hdmi.c
drivers/video/omap2/displays-new/encoder-tfp410.c
drivers/video/omap2/displays-new/encoder-tpd12s015.c
drivers/video/omap2/displays-new/panel-dsi-cm.c
drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
drivers/video/omap2/displays-new/panel-sony-acx565akm.c
drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
drivers/video/omap2/dss/Makefile
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/display-sysfs.c
drivers/video/omap2/dss/display.c
drivers/video/omap2/dss/dpi.c
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dss-of.c [new file with mode: 0644]
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/dss.h
drivers/video/omap2/dss/hdmi4.c
drivers/video/omap2/dss/hdmi_common.c
drivers/video/omap2/dss/hdmi_wp.c
drivers/video/omap2/dss/sdi.c
drivers/video/omap2/dss/venc.c
drivers/video/omap2/dss/venc_panel.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/pxa3xx-gcu.c
drivers/video/sis/init.c
drivers/video/tgafb.c
drivers/video/uvesafb.c
drivers/video/vesafb.c
drivers/video/xilinxfb.c
drivers/watchdog/Kconfig
drivers/watchdog/iTCO_wdt.c
drivers/watchdog/octeon-wdt-main.c
drivers/watchdog/orion_wdt.c
drivers/xen/balloon.c
fs/adfs/super.c
fs/affs/super.c
fs/befs/linuxvfs.c
fs/btrfs/async-thread.c
fs/btrfs/async-thread.h
fs/btrfs/backref.c
fs/btrfs/btrfs_inode.h
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-ref.c
fs/btrfs/dev-replace.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/qgroup.c
fs/btrfs/raid56.c
fs/btrfs/reada.c
fs/btrfs/relocation.c
fs/btrfs/root-tree.c
fs/btrfs/scrub.c
fs/btrfs/send.c
fs/btrfs/super.c
fs/btrfs/sysfs.c
fs/btrfs/sysfs.h
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/tree-log.h
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/cachefiles/namei.c
fs/ceph/cache.c
fs/ceph/cache.h
fs/ceph/caps.c
fs/ceph/debugfs.c
fs/ceph/dir.c
fs/ceph/export.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/ioctl.c
fs/ceph/locks.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/strings.c
fs/ceph/super.c
fs/ceph/super.h
fs/ceph/xattr.c
fs/cifs/cifsfs.c
fs/coda/inode.c
fs/compat.c
fs/cramfs/inode.c
fs/dcache.c
fs/debugfs/inode.c
fs/devpts/inode.c
fs/direct-io.c
fs/dlm/ast.c
fs/dlm/dir.c
fs/dlm/dlm_internal.h
fs/dlm/lock.c
fs/dlm/lockspace.c
fs/dlm/member.c
fs/dlm/recover.c
fs/dlm/recoverd.c
fs/ecryptfs/inode.c
fs/efs/super.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/ext4.h
fs/ext4/ext4_jbd2.c
fs/ext4/extents.c
fs/ext4/extents_status.c
fs/ext4/extents_status.h
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/mballoc.h
fs/ext4/move_extent.c
fs/ext4/namei.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/ext4/xattr.h
fs/f2fs/acl.c
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/debug.c
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/gc.c
fs/f2fs/inline.c
fs/f2fs/inode.c
fs/f2fs/namei.c
fs/f2fs/node.c
fs/f2fs/node.h
fs/f2fs/recovery.c
fs/f2fs/segment.c
fs/f2fs/segment.h
fs/f2fs/super.c
fs/f2fs/xattr.c
fs/fat/inode.c
fs/fcntl.c
fs/file_table.c
fs/freevxfs/vxfs_super.c
fs/fs-writeback.c
fs/fuse/cuse.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/gfs2/acl.c
fs/gfs2/acl.h
fs/gfs2/aops.c
fs/gfs2/bmap.c
fs/gfs2/bmap.h
fs/gfs2/dir.c
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/lock_dlm.c
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/lops.h
fs/gfs2/main.c
fs/gfs2/meta_io.c
fs/gfs2/meta_io.h
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/recovery.c
fs/gfs2/recovery.h
fs/gfs2/rgrp.c
fs/gfs2/super.c
fs/gfs2/sys.c
fs/gfs2/trans.c
fs/gfs2/util.c
fs/gfs2/util.h
fs/hfs/super.c
fs/hfsplus/super.c
fs/hpfs/super.c
fs/inode.c
fs/isofs/inode.c
fs/jbd2/commit.c
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/jffs2/compr_rtime.c
fs/jffs2/fs.c
fs/jffs2/nodelist.h
fs/jffs2/nodemgmt.c
fs/jffs2/super.c
fs/jfs/super.c
fs/locks.c
fs/mbcache.c
fs/minix/inode.c
fs/namei.c
fs/ncpfs/inode.c
fs/nfs/callback_proc.c
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs3proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
fs/nfs/pnfs.c
fs/nfs/proc.c
fs/nfs/super.c
fs/nfs/unlink.c
fs/nfsd/vfs.c
fs/nilfs2/super.c
fs/ntfs/super.c
fs/ocfs2/cluster/sys.c
fs/ocfs2/stackglue.c
fs/ocfs2/super.c
fs/open.c
fs/openpromfs/inode.c
fs/posix_acl.c
fs/proc/root.c
fs/pstore/inode.c
fs/pstore/platform.c
fs/pstore/ram.c
fs/pstore/ram_core.c
fs/qnx4/inode.c
fs/qnx6/inode.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/squashfs/super.c
fs/super.c
fs/sysv/inode.c
fs/ubifs/super.c
fs/udf/super.c
fs/ufs/super.c
fs/xfs/kmem.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_ag.h
fs/xfs/xfs_alloc.c
fs/xfs/xfs_alloc_btree.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_attr_remote.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.h
fs/xfs/xfs_bmap_btree.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_bmap_util.h
fs/xfs/xfs_btree.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_da_btree.c
fs/xfs/xfs_dinode.h
fs/xfs/xfs_dir2.c
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_data.c
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_dir2_node.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_dquot_buf.c
fs/xfs/xfs_error.c
fs/xfs/xfs_error.h
fs/xfs/xfs_file.c
fs/xfs/xfs_format.h
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc_btree.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_buf.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_linux.h
fs/xfs/xfs_log.h
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_sb.c
fs/xfs/xfs_sb.h
fs/xfs/xfs_shared.h
fs/xfs/xfs_super.c
fs/xfs/xfs_symlink.c
fs/xfs/xfs_symlink_remote.c
fs/xfs/xfs_trace.h
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans_buf.c
fs/xfs/xfs_trans_resv.c
fs/xfs/xfs_trans_resv.h
include/acpi/actbl2.h
include/asm-generic/vmlinux.lds.h
include/dt-bindings/clk/exynos-audss-clk.h [deleted file]
include/dt-bindings/clock/bcm281xx.h [new file with mode: 0644]
include/dt-bindings/clock/exynos-audss-clk.h [new file with mode: 0644]
include/dt-bindings/clock/hi3620-clock.h
include/dt-bindings/clock/hip04-clock.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7790-clock.h
include/dt-bindings/pinctrl/am43xx.h
include/dt-bindings/reset-controller/stih415-resets.h [new file with mode: 0644]
include/dt-bindings/reset-controller/stih416-resets.h [new file with mode: 0644]
include/linux/ceph/ceph_features.h
include/linux/ceph/ceph_fs.h
include/linux/ceph/osd_client.h
include/linux/ceph/osdmap.h
include/linux/ceph/rados.h
include/linux/clk-provider.h
include/linux/clk.h
include/linux/clk/zynq.h
include/linux/cpu.h
include/linux/crush/crush.h
include/linux/dcache.h
include/linux/device-mapper.h
include/linux/dmar.h
include/linux/f2fs_fs.h
include/linux/fs.h
include/linux/i2c/twl.h
include/linux/i2c/twl4030-madc.h
include/linux/intel-iommu.h
include/linux/iova.h
include/linux/irqchip/arm-gic.h
include/linux/irqchip/arm-vic.h
include/linux/irqchip/irq-crossbar.h [new file with mode: 0644]
include/linux/isapnp.h
include/linux/kernel.h
include/linux/mbcache.h
include/linux/memblock.h
include/linux/mfd/abx500/ab8500.h
include/linux/mfd/arizona/registers.h
include/linux/mfd/bcm590xx.h [new file with mode: 0644]
include/linux/mfd/da9052/da9052.h
include/linux/mfd/da9063/core.h
include/linux/mfd/da9063/registers.h
include/linux/mfd/dbx500-prcmu.h
include/linux/mfd/lpc_ich.h
include/linux/mfd/max14577-private.h
include/linux/mfd/max14577.h
include/linux/mfd/pm8xxx/irq.h [deleted file]
include/linux/mfd/pm8xxx/pm8921.h [deleted file]
include/linux/mfd/rtsx_usb.h [new file with mode: 0644]
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
include/linux/mfd/tps65218.h [new file with mode: 0644]
include/linux/module.h
include/linux/moduleparam.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/of_mtd.h
include/linux/omap-dma.h
include/linux/perf_event.h
include/linux/platform_data/atmel.h
include/linux/platform_data/clk-integrator.h
include/linux/platform_data/elm.h
include/linux/platform_data/mtd-davinci-aemif.h
include/linux/platform_data/mtd-nand-s3c2410.h
include/linux/platform_data/video-imxfb.h
include/linux/pwm.h
include/linux/pxa2xx_ssp.h
include/linux/random.h
include/linux/reset.h
include/linux/security.h
include/linux/serial_s3c.h
include/linux/sh_clk.h
include/linux/ssbi.h
include/linux/sunrpc/bc_xprt.h
include/linux/sysfs.h
include/linux/uprobes.h
include/linux/wait.h
include/linux/xilinxfb.h [deleted file]
include/media/adv7842.h
include/media/lm3646.h [new file with mode: 0644]
include/media/rc-core.h
include/media/rc-map.h
include/media/v4l2-dev.h
include/media/v4l2-ioctl.h
include/media/v4l2-subdev.h
include/media/videobuf2-core.h
include/trace/events/btrfs.h
include/trace/events/ext4.h
include/trace/events/module.h
include/trace/events/v4l2.h
include/uapi/asm-generic/fcntl.h
include/uapi/linux/falloc.h
include/uapi/linux/fs.h
include/uapi/linux/fuse.h
include/uapi/linux/gfs2_ondisk.h
include/uapi/linux/v4l2-common.h
include/uapi/linux/v4l2-controls.h
include/uapi/linux/v4l2-dv-timings.h
include/uapi/linux/v4l2-subdev.h
include/uapi/linux/videodev2.h
include/uapi/mtd/ubi-user.h
include/video/omapdss.h
kernel/cpu.c
kernel/events/uprobes.c
kernel/module.c
kernel/panic.c
kernel/profile.c
kernel/sched/core.c
kernel/trace/Kconfig
kernel/trace/ring_buffer.c
kernel/tracepoint.c
mm/memblock.c
mm/memory.c
mm/mmap.c
mm/nommu.c
mm/vmstat.c
mm/zsmalloc.c
mm/zswap.c
net/ceph/crush/mapper.c
net/ceph/debugfs.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/ceph/osdmap.c
net/core/flow.c
net/iucv/iucv.c
net/sunrpc/backchannel_rqst.c
net/sunrpc/clnt.c
net/sunrpc/sched.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtsock.c
scripts/kallsyms.c
scripts/link-vmlinux.sh
scripts/mod/file2alias.c
security/security.c
security/selinux/hooks.c
sound/soc/kirkwood/Kconfig
tools/perf/config/Makefile.arch
tools/perf/perf.h
tools/testing/ktest/examples/kvm.conf

diff --git a/CREDITS b/CREDITS
index 61eabf7ca37614fe83239b4e4bbd91ada337bcfc..c322dcfb926d3c2d850f22af9b3c287e086bd9c2 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -630,6 +630,13 @@ N: Michael Elizabeth Chastain
 E: mec@shout.net
 D: Configure, Menuconfig, xconfig
 
+N: Mauro Carvalho Chehab
+E: m.chehab@samsung.org
+E: mchehab@infradead.org
+D: Media subsystem (V4L/DVB) drivers and core
+D: EDAC drivers and EDAC 3.0 core rework
+S: Brazil
+
 N: Raymond Chen
 E: raymondc@microsoft.com
 D: Author of Configure script
diff --git a/Documentation/ABI/testing/sysfs-class-rc b/Documentation/ABI/testing/sysfs-class-rc
new file mode 100644 (file)
index 0000000..b65674d
--- /dev/null
@@ -0,0 +1,111 @@
+What:          /sys/class/rc/
+Date:          Apr 2010
+KernelVersion: 2.6.35
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               The rc/ class sub-directory belongs to the Remote Controller
+               core and provides a sysfs interface for configuring infrared
+               remote controller receivers.
+
+What:          /sys/class/rc/rcN/
+Date:          Apr 2010
+KernelVersion: 2.6.35
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               A /sys/class/rc/rcN directory is created for each remote
+               control receiver device where N is the number of the receiver.
+
+What:          /sys/class/rc/rcN/protocols
+Date:          Jun 2010
+KernelVersion: 2.6.36
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               Reading this file returns a list of available protocols,
+               something like:
+                   "rc5 [rc6] nec jvc [sony]"
+               Enabled protocols are shown in [] brackets.
+               Writing "+proto" will add a protocol to the list of enabled
+               protocols.
+               Writing "-proto" will remove a protocol from the list of enabled
+               protocols.
+               Writing "proto" will enable only "proto".
+               Writing "none" will disable all protocols.
+               Write fails with EINVAL if an invalid protocol combination or
+               unknown protocol name is used.
+
+What:          /sys/class/rc/rcN/filter
+Date:          Jan 2014
+KernelVersion: 3.15
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               Sets the scancode filter expected value.
+               Use in combination with /sys/class/rc/rcN/filter_mask to set the
+               expected value of the bits set in the filter mask.
+               If the hardware supports it then scancodes which do not match
+               the filter will be ignored. Otherwise the write will fail with
+               an error.
+               This value may be reset to 0 if the current protocol is altered.
+
+What:          /sys/class/rc/rcN/filter_mask
+Date:          Jan 2014
+KernelVersion: 3.15
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               Sets the scancode filter mask of bits to compare.
+               Use in combination with /sys/class/rc/rcN/filter to set the bits
+               of the scancode which should be compared against the expected
+               value. A value of 0 disables the filter to allow all valid
+               scancodes to be processed.
+               If the hardware supports it then scancodes which do not match
+               the filter will be ignored. Otherwise the write will fail with
+               an error.
+               This value may be reset to 0 if the current protocol is altered.
+
+What:          /sys/class/rc/rcN/wakeup_protocols
+Date:          Feb 2014
+KernelVersion: 3.15
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               Reading this file returns a list of available protocols to use
+               for the wakeup filter, something like:
+                   "rc5 rc6 nec jvc [sony]"
+               The enabled wakeup protocol is shown in [] brackets.
+               Writing "+proto" will add a protocol to the list of enabled
+               wakeup protocols.
+               Writing "-proto" will remove a protocol from the list of enabled
+               wakeup protocols.
+               Writing "proto" will use "proto" for wakeup events.
+               Writing "none" will disable wakeup.
+               Write fails with EINVAL if an invalid protocol combination or
+               unknown protocol name is used, or if wakeup is not supported by
+               the hardware.
+
+What:          /sys/class/rc/rcN/wakeup_filter
+Date:          Jan 2014
+KernelVersion: 3.15
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               Sets the scancode wakeup filter expected value.
+               Use in combination with /sys/class/rc/rcN/wakeup_filter_mask to
+               set the expected value of the bits set in the wakeup filter mask
+               to trigger a system wake event.
+               If the hardware supports it and wakeup_filter_mask is not 0 then
+               scancodes which match the filter will wake the system from e.g.
+               suspend to RAM or power off.
+               Otherwise the write will fail with an error.
+               This value may be reset to 0 if the wakeup protocol is altered.
+
+What:          /sys/class/rc/rcN/wakeup_filter_mask
+Date:          Jan 2014
+KernelVersion: 3.15
+Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
+Description:
+               Sets the scancode wakeup filter mask of bits to compare.
+               Use in combination with /sys/class/rc/rcN/wakeup_filter to set
+               the bits of the scancode which should be compared against the
+               expected value to trigger a system wake event.
+               If the hardware supports it and wakeup_filter_mask is not 0 then
+               scancodes which match the filter will wake the system from e.g.
+               suspend to RAM or power off.
+               Otherwise the write will fail with an error.
+               This value may be reset to 0 if the wakeup protocol is altered.
index 32b0809203ddd00dfa7f5a236f72b8c00058ec5d..62dd72522d6e4f5f2db69eda0991511c5cec9df6 100644 (file)
@@ -55,3 +55,15 @@ Date:                January 2014
 Contact:       "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
 Description:
                 Controls the number of trials to find a victim segment.
+
+What:          /sys/fs/f2fs/<disk>/dir_level
+Date:          March 2014
+Contact:       "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
+Description:
+                Controls the directory level for large directory.
+
+What:          /sys/fs/f2fs/<disk>/ram_thresh
+Date:          March 2014
+Contact:       "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
+Description:
+                Controls the memory footprint used by f2fs.
index 47064c2b1f79b3cc4e1039323b7b43e9278735be..0aac02e7fb0e22e532dca3aca30c6fe7472bef95 100644 (file)
@@ -49,3 +49,4 @@ Description:  Module taint flags:
                        O - out-of-tree module
                        F - force-loaded module
                        C - staging driver module
+                       E - unsigned module
index d0758b241b235d562d46c729cd969f53a8e47e3e..bd9015d10cffa5d453870a07be347d814bf599ab 100644 (file)
@@ -850,16 +850,6 @@ printk(KERN_INFO "my ip: %pI4\n", &amp;ipaddress);
     <returnvalue>-ERESTARTSYS</returnvalue> if a signal is received.
     The <function>wait_event()</function> version ignores signals.
    </para>
-   <para>
-   Do not use the <function>sleep_on()</function> function family -
-   it is very easy to accidentally introduce races; almost certainly
-   one of the <function>wait_event()</function> family will do, or a
-   loop around <function>schedule_timeout()</function>. If you choose
-   to loop around <function>schedule_timeout()</function> remember
-   you must set the task state (with 
-   <function>set_current_state()</function>) on each iteration to avoid
-   busy-looping.
-   </para>
  
   </sect1>
 
index 86de89cfbd676cbeda054aba040432e25c4f68d3..c8683d66f0590d461a8f47f18f83c866448e43d2 100644 (file)
@@ -1042,7 +1042,14 @@ role="subsection"><title>DMX_ADD_PID</title>
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>This ioctl is undocumented. Documentation is welcome.</para>
+<para>This ioctl call allows to add multiple PIDs to a transport stream filter
+previously set up with DMX_SET_PES_FILTER and output equal to DMX_OUT_TSDEMUX_TAP.
+</para></entry></row><row><entry align="char"><para>
+It is used by readers of /dev/dvb/adapterX/demuxY.
+</para></entry></row><row><entry align="char"><para>
+It may be called at any time, i.e. before or after the first filter on the
+shared file descriptor was started. It makes it possible to record multiple
+services without the need to de-multiplex or re-multiplex TS packets.</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 <para>SYNOPSIS
@@ -1075,7 +1082,7 @@ role="subsection"><title>DMX_ADD_PID</title>
 </para>
 </entry><entry
  align="char">
-<para>Undocumented.</para>
+<para>PID number to be filtered.</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 &return-value-dvb;
@@ -1087,7 +1094,15 @@ role="subsection"><title>DMX_REMOVE_PID</title>
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>This ioctl is undocumented. Documentation is welcome.</para>
+<para>This ioctl call allows to remove a PID when multiple PIDs are set on a
+transport stream filter, e. g. a filter previously set up with output equal to
+DMX_OUT_TSDEMUX_TAP, created via either DMX_SET_PES_FILTER or DMX_ADD_PID.
+</para></entry></row><row><entry align="char"><para>
+It is used by readers of /dev/dvb/adapterX/demuxY.
+</para></entry></row><row><entry align="char"><para>
+It may be called at any time, i.e. before or after the first filter on the
+shared file descriptor was started. It makes it possible to record multiple
+services without the need to de-multiplex or re-multiplex TS packets.</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 <para>SYNOPSIS
@@ -1120,7 +1135,7 @@ role="subsection"><title>DMX_REMOVE_PID</title>
 </para>
 </entry><entry
  align="char">
-<para>Undocumented.</para>
+<para>PID of the PES filter to be removed.</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 &return-value-dvb;
index 0197bcc7842d84dd91e4135acf80c8c2e61d7f9c..4c15396c67e5911f0121f9ff21629fc24db0ccf3 100644 (file)
@@ -18,7 +18,7 @@
 <firstname>Mauro</firstname>
 <othername role="mi">Carvalho</othername>
 <surname>Chehab</surname>
-<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
+<affiliation><address><email>m.chehab@samsung.com</email></address></affiliation>
 <contrib>Ported document to Docbook XML.</contrib>
 </author>
 </authorgroup>
@@ -28,7 +28,7 @@
        <holder>Convergence GmbH</holder>
 </copyright>
 <copyright>
-       <year>2009-2012</year>
+       <year>2009-2014</year>
        <holder>Mauro Carvalho Chehab</holder>
 </copyright>
 
index 0d6e81bd9ed2f3b327666f79a38a3b7672491da3..8a6a6ff27af59ec8476862cda55b52765091a4d2 100644 (file)
@@ -744,7 +744,7 @@ typedef enum fe_hierarchy {
 </para>
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
-<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, int16_t
+<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, uint16_t
  &#x22C6;snr);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
@@ -766,7 +766,7 @@ typedef enum fe_hierarchy {
 </entry>
  </row><row><entry
  align="char">
-<para>int16_t *snr</para>
+<para>uint16_t *snr</para>
 </entry><entry
  align="char">
 <para>The signal-to-noise ratio is stored into *snr.</para>
@@ -791,7 +791,7 @@ typedef enum fe_hierarchy {
 <informaltable><tgroup cols="1"><tbody><row><entry
  align="char">
 <para>int ioctl( int fd, int request =
- <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, int16_t &#x22C6;strength);</para>
+ <link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, uint16_t &#x22C6;strength);</para>
 </entry>
  </row></tbody></tgroup></informaltable>
 
@@ -814,7 +814,7 @@ typedef enum fe_hierarchy {
 </entry>
  </row><row><entry
  align="char">
-<para>int16_t *strength</para>
+<para>uint16_t *strength</para>
 </entry><entry
  align="char">
 <para>The signal strength value is stored into *strength.</para>
index 1ddf354aa997947306d955ea2b6bd693b0aa1c1a..71f6bf9e735e89067902618ebea4b22035a892df 100644 (file)
@@ -38,70 +38,41 @@ the basic concepts applicable to all devices.</para>
 
       <para>V4L2 drivers are implemented as kernel modules, loaded
 manually by the system administrator or automatically when a device is
-first opened. The driver modules plug into the "videodev" kernel
+first discovered. The driver modules plug into the "videodev" kernel
 module. It provides helper functions and a common application
 interface specified in this document.</para>
 
       <para>Each driver thus loaded registers one or more device nodes
-with major number 81 and a minor number between 0 and 255. Assigning
-minor numbers to V4L2 devices is entirely up to the system administrator,
-this is primarily intended to solve conflicts between devices.<footnote>
-         <para>Access permissions are associated with character
-device special files, hence we must ensure device numbers cannot
-change with the module load order. To this end minor numbers are no
-longer automatically assigned by the "videodev" module as in V4L but
-requested by the driver. The defaults will suffice for most people
-unless two drivers compete for the same minor numbers.</para>
-       </footnote> The module options to select minor numbers are named
-after the device special file with a "_nr" suffix. For example "video_nr"
-for <filename>/dev/video</filename> video capture devices. The number is
-an offset to the base minor number associated with the device type.
-<footnote>
-         <para>In earlier versions of the V4L2 API the module options
-where named after the device special file with a "unit_" prefix, expressing
-the minor number itself, not an offset. Rationale for this change is unknown.
-Lastly the naming and semantics are just a convention among driver writers,
-the point to note is that minor numbers are not supposed to be hardcoded
-into drivers.</para>
-       </footnote> When the driver supports multiple devices of the same
-type more than one minor number can be assigned, separated by commas:
-<informalexample>
+with major number 81 and a minor number between 0 and 255. Minor numbers
+are allocated dynamically unless the kernel is compiled with the kernel
+option CONFIG_VIDEO_FIXED_MINOR_RANGES. In that case minor numbers are
+allocated in ranges depending on the device node type (video, radio, etc.).</para>
+
+      <para>Many drivers support "video_nr", "radio_nr" or "vbi_nr"
+module options to select specific video/radio/vbi node numbers. This allows
+the user to request that the device node is named e.g. /dev/video5 instead
+of leaving it to chance. When the driver supports multiple devices of the same
+type more than one device node number can be assigned, separated by commas:
+       <informalexample>
          <screen>
-&gt; insmod mydriver.o video_nr=0,1 radio_nr=0,1</screen>
+&gt; modprobe mydriver video_nr=0,1 radio_nr=0,1</screen>
        </informalexample></para>
 
       <para>In <filename>/etc/modules.conf</filename> this may be
 written as: <informalexample>
          <screen>
-alias char-major-81-0 mydriver
-alias char-major-81-1 mydriver
-alias char-major-81-64 mydriver              <co id="alias" />
-options mydriver video_nr=0,1 radio_nr=0,1   <co id="options" />
+options mydriver video_nr=0,1 radio_nr=0,1
          </screen>
-         <calloutlist>
-           <callout arearefs="alias">
-             <para>When an application attempts to open a device
-special file with major number 81 and minor number 0, 1, or 64, load
-"mydriver" (and the "videodev" module it depends upon).</para>
-           </callout>
-           <callout arearefs="options">
-             <para>Register the first two video capture devices with
-minor number 0 and 1 (base number is 0), the first two radio device
-with minor number 64 and 65 (base 64).</para>
-           </callout>
-         </calloutlist>
-       </informalexample> When no minor number is given as module
-option the driver supplies a default. <xref linkend="devices" />
-recommends the base minor numbers to be used for the various device
-types. Obviously minor numbers must be unique. When the number is
-already in use the <emphasis>offending device</emphasis> will not be
-registered. <!-- Blessed by Linus Torvalds on
-linux-kernel@vger.kernel.org, 2002-11-20. --></para>
-
-      <para>By convention system administrators create various
-character device special files with these major and minor numbers in
-the <filename>/dev</filename> directory. The names recommended for the
-different V4L2 device types are listed in <xref linkend="devices" />.
+       </informalexample> When no device node number is given as module
+option the driver supplies a default.</para>
+
+      <para>Normally udev will create the device nodes in /dev automatically
+for you. If udev is not installed, then you need to enable the
+CONFIG_VIDEO_FIXED_MINOR_RANGES kernel option in order to be able to correctly
+relate a minor number to a device node number. I.e., you need to be certain
+that minor number 5 maps to device node name video5. With this kernel option
+different device types have different minor number ranges. These ranges are
+listed in <xref linkend="devices" />.
 </para>
 
       <para>The creation of character special files (with
@@ -110,85 +81,66 @@ devices cannot be opened by major and minor number. That means
 applications cannot <emphasis>reliable</emphasis> scan for loaded or
 installed drivers. The user must enter a device name, or the
 application can try the conventional device names.</para>
-
-      <para>Under the device filesystem (devfs) the minor number
-options are ignored. V4L2 drivers (or by proxy the "videodev" module)
-automatically create the required device files in the
-<filename>/dev/v4l</filename> directory using the conventional device
-names above.</para>
     </section>
 
     <section id="related">
       <title>Related Devices</title>
 
-      <para>Devices can support several related functions. For example
-video capturing, video overlay and VBI capturing are related because
-these functions share, amongst other, the same video input and tuner
-frequency. V4L and earlier versions of V4L2 used the same device name
-and minor number for video capturing and overlay, but different ones
-for VBI. Experience showed this approach has several problems<footnote>
-         <para>Given a device file name one cannot reliable find
-related devices. For once names are arbitrary and in a system with
-multiple devices, where only some support VBI capturing, a
-<filename>/dev/video2</filename> is not necessarily related to
-<filename>/dev/vbi2</filename>. The V4L
-<constant>VIDIOCGUNIT</constant> ioctl would require a search for a
-device file with a particular major and minor number.</para>
-       </footnote>, and to make things worse the V4L videodev module
-used to prohibit multiple opens of a device.</para>
-
-      <para>As a remedy the present version of the V4L2 API relaxed the
-concept of device types with specific names and minor numbers. For
-compatibility with old applications drivers must still register different
-minor numbers to assign a default function to the device. But if related
-functions are supported by the driver they must be available under all
-registered minor numbers. The desired function can be selected after
-opening the device as described in <xref linkend="devices" />.</para>
-
-      <para>Imagine a driver supporting video capturing, video
-overlay, raw VBI capturing, and FM radio reception. It registers three
-devices with minor number 0, 64 and 224 (this numbering scheme is
-inherited from the V4L API). Regardless if
-<filename>/dev/video</filename> (81, 0) or
-<filename>/dev/vbi</filename> (81, 224) is opened the application can
-select any one of the video capturing, overlay or VBI capturing
-functions. Without programming (e.&nbsp;g. reading from the device
-with <application>dd</application> or <application>cat</application>)
-<filename>/dev/video</filename> captures video images, while
-<filename>/dev/vbi</filename> captures raw VBI data.
-<filename>/dev/radio</filename> (81, 64) is invariable a radio device,
-unrelated to the video functions. Being unrelated does not imply the
-devices can be used at the same time, however. The &func-open;
-function may very well return an &EBUSY;.</para>
+      <para>Devices can support several functions. For example
+video capturing, VBI capturing and radio support.</para>
+
+      <para>The V4L2 API creates different nodes for each of these functions.</para>
+
+      <para>The V4L2 API was designed with the idea that one device node could support
+all functions. However, in practice this never worked: this 'feature'
+was never used by applications and many drivers did not support it and if
+they did it was certainly never tested. In addition, switching a device
+node between different functions only works when using the streaming I/O
+API, not with the read()/write() API.</para>
+
+      <para>Today each device node supports just one function.</para>
 
       <para>Besides video input or output the hardware may also
 support audio sampling or playback. If so, these functions are
-implemented as OSS or ALSA PCM devices and eventually OSS or ALSA
-audio mixer. The V4L2 API makes no provisions yet to find these
-related devices. If you have an idea please write to the linux-media
-mailing list: &v4l-ml;.</para>
+implemented as ALSA PCM devices with optional ALSA audio mixer
+devices.</para>
+
+      <para>One problem with all these devices is that the V4L2 API
+makes no provisions to find these related devices. Some really
+complex devices use the Media Controller (see <xref linkend="media_controller" />)
+which can be used for this purpose. But most drivers do not use it,
+and while some code exists that uses sysfs to discover related devices
+(see libmedia_dev in the <ulink url="http://git.linuxtv.org/v4l-utils/">v4l-utils</ulink>
+git repository), there is no library yet that can provide a single API towards
+both Media Controller-based devices and devices that do not use the Media Controller.
+If you want to work on this please write to the linux-media mailing list: &v4l-ml;.</para>
     </section>
 
     <section>
       <title>Multiple Opens</title>
 
-      <para>In general, V4L2 devices can be opened more than once.
+      <para>V4L2 devices can be opened more than once.<footnote><para>
+There are still some old and obscure drivers that have not been updated to
+allow for multiple opens. This implies that for such drivers &func-open; can
+return an &EBUSY; when the device is already in use.</para></footnote>
 When this is supported by the driver, users can for example start a
 "panel" application to change controls like brightness or audio
 volume, while another application captures video and audio. In other words, panel
-applications are comparable to an OSS or ALSA audio mixer application.
-When a device supports multiple functions like capturing and overlay
-<emphasis>simultaneously</emphasis>, multiple opens allow concurrent
-use of the device by forked processes or specialized applications.</para>
-
-      <para>Multiple opens are optional, although drivers should
-permit at least concurrent accesses without data exchange, &ie; panel
-applications. This implies &func-open; can return an &EBUSY; when the
-device is already in use, as well as &func-ioctl; functions initiating
-data exchange (namely the &VIDIOC-S-FMT; ioctl), and the &func-read;
-and &func-write; functions.</para>
-
-      <para>Mere opening a V4L2 device does not grant exclusive
+applications are comparable to an ALSA audio mixer application.
+Just opening a V4L2 device should not change the state of the device.<footnote>
+<para>Unfortunately, opening a radio device often switches the state of the
+device to radio mode in many drivers. This behavior should be fixed eventually
+as it violates the V4L2 specification.</para></footnote></para>
+
+      <para>Once an application has allocated the memory buffers needed for
+streaming data (by calling the &VIDIOC-REQBUFS; or &VIDIOC-CREATE-BUFS; ioctls,
+or implicitly by calling the &func-read; or &func-write; functions) that
+application (filehandle) becomes the owner of the device. It is no longer
+allowed to make changes that would affect the buffer sizes (e.g. by calling
+the &VIDIOC-S-FMT; ioctl) and other applications are no longer allowed to allocate
+buffers or start or stop streaming. The &EBUSY; will be returned instead.</para>
+
+      <para>Merely opening a V4L2 device does not grant exclusive
 access.<footnote>
          <para>Drivers could recognize the
 <constant>O_EXCL</constant> open flag. Presently this is not required,
@@ -206,12 +158,7 @@ additional access privileges using the priority mechanism described in
       <para>V4L2 drivers should not support multiple applications
 reading or writing the same data stream on a device by copying
 buffers, time multiplexing or similar means. This is better handled by
-a proxy application in user space. When the driver supports stream
-sharing anyway it must be implemented transparently. The V4L2 API does
-not specify how conflicts are solved. <!-- For example O_EXCL when the
-application does not want to be preempted, PROT_READ mmapped buffers
-which can be mapped twice, what happens when image formats do not
-match etc.--></para>
+a proxy application in user space.</para>
     </section>
 
     <section>
@@ -240,15 +187,15 @@ methods</link> supported by the device.</para>
 
     <para>Starting with kernel version 3.1, VIDIOC-QUERYCAP will return the
 V4L2 API version used by the driver, with generally matches the Kernel version.
-There's no need of using &VIDIOC-QUERYCAP; to check if an specific ioctl is
-supported, the V4L2 core now returns ENOIOCTLCMD if a driver doesn't provide
+There's no need of using &VIDIOC-QUERYCAP; to check if a specific ioctl is
+supported, the V4L2 core now returns ENOTTY if a driver doesn't provide
 support for an ioctl.</para>
 
     <para>Other features can be queried
 by calling the respective ioctl, for example &VIDIOC-ENUMINPUT;
 to learn about the number, types and names of video connectors on the
 device. Although abstraction is a major objective of this API, the
-ioctl also allows driver specific applications to reliable identify
+&VIDIOC-QUERYCAP; ioctl also allows driver specific applications to reliably identify
 the driver.</para>
 
     <para>All V4L2 drivers must support
@@ -278,9 +225,7 @@ Applications requiring a different priority will usually call
 the &VIDIOC-QUERYCAP; ioctl.</para>
 
     <para>Ioctls changing driver properties, such as &VIDIOC-S-INPUT;,
-return an &EBUSY; after another application obtained higher priority.
-An event mechanism to notify applications about asynchronous property
-changes has been proposed but not added yet.</para>
+return an &EBUSY; after another application obtained higher priority.</para>
   </section>
 
   <section id="video">
@@ -288,9 +233,9 @@ changes has been proposed but not added yet.</para>
 
     <para>Video inputs and outputs are physical connectors of a
 device. These can be for example RF connectors (antenna/cable), CVBS
-a.k.a. Composite Video, S-Video or RGB connectors. Only video and VBI
-capture devices have inputs, output devices have outputs, at least one
-each. Radio devices have no video inputs or outputs.</para>
+a.k.a. Composite Video, S-Video or RGB connectors. Video and VBI
+capture devices have inputs. Video and VBI output devices have outputs,
+at least one each. Radio devices have no video inputs or outputs.</para>
 
     <para>To learn about the number and attributes of the
 available inputs and outputs applications can enumerate them with the
@@ -299,30 +244,13 @@ available inputs and outputs applications can enumerate them with the
 ioctl also contains signal status information applicable when the
 current video input is queried.</para>
 
-    <para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctl return the
+    <para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctls return the
 index of the current video input or output. To select a different
 input or output applications call the &VIDIOC-S-INPUT; and
-&VIDIOC-S-OUTPUT; ioctl. Drivers must implement all the input ioctls
+&VIDIOC-S-OUTPUT; ioctls. Drivers must implement all the input ioctls
 when the device has one or more inputs, all the output ioctls when the
 device has one or more outputs.</para>
 
-    <!--
-    <figure id=io-tree>
-      <title>Input and output enumeration is the root of most device properties.</title>
-      <mediaobject>
-       <imageobject>
-         <imagedata fileref="links.pdf" format="ps" />
-       </imageobject>
-       <imageobject>
-         <imagedata fileref="links.gif" format="gif" />
-       </imageobject>
-       <textobject>
-         <phrase>Links between various device property structures.</phrase>
-       </textobject>
-      </mediaobject>
-    </figure>
-    -->
-
     <example>
       <title>Information about the current video input</title>
 
@@ -330,20 +258,20 @@ device has one or more outputs.</para>
 &v4l2-input; input;
 int index;
 
-if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;index)) {
-       perror ("VIDIOC_G_INPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &amp;index)) {
+       perror("VIDIOC_G_INPUT");
+       exit(EXIT_FAILURE);
 }
 
-memset (&amp;input, 0, sizeof (input));
+memset(&amp;input, 0, sizeof(input));
 input.index = index;
 
-if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
-       perror ("VIDIOC_ENUMINPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+       perror("VIDIOC_ENUMINPUT");
+       exit(EXIT_FAILURE);
 }
 
-printf ("Current input: %s\n", input.name);
+printf("Current input: %s\n", input.name);
       </programlisting>
     </example>
 
@@ -355,9 +283,9 @@ int index;
 
 index = 0;
 
-if (-1 == ioctl (fd, &VIDIOC-S-INPUT;, &amp;index)) {
-       perror ("VIDIOC_S_INPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-S-INPUT;, &amp;index)) {
+       perror("VIDIOC_S_INPUT");
+       exit(EXIT_FAILURE);
 }
       </programlisting>
     </example>
@@ -397,7 +325,7 @@ available inputs and outputs applications can enumerate them with the
 also contains signal status information applicable when the current
 audio input is queried.</para>
 
-    <para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctl report
+    <para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctls report
 the current audio input and output, respectively. Note that, unlike
 &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; these ioctls return a structure
 as <constant>VIDIOC_ENUMAUDIO</constant> and
@@ -408,11 +336,11 @@ applications call the &VIDIOC-S-AUDIO; ioctl. To select an audio
 output (which presently has no changeable properties) applications
 call the &VIDIOC-S-AUDOUT; ioctl.</para>
 
-    <para>Drivers must implement all input ioctls when the device
-has one or more inputs, all output ioctls when the device has one
-or more outputs. When the device has any audio inputs or outputs the
-driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
-&v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
+    <para>Drivers must implement all audio input ioctls when the device
+has multiple selectable audio inputs, all audio output ioctls when the
+device has multiple selectable audio outputs. When the device has any
+audio inputs or outputs the driver must set the <constant>V4L2_CAP_AUDIO</constant>
+flag in the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
 
     <example>
       <title>Information about the current audio input</title>
@@ -420,14 +348,14 @@ driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
       <programlisting>
 &v4l2-audio; audio;
 
-memset (&amp;audio, 0, sizeof (audio));
+memset(&amp;audio, 0, sizeof(audio));
 
-if (-1 == ioctl (fd, &VIDIOC-G-AUDIO;, &amp;audio)) {
-       perror ("VIDIOC_G_AUDIO");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-G-AUDIO;, &amp;audio)) {
+       perror("VIDIOC_G_AUDIO");
+       exit(EXIT_FAILURE);
 }
 
-printf ("Current input: %s\n", audio.name);
+printf("Current input: %s\n", audio.name);
       </programlisting>
     </example>
 
@@ -437,13 +365,13 @@ printf ("Current input: %s\n", audio.name);
       <programlisting>
 &v4l2-audio; audio;
 
-memset (&amp;audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */
+memset(&amp;audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
 
 audio.index = 0;
 
-if (-1 == ioctl (fd, &VIDIOC-S-AUDIO;, &amp;audio)) {
-       perror ("VIDIOC_S_AUDIO");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-S-AUDIO;, &amp;audio)) {
+       perror("VIDIOC_S_AUDIO");
+       exit(EXIT_FAILURE);
 }
       </programlisting>
     </example>
@@ -468,7 +396,7 @@ the tuner.</para>
 video inputs.</para>
 
       <para>To query and change tuner properties applications use the
-&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctl, respectively. The
+&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctls, respectively. The
 &v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
 contains signal status information applicable when the tuner of the
 current video or radio input is queried. Note that
@@ -533,7 +461,7 @@ standards or variations of standards. Each video input and output may
 support another set of standards. This set is reported by the
 <structfield>std</structfield> field of &v4l2-input; and
 &v4l2-output; returned by the &VIDIOC-ENUMINPUT; and
-&VIDIOC-ENUMOUTPUT; ioctl, respectively.</para>
+&VIDIOC-ENUMOUTPUT; ioctls, respectively.</para>
 
     <para>V4L2 defines one bit for each analog video standard
 currently in use worldwide, and sets aside bits for driver defined
@@ -564,28 +492,10 @@ automatically.</para>
     <para>To query and select the standard used by the current video
 input or output applications call the &VIDIOC-G-STD; and
 &VIDIOC-S-STD; ioctl, respectively. The <emphasis>received</emphasis>
-standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note that the parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
-       <para>An alternative to the current scheme is to use pointers
-to indices as arguments of <constant>VIDIOC_G_STD</constant> and
-<constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
-&v4l2-output; <structfield>std</structfield> field would be a set of
-indices like <structfield>audioset</structfield>.</para>
-       <para>Indices are consistent with the rest of the API
-and identify the standard unambiguously. In the present scheme of
-things an enumerated standard is looked up by &v4l2-std-id;. Now the
-standards supported by the inputs of a device can overlap. Just
-assume the tuner and composite input in the example above both
-exist on a device. An enumeration of "PAL-B/G", "PAL-H/I" suggests
-a choice which does not exist. We cannot merge or omit sets, because
-applications would be unable to find the standards reported by
-<constant>VIDIOC_G_STD</constant>. That leaves separate enumerations
-for each input. Also selecting a standard by &v4l2-std-id; can be
-ambiguous. Advantage of this method is that applications need not
-identify the standard indirectly, after enumerating.</para><para>So in
-summary, the lookup itself is unavoidable. The difference is only
-whether the lookup is necessary to find an enumerated standard or to
-switch to a standard by &v4l2-std-id;.</para>
-      </footnote> Drivers must implement all video standard ioctls
+standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note that the
+parameter of all these ioctls is a pointer to a &v4l2-std-id; type
+(a standard set), <emphasis>not</emphasis> an index into the standard
+enumeration. Drivers must implement all video standard ioctls
 when the device has one or more video inputs or outputs.</para>
 
     <para>Special rules apply to devices such as USB cameras where the notion of video
@@ -604,17 +514,10 @@ to zero and the <constant>VIDIOC_G_STD</constant>,
 <constant>VIDIOC_S_STD</constant>,
 <constant>VIDIOC_QUERYSTD</constant> and
 <constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
-&ENOTTY;.<footnote>
-       <para>See <xref linkend="buffer" /> for a rationale.</para>
+&ENOTTY; or the &EINVAL;.</para>
        <para>Applications can make use of the <xref linkend="input-capabilities" /> and
 <xref linkend="output-capabilities"/> flags to determine whether the video standard ioctls
-are available for the device.</para>
-
-       <para>See <xref linkend="buffer" /> for a rationale. Probably
-even USB cameras follow some well known video standard. It might have
-been better to explicitly indicate elsewhere if a device cannot live
-up to normal expectations, instead of this exception.</para>
-           </footnote></para>
+can be used with the given input or output.</para>
 
     <example>
       <title>Information about the current video standard</title>
@@ -623,22 +526,22 @@ up to normal expectations, instead of this exception.</para>
 &v4l2-std-id; std_id;
 &v4l2-standard; standard;
 
-if (-1 == ioctl (fd, &VIDIOC-G-STD;, &amp;std_id)) {
+if (-1 == ioctl(fd, &VIDIOC-G-STD;, &amp;std_id)) {
        /* Note when VIDIOC_ENUMSTD always returns ENOTTY this
           is no video device or it falls under the USB exception,
           and VIDIOC_G_STD returning ENOTTY is no error. */
 
-       perror ("VIDIOC_G_STD");
-       exit (EXIT_FAILURE);
+       perror("VIDIOC_G_STD");
+       exit(EXIT_FAILURE);
 }
 
-memset (&amp;standard, 0, sizeof (standard));
+memset(&amp;standard, 0, sizeof(standard));
 standard.index = 0;
 
-while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
+while (0 == ioctl(fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
        if (standard.id &amp; std_id) {
-              printf ("Current video standard: %s\n", standard.name);
-              exit (EXIT_SUCCESS);
+              printf("Current video standard: %s\n", standard.name);
+              exit(EXIT_SUCCESS);
        }
 
        standard.index++;
@@ -648,8 +551,8 @@ while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
    empty unless this device falls under the USB exception. */
 
 if (errno == EINVAL || standard.index == 0) {
-       perror ("VIDIOC_ENUMSTD");
-       exit (EXIT_FAILURE);
+       perror("VIDIOC_ENUMSTD");
+       exit(EXIT_FAILURE);
 }
       </programlisting>
     </example>
@@ -662,26 +565,26 @@ input</title>
 &v4l2-input; input;
 &v4l2-standard; standard;
 
-memset (&amp;input, 0, sizeof (input));
+memset(&amp;input, 0, sizeof(input));
 
-if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
-       perror ("VIDIOC_G_INPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
+       perror("VIDIOC_G_INPUT");
+       exit(EXIT_FAILURE);
 }
 
-if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
-       perror ("VIDIOC_ENUM_INPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+       perror("VIDIOC_ENUM_INPUT");
+       exit(EXIT_FAILURE);
 }
 
-printf ("Current input %s supports:\n", input.name);
+printf("Current input %s supports:\n", input.name);
 
-memset (&amp;standard, 0, sizeof (standard));
+memset(&amp;standard, 0, sizeof(standard));
 standard.index = 0;
 
-while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
+while (0 == ioctl(fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
        if (standard.id &amp; input.std)
-               printf ("%s\n", standard.name);
+               printf("%s\n", standard.name);
 
        standard.index++;
 }
@@ -690,8 +593,8 @@ while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
    empty unless this device falls under the USB exception. */
 
 if (errno != EINVAL || standard.index == 0) {
-       perror ("VIDIOC_ENUMSTD");
-       exit (EXIT_FAILURE);
+       perror("VIDIOC_ENUMSTD");
+       exit(EXIT_FAILURE);
 }
       </programlisting>
     </example>
@@ -703,21 +606,21 @@ if (errno != EINVAL || standard.index == 0) {
 &v4l2-input; input;
 &v4l2-std-id; std_id;
 
-memset (&amp;input, 0, sizeof (input));
+memset(&amp;input, 0, sizeof(input));
 
-if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
-       perror ("VIDIOC_G_INPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
+       perror("VIDIOC_G_INPUT");
+       exit(EXIT_FAILURE);
 }
 
-if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
-       perror ("VIDIOC_ENUM_INPUT");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+       perror("VIDIOC_ENUM_INPUT");
+       exit(EXIT_FAILURE);
 }
 
 if (0 == (input.std &amp; V4L2_STD_PAL_BG)) {
-       fprintf (stderr, "Oops. B/G PAL is not supported.\n");
-       exit (EXIT_FAILURE);
+       fprintf(stderr, "Oops. B/G PAL is not supported.\n");
+       exit(EXIT_FAILURE);
 }
 
 /* Note this is also supposed to work when only B
@@ -725,9 +628,9 @@ if (0 == (input.std &amp; V4L2_STD_PAL_BG)) {
 
 std_id = V4L2_STD_PAL_BG;
 
-if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
-       perror ("VIDIOC_S_STD");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, &VIDIOC-S-STD;, &amp;std_id)) {
+       perror("VIDIOC_S_STD");
+       exit(EXIT_FAILURE);
 }
       </programlisting>
     </example>
@@ -740,26 +643,25 @@ corresponding video timings. Today there are many more different hardware interf
 such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry
 video signals and there is a need to extend the API to select the video timings
 for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to
-the limited bits available, a new set of IOCTLs was added to set/get video timings at
-the input and output: </para><itemizedlist>
-       <listitem>
-       <para>DV Timings: This will allow applications to define detailed
-video timings for the interface. This includes parameters such as width, height,
-polarities, frontporch, backporch etc. The <filename>linux/v4l2-dv-timings.h</filename>
+the limited bits available, a new set of ioctls was added to set/get video timings at
+the input and output.</para>
+
+       <para>These ioctls deal with the detailed digital video timings that define
+each video format. This includes parameters such as the active video width and height,
+signal polarities, frontporches, backporches, sync widths etc. The <filename>linux/v4l2-dv-timings.h</filename>
 header can be used to get the timings of the formats in the <xref linkend="cea861" /> and
 <xref linkend="vesadmt" /> standards.
        </para>
-       </listitem>
-       </itemizedlist>
-       <para>To enumerate and query the attributes of the DV timings supported by a device,
+
+       <para>To enumerate and query the attributes of the DV timings supported by a device
        applications use the &VIDIOC-ENUM-DV-TIMINGS; and &VIDIOC-DV-TIMINGS-CAP; ioctls.
-       To set DV timings for the device, applications use the
+       To set DV timings for the device applications use the
 &VIDIOC-S-DV-TIMINGS; ioctl and to get current DV timings they use the
 &VIDIOC-G-DV-TIMINGS; ioctl. To detect the DV timings as seen by the video receiver applications
 use the &VIDIOC-QUERY-DV-TIMINGS; ioctl.</para>
        <para>Applications can make use of the <xref linkend="input-capabilities" /> and
-<xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the
-video timings for the device.</para>
+<xref linkend="output-capabilities"/> flags to determine whether the digital video ioctls
+can be used with the given input or output.</para>
   </section>
 
   &sub-controls;
index 86c6dd2f6b8a0830cff2b442484450a1755fe6cd..eee6f0f4aa433cb535d6375bf307273a8e3d1c22 100644 (file)
@@ -2535,6 +2535,16 @@ fields changed from _s32 to _u32.
       </orderedlist>
     </section>
 
+    <section>
+      <title>V4L2 in Linux 3.15</title>
+      <orderedlist>
+        <listitem>
+         <para>Added Software Defined Radio (SDR) Interface.
+         </para>
+        </listitem>
+      </orderedlist>
+    </section>
+
     <section id="other">
       <title>Relation of V4L2 to other Linux multimedia APIs</title>
 
@@ -2651,6 +2661,9 @@ ioctls.</para>
         <listitem>
          <para>Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.</para>
         </listitem>
+        <listitem>
+         <para>Software Defined Radio (SDR) Interface, <xref linkend="sdr" />.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
index a5a3188e5af7961889f27c61b295cbf04a2e1c8b..47198eef75a4c32b5227cb71b041e00749dc1000 100644 (file)
@@ -2256,6 +2256,26 @@ Applicable to the MPEG1, MPEG2, MPEG4 encoders.</entry>
                <entry>integer</entry>
              </row><row><entry spanname="descr">Sets the initial delay in milliseconds for
 VBV buffer control.</entry>
+             </row>
+
+                 <row><entry></entry></row>
+             <row id="v4l2-mpeg-video-hor-search-range">
+               <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE</constant>&nbsp;</entry>
+               <entry>integer</entry>
+             </row>
+               <row><entry spanname="descr">Horizontal search range defines maximum horizontal search area in pixels
+to search and match for the present Macroblock (MB) in the reference picture. This V4L2 control macro is used to set
+horizontal search range for motion estimation module in video encoder.</entry>
+             </row>
+
+                <row><entry></entry></row>
+             <row id="v4l2-mpeg-video-vert-search-range">
+               <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE</constant>&nbsp;</entry>
+               <entry>integer</entry>
+             </row>
+               <row><entry spanname="descr">Vertical search range defines maximum vertical search area in pixels
+to search and match for the present Macroblock (MB) in the reference picture. This V4L2 control macro is used to set
+vertical search range for motion estimation module in video encoder.</entry>
              </row>
 
              <row><entry></entry></row>
@@ -4370,6 +4390,24 @@ interface and may change in the future.</para>
                  <entry>The flash controller has detected a short or open
                  circuit condition on the indicator LED.</entry>
                </row>
+               <row>
+                 <entry><constant>V4L2_FLASH_FAULT_UNDER_VOLTAGE</constant></entry>
+                 <entry>Flash controller voltage to the flash LED
+                 has been below the minimum limit specific to the flash
+                 controller.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_FLASH_FAULT_INPUT_VOLTAGE</constant></entry>
+                 <entry>The input voltage of the flash controller is below
+                 the limit under which strobing the flash at full current
+                 will not be possible.The condition persists until this flag
+                 is no longer set.</entry>
+               </row>
+               <row>
+                 <entry><constant>V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE</constant></entry>
+                 <entry>The temperature of the LED has exceeded its
+                 allowed upper limit.</entry>
+               </row>
              </tbody>
            </entrytbl>
          </row>
@@ -4971,4 +5009,142 @@ defines possible values for de-emphasis. Here they are:</entry>
       </table>
 
       </section>
+
+    <section id="rf-tuner-controls">
+      <title>RF Tuner Control Reference</title>
+
+      <para>
+The RF Tuner (RF_TUNER) class includes controls for common features of devices
+having RF tuner.
+      </para>
+      <para>
+In this context, RF tuner is radio receiver circuit between antenna and
+demodulator. It receives radio frequency (RF) from the antenna and converts that
+received signal to lower intermediate frequency (IF) or baseband frequency (BB).
+Tuners that could do baseband output are often called Zero-IF tuners. Older
+tuners were typically simple PLL tuners inside a metal box, whilst newer ones
+are highly integrated chips without a metal box "silicon tuners". These controls
+are mostly applicable for new feature rich silicon tuners, just because older
+tuners does not have much adjustable features.
+      </para>
+      <para>
+For more information about RF tuners see
+<ulink url="http://en.wikipedia.org/wiki/Tuner_%28radio%29">Tuner (radio)</ulink>
+and
+<ulink url="http://en.wikipedia.org/wiki/RF_front_end">RF front end</ulink>
+from Wikipedia.
+      </para>
+
+      <table pgwide="1" frame="none" id="rf-tuner-control-id">
+        <title>RF_TUNER Control IDs</title>
+
+        <tgroup cols="4">
+          <colspec colname="c1" colwidth="1*" />
+          <colspec colname="c2" colwidth="6*" />
+          <colspec colname="c3" colwidth="2*" />
+          <colspec colname="c4" colwidth="6*" />
+          <spanspec namest="c1" nameend="c2" spanname="id" />
+          <spanspec namest="c2" nameend="c4" spanname="descr" />
+          <thead>
+            <row>
+              <entry spanname="id" align="left">ID</entry>
+              <entry align="left">Type</entry>
+            </row>
+            <row rowsep="1">
+              <entry spanname="descr" align="left">Description</entry>
+            </row>
+          </thead>
+          <tbody valign="top">
+            <row><entry></entry></row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_CLASS</constant>&nbsp;</entry>
+              <entry>class</entry>
+            </row><row><entry spanname="descr">The RF_TUNER class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class.</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_BANDWIDTH_AUTO</constant>&nbsp;</entry>
+              <entry>boolean</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Enables/disables tuner radio channel
+bandwidth configuration. In automatic mode bandwidth configuration is performed
+by the driver.</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_BANDWIDTH</constant>&nbsp;</entry>
+              <entry>integer</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Filter(s) on tuner signal path are used to
+filter signal according to receiving party needs. Driver configures filters to
+fulfill desired bandwidth requirement. Used when V4L2_CID_RF_TUNER_BANDWIDTH_AUTO is not
+set. Unit is in Hz. The range and step are driver-specific.</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_LNA_GAIN_AUTO</constant>&nbsp;</entry>
+              <entry>boolean</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Enables/disables LNA automatic gain control (AGC)</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO</constant>&nbsp;</entry>
+              <entry>boolean</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Enables/disables mixer automatic gain control (AGC)</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_IF_GAIN_AUTO</constant>&nbsp;</entry>
+              <entry>boolean</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Enables/disables IF automatic gain control (AGC)</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_LNA_GAIN</constant>&nbsp;</entry>
+              <entry>integer</entry>
+            </row>
+            <row>
+              <entry spanname="descr">LNA (low noise amplifier) gain is first
+gain stage on the RF tuner signal path. It is located very close to tuner
+antenna input. Used when <constant>V4L2_CID_RF_TUNER_LNA_GAIN_AUTO</constant> is not set.
+The range and step are driver-specific.</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_MIXER_GAIN</constant>&nbsp;</entry>
+              <entry>integer</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Mixer gain is second gain stage on the RF
+tuner signal path. It is located inside mixer block, where RF signal is
+down-converted by the mixer. Used when <constant>V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO</constant>
+is not set. The range and step are driver-specific.</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_IF_GAIN</constant>&nbsp;</entry>
+              <entry>integer</entry>
+            </row>
+            <row>
+              <entry spanname="descr">IF gain is last gain stage on the RF tuner
+signal path. It is located on output of RF tuner. It controls signal level of
+intermediate frequency output or baseband output. Used when
+<constant>V4L2_CID_RF_TUNER_IF_GAIN_AUTO</constant> is not set. The range and step are
+driver-specific.</entry>
+            </row>
+            <row>
+              <entry spanname="id"><constant>V4L2_CID_RF_TUNER_PLL_LOCK</constant>&nbsp;</entry>
+              <entry>boolean</entry>
+            </row>
+            <row>
+              <entry spanname="descr">Is synthesizer PLL locked? RF tuner is
+receiving given frequency when that control is set. This is a read-only control.
+</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+    </section>
 </section>
index dd91d6134e8c950a0add05ab4e6cd45f2c04b1f7..54853329140b1ab3f2144ff6dd039cc254c67e46 100644 (file)
@@ -56,18 +56,18 @@ framebuffer device.</para>
 unsigned int i;
 int fb_fd;
 
-if (-1 == ioctl (fd, VIDIOC_G_FBUF, &amp;fbuf)) {
-       perror ("VIDIOC_G_FBUF");
-       exit (EXIT_FAILURE);
+if (-1 == ioctl(fd, VIDIOC_G_FBUF, &amp;fbuf)) {
+       perror("VIDIOC_G_FBUF");
+       exit(EXIT_FAILURE);
 }
 
-for (i = 0; i &gt; 30; ++i) {
+for (i = 0; i &lt; 30; i++) {
        char dev_name[16];
        struct fb_fix_screeninfo si;
 
-       snprintf (dev_name, sizeof (dev_name), "/dev/fb%u", i);
+       snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
 
-       fb_fd = open (dev_name, O_RDWR);
+       fb_fd = open(dev_name, O_RDWR);
        if (-1 == fb_fd) {
                switch (errno) {
                case ENOENT: /* no such file */
@@ -75,19 +75,19 @@ for (i = 0; i &gt; 30; ++i) {
                        continue;
 
                default:
-                       perror ("open");
-                       exit (EXIT_FAILURE);
+                       perror("open");
+                       exit(EXIT_FAILURE);
                }
        }
 
-       if (0 == ioctl (fb_fd, FBIOGET_FSCREENINFO, &amp;si)) {
-               if (si.smem_start == (unsigned long) fbuf.base)
+       if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &amp;si)) {
+               if (si.smem_start == (unsigned long)fbuf.base)
                        break;
        } else {
                /* Apparently not a framebuffer device. */
        }
 
-       close (fb_fd);
+       close(fb_fd);
        fb_fd = -1;
 }
 
diff --git a/Documentation/DocBook/media/v4l/dev-sdr.xml b/Documentation/DocBook/media/v4l/dev-sdr.xml
new file mode 100644 (file)
index 0000000..dc14804
--- /dev/null
@@ -0,0 +1,110 @@
+  <title>Software Defined Radio Interface (SDR)</title>
+
+  <note>
+    <title>Experimental</title>
+    <para>This is an <link linkend="experimental"> experimental </link>
+    interface and may change in the future.</para>
+  </note>
+
+  <para>
+SDR is an abbreviation of Software Defined Radio, the radio device
+which uses application software for modulation or demodulation. This interface
+is intended for controlling and data streaming of such devices.
+  </para>
+
+  <para>
+SDR devices are accessed through character device special files named
+<filename>/dev/swradio0</filename> to <filename>/dev/swradio255</filename>
+with major number 81 and dynamically allocated minor numbers 0 to 255.
+  </para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>
+Devices supporting the SDR receiver interface set the
+<constant>V4L2_CAP_SDR_CAPTURE</constant> and
+<constant>V4L2_CAP_TUNER</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. That flag means the device has an
+Analog to Digital Converter (ADC), which is a mandatory element for the SDR receiver.
+At least one of the read/write, streaming or asynchronous I/O methods must
+be supported.
+    </para>
+  </section>
+
+  <section>
+    <title>Supplemental Functions</title>
+
+    <para>
+SDR devices can support <link linkend="control">controls</link>, and must
+support the <link linkend="tuner">tuner</link> ioctls. Tuner ioctls are used
+for setting the ADC sampling rate (sampling frequency) and the possible RF tuner
+frequency.
+    </para>
+
+    <para>
+The <constant>V4L2_TUNER_ADC</constant> tuner type is used for ADC tuners, and
+the <constant>V4L2_TUNER_RF</constant> tuner type is used for RF tuners. The
+tuner index of the RF tuner (if any) must always follow the ADC tuner index.
+Normally the ADC tuner is #0 and the RF tuner is #1.
+    </para>
+
+    <para>
+The &VIDIOC-S-HW-FREQ-SEEK; ioctl is not supported.
+    </para>
+  </section>
+
+  <section>
+    <title>Data Format Negotiation</title>
+
+    <para>
+The SDR capture device uses the <link linkend="format">format</link> ioctls to
+select the capture format. Both the sampling resolution and the data streaming
+format are bound to that selectable format. In addition to the basic
+<link linkend="format">format</link> ioctls, the &VIDIOC-ENUM-FMT; ioctl
+must be supported as well.
+    </para>
+
+    <para>
+To use the <link linkend="format">format</link> ioctls applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant> and use the &v4l2-sdr-format;
+<structfield>sdr</structfield> member of the <structfield>fmt</structfield>
+union as needed per the desired operation.
+Currently only the <structfield>pixelformat</structfield> field of
+&v4l2-sdr-format; is used. The content of that field is the V4L2 fourcc code
+of the data format.
+    </para>
+
+    <table pgwide="1" frame="none" id="v4l2-sdr-format">
+      <title>struct <structname>v4l2_sdr_format</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+        <tbody valign="top">
+          <row>
+            <entry>__u32</entry>
+            <entry><structfield>pixelformat</structfield></entry>
+            <entry>
+The data format or type of compression, set by the application. This is a
+little endian <link linkend="v4l2-fourcc">four character code</link>.
+V4L2 defines SDR formats in <xref linkend="sdr-formats" />.
+           </entry>
+          </row>
+          <row>
+            <entry>__u8</entry>
+            <entry><structfield>reserved[28]</structfield></entry>
+            <entry>This array is reserved for future extensions.
+Drivers and applications must set it to zero.</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <para>
+An SDR device may support <link linkend="rw">read/write</link>
+and/or streaming (<link linkend="mmap">memory mapping</link>
+or <link linkend="userp">user pointer</link>) I/O.
+    </para>
+
+  </section>
index 2c4c068dde83f26d723382e7c1765b9a4ef95653..97a69bf6f3ebddc62adbd9921421e1f041cfbe8d 100644 (file)
@@ -339,8 +339,8 @@ returns immediately with an &EAGAIN; when no buffer is available. The
 queues as a side effect. Since there is no notion of doing anything
 "now" on a multitasking system, if an application needs to synchronize
 with another event it should examine the &v4l2-buffer;
-<structfield>timestamp</structfield> of captured buffers, or set the
-field before enqueuing buffers for output.</para>
+<structfield>timestamp</structfield> of captured or outputted buffers.
+</para>
 
     <para>Drivers implementing memory mapping I/O must
 support the <constant>VIDIOC_REQBUFS</constant>,
@@ -457,7 +457,7 @@ queues and unlocks all buffers as a side effect. Since there is no
 notion of doing anything "now" on a multitasking system, if an
 application needs to synchronize with another event it should examine
 the &v4l2-buffer; <structfield>timestamp</structfield> of captured
-buffers, or set the field before enqueuing buffers for output.</para>
+or outputted buffers.</para>
 
     <para>Drivers implementing user pointer I/O must
 support the <constant>VIDIOC_REQBUFS</constant>,
@@ -620,8 +620,7 @@ returns immediately with an &EAGAIN; when no buffer is available. The
 unlocks all buffers as a side effect. Since there is no notion of doing
 anything "now" on a multitasking system, if an application needs to synchronize
 with another event it should examine the &v4l2-buffer;
-<structfield>timestamp</structfield> of captured buffers, or set the field
-before enqueuing buffers for output.</para>
+<structfield>timestamp</structfield> of captured or outputted buffers.</para>
 
     <para>Drivers implementing DMABUF importing I/O must support the
 <constant>VIDIOC_REQBUFS</constant>, <constant>VIDIOC_QBUF</constant>,
@@ -654,38 +653,19 @@ plane, are stored in struct <structname>v4l2_plane</structname> instead.
 In that case, struct <structname>v4l2_buffer</structname> contains an array of
 plane structures.</para>
 
-      <para>Nominally timestamps refer to the first data byte transmitted.
-In practice however the wide range of hardware covered by the V4L2 API
-limits timestamp accuracy. Often an interrupt routine will
-sample the system clock shortly after the field or frame was stored
-completely in memory. So applications must expect a constant
-difference up to one field or frame period plus a small (few scan
-lines) random error. The delay and error can be much
-larger due to compression or transmission over an external bus when
-the frames are not properly stamped by the sender. This is frequently
-the case with USB cameras. Here timestamps refer to the instant the
-field or frame was received by the driver, not the capture time. These
-devices identify by not enumerating any video standards, see <xref
-linkend="standard" />.</para>
-
-      <para>Similar limitations apply to output timestamps. Typically
-the video hardware locks to a clock controlling the video timing, the
-horizontal and vertical synchronization pulses. At some point in the
-line sequence, possibly the vertical blanking, an interrupt routine
-samples the system clock, compares against the timestamp and programs
-the hardware to repeat the previous field or frame, or to display the
-buffer contents.</para>
-
-      <para>Apart of limitations of the video device and natural
-inaccuracies of all clocks, it should be noted system time itself is
-not perfectly stable. It can be affected by power saving cycles,
-warped to insert leap seconds, or even turned back or forth by the
-system administrator affecting long term measurements. <footnote>
-         <para>Since no other Linux multimedia
-API supports unadjusted time it would be foolish to introduce here. We
-must use a universally supported clock to synchronize different media,
-hence time of day.</para>
-       </footnote></para>
+    <para>Dequeued video buffers come with timestamps. The driver
+    decides at which part of the frame and with which clock the
+    timestamp is taken. Please see flags in the masks
+    <constant>V4L2_BUF_FLAG_TIMESTAMP_MASK</constant> and
+    <constant>V4L2_BUF_FLAG_TSTAMP_SRC_MASK</constant> in <xref
+    linkend="buffer-flags" />. These flags are always valid and constant
+    across all buffers during the whole video stream. Changes in these
+    flags may take place as a side effect of &VIDIOC-S-INPUT; or
+    &VIDIOC-S-OUTPUT; however. The
+    <constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant> timestamp type
+    which is used by e.g. on mem-to-mem devices is an exception to the
+    rule: the timestamp source flags are copied from the OUTPUT video
+    buffer to the CAPTURE video buffer.</para>
 
     <table frame="none" pgwide="1" id="v4l2-buffer">
       <title>struct <structname>v4l2_buffer</structname></title>
@@ -696,10 +676,11 @@ hence time of day.</para>
            <entry>__u32</entry>
            <entry><structfield>index</structfield></entry>
            <entry></entry>
-           <entry>Number of the buffer, set by the application. This
-field is only used for <link linkend="mmap">memory mapping</link> I/O
-and can range from zero to the number of buffers allocated
-with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
+           <entry>Number of the buffer, set by the application except
+when calling &VIDIOC-DQBUF;, then it is set by the driver.
+This field can range from zero to the number of buffers allocated
+with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>),
+plus any buffers allocated with &VIDIOC-CREATE-BUFS; minus one.</entry>
          </row>
          <row>
            <entry>__u32</entry>
@@ -718,7 +699,7 @@ linkend="v4l2-buf-type" /></entry>
 buffer. It depends on the negotiated data format and may change with
 each buffer for compressed variable size data like JPEG images.
 Drivers must set this field when <structfield>type</structfield>
-refers to an input stream, applications when an output stream.</entry>
+refers to an input stream, applications when it refers to an output stream.</entry>
          </row>
          <row>
            <entry>__u32</entry>
@@ -735,7 +716,7 @@ linkend="buffer-flags" />.</entry>
 buffer, see <xref linkend="v4l2-field" />. This field is not used when
 the buffer contains VBI data. Drivers must set it when
 <structfield>type</structfield> refers to an input stream,
-applications when an output stream.</entry>
+applications when it refers to an output stream.</entry>
          </row>
          <row>
            <entry>struct timeval</entry>
@@ -745,15 +726,13 @@ applications when an output stream.</entry>
            byte was captured, as returned by the
            <function>clock_gettime()</function> function for the relevant
            clock id; see <constant>V4L2_BUF_FLAG_TIMESTAMP_*</constant> in
-           <xref linkend="buffer-flags" />. For output streams the data
-           will not be displayed before this time, secondary to the nominal
-           frame rate determined by the current video standard in enqueued
-           order. Applications can for example zero this field to display
-           frames as soon as possible. The driver stores the time at which
-           the first data byte was actually sent out in the
-           <structfield>timestamp</structfield> field. This permits
+           <xref linkend="buffer-flags" />. For output streams the driver
+           stores the time at which the last data byte was actually sent out
+           in the  <structfield>timestamp</structfield> field. This permits
            applications to monitor the drift between the video and system
-           clock.</para></entry>
+           clock. For output streams that use <constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant>
+           the application has to fill in the timestamp which will be copied
+           by the driver to the capture stream.</para></entry>
          </row>
          <row>
            <entry>&v4l2-timecode;</entry>
@@ -846,7 +825,8 @@ is the file descriptor associated with a DMABUF buffer.</entry>
            <entry><structfield>length</structfield></entry>
            <entry></entry>
            <entry>Size of the buffer (not the payload) in bytes for the
-           single-planar API. For the multi-planar API the application sets
+           single-planar API. This is set by the driver based on the calls to
+           &VIDIOC-REQBUFS; and/or &VIDIOC-CREATE-BUFS;. For the multi-planar API the application sets
            this to the number of elements in the <structfield>planes</structfield>
            array. The driver will fill in the actual number of valid elements in
            that array.
@@ -880,13 +860,15 @@ should set this to 0.</entry>
            <entry><structfield>bytesused</structfield></entry>
            <entry></entry>
            <entry>The number of bytes occupied by data in the plane
-           (its payload).</entry>
+             (its payload). Drivers must set this field when <structfield>type</structfield>
+             refers to an input stream, applications when it refers to an output stream.</entry>
          </row>
          <row>
            <entry>__u32</entry>
            <entry><structfield>length</structfield></entry>
            <entry></entry>
-           <entry>Size in bytes of the plane (not its payload).</entry>
+           <entry>Size in bytes of the plane (not its payload). This is set by the driver
+           based on the calls to &VIDIOC-REQBUFS; and/or &VIDIOC-CREATE-BUFS;.</entry>
          </row>
          <row>
            <entry>union</entry>
@@ -925,7 +907,9 @@ should set this to 0.</entry>
            <entry>__u32</entry>
            <entry><structfield>data_offset</structfield></entry>
            <entry></entry>
-           <entry>Offset in bytes to video data in the plane, if applicable.
+           <entry>Offset in bytes to video data in the plane.
+             Drivers must set this field when <structfield>type</structfield>
+             refers to an input stream, applications when it refers to an output stream.
            </entry>
          </row>
          <row>
@@ -1005,6 +989,12 @@ should set this to 0.</entry>
            <entry>Buffer for video output overlay (OSD), see <xref
                linkend="osd" />.</entry>
          </row>
+         <row>
+           <entry><constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant></entry>
+           <entry>11</entry>
+           <entry>Buffer for Software Defined Radio (SDR), see <xref
+               linkend="sdr" />.</entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
@@ -1016,7 +1006,7 @@ should set this to 0.</entry>
        <tbody valign="top">
          <row>
            <entry><constant>V4L2_BUF_FLAG_MAPPED</constant></entry>
-           <entry>0x0001</entry>
+           <entry>0x00000001</entry>
            <entry>The buffer resides in device memory and has been mapped
 into the application's address space, see <xref linkend="mmap" /> for details.
 Drivers set or clear this flag when the
@@ -1026,7 +1016,7 @@ Drivers set or clear this flag when the
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_QUEUED</constant></entry>
-           <entry>0x0002</entry>
+           <entry>0x00000002</entry>
          <entry>Internally drivers maintain two buffer queues, an
 incoming and outgoing queue. When this flag is set, the buffer is
 currently on the incoming queue. It automatically moves to the
@@ -1039,7 +1029,7 @@ cleared.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_DONE</constant></entry>
-           <entry>0x0004</entry>
+           <entry>0x00000004</entry>
            <entry>When this flag is set, the buffer is currently on
 the outgoing queue, ready to be dequeued from the driver. Drivers set
 or clear this flag when the <constant>VIDIOC_QUERYBUF</constant> ioctl
@@ -1049,11 +1039,11 @@ buffer cannot be on both queues at the same time, the
 <constant>V4L2_BUF_FLAG_QUEUED</constant> and
 <constant>V4L2_BUF_FLAG_DONE</constant> flag are mutually exclusive.
 They can be both cleared however, then the buffer is in "dequeued"
-state, in the application domain to say so.</entry>
+state, in the application domain so to say.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_ERROR</constant></entry>
-           <entry>0x0040</entry>
+           <entry>0x00000040</entry>
            <entry>When this flag is set, the buffer has been dequeued
            successfully, although the data might have been corrupted.
            This is recoverable, streaming may continue as normal and
@@ -1063,35 +1053,43 @@ state, in the application domain to say so.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
-           <entry>0x0008</entry>
+           <entry>0x00000008</entry>
          <entry>Drivers set or clear this flag when calling the
 <constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video
 capture devices when the buffer contains a compressed image which is a
-key frame (or field), &ie; can be decompressed on its own.</entry>
+key frame (or field), &ie; can be decompressed on its own. Also know as
+an I-frame.  Applications can set this bit when <structfield>type</structfield>
+refers to an output stream.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_PFRAME</constant></entry>
-           <entry>0x0010</entry>
+           <entry>0x00000010</entry>
            <entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
 this flags predicted frames or fields which contain only differences to a
-previous key frame.</entry>
+previous key frame. Applications can set this bit when <structfield>type</structfield>
+refers to an output stream.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_BFRAME</constant></entry>
-           <entry>0x0020</entry>
-           <entry>Similar to <constant>V4L2_BUF_FLAG_PFRAME</constant>
-       this is a bidirectional predicted frame or field. [ooc tbd]</entry>
+           <entry>0x00000020</entry>
+           <entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
+this flags a bi-directional predicted frame or field which contains only
+the differences between the current frame and both the preceding and following
+key frames to specify its content. Applications can set this bit when
+<structfield>type</structfield> refers to an output stream.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_TIMECODE</constant></entry>
-           <entry>0x0100</entry>
+           <entry>0x00000100</entry>
            <entry>The <structfield>timecode</structfield> field is valid.
 Drivers set or clear this flag when the <constant>VIDIOC_DQBUF</constant>
-ioctl is called.</entry>
+ioctl is called.  Applications can set this bit and the corresponding
+<structfield>timecode</structfield> structure when <structfield>type</structfield>
+refers to an output stream.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
-           <entry>0x0400</entry>
+           <entry>0x00000400</entry>
            <entry>The buffer has been prepared for I/O and can be queued by the
 application. Drivers set or clear this flag when the
 <link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
@@ -1101,7 +1099,7 @@ application. Drivers set or clear this flag when the
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
-           <entry>0x0800</entry>
+           <entry>0x00000800</entry>
            <entry>Caches do not have to be invalidated for this buffer.
 Typically applications shall use this flag if the data captured in the buffer
 is not going to be touched by the CPU, instead the buffer will, probably, be
@@ -1110,7 +1108,7 @@ passed on to a DMA-capable hardware unit for further processing or output.
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
-           <entry>0x1000</entry>
+           <entry>0x00001000</entry>
            <entry>Caches do not have to be cleaned for this buffer.
 Typically applications shall use this flag for output buffers if the data
 in this buffer has not been created by the CPU but by some DMA-capable unit,
@@ -1118,7 +1116,7 @@ in which case caches have not been used.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_TIMESTAMP_MASK</constant></entry>
-           <entry>0xe000</entry>
+           <entry>0x0000e000</entry>
            <entry>Mask for timestamp types below. To test the
            timestamp type, mask out bits not belonging to timestamp
            type by performing a logical and operation with buffer
@@ -1126,7 +1124,7 @@ in which case caches have not been used.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN</constant></entry>
-           <entry>0x0000</entry>
+           <entry>0x00000000</entry>
            <entry>Unknown timestamp type. This type is used by
            drivers before Linux 3.9 and may be either monotonic (see
            below) or realtime (wall clock). Monotonic clock has been
@@ -1139,7 +1137,7 @@ in which case caches have not been used.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC</constant></entry>
-           <entry>0x2000</entry>
+           <entry>0x00002000</entry>
            <entry>The buffer timestamp has been taken from the
            <constant>CLOCK_MONOTONIC</constant> clock. To access the
            same clock outside V4L2, use
@@ -1147,10 +1145,42 @@ in which case caches have not been used.</entry>
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant></entry>
-           <entry>0x4000</entry>
+           <entry>0x00004000</entry>
            <entry>The CAPTURE buffer timestamp has been taken from the
            corresponding OUTPUT buffer. This flag applies only to mem2mem devices.</entry>
          </row>
+         <row>
+           <entry><constant>V4L2_BUF_FLAG_TSTAMP_SRC_MASK</constant></entry>
+           <entry>0x00070000</entry>
+           <entry>Mask for timestamp sources below. The timestamp source
+           defines the point of time the timestamp is taken in relation to
+           the frame. Logical 'and' operation between the
+           <structfield>flags</structfield> field and
+           <constant>V4L2_BUF_FLAG_TSTAMP_SRC_MASK</constant> produces the
+           value of the timestamp source. Applications must set the timestamp
+           source when <structfield>type</structfield> refers to an output stream
+           and <constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant> is set.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_BUF_FLAG_TSTAMP_SRC_EOF</constant></entry>
+           <entry>0x00000000</entry>
+           <entry>End Of Frame. The buffer timestamp has been taken
+           when the last pixel of the frame has been received or the
+           last pixel of the frame has been transmitted. In practice,
+           software generated timestamps will typically be read from
+           the clock a small amount of time after the last pixel has
+           been received or transmitten, depending on the system and
+           other activity in it.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_BUF_FLAG_TSTAMP_SRC_SOE</constant></entry>
+           <entry>0x00010000</entry>
+           <entry>Start Of Exposure. The buffer timestamp has been
+           taken when the exposure of the frame has begun. This is
+           only valid for the
+           <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> buffer
+           type.</entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
@@ -1440,10 +1470,9 @@ or application, depending on data direction, must set &v4l2-buffer;
 <constant>V4L2_FIELD_BOTTOM</constant>. Any two successive fields pair
 to build a frame. If fields are successive, without any dropped fields
 between them (fields can drop individually), can be determined from
-the &v4l2-buffer; <structfield>sequence</structfield> field. Image
-sizes refer to the frame, not fields. This format cannot be selected
-when using the read/write I/O method.<!-- Where it's indistinguishable
-from V4L2_FIELD_SEQ_*. --></entry>
+the &v4l2-buffer; <structfield>sequence</structfield> field. This format
+cannot be selected when using the read/write I/O method since there
+is no way to communicate if a field was a top or bottom field.</entry>
          </row>
          <row>
            <entry><constant>V4L2_FIELD_INTERLACED_TB</constant></entry>
index c51d5a4cda091f795beba7316498431a7defcc63..fb2b5e35d665f0ab85546ce717eb2396e11c5c99 100644 (file)
       <refsect1>
        <title>Description</title>
 
-       <para>This is a multi-planar, two-plane version of the YUV 4:2:0 format.
+       <para>This is a multi-planar, two-plane version of the YUV 4:2:2 format.
 The three components are separated into two sub-images or planes.
 <constant>V4L2_PIX_FMT_NV16M</constant> differs from <constant>V4L2_PIX_FMT_NV16
 </constant> in that the two planes are non-contiguous in memory, i.e. the chroma
-plane does not necessarily immediately follows the luma plane.
+plane does not necessarily immediately follow the luma plane.
 The luminance data occupies the first plane. The Y plane has one byte per pixel.
 In the second plane there is chrominance data with alternating chroma samples.
 The CbCr plane is the same width and height, in bytes, as the Y plane.
-Each CbCr pair belongs to four pixels. For example,
+Each CbCr pair belongs to two pixels. For example,
 Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
-Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
-Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.
+Y'<subscript>00</subscript>, Y'<subscript>01</subscript>.
 <constant>V4L2_PIX_FMT_NV61M</constant> is the same as <constant>V4L2_PIX_FMT_NV16M</constant>
 except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
 
index 166c8d65e4f72ced74e3c359203f157316b62235..e1c4f8b4c0b36f35f95667b59ac3a06fd79fe328 100644 (file)
@@ -121,14 +121,14 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
            <entry>'RGB1'</entry>
            <entry></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
            <entry>r<subscript>2</subscript></entry>
            <entry>r<subscript>1</subscript></entry>
            <entry>r<subscript>0</subscript></entry>
+           <entry>g<subscript>2</subscript></entry>
+           <entry>g<subscript>1</subscript></entry>
+           <entry>g<subscript>0</subscript></entry>
+           <entry>b<subscript>1</subscript></entry>
+           <entry>b<subscript>0</subscript></entry>
          </row>
          <row id="V4L2-PIX-FMT-RGB444">
            <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
@@ -159,18 +159,18 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry>g<subscript>2</subscript></entry>
            <entry>g<subscript>1</subscript></entry>
            <entry>g<subscript>0</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>a</entry>
            <entry>b<subscript>4</subscript></entry>
            <entry>b<subscript>3</subscript></entry>
            <entry>b<subscript>2</subscript></entry>
            <entry>b<subscript>1</subscript></entry>
            <entry>b<subscript>0</subscript></entry>
+           <entry></entry>
+           <entry>a</entry>
+           <entry>r<subscript>4</subscript></entry>
+           <entry>r<subscript>3</subscript></entry>
+           <entry>r<subscript>2</subscript></entry>
+           <entry>r<subscript>1</subscript></entry>
+           <entry>r<subscript>0</subscript></entry>
            <entry>g<subscript>4</subscript></entry>
            <entry>g<subscript>3</subscript></entry>
          </row>
@@ -181,17 +181,17 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry>g<subscript>2</subscript></entry>
            <entry>g<subscript>1</subscript></entry>
            <entry>g<subscript>0</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry></entry>
            <entry>b<subscript>4</subscript></entry>
            <entry>b<subscript>3</subscript></entry>
            <entry>b<subscript>2</subscript></entry>
            <entry>b<subscript>1</subscript></entry>
            <entry>b<subscript>0</subscript></entry>
+           <entry></entry>
+           <entry>r<subscript>4</subscript></entry>
+           <entry>r<subscript>3</subscript></entry>
+           <entry>r<subscript>2</subscript></entry>
+           <entry>r<subscript>1</subscript></entry>
+           <entry>r<subscript>0</subscript></entry>
            <entry>g<subscript>5</subscript></entry>
            <entry>g<subscript>4</subscript></entry>
            <entry>g<subscript>3</subscript></entry>
@@ -201,32 +201,32 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry>'RGBQ'</entry>
            <entry></entry>
            <entry>a</entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
            <entry>r<subscript>4</subscript></entry>
            <entry>r<subscript>3</subscript></entry>
            <entry>r<subscript>2</subscript></entry>
            <entry>r<subscript>1</subscript></entry>
            <entry>r<subscript>0</subscript></entry>
-         </row>
-         <row id="V4L2-PIX-FMT-RGB565X">
-           <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
-           <entry>'RGBR'</entry>
+           <entry>g<subscript>4</subscript></entry>
+           <entry>g<subscript>3</subscript></entry>
            <entry></entry>
+           <entry>g<subscript>2</subscript></entry>
+           <entry>g<subscript>1</subscript></entry>
+           <entry>g<subscript>0</subscript></entry>
            <entry>b<subscript>4</subscript></entry>
            <entry>b<subscript>3</subscript></entry>
            <entry>b<subscript>2</subscript></entry>
            <entry>b<subscript>1</subscript></entry>
            <entry>b<subscript>0</subscript></entry>
+         </row>
+         <row id="V4L2-PIX-FMT-RGB565X">
+           <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
+           <entry>'RGBR'</entry>
+           <entry></entry>
+           <entry>r<subscript>4</subscript></entry>
+           <entry>r<subscript>3</subscript></entry>
+           <entry>r<subscript>2</subscript></entry>
+           <entry>r<subscript>1</subscript></entry>
+           <entry>r<subscript>0</subscript></entry>
            <entry>g<subscript>5</subscript></entry>
            <entry>g<subscript>4</subscript></entry>
            <entry>g<subscript>3</subscript></entry>
@@ -234,11 +234,11 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry>g<subscript>2</subscript></entry>
            <entry>g<subscript>1</subscript></entry>
            <entry>g<subscript>0</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
+           <entry>b<subscript>4</subscript></entry>
+           <entry>b<subscript>3</subscript></entry>
+           <entry>b<subscript>2</subscript></entry>
+           <entry>b<subscript>1</subscript></entry>
+           <entry>b<subscript>0</subscript></entry>
          </row>
          <row id="V4L2-PIX-FMT-BGR666">
            <entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
@@ -385,6 +385,15 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
            <entry>'RGB4'</entry>
            <entry></entry>
+           <entry>a<subscript>7</subscript></entry>
+           <entry>a<subscript>6</subscript></entry>
+           <entry>a<subscript>5</subscript></entry>
+           <entry>a<subscript>4</subscript></entry>
+           <entry>a<subscript>3</subscript></entry>
+           <entry>a<subscript>2</subscript></entry>
+           <entry>a<subscript>1</subscript></entry>
+           <entry>a<subscript>0</subscript></entry>
+           <entry></entry>
            <entry>r<subscript>7</subscript></entry>
            <entry>r<subscript>6</subscript></entry>
            <entry>r<subscript>5</subscript></entry>
@@ -411,25 +420,16 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
            <entry>b<subscript>2</subscript></entry>
            <entry>b<subscript>1</subscript></entry>
            <entry>b<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>a<subscript>7</subscript></entry>
-           <entry>a<subscript>6</subscript></entry>
-           <entry>a<subscript>5</subscript></entry>
-           <entry>a<subscript>4</subscript></entry>
-           <entry>a<subscript>3</subscript></entry>
-           <entry>a<subscript>2</subscript></entry>
-           <entry>a<subscript>1</subscript></entry>
-           <entry>a<subscript>0</subscript></entry>
          </row>
        </tbody>
       </tgroup>
     </table>
 
-    <para>Bit 7 is the most significant bit. The value of a = alpha
+    <para>Bit 7 is the most significant bit. The value of the a = alpha
 bits is undefined when reading from the driver, ignored when writing
 to the driver, except when alpha blending has been negotiated for a
 <link linkend="overlay">Video Overlay</link> or <link linkend="osd">
-Video Output Overlay</link> or when alpha component has been configured
+Video Output Overlay</link> or when the alpha component has been configured
 for a <link linkend="capture">Video Capture</link> by means of <link
 linkend="v4l2-alpha-component"> <constant>V4L2_CID_ALPHA_COMPONENT
 </constant> </link> control.</para>
@@ -512,421 +512,6 @@ image</title>
       </formalpara>
     </example>
 
-    <important>
-      <para>Drivers may interpret these formats differently.</para>
-    </important>
-
-    <para>Some RGB formats above are uncommon and were probably
-defined in error. Drivers may interpret them as in <xref
-       linkend="rgb-formats-corrected" />.</para>
-
-    <table pgwide="1" frame="none" id="rgb-formats-corrected">
-      <title>Packed RGB Image Formats (corrected)</title>
-      <tgroup cols="37" align="center">
-       <colspec colname="id" align="left" />
-       <colspec colname="fourcc" />
-       <colspec colname="bit" />
-
-       <colspec colnum="4" colname="b07" align="center" />
-       <colspec colnum="5" colname="b06" align="center" />
-       <colspec colnum="6" colname="b05" align="center" />
-       <colspec colnum="7" colname="b04" align="center" />
-       <colspec colnum="8" colname="b03" align="center" />
-       <colspec colnum="9" colname="b02" align="center" />
-       <colspec colnum="10" colname="b01" align="center" />
-       <colspec colnum="11" colname="b00" align="center" />
-
-       <colspec colnum="13" colname="b17" align="center" />
-       <colspec colnum="14" colname="b16" align="center" />
-       <colspec colnum="15" colname="b15" align="center" />
-       <colspec colnum="16" colname="b14" align="center" />
-       <colspec colnum="17" colname="b13" align="center" />
-       <colspec colnum="18" colname="b12" align="center" />
-       <colspec colnum="19" colname="b11" align="center" />
-       <colspec colnum="20" colname="b10" align="center" />
-
-       <colspec colnum="22" colname="b27" align="center" />
-       <colspec colnum="23" colname="b26" align="center" />
-       <colspec colnum="24" colname="b25" align="center" />
-       <colspec colnum="25" colname="b24" align="center" />
-       <colspec colnum="26" colname="b23" align="center" />
-       <colspec colnum="27" colname="b22" align="center" />
-       <colspec colnum="28" colname="b21" align="center" />
-       <colspec colnum="29" colname="b20" align="center" />
-
-       <colspec colnum="31" colname="b37" align="center" />
-       <colspec colnum="32" colname="b36" align="center" />
-       <colspec colnum="33" colname="b35" align="center" />
-       <colspec colnum="34" colname="b34" align="center" />
-       <colspec colnum="35" colname="b33" align="center" />
-       <colspec colnum="36" colname="b32" align="center" />
-       <colspec colnum="37" colname="b31" align="center" />
-       <colspec colnum="38" colname="b30" align="center" />
-
-       <spanspec namest="b07" nameend="b00" spanname="b0" />
-       <spanspec namest="b17" nameend="b10" spanname="b1" />
-       <spanspec namest="b27" nameend="b20" spanname="b2" />
-       <spanspec namest="b37" nameend="b30" spanname="b3" />
-       <thead>
-         <row>
-           <entry>Identifier</entry>
-           <entry>Code</entry>
-           <entry>&nbsp;</entry>
-           <entry spanname="b0">Byte&nbsp;0 in memory</entry>
-           <entry spanname="b1">Byte&nbsp;1</entry>
-           <entry spanname="b2">Byte&nbsp;2</entry>
-           <entry spanname="b3">Byte&nbsp;3</entry>
-         </row>
-         <row>
-           <entry>&nbsp;</entry>
-           <entry>&nbsp;</entry>
-           <entry>Bit</entry>
-           <entry>7</entry>
-           <entry>6</entry>
-           <entry>5</entry>
-           <entry>4</entry>
-           <entry>3</entry>
-           <entry>2</entry>
-           <entry>1</entry>
-           <entry>0</entry>
-           <entry>&nbsp;</entry>
-           <entry>7</entry>
-           <entry>6</entry>
-           <entry>5</entry>
-           <entry>4</entry>
-           <entry>3</entry>
-           <entry>2</entry>
-           <entry>1</entry>
-           <entry>0</entry>
-           <entry>&nbsp;</entry>
-           <entry>7</entry>
-           <entry>6</entry>
-           <entry>5</entry>
-           <entry>4</entry>
-           <entry>3</entry>
-           <entry>2</entry>
-           <entry>1</entry>
-           <entry>0</entry>
-           <entry>&nbsp;</entry>
-           <entry>7</entry>
-           <entry>6</entry>
-           <entry>5</entry>
-           <entry>4</entry>
-           <entry>3</entry>
-           <entry>2</entry>
-           <entry>1</entry>
-           <entry>0</entry>
-         </row>
-       </thead>
-       <tbody valign="top">
-         <row><!-- id="V4L2-PIX-FMT-RGB332" -->
-           <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
-           <entry>'RGB1'</entry>
-           <entry></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB444" -->
-           <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
-           <entry>'R444'</entry>
-           <entry></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>a<subscript>3</subscript></entry>
-           <entry>a<subscript>2</subscript></entry>
-           <entry>a<subscript>1</subscript></entry>
-           <entry>a<subscript>0</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB555" -->
-           <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
-           <entry>'RGBO'</entry>
-           <entry></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>a</entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB565" -->
-           <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
-           <entry>'RGBP'</entry>
-           <entry></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB555X" -->
-           <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
-           <entry>'RGBQ'</entry>
-           <entry></entry>
-           <entry>a</entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB565X" -->
-           <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
-           <entry>'RGBR'</entry>
-           <entry></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-BGR666" -->
-           <entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
-           <entry>'BGRH'</entry>
-           <entry></entry>
-           <entry>b<subscript>5</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry>r<subscript>5</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-           <entry></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-BGR24" -->
-           <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
-           <entry>'BGR3'</entry>
-           <entry></entry>
-           <entry>b<subscript>7</subscript></entry>
-           <entry>b<subscript>6</subscript></entry>
-           <entry>b<subscript>5</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>7</subscript></entry>
-           <entry>g<subscript>6</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>r<subscript>7</subscript></entry>
-           <entry>r<subscript>6</subscript></entry>
-           <entry>r<subscript>5</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB24" -->
-           <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
-           <entry>'RGB3'</entry>
-           <entry></entry>
-           <entry>r<subscript>7</subscript></entry>
-           <entry>r<subscript>6</subscript></entry>
-           <entry>r<subscript>5</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>7</subscript></entry>
-           <entry>g<subscript>6</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>b<subscript>7</subscript></entry>
-           <entry>b<subscript>6</subscript></entry>
-           <entry>b<subscript>5</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-BGR32" -->
-           <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
-           <entry>'BGR4'</entry>
-           <entry></entry>
-           <entry>b<subscript>7</subscript></entry>
-           <entry>b<subscript>6</subscript></entry>
-           <entry>b<subscript>5</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>7</subscript></entry>
-           <entry>g<subscript>6</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>r<subscript>7</subscript></entry>
-           <entry>r<subscript>6</subscript></entry>
-           <entry>r<subscript>5</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>a<subscript>7</subscript></entry>
-           <entry>a<subscript>6</subscript></entry>
-           <entry>a<subscript>5</subscript></entry>
-           <entry>a<subscript>4</subscript></entry>
-           <entry>a<subscript>3</subscript></entry>
-           <entry>a<subscript>2</subscript></entry>
-           <entry>a<subscript>1</subscript></entry>
-           <entry>a<subscript>0</subscript></entry>
-         </row>
-         <row><!-- id="V4L2-PIX-FMT-RGB32" -->
-           <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
-           <entry>'RGB4'</entry>
-           <entry></entry>
-           <entry>a<subscript>7</subscript></entry>
-           <entry>a<subscript>6</subscript></entry>
-           <entry>a<subscript>5</subscript></entry>
-           <entry>a<subscript>4</subscript></entry>
-           <entry>a<subscript>3</subscript></entry>
-           <entry>a<subscript>2</subscript></entry>
-           <entry>a<subscript>1</subscript></entry>
-           <entry>a<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>r<subscript>7</subscript></entry>
-           <entry>r<subscript>6</subscript></entry>
-           <entry>r<subscript>5</subscript></entry>
-           <entry>r<subscript>4</subscript></entry>
-           <entry>r<subscript>3</subscript></entry>
-           <entry>r<subscript>2</subscript></entry>
-           <entry>r<subscript>1</subscript></entry>
-           <entry>r<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>g<subscript>7</subscript></entry>
-           <entry>g<subscript>6</subscript></entry>
-           <entry>g<subscript>5</subscript></entry>
-           <entry>g<subscript>4</subscript></entry>
-           <entry>g<subscript>3</subscript></entry>
-           <entry>g<subscript>2</subscript></entry>
-           <entry>g<subscript>1</subscript></entry>
-           <entry>g<subscript>0</subscript></entry>
-           <entry></entry>
-           <entry>b<subscript>7</subscript></entry>
-           <entry>b<subscript>6</subscript></entry>
-           <entry>b<subscript>5</subscript></entry>
-           <entry>b<subscript>4</subscript></entry>
-           <entry>b<subscript>3</subscript></entry>
-           <entry>b<subscript>2</subscript></entry>
-           <entry>b<subscript>1</subscript></entry>
-           <entry>b<subscript>0</subscript></entry>
-         </row>
-       </tbody>
-      </tgroup>
-    </table>
-
     <para>A test utility to determine which RGB formats a driver
 actually supports is available from the LinuxTV v4l-dvb repository.
 See &v4l-dvb; for access instructions.</para>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sdr-cu08.xml b/Documentation/DocBook/media/v4l/pixfmt-sdr-cu08.xml
new file mode 100644 (file)
index 0000000..2d80104
--- /dev/null
@@ -0,0 +1,44 @@
+<refentry id="V4L2-SDR-FMT-CU08">
+  <refmeta>
+    <refentrytitle>V4L2_SDR_FMT_CU8 ('CU08')</refentrytitle>
+    &manvol;
+  </refmeta>
+    <refnamediv>
+      <refname>
+        <constant>V4L2_SDR_FMT_CU8</constant>
+      </refname>
+      <refpurpose>Complex unsigned 8-bit IQ sample</refpurpose>
+    </refnamediv>
+    <refsect1>
+      <title>Description</title>
+      <para>
+This format contains sequence of complex number samples. Each complex number
+consist two parts, called In-phase and Quadrature (IQ). Both I and Q are
+represented as a 8 bit unsigned number. I value comes first and Q value after
+that.
+      </para>
+    <example>
+      <title><constant>V4L2_SDR_FMT_CU8</constant> 1 sample</title>
+      <formalpara>
+        <title>Byte Order.</title>
+        <para>Each cell is one byte.
+          <informaltable frame="none">
+            <tgroup cols="2" align="center">
+              <colspec align="left" colwidth="2*" />
+              <tbody valign="top">
+                <row>
+                  <entry>start&nbsp;+&nbsp;0:</entry>
+                  <entry>I'<subscript>0</subscript></entry>
+                </row>
+                <row>
+                  <entry>start&nbsp;+&nbsp;1:</entry>
+                  <entry>Q'<subscript>0</subscript></entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </informaltable>
+        </para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sdr-cu16le.xml b/Documentation/DocBook/media/v4l/pixfmt-sdr-cu16le.xml
new file mode 100644 (file)
index 0000000..26288ff
--- /dev/null
@@ -0,0 +1,46 @@
+<refentry id="V4L2-SDR-FMT-CU16LE">
+  <refmeta>
+    <refentrytitle>V4L2_SDR_FMT_CU16LE ('CU16')</refentrytitle>
+    &manvol;
+  </refmeta>
+    <refnamediv>
+      <refname>
+        <constant>V4L2_SDR_FMT_CU16LE</constant>
+      </refname>
+      <refpurpose>Complex unsigned 16-bit little endian IQ sample</refpurpose>
+    </refnamediv>
+    <refsect1>
+      <title>Description</title>
+      <para>
+This format contains sequence of complex number samples. Each complex number
+consist two parts, called In-phase and Quadrature (IQ). Both I and Q are
+represented as a 16 bit unsigned little endian number. I value comes first
+and Q value after that.
+      </para>
+    <example>
+      <title><constant>V4L2_SDR_FMT_CU16LE</constant> 1 sample</title>
+      <formalpara>
+        <title>Byte Order.</title>
+        <para>Each cell is one byte.
+          <informaltable frame="none">
+            <tgroup cols="3" align="center">
+              <colspec align="left" colwidth="2*" />
+              <tbody valign="top">
+                <row>
+                  <entry>start&nbsp;+&nbsp;0:</entry>
+                  <entry>I'<subscript>0[7:0]</subscript></entry>
+                  <entry>I'<subscript>0[15:8]</subscript></entry>
+                </row>
+                <row>
+                  <entry>start&nbsp;+&nbsp;2:</entry>
+                  <entry>Q'<subscript>0[7:0]</subscript></entry>
+                  <entry>Q'<subscript>0[15:8]</subscript></entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </informaltable>
+        </para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
index 72d72bd67d0a9eb00836b5495a0b9e6c4821d5f3..ea514d6075c505a7795891d2f218b5a6e5bef6e9 100644 (file)
@@ -25,7 +25,12 @@ capturing and output, for overlay frame buffer formats see also
        <row>
          <entry>__u32</entry>
          <entry><structfield>height</structfield></entry>
-         <entry>Image height in pixels.</entry>
+         <entry>Image height in pixels. If <structfield>field</structfield> is
+         one of <constant>V4L2_FIELD_TOP</constant>, <constant>V4L2_FIELD_BOTTOM</constant>
+         or <constant>V4L2_FIELD_ALTERNATE</constant> then height refers to the
+         number of lines in the field, otherwise it refers to the number of
+         lines in the frame (which is twice the field height for interlaced
+         formats).</entry>
        </row>
        <row>
          <entry spanname="hspan">Applications set these fields to
@@ -54,7 +59,7 @@ linkend="reserved-formats" /></entry>
 can request to capture or output only the top or bottom field, or both
 fields interlaced or sequentially stored in one buffer or alternating
 in separate buffers. Drivers return the actual field order selected.
-For details see <xref linkend="field-order" />.</entry>
+For more details on fields see <xref linkend="field-order" />.</entry>
        </row>
        <row>
          <entry>__u32</entry>
@@ -81,7 +86,10 @@ plane and is divided by the same factor as the
 example the Cb and Cr planes of a YUV 4:2:0 image have half as many
 padding bytes following each line as the Y plane. To avoid ambiguities
 drivers must return a <structfield>bytesperline</structfield> value
-rounded up to a multiple of the scale factor.</para></entry>
+rounded up to a multiple of the scale factor.</para>
+<para>For compressed formats the <structfield>bytesperline</structfield>
+value makes no sense. Applications and drivers must set this to 0 in
+that case.</para></entry>
        </row>
        <row>
          <entry>__u32</entry>
@@ -97,7 +105,8 @@ hold an image.</entry>
          <entry>&v4l2-colorspace;</entry>
          <entry><structfield>colorspace</structfield></entry>
          <entry>This information supplements the
-<structfield>pixelformat</structfield> and must be set by the driver,
+<structfield>pixelformat</structfield> and must be set by the driver for
+capture streams and by the application for output streams,
 see <xref linkend="colorspaces" />.</entry>
        </row>
        <row>
@@ -135,7 +144,7 @@ set this field to zero.</entry>
           <entry>__u16</entry>
           <entry><structfield>bytesperline</structfield></entry>
           <entry>Distance in bytes between the leftmost pixels in two adjacent
-            lines.</entry>
+            lines. See &v4l2-pix-format;.</entry>
         </row>
         <row>
           <entry>__u16</entry>
@@ -154,12 +163,12 @@ set this field to zero.</entry>
         <row>
           <entry>__u32</entry>
           <entry><structfield>width</structfield></entry>
-          <entry>Image width in pixels.</entry>
+          <entry>Image width in pixels. See &v4l2-pix-format;.</entry>
         </row>
         <row>
           <entry>__u32</entry>
           <entry><structfield>height</structfield></entry>
-          <entry>Image height in pixels.</entry>
+          <entry>Image height in pixels. See &v4l2-pix-format;.</entry>
         </row>
         <row>
           <entry>__u32</entry>
@@ -811,6 +820,17 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
     </table>
   </section>
 
+  <section id="sdr-formats">
+    <title>SDR Formats</title>
+
+    <para>These formats are used for <link linkend="sdr">SDR Capture</link>
+interface only.</para>
+
+    &sub-sdr-cu08;
+    &sub-sdr-cu16le;
+
+  </section>
+
   <section id="pixfmt-reserved">
     <title>Reserved Format Identifiers</title>
 
index 160e464d44b7588e963313c77730d4f28db6bd0c..5124a6c4daa8a359fa3a3f9aa7a83df882c85402 100644 (file)
+<partinfo>
+<authorgroup>
+<author>
+<firstname>Mauro</firstname>
+<surname>Chehab</surname>
+<othername role="mi">Carvalho</othername>
+<affiliation><address><email>m.chehab@samsung.com</email></address></affiliation>
+<contrib>Initial version.</contrib>
+</author>
+</authorgroup>
+<copyright>
+       <year>2009-2014</year>
+        <holder>Mauro Carvalho Chehab</holder>
+</copyright>
+
+<revhistory>
+<!-- Put document revisions here, newest first. -->
+<revision>
+<revnumber>3.15</revnumber>
+<date>2014-02-06</date>
+<authorinitials>mcc</authorinitials>
+<revremark>Added the interface description and the RC sysfs class description.</revremark>
+</revision>
+<revision>
+<revnumber>1.0</revnumber>
+<date>2009-09-06</date>
+<authorinitials>mcc</authorinitials>
+<revremark>Initial revision</revremark>
+</revision>
+</revhistory>
+</partinfo>
+
+ <title>Remote Controller API</title>
+ <chapter id="remote_controllers">
+
 <title>Remote Controllers</title>
+
 <section id="Remote_controllers_Intro">
 <title>Introduction</title>
 
 <para>Currently, most analog and digital devices have a Infrared input for remote controllers. Each
 manufacturer has their own type of control. It is not rare for the same manufacturer to ship different
 types of controls, depending on the device.</para>
+<para>A Remote Controller interface is mapped as a normal evdev/input interface, just like a keyboard or a mouse.
+So, it uses all ioctls already defined for any other input devices.</para>
+<para>However, remove controllers are more flexible than a normal input device, as the IR
+receiver (and/or transmitter) can be used in conjunction with a wide variety of different IR remotes.</para>
+<para>In order to allow flexibility, the Remote Controller subsystem allows controlling the
+RC-specific attributes via <link linkend="remote_controllers_sysfs_nodes">the sysfs class nodes</link>.</para>
+</section>
+
+<section id="remote_controllers_sysfs_nodes">
+<title>Remote Controller's sysfs nodes</title>
+<para>As defined at <constant>Documentation/ABI/testing/sysfs-class-rc</constant>, those are the sysfs nodes that control the Remote Controllers:</para>
+
+<section id="sys_class_rc">
+<title>/sys/class/rc/</title>
+<para>The <constant>/sys/class/rc/</constant> class sub-directory belongs to the Remote Controller
+core and provides a sysfs interface for configuring infrared remote controller receivers.
+</para>
+
+</section>
+<section id="sys_class_rc_rcN">
+<title>/sys/class/rc/rcN/</title>
+<para>A <constant>/sys/class/rc/rcN</constant> directory is created for each remote
+  control receiver device where N is the number of the receiver.</para>
+
+</section>
+<section id="sys_class_rc_rcN_protocols">
+<title>/sys/class/rc/rcN/protocols</title>
+<para>Reading this file returns a list of available protocols, something like:</para>
+<para><constant>rc5 [rc6] nec jvc [sony]</constant></para>
+<para>Enabled protocols are shown in [] brackets.</para>
+<para>Writing "+proto" will add a protocol to the list of enabled protocols.</para>
+<para>Writing "-proto" will remove a protocol from the list of enabled protocols.</para>
+<para>Writing "proto" will enable only "proto".</para>
+<para>Writing "none" will disable all protocols.</para>
+<para>Write fails with EINVAL if an invalid protocol combination or unknown protocol name is used.</para>
+
+</section>
+<section id="sys_class_rc_rcN_filter">
+<title>/sys/class/rc/rcN/filter</title>
+<para>Sets the scancode filter expected value.</para>
+<para>Use in combination with <constant>/sys/class/rc/rcN/filter_mask</constant> to set the
+expected value of the bits set in the filter mask.
+If the hardware supports it then scancodes which do not match
+the filter will be ignored. Otherwise the write will fail with
+an error.</para>
+<para>This value may be reset to 0 if the current protocol is altered.</para>
+
+</section>
+<section id="sys_class_rc_rcN_filter_mask">
+<title>/sys/class/rc/rcN/filter_mask</title>
+<para>Sets the scancode filter mask of bits to compare.
+Use in combination with <constant>/sys/class/rc/rcN/filter</constant> to set the bits
+of the scancode which should be compared against the expected
+value. A value of 0 disables the filter to allow all valid
+scancodes to be processed.</para>
+<para>If the hardware supports it then scancodes which do not match
+the filter will be ignored. Otherwise the write will fail with
+an error.</para>
+<para>This value may be reset to 0 if the current protocol is altered.</para>
+
+</section>
+<section id="sys_class_rc_rcN_wakeup_protocols">
+<title>/sys/class/rc/rcN/wakeup_protocols</title>
+<para>Reading this file returns a list of available protocols to use for the
+wakeup filter, something like:</para>
+<para><constant>rc5 rc6 nec jvc [sony]</constant></para>
+<para>The enabled wakeup protocol is shown in [] brackets.</para>
+<para>Writing "+proto" will add a protocol to the list of enabled wakeup
+protocols.</para>
+<para>Writing "-proto" will remove a protocol from the list of enabled wakeup
+protocols.</para>
+<para>Writing "proto" will use "proto" for wakeup events.</para>
+<para>Writing "none" will disable wakeup.</para>
+<para>Write fails with EINVAL if an invalid protocol combination or unknown
+protocol name is used, or if wakeup is not supported by the hardware.</para>
+
+</section>
+<section id="sys_class_rc_rcN_wakeup_filter">
+<title>/sys/class/rc/rcN/wakeup_filter</title>
+<para>Sets the scancode wakeup filter expected value.
+Use in combination with <constant>/sys/class/rc/rcN/wakeup_filter_mask</constant> to
+set the expected value of the bits set in the wakeup filter mask
+to trigger a system wake event.</para>
+<para>If the hardware supports it and wakeup_filter_mask is not 0 then
+scancodes which match the filter will wake the system from e.g.
+suspend to RAM or power off.
+Otherwise the write will fail with an error.</para>
+<para>This value may be reset to 0 if the wakeup protocol is altered.</para>
+
+</section>
+<section id="sys_class_rc_rcN_wakeup_filter_mask">
+<title>/sys/class/rc/rcN/wakeup_filter_mask</title>
+<para>Sets the scancode wakeup filter mask of bits to compare.
+Use in combination with <constant>/sys/class/rc/rcN/wakeup_filter</constant> to set
+the bits of the scancode which should be compared against the
+expected value to trigger a system wake event.</para>
+<para>If the hardware supports it and wakeup_filter_mask is not 0 then
+scancodes which match the filter will wake the system from e.g.
+suspend to RAM or power off.
+Otherwise the write will fail with an error.</para>
+<para>This value may be reset to 0 if the wakeup protocol is altered.</para>
+</section>
+</section>
+
+<section id="Remote_controllers_tables">
+<title>Remote controller tables</title>
 <para>Unfortunately, for several years, there was no effort to create uniform IR keycodes for
 different devices.  This caused the same IR keyname to be mapped completely differently on
 different IR devices. This resulted that the same IR keyname to be mapped completely different on
@@ -175,3 +317,4 @@ keymapping.</para>
 </section>
 
 &sub-lirc_device_interface;
+</chapter>
index 74b7f27af71a71e4f17d718a590a013e1b5908d4..b445161b912c4329079bada5d11f1e1ab3ceede4 100644 (file)
@@ -70,7 +70,7 @@ MPEG stream embedded, sliced VBI data format in this specification.
 Remote Controller chapter.</contrib>
        <affiliation>
          <address>
-           <email>mchehab@redhat.com</email>
+           <email>m.chehab@samsung.com</email>
          </address>
        </affiliation>
       </author>
@@ -107,6 +107,16 @@ Remote Controller chapter.</contrib>
          </address>
        </affiliation>
       </author>
+      <author>
+       <firstname>Antti</firstname>
+       <surname>Palosaari</surname>
+       <contrib>SDR API.</contrib>
+       <affiliation>
+         <address>
+           <email>crope@iki.fi</email>
+         </address>
+       </affiliation>
+      </author>
     </authorgroup>
 
     <copyright>
@@ -125,6 +135,7 @@ Remote Controller chapter.</contrib>
       <year>2011</year>
       <year>2012</year>
       <year>2013</year>
+      <year>2014</year>
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
 Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
        Pawel Osciak</holder>
@@ -140,6 +151,16 @@ structs, ioctls) must be noted in more detail in the history chapter
 (compat.xml), along with the possible impact on existing drivers and
 applications. -->
 
+      <revision>
+       <revnumber>3.15</revnumber>
+       <date>2014-02-03</date>
+       <authorinitials>hv, ap</authorinitials>
+       <revremark>Update several sections of "Common API Elements": "Opening and Closing Devices"
+"Querying Capabilities", "Application Priority", "Video Inputs and Outputs", "Audio Inputs and Outputs"
+"Tuners and Modulators", "Video Standards" and "Digital Video (DV) Timings". Added SDR API.
+       </revremark>
+      </revision>
+
       <revision>
        <revnumber>3.14</revnumber>
        <date>2013-11-25</date>
@@ -537,6 +558,7 @@ and discussions on the V4L mailing list.</revremark>
     <section id="ttx"> &sub-dev-teletext; </section>
     <section id="radio"> &sub-dev-radio; </section>
     <section id="rds"> &sub-dev-rds; </section>
+    <section id="sdr"> &sub-dev-sdr; </section>
     <section id="event"> &sub-dev-event; </section>
     <section id="subdev"> &sub-dev-subdev; </section>
   </chapter>
@@ -585,6 +607,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-g-crop;
     &sub-g-ctrl;
     &sub-g-dv-timings;
+    &sub-g-edid;
     &sub-g-enc-index;
     &sub-g-ext-ctrls;
     &sub-g-fbuf;
@@ -616,7 +639,6 @@ and discussions on the V4L mailing list.</revremark>
     &sub-subdev-enum-frame-size;
     &sub-subdev-enum-mbus-code;
     &sub-subdev-g-crop;
-    &sub-subdev-g-edid;
     &sub-subdev-g-fmt;
     &sub-subdev-g-frame-interval;
     &sub-subdev-g-selection;
index 6541ba0175eddbe1078c47778a646c3bb7dd0f1b..4e8ea65f7282257f3f72d95de5f1439d2b3023e2 100644 (file)
@@ -100,7 +100,7 @@ See <xref linkend="v4l2-tuner-type" /></entry>
            <entry><structfield>capability</structfield></entry>
            <entry spanname="hspan">The tuner/modulator capability flags for
 this frequency band, see <xref linkend="tuner-capability" />. The <constant>V4L2_TUNER_CAP_LOW</constant>
-capability must be the same for all frequency bands of the selected tuner/modulator.
+or <constant>V4L2_TUNER_CAP_1HZ</constant> capability must be the same for all frequency bands of the selected tuner/modulator.
 So either all bands have that capability set, or none of them have that capability.</entry>
          </row>
          <row>
@@ -109,7 +109,8 @@ So either all bands have that capability set, or none of them have that capabili
            <entry spanname="hspan">The lowest tunable frequency in
 units of 62.5 kHz, or if the <structfield>capability</structfield>
 flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz, for this frequency band.</entry>
+Hz, for this frequency band. A 1 Hz unit is used when the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
          </row>
          <row>
            <entry>__u32</entry>
@@ -117,7 +118,8 @@ Hz, for this frequency band.</entry>
            <entry spanname="hspan">The highest tunable frequency in
 units of 62.5 kHz, or if the <structfield>capability</structfield>
 flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz, for this frequency band.</entry>
+Hz, for this frequency band. A 1 Hz unit is used when the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
          </row>
          <row>
            <entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-edid.xml b/Documentation/DocBook/media/v4l/vidioc-g-edid.xml
new file mode 100644 (file)
index 0000000..ce4563b
--- /dev/null
@@ -0,0 +1,162 @@
+<refentry id="vidioc-g-edid">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_EDID, VIDIOC_S_EDID</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_EDID</refname>
+    <refname>VIDIOC_S_EDID</refname>
+    <refpurpose>Get or set the EDID of a video receiver/transmitter</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>struct v4l2_edid *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>const struct v4l2_edid *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_G_EDID, VIDIOC_S_EDID</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+    <para>These ioctls can be used to get or set an EDID associated with an input
+    from a receiver or an output of a transmitter device. They can be
+    used with subdevice nodes (/dev/v4l-subdevX) or with video nodes (/dev/videoX).</para>
+
+    <para>When used with video nodes the <structfield>pad</structfield> field represents the
+    input (for video capture devices) or output (for video output devices) index as
+    is returned by &VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; respectively. When used
+    with subdevice nodes the <structfield>pad</structfield> field represents the
+    input or output pad of the subdevice. If there is no EDID support for the given
+    <structfield>pad</structfield> value, then the &EINVAL; will be returned.</para>
+
+    <para>To get the EDID data the application has to fill in the <structfield>pad</structfield>,
+    <structfield>start_block</structfield>, <structfield>blocks</structfield> and <structfield>edid</structfield>
+    fields and call <constant>VIDIOC_G_EDID</constant>. The current EDID from block
+    <structfield>start_block</structfield> and of size <structfield>blocks</structfield>
+    will be placed in the memory <structfield>edid</structfield> points to. The <structfield>edid</structfield>
+    pointer must point to memory at least <structfield>blocks</structfield>&nbsp;*&nbsp;128 bytes
+    large (the size of one block is 128 bytes).</para>
+
+    <para>If there are fewer blocks than specified, then the driver will set <structfield>blocks</structfield>
+    to the actual number of blocks. If there are no EDID blocks available at all, then the error code
+    ENODATA is set.</para>
+
+    <para>If blocks have to be retrieved from the sink, then this call will block until they
+    have been read.</para>
+
+    <para>To set the EDID blocks of a receiver the application has to fill in the <structfield>pad</structfield>,
+    <structfield>blocks</structfield> and <structfield>edid</structfield> fields and set
+    <structfield>start_block</structfield> to 0. It is not possible to set part of an EDID,
+    it is always all or nothing. Setting the EDID data is only valid for receivers as it makes
+    no sense for a transmitter.</para>
+
+    <para>The driver assumes that the full EDID is passed in. If there are more EDID blocks than
+    the hardware can handle then the EDID is not written, but instead the error code E2BIG is set
+    and <structfield>blocks</structfield> is set to the maximum that the hardware supports.
+    If <structfield>start_block</structfield> is any
+    value other than 0 then the error code EINVAL is set.</para>
+
+    <para>To disable an EDID you set <structfield>blocks</structfield> to 0. Depending on the
+    hardware this will drive the hotplug pin low and/or block the source from reading the EDID
+    data in some way. In any case, the end result is the same: the EDID is no longer available.
+    </para>
+
+    <table pgwide="1" frame="none" id="v4l2-edid">
+      <title>struct <structname>v4l2_edid</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>pad</structfield></entry>
+           <entry>Pad for which to get/set the EDID blocks. When used with a video device
+           node the pad represents the input or output index as returned by
+           &VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; respectively.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>start_block</structfield></entry>
+           <entry>Read the EDID from starting with this block. Must be 0 when setting
+           the EDID.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>blocks</structfield></entry>
+           <entry>The number of blocks to get or set. Must be less or equal to 256 (the
+           maximum number of blocks as defined by the standard). When you set the EDID and
+           <structfield>blocks</structfield> is 0, then the EDID is disabled or erased.</entry>
+         </row>
+         <row>
+           <entry>__u8&nbsp;*</entry>
+           <entry><structfield>edid</structfield></entry>
+           <entry>Pointer to memory that contains the EDID. The minimum size is
+           <structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved</structfield>[5]</entry>
+           <entry>Reserved for future extensions. Applications and drivers must
+           set the array to zero.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>ENODATA</errorcode></term>
+       <listitem>
+         <para>The EDID data is not available.</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><errorcode>E2BIG</errorcode></term>
+       <listitem>
+         <para>The EDID data you provided is more than the hardware can handle.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
index b3bb9575b2e014dc6e090b8a1b9b639d9bfd9a00..e9f6735c08233bc360339bf0171504f87d652091 100644 (file)
@@ -327,7 +327,12 @@ These controls are described in <xref
 These controls are described in <xref
                linkend="fm-rx-controls" />.</entry>
          </row>
-
+         <row>
+           <entry><constant>V4L2_CTRL_CLASS_RF_TUNER</constant></entry>
+           <entry>0xa20000</entry>
+           <entry>The class containing RF tuner controls.
+These controls are described in <xref linkend="rf-tuner-controls" />.</entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
index ee8f56e1bac0924a1cffc27462743ad24aa62088..4fe19a7a9a31efa3b2628e683853ef295ccf7932 100644 (file)
@@ -169,6 +169,13 @@ capture and output devices.</entry>
            <entry>Sliced VBI capture or output parameters. See
 <xref linkend="sliced" /> for details. Used by sliced VBI
 capture and output devices.</entry>
+         </row>
+         <row>
+           <entry></entry>
+           <entry>&v4l2-sdr-format;</entry>
+           <entry><structfield>sdr</structfield></entry>
+           <entry>Definition of a data format, see
+<xref linkend="pixfmt" />, used by SDR capture devices.</entry>
          </row>
          <row>
            <entry></entry>
index c7a1c462e7243fe665dab4b5e4fbcb762765f874..d1034fb61d15f1ad5bb945d34cbcffed37e9599c 100644 (file)
@@ -109,9 +109,10 @@ See <xref linkend="v4l2-tuner-type" /></entry>
            <entry>__u32</entry>
            <entry><structfield>frequency</structfield></entry>
            <entry>Tuning frequency in units of 62.5 kHz, or if the
-&v4l2-tuner; or &v4l2-modulator; <structfield>capabilities</structfield> flag
+&v4l2-tuner; or &v4l2-modulator; <structfield>capability</structfield> flag
 <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz.</entry>
+Hz. A 1 Hz unit is used when the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
          </row>
          <row>
            <entry>__u32</entry>
index 7f4ac7e41fa8765d709794a130a2f11091b7c98a..7068b599a00dd331c39c14a2f52c79d1c21708f8 100644 (file)
@@ -113,7 +113,8 @@ change for example with the current video standard.</entry>
            <entry>The lowest tunable frequency in units of 62.5
 KHz, or if the <structfield>capability</structfield> flag
 <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz.</entry>
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.</entry>
          </row>
          <row>
            <entry>__u32</entry>
@@ -121,7 +122,8 @@ Hz.</entry>
            <entry>The highest tunable frequency in units of 62.5
 KHz, or if the <structfield>capability</structfield> flag
 <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz.</entry>
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.</entry>
          </row>
          <row>
            <entry>__u32</entry>
index 6cc82010c7366921792eb4204655bfc92675d0bc..b0d865933da69247aaf85a569d1de4cc1a28acf4 100644 (file)
@@ -134,7 +134,9 @@ the structure refers to a radio tuner the
            <entry spanname="hspan">The lowest tunable frequency in
 units of 62.5 kHz, or if the <structfield>capability</structfield>
 flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz. If multiple frequency bands are supported, then
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.
+If multiple frequency bands are supported, then
 <structfield>rangelow</structfield> is the lowest frequency
 of all the frequency bands.</entry>
          </row>
@@ -144,7 +146,9 @@ of all the frequency bands.</entry>
            <entry spanname="hspan">The highest tunable frequency in
 units of 62.5 kHz, or if the <structfield>capability</structfield>
 flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz. If multiple frequency bands are supported, then
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.
+If multiple frequency bands are supported, then
 <structfield>rangehigh</structfield> is the highest frequency
 of all the frequency bands.</entry>
          </row>
@@ -270,7 +274,7 @@ applications must set the array to zero.</entry>
            <entry><constant>V4L2_TUNER_CAP_LOW</constant></entry>
            <entry>0x0001</entry>
            <entry>When set, tuning frequencies are expressed in units of
-62.5&nbsp;Hz, otherwise in units of 62.5&nbsp;kHz.</entry>
+62.5 Hz instead of 62.5 kHz.</entry>
          </row>
          <row>
            <entry><constant>V4L2_TUNER_CAP_NORM</constant></entry>
@@ -360,6 +364,11 @@ radio tuners.</entry>
        <entry>The range to search when using the hardware seek functionality
        is programmable, see &VIDIOC-S-HW-FREQ-SEEK; for details.</entry>
          </row>
+         <row>
+       <entry><constant>V4L2_TUNER_CAP_1HZ</constant></entry>
+       <entry>0x1000</entry>
+       <entry>When set, tuning frequencies are expressed in units of 1 Hz instead of 62.5 kHz.</entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
index d5a3c97b206a431d9b5d7a969a56d877aee83558..370d49d6fb64e80077f833ff428cd4c33804af74 100644 (file)
@@ -294,6 +294,12 @@ interface. For more information on audio inputs and outputs see <xref
 emit RF-modulated video/audio signals. For more information about
 modulator programming see
 <xref linkend="tuner" />.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_CAP_SDR_CAPTURE</constant></entry>
+           <entry>0x00100000</entry>
+           <entry>The device supports the
+<link linkend="sdr">SDR Capture</link> interface.</entry>
          </row>
          <row>
            <entry><constant>V4L2_CAP_READWRITE</constant></entry>
index 5b379e752194a2b096ce512e11facde121c8aabc..a5fc4c4880f3366767d9ac56483dd71176ac6df6 100644 (file)
@@ -121,7 +121,9 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
            <entry>If non-zero, the lowest tunable frequency of the band to
 search in units of 62.5 kHz, or if the &v4l2-tuner;
 <structfield>capability</structfield> field has the
-<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz.
+<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz or if the &v4l2-tuner;
+<structfield>capability</structfield> field has the
+<constant>V4L2_TUNER_CAP_1HZ</constant> flag set, in units of 1 Hz.
 If <structfield>rangelow</structfield> is zero a reasonable default value
 is used.</entry>
          </row>
@@ -131,7 +133,9 @@ is used.</entry>
            <entry>If non-zero, the highest tunable frequency of the band to
 search in units of 62.5 kHz, or if the &v4l2-tuner;
 <structfield>capability</structfield> field has the
-<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz.
+<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz or if the &v4l2-tuner;
+<structfield>capability</structfield> field has the
+<constant>V4L2_TUNER_CAP_1HZ</constant> flag set, in units of 1 Hz.
 If <structfield>rangehigh</structfield> is zero a reasonable default value
 is used.</entry>
          </row>
index 65dff55079d71763942fc8991ee8ae76a80bc65d..df2c63d07bac8e81b6c90c2b62a31bd62e9ab37f 100644 (file)
     <para>The <constant>VIDIOC_STREAMON</constant> and
 <constant>VIDIOC_STREAMOFF</constant> ioctl start and stop the capture
 or output process during streaming (<link linkend="mmap">memory
-mapping</link> or <link linkend="userp">user pointer</link>) I/O.</para>
+mapping</link>, <link linkend="userp">user pointer</link> or
+<link linkend="dmabuf">DMABUF</link>) I/O.</para>
 
-    <para>Specifically the capture hardware is disabled and no input
+    <para>Capture hardware is disabled and no input
 buffers are filled (if there are any empty buffers in the incoming
 queue) until <constant>VIDIOC_STREAMON</constant> has been called.
-Accordingly the output hardware is disabled, no video signal is
+Output hardware is disabled and no video signal is
 produced until <constant>VIDIOC_STREAMON</constant> has been called.
 The ioctl will succeed when at least one output buffer is in the
 incoming queue.</para>
 
+    <para>Memory-to-memory devices will not start until
+<constant>VIDIOC_STREAMON</constant> has been called for both the capture
+and output stream types.</para>
+
+    <para>If <constant>VIDIOC_STREAMON</constant> fails then any already
+queued buffers will remain queued.</para>
+
     <para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of
 aborting or finishing any DMA in progress, unlocks any user pointer
 buffers locked in physical memory, and it removes all buffers from the
@@ -70,14 +78,22 @@ dequeued yet will be lost, likewise all images enqueued for output but
 not transmitted yet. I/O returns to the same state as after calling
 &VIDIOC-REQBUFS; and can be restarted accordingly.</para>
 
+    <para>If buffers have been queued with &VIDIOC-QBUF; and
+<constant>VIDIOC_STREAMOFF</constant> is called without ever having
+called <constant>VIDIOC_STREAMON</constant>, then those queued buffers
+will also be removed from the incoming queue and all are returned to the
+same state as after calling &VIDIOC-REQBUFS; and can be restarted
+accordingly.</para>
+
     <para>Both ioctls take a pointer to an integer, the desired buffer or
 stream type. This is the same as &v4l2-requestbuffers;
 <structfield>type</structfield>.</para>
 
     <para>If <constant>VIDIOC_STREAMON</constant> is called when streaming
 is already in progress, or if <constant>VIDIOC_STREAMOFF</constant> is called
-when streaming is already stopped, then the ioctl does nothing and 0 is
-returned.</para>
+when streaming is already stopped, then 0 is returned. Nothing happens in the
+case of <constant>VIDIOC_STREAMON</constant>, but <constant>VIDIOC_STREAMOFF</constant>
+will return queued buffers to their starting state as mentioned above.</para>
 
     <para>Note that applications can be preempted for unknown periods right
 before or after the <constant>VIDIOC_STREAMON</constant> or
@@ -93,7 +109,7 @@ synchronize with other events.</para>
       <varlistentry>
        <term><errorcode>EINVAL</errorcode></term>
        <listitem>
-         <para>The buffer<structfield>type</structfield> is not supported,
+         <para>The buffer <structfield>type</structfield> is not supported,
          or no buffers have been allocated (memory mapping) or enqueued
          (output) yet.</para>
        </listitem>
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml b/Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml
deleted file mode 100644 (file)
index bbd18f0..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-<refentry id="vidioc-subdev-g-edid">
-  <refmeta>
-    <refentrytitle>ioctl VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID</refentrytitle>
-    &manvol;
-  </refmeta>
-
-  <refnamediv>
-    <refname>VIDIOC_SUBDEV_G_EDID</refname>
-    <refname>VIDIOC_SUBDEV_S_EDID</refname>
-    <refpurpose>Get or set the EDID of a video receiver/transmitter</refpurpose>
-  </refnamediv>
-
-  <refsynopsisdiv>
-    <funcsynopsis>
-      <funcprototype>
-       <funcdef>int <function>ioctl</function></funcdef>
-       <paramdef>int <parameter>fd</parameter></paramdef>
-       <paramdef>int <parameter>request</parameter></paramdef>
-       <paramdef>struct v4l2_subdev_edid *<parameter>argp</parameter></paramdef>
-      </funcprototype>
-    </funcsynopsis>
-    <funcsynopsis>
-      <funcprototype>
-       <funcdef>int <function>ioctl</function></funcdef>
-       <paramdef>int <parameter>fd</parameter></paramdef>
-       <paramdef>int <parameter>request</parameter></paramdef>
-       <paramdef>const struct v4l2_subdev_edid *<parameter>argp</parameter></paramdef>
-      </funcprototype>
-    </funcsynopsis>
-  </refsynopsisdiv>
-
-  <refsect1>
-    <title>Arguments</title>
-
-    <variablelist>
-      <varlistentry>
-       <term><parameter>fd</parameter></term>
-       <listitem>
-         <para>&fd;</para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term><parameter>request</parameter></term>
-       <listitem>
-         <para>VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID</para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term><parameter>argp</parameter></term>
-       <listitem>
-         <para></para>
-       </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-
-  <refsect1>
-    <title>Description</title>
-    <para>These ioctls can be used to get or set an EDID associated with an input pad
-    from a receiver or an output pad of a transmitter subdevice.</para>
-
-    <para>To get the EDID data the application has to fill in the <structfield>pad</structfield>,
-    <structfield>start_block</structfield>, <structfield>blocks</structfield> and <structfield>edid</structfield>
-    fields and call <constant>VIDIOC_SUBDEV_G_EDID</constant>. The current EDID from block
-    <structfield>start_block</structfield> and of size <structfield>blocks</structfield>
-    will be placed in the memory <structfield>edid</structfield> points to. The <structfield>edid</structfield>
-    pointer must point to memory at least <structfield>blocks</structfield>&nbsp;*&nbsp;128 bytes
-    large (the size of one block is 128 bytes).</para>
-
-    <para>If there are fewer blocks than specified, then the driver will set <structfield>blocks</structfield>
-    to the actual number of blocks. If there are no EDID blocks available at all, then the error code
-    ENODATA is set.</para>
-
-    <para>If blocks have to be retrieved from the sink, then this call will block until they
-    have been read.</para>
-
-    <para>To set the EDID blocks of a receiver the application has to fill in the <structfield>pad</structfield>,
-    <structfield>blocks</structfield> and <structfield>edid</structfield> fields and set
-    <structfield>start_block</structfield> to 0. It is not possible to set part of an EDID,
-    it is always all or nothing. Setting the EDID data is only valid for receivers as it makes
-    no sense for a transmitter.</para>
-
-    <para>The driver assumes that the full EDID is passed in. If there are more EDID blocks than
-    the hardware can handle then the EDID is not written, but instead the error code E2BIG is set
-    and <structfield>blocks</structfield> is set to the maximum that the hardware supports.
-    If <structfield>start_block</structfield> is any
-    value other than 0 then the error code EINVAL is set.</para>
-
-    <para>To disable an EDID you set <structfield>blocks</structfield> to 0. Depending on the
-    hardware this will drive the hotplug pin low and/or block the source from reading the EDID
-    data in some way. In any case, the end result is the same: the EDID is no longer available.
-    </para>
-
-    <table pgwide="1" frame="none" id="v4l2-subdev-edid">
-      <title>struct <structname>v4l2_subdev_edid</structname></title>
-      <tgroup cols="3">
-        &cs-str;
-       <tbody valign="top">
-         <row>
-           <entry>__u32</entry>
-           <entry><structfield>pad</structfield></entry>
-           <entry>Pad for which to get/set the EDID blocks.</entry>
-         </row>
-         <row>
-           <entry>__u32</entry>
-           <entry><structfield>start_block</structfield></entry>
-           <entry>Read the EDID from starting with this block. Must be 0 when setting
-           the EDID.</entry>
-         </row>
-         <row>
-           <entry>__u32</entry>
-           <entry><structfield>blocks</structfield></entry>
-           <entry>The number of blocks to get or set. Must be less or equal to 256 (the
-           maximum number of blocks as defined by the standard). When you set the EDID and
-           <structfield>blocks</structfield> is 0, then the EDID is disabled or erased.</entry>
-         </row>
-         <row>
-           <entry>__u8&nbsp;*</entry>
-           <entry><structfield>edid</structfield></entry>
-           <entry>Pointer to memory that contains the EDID. The minimum size is
-           <structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
-         </row>
-         <row>
-           <entry>__u32</entry>
-           <entry><structfield>reserved</structfield>[5]</entry>
-           <entry>Reserved for future extensions. Applications and drivers must
-           set the array to zero.</entry>
-         </row>
-       </tbody>
-      </tgroup>
-    </table>
-  </refsect1>
-
-  <refsect1>
-    &return-value;
-
-    <variablelist>
-      <varlistentry>
-       <term><errorcode>ENODATA</errorcode></term>
-       <listitem>
-         <para>The EDID data is not available.</para>
-       </listitem>
-      </varlistentry>
-      <varlistentry>
-       <term><errorcode>E2BIG</errorcode></term>
-       <listitem>
-         <para>The EDID data you provided is more than the hardware can handle.</para>
-       </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-</refentry>
index ab56f89c8642d9ab7087c5f28d054b56d3249e2c..4decb46bfa76d576c021cc7aac9a72d91df968b4 100644 (file)
 
 <book id="media_api">
 <bookinfo>
-<title>LINUX MEDIA INFRASTRUCTURE API</title>
-
-<copyright>
-       <year>2009-2012</year>
-       <holder>LinuxTV Developers</holder>
-</copyright>
-
-<legalnotice>
-
-<para>Permission is granted to copy, distribute and/or modify
-this document under the terms of the GNU Free Documentation License,
-Version 1.1 or any later version published by the Free Software
-Foundation. A copy of the license is included in the chapter entitled
-"GNU Free Documentation License"</para>
-</legalnotice>
-
+       <title>LINUX MEDIA INFRASTRUCTURE API</title>
+
+       <copyright>
+               <year>2009-2014</year>
+               <holder>LinuxTV Developers</holder>
+       </copyright>
+
+       <legalnotice>
+               <para>Permission is granted to copy, distribute and/or modify
+               this document under the terms of the GNU Free Documentation License,
+               Version 1.1 or any later version published by the Free Software
+               Foundation. A copy of the license is included in the chapter entitled
+               "GNU Free Documentation License"</para>
+       </legalnotice>
 </bookinfo>
 
 <toc></toc> <!-- autogenerated -->
@@ -60,10 +58,11 @@ Foundation. A copy of the license is included in the chapter entitled
        <para>This document covers the Linux Kernel to Userspace API's used by
                video and radio streaming devices, including video cameras,
                analog and digital TV receiver cards, AM/FM receiver cards,
-               streaming capture devices.</para>
+               streaming capture and output devices, codec devices and remote
+               controllers.</para>
        <para>It is divided into four parts.</para>
-       <para>The first part covers radio, capture,
-               cameras and analog TV devices.</para>
+       <para>The first part covers radio, video capture and output,
+               cameras, analog TV devices and codecs.</para>
        <para>The second part covers the
                API used for digital TV and Internet reception via one of the
                several digital tv standards. While it is called as DVB API,
@@ -75,55 +74,14 @@ Foundation. A copy of the license is included in the chapter entitled
        <para>For additional information and for the latest development code,
                see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
        <para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
-
 </preface>
 
-<part id="v4l2spec">
-&sub-v4l2;
-</part>
-<part id="dvbapi">
-&sub-dvbapi;
-</part>
-<part id="v4ldvb_common">
-<partinfo>
-<authorgroup>
-<author>
-<firstname>Mauro</firstname>
-<surname>Chehab</surname>
-<othername role="mi">Carvalho</othername>
-<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
-<contrib>Initial version.</contrib>
-</author>
-</authorgroup>
-<copyright>
-       <year>2009-2012</year>
-       <holder>Mauro Carvalho Chehab</holder>
-</copyright>
-
-<revhistory>
-<!-- Put document revisions here, newest first. -->
-<revision>
-<revnumber>1.0.0</revnumber>
-<date>2009-09-06</date>
-<authorinitials>mcc</authorinitials>
-<revremark>Initial revision</revremark>
-</revision>
-</revhistory>
-</partinfo>
-
-<title>Remote Controller API</title>
-<chapter id="remote_controllers">
-&sub-remote_controllers;
-</chapter>
-</part>
-<part id="media_common">
-&sub-media-controller;
-</part>
-
-<chapter id="gen_errors">
-&sub-gen-errors;
-</chapter>
+<part id="v4l2spec">&sub-v4l2;</part>
+<part id="dvbapi">&sub-dvbapi;</part>
+<part id="remotes">&sub-remote_controllers;</part>
+<part id="media_common">&sub-media-controller;</part>
 
+<chapter id="gen_errors">&sub-gen-errors;</chapter>
 
 &sub-fdl-appendix;
 
index 5a930c1528ad25c67f3cf98aa05a3ce9560b0019..963ec445e15a3a1a84571b15c3e2362bdd5e19b9 100644 (file)
@@ -83,14 +83,24 @@ EBU Armada family
         88F6710
         88F6707
         88F6W11
+    Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
+
+  Armada 375 Flavors:
+       88F6720
+    Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf
+
+  Armada 380/385 Flavors:
+       88F6810
+       88F6820
+       88F6828
 
   Armada XP Flavors:
         MV78230
         MV78260
         MV78460
     NOTE: not to be confused with the non-SMP 78xx0 SoCs
+    Product Brief: http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
 
-  Product Brief: http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf
   No public datasheet available.
 
   Core: Sheeva ARMv7 compatible
index 699ef2a323b102a7c176a8cf30fcbd7ef99997ba..c9c399af7c0871c6cca5718f536d1c9335a9c1dd 100644 (file)
@@ -255,3 +255,37 @@ are sorted out.
 
 To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
 kernel.
+
+       Part 7 - Locking
+
+The common clock framework uses two global locks, the prepare lock and the
+enable lock.
+
+The enable lock is a spinlock and is held across calls to the .enable,
+.disable and .is_enabled operations. Those operations are thus not allowed to
+sleep, and calls to the clk_enable(), clk_disable() and clk_is_enabled() API
+functions are allowed in atomic context.
+
+The prepare lock is a mutex and is held across calls to all other operations.
+All those operations are allowed to sleep, and calls to the corresponding API
+functions are not allowed in atomic context.
+
+This effectively divides operations in two groups from a locking perspective.
+
+Drivers don't need to manually protect resources shared between the operations
+of one group, regardless of whether those resources are shared by multiple
+clocks or not. However, access to resources that are shared between operations
+of the two groups needs to be protected by the drivers. An example of such a
+resource would be a register that controls both the clock rate and the clock
+enable/disable state.
+
+The clock framework is reentrant, in that a driver is allowed to call clock
+framework functions from within its implementation of clock operations. This
+can for instance cause a .set_rate operation of one clock being called from
+within the .set_rate operation of another clock. This case must be considered
+in the driver implementations, but the code flow is usually controlled by the
+driver in that case.
+
+Note that locking must also be considered when code outside of the common
+clock framework needs to access resources used by the clock operations. This
+is considered out of scope of this document.
index be675d2d15a73a4f784d7192931e187be294109d..a0b005d2bd95ce8d0251679adc90002a6e3b4809 100644 (file)
@@ -312,12 +312,57 @@ things will happen if a notifier in path sent a BAD notify code.
 Q: I don't see my action being called for all CPUs already up and running?
 A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined.
    If you need to perform some action for each cpu already in the system, then
+   do this:
 
        for_each_online_cpu(i) {
                foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i);
                foobar_cpu_callback(&foobar_cpu_notifier, CPU_ONLINE, i);
        }
 
+   However, if you want to register a hotplug callback, as well as perform
+   some initialization for CPUs that are already online, then do this:
+
+   Version 1: (Correct)
+   ---------
+
+       cpu_notifier_register_begin();
+
+               for_each_online_cpu(i) {
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_UP_PREPARE, i);
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_ONLINE, i);
+               }
+
+       /* Note the use of the double underscored version of the API */
+       __register_cpu_notifier(&foobar_cpu_notifier);
+
+       cpu_notifier_register_done();
+
+   Note that the following code is *NOT* the right way to achieve this,
+   because it is prone to an ABBA deadlock between the cpu_add_remove_lock
+   and the cpu_hotplug.lock.
+
+   Version 2: (Wrong!)
+   ---------
+
+       get_online_cpus();
+
+               for_each_online_cpu(i) {
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_UP_PREPARE, i);
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_ONLINE, i);
+               }
+
+       register_cpu_notifier(&foobar_cpu_notifier);
+
+       put_online_cpus();
+
+    So always use the first version shown above when you want to register
+    callbacks as well as initialize the already online CPUs.
+
+
 Q: If i would like to develop cpu hotplug support for a new architecture,
    what do i need at a minimum?
 A: The following are what is required for CPU hotplug infrastructure to work
diff --git a/Documentation/device-mapper/era.txt b/Documentation/device-mapper/era.txt
new file mode 100644 (file)
index 0000000..3c6d01b
--- /dev/null
@@ -0,0 +1,108 @@
+Introduction
+============
+
+dm-era is a target that behaves similar to the linear target.  In
+addition it keeps track of which blocks were written within a user
+defined period of time called an 'era'.  Each era target instance
+maintains the current era as a monotonically increasing 32-bit
+counter.
+
+Use cases include tracking changed blocks for backup software, and
+partially invalidating the contents of a cache to restore cache
+coherency after rolling back a vendor snapshot.
+
+Constructor
+===========
+
+ era <metadata dev> <origin dev> <block size>
+
+ metadata dev    : fast device holding the persistent metadata
+ origin dev     : device holding data blocks that may change
+ block size      : block size of origin data device, granularity that is
+                    tracked by the target
+
+Messages
+========
+
+None of the dm messages take any arguments.
+
+checkpoint
+----------
+
+Possibly move to a new era.  You shouldn't assume the era has
+incremented.  After sending this message, you should check the
+current era via the status line.
+
+take_metadata_snap
+------------------
+
+Create a clone of the metadata, to allow a userland process to read it.
+
+drop_metadata_snap
+------------------
+
+Drop the metadata snapshot.
+
+Status
+======
+
+<metadata block size> <#used metadata blocks>/<#total metadata blocks>
+<current era> <held metadata root | '-'>
+
+metadata block size     : Fixed block size for each metadata block in
+                            sectors
+#used metadata blocks   : Number of metadata blocks used
+#total metadata blocks  : Total number of metadata blocks
+current era             : The current era
+held metadata root      : The location, in blocks, of the metadata root
+                            that has been 'held' for userspace read
+                            access. '-' indicates there is no held root
+
+Detailed use case
+=================
+
+The scenario of invalidating a cache when rolling back a vendor
+snapshot was the primary use case when developing this target:
+
+Taking a vendor snapshot
+------------------------
+
+- Send a checkpoint message to the era target
+- Make a note of the current era in its status line
+- Take vendor snapshot (the era and snapshot should be forever
+  associated now).
+
+Rolling back to an vendor snapshot
+----------------------------------
+
+- Cache enters passthrough mode (see: dm-cache's docs in cache.txt)
+- Rollback vendor storage
+- Take metadata snapshot
+- Ascertain which blocks have been written since the snapshot was taken
+  by checking each block's era
+- Invalidate those blocks in the caching software
+- Cache returns to writeback/writethrough mode
+
+Memory usage
+============
+
+The target uses a bitset to record writes in the current era.  It also
+has a spare bitset ready for switching over to a new era.  Other than
+that it uses a few 4k blocks for updating metadata.
+
+   (4 * nr_blocks) bytes + buffers
+
+Resilience
+==========
+
+Metadata is updated on disk before a write to a previously unwritten
+block is performed.  As such dm-era should not be effected by a hard
+crash such as power failure.
+
+Userland tools
+==============
+
+Userland tools are found in the increasingly poorly named
+thin-provisioning-tools project:
+
+    https://github.com/jthornber/thin-provisioning-tools
index d154147d00153700fb1788139f9d1b87d1d8dae8..87b4c5e82d39023094f9b5f9b10cf919e3740f9d 100644 (file)
@@ -1494,10 +1494,17 @@ Your cooperation is appreciated.
                 64 = /dev/radio0       Radio device
                    ...
                127 = /dev/radio63      Radio device
+               128 = /dev/swradio0     Software Defined Radio device
+                   ...
+               191 = /dev/swradio63    Software Defined Radio device
                224 = /dev/vbi0         Vertical blank interrupt
                    ...
                255 = /dev/vbi31        Vertical blank interrupt
 
+               Minor numbers are allocated dynamically unless
+               CONFIG_VIDEO_FIXED_MINOR_RANGES (default n)
+               configuration option is set.
+
  81 block      I2O hard disk
                  0 = /dev/i2o/hdq      17th I2O hard disk, whole disk
                 16 = /dev/i2o/hdr      18th I2O hard disk, whole disk
diff --git a/Documentation/devicetree/bindings/arm/armada-375.txt b/Documentation/devicetree/bindings/arm/armada-375.txt
new file mode 100644 (file)
index 0000000..867d0b8
--- /dev/null
@@ -0,0 +1,9 @@
+Marvell Armada 375 Platforms Device Tree Bindings
+-------------------------------------------------
+
+Boards with a SoC of the Marvell Armada 375 family shall have the
+following property:
+
+Required root node property:
+
+compatible: must contain "marvell,armada375"
diff --git a/Documentation/devicetree/bindings/arm/armada-38x.txt b/Documentation/devicetree/bindings/arm/armada-38x.txt
new file mode 100644 (file)
index 0000000..11f2330
--- /dev/null
@@ -0,0 +1,10 @@
+Marvell Armada 38x Platforms Device Tree Bindings
+-------------------------------------------------
+
+Boards with a SoC of the Marvell Armada 38x family shall have the
+following property:
+
+Required root node property:
+
+ - compatible: must contain either "marvell,armada380" or
+   "marvell,armada385" depending on the variant of the SoC being used.
diff --git a/Documentation/devicetree/bindings/arm/atmel-adc.txt b/Documentation/devicetree/bindings/arm/atmel-adc.txt
deleted file mode 100644 (file)
index 9a1175b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-* AT91's Analog to Digital Converter (ADC)
-
-Required properties:
-  - compatible: Should be "atmel,<chip>-adc"
-    <chip> can be "at91sam9260", "at91sam9g45" or "at91sam9x5"
-  - reg: Should contain ADC registers location and length
-  - interrupts: Should contain the IRQ line for the ADC
-  - clock-names: tuple listing input clock names.
-       Required elements: "adc_clk", "adc_op_clk".
-  - clocks: phandles to input clocks.
-  - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
-    device
-  - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
-    defined in the datasheet
-  - atmel,adc-vref: Reference voltage in millivolts for the conversions
-  - atmel,adc-res: List of resolution in bits supported by the ADC. List size
-                  must be two at least.
-  - atmel,adc-res-names: Contains one identifier string for each resolution
-                        in atmel,adc-res property. "lowres" and "highres"
-                        identifiers are required.
-
-Optional properties:
-  - atmel,adc-use-external: Boolean to enable of external triggers
-  - atmel,adc-use-res: String corresponding to an identifier from
-                      atmel,adc-res-names property. If not specified, the highest
-                      resolution will be used.
-  - atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
-  - atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
-  - atmel,adc-ts-wires: Number of touch screen wires. Should be 4 or 5. If this
-                        value is set, then adc driver will enable touch screen
-                        support.
-    NOTE: when adc touch screen enabled, the adc hardware trigger will be
-          disabled. Since touch screen will occupied the trigger register.
-  - atmel,adc-ts-pressure-threshold: a pressure threshold for touchscreen. It
-                                     make touch detect more precision.
-Optional trigger Nodes:
-  - Required properties:
-    * trigger-name: Name of the trigger exposed to the user
-    * trigger-value: Value to put in the Trigger register
-      to activate this trigger
-  - Optional properties:
-    * trigger-external: Is the trigger an external trigger?
-
-Examples:
-adc0: adc@fffb0000 {
-       compatible = "atmel,at91sam9260-adc";
-       reg = <0xfffb0000 0x100>;
-       interrupts = <20 4>;
-       clocks = <&adc_clk>, <&adc_op_clk>;
-       clock-names = "adc_clk", "adc_op_clk";
-       atmel,adc-channel-base = <0x30>;
-       atmel,adc-channels-used = <0xff>;
-       atmel,adc-drdy-mask = <0x10000>;
-       atmel,adc-num-channels = <8>;
-       atmel,adc-startup-time = <40>;
-       atmel,adc-status-register = <0x1c>;
-       atmel,adc-trigger-register = <0x08>;
-       atmel,adc-use-external;
-       atmel,adc-vref = <3300>;
-       atmel,adc-res = <8 10>;
-       atmel,adc-res-names = "lowres", "highres";
-       atmel,adc-use-res = "lowres";
-
-       trigger@0 {
-               trigger-name = "external-rising";
-               trigger-value = <0x1>;
-               trigger-external;
-       };
-       trigger@1 {
-               trigger-name = "external-falling";
-               trigger-value = <0x2>;
-               trigger-external;
-       };
-
-       trigger@2 {
-               trigger-name = "external-any";
-               trigger-value = <0x3>;
-               trigger-external;
-       };
-
-       trigger@3 {
-               trigger-name = "continuous";
-               trigger-value = <0x6>;
-       };
-};
diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm21664.txt b/Documentation/devicetree/bindings/arm/bcm/bcm21664.txt
new file mode 100644 (file)
index 0000000..e077425
--- /dev/null
@@ -0,0 +1,15 @@
+Broadcom BCM21664 device tree bindings
+--------------------------------------
+
+This document describes the device tree bindings for boards with the BCM21664
+SoC.
+
+Required root node property:
+  - compatible: brcm,bcm21664
+
+Example:
+       / {
+               model = "BCM21664 SoC";
+               compatible = "brcm,bcm21664";
+               [...]
+       }
diff --git a/Documentation/devicetree/bindings/arm/bcm/kona-resetmgr.txt b/Documentation/devicetree/bindings/arm/bcm/kona-resetmgr.txt
new file mode 100644 (file)
index 0000000..93f31ca
--- /dev/null
@@ -0,0 +1,14 @@
+Broadcom Kona Family Reset Manager
+----------------------------------
+
+The reset manager is used on the Broadcom BCM21664 SoC.
+
+Required properties:
+  - compatible: brcm,bcm21664-resetmgr
+  - reg: memory address & range
+
+Example:
+       brcm,resetmgr@35001f00 {
+               compatible = "brcm,bcm21664-resetmgr";
+               reg = <0x35001f00 0x24>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/bcm4708.txt b/Documentation/devicetree/bindings/arm/bcm4708.txt
new file mode 100644 (file)
index 0000000..6b0f49f
--- /dev/null
@@ -0,0 +1,8 @@
+Broadcom BCM4708 device tree bindings
+-------------------------------------------
+
+Boards with the BCM4708 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "brcm,bcm4708";
index 91304353eea45193606d1df7925b4e45e7484f74..333f4aea30291e7a2882c8f2f67d1ec417307ef5 100644 (file)
@@ -180,7 +180,11 @@ nodes to be present and contain the properties described below.
                          be one of:
                             "spin-table"
                             "psci"
-                       # On ARM 32-bit systems this property is optional.
+                       # On ARM 32-bit systems this property is optional and
+                         can be one of:
+                           "qcom,gcc-msm8660"
+                           "qcom,kpss-acc-v1"
+                           "qcom,kpss-acc-v2"
 
        - cpu-release-addr
                Usage: required for systems that have an "enable-method"
@@ -191,6 +195,21 @@ nodes to be present and contain the properties described below.
                          property identifying a 64-bit zero-initialised
                          memory location.
 
+       - qcom,saw
+               Usage: required for systems that have an "enable-method"
+                      property value of "qcom,kpss-acc-v1" or
+                      "qcom,kpss-acc-v2"
+               Value type: <phandle>
+               Definition: Specifies the SAW[1] node associated with this CPU.
+
+       - qcom,acc
+               Usage: required for systems that have an "enable-method"
+                      property value of "qcom,kpss-acc-v1" or
+                      "qcom,kpss-acc-v2"
+               Value type: <phandle>
+               Definition: Specifies the ACC[2] node associated with this CPU.
+
+
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
        cpus {
@@ -382,3 +401,7 @@ cpus {
                cpu-release-addr = <0 0x20000000>;
        };
 };
+
+--
+[1] arm/msm/qcom,saw2.txt
+[2] arm/msm/qcom,kpss-acc.txt
index bae0d87a38b2bb4c6577e2a597c0ac7f501d1b2b..5573c08d3180b301a80990930c0da6259deff94f 100644 (file)
@@ -50,6 +50,11 @@ Optional
   regions, used when the GIC doesn't have banked registers. The offset is
   cpu-offset * cpu-nr.
 
+- arm,routable-irqs : Total number of gic irq inputs which are not directly
+                 connected from the peripherals, but are routed dynamically
+                 by a crossbar/multiplexer preceding the GIC. The GIC irq
+                 input line is assigned dynamically when the corresponding
+                 peripheral's crossbar line is mapped.
 Example:
 
        intc: interrupt-controller@fff11000 {
@@ -57,6 +62,7 @@ Example:
                #interrupt-cells = <3>;
                #address-cells = <1>;
                interrupt-controller;
+               arm,routable-irqs = <160>;
                reg = <0xfff11000 0x1000>,
                      <0xfff10100 0x100>;
        };
index 8c7a4653508dabeeb77e3251531bfddfbc65a40f..df0a452b8526de02bc935f235123acb7ae87b54c 100644 (file)
@@ -30,3 +30,17 @@ Example:
                resume-offset = <0x308>;
                reboot-offset = <0x4>;
        };
+
+PCTRL: Peripheral misc control register
+
+Required Properties:
+- compatible: "hisilicon,pctrl"
+- reg: Address and size of pctrl.
+
+Example:
+
+       /* for Hi3620 */
+       pctrl: pctrl@fca09000 {
+               compatible = "hisilicon,pctrl";
+               reg = <0xfca09000 0x1000>;
+       };
index 63c0e6ae5cf7aa60c6df81563a11ec11fe7ddae4..59d7a46f85eb59ae0e33f217c98c0277fd7182b9 100644 (file)
@@ -8,3 +8,13 @@ Required properties:
  - compatible: All TI specific devices present in Keystone SOC should be in
    the form "ti,keystone-*". Generic devices like gic, arch_timers, ns16550
    type UART should use the specified compatible for those devices.
+
+Boards:
+-  Keystone 2 Hawking/Kepler EVM
+   compatible = "ti,k2hk-evm","ti,keystone"
+
+-  Keystone 2 Lamarr EVM
+   compatible = "ti,k2l-evm","ti,keystone"
+
+-  Keystone 2 Edison EVM
+   compatible = "ti,k2e-evm","ti,keystone"
diff --git a/Documentation/devicetree/bindings/arm/mrvl/feroceon.txt b/Documentation/devicetree/bindings/arm/mrvl/feroceon.txt
new file mode 100644 (file)
index 0000000..0d244b9
--- /dev/null
@@ -0,0 +1,16 @@
+* Marvell Feroceon Cache
+
+Required properties:
+- compatible : Should be either "marvell,feroceon-cache" or
+              "marvell,kirkwood-cache".
+
+Optional properties:
+- reg        : Address of the L2 cache control register. Mandatory for
+              "marvell,kirkwood-cache", not used by "marvell,feroceon-cache"
+
+
+Example:
+               l2: l2-cache@20128 {
+                       compatible = "marvell,kirkwood-cache";
+                       reg = <0x20128 0x4>;
+               };
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
new file mode 100644 (file)
index 0000000..1333db9
--- /dev/null
@@ -0,0 +1,30 @@
+Krait Processor Sub-system (KPSS) Application Clock Controller (ACC)
+
+The KPSS ACC provides clock, power domain, and reset control to a Krait CPU.
+There is one ACC register region per CPU within the KPSS remapped region as
+well as an alias register region that remaps accesses to the ACC associated
+with the CPU accessing the region.
+
+PROPERTIES
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: should be one of:
+                       "qcom,kpss-acc-v1"
+                       "qcom,kpss-acc-v2"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: the first element specifies the base address and size of
+                   the register region. An optional second element specifies
+                   the base address and size of the alias register region.
+
+Example:
+
+       clock-controller@2088000 {
+               compatible = "qcom,kpss-acc-v2";
+               reg = <0x02088000 0x1000>,
+                     <0x02008000 0x1000>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
new file mode 100644 (file)
index 0000000..1505fb8
--- /dev/null
@@ -0,0 +1,35 @@
+SPM AVS Wrapper 2 (SAW2)
+
+The SAW2 is a wrapper around the Subsystem Power Manager (SPM) and the
+Adaptive Voltage Scaling (AVS) hardware. The SPM is a programmable
+micro-controller that transitions a piece of hardware (like a processor or
+subsystem) into and out of low power modes via a direct connection to
+the PMIC. It can also be wired up to interact with other processors in the
+system, notifying them when a low power state is entered or exited.
+
+PROPERTIES
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: shall contain "qcom,saw2". A more specific value should be
+                   one of:
+                        "qcom,saw2-v1"
+                        "qcom,saw2-v1.1"
+                        "qcom,saw2-v2"
+                        "qcom,saw2-v2.1"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: the first element specifies the base address and size of
+                   the register region. An optional second element specifies
+                   the base address and size of the alias register region.
+
+
+Example:
+
+       regulator@2099000 {
+               compatible = "qcom,saw2";
+               reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
+       };
index 081c6a786c8a93a7f07a58246b0a8118fbf80fb5..d24ab2ebf8a721f630868de9d3f4b85f07c2f1e2 100644 (file)
@@ -1,12 +1,13 @@
 MVEBU System Controller
 -----------------------
-MVEBU (Marvell SOCs: Armada 370/XP, Dove, mv78xx0, Kirkwood, Orion5x)
+MVEBU (Marvell SOCs: Armada 370/375/XP, Dove, mv78xx0, Kirkwood, Orion5x)
 
 Required properties:
 
 - compatible: one of:
        - "marvell,orion-system-controller"
        - "marvell,armada-370-xp-system-controller"
+       - "marvell,armada-375-system-controller"
 - reg: Should contain system controller registers location and length.
 
 Example:
diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt
new file mode 100644 (file)
index 0000000..fb88585
--- /dev/null
@@ -0,0 +1,27 @@
+Some socs have a large number of interrupts requests to service
+the needs of its many peripherals and subsystems. All of the
+interrupt lines from the subsystems are not needed at the same
+time, so they have to be muxed to the irq-controller appropriately.
+In such places a interrupt controllers are preceded by an CROSSBAR
+that provides flexibility in muxing the device requests to the controller
+inputs.
+
+Required properties:
+- compatible : Should be "ti,irq-crossbar"
+- reg: Base address and the size of the crossbar registers.
+- ti,max-irqs: Total number of irqs available at the interrupt controller.
+- ti,reg-size: Size of a individual register in bytes. Every individual
+           register is assumed to be of same size. Valid sizes are 1, 2, 4.
+- ti,irqs-reserved: List of the reserved irq lines that are not muxed using
+                crossbar. These interrupt lines are reserved in the soc,
+                so crossbar bar driver should not consider them as free
+                lines.
+
+Examples:
+               crossbar_mpu: @4a020000 {
+                       compatible = "ti,irq-crossbar";
+                       reg = <0x4a002a48 0x130>;
+                       ti,max-irqs = <160>;
+                       ti,reg-size = <2>;
+                       ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>;
+               };
diff --git a/Documentation/devicetree/bindings/arm/omap/dmm.txt b/Documentation/devicetree/bindings/arm/omap/dmm.txt
new file mode 100644 (file)
index 0000000..8bd6d0a
--- /dev/null
@@ -0,0 +1,22 @@
+OMAP Dynamic Memory Manager (DMM) bindings
+
+The dynamic memory manager (DMM) is a module located immediately in front of the
+SDRAM controllers (called EMIFs on OMAP). DMM manages various aspects of memory
+accesses such as priority generation amongst initiators, configuration of SDRAM
+interleaving, optimizing transfer of 2D block objects, and provide MMU-like page
+translation for initiators which need contiguous dma bus addresses.
+
+Required properties:
+- compatible:  Should contain "ti,omap4-dmm" for OMAP4 family
+               Should contain "ti,omap5-dmm" for OMAP5 and DRA7x family
+- reg:         Contains DMM register address range (base address and length)
+- interrupts:  Should contain an interrupt-specifier for DMM_IRQ.
+- ti,hwmods:   Name of the hwmod associated to DMM, which is typically "dmm"
+
+Example:
+
+dmm@4e000000 {
+       compatible = "ti,omap4-dmm";
+       reg = <0x4e000000 0x800>;
+       ti,hwmods = "dmm";
+};
index af9b4a0d902b3f7a182864b02dbfec13fb6c2cba..36ede19a16304f212513b829c9cf3b3b2e0441cc 100644 (file)
@@ -99,6 +99,9 @@ Boards:
 - OMAP4 PandaBoard : Low cost community board
   compatible = "ti,omap4-panda", "ti,omap4430"
 
+- OMAP4 DuoVero with Parlor : Commercial expansion board with daughter board
+  compatible = "gumstix,omap4-duovero-parlor", "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4";
+
 - OMAP3 EVM : Software Development Board for OMAP35x, AM/DM37x
   compatible = "ti,omap3-evm", "ti,omap3"
 
@@ -114,5 +117,8 @@ Boards:
 - AM43x EPOS EVM
   compatible = "ti,am43x-epos-evm", "ti,am4372", "ti,am43"
 
+- AM437x GP EVM
+  compatible = "ti,am437x-gp-evm", "ti,am4372", "ti,am43"
+
 - DRA7 EVM:  Software Developement Board for DRA7XX
   compatible = "ti,dra7-evm", "ti,dra7"
index 3e1e498fea96b357ff990f6fbb682dd43f5254cc..fe5cef8976cb0724833b292ab17d25fa779423c5 100644 (file)
@@ -9,6 +9,7 @@ Required properties:
 - compatible : should be one of
        "arm,armv8-pmuv3"
        "arm,cortex-a15-pmu"
+       "arm,cortex-a12-pmu"
        "arm,cortex-a9-pmu"
        "arm,cortex-a8-pmu"
        "arm,cortex-a7-pmu"
@@ -16,7 +17,14 @@ Required properties:
        "arm,arm11mpcore-pmu"
        "arm,arm1176-pmu"
        "arm,arm1136-pmu"
-- interrupts : 1 combined interrupt or 1 per core.
+       "qcom,krait-pmu"
+- interrupts : 1 combined interrupt or 1 per core. If the interrupt is a per-cpu
+               interrupt (PPI) then 1 interrupt should be specified.
+
+Optional properties:
+
+- qcom,no-pc-write : Indicates that this PMU doesn't support the 0xc and 0xd
+                     events.
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/arm/rockchip/pmu.txt b/Documentation/devicetree/bindings/arm/rockchip/pmu.txt
new file mode 100644 (file)
index 0000000..3ee9b42
--- /dev/null
@@ -0,0 +1,16 @@
+Rockchip power-management-unit:
+-------------------------------
+
+The pmu is used to turn off and on different power domains of the SoCs
+This includes the power to the CPU cores.
+
+Required node properties:
+- compatible value : = "rockchip,rk3066-pmu";
+- reg : physical base address and the size of the registers window
+
+Example:
+
+       pmu@20004000 {
+               compatible = "rockchip,rk3066-pmu";
+               reg = <0x20004000 0x100>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt b/Documentation/devicetree/bindings/arm/rockchip/smp-sram.txt
new file mode 100644 (file)
index 0000000..d9416fb
--- /dev/null
@@ -0,0 +1,30 @@
+Rockchip SRAM for smp bringup:
+------------------------------
+
+Rockchip's smp-capable SoCs use the first part of the sram for the bringup
+of the cores. Once the core gets powered up it executes the code that is
+residing at the very beginning of the sram.
+
+Therefore a reserved section sub-node has to be added to the mmio-sram
+declaration.
+
+Required sub-node properties:
+- compatible : should be "rockchip,rk3066-smp-sram"
+
+The rest of the properties should follow the generic mmio-sram discription
+found in ../../misc/sram.txt
+
+Example:
+
+       sram: sram@10080000 {
+               compatible = "mmio-sram";
+               reg = <0x10080000 0x10000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               smp-sram@10080000 {
+                       compatible = "rockchip,rk3066-smp-sram";
+                       reg = <0x10080000 0x50>;
+               };
+       };
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
new file mode 100644 (file)
index 0000000..f1f1552
--- /dev/null
@@ -0,0 +1,15 @@
+SAMSUNG Exynos SoC series PMU Registers
+
+Properties:
+ - compatible : should contain two values. First value must be one from following list:
+                  - "samsung,exynos5250-pmu" - for Exynos5250 SoC,
+                  - "samsung,exynos5420-pmu" - for Exynos5420 SoC.
+               second value must be always "syscon".
+
+ - reg : offset and length of the register set.
+
+Example :
+pmu_system_controller: system-controller@10040000 {
+       compatible = "samsung,exynos5250-pmu", "syscon";
+       reg = <0x10040000 0x5000>;
+};
diff --git a/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt b/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt
deleted file mode 100644 (file)
index 37824fa..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-* Samsung SATA PHY Controller
-
-SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
-Each SATA PHY controller should have its own node.
-
-Required properties:
-- compatible        : compatible list, contains "samsung,exynos5-sata-phy"
-- reg               : <registers mapping>
-
-Example:
-        sata@ffe07000 {
-                compatible = "samsung,exynos5-sata-phy";
-                reg = <0xffe07000 0x1000>;
-        };
index 0849f1025e3468b0aa6cf945beaa3547d141c15c..cb48448247ead3e34292bef11166a5074c9650c8 100644 (file)
@@ -4,14 +4,27 @@ SATA nodes are defined to describe on-chip Serial ATA controllers.
 Each SATA controller should have its own node.
 
 Required properties:
-- compatible        : compatible list, contains "samsung,exynos5-sata"
-- interrupts        : <interrupt mapping for SATA IRQ>
-- reg               : <registers mapping>
-- samsung,sata-freq : <frequency in MHz>
+- compatible           : compatible list, contains "samsung,exynos5-sata"
+- interrupts           : <interrupt mapping for SATA IRQ>
+- reg                  : <registers mapping>
+- samsung,sata-freq    : <frequency in MHz>
+- phys                 : Must contain exactly one entry as specified
+                         in phy-bindings.txt
+- phy-names            : Must be "sata-phy"
+
+Optional properties:
+- clocks               : Must contain an entry for each entry in clock-names.
+- clock-names          : Shall be "sata" for the external SATA bus clock,
+                         and "sclk_sata" for the internal controller clock.
 
 Example:
-        sata@ffe08000 {
-                compatible = "samsung,exynos5-sata";
-                reg = <0xffe08000 0x1000>;
-                interrupts = <115>;
-        };
+       sata@122f0000 {
+               compatible = "snps,dwc-ahci";
+               samsung,sata-freq = <66>;
+               reg = <0x122f0000 0x1ff>;
+               interrupts = <0 115 0>;
+               clocks = <&clock 277>, <&clock 143>;
+               clock-names = "sata", "sclk_sata";
+               phys = <&sata_phy>;
+               phy-names = "sata-phy";
+       };
index 0fd76c405208472cf6f8ce5553cd1a2a986b52db..6630d842c7a3716abde1bc4f6e4706b9a2ad466c 100644 (file)
@@ -8,7 +8,12 @@ The actual devices are instantiated from the child nodes of a WEIM node.
 
 Required properties:
 
- - compatible:         Should be set to "fsl,<soc>-weim"
+ - compatible:         Should contain one of the following:
+                         "fsl,imx1-weim"
+                         "fsl,imx27-weim"
+                         "fsl,imx51-weim"
+                         "fsl,imx50-weim"
+                         "fsl,imx6q-weim"
  - reg:                        A resource specifier for the register space
                        (see the example below)
  - clocks:             the clock, see the example below.
@@ -19,6 +24,26 @@ Required properties:
 
                           <cs-number> 0 <physical address of mapping> <size>
 
+Optional properties:
+
+ - fsl,weim-cs-gpr:    For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
+                       devices, it should be the phandle to the system General
+                       Purpose Register controller that contains WEIM CS GPR
+                       register, e.g. IOMUXC_GPR1 on i.MX6Q.  IOMUXC_GPR1[11:0]
+                       should be set up as one of the following 4 possible
+                       values depending on the CS space configuration.
+
+                       IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
+                       ---------------------------------------------
+                               05          128M     0M     0M     0M
+                               033          64M    64M     0M     0M
+                               0113         64M    32M    32M     0M
+                               01111        32M    32M    32M    32M
+
+                       In case that the property is absent, the reset value or
+                       what bootloader sets up in IOMUXC_GPR1[11:0] will be
+                       used.
+
 Timing property for child nodes. It is mandatory, not optional.
 
  - fsl,weim-cs-timing: The timing array, contains timing values for the
@@ -43,6 +68,7 @@ Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
                #address-cells = <2>;
                #size-cells = <1>;
                ranges = <0 0 0x08000000 0x08000000>;
+               fsl,weim-cs-gpr = <&gpr>;
 
                nor@0,0 {
                        compatible = "cfi-flash";
index 0045433eae1f81ef4b3263ba18fa0e6ec8c018e6..5dfd145d3ccf673492e91eee8f9b43d94a3faee0 100644 (file)
@@ -23,3 +23,8 @@ Optional properties:
         and the bit index.
 - div-reg : For "socfpga-gate-clk", div-reg contains the divider register, bit shift,
         and width.
+- clk-phase : For the sdmmc_clk, contains the value of the clock phase that controls
+       the SDMMC CIU clock. The first value is the clk_sample(smpsel), and the second
+       value is the cclk_in_drv(drvsel). The clk-phase is used to enable the correct
+       hold/delay times that is needed for the SD/MMC CIU clock. The values of both
+       can be 0-315 degrees, in 45 degree increments.
diff --git a/Documentation/devicetree/bindings/clock/arm-integrator.txt b/Documentation/devicetree/bindings/clock/arm-integrator.txt
new file mode 100644 (file)
index 0000000..652914b
--- /dev/null
@@ -0,0 +1,34 @@
+Clock bindings for ARM Integrator Core Module clocks
+
+Auxilary Oscillator Clock
+
+This is a configurable clock fed from a 24 MHz chrystal,
+used for generating e.g. video clocks. It is located on the
+core module and there is only one of these.
+
+This clock node *must* be a subnode of the core module, since
+it obtains the base address for it's address range from its
+parent node.
+
+
+Required properties:
+- compatible: must be "arm,integrator-cm-auxosc"
+- #clock-cells: must be <0>
+
+Optional properties:
+- clocks: parent clock(s)
+
+Example:
+
+core-module@10000000 {
+       xtal24mhz: xtal24mhz@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+       };
+       auxosc: cm_aux_osc@25M {
+               #clock-cells = <0>;
+               compatible = "arm,integrator-cm-auxosc";
+               clocks = <&xtal24mhz>;
+       };
+};
index 028b493e97ff2d95591ccc19fccffdbb53db75dd..20e1704e7df2110c518ce71ca07e94a0b4db574a 100644 (file)
@@ -5,7 +5,7 @@ This binding uses the common clock binding[1].
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 
 Required properties:
-- compatible : shall be "adi,axi-clkgen".
+- compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a".
 - #clock-cells : from common clock binding; Should always be set to 0.
 - reg : Address and length of the axi-clkgen register set.
 - clocks : Phandle and clock specifier for the parent clock.
index 7c52c29d99fa316c37221fec207dfee47d3c028d..700e7aac37174dc41a23c442abc9ec74db39a4ca 100644 (file)
@@ -44,6 +44,23 @@ For example:
   clocks by index. The names should reflect the clock output signal
   names for the device.
 
+clock-indices:    If the identifyng number for the clocks in the node
+                  is not linear from zero, then the this mapping allows
+                  the mapping of identifiers into the clock-output-names
+                  array.
+
+For example, if we have two clocks <&oscillator 1> and <&oscillator 3>:
+
+       oscillator {
+               compatible = "myclocktype";
+               #clock-cells = <1>;
+               clock-indices = <1>, <3>;
+               clock-output-names = "clka", "clkb";
+       }
+
+       This ensures we do not have any empty nodes in clock-output-names
+
+
 ==Clock consumers==
 
 Required properties:
index a2ac2d9ac71a7d0e4566dbc872dc5d4bb771407b..f5a5b19ed3b23bfd11631b9c14641e2ba3c484e3 100644 (file)
@@ -15,259 +15,12 @@ Required Properties:
 
 - #clock-cells: should be 1.
 
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume. Some of the clocks are available only on a particular
-Exynos4 SoC and this is specified where applicable.
-
-
-                [Core Clocks]
-
-  Clock               ID      SoC (if specific)
-  -----------------------------------------------
-
-  xxti                1
-  xusbxti             2
-  fin_pll             3
-  fout_apll           4
-  fout_mpll           5
-  fout_epll           6
-  fout_vpll           7
-  sclk_apll           8
-  sclk_mpll           9
-  sclk_epll           10
-  sclk_vpll           11
-  arm_clk             12
-  aclk200             13
-  aclk100             14
-  aclk160             15
-  aclk133             16
-  mout_mpll_user_t    17      Exynos4x12
-  mout_mpll_user_c    18      Exynos4x12
-  mout_core           19
-  mout_apll           20
-
-
-            [Clock Gate for Special Clocks]
-
-  Clock               ID      SoC (if specific)
-  -----------------------------------------------
-
-  sclk_fimc0          128
-  sclk_fimc1          129
-  sclk_fimc2          130
-  sclk_fimc3          131
-  sclk_cam0           132
-  sclk_cam1           133
-  sclk_csis0          134
-  sclk_csis1          135
-  sclk_hdmi           136
-  sclk_mixer          137
-  sclk_dac            138
-  sclk_pixel          139
-  sclk_fimd0          140
-  sclk_mdnie0         141     Exynos4412
-  sclk_mdnie_pwm0 12  142     Exynos4412
-  sclk_mipi0          143
-  sclk_audio0         144
-  sclk_mmc0           145
-  sclk_mmc1           146
-  sclk_mmc2           147
-  sclk_mmc3           148
-  sclk_mmc4           149
-  sclk_sata           150     Exynos4210
-  sclk_uart0          151
-  sclk_uart1          152
-  sclk_uart2          153
-  sclk_uart3          154
-  sclk_uart4          155
-  sclk_audio1         156
-  sclk_audio2         157
-  sclk_spdif          158
-  sclk_spi0           159
-  sclk_spi1           160
-  sclk_spi2           161
-  sclk_slimbus        162
-  sclk_fimd1          163     Exynos4210
-  sclk_mipi1          164     Exynos4210
-  sclk_pcm1           165
-  sclk_pcm2           166
-  sclk_i2s1           167
-  sclk_i2s2           168
-  sclk_mipihsi        169     Exynos4412
-  sclk_mfc            170
-  sclk_pcm0           171
-  sclk_g3d            172
-  sclk_pwm_isp        173     Exynos4x12
-  sclk_spi0_isp       174     Exynos4x12
-  sclk_spi1_isp       175     Exynos4x12
-  sclk_uart_isp       176     Exynos4x12
-  sclk_fimg2d         177
-
-             [Peripheral Clock Gates]
-
-  Clock               ID      SoC (if specific)
-  -----------------------------------------------
-
-  fimc0               256
-  fimc1               257
-  fimc2               258
-  fimc3               259
-  csis0               260
-  csis1               261
-  jpeg                262
-  smmu_fimc0          263
-  smmu_fimc1          264
-  smmu_fimc2          265
-  smmu_fimc3          266
-  smmu_jpeg           267
-  vp                  268
-  mixer               269
-  tvenc               270     Exynos4210
-  hdmi                271
-  smmu_tv             272
-  mfc                 273
-  smmu_mfcl           274
-  smmu_mfcr           275
-  g3d                 276
-  g2d                 277
-  rotator             278     Exynos4210
-  mdma                279     Exynos4210
-  smmu_g2d            280     Exynos4210
-  smmu_rotator        281     Exynos4210
-  smmu_mdma           282     Exynos4210
-  fimd0               283
-  mie0                284
-  mdnie0              285     Exynos4412
-  dsim0               286
-  smmu_fimd0          287
-  fimd1               288     Exynos4210
-  mie1                289     Exynos4210
-  dsim1               290     Exynos4210
-  smmu_fimd1          291     Exynos4210
-  pdma0               292
-  pdma1               293
-  pcie_phy            294
-  sata_phy            295     Exynos4210
-  tsi                 296
-  sdmmc0              297
-  sdmmc1              298
-  sdmmc2              299
-  sdmmc3              300
-  sdmmc4              301
-  sata                302     Exynos4210
-  sromc               303
-  usb_host            304
-  usb_device          305
-  pcie                306
-  onenand             307
-  nfcon               308
-  smmu_pcie           309
-  gps                 310
-  smmu_gps            311
-  uart0               312
-  uart1               313
-  uart2               314
-  uart3               315
-  uart4               316
-  i2c0                317
-  i2c1                318
-  i2c2                319
-  i2c3                320
-  i2c4                321
-  i2c5                322
-  i2c6                323
-  i2c7                324
-  i2c_hdmi            325
-  tsadc               326
-  spi0                327
-  spi1                328
-  spi2                329
-  i2s1                330
-  i2s2                331
-  pcm0                332
-  i2s0                333
-  pcm1                334
-  pcm2                335
-  pwm                 336
-  slimbus             337
-  spdif               338
-  ac97                339
-  modemif             340
-  chipid              341
-  sysreg              342
-  hdmi_cec            343
-  mct                 344
-  wdt                 345
-  rtc                 346
-  keyif               347
-  audss               348
-  mipi_hsi            349     Exynos4210
-  mdma2               350     Exynos4210
-  pixelasyncm0        351
-  pixelasyncm1        352
-  fimc_lite0          353     Exynos4x12
-  fimc_lite1          354     Exynos4x12
-  ppmuispx            355     Exynos4x12
-  ppmuispmx           356     Exynos4x12
-  fimc_isp            357     Exynos4x12
-  fimc_drc            358     Exynos4x12
-  fimc_fd             359     Exynos4x12
-  mcuisp              360     Exynos4x12
-  gicisp              361     Exynos4x12
-  smmu_isp            362     Exynos4x12
-  smmu_drc            363     Exynos4x12
-  smmu_fd             364     Exynos4x12
-  smmu_lite0          365     Exynos4x12
-  smmu_lite1          366     Exynos4x12
-  mcuctl_isp          367     Exynos4x12
-  mpwm_isp            368     Exynos4x12
-  i2c0_isp            369     Exynos4x12
-  i2c1_isp            370     Exynos4x12
-  mtcadc_isp          371     Exynos4x12
-  pwm_isp             372     Exynos4x12
-  wdt_isp             373     Exynos4x12
-  uart_isp            374     Exynos4x12
-  asyncaxim           375     Exynos4x12
-  smmu_ispcx          376     Exynos4x12
-  spi0_isp            377     Exynos4x12
-  spi1_isp            378     Exynos4x12
-  pwm_isp_sclk        379     Exynos4x12
-  spi0_isp_sclk       380     Exynos4x12
-  spi1_isp_sclk       381     Exynos4x12
-  uart_isp_sclk       382     Exynos4x12
-  tmu_apbif           383
-
-               [Mux Clocks]
-
-  Clock                        ID      SoC (if specific)
-  -----------------------------------------------
-
-  mout_fimc0           384
-  mout_fimc1           385
-  mout_fimc2           386
-  mout_fimc3           387
-  mout_cam0            388
-  mout_cam1            389
-  mout_csis0           390
-  mout_csis1           391
-  mout_g3d0            392
-  mout_g3d1            393
-  mout_g3d             394
-  aclk400_mcuisp       395     Exynos4x12
-
-               [Div Clocks]
-
-  Clock                        ID      SoC (if specific)
-  -----------------------------------------------
-
-  div_isp0             450     Exynos4x12
-  div_isp1             451     Exynos4x12
-  div_mcuisp0          452     Exynos4x12
-  div_mcuisp1          453     Exynos4x12
-  div_aclk200          454     Exynos4x12
-  div_aclk400_mcuisp   455     Exynos4x12
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume.
 
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/exynos4.h header and can be used in device
+tree sources.
 
 Example 1: An example of a clock controller node is listed below.
 
@@ -285,6 +38,6 @@ Example 2: UART controller node that consumes the clock generated by the clock
                compatible = "samsung,exynos4210-uart";
                reg = <0x13820000 0x100>;
                interrupts = <0 54 0>;
-               clocks = <&clock 314>, <&clock 153>;
+               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
        };
index 72ce617dea8210572f300501b4f9e79ad5aade78..536eacd1063f88ccf2e9ef0e0bdcf06137558cf8 100644 (file)
@@ -13,163 +13,12 @@ Required Properties:
 
 - #clock-cells: should be 1.
 
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume.
-
-
-       [Core Clocks]
-
-  Clock                        ID
-  ----------------------------
-
-  fin_pll              1
-
-  [Clock Gate for Special Clocks]
-
-  Clock                        ID
-  ----------------------------
-
-  sclk_cam_bayer       128
-  sclk_cam0            129
-  sclk_cam1            130
-  sclk_gscl_wa         131
-  sclk_gscl_wb         132
-  sclk_fimd1           133
-  sclk_mipi1           134
-  sclk_dp              135
-  sclk_hdmi            136
-  sclk_pixel           137
-  sclk_audio0          138
-  sclk_mmc0            139
-  sclk_mmc1            140
-  sclk_mmc2            141
-  sclk_mmc3            142
-  sclk_sata            143
-  sclk_usb3            144
-  sclk_jpeg            145
-  sclk_uart0           146
-  sclk_uart1           147
-  sclk_uart2           148
-  sclk_uart3           149
-  sclk_pwm             150
-  sclk_audio1          151
-  sclk_audio2          152
-  sclk_spdif           153
-  sclk_spi0            154
-  sclk_spi1            155
-  sclk_spi2            156
-  div_i2s1             157
-  div_i2s2             158
-  sclk_hdmiphy         159
-  div_pcm0             160
-
-
-   [Peripheral Clock Gates]
-
-  Clock                        ID
-  ----------------------------
-
-  gscl0                        256
-  gscl1                        257
-  gscl2                        258
-  gscl3                        259
-  gscl_wa              260
-  gscl_wb              261
-  smmu_gscl0           262
-  smmu_gscl1           263
-  smmu_gscl2           264
-  smmu_gscl3           265
-  mfc                  266
-  smmu_mfcl            267
-  smmu_mfcr            268
-  rotator              269
-  jpeg                 270
-  mdma1                        271
-  smmu_rotator         272
-  smmu_jpeg            273
-  smmu_mdma1           274
-  pdma0                        275
-  pdma1                        276
-  sata                 277
-  usbotg               278
-  mipi_hsi             279
-  sdmmc0               280
-  sdmmc1               281
-  sdmmc2               282
-  sdmmc3               283
-  sromc                        284
-  usb2                 285
-  usb3                 286
-  sata_phyctrl         287
-  sata_phyi2c          288
-  uart0                        289
-  uart1                        290
-  uart2                        291
-  uart3                        292
-  uart4                        293
-  i2c0                 294
-  i2c1                 295
-  i2c2                 296
-  i2c3                 297
-  i2c4                 298
-  i2c5                 299
-  i2c6                 300
-  i2c7                 301
-  i2c_hdmi             302
-  adc                  303
-  spi0                 304
-  spi1                 305
-  spi2                 306
-  i2s1                 307
-  i2s2                 308
-  pcm1                 309
-  pcm2                 310
-  pwm                  311
-  spdif                        312
-  ac97                 313
-  hsi2c0               314
-  hsi2c1               315
-  hs12c2               316
-  hs12c3               317
-  chipid               318
-  sysreg               319
-  pmu                  320
-  cmu_top              321
-  cmu_core             322
-  cmu_mem              323
-  tzpc0                        324
-  tzpc1                        325
-  tzpc2                        326
-  tzpc3                        327
-  tzpc4                        328
-  tzpc5                        329
-  tzpc6                        330
-  tzpc7                        331
-  tzpc8                        332
-  tzpc9                        333
-  hdmi_cec             334
-  mct                  335
-  wdt                  336
-  rtc                  337
-  tmu                  338
-  fimd1                        339
-  mie1                 340
-  dsim0                        341
-  dp                   342
-  mixer                        343
-  hdmi                 344
-  g2d                  345
-  mdma0                        346
-  smmu_mdma0           347
-
-
-   [Clock Muxes]
-
-  Clock                        ID
-  ----------------------------
-  mout_hdmi            1024
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume.
 
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/exynos5250.h header and can be used in device
+tree sources.
 
 Example 1: An example of a clock controller node is listed below.
 
@@ -187,6 +36,6 @@ Example 2: UART controller node that consumes the clock generated by the clock
                compatible = "samsung,exynos4210-uart";
                reg = <0x13820000 0x100>;
                interrupts = <0 54 0>;
-               clocks = <&clock 314>, <&clock 153>;
+               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
        };
index 458f34789e5d1aa6c6b6944d37f5dad4cfc22cf9..ca88c97a8562dd6c5e5c5839510b8efdc8d7ce49 100644 (file)
@@ -13,184 +13,12 @@ Required Properties:
 
 - #clock-cells: should be 1.
 
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume.
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume.
 
-
-       [Core Clocks]
-
-  Clock                        ID
-  ----------------------------
-
-  fin_pll              1
-
-  [Clock Gate for Special Clocks]
-
-  Clock                        ID
-  ----------------------------
-  sclk_uart0           128
-  sclk_uart1           129
-  sclk_uart2           130
-  sclk_uart3           131
-  sclk_mmc0            132
-  sclk_mmc1            133
-  sclk_mmc2            134
-  sclk_spi0            135
-  sclk_spi1            136
-  sclk_spi2            137
-  sclk_i2s1            138
-  sclk_i2s2            139
-  sclk_pcm1            140
-  sclk_pcm2            141
-  sclk_spdif           142
-  sclk_hdmi            143
-  sclk_pixel           144
-  sclk_dp1             145
-  sclk_mipi1           146
-  sclk_fimd1           147
-  sclk_maudio0         148
-  sclk_maupcm0         149
-  sclk_usbd300         150
-  sclk_usbd301         151
-  sclk_usbphy300       152
-  sclk_usbphy301       153
-  sclk_unipro          154
-  sclk_pwm             155
-  sclk_gscl_wa         156
-  sclk_gscl_wb         157
-  sclk_hdmiphy         158
-
-   [Peripheral Clock Gates]
-
-  Clock                        ID
-  ----------------------------
-
-  aclk66_peric         256
-  uart0                        257
-  uart1                        258
-  uart2                        259
-  uart3                        260
-  i2c0                 261
-  i2c1                 262
-  i2c2                 263
-  i2c3                 264
-  i2c4                 265
-  i2c5                 266
-  i2c6                 267
-  i2c7                 268
-  i2c_hdmi             269
-  tsadc                        270
-  spi0                 271
-  spi1                 272
-  spi2                 273
-  keyif                        274
-  i2s1                 275
-  i2s2                 276
-  pcm1                 277
-  pcm2                 278
-  pwm                  279
-  spdif                        280
-  i2c8                 281
-  i2c9                 282
-  i2c10                        283
-  aclk66_psgen         300
-  chipid               301
-  sysreg               302
-  tzpc0                        303
-  tzpc1                        304
-  tzpc2                        305
-  tzpc3                        306
-  tzpc4                        307
-  tzpc5                        308
-  tzpc6                        309
-  tzpc7                        310
-  tzpc8                        311
-  tzpc9                        312
-  hdmi_cec             313
-  seckey               314
-  mct                  315
-  wdt                  316
-  rtc                  317
-  tmu                  318
-  tmu_gpu              319
-  pclk66_gpio          330
-  aclk200_fsys2                350
-  mmc0                 351
-  mmc1                 352
-  mmc2                 353
-  sromc                        354
-  ufs                  355
-  aclk200_fsys         360
-  tsi                  361
-  pdma0                        362
-  pdma1                        363
-  rtic                 364
-  usbh20               365
-  usbd300              366
-  usbd301              377
-  aclk400_mscl         380
-  mscl0                        381
-  mscl1                        382
-  mscl2                        383
-  smmu_mscl0           384
-  smmu_mscl1           385
-  smmu_mscl2           386
-  aclk333              400
-  mfc                  401
-  smmu_mfcl            402
-  smmu_mfcr            403
-  aclk200_disp1                410
-  dsim1                        411
-  dp1                  412
-  hdmi                 413
-  aclk300_disp1                420
-  fimd1                        421
-  smmu_fimd1           422
-  aclk166              430
-  mixer                        431
-  aclk266              440
-  rotator              441
-  mdma1                        442
-  smmu_rotator         443
-  smmu_mdma1           444
-  aclk300_jpeg         450
-  jpeg                 451
-  jpeg2                        452
-  smmu_jpeg            453
-  aclk300_gscl         460
-  smmu_gscl0           461
-  smmu_gscl1           462
-  gscl_wa              463
-  gscl_wb              464
-  gscl0                        465
-  gscl1                        466
-  clk_3aa              467
-  aclk266_g2d          470
-  sss                  471
-  slim_sss             472
-  mdma0                        473
-  aclk333_g2d          480
-  g2d                  481
-  aclk333_432_gscl     490
-  smmu_3aa             491
-  smmu_fimcl0          492
-  smmu_fimcl1          493
-  smmu_fimcl3          494
-  fimc_lite3           495
-  aclk_g3d             500
-  g3d                  501
-  smmu_mixer           502
-
-  Mux                  ID
-  ----------------------------
-
-  mout_hdmi            640
-
-  Divider              ID
-  ----------------------------
-
-  dout_pixel           768
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/exynos5420.h header and can be used in device
+tree sources.
 
 Example 1: An example of a clock controller node is listed below.
 
@@ -208,6 +36,6 @@ Example 2: UART controller node that consumes the clock generated by the clock
                compatible = "samsung,exynos4210-uart";
                reg = <0x13820000 0x100>;
                interrupts = <0 54 0>;
-               clocks = <&clock 259>, <&clock 130>;
+               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
        };
index 9955dc9c7d969f5cb0888dc8a6c352dc037d81cf..5f7005f73058f74a1fe308814eb11f75d8100435 100644 (file)
@@ -12,45 +12,12 @@ Required Properties:
 
 - #clock-cells: should be 1.
 
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume.
-
-
-       [Core Clocks]
-
-  Clock                        ID
-  ----------------------------
-
-  xtal                 1
-  arm_clk              2
-
-   [Peripheral Clock Gates]
-
-  Clock                        ID
-  ----------------------------
-
-  spi_baud             16
-  pb0_250              17
-  pr0_250              18
-  pr1_250              19
-  b_250                        20
-  b_125                        21
-  b_200                        22
-  sata                 23
-  usb                  24
-  gmac0                        25
-  cs250                        26
-  pb0_250_o            27
-  pr0_250_o            28
-  pr1_250_o            29
-  b_250_o              30
-  b_125_o              31
-  b_200_o              32
-  sata_o               33
-  usb_o                        34
-  gmac0_o              35
-  cs250_o              36
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume.
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/exynos5440.h header and can be used in device
+tree sources.
 
 Example: An example of a clock controller node is listed below.
 
index 4b71ab41be5357584427fb49921d6c2345886cbc..dad6269f52c5a6c6a2be5c7eb09aa1f4bcce9a9d 100644 (file)
@@ -7,6 +7,7 @@ Required Properties:
 
 - compatible: should be one of the following.
   - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
+  - "hisilicon,hi3620-mmc-clock" - controller specific for Hi3620 mmc.
 
 - reg: physical base address of the controller and length of memory mapped
   region.
diff --git a/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt b/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
new file mode 100644 (file)
index 0000000..fedea84
--- /dev/null
@@ -0,0 +1,48 @@
+Device Tree Clock bindings for arch-moxart
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+MOXA ART SoCs allow to determine PLL output and APB frequencies
+by reading registers holding multiplier and divisor information.
+
+
+PLL:
+
+Required properties:
+- compatible : Must be "moxa,moxart-pll-clock"
+- #clock-cells : Should be 0
+- reg : Should contain registers location and length
+- clocks : Should contain phandle + clock-specifier for the parent clock
+
+Optional properties:
+- clock-output-names : Should contain clock name
+
+
+APB:
+
+Required properties:
+- compatible : Must be "moxa,moxart-apb-clock"
+- #clock-cells : Should be 0
+- reg : Should contain registers location and length
+- clocks : Should contain phandle + clock-specifier for the parent clock
+
+Optional properties:
+- clock-output-names : Should contain clock name
+
+
+For example:
+
+       clk_pll: clk_pll@98100000 {
+               compatible = "moxa,moxart-pll-clock";
+               #clock-cells = <0>;
+               reg = <0x98100000 0x34>;
+       };
+
+       clk_apb: clk_apb@98100000 {
+               compatible = "moxa,moxart-apb-clock";
+               #clock-cells = <0>;
+               reg = <0x98100000 0x34>;
+               clocks = <&clk_pll>;
+       };
index 1e662948661e12a9878815a5fede4c93ac7a9201..307a503c5db882cc600710aae58381ea131977ae 100644 (file)
@@ -11,6 +11,18 @@ The following is a list of provided IDs and clock names on Armada 370/XP:
  3 = hclk    (DRAM control clock)
  4 = dramclk (DDR clock)
 
+The following is a list of provided IDs and clock names on Armada 375:
+ 0 = tclk    (Internal Bus clock)
+ 1 = cpuclk  (CPU clock)
+ 2 = l2clk   (L2 Cache clock)
+ 3 = ddrclk  (DDR clock)
+
+The following is a list of provided IDs and clock names on Armada 380/385:
+ 0 = tclk    (Internal Bus clock)
+ 1 = cpuclk  (CPU clock)
+ 2 = l2clk   (L2 Cache clock)
+ 3 = ddrclk  (DDR clock)
+
 The following is a list of provided IDs and clock names on Kirkwood and Dove:
  0 = tclk   (Internal Bus clock)
  1 = cpuclk (CPU0 clock)
@@ -20,6 +32,8 @@ The following is a list of provided IDs and clock names on Kirkwood and Dove:
 Required properties:
 - compatible : shall be one of the following:
        "marvell,armada-370-core-clock" - For Armada 370 SoC core clocks
+       "marvell,armada-375-core-clock" - For Armada 375 SoC core clocks
+       "marvell,armada-380-core-clock" - For Armada 380/385 SoC core clocks
        "marvell,armada-xp-core-clock" - For Armada XP SoC core clocks
        "marvell,dove-core-clock" - for Dove SoC core clocks
        "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180)
index c62391fc0e39038adbb9d5faff227b7d8257f748..520562a7dc2abedefd6a04c6e8b2870071136cb2 100644 (file)
@@ -4,7 +4,10 @@ The following is a list of provided IDs and clock names on Armada 370/XP:
  0 = nand (NAND clock)
 
 Required properties:
-- compatible : must be "marvell,armada-370-corediv-clock"
+- compatible : must be "marvell,armada-370-corediv-clock",
+                      "marvell,armada-375-corediv-clock",
+                      "marvell,armada-380-corediv-clock",
+
 - reg : must be the register address of Core Divider control register
 - #clock-cells : from common clock binding; shall be set to 1
 - clocks : must be set to the parent's phandle
index fc2910fa7e45fdbbe41a0ccdd947e736ca2e0e75..76477be742b21c016e06d59f2a67c28b9ffdabf0 100644 (file)
@@ -1,9 +1,10 @@
 * Gated Clock bindings for Marvell EBU SoCs
 
-Marvell Armada 370/XP, Dove and Kirkwood allow some peripheral clocks to be
-gated to save some power. The clock consumer should specify the desired clock
-by having the clock ID in its "clocks" phandle cell. The clock ID is directly
-mapped to the corresponding clock gating control bit in HW to ease manual clock
+Marvell Armada 370/375/380/385/XP, Dove and Kirkwood allow some
+peripheral clocks to be gated to save some power. The clock consumer
+should specify the desired clock by having the clock ID in its
+"clocks" phandle cell. The clock ID is directly mapped to the
+corresponding clock gating control bit in HW to ease manual clock
 lookup in datasheet.
 
 The following is a list of provided IDs for Armada 370:
@@ -22,6 +23,60 @@ ID   Clock   Peripheral
 28     ddr     DDR Cntrl
 30     sata1   SATA Host 0
 
+The following is a list of provided IDs for Armada 375:
+ID     Clock           Peripheral
+-----------------------------------
+2      mu              Management Unit
+3      pp              Packet Processor
+4      ptp             PTP
+5      pex0            PCIe 0 Clock out
+6      pex1            PCIe 1 Clock out
+8      audio           Audio Cntrl
+11     nd_clk          Nand Flash Cntrl
+14     sata0_link      SATA 0 Link
+15     sata0_core      SATA 0 Core
+16     usb3            USB3 Host
+17     sdio            SDHCI Host
+18     usb             USB Host
+19     gop             Gigabit Ethernet MAC
+20     sata1_link      SATA 1 Link
+21     sata1_core      SATA 1 Core
+22     xor0            XOR DMA 0
+23     xor1            XOR DMA 0
+24     copro           Coprocessor
+25     tdm             Time Division Mplx
+28     crypto0_enc     Cryptographic Unit Port 0 Encryption
+29     crypto0_core    Cryptographic Unit Port 0 Core
+30     crypto1_enc     Cryptographic Unit Port 1 Encryption
+31     crypto1_core    Cryptographic Unit Port 1 Core
+
+The following is a list of provided IDs for Armada 380/385:
+ID     Clock           Peripheral
+-----------------------------------
+0      audio           Audio
+2      ge2             Gigabit Ethernet 2
+3      ge1             Gigabit Ethernet 1
+4      ge0             Gigabit Ethernet 0
+5      pex1            PCIe 1
+6      pex2            PCIe 2
+7      pex3            PCIe 3
+8      pex0            PCIe 0
+9      usb3h0          USB3 Host 0
+10     usb3h1          USB3 Host 1
+11     usb3d           USB3 Device
+13     bm              Buffer Management
+14     crypto0z        Cryptographic 0 Z
+15     sata0           SATA 0
+16     crypto1z        Cryptographic 1 Z
+17     sdio            SDIO
+18     usb2            USB 2
+21     crypto1         Cryptographic 1
+22     xor0            XOR 0
+23     crypto0         Cryptographic 0
+25     tdm             Time Division Multiplexing
+28     xor1            XOR 1
+30     sata1           SATA 1
+
 The following is a list of provided IDs for Armada XP:
 ID     Clock   Peripheral
 -----------------------------------
@@ -95,6 +150,8 @@ ID   Clock   Peripheral
 Required properties:
 - compatible : shall be one of the following:
        "marvell,armada-370-gating-clock" - for Armada 370 SoC clock gating
+       "marvell,armada-375-gating-clock" - for Armada 375 SoC clock gating
+       "marvell,armada-380-gating-clock" - for Armada 380/385 SoC clock gating
        "marvell,armada-xp-gating-clock" - for Armada XP SoC clock gating
        "marvell,dove-gating-clock" - for Dove SoC clock gating
        "marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating
diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
new file mode 100644 (file)
index 0000000..98a2574
--- /dev/null
@@ -0,0 +1,29 @@
+* Renesas RZ Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the RZ SoCs. It includes the PLL, variable
+CPU and GPU clocks, and several fixed ratio dividers.
+
+Required Properties:
+
+  - compatible: Must be one of
+    - "renesas,r7s72100-cpg-clocks" for the r7s72100 CPG
+    - "renesas,rz-cpg-clocks" for the generic RZ CPG
+  - reg: Base address and length of the memory resource used by the CPG
+  - clocks: References to possible parent clocks. Order must match clock modes
+    in the datasheet. For the r7s72100, this is extal, usb_x1.
+  - #clock-cells: Must be 1
+  - clock-output-names: The names of the clocks. Supported clocks are "pll",
+    "i", and "g"
+
+
+Example
+-------
+
+       cpg_clocks: cpg_clocks@fcfe0000 {
+               #clock-cells = <1>;
+               compatible = "renesas,r7s72100-cpg-clocks",
+                            "renesas,rz-cpg-clocks";
+               reg = <0xfcfe0000 0x18>;
+               clocks = <&extal_clk>, <&usb_x1_clk>;
+               clock-output-names = "pll", "i", "g";
+       };
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt
new file mode 100644 (file)
index 0000000..ae56315
--- /dev/null
@@ -0,0 +1,49 @@
+Binding for a ST divider and multiplexer clock driver.
+
+This binding uses the common clock binding[1].
+Base address is located to the parent node. See clock binding[2]
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
+
+Required properties:
+
+- compatible : shall be:
+       "st,clkgena-divmux-c65-hs",     "st,clkgena-divmux"
+       "st,clkgena-divmux-c65-ls",     "st,clkgena-divmux"
+       "st,clkgena-divmux-c32-odf0",   "st,clkgena-divmux"
+       "st,clkgena-divmux-c32-odf1",   "st,clkgena-divmux"
+       "st,clkgena-divmux-c32-odf2",   "st,clkgena-divmux"
+       "st,clkgena-divmux-c32-odf3",   "st,clkgena-divmux"
+
+- #clock-cells : From common clock binding; shall be set to 1.
+
+- clocks : From common clock binding
+
+- clock-output-names : From common clock binding.
+
+Example:
+
+       clockgenA@fd345000 {
+               reg = <0xfd345000 0xb50>;
+
+               CLK_M_A1_DIV1: CLK_M_A1_DIV1 {
+                       #clock-cells = <1>;
+                       compatible = "st,clkgena-divmux-c32-odf1",
+                                    "st,clkgena-divmux";
+
+                       clocks = <&CLK_M_A1_OSC_PREDIV>,
+                                <&CLK_M_A1_PLL0 1>, /* PLL0 PHI1 */
+                                <&CLK_M_A1_PLL1 1>; /* PLL1 PHI1 */
+
+                       clock-output-names = "CLK_M_RX_ICN_TS",
+                                            "CLK_M_RX_ICN_VDP_0",
+                                            "", /* Unused */
+                                            "CLK_M_PRV_T1_BUS",
+                                            "CLK_M_ICN_REG_12",
+                                            "CLK_M_ICN_REG_10",
+                                            "", /* Unused */
+                                            "CLK_M_ICN_ST231";
+               };
+       };
+
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt
new file mode 100644 (file)
index 0000000..943e080
--- /dev/null
@@ -0,0 +1,36 @@
+Binding for a ST multiplexed clock driver.
+
+This binding supports only simple indexed multiplexers, it does not
+support table based parent index to hardware value translations.
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+
+- compatible : shall be:
+       "st,stih416-clkgenc-vcc-hd",    "st,clkgen-mux"
+       "st,stih416-clkgenf-vcc-fvdp",  "st,clkgen-mux"
+       "st,stih416-clkgenf-vcc-hva",   "st,clkgen-mux"
+       "st,stih416-clkgenf-vcc-hd",    "st,clkgen-mux"
+       "st,stih416-clkgenf-vcc-sd",    "st,clkgen-mux"
+       "st,stih415-clkgen-a9-mux",     "st,clkgen-mux"
+       "st,stih416-clkgen-a9-mux",     "st,clkgen-mux"
+
+
+- #clock-cells : from common clock binding; shall be set to 0.
+
+- reg : A Base address and length of the register set.
+
+- clocks : from common clock binding
+
+Example:
+
+       CLK_M_HVA: CLK_M_HVA {
+               #clock-cells = <0>;
+               compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux";
+               reg = <0xfd690868 4>;
+
+               clocks = <&CLOCKGEN_F 1>, <&CLK_M_A1_DIV0 3>;
+       };
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
new file mode 100644 (file)
index 0000000..81eb385
--- /dev/null
@@ -0,0 +1,48 @@
+Binding for a ST pll clock driver.
+
+This binding uses the common clock binding[1].
+Base address is located to the parent node. See clock binding[2]
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
+
+Required properties:
+
+- compatible : shall be:
+       "st,clkgena-prediv-c65",        "st,clkgena-prediv"
+       "st,clkgena-prediv-c32",        "st,clkgena-prediv"
+
+       "st,clkgena-plls-c65"
+       "st,plls-c32-a1x-0",            "st,clkgen-plls-c32"
+       "st,plls-c32-a1x-1",            "st,clkgen-plls-c32"
+       "st,stih415-plls-c32-a9",       "st,clkgen-plls-c32"
+       "st,stih415-plls-c32-ddr",      "st,clkgen-plls-c32"
+       "st,stih416-plls-c32-a9",       "st,clkgen-plls-c32"
+       "st,stih416-plls-c32-ddr",      "st,clkgen-plls-c32"
+
+       "st,stih415-gpu-pll-c32",       "st,clkgengpu-pll-c32"
+       "st,stih416-gpu-pll-c32",       "st,clkgengpu-pll-c32"
+
+
+- #clock-cells : From common clock binding; shall be set to 1.
+
+- clocks : From common clock binding
+
+- clock-output-names : From common clock binding.
+
+Example:
+
+       clockgenA@fee62000 {
+               reg = <0xfee62000 0xb48>;
+
+               CLK_S_A0_PLL: CLK_S_A0_PLL {
+                       #clock-cells = <1>;
+                       compatible = "st,clkgena-plls-c65";
+
+                       clocks = <&CLK_SYSIN>;
+
+                       clock-output-names = "CLK_S_A0_PLL0_HS",
+                                            "CLK_S_A0_PLL0_LS",
+                                            "CLK_S_A0_PLL1";
+               };
+       };
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt
new file mode 100644 (file)
index 0000000..566c9d7
--- /dev/null
@@ -0,0 +1,36 @@
+Binding for a ST pre-divider clock driver.
+
+This binding uses the common clock binding[1].
+Base address is located to the parent node. See clock binding[2]
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt
+
+Required properties:
+
+- compatible : shall be:
+       "st,clkgena-prediv-c65",        "st,clkgena-prediv"
+       "st,clkgena-prediv-c32",        "st,clkgena-prediv"
+
+- #clock-cells : From common clock binding; shall be set to 0.
+
+- clocks : From common clock binding
+
+- clock-output-names : From common clock binding.
+
+Example:
+
+       clockgenA@fd345000 {
+               reg = <0xfd345000 0xb50>;
+
+               CLK_M_A2_OSC_PREDIV: CLK_M_A2_OSC_PREDIV {
+                       #clock-cells = <0>;
+                       compatible = "st,clkgena-prediv-c32",
+                                    "st,clkgena-prediv";
+
+                       clocks = <&CLK_SYSIN>;
+
+                       clock-output-names = "CLK_M_A2_OSC_PREDIV";
+               };
+       };
+
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt
new file mode 100644 (file)
index 0000000..4e3ff28
--- /dev/null
@@ -0,0 +1,53 @@
+Binding for a type of STMicroelectronics clock crossbar (VCC).
+
+The crossbar can take up to 4 input clocks and control up to 16
+output clocks. Not all inputs or outputs have to be in use in a
+particular instantiation. Each output can be individually enabled,
+select any of the input clocks and apply a divide (by 1,2,4 or 8) to
+that selected clock.
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+
+- compatible : shall be:
+       "st,stih416-clkgenc",           "st,vcc"
+       "st,stih416-clkgenf",           "st,vcc"
+
+- #clock-cells : from common clock binding; shall be set to 1.
+
+- reg : A Base address and length of the register set.
+
+- clocks : from common clock binding
+
+- clock-output-names : From common clock binding. The block has 16
+                       clock outputs but not all of them in a specific instance
+                       have to be used in the SoC. If a clock name is left as
+                       an empty string then no clock will be created for the
+                       output associated with that string index. If fewer than
+                       16 strings are provided then no clocks will be created
+                       for the remaining outputs.
+
+Example:
+
+       CLOCKGEN_C_VCC: CLOCKGEN_C_VCC {
+               #clock-cells = <1>;
+               compatible = "st,stih416-clkgenc", "st,clkgen-vcc";
+               reg = <0xfe8308ac 12>;
+
+               clocks = <&CLK_S_VCC_HD>, <&CLOCKGEN_C 1>,
+                       <&CLK_S_TMDS_FROMPHY>, <&CLOCKGEN_C 2>;
+
+               clock-output-names  =
+                       "CLK_S_PIX_HDMI",  "CLK_S_PIX_DVO",
+                       "CLK_S_OUT_DVO",   "CLK_S_PIX_HD",
+                       "CLK_S_HDDAC",     "CLK_S_DENC",
+                       "CLK_S_SDDAC",     "CLK_S_PIX_MAIN",
+                       "CLK_S_PIX_AUX",   "CLK_S_STFE_FRC_0",
+                       "CLK_S_REF_MCRU",  "CLK_S_SLAVE_MCRU",
+                       "CLK_S_TMDS_HDMI", "CLK_S_HDMI_REJECT_PLL",
+                       "CLK_S_THSENS";
+       };
+
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
new file mode 100644 (file)
index 0000000..49ec5ae
--- /dev/null
@@ -0,0 +1,83 @@
+Binding for a Clockgen hardware block found on
+certain STMicroelectronics consumer electronics SoC devices.
+
+A Clockgen node can contain pll, diviser or multiplexer nodes.
+
+We will find only the base address of the Clockgen, this base
+address is common of all subnode.
+
+       clockgen_node {
+               reg = <>;
+
+               pll_node {
+                       ...
+               };
+
+               prediv_node {
+                       ...
+               };
+
+               divmux_node {
+                       ...
+               };
+
+               quadfs_node {
+                       ...
+               };
+               ...
+       };
+
+This binding uses the common clock binding[1].
+Each subnode should use the binding discribe in [2]..[4]
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/clock/st,quadfs.txt
+[3] Documentation/devicetree/bindings/clock/st,quadfs.txt
+[4] Documentation/devicetree/bindings/clock/st,quadfs.txt
+
+Required properties:
+- reg : A Base address and length of the register set.
+
+Example:
+
+       clockgenA@fee62000 {
+
+               reg = <0xfee62000 0xb48>;
+
+               CLK_S_A0_PLL: CLK_S_A0_PLL {
+                       #clock-cells = <1>;
+                       compatible = "st,clkgena-plls-c65";
+
+                       clocks = <&CLK_SYSIN>;
+
+                       clock-output-names = "CLK_S_A0_PLL0_HS",
+                                            "CLK_S_A0_PLL0_LS",
+                                            "CLK_S_A0_PLL1";
+               };
+
+               CLK_S_A0_OSC_PREDIV: CLK_S_A0_OSC_PREDIV {
+                       #clock-cells = <0>;
+                       compatible = "st,clkgena-prediv-c65",
+                                    "st,clkgena-prediv";
+
+                       clocks = <&CLK_SYSIN>;
+
+                       clock-output-names = "CLK_S_A0_OSC_PREDIV";
+               };
+
+               CLK_S_A0_HS: CLK_S_A0_HS {
+                       #clock-cells = <1>;
+                       compatible = "st,clkgena-divmux-c65-hs",
+                                    "st,clkgena-divmux";
+
+                       clocks = <&CLK_S_A0_OSC_PREDIV>,
+                                <&CLK_S_A0_PLL 0>, /* PLL0 HS */
+                                <&CLK_S_A0_PLL 2>; /* PLL1 */
+
+                       clock-output-names = "CLK_S_FDMA_0",
+                                            "CLK_S_FDMA_1",
+                                            ""; /* CLK_S_JIT_SENSE */
+                                            /* Fourth output unused */
+               };
+       };
+
diff --git a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt
new file mode 100644 (file)
index 0000000..ec86d62
--- /dev/null
@@ -0,0 +1,45 @@
+Binding for a type of quad channel digital frequency synthesizer found on
+certain STMicroelectronics consumer electronics SoC devices.
+
+This version contains a programmable PLL which can generate up to 216, 432
+or 660MHz (from a 30MHz oscillator input) as the input to the digital
+synthesizers.
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be:
+  "st,stih416-quadfs216",      "st,quadfs"
+  "st,stih416-quadfs432",      "st,quadfs"
+  "st,stih416-quadfs660-E",    "st,quadfs"
+  "st,stih416-quadfs660-F",    "st,quadfs"
+
+- #clock-cells : from common clock binding; shall be set to 1.
+
+- reg : A Base address and length of the register set.
+
+- clocks : from common clock binding
+
+- clock-output-names : From common clock binding. The block has 4
+                       clock outputs but not all of them in a specific instance
+                       have to be used in the SoC. If a clock name is left as
+                       an empty string then no clock will be created for the
+                       output associated with that string index. If fewer than
+                       4 strings are provided then no clocks will be created
+                       for the remaining outputs.
+
+Example:
+
+       CLOCKGEN_E: CLOCKGEN_E {
+                #clock-cells = <1>;
+                compatible = "st,stih416-quadfs660-E", "st,quadfs";
+                reg = <0xfd3208bc 0xB0>;
+
+                clocks = <&CLK_SYSIN>;
+                clock-output-names = "CLK_M_PIX_MDTP_0",
+                                        "CLK_M_PIX_MDTP_1",
+                                        "CLK_M_PIX_MDTP_2",
+                                        "CLK_M_MPELPC";
+        };
index c2cb7621ad2dd194f8342ac353770694136558aa..a5160d8cbb5f7e1c020e925da23d491ca3b3a0a4 100644 (file)
@@ -6,37 +6,41 @@ This binding uses the common clock binding[1].
 
 Required properties:
 - compatible : shall be one of the following:
-       "allwinner,sun4i-osc-clk" - for a gatable oscillator
-       "allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
+       "allwinner,sun4i-a10-osc-clk" - for a gatable oscillator
+       "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4
        "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
-       "allwinner,sun4i-pll5-clk" - for the PLL5 clock
-       "allwinner,sun4i-pll6-clk" - for the PLL6 clock
-       "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
-       "allwinner,sun4i-axi-clk" - for the AXI clock
-       "allwinner,sun4i-axi-gates-clk" - for the AXI gates
-       "allwinner,sun4i-ahb-clk" - for the AHB clock
-       "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
+       "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock
+       "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock
+       "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
+       "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock
+       "allwinner,sun4i-a10-axi-clk" - for the AXI clock
+       "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates
+       "allwinner,sun4i-a10-ahb-clk" - for the AHB clock
+       "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10
        "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
        "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
        "allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
        "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
        "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
-       "allwinner,sun4i-apb0-clk" - for the APB0 clock
-       "allwinner,sun4i-apb0-gates-clk" - for the APB0 gates on A10
+       "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock
+       "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10
        "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13
        "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
        "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
-       "allwinner,sun4i-apb1-clk" - for the APB1 clock
-       "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
-       "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10
+       "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock
+       "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing
+       "allwinner,sun4i-a10-apb1-gates-clk" - for the APB1 gates on A10
        "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13
        "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s
        "allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31
        "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
        "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
        "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
-       "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
+       "allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
        "allwinner,sun7i-a20-out-clk" - for the external output clocks
+       "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
+       "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
+       "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
 
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
@@ -44,10 +48,17 @@ Required properties for all clocks:
        multiplexed clocks, the list order must match the hardware
        programming order.
 - #clock-cells : from common clock binding; shall be set to 0 except for
-       "allwinner,*-gates-clk" where it shall be set to 1
+       "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk" and
+       "allwinner,sun4i-pll6-clk" where it shall be set to 1
+- clock-output-names : shall be the corresponding names of the outputs.
+       If the clock module only has one output, the name shall be the
+       module name.
 
-Additionally, "allwinner,*-gates-clk" clocks require:
-- clock-output-names : the corresponding gate names that the clock controls
+And "allwinner,*-usb-clk" clocks also require:
+- reset-cells : shall be set to 1
+
+For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
+dummy clocks at 25 MHz and 125 MHz, respectively. See example.
 
 Clock consumers should specify the desired clocks they use with a
 "clocks" phandle cell. Consumers that are using a gated clock should
@@ -56,23 +67,68 @@ offset of the bit controlling this particular gate in the register.
 
 For example:
 
-osc24M: osc24M@01c20050 {
+osc24M: clk@01c20050 {
        #clock-cells = <0>;
-       compatible = "allwinner,sun4i-osc-clk";
+       compatible = "allwinner,sun4i-a10-osc-clk";
        reg = <0x01c20050 0x4>;
        clocks = <&osc24M_fixed>;
+       clock-output-names = "osc24M";
 };
 
-pll1: pll1@01c20000 {
+pll1: clk@01c20000 {
        #clock-cells = <0>;
-       compatible = "allwinner,sun4i-pll1-clk";
+       compatible = "allwinner,sun4i-a10-pll1-clk";
        reg = <0x01c20000 0x4>;
        clocks = <&osc24M>;
+       clock-output-names = "pll1";
+};
+
+pll5: clk@01c20020 {
+       #clock-cells = <1>;
+       compatible = "allwinner,sun4i-pll5-clk";
+       reg = <0x01c20020 0x4>;
+       clocks = <&osc24M>;
+       clock-output-names = "pll5_ddr", "pll5_other";
 };
 
 cpu: cpu@01c20054 {
        #clock-cells = <0>;
-       compatible = "allwinner,sun4i-cpu-clk";
+       compatible = "allwinner,sun4i-a10-cpu-clk";
        reg = <0x01c20054 0x4>;
        clocks = <&osc32k>, <&osc24M>, <&pll1>;
+       clock-output-names = "cpu";
+};
+
+mmc0_clk: clk@01c20088 {
+       #clock-cells = <0>;
+       compatible = "allwinner,sun4i-mod0-clk";
+       reg = <0x01c20088 0x4>;
+       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+       clock-output-names = "mmc0";
+};
+
+mii_phy_tx_clk: clk@2 {
+       #clock-cells = <0>;
+       compatible = "fixed-clock";
+       clock-frequency = <25000000>;
+       clock-output-names = "mii_phy_tx";
+};
+
+gmac_int_tx_clk: clk@3 {
+       #clock-cells = <0>;
+       compatible = "fixed-clock";
+       clock-frequency = <125000000>;
+       clock-output-names = "gmac_int_tx";
+};
+
+gmac_clk: clk@01c20164 {
+       #clock-cells = <0>;
+       compatible = "allwinner,sun7i-a20-gmac-clk";
+       reg = <0x01c20164 0x4>;
+       /*
+        * The first clock must be fixed at 25MHz;
+        * the second clock must be fixed at 125MHz
+        */
+       clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
+       clock-output-names = "gmac";
 };
index 17b4a94916d6d87c9d1fb9f42da49522594b5e2d..d93746cf29751e9ada09eb02ff9a5797cd186e9f 100644 (file)
@@ -14,6 +14,7 @@ for all clock consumers of PS clocks.
 Required properties:
  - #clock-cells : Must be 1
  - compatible : "xlnx,ps7-clkc"
+ - reg : SLCR offset and size taken via syscon < 0x100 0x100 >
  - ps-clk-frequency : Frequency of the oscillator providing ps_clk in HZ
                      (usually 33 MHz oscillators are used for Zynq platforms)
  - clock-output-names : List of strings used to name the clock outputs. Shall be
@@ -87,10 +88,11 @@ Clock outputs:
  47: dbg_apb
 
 Example:
-       clkc: clkc {
+       clkc: clkc@100 {
                #clock-cells = <1>;
                compatible = "xlnx,ps7-clkc";
                ps-clk-frequency = <33333333>;
+               reg = <0x100 0x100>;
                clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
                                "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
                                "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
index f47e56bcf78d49bea32e9b259cd09a44638f4e81..71724d026ffacf0876a24c228466d38265f3eedc 100644 (file)
@@ -59,6 +59,7 @@ plx,pex8648           48-Lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
 ramtron,24c64          i2c serial eeprom  (24cxx)
 ricoh,rs5c372a         I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
 samsung,24ad0xd1       S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power)
+sii,s35390a            2-wire CMOS real-time clock
 st-micro,24c256                i2c serial eeprom  (24cxx)
 stm,m41t00             Serial Access TIMEKEEPER
 stm,m41t62             Serial real-time clock (RTC) with alarm
diff --git a/Documentation/devicetree/bindings/iio/adc/at91_adc.txt b/Documentation/devicetree/bindings/iio/adc/at91_adc.txt
new file mode 100644 (file)
index 0000000..0f813de
--- /dev/null
@@ -0,0 +1,87 @@
+* AT91's Analog to Digital Converter (ADC)
+
+Required properties:
+  - compatible: Should be "atmel,<chip>-adc"
+    <chip> can be "at91sam9260", "at91sam9g45" or "at91sam9x5"
+  - reg: Should contain ADC registers location and length
+  - interrupts: Should contain the IRQ line for the ADC
+  - clock-names: tuple listing input clock names.
+       Required elements: "adc_clk", "adc_op_clk".
+  - clocks: phandles to input clocks.
+  - atmel,adc-channels-used: Bitmask of the channels muxed and enabled for this
+    device
+  - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
+    defined in the datasheet
+  - atmel,adc-vref: Reference voltage in millivolts for the conversions
+  - atmel,adc-res: List of resolutions in bits supported by the ADC. List size
+                  must be two at least.
+  - atmel,adc-res-names: Contains one identifier string for each resolution
+                        in atmel,adc-res property. "lowres" and "highres"
+                        identifiers are required.
+
+Optional properties:
+  - atmel,adc-use-external-triggers: Boolean to enable the external triggers
+  - atmel,adc-use-res: String corresponding to an identifier from
+                      atmel,adc-res-names property. If not specified, the highest
+                      resolution will be used.
+  - atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
+  - atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
+  - atmel,adc-ts-wires: Number of touchscreen wires. Should be 4 or 5. If this
+                        value is set, then the adc driver will enable touchscreen
+                        support.
+    NOTE: when adc touchscreen is enabled, the adc hardware trigger will be
+          disabled. Since touchscreen will occupy the trigger register.
+  - atmel,adc-ts-pressure-threshold: a pressure threshold for touchscreen. It
+                                     makes touch detection more precise.
+
+Optional trigger Nodes:
+  - Required properties:
+    * trigger-name: Name of the trigger exposed to the user
+    * trigger-value: Value to put in the Trigger register
+      to activate this trigger
+  - Optional properties:
+    * trigger-external: Is the trigger an external trigger?
+
+Examples:
+adc0: adc@fffb0000 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       compatible = "atmel,at91sam9260-adc";
+       reg = <0xfffb0000 0x100>;
+       interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+       clocks = <&adc_clk>, <&adc_op_clk>;
+       clock-names = "adc_clk", "adc_op_clk";
+       atmel,adc-channels-used = <0xff>;
+       atmel,adc-startup-time = <40>;
+       atmel,adc-use-external-triggers;
+       atmel,adc-vref = <3300>;
+       atmel,adc-res = <8 10>;
+       atmel,adc-res-names = "lowres", "highres";
+       atmel,adc-use-res = "lowres";
+
+       trigger@0 {
+               reg = <0>;
+               trigger-name = "external-rising";
+               trigger-value = <0x1>;
+               trigger-external;
+       };
+       trigger@1 {
+               reg = <1>;
+               trigger-name = "external-falling";
+               trigger-value = <0x2>;
+               trigger-external;
+       };
+
+       trigger@2 {
+               reg = <2>;
+               trigger-name = "external-any";
+               trigger-value = <0x3>;
+               trigger-external;
+       };
+
+       trigger@3 {
+               reg = <3>;
+               trigger-name = "continuous";
+               trigger-value = <0x6>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt b/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt
new file mode 100644 (file)
index 0000000..6bdd214
--- /dev/null
@@ -0,0 +1,24 @@
+* TWL4030 Monitoring Analog to Digital Converter (MADC)
+
+The MADC subsystem in the TWL4030 consists of a 10-bit ADC
+combined with a 16-input analog multiplexer.
+
+Required properties:
+  - compatible: Should contain "ti,twl4030-madc".
+  - interrupts: IRQ line for the MADC submodule.
+  - #io-channel-cells: Should be set to <1>.
+
+Optional properties:
+  - ti,system-uses-second-madc-irq: boolean, set if the second madc irq register
+                                   should be used, which is intended to be used
+                                   by Co-Processors (e.g. a modem).
+
+Example:
+
+&twl {
+       madc {
+               compatible = "ti,twl4030-madc";
+               interrupts = <3>;
+               #io-channel-cells = <1>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
new file mode 100644 (file)
index 0000000..759339c
--- /dev/null
@@ -0,0 +1,41 @@
+Cirrus Logic CLPS711X Interrupt Controller
+
+Required properties:
+
+- compatible: Should be "cirrus,clps711x-intc".
+- reg: Specifies base physical address of the registers set.
+- interrupt-controller: Identifies the node as an interrupt controller.
+- #interrupt-cells: Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+The interrupt sources are as follows:
+ID     Name    Description
+---------------------------
+1:     BLINT   Battery low (FIQ)
+3:     MCINT   Media changed (FIQ)
+4:     CSINT   CODEC sound
+5:     EINT1   External 1
+6:     EINT2   External 2
+7:     EINT3   External 3
+8:     TC1OI   TC1 under flow
+9:     TC2OI   TC2 under flow
+10:    RTCMI   RTC compare match
+11:    TINT    64Hz tick
+12:    UTXINT1 UART1 transmit FIFO half empty
+13:    URXINT1 UART1 receive FIFO half full
+14:    UMSINT  UART1 modem status changed
+15:    SSEOTI  SSI1 end of transfer
+16:    KBDINT  Keyboard
+17:    SS2RX   SSI2 receive FIFO half or greater full
+18:    SS2TX   SSI2 transmit FIFO less than half empty
+28:    UTXINT2 UART2 transmit FIFO half empty
+29:    URXINT2 UART2 receive FIFO half full
+32:    DAIINT  DAI interface (FIQ)
+
+Example:
+       intc: interrupt-controller {
+               compatible = "cirrus,clps711x-intc";
+               reg = <0x80000000 0x4000>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
index e34c6cdd8ba8f9e1b14ef089a6e11105e796768a..f284b99402bc3d5d704b6f42debac89465ba36f3 100644 (file)
@@ -48,6 +48,12 @@ conditions.
                   from the mmu-masters towards memory) node for this
                   SMMU.
 
+- calxeda,smmu-secure-config-access : Enable proper handling of buggy
+                  implementations that always use secure access to
+                  SMMU configuration registers. In this case non-secure
+                  aliases of secure registers have to be used during
+                  SMMU configuration.
+
 Example:
 
         smmu {
diff --git a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
new file mode 100644 (file)
index 0000000..42531dc
--- /dev/null
@@ -0,0 +1,26 @@
+OMAP2+ IOMMU
+
+Required properties:
+- compatible : Should be one of,
+               "ti,omap2-iommu" for OMAP2/OMAP3 IOMMU instances
+               "ti,omap4-iommu" for OMAP4/OMAP5 IOMMU instances
+               "ti,dra7-iommu" for DRA7xx IOMMU instances
+- ti,hwmods  : Name of the hwmod associated with the IOMMU instance
+- reg        : Address space for the configuration registers
+- interrupts : Interrupt specifier for the IOMMU instance
+
+Optional properties:
+- ti,#tlb-entries : Number of entries in the translation look-aside buffer.
+                    Should be either 8 or 32 (default: 32)
+- ti,iommu-bus-err-back : Indicates the IOMMU instance supports throwing
+                         back a bus error response on MMU faults.
+
+Example:
+       /* OMAP3 ISP MMU */
+       mmu_isp: mmu@480bd400 {
+               compatible = "ti,omap2-iommu";
+               reg = <0x480bd400 0x80>;
+               interrupts = <24>;
+               ti,hwmods = "mmu_isp";
+               ti,#tlb-entries = <8>;
+       };
diff --git a/Documentation/devicetree/bindings/media/img-ir-rev1.txt b/Documentation/devicetree/bindings/media/img-ir-rev1.txt
new file mode 100644 (file)
index 0000000..5434ce6
--- /dev/null
@@ -0,0 +1,34 @@
+* ImgTec Infrared (IR) decoder version 1
+
+This binding is for Imagination Technologies' Infrared decoder block,
+specifically major revision 1.
+
+Required properties:
+- compatible:          Should be "img,ir-rev1"
+- reg:                 Physical base address of the controller and length of
+                       memory mapped region.
+- interrupts:          The interrupt specifier to the cpu.
+
+Optional properties:
+- clocks:              List of clock specifiers as described in standard
+                       clock bindings.
+                       Up to 3 clocks may be specified in the following order:
+                       1st:    Core clock (defaults to 32.768KHz if omitted).
+                       2nd:    System side (fast) clock.
+                       3rd:    Power modulation clock.
+- clock-names:         List of clock names corresponding to the clocks
+                       specified in the clocks property.
+                       Accepted clock names are:
+                       "core": Core clock.
+                       "sys":  System clock.
+                       "mod":  Power modulation clock.
+
+Example:
+
+       ir@02006200 {
+               compatible = "img,ir-rev1";
+               reg = <0x02006200 0x100>;
+               interrupts = <29 4>;
+               clocks = <&clk_32khz>;
+               clock-names =  "core";
+       };
index 96312f6c4c2651db3c0b088342b86e39af8e6cfc..922d6f8e74be37c9992655402861af59ae8ff83a 100644 (file)
@@ -15,11 +15,21 @@ Common 'camera' node
 
 Required properties:
 
-- compatible   : must be "samsung,fimc", "simple-bus"
-- clocks       : list of clock specifiers, corresponding to entries in
-                 the clock-names property;
-- clock-names  : must contain "sclk_cam0", "sclk_cam1", "pxl_async0",
-                 "pxl_async1" entries, matching entries in the clocks property.
+- compatible: must be "samsung,fimc", "simple-bus"
+- clocks: list of clock specifiers, corresponding to entries in
+  the clock-names property;
+- clock-names : must contain "sclk_cam0", "sclk_cam1", "pxl_async0",
+  "pxl_async1" entries, matching entries in the clocks property.
+
+- #clock-cells: from the common clock bindings (../clock/clock-bindings.txt),
+  must be 1. A clock provider is associated with the 'camera' node and it should
+  be referenced by external sensors that use clocks provided by the SoC on
+  CAM_*_CLKOUT pins. The clock specifier cell stores an index of a clock.
+  The indices are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
+
+- clock-output-names: from the common clock bindings, should contain names of
+  clocks registered by the camera subsystem corresponding to CAM_A_CLKOUT,
+  CAM_B_CLKOUT output clocks respectively.
 
 The pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt must be used
 to define a required pinctrl state named "default" and optional pinctrl states:
@@ -32,6 +42,7 @@ way around.
 
 The 'camera' node must include at least one 'fimc' child node.
 
+
 'fimc' device nodes
 -------------------
 
@@ -88,8 +99,8 @@ port nodes specifies data input - 0, 1 indicates input A, B respectively.
 
 Optional properties
 
-- samsung,camclk-out : specifies clock output for remote sensor,
-                      0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT;
+- samsung,camclk-out (deprecated) : specifies clock output for remote sensor,
+  0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT;
 
 Image sensor nodes
 ------------------
@@ -97,8 +108,6 @@ Image sensor nodes
 The sensor device nodes should be added to their control bus controller (e.g.
 I2C0) nodes and linked to a port node in the csis or the parallel-ports node,
 using the common video interfaces bindings, defined in video-interfaces.txt.
-The implementation of this bindings requires clock-frequency property to be
-present in the sensor device nodes.
 
 Example:
 
@@ -114,7 +123,7 @@ Example:
                        vddio-supply = <...>;
 
                        clock-frequency = <24000000>;
-                       clocks = <...>;
+                       clocks = <&camera 1>;
                        clock-names = "mclk";
 
                        port {
@@ -135,7 +144,7 @@ Example:
                        vddio-supply = <...>;
 
                        clock-frequency = <24000000>;
-                       clocks = <...>;
+                       clocks = <&camera 0>;
                        clock-names = "mclk";
 
                        port {
@@ -149,12 +158,17 @@ Example:
 
        camera {
                compatible = "samsung,fimc", "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               status = "okay";
-
+               clocks = <&clock 132>, <&clock 133>, <&clock 351>,
+                        <&clock 352>;
+               clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
+                             "pxl_async1";
+               #clock-cells = <1>;
+               clock-output-names = "cam_a_clkout", "cam_b_clkout";
                pinctrl-names = "default";
                pinctrl-0 = <&cam_port_a_clk_active>;
+               status = "okay";
+               #address-cells = <1>;
+               #size-cells = <1>;
 
                /* parallel camera ports */
                parallel-ports {
diff --git a/Documentation/devicetree/bindings/media/samsung-s5c73m3.txt b/Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
new file mode 100644 (file)
index 0000000..2c85c45
--- /dev/null
@@ -0,0 +1,97 @@
+Samsung S5C73M3 8Mp camera ISP
+------------------------------
+
+The S5C73M3 camera ISP supports MIPI CSI-2 and parallel (ITU-R BT.656) video
+data busses. The I2C bus is the main control bus and additionally the SPI bus
+is used, mostly for transferring the firmware to and from the device. Two
+slave device nodes corresponding to these control bus interfaces are required
+and should be placed under respective bus controller nodes.
+
+I2C slave device node
+---------------------
+
+Required properties:
+
+- compatible       : "samsung,s5c73m3";
+- reg              : I2C slave address of the sensor;
+- vdd-int-supply    : digital power supply (1.2V);
+- vdda-supply      : analog power supply (1.2V);
+- vdd-reg-supply    : regulator input power supply (2.8V);
+- vddio-host-supply : host I/O power supply (1.8V to 2.8V);
+- vddio-cis-supply  : CIS I/O power supply (1.2V to 1.8V);
+- vdd-af-supply     : lens power supply (2.8V);
+- xshutdown-gpios   : specifier of GPIO connected to the XSHUTDOWN pin;
+- standby-gpios     : specifier of GPIO connected to the STANDBY pin;
+- clocks           : should contain list of phandle and clock specifier pairs
+                     according to common clock bindings for the clocks described
+                     in the clock-names property;
+- clock-names      : should contain "cis_extclk" entry for the CIS_EXTCLK clock;
+
+Optional properties:
+
+- clock-frequency   : the frequency at which the "cis_extclk" clock should be
+                     configured to operate, in Hz; if this property is not
+                     specified default 24 MHz value will be used.
+
+The common video interfaces bindings (see video-interfaces.txt) should be used
+to specify link from the S5C73M3 to an external image data receiver. The S5C73M3
+device node should contain one 'port' child node with an 'endpoint' subnode for
+this purpose. The data link from a raw image sensor to the S5C73M3 can be
+similarly specified, but it is optional since the S5C73M3 ISP and a raw image
+sensor are usually inseparable and form a hybrid module.
+
+Following properties are valid for the endpoint node(s):
+
+endpoint subnode
+----------------
+
+- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
+  video-interfaces.txt. This sensor doesn't support data lane remapping
+  and physical lane indexes in subsequent elements of the array should
+  be only consecutive ascending values.
+
+SPI device node
+---------------
+
+Required properties:
+
+- compatible       : "samsung,s5c73m3";
+
+For more details see description of the SPI busses bindings
+(../spi/spi-bus.txt) and bindings of a specific bus controller.
+
+Example:
+
+i2c@138A000000 {
+       ...
+       s5c73m3@3c {
+               compatible = "samsung,s5c73m3";
+               reg = <0x3c>;
+               vdd-int-supply = <&buck9_reg>;
+               vdda-supply = <&ldo17_reg>;
+               vdd-reg-supply = <&cam_io_reg>;
+               vddio-host-supply = <&ldo18_reg>;
+               vddio-cis-supply = <&ldo9_reg>;
+               vdd-af-supply = <&cam_af_reg>;
+               clock-frequency = <24000000>;
+               clocks = <&clk 0>;
+               clock-names = "cis_extclk";
+               reset-gpios = <&gpf1 3 1>;
+               standby-gpios = <&gpm0 1 1>;
+               port {
+                       s5c73m3_ep: endpoint {
+                               remote-endpoint = <&csis0_ep>;
+                               data-lanes = <1 2 3 4>;
+                       };
+               };
+       };
+};
+
+spi@1392000 {
+       ...
+       s5c73m3_spi: s5c73m3@0 {
+               compatible = "samsung,s5c73m3";
+               reg = <0>;
+               ...
+       };
+};
diff --git a/Documentation/devicetree/bindings/media/samsung-s5k6a3.txt b/Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
new file mode 100644 (file)
index 0000000..cce01e8
--- /dev/null
@@ -0,0 +1,33 @@
+Samsung S5K6A3(YX) raw image sensor
+---------------------------------
+
+S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
+and CCI (I2C compatible) control bus.
+
+Required properties:
+
+- compatible   : "samsung,s5k6a3";
+- reg          : I2C slave address of the sensor;
+- svdda-supply : core voltage supply;
+- svddio-supply        : I/O voltage supply;
+- afvdd-supply : AF (actuator) voltage supply;
+- gpios                : specifier of a GPIO connected to the RESET pin;
+- clocks       : should contain list of phandle and clock specifier pairs
+                 according to common clock bindings for the clocks described
+                 in the clock-names property;
+- clock-names  : should contain "extclk" entry for the sensor's EXTCLK clock;
+
+Optional properties:
+
+- clock-frequency : the frequency at which the "extclk" clock should be
+                   configured to operate, in Hz; if this property is not
+                   specified default 24 MHz value will be used.
+
+The common video interfaces bindings (see video-interfaces.txt) should be
+used to specify link to the image data receiver. The S5K6A3(YX) device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Following properties are valid for the endpoint node:
+
+- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
+  video-interfaces.txt.  The sensor supports only one data lane.
index 0e295c9d8937145bcf54c82646cabba06d6196b8..36a0c3d8c726a42a976867bb6a2e3a6df62e0d08 100644 (file)
@@ -5,9 +5,10 @@ of analogue I/O.
 
 Required properties:
 
-  - compatible : one of the following chip-specific strings:
-       "wlf,wm5102"
-       "wlf,wm5110"
+  - compatible : One of the following chip-specific strings:
+        "wlf,wm5102"
+        "wlf,wm5110"
+        "wlf,wm8997"
   - reg : I2C slave address when connected using I2C, chip select number when
     using SPI.
 
@@ -25,8 +26,9 @@ Required properties:
   - #gpio-cells : Must be 2. The first cell is the pin number and the
     second cell is used to specify optional parameters (currently unused).
 
-  - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
-    SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
+  - AVDD-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply (wm5102, wm5110),
+    CPVDD-supply, SPKVDDL-supply (wm5102, wm5110), SPKVDDR-supply (wm5102,
+    wm5110), SPKVDD-supply (wm8997) : Power supplies for the device, as covered
     in Documentation/devicetree/bindings/regulator/regulator.txt
 
 Optional properties:
@@ -46,6 +48,7 @@ codec: wm5102@1a {
        compatible = "wlf,wm5102";
        reg = <0x1a>;
        interrupts = <347>;
+       interrupt-controller;
        #interrupt-cells = <2>;
         interrupt-parent = <&gic>;
 
@@ -53,10 +56,10 @@ codec: wm5102@1a {
        #gpio-cells = <2>;
 
        wlf,gpio-defaults = <
-               0x00000000, /* AIF1TXLRCLK */
-               0xffffffff,
-               0xffffffff,
-               0xffffffff,
-               0xffffffff,
+               0x00000000 /* AIF1TXLRCLK */
+               0xffffffff
+               0xffffffff
+               0xffffffff
+               0xffffffff
        >;
 };
diff --git a/Documentation/devicetree/bindings/mfd/bcm590xx.txt b/Documentation/devicetree/bindings/mfd/bcm590xx.txt
new file mode 100644 (file)
index 0000000..1fe30e2
--- /dev/null
@@ -0,0 +1,37 @@
+-------------------------------
+BCM590xx Power Management Units
+-------------------------------
+
+Required properties:
+- compatible: "brcm,bcm59056"
+- reg: I2C slave address
+- interrupts: interrupt for the PMU. Generic interrupt client node bindings
+  are described in interrupt-controller/interrupts.txt
+
+------------------
+Voltage Regulators
+------------------
+
+Optional child nodes:
+- regulators: container node for regulators following the generic
+  regulator binding in regulator/regulator.txt
+
+  The valid regulator node names for BCM59056 are:
+       rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo,
+       mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo,
+       csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr
+
+Example:
+       pmu: bcm59056@8 {
+               compatible = "brcm,bcm59056";
+               reg = <0x08>;
+               interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+               regulators {
+                       rfldo_reg: rfldo {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       ...
+               };
+       };
diff --git a/Documentation/devicetree/bindings/mfd/da9055.txt b/Documentation/devicetree/bindings/mfd/da9055.txt
new file mode 100644 (file)
index 0000000..6dab34d
--- /dev/null
@@ -0,0 +1,72 @@
+* Dialog DA9055 Power Management Integrated Circuit (PMIC)
+
+DA9055 consists of a large and varied group of sub-devices (I2C Only):
+
+Device                  Supply Names    Description
+------                  ------------    -----------
+da9055-gpio            :               : GPIOs
+da9055-regulator       :               : Regulators
+da9055-onkey           :               : On key
+da9055-rtc             :               : RTC
+da9055-hwmon           :               : ADC
+da9055-watchdog                :               : Watchdog
+
+The CODEC device in DA9055 has a separate, configurable I2C address and so
+is instantiated separately from the PMIC.
+
+For details on accompanying CODEC I2C device, see the following:
+Documentation/devicetree/bindings/sound/da9055.txt
+
+======
+
+Required properties:
+- compatible : Should be "dlg,da9055-pmic"
+- reg: Specifies the I2C slave address (defaults to 0x5a but can be modified)
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the IRQs from da9055 are delivered to.
+- interrupts: IRQ line info for da9055 chip.
+- interrupt-controller: da9055 has internal IRQs (has own IRQ domain).
+- #interrupt-cells: Should be 1, is the local IRQ number for da9055.
+
+Sub-nodes:
+- regulators : Contain the regulator nodes. The DA9055 regulators are
+  bound using their names as listed below:
+
+    buck1     : regulator BUCK1
+    buck2     : regulator BUCK2
+    ldo1      : regulator LDO1
+    ldo2      : regulator LDO2
+    ldo3      : regulator LDO3
+    ldo4      : regulator LDO4
+    ldo5      : regulator LDO5
+    ldo6      : regulator LDO6
+
+  The bindings details of individual regulator device can be found in:
+  Documentation/devicetree/bindings/regulator/regulator.txt
+
+
+Example:
+
+       pmic: da9055-pmic@5a {
+               compatible = "dlg,da9055-pmic";
+               reg = <0x5a>;
+               interrupt-parent = <&intc>;
+               interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+
+               regulators {
+                       buck1: BUCK1 {
+                               regulator-min-microvolt = <725000>;
+                               regulator-max-microvolt = <2075000>;
+                       };
+                       buck2: BUCK2 {
+                               regulator-min-microvolt = <925000>;
+                               regulator-max-microvolt = <2500000>;
+                       };
+                       ldo1: LDO1 {
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+       };
index b381fa696bf95c7e35c5a850f2a9425d9f9e7fab..4721b2d521e4c62b51a06aff7bd34e3db9dda9f3 100644 (file)
@@ -32,6 +32,29 @@ Optional properties:
 - single-ulpi-bypass: Must be present if the controller contains a single
   ULPI bypass control bit. e.g. OMAP3 silicon <= ES2.1
 
+- clocks: a list of phandles and clock-specifier pairs, one for each entry in
+  clock-names.
+
+- clock-names: should include:
+  For OMAP3
+  * "usbhost_120m_fck" - 120MHz Functional clock.
+
+  For OMAP4+
+  * "refclk_60m_int" - 60MHz internal reference clock for UTMI clock mux
+  * "refclk_60m_ext_p1" - 60MHz external ref. clock for Port 1's UTMI clock mux.
+  * "refclk_60m_ext_p2" - 60MHz external ref. clock for Port 2's UTMI clock mux
+  * "utmi_p1_gfclk" - Port 1 UTMI clock mux.
+  * "utmi_p2_gfclk" - Port 2 UTMI clock mux.
+  * "usb_host_hs_utmi_p1_clk" - Port 1 UTMI clock gate.
+  * "usb_host_hs_utmi_p2_clk" - Port 2 UTMI clock gate.
+  * "usb_host_hs_utmi_p3_clk" - Port 3 UTMI clock gate.
+  * "usb_host_hs_hsic480m_p1_clk" - Port 1 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic480m_p2_clk" - Port 2 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic480m_p3_clk" - Port 3 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p1_clk" - Port 1 60MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p2_clk" - Port 2 60MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p3_clk" - Port 3 60MHz HSIC clock gate.
+
 Required properties if child node exists:
 
 - #address-cells: Must be 1
index 62fe69724e3b1da6a4b0b8f31c79f85e4dbdca93..c58d70437fce8b0dd11636a5a5f98946d8674d42 100644 (file)
@@ -7,6 +7,16 @@ Required properties:
 - interrupts : should contain the TLL module's interrupt
 - ti,hwmod : must contain "usb_tll_hs"
 
+Optional properties:
+
+- clocks: a list of phandles and clock-specifier pairs, one for each entry in
+  clock-names.
+
+- clock-names: should include:
+  * "usb_tll_hs_usb_ch0_clk" - USB TLL channel 0 clock
+  * "usb_tll_hs_usb_ch1_clk" - USB TLL channel 1 clock
+  * "usb_tll_hs_usb_ch2_clk" - USB TLL channel 2 clock
+
 Example:
 
        usbhstll: usbhstll@4a062000 {
diff --git a/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt b/Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
new file mode 100644 (file)
index 0000000..03518dc
--- /dev/null
@@ -0,0 +1,96 @@
+Qualcomm PM8xxx PMIC multi-function devices
+
+The PM8xxx family of Power Management ICs are used to provide regulated
+voltages and other various functionality to Qualcomm SoCs.
+
+= PROPERTIES
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be one of:
+                   "qcom,pm8058"
+                   "qcom,pm8921"
+
+- #address-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 1
+
+- #size-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 0
+
+- interrupts:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: specifies the interrupt that indicates a subdevice
+                   has generated an interrupt (summary interrupt). The
+                   format of the specifier is defined by the binding document
+                   describing the node's interrupt parent.
+
+- #interrupt-cells:
+       Usage: required
+       Value type : <u32>
+       Definition: must be 2. Specifies the number of cells needed to encode
+                   an interrupt source. The 1st cell contains the interrupt
+                   number. The 2nd cell is the trigger type and level flags
+                   encoded as follows:
+
+                       1 = low-to-high edge triggered
+                       2 = high-to-low edge triggered
+                       4 = active high level-sensitive
+                       8 = active low level-sensitive
+
+- interrupt-controller:
+       Usage: required
+       Value type: <empty>
+       Definition: identifies this node as an interrupt controller
+
+= SUBCOMPONENTS
+
+The PMIC contains multiple independent functions, each described in a subnode.
+The below bindings specify the set of valid subnodes.
+
+== Real-Time Clock
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be one of:
+                   "qcom,pm8058-rtc"
+                   "qcom,pm8921-rtc"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: single entry specifying the base address of the RTC registers
+
+- interrupts:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: single entry specifying the RTC's alarm interrupt
+
+- allow-set-time:
+       Usage: optional
+       Value type: <empty>
+       Definition: indicates that the setting of RTC time is allowed by
+                   the host CPU
+
+= EXAMPLE
+
+       pmicintc: pmic@0 {
+               compatible = "qcom,pm8921";
+               interrupts = <104 8>;
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               rtc@11d {
+                       compatible = "qcom,pm8921-rtc";
+                       reg = <0x11d>;
+                       interrupts = <0x27 0>;
+               };
+       };
index f69bec294f0200d55806109b0c70c94f7ae7c732..802e839b08294f6ef5f54c561b03c1981e395f0c 100644 (file)
@@ -16,20 +16,25 @@ Optional properties:
 - interrupts: Interrupt specifiers for interrupt sources.
 
 Optional nodes:
-- clocks: s2mps11 provides three(AP/CP/BT) buffered 32.768 KHz outputs, so to
-  register these as clocks with common clock framework instantiate a sub-node
-  named "clocks". It uses the common clock binding documented in :
+- clocks: s2mps11 and s5m8767 provide three(AP/CP/BT) buffered 32.768 KHz
+  outputs, so to register these as clocks with common clock framework
+  instantiate a sub-node named "clocks". It uses the common clock binding
+  documented in :
   [Documentation/devicetree/bindings/clock/clock-bindings.txt]
+  The s2mps14 provides two (AP/BT) buffered 32.768 KHz outputs.
   - #clock-cells: should be 1.
 
   - The following is the list of clocks generated by the controller. Each clock
     is assigned an identifier and client nodes use this identifier to specify
     the clock which they consume.
-    Clock               ID
-    ----------------------
-    32KhzAP            0
-    32KhzCP            1
-    32KhzBT            2
+    Clock               ID           Devices
+    ----------------------------------------------------------
+    32KhzAP            0            S2MPS11, S2MPS14, S5M8767
+    32KhzCP            1            S2MPS11, S5M8767
+    32KhzBT            2            S2MPS11, S2MPS14, S5M8767
+
+  - compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps14-clk",
+               "samsung,s5m8767-clk"
 
 - regulators: The regulators of s2mps11 that have to be instantiated should be
 included in a sub-node named 'regulators'. Regulator nodes included in this
@@ -75,7 +80,8 @@ Example:
                compatible = "samsung,s2mps11-pmic";
                reg = <0x66>;
 
-               s2m_osc: clocks{
+               s2m_osc: clocks {
+                       compatible = "samsung,s2mps11-clk";
                        #clock-cells = 1;
                        clock-output-names = "xx", "yy", "zz";
                };
diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
new file mode 100644 (file)
index 0000000..4897bea
--- /dev/null
@@ -0,0 +1,23 @@
+* Altera SOCFPGA specific extensions to the Synopsys Designware Mobile
+  Storage Host Controller
+
+The Synopsys designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core Synopsys dw mshc controller properties described
+by synopsys-dw-mshc.txt and the properties used by the Altera SOCFPGA specific
+extensions to the Synopsys Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+       - "altr,socfpga-dw-mshc": for Altera's SOCFPGA platform
+
+Example:
+
+       mmc: dwmmc0@ff704000 {
+               compatible = "altr,socfpga-dw-mshc";
+               reg = <0xff704000 0x1000>;
+               interrupts = <0 129 4>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
index 03855c8c492a28384619e4a7def0a0b98e527e36..b53f92e252d4a7f48427ca1e123381dc04e91e41 100644 (file)
@@ -5,3 +5,17 @@
   "soft_bch".
 - nand-bus-width : 8 or 16 bus width if not present 8
 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
+
+- nand-ecc-strength: integer representing the number of bits to correct
+                    per ECC step.
+
+- nand-ecc-step-size: integer representing the number of data bytes
+                     that are covered by a single ECC step.
+
+The ECC strength and ECC step size properties define the correction capability
+of a controller. Together, they say a controller can correct "{strength} bit
+errors per {size} bytes".
+
+The interpretation of these parameters is implementation-defined, so not all
+implementations must support all possible combinations. However, implementations
+are encouraged to further specify the value(s) they support.
diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt
new file mode 100644 (file)
index 0000000..c248939
--- /dev/null
@@ -0,0 +1,26 @@
+* ST-Microelectronics SPI FSM Serial (NOR) Flash Controller
+
+Required properties:
+  - compatible : Should be "st,spi-fsm"
+  - reg        : Contains register's location and length.
+  - reg-names  : Should contain the reg names "spi-fsm"
+  - interrupts : The interrupt number
+  - pinctrl-0  : Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+
+Optional properties:
+  - st,syscfg          : Phandle to boot-device system configuration registers
+  - st,boot-device-reg : Address of the aforementioned boot-device register(s)
+  - st,boot-device-spi : Expected boot-device value if booted via this device
+
+Example:
+       spifsm: spifsm@fe902000{
+               compatible         = "st,spi-fsm";
+               reg                =  <0xfe902000 0x1000>;
+               reg-names          = "spi-fsm";
+               pinctrl-0          = <&pinctrl_fsm>;
+               st,syscfg          = <&syscfg_rear>;
+               st,boot-device-reg = <0x958>;
+               st,boot-device-spi = <0x1a>;
+               status = "okay";
+       };
+
diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
new file mode 100644 (file)
index 0000000..636f0ac
--- /dev/null
@@ -0,0 +1,27 @@
+Altera SOCFPGA SoC DWMAC controller
+
+This is a variant of the dwmac/stmmac driver an inherits all descriptions
+present in Documentation/devicetree/bindings/net/stmmac.txt.
+
+The device node has additional properties:
+
+Required properties:
+ - compatible  : Should contain "altr,socfpga-stmmac" along with
+                 "snps,dwmac" and any applicable more detailed
+                 designware version numbers documented in stmmac.txt
+ - altr,sysmgr-syscon : Should be the phandle to the system manager node that
+   encompasses the glue register, the register offset, and the register shift.
+
+Example:
+
+gmac0: ethernet@ff700000 {
+       compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+       altr,sysmgr-syscon = <&sysmgr 0x60 0>;
+       status = "disabled";
+       reg = <0xff700000 0x2000>;
+       interrupts = <0 115 4>;
+       interrupt-names = "macirq";
+       mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
+       clocks = <&emac_0_clk>;
+       clocks-names = "stmmaceth";
+};
index 5748351fb9dfce76f148772e4546e97684fb6b67..80c1fb8bfbb8bd778a6682fa75d863ce51d3c0e4 100644 (file)
@@ -31,6 +31,10 @@ Optional properties:
 - reset-names: Should contain the reset signal name "stmmaceth", if a
        reset phandle is given
 - max-frame-size: See ethernet.txt file in the same directory
+- clocks: If present, the first clock should be the GMAC main clock,
+  further clocks may be specified in derived bindings.
+- clocks-names: One name for each entry in the clocks property, the
+  first one should be "stmmaceth".
 
 Examples:
 
@@ -43,4 +47,6 @@ Examples:
                mac-address = [000000000000]; /* Filled in by U-Boot */
                max-frame-size = <3800>;
                phy-mode = "gmii";
+               clocks = <&clock>;
+               clock-names = "stmmaceth">;
        };
index 24cee06915c989cfd6866ad5f3d86e3605cd0ae3..c300391e8d3e3eac79b29d1ed231bf7ce7260a94 100644 (file)
@@ -42,6 +42,10 @@ Required properties:
     - 0xc2000000: prefetchable memory region
   Please refer to the standard PCI bus binding document for a more detailed
   explanation.
+- #interrupt-cells: Size representation for interrupts (must be 1)
+- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties
+  Please refer to the standard PCI bus binding document for a more detailed
+  explanation.
 - clocks: Must contain an entry for each entry in clock-names.
   See ../clocks/clock-bindings.txt for details.
 - clock-names: Must include the following entries:
@@ -86,6 +90,10 @@ SoC DTSI:
                              0 99 0x04>; /* MSI interrupt */
                interrupt-names = "intr", "msi";
 
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
                bus-range = <0x00 0xff>;
                #address-cells = <3>;
                #size-cells = <2>;
index 28f9edb8f19c6f9966610fdac0589407245f3ea7..b422e38946d7851c47a0c9a97772944ab70e60ce 100644 (file)
@@ -74,3 +74,43 @@ phy-consumer@12340000 {
 
 Refer to DT bindings documentation of particular PHY consumer devices for more
 information about required PHYs and the way of specification.
+
+Samsung SATA PHY Controller
+---------------------------
+
+SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
+Each SATA PHY controller should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "samsung,exynos5250-sata-phy"
+- reg : offset and length of the SATA PHY register set;
+- #phy-cells : must be zero
+- clocks : must be exactly one entry
+- clock-names : must be "sata_phyctrl"
+- samsung,exynos-sataphy-i2c-phandle : a phandle to the I2C device, no arguments
+- samsung,syscon-phandle : a phandle to the PMU system controller, no arguments
+
+Example:
+       sata_phy: sata-phy@12170000 {
+               compatible = "samsung,exynos5250-sata-phy";
+               reg = <0x12170000 0x1ff>;
+               clocks = <&clock 287>;
+               clock-names = "sata_phyctrl";
+               #phy-cells = <0>;
+               samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+               samsung,syscon-phandle = <&pmu_syscon>;
+       };
+
+Device-Tree bindings for sataphy i2c client driver
+--------------------------------------------------
+
+Required properties:
+compatible: Should be "samsung,exynos-sataphy-i2c"
+- reg: I2C address of the sataphy i2c device.
+
+Example:
+
+       sata_phy_i2c:sata-phy@38 {
+               compatible = "samsung,exynos-sataphy-i2c";
+               reg = <0x38>;
+       };
index 0347d8350d94712fc26a42e153ea2f06c3363438..af25e77c0e0c34a71659c091ad80b026b28bd817 100644 (file)
@@ -6,8 +6,11 @@ Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
 microcontroller to turn the power off. This driver adds a handler to
 pm_power_off which is called to turn the power off.
 
+Synology NAS devices use a similar scheme, but a different baud rate,
+9600, and a different character, '1'.
+
 Required Properties:
-- compatible: Should be "qnap,power-off"
+- compatible: Should be "qnap,power-off" or "synology,power-off"
 
 - reg: Address and length of the register set for UART1
 - clocks: tclk clock
diff --git a/Documentation/devicetree/bindings/pwm/cirrus,clps711x-pwm.txt b/Documentation/devicetree/bindings/pwm/cirrus,clps711x-pwm.txt
new file mode 100644 (file)
index 0000000..a183db4
--- /dev/null
@@ -0,0 +1,16 @@
+* Cirris Logic CLPS711X PWM controller
+
+Required properties:
+- compatible: Shall contain "cirrus,clps711x-pwm".
+- reg: Physical base address and length of the controller's registers.
+- clocks: phandle + clock specifier pair of the PWM reference clock.
+- #pwm-cells: Should be 1. The cell specifies the index of the channel.
+
+Example:
+       pwm: pwm@80000400 {
+               compatible = "cirrus,ep7312-pwm",
+                            "cirrus,clps711x-pwm";
+               reg = <0x80000400 0x4>;
+               clocks = <&clks 8>;
+               #pwm-cells = <1>;
+       };
diff --git a/Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt b/Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt
new file mode 100644 (file)
index 0000000..0bda229
--- /dev/null
@@ -0,0 +1,35 @@
+Freescale FlexTimer Module (FTM) PWM controller
+
+Required properties:
+- compatible: Should be "fsl,vf610-ftm-pwm".
+- reg: Physical base address and length of the controller's registers
+- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+- clock-names: Should include the following module clock source entries:
+    "ftm_sys" (module clock, also can be used as counter clock),
+    "ftm_ext" (external counter clock),
+    "ftm_fix" (fixed counter clock),
+    "ftm_cnt_clk_en" (external and fixed counter clock enable/disable).
+- clocks: Must contain a phandle and clock specifier for each entry in
+  clock-names, please see clock/clock-bindings.txt for details of the property
+  values.
+- pinctrl-names: Must contain a "default" entry.
+- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
+  See pinctrl/pinctrl-bindings.txt for details of the property values.
+
+
+Example:
+
+pwm0: pwm@40038000 {
+               compatible = "fsl,vf610-ftm-pwm";
+               reg = <0x40038000 0x1000>;
+               #pwm-cells = <3>;
+               clock-names = "ftm_sys", "ftm_ext",
+                               "ftm_fix", "ftm_cnt_clk_en";
+               clocks = <&clks VF610_CLK_FTM0>,
+                       <&clks VF610_CLK_FTM0_EXT_SEL>,
+                       <&clks VF610_CLK_FTM0_FIX_SEL>,
+                       <&clks VF610_CLK_FTM0_EXT_FIX_EN>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pwm0_1>;
+};
diff --git a/Documentation/devicetree/bindings/reset/sirf,rstc.txt b/Documentation/devicetree/bindings/reset/sirf,rstc.txt
new file mode 100644 (file)
index 0000000..0505de7
--- /dev/null
@@ -0,0 +1,42 @@
+CSR SiRFSoC Reset Controller
+======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "sirf,prima2-rstc" or "sirf,marco-rstc"
+- reg: should be register base and length as documented in the
+  datasheet
+- #reset-cells: 1, see below
+
+example:
+
+rstc: reset-controller@88010000 {
+       compatible = "sirf,prima2-rstc";
+       reg = <0x88010000 0x1000>;
+       #reset-cells = <1>;
+};
+
+Specifying reset lines connected to IP modules
+==============================================
+
+The reset controller(rstc) manages various reset sources. This module provides
+reset signals for most blocks in system. Those device nodes should specify the
+reset line on the rstc in their resets property, containing a phandle to the
+rstc device node and a RESET_INDEX specifying which module to reset, as described
+in reset.txt.
+
+For SiRFSoC, RESET_INDEX is just reset_bit defined in SW_RST0 and SW_RST1 registers.
+For modules whose rest_bit is in SW_RST0, its RESET_INDEX is 0~31. For modules whose
+rest_bit is in SW_RST1, its RESET_INDEX is 32~63.
+
+example:
+
+vpp@90020000 {
+       compatible = "sirf,prima2-vpp";
+       reg = <0x90020000 0x10000>;
+       interrupts = <31>;
+       clocks = <&clks 35>;
+       resets = <&rstc 6>;
+};
diff --git a/Documentation/devicetree/bindings/reset/st,sti-powerdown.txt b/Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
new file mode 100644 (file)
index 0000000..5ab26b7
--- /dev/null
@@ -0,0 +1,47 @@
+STMicroelectronics STi family Sysconfig Peripheral Powerdown Reset Controller
+=============================================================================
+
+This binding describes a reset controller device that is used to enable and
+disable on-chip peripheral controllers such as USB and SATA, using
+"powerdown" control bits found in the STi family SoC system configuration
+registers. These have been grouped together into a single reset controller
+device for convenience.
+
+The actual action taken when powerdown is asserted is hardware dependent.
+However, when asserted it may not be possible to access the hardware's
+registers and after an assert/deassert sequence the hardware's previous state
+may no longer be valid.
+
+Please refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "st,<chip>-powerdown"
+       ex: "st,stih415-powerdown", "st,stih416-powerdown"
+- #reset-cells: 1, see below
+
+example:
+
+       powerdown: powerdown-controller {
+               #reset-cells = <1>;
+               compatible = "st,stih415-powerdown";
+       };
+
+
+Specifying powerdown control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the powerdown device node and an
+index specifying which channel to use, as described in reset.txt
+
+example:
+
+       usb1: usb@fe200000 {
+               resets  = <&powerdown STIH41X_USB1_POWERDOWN>;
+       };
+
+Macro definitions for the supported reset channels can be found in:
+
+include/dt-bindings/reset-controller/stih415-resets.h
+include/dt-bindings/reset-controller/stih416-resets.h
diff --git a/Documentation/devicetree/bindings/reset/st,sti-softreset.txt b/Documentation/devicetree/bindings/reset/st,sti-softreset.txt
new file mode 100644 (file)
index 0000000..a8d3d3c
--- /dev/null
@@ -0,0 +1,46 @@
+STMicroelectronics STi family Sysconfig Peripheral SoftReset Controller
+=============================================================================
+
+This binding describes a reset controller device that is used to enable and
+disable on-chip peripheral controllers such as USB and SATA, using
+"softreset" control bits found in the STi family SoC system configuration
+registers.
+
+The actual action taken when softreset is asserted is hardware dependent.
+However, when asserted it may not be possible to access the hardware's
+registers and after an assert/deassert sequence the hardware's previous state
+may no longer be valid.
+
+Please refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "st,<chip>-softreset" example:
+       "st,stih415-softreset" or "st,stih416-softreset";
+- #reset-cells: 1, see below
+
+example:
+
+       softreset: softreset-controller {
+               #reset-cells = <1>;
+               compatible = "st,stih415-softreset";
+       };
+
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the softreset device node and an
+index specifying which channel to use, as described in reset.txt
+
+example:
+
+       ethernet0{
+               resets                  = <&softreset STIH415_ETH0_SOFTRESET>;
+       };
+
+Macro definitions for the supported reset channels can be found in:
+
+include/dt-bindings/reset-controller/stih415-resets.h
+include/dt-bindings/reset-controller/stih416-resets.h
index 9c5d19ac935c335d88400b6724aaff75b5c99712..17c1042b2df895da595191fa8d8acd132fd546e8 100644 (file)
@@ -13,6 +13,8 @@ Required properties:
 Optional properties:
 - atmel,use-dma-rx: use of PDC or DMA for receiving data
 - atmel,use-dma-tx: use of PDC or DMA for transmitting data
+- rts-gpios: specify a GPIO for RTS line. It will use specified PIO instead of the peripheral
+  function pin for the USART RTS feature. If unsure, don't specify this property.
 - add dma bindings for dma transfer:
        - dmas: DMA specifier, consisting of a phandle to DMA controller node,
                memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -33,6 +35,7 @@ Example:
                clock-names = "usart";
                atmel,use-dma-rx;
                atmel,use-dma-tx;
+               rts-gpios = <&pioD 15 0>;
        };
 
 - use DMA:
index 55f51af08bc7cf22de68f8d13e12a380c3155c71..bc2222ca3f2ad8bf0e1e173be5a63a5d09fc76a6 100644 (file)
@@ -57,8 +57,8 @@ Required properties:
  - ep childnode: To specify the number of endpoints and their properties.
 
 Optional properties:
- - atmel,vbus-gpio: If present, specifies a gpio that needs to be
-   activated for the bus to be powered.
+ - atmel,vbus-gpio: If present, specifies a gpio that allows to detect whether
+   vbus is present (USB is connected).
 
 Required child node properties:
  - name: Name of the endpoint.
index 485a9a1efa7a7e89ea465bc5fee72660a3e2049b..3dc231c832b0f36ad6b736be6eaef15dd602dc3f 100644 (file)
@@ -21,7 +21,7 @@ Documentation/devicetree/bindings/mfd/omap-usb-host.txt
 Example for OMAP4:
 
 usbhsehci: ehci@4a064c00 {
-       compatible = "ti,ehci-omap", "usb-ehci";
+       compatible = "ti,ehci-omap";
        reg = <0x4a064c00 0x400>;
        interrupts = <0 77 0x4>;
 };
index 14ab42812a8e609c3687346ace17410bafe85a53..ce8c47cff6d0c98b803c9224929315a1efae10e5 100644 (file)
@@ -9,7 +9,7 @@ Required properties:
 Example for OMAP4:
 
 usbhsohci: ohci@4a064800 {
-       compatible = "ti,ohci-omap3", "usb-ohci";
+       compatible = "ti,ohci-omap3";
        reg = <0x4a064800 0x400>;
        interrupts = <0 76 0x4>;
 };
index 95465d57eb312bf01e3d689166ef736429d3aa2e..0f01c9bf19c8fa7189387f3b1ad7a4e907c020d1 100644 (file)
@@ -35,11 +35,13 @@ dallas      Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom        DAVICOM Semiconductor, Inc.
 dlink  D-Link Systems, Inc.
 denx   Denx Software Engineering
+dmo    Data Modul AG
 edt    Emerging Display Technologies
 emmicro        EM Microelectronic
 epfl   Ecole Polytechnique Fédérale de Lausanne
 epson  Seiko Epson Corp.
 est    ESTeem Wireless Modems
+eukrea  Eukréa Electromatique
 fsl    Freescale Semiconductor
 GEFanuc        GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef    GE Fanuc Intelligent Platforms Embedded Systems, Inc.
@@ -83,10 +85,12 @@ picochip    Picochip Ltd
 powervr        PowerVR (deprecated, use img)
 qca    Qualcomm Atheros, Inc.
 qcom   Qualcomm Technologies, Inc
+qnap   QNAP Systems, Inc.
 ralink Mediatek/Ralink Technology Corp.
 ramtron        Ramtron International
 realtek Realtek Semiconductor Corp.
 renesas        Renesas Electronics Corporation
+ricoh  Ricoh Co. Ltd.
 rockchip       Fuzhou Rockchip Electronics Co., Ltd
 samsung        Samsung Semiconductor
 sbs    Smart Battery System
@@ -94,6 +98,7 @@ schindler     Schindler
 sil    Silicon Image
 silabs Silicon Laboratories
 simtek
+sii    Seiko Instruments, Inc.
 sirf   SiRF Technology, Inc.
 smsc   Standard Microsystems Corporation
 snps   Synopsys, Inc.
@@ -101,12 +106,14 @@ spansion  Spansion Inc.
 st     STMicroelectronics
 ste    ST-Ericsson
 stericsson     ST-Ericsson
+synology       Synology, Inc.
 ti     Texas Instruments
 tlm    Trusted Logic Mobility
 toshiba        Toshiba Corporation
 toumaz Toumaz
 v3     V3 Semiconductor
 via    VIA Technologies, Inc.
+voipac Voipac Technologies s.r.o.
 winbond Winbond Electronics corp.
 wlf    Wolfson Microelectronics
 wm     Wondermedia Technologies, Inc.
diff --git a/Documentation/devicetree/bindings/video/analog-tv-connector.txt b/Documentation/devicetree/bindings/video/analog-tv-connector.txt
new file mode 100644 (file)
index 0000000..0218fcd
--- /dev/null
@@ -0,0 +1,25 @@
+Analog TV Connector
+===================
+
+Required properties:
+- compatible: "composite-connector" or "svideo-connector"
+
+Optional properties:
+- label: a symbolic name for the connector
+
+Required nodes:
+- Video port for TV input
+
+Example
+-------
+
+tv: connector {
+       compatible = "composite-connector";
+       label = "tv";
+
+       port {
+               tv_connector_in: endpoint {
+                       remote-endpoint = <&venc_out>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/video/dvi-connector.txt b/Documentation/devicetree/bindings/video/dvi-connector.txt
new file mode 100644 (file)
index 0000000..fc53f7c
--- /dev/null
@@ -0,0 +1,35 @@
+DVI Connector
+==============
+
+Required properties:
+- compatible: "dvi-connector"
+
+Optional properties:
+- label: a symbolic name for the connector
+- ddc-i2c-bus: phandle to the i2c bus that is connected to DVI DDC
+- analog: the connector has DVI analog pins
+- digital: the connector has DVI digital pins
+- dual-link: the connector has pins for DVI dual-link
+
+Required nodes:
+- Video port for DVI input
+
+Note: One (or both) of 'analog' or 'digital' must be set.
+
+Example
+-------
+
+dvi0: connector@0 {
+       compatible = "dvi-connector";
+       label = "dvi";
+
+       digital;
+
+       ddc-i2c-bus = <&i2c3>;
+
+       port {
+               dvi_connector_in: endpoint {
+                       remote-endpoint = <&tfp410_out>;
+               };
+       };
+};
index 46da08db186aa250450e121fb8f65f7a1505428c..0329f60d431e10ce5feb14878d654649d9767543 100644 (file)
@@ -15,8 +15,12 @@ Required nodes:
        - fsl,pcr: LCDC PCR value
 
 Optional properties:
+- lcd-supply: Regulator for LCD supply voltage.
 - fsl,dmacr: DMA Control Register value. This is optional. By default, the
        register is not modified as recommended by the datasheet.
+- fsl,lpccr: Contrast Control Register value. This property provides the
+       default value for the contrast control register.
+       If that property is ommited, the register is zeroed.
 - fsl,lscr1: LCDC Sharp Configuration Register value.
 
 Example:
diff --git a/Documentation/devicetree/bindings/video/hdmi-connector.txt b/Documentation/devicetree/bindings/video/hdmi-connector.txt
new file mode 100644 (file)
index 0000000..ccccc19
--- /dev/null
@@ -0,0 +1,28 @@
+HDMI Connector
+==============
+
+Required properties:
+- compatible: "hdmi-connector"
+- type: the HDMI connector type: "a", "b", "c", "d" or "e"
+
+Optional properties:
+- label: a symbolic name for the connector
+
+Required nodes:
+- Video port for HDMI input
+
+Example
+-------
+
+hdmi0: connector@1 {
+       compatible = "hdmi-connector";
+       label = "hdmi";
+
+       type = "a";
+
+       port {
+               hdmi_connector_in: endpoint {
+                       remote-endpoint = <&tpd12s015_out>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/video/panel-dsi-cm.txt b/Documentation/devicetree/bindings/video/panel-dsi-cm.txt
new file mode 100644 (file)
index 0000000..dce48eb
--- /dev/null
@@ -0,0 +1,29 @@
+Generic MIPI DSI Command Mode Panel
+===================================
+
+Required properties:
+- compatible: "panel-dsi-cm"
+
+Optional properties:
+- label: a symbolic name for the panel
+- reset-gpios: panel reset gpio
+- te-gpios: panel TE gpio
+
+Required nodes:
+- Video port for DSI input
+
+Example
+-------
+
+lcd0: display {
+       compatible = "tpo,taal", "panel-dsi-cm";
+       label = "lcd0";
+
+       reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
+
+       port {
+               lcd0_in: endpoint {
+                       remote-endpoint = <&dsi1_out_ep>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/video/sony,acx565akm.txt b/Documentation/devicetree/bindings/video/sony,acx565akm.txt
new file mode 100644 (file)
index 0000000..e123332
--- /dev/null
@@ -0,0 +1,30 @@
+Sony ACX565AKM SDI Panel
+========================
+
+Required properties:
+- compatible: "sony,acx565akm"
+
+Optional properties:
+- label: a symbolic name for the panel
+- reset-gpios: panel reset gpio
+
+Required nodes:
+- Video port for SDI input
+
+Example
+-------
+
+acx565akm@2 {
+       compatible = "sony,acx565akm";
+       spi-max-frequency = <6000000>;
+       reg = <2>;
+
+       label = "lcd";
+       reset-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* 90 */
+
+       port {
+               lcd_in: endpoint {
+                       remote-endpoint = <&sdi_out>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/video/ti,omap-dss.txt b/Documentation/devicetree/bindings/video/ti,omap-dss.txt
new file mode 100644 (file)
index 0000000..d5f1a3f
--- /dev/null
@@ -0,0 +1,211 @@
+Texas Instruments OMAP Display Subsystem
+========================================
+
+Generic Description
+-------------------
+
+This document is a generic description of the OMAP Display Subsystem bindings.
+Binding details for each OMAP SoC version are described in respective binding
+documentation.
+
+The OMAP Display Subsystem (DSS) hardware consists of DSS Core, DISPC module and
+a number of encoder modules. All DSS versions contain DSS Core and DISPC, but
+the encoder modules vary.
+
+The DSS Core is the parent of the other DSS modules, and manages clock routing,
+integration to the SoC, etc.
+
+DISPC is the display controller, which reads pixels from the memory and outputs
+a RGB pixel stream to encoders.
+
+The encoder modules encode the received RGB pixel stream to a video output like
+HDMI, MIPI DPI, etc.
+
+Video Ports
+-----------
+
+The DSS Core and the encoders have video port outputs. The structure of the
+video ports is described in Documentation/devicetree/bindings/video/video-
+ports.txt, and the properties for the ports and endpoints for each encoder are
+described in the SoC's DSS binding documentation.
+
+The video ports are used to describe the connections to external hardware, like
+panels or external encoders.
+
+Aliases
+-------
+
+The board dts file may define aliases for displays to assign "displayX" style
+name for each display. If no aliases are defined, a semi-random number is used
+for the display.
+
+Example
+-------
+
+A shortened example of the DSS description for OMAP4, with non-relevant parts
+removed, defined in omap4.dtsi:
+
+dss: dss@58000000 {
+       compatible = "ti,omap4-dss";
+       reg = <0x58000000 0x80>;
+       status = "disabled";
+       ti,hwmods = "dss_core";
+       clocks = <&dss_dss_clk>;
+       clock-names = "fck";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges;
+
+       dispc@58001000 {
+               compatible = "ti,omap4-dispc";
+               reg = <0x58001000 0x1000>;
+               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+               ti,hwmods = "dss_dispc";
+               clocks = <&dss_dss_clk>;
+               clock-names = "fck";
+       };
+
+       hdmi: encoder@58006000 {
+               compatible = "ti,omap4-hdmi";
+               reg = <0x58006000 0x200>,
+                     <0x58006200 0x100>,
+                     <0x58006300 0x100>,
+                     <0x58006400 0x1000>;
+               reg-names = "wp", "pll", "phy", "core";
+               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+               ti,hwmods = "dss_hdmi";
+               clocks = <&dss_48mhz_clk>, <&dss_sys_clk>;
+               clock-names = "fck", "sys_clk";
+       };
+};
+
+A shortened example of the board description for OMAP4 Panda board, defined in
+omap4-panda.dts.
+
+The Panda board has a DVI and a HDMI connector, and the board contains a TFP410
+chip (MIPI DPI to DVI encoder) and a TPD12S015 chip (HDMI ESD protection & level
+shifter). The video pipelines for the connectors are formed as follows:
+
+DSS Core --(MIPI DPI)--> TFP410 --(DVI)--> DVI Connector
+OMAP HDMI --(HDMI)--> TPD12S015 --(HDMI)--> HDMI Connector
+
+/ {
+       aliases {
+               display0 = &dvi0;
+               display1 = &hdmi0;
+       };
+
+       tfp410: encoder@0 {
+               compatible = "ti,tfp410";
+               gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;     /* 0, power-down */
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&tfp410_pins>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tfp410_in: endpoint@0 {
+                                       remote-endpoint = <&dpi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tfp410_out: endpoint@0 {
+                                       remote-endpoint = <&dvi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       dvi0: connector@0 {
+               compatible = "dvi-connector";
+               label = "dvi";
+
+               i2c-bus = <&i2c3>;
+
+               port {
+                       dvi_connector_in: endpoint {
+                               remote-endpoint = <&tfp410_out>;
+                       };
+               };
+       };
+
+       tpd12s015: encoder@1 {
+               compatible = "ti,tpd12s015";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&tpd12s015_pins>;
+
+               gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,   /* 60, CT CP HPD */
+                       <&gpio2 9 GPIO_ACTIVE_HIGH>,    /* 41, LS OE */
+                       <&gpio2 31 GPIO_ACTIVE_HIGH>;   /* 63, HPD */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tpd12s015_in: endpoint@0 {
+                                       remote-endpoint = <&hdmi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tpd12s015_out: endpoint@0 {
+                                       remote-endpoint = <&hdmi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       hdmi0: connector@1 {
+               compatible = "hdmi-connector";
+               label = "hdmi";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&tpd12s015_out>;
+                       };
+               };
+       };
+};
+
+&dss {
+       status = "ok";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&dss_dpi_pins>;
+
+       port {
+               dpi_out: endpoint {
+                       remote-endpoint = <&tfp410_in>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&hdmi {
+       status = "ok";
+       vdda-supply = <&vdac>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&dss_hdmi_pins>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&tpd12s015_in>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/video/ti,omap2-dss.txt b/Documentation/devicetree/bindings/video/ti,omap2-dss.txt
new file mode 100644 (file)
index 0000000..fa8bb2e
--- /dev/null
@@ -0,0 +1,54 @@
+Texas Instruments OMAP2 Display Subsystem
+=========================================
+
+See Documentation/devicetree/bindings/video/ti,omap-dss.txt for generic
+description about OMAP Display Subsystem bindings.
+
+DSS Core
+--------
+
+Required properties:
+- compatible: "ti,omap2-dss"
+- reg: address and length of the register space
+- ti,hwmods: "dss_core"
+
+Optional nodes:
+- Video port for DPI output
+
+DPI Endpoint required properties:
+- data-lines: number of lines used
+
+
+DISPC
+-----
+
+Required properties:
+- compatible: "ti,omap2-dispc"
+- reg: address and length of the register space
+- ti,hwmods: "dss_dispc"
+- interrupts: the DISPC interrupt
+
+
+RFBI
+----
+
+Required properties:
+- compatible: "ti,omap2-rfbi"
+- reg: address and length of the register space
+- ti,hwmods: "dss_rfbi"
+
+
+VENC
+----
+
+Required properties:
+- compatible: "ti,omap2-venc"
+- reg: address and length of the register space
+- ti,hwmods: "dss_venc"
+- vdda-supply: power supply for DAC
+
+VENC Endpoint required properties:
+
+Required properties:
+- ti,invert-polarity: invert the polarity of the video signal
+- ti,channels: 1 for composite, 2 for s-video
diff --git a/Documentation/devicetree/bindings/video/ti,omap3-dss.txt b/Documentation/devicetree/bindings/video/ti,omap3-dss.txt
new file mode 100644 (file)
index 0000000..0023fa4
--- /dev/null
@@ -0,0 +1,83 @@
+Texas Instruments OMAP3 Display Subsystem
+=========================================
+
+See Documentation/devicetree/bindings/video/ti,omap-dss.txt for generic
+description about OMAP Display Subsystem bindings.
+
+DSS Core
+--------
+
+Required properties:
+- compatible: "ti,omap3-dss"
+- reg: address and length of the register space
+- ti,hwmods: "dss_core"
+- clocks: handle to fclk
+- clock-names: "fck"
+
+Optional nodes:
+- Video ports:
+       - Port 0: DPI output
+       - Port 1: SDI output
+
+DPI Endpoint required properties:
+- data-lines: number of lines used
+
+SDI Endpoint required properties:
+- datapairs: number of datapairs used
+
+
+DISPC
+-----
+
+Required properties:
+- compatible: "ti,omap3-dispc"
+- reg: address and length of the register space
+- ti,hwmods: "dss_dispc"
+- interrupts: the DISPC interrupt
+- clocks: handle to fclk
+- clock-names: "fck"
+
+
+RFBI
+----
+
+Required properties:
+- compatible: "ti,omap3-rfbi"
+- reg: address and length of the register space
+- ti,hwmods: "dss_rfbi"
+- clocks: handles to fclk and iclk
+- clock-names: "fck", "ick"
+
+
+VENC
+----
+
+Required properties:
+- compatible: "ti,omap3-venc"
+- reg: address and length of the register space
+- ti,hwmods: "dss_venc"
+- vdda-supply: power supply for DAC
+- clocks: handle to fclk
+- clock-names: "fck"
+
+VENC Endpoint required properties:
+- ti,invert-polarity: invert the polarity of the video signal
+- ti,channels: 1 for composite, 2 for s-video
+
+
+DSI
+---
+
+Required properties:
+- compatible: "ti,omap3-dsi"
+- reg: addresses and lengths of the register spaces for 'proto', 'phy' and 'pll'
+- reg-names: "proto", "phy", "pll"
+- interrupts: the DSI interrupt line
+- ti,hwmods: "dss_dsi1"
+- vdd-supply: power supply for DSI
+- clocks: handles to fclk and pll clock
+- clock-names: "fck", "sys_clk"
+
+DSI Endpoint required properties:
+- lanes: list of pin numbers for the DSI lanes: CLK+, CLK-, DATA0+, DATA0-,
+  DATA1+, DATA1-, ...
diff --git a/Documentation/devicetree/bindings/video/ti,omap4-dss.txt b/Documentation/devicetree/bindings/video/ti,omap4-dss.txt
new file mode 100644 (file)
index 0000000..f85d6fc
--- /dev/null
@@ -0,0 +1,111 @@
+Texas Instruments OMAP4 Display Subsystem
+=========================================
+
+See Documentation/devicetree/bindings/video/ti,omap-dss.txt for generic
+description about OMAP Display Subsystem bindings.
+
+DSS Core
+--------
+
+Required properties:
+- compatible: "ti,omap4-dss"
+- reg: address and length of the register space
+- ti,hwmods: "dss_core"
+- clocks: handle to fclk
+- clock-names: "fck"
+
+Required nodes:
+- DISPC
+
+Optional nodes:
+- DSS Submodules: RFBI, VENC, DSI, HDMI
+- Video port for DPI output
+
+DPI Endpoint required properties:
+- data-lines: number of lines used
+
+
+DISPC
+-----
+
+Required properties:
+- compatible: "ti,omap4-dispc"
+- reg: address and length of the register space
+- ti,hwmods: "dss_dispc"
+- interrupts: the DISPC interrupt
+- clocks: handle to fclk
+- clock-names: "fck"
+
+
+RFBI
+----
+
+Required properties:
+- compatible: "ti,omap4-rfbi"
+- reg: address and length of the register space
+- ti,hwmods: "dss_rfbi"
+- clocks: handles to fclk and iclk
+- clock-names: "fck", "ick"
+
+Optional nodes:
+- Video port for RFBI output
+- RFBI controlled peripherals
+
+
+VENC
+----
+
+Required properties:
+- compatible: "ti,omap4-venc"
+- reg: address and length of the register space
+- ti,hwmods: "dss_venc"
+- vdda-supply: power supply for DAC
+- clocks: handle to fclk
+- clock-names: "fck"
+
+Optional nodes:
+- Video port for VENC output
+
+VENC Endpoint required properties:
+- ti,invert-polarity: invert the polarity of the video signal
+- ti,channels: 1 for composite, 2 for s-video
+
+
+DSI
+---
+
+Required properties:
+- compatible: "ti,omap4-dsi"
+- reg: addresses and lengths of the register spaces for 'proto', 'phy' and 'pll'
+- reg-names: "proto", "phy", "pll"
+- interrupts: the DSI interrupt line
+- ti,hwmods: "dss_dsi1" or "dss_dsi2"
+- vdd-supply: power supply for DSI
+- clocks: handles to fclk and pll clock
+- clock-names: "fck", "sys_clk"
+
+Optional nodes:
+- Video port for DSI output
+- DSI controlled peripherals
+
+DSI Endpoint required properties:
+- lanes: list of pin numbers for the DSI lanes: CLK+, CLK-, DATA0+, DATA0-,
+  DATA1+, DATA1-, ...
+
+
+HDMI
+----
+
+Required properties:
+- compatible: "ti,omap4-hdmi"
+- reg: addresses and lengths of the register spaces for 'wp', 'pll', 'phy',
+       'core'
+- reg-names: "wp", "pll", "phy", "core"
+- interrupts: the HDMI interrupt line
+- ti,hwmods: "dss_hdmi"
+- vdda-supply: vdda power supply
+- clocks: handles to fclk and pll clock
+- clock-names: "fck", "sys_clk"
+
+Optional nodes:
+- Video port for HDMI output
diff --git a/Documentation/devicetree/bindings/video/ti,tfp410.txt b/Documentation/devicetree/bindings/video/ti,tfp410.txt
new file mode 100644 (file)
index 0000000..2cbe32a
--- /dev/null
@@ -0,0 +1,41 @@
+TFP410 DPI to DVI encoder
+=========================
+
+Required properties:
+- compatible: "ti,tfp410"
+
+Optional properties:
+- powerdown-gpios: power-down gpio
+
+Required nodes:
+- Video port 0 for DPI input
+- Video port 1 for DVI output
+
+Example
+-------
+
+tfp410: encoder@0 {
+       compatible = "ti,tfp410";
+       powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+
+                       tfp410_in: endpoint@0 {
+                               remote-endpoint = <&dpi_out>;
+                       };
+               };
+
+               port@1 {
+                       reg = <1>;
+
+                       tfp410_out: endpoint@0 {
+                               remote-endpoint = <&dvi_connector_in>;
+                       };
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/video/ti,tpd12s015.txt b/Documentation/devicetree/bindings/video/ti,tpd12s015.txt
new file mode 100644 (file)
index 0000000..26e6d32
--- /dev/null
@@ -0,0 +1,44 @@
+TPD12S015 HDMI level shifter and ESD protection chip
+====================================================
+
+Required properties:
+- compatible: "ti,tpd12s015"
+
+Optional properties:
+- gpios: CT CP HPD, LS OE and HPD gpios
+
+Required nodes:
+- Video port 0 for HDMI input
+- Video port 1 for HDMI output
+
+Example
+-------
+
+tpd12s015: encoder@1 {
+       compatible = "ti,tpd12s015";
+
+       gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,   /* 60, CT CP HPD */
+               <&gpio2 9 GPIO_ACTIVE_HIGH>,    /* 41, LS OE */
+               <&gpio2 31 GPIO_ACTIVE_HIGH>;   /* 63, HPD */
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+
+                       tpd12s015_in: endpoint@0 {
+                               remote-endpoint = <&hdmi_out>;
+                       };
+               };
+
+               port@1 {
+                       reg = <1>;
+
+                       tpd12s015_out: endpoint@0 {
+                               remote-endpoint = <&hdmi_connector_in>;
+                       };
+               };
+       };
+};
index 5dc8d30061ce0b9c01347864135c5f0a40763751..de11eb4c121fff77e119e7ec251707f69badecc5 100644 (file)
@@ -3,17 +3,24 @@
 Required Properties:
 
 - Compatibility : "marvell,orion-wdt"
-- reg          : Address of the timer registers
+                 "marvell,armada-370-wdt"
+                 "marvell,armada-xp-wdt"
+
+- reg          : Should contain two entries: first one with the
+                 timer control address, second one with the
+                 rstout enable address.
 
 Optional properties:
 
+- interrupts   : Contains the IRQ for watchdog expiration
 - timeout-sec  : Contains the watchdog timeout in seconds
 
 Example:
 
        wdt@20300 {
                compatible = "marvell,orion-wdt";
-               reg = <0x20300 0x28>;
+               reg = <0x20300 0x28>, <0x20108 0x4>;
+               interrupts = <3>;
                timeout-sec = <10>;
                status = "okay";
        };
index 5d5ee4c13fa63dbc1d139c5875c1748bb3ae54a3..d91b8be80b66ebb8cbeabc4822a0a91dccf325eb 100755 (executable)
@@ -28,8 +28,8 @@ use IO::Handle;
                "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
                "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
                "lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
-               "drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137",
-               "drxk_pctv", "drxk_terratec_htc_stick", "sms1xxx_hcw");
+               "drxk_hauppauge_hvr930c", "tda10071", "it9135", "drxk_pctv",
+               "drxk_terratec_htc_stick", "sms1xxx_hcw");
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -727,24 +727,6 @@ sub it9135 {
        "$fwfile1 $fwfile2"
 }
 
-sub it9137 {
-    my $url = "http://kworld.server261.com/kworld/CD/ITE_TiVme/V1.00/";
-    my $zipfile = "Driver_V10.323.1.0412.100412.zip";
-    my $hash = "79b597dc648698ed6820845c0c9d0d37";
-    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
-    my $drvfile = "Driver_V10.323.1.0412.100412/Data/x86/IT9135BDA.sys";
-    my $fwfile = "dvb-usb-it9137-01.fw";
-
-    checkstandard();
-
-    wgetfile($zipfile, $url . $zipfile);
-    verify($zipfile, $hash);
-    unzip($zipfile, $tmpdir);
-    extract("$tmpdir/$drvfile", 69632, 5731, "$fwfile");
-
-    "$fwfile"
-}
-
 sub tda10071 {
     my $sourcefile = "PCTV_460e_reference.zip";
     my $url = "ftp://ftp.pctvsystems.com/TV/driver/PCTV%2070e%2080e%20100e%20320e%20330e%20800e/";
diff --git a/Documentation/dvb/it9137.txt b/Documentation/dvb/it9137.txt
deleted file mode 100644 (file)
index 9e6726e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-To extract firmware for Kworld UB499-2T (id 1b80:e409) you need to copy the
-following file(s) to this directory.
-
-IT9135BDA.sys Dated Mon 22 Mar 2010 02:20:08 GMT
-
-extract using dd
-dd if=IT9135BDA.sys ibs=1 skip=69632 count=5731 of=dvb-usb-it9137-01.fw
-
-copy to default firmware location.
index 56c7e936430f172e135ea8d180682167ce907754..cb4c2cefd45a452b3dabb2bb55587136643c9efb 100644 (file)
@@ -6,7 +6,7 @@ Written by Doug Thompson <dougthompson@xmission.com>
 7 Dec 2005
 17 Jul 2007    Updated
 
-(c) Mauro Carvalho Chehab <mchehab@redhat.com>
+(c) Mauro Carvalho Chehab
 05 Aug 2009    Nehalem interface
 
 EDAC is maintained and written by:
index 5b0c083d7c0e98eccfb315cf6b5cd72f8e73d7e5..f424e0e5b46bb4b2668f33a74ebf5624a92fb6ee 100644 (file)
@@ -47,6 +47,8 @@ prototypes:
        int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
+       int (*rename2) (struct inode *, struct dentry *,
+                       struct inode *, struct dentry *, unsigned int);
        int (*readlink) (struct dentry *, char __user *,int);
        void * (*follow_link) (struct dentry *, struct nameidata *);
        void (*put_link) (struct dentry *, struct nameidata *, void *);
@@ -78,6 +80,7 @@ mkdir:                yes
 unlink:                yes (both)
 rmdir:         yes (both)      (see below)
 rename:                yes (all)       (see below)
+rename2:       yes (all)       (see below)
 readlink:      no
 follow_link:   no
 put_link:      no
@@ -96,7 +99,8 @@ tmpfile:      no
 
        Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
 victim.
-       cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
+       cross-directory ->rename() and rename2() has (per-superblock)
+->s_vfs_rename_sem.
 
 See Documentation/filesystems/directory-locking for more detailed discussion
 of the locking scheme for directory operations.
index b8d284975f0f074c5e2c5d6126e1cf33bb6798d4..25311e113e75415e1962b2e157d3e55d5023aa1c 100644 (file)
@@ -122,6 +122,10 @@ disable_ext_identify   Disable the extension list configured by mkfs, so f2fs
 inline_xattr           Enable the inline xattrs feature.
 inline_data            Enable the inline data feature: New created small(<~3.4k)
                        files can be written into inode block.
+flush_merge           Merge concurrent cache_flush commands as much as possible
+                       to eliminate redundant command issues. If the underlying
+                      device handles the cache_flush command relatively slowly,
+                      recommend to enable this option.
 
 ================================================================================
 DEBUGFS ENTRIES
@@ -169,9 +173,11 @@ Files in /sys/fs/f2fs/<devname>
 
  reclaim_segments             This parameter controls the number of prefree
                               segments to be reclaimed. If the number of prefree
-                             segments is larger than this number, f2fs tries to
-                             conduct checkpoint to reclaim the prefree segments
-                             to free segments. By default, 100 segments, 200MB.
+                             segments is larger than the number of segments
+                             in the proportion to the percentage over total
+                             volume size, f2fs tries to conduct checkpoint to
+                             reclaim the prefree segments to free segments.
+                             By default, 5% over total # of segments.
 
  max_small_discards          This parameter controls the number of discard
                              commands that consist small blocks less than 2MB.
@@ -195,6 +201,17 @@ Files in /sys/fs/f2fs/<devname>
                              cleaning operations. The default value is 4096
                              which covers 8GB block address range.
 
+ dir_level                    This parameter controls the directory level to
+                             support large directory. If a directory has a
+                             number of files, it can reduce the file lookup
+                             latency by increasing this dir_level value.
+                             Otherwise, it needs to decrease this value to
+                             reduce the space overhead. The default value is 0.
+
+ ram_thresh                   This parameter controls the memory footprint used
+                             by free nids and cached nat entries. By default,
+                             10 is set, which indicates 10 MB / 1 GB RAM.
+
 ================================================================================
 USAGE
 ================================================================================
@@ -444,9 +461,11 @@ The number of blocks and buckets are determined by,
   # of blocks in level #n = |
                             `- 4, Otherwise
 
-                             ,- 2^n, if n < MAX_DIR_HASH_DEPTH / 2,
+                             ,- 2^ (n + dir_level),
+                            |            if n < MAX_DIR_HASH_DEPTH / 2,
   # of buckets in level #n = |
-                             `- 2^((MAX_DIR_HASH_DEPTH / 2) - 1), Otherwise
+                             `- 2^((MAX_DIR_HASH_DEPTH / 2 + dir_level) - 1),
+                                         Otherwise
 
 When F2FS finds a file name in a directory, at first a hash value of the file
 name is calculated. Then, F2FS scans the hash table in level #0 to find the
index c53784c119c8ea29a532c4e0d9460dd4801690fd..94eb86287bcb08f3ebc0fa826438fed1af8ded1a 100644 (file)
@@ -347,6 +347,8 @@ struct inode_operations {
        int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
+       int (*rename2) (struct inode *, struct dentry *,
+                       struct inode *, struct dentry *, unsigned int);
        int (*readlink) (struct dentry *, char __user *,int);
         void * (*follow_link) (struct dentry *, struct nameidata *);
         void (*put_link) (struct dentry *, struct nameidata *, void *);
@@ -414,6 +416,20 @@ otherwise noted.
   rename: called by the rename(2) system call to rename the object to
        have the parent and name given by the second inode and dentry.
 
+  rename2: this has an additional flags argument compared to rename.
+       If no flags are supported by the filesystem then this method
+       need not be implemented.  If some flags are supported then the
+       filesystem must return -EINVAL for any unsupported or unknown
+       flags.  Currently the following flags are implemented:
+       (1) RENAME_NOREPLACE: this flag indicates that if the target
+       of the rename exists the rename should fail with -EEXIST
+       instead of replacing the target.  The VFS already checks for
+       existence, so for local filesystems the RENAME_NOREPLACE
+       implementation is equivalent to plain rename.
+       (2) RENAME_EXCHANGE: exchange source and target.  Both must
+       exist; this is checked by the VFS.  Unlike plain rename,
+       source and target may be of different type.
+
   readlink: called by the readlink(2) system call. Only required if
        you want to support reading symbolic links
 
index 0c1635082c9951c6b9c1b038a283ba5ef68ae0bf..fe80e9adebfa452d184cf8ec75491cb4d26785b4 100644 (file)
@@ -2,7 +2,7 @@ Kernel driver it87
 ==================
 
 Supported chips:
-  * IT8603E
+  * IT8603E/IT8623E
     Prefix: 'it8603'
     Addresses scanned: from Super I/O config space (8 I/O ports)
     Datasheet: Not publicly available
@@ -94,9 +94,9 @@ motherboard models.
 Description
 -----------
 
-This driver implements support for the IT8603E, IT8705F, IT8712F, IT8716F,
-IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8771E, IT8772E,
-IT8782F, IT8783E/F, and SiS950 chips.
+This driver implements support for the IT8603E, IT8623E, IT8705F, IT8712F,
+IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8771E,
+IT8772E, IT8782F, IT8783E/F, and SiS950 chips.
 
 These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
 joysticks and other miscellaneous stuff. For hardware monitoring, they
@@ -133,7 +133,7 @@ to userspace applications.
 The IT8728F, IT8771E, and IT8772E are considered compatible with the IT8721F,
 until a datasheet becomes available (hopefully.)
 
-The IT8603E is a custom design, hardware monitoring part is similar to
+The IT8603E/IT8623E is a custom design, hardware monitoring part is similar to
 IT8728F. It only supports 16-bit fan mode, the full speed mode of the
 fan is not supported (value 0 of pwmX_enable).
 
index 09b583e38907422b027d62dee999282661c0f583..09c2382ad0556b196a3b4bb941b9e86597e8ebc5 100644 (file)
@@ -53,7 +53,8 @@ This has a number of options available:
 
      If this is off (ie. "permissive"), then modules for which the key is not
      available and modules that are unsigned are permitted, but the kernel will
-     be marked as being tainted.
+     be marked as being tainted, and the concerned modules will be marked as
+     tainted, shown with the character 'E'.
 
      If this is on (ie. "restrictive"), only modules that have a valid
      signature that can be verified by a public key in the kernel's possession
index 13032c0140d430b3bc15a5e4a5771eecfc208f4e..e3155995ddd878c59d60d3519f2addaac716a743 100644 (file)
@@ -265,6 +265,9 @@ characters, each representing a particular tainted value.
 
  13: 'O' if an externally-built ("out-of-tree") module has been loaded.
 
+ 14: 'E' if an unsigned module has been loaded in a kernel supporting
+     module signature.
+
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent: even if an offending module is
index ec8be46bf48da2146cbf2689a6aa51a315e1f2f4..271a09db6629f539753b864a567e78f011d0efde 100644 (file)
@@ -785,6 +785,8 @@ can be ORed together:
 1024 - A module from drivers/staging was loaded.
 2048 - The system is working around a severe firmware bug.
 4096 - An out-of-tree module has been loaded.
+8192 - An unsigned module has been loaded in a kernel supporting module
+       signature.
 
 ==============================================================
 
index f14475011feab6604a8abe5edf5422cdb10a203e..2f6e93597ce0a85193506fecea3e0bf6b9f22e78 100644 (file)
 162 -> Adlink MPG24
 163 -> Bt848 Capture 14MHz
 164 -> CyberVision CV06 (SV)
+165 -> Kworld V-Stream Xpert TV PVR878
index 9f056d512e35e6313e797ec4cf09621aed7c097e..fc009d0ee7d63e6566be0a7be5a331c4e0ccbce0 100644 (file)
  30 -> NetUP Dual DVB-T/C-CI RF                            [1b55:e2e4]
  31 -> Leadtek Winfast PxDVR3200 H XC4000                  [107d:6f39]
  32 -> MPX-885
- 33 -> Mygica X8507                                        [14f1:8502]
+ 33 -> Mygica X8502/X8507 ISDB-T                           [14f1:8502]
  34 -> TerraTec Cinergy T PCIe Dual                        [153b:117e]
  35 -> TeVii S471                                          [d471:9022]
  36 -> Hauppauge WinTV-HVR1255                             [0070:2259]
  37 -> Prof Revolution DVB-S2 8000                         [8000:3034]
  38 -> Hauppauge WinTV-HVR4400                             [0070:c108,0070:c138,0070:c12a,0070:c1f8]
  39 -> AVerTV Hybrid Express Slim HC81R                    [1461:d939]
+ 40 -> TurboSight TBS 6981                                 [6981:8888]
+ 41 -> TurboSight TBS 6980                                 [6980:8888]
+ 42 -> Leadtek Winfast PxPVR2200                           [107d:6f21]
index e8186440510250cb7f7abf5e34d69e796fa84962..e085b1243b451656e0364d07d8c8ddf4bc3a7c85 100644 (file)
@@ -57,6 +57,7 @@
  56 -> Pinnacle Hybrid Pro (330e)               (em2882)        [2304:0226]
  57 -> Kworld PlusTV HD Hybrid 330              (em2883)        [eb1a:a316]
  58 -> Compro VideoMate ForYou/Stereo           (em2820/em2840) [185b:2041]
+ 59 -> Pinnacle PCTV HD Mini                    (em2874)        [2304:023f]
  60 -> Hauppauge WinTV HVR 850                  (em2883)        [2040:651f]
  61 -> Pixelview PlayTV Box 4 USB 2.0           (em2820/em2840)
  62 -> Gadmei TVR200                            (em2820/em2840)
@@ -86,3 +87,8 @@
  86 -> PCTV QuatroStick nano (520e)             (em2884)        [2013:0251]
  87 -> Terratec Cinergy HTC USB XS              (em2884)        [0ccd:008e,0ccd:00ac]
  88 -> C3 Tech Digital Duo HDTV/SDTV USB        (em2884)        [1b80:e755]
+ 89 -> Delock 61959                             (em2874)        [1b80:e1cc]
+ 90 -> KWorld USB ATSC TV Stick UB435-Q V2      (em2874)        [1b80:e346]
+ 91 -> SpeedLink Vicious And Devine Laplace webcam (em2765)        [1ae7:9003,1ae7:9004]
+ 92 -> PCTV DVB-S2 Stick (461e)                 (em28178)
+ 93 -> KWorld USB ATSC TV Stick UB435-Q V3      (em2874)        [1b80:e34c]
index e51f1b5b7324baf92a620d3c941f6bae06b807ea..7d6e160724bd4b15547d579556dbb3d5399d98d0 100644 (file)
@@ -151,9 +151,8 @@ CONFIG_S5P_DEV_FIMC1  \
 CONFIG_S5P_DEV_FIMC2  |    optional
 CONFIG_S5P_DEV_FIMC3  |
 CONFIG_S5P_SETUP_FIMC /
-CONFIG_S5P_SETUP_MIPIPHY \
-CONFIG_S5P_DEV_CSIS0     | optional for MIPI-CSI interface
-CONFIG_S5P_DEV_CSIS1     /
+CONFIG_S5P_DEV_CSIS0  \    optional for MIPI-CSI interface
+CONFIG_S5P_DEV_CSIS1  /
 
 Except that, relevant s5p_device_fimc? should be registered in the machine code
 in addition to a "s5p-fimc-md" platform device to which the media device driver
index 1e6b6531bbcc2af5734926aafc873f635cc5d632..d2ba80bb7af5fdd89f3235eae2c21de050b581e7 100644 (file)
@@ -55,6 +55,7 @@ zc3xx         0458:700f       Genius VideoCam Web V2
 sonixj         0458:7025       Genius Eye 311Q
 sn9c20x                0458:7029       Genius Look 320s
 sonixj         0458:702e       Genius Slim 310 NB
+sn9c20x                0458:7045       Genius Look 1320 V2
 sn9c20x                0458:704a       Genius Slim 1320
 sn9c20x                0458:704c       Genius i-Look 1321
 sn9c20x                045e:00f4       LifeCam VX-6000 (SN9C20x + OV9650)
index 6c4866b49eb57e07b1696fc5d7fa7e4d60294b9a..667a43361706c28c5343944de9836b40009cad8b 100644 (file)
@@ -34,6 +34,10 @@ So this framework sets up the basic building blocks that all drivers
 need and this same framework should make it much easier to refactor
 common code into utility functions shared by all drivers.
 
+A good example to look at as a reference is the v4l2-pci-skeleton.c
+source that is available in this directory. It is a skeleton driver for
+a PCI capture card, and demonstrates how to use the V4L2 driver
+framework. It can be used as a template for real PCI video capture driver.
 
 Structure of a driver
 ---------------------
@@ -768,6 +772,7 @@ types exist:
 VFL_TYPE_GRABBER: videoX for video input/output devices
 VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext)
 VFL_TYPE_RADIO: radioX for radio tuners
+VFL_TYPE_SDR: swradioX for Software Defined Radio tuners
 
 The last argument gives you a certain amount of control over the device
 device node number used (i.e. the X in videoX). Normally you will pass -1
diff --git a/Documentation/video4linux/v4l2-pci-skeleton.c b/Documentation/video4linux/v4l2-pci-skeleton.c
new file mode 100644 (file)
index 0000000..3a1c0d2
--- /dev/null
@@ -0,0 +1,913 @@
+/*
+ * This is a V4L2 PCI Skeleton Driver. It gives an initial skeleton source
+ * for use with other PCI drivers.
+ *
+ * This skeleton PCI driver assumes that the card has an S-Video connector as
+ * input 0 and an HDMI connector as input 1.
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-dma-contig.h>
+
+MODULE_DESCRIPTION("V4L2 PCI Skeleton Driver");
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl);
+
+/**
+ * struct skeleton - All internal data for one instance of device
+ * @pdev: PCI device
+ * @v4l2_dev: top-level v4l2 device struct
+ * @vdev: video node structure
+ * @ctrl_handler: control handler structure
+ * @lock: ioctl serialization mutex
+ * @std: current SDTV standard
+ * @timings: current HDTV timings
+ * @format: current pix format
+ * @input: current video input (0 = SDTV, 1 = HDTV)
+ * @queue: vb2 video capture queue
+ * @alloc_ctx: vb2 contiguous DMA context
+ * @qlock: spinlock controlling access to buf_list and sequence
+ * @buf_list: list of buffers queued for DMA
+ * @sequence: frame sequence counter
+ */
+struct skeleton {
+       struct pci_dev *pdev;
+       struct v4l2_device v4l2_dev;
+       struct video_device vdev;
+       struct v4l2_ctrl_handler ctrl_handler;
+       struct mutex lock;
+       v4l2_std_id std;
+       struct v4l2_dv_timings timings;
+       struct v4l2_pix_format format;
+       unsigned input;
+
+       struct vb2_queue queue;
+       struct vb2_alloc_ctx *alloc_ctx;
+
+       spinlock_t qlock;
+       struct list_head buf_list;
+       unsigned int sequence;
+};
+
+struct skel_buffer {
+       struct vb2_buffer vb;
+       struct list_head list;
+};
+
+static inline struct skel_buffer *to_skel_buffer(struct vb2_buffer *vb2)
+{
+       return container_of(vb2, struct skel_buffer, vb);
+}
+
+static const struct pci_device_id skeleton_pci_tbl[] = {
+       /* { PCI_DEVICE(PCI_VENDOR_ID_, PCI_DEVICE_ID_) }, */
+       { 0, }
+};
+
+/*
+ * HDTV: this structure has the capabilities of the HDTV receiver.
+ * It is used to constrain the huge list of possible formats based
+ * upon the hardware capabilities.
+ */
+static const struct v4l2_dv_timings_cap skel_timings_cap = {
+       .type = V4L2_DV_BT_656_1120,
+       /* keep this initialization for compatibility with GCC < 4.4.6 */
+       .reserved = { 0 },
+       V4L2_INIT_BT_TIMINGS(
+               720, 1920,              /* min/max width */
+               480, 1080,              /* min/max height */
+               27000000, 74250000,     /* min/max pixelclock*/
+               V4L2_DV_BT_STD_CEA861,  /* Supported standards */
+               /* capabilities */
+               V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE
+       )
+};
+
+/*
+ * Supported SDTV standards. This does the same job as skel_timings_cap, but
+ * for standard TV formats.
+ */
+#define SKEL_TVNORMS V4L2_STD_ALL
+
+/*
+ * Interrupt handler: typically interrupts happen after a new frame has been
+ * captured. It is the job of the handler to remove the new frame from the
+ * internal list and give it back to the vb2 framework, updating the sequence
+ * counter and timestamp at the same time.
+ */
+static irqreturn_t skeleton_irq(int irq, void *dev_id)
+{
+#ifdef TODO
+       struct skeleton *skel = dev_id;
+
+       /* handle interrupt */
+
+       /* Once a new frame has been captured, mark it as done like this: */
+       if (captured_new_frame) {
+               ...
+               spin_lock(&skel->qlock);
+               list_del(&new_buf->list);
+               spin_unlock(&skel->qlock);
+               new_buf->vb.v4l2_buf.sequence = skel->sequence++;
+               v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
+               vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
+       }
+#endif
+       return IRQ_HANDLED;
+}
+
+/*
+ * Setup the constraints of the queue: besides setting the number of planes
+ * per buffer and the size and allocation context of each plane, it also
+ * checks if sufficient buffers have been allocated. Usually 3 is a good
+ * minimum number: many DMA engines need a minimum of 2 buffers in the
+ * queue and you need to have another available for userspace processing.
+ */
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                      unsigned int *nbuffers, unsigned int *nplanes,
+                      unsigned int sizes[], void *alloc_ctxs[])
+{
+       struct skeleton *skel = vb2_get_drv_priv(vq);
+
+       if (vq->num_buffers + *nbuffers < 3)
+               *nbuffers = 3 - vq->num_buffers;
+
+       if (fmt && fmt->fmt.pix.sizeimage < skel->format.sizeimage)
+               return -EINVAL;
+       *nplanes = 1;
+       sizes[0] = fmt ? fmt->fmt.pix.sizeimage : skel->format.sizeimage;
+       alloc_ctxs[0] = skel->alloc_ctx;
+       return 0;
+}
+
+/*
+ * Prepare the buffer for queueing to the DMA engine: check and set the
+ * payload size and fill in the field. Note: if the format's field is
+ * V4L2_FIELD_ALTERNATE, then vb->v4l2_buf.field should be set in the
+ * interrupt handler since that's usually where you know if the TOP or
+ * BOTTOM field has been captured.
+ */
+static int buffer_prepare(struct vb2_buffer *vb)
+{
+       struct skeleton *skel = vb2_get_drv_priv(vb->vb2_queue);
+       unsigned long size = skel->format.sizeimage;
+
+       if (vb2_plane_size(vb, 0) < size) {
+               dev_err(&skel->pdev->dev, "buffer too small (%lu < %lu)\n",
+                        vb2_plane_size(vb, 0), size);
+               return -EINVAL;
+       }
+
+       vb2_set_plane_payload(vb, 0, size);
+       vb->v4l2_buf.field = skel->format.field;
+       return 0;
+}
+
+/*
+ * Queue this buffer to the DMA engine.
+ */
+static void buffer_queue(struct vb2_buffer *vb)
+{
+       struct skeleton *skel = vb2_get_drv_priv(vb->vb2_queue);
+       struct skel_buffer *buf = to_skel_buffer(vb);
+       unsigned long flags;
+
+       spin_lock_irqsave(&skel->qlock, flags);
+       list_add_tail(&buf->list, &skel->buf_list);
+
+       /* TODO: Update any DMA pointers if necessary */
+
+       spin_unlock_irqrestore(&skel->qlock, flags);
+}
+
+static void return_all_buffers(struct skeleton *skel,
+                              enum vb2_buffer_state state)
+{
+       struct skel_buffer *buf, *node;
+       unsigned long flags;
+
+       spin_lock_irqsave(&skel->qlock, flags);
+       list_for_each_entry_safe(buf, node, &skel->buf_list, list) {
+               vb2_buffer_done(&buf->vb, state);
+               list_del(&buf->list);
+       }
+       spin_unlock_irqrestore(&skel->qlock, flags);
+}
+
+/*
+ * Start streaming. First check if the minimum number of buffers have been
+ * queued. If not, then return -ENOBUFS and the vb2 framework will call
+ * this function again the next time a buffer has been queued until enough
+ * buffers are available to actually start the DMA engine.
+ */
+static int start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct skeleton *skel = vb2_get_drv_priv(vq);
+       int ret = 0;
+
+       skel->sequence = 0;
+
+       /* TODO: start DMA */
+
+       if (ret) {
+               /*
+                * In case of an error, return all active buffers to the
+                * QUEUED state
+                */
+               return_all_buffers(skel, VB2_BUF_STATE_QUEUED);
+       }
+       return ret;
+}
+
+/*
+ * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
+ * and passed on to the vb2 framework marked as STATE_ERROR.
+ */
+static int stop_streaming(struct vb2_queue *vq)
+{
+       struct skeleton *skel = vb2_get_drv_priv(vq);
+
+       /* TODO: stop DMA */
+
+       /* Release all active buffers */
+       return_all_buffers(skel, VB2_BUF_STATE_ERROR);
+       return 0;
+}
+
+/*
+ * The vb2 queue ops. Note that since q->lock is set we can use the standard
+ * vb2_ops_wait_prepare/finish helper functions. If q->lock would be NULL,
+ * then this driver would have to provide these ops.
+ */
+static struct vb2_ops skel_qops = {
+       .queue_setup            = queue_setup,
+       .buf_prepare            = buffer_prepare,
+       .buf_queue              = buffer_queue,
+       .start_streaming        = start_streaming,
+       .stop_streaming         = stop_streaming,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+};
+
+/*
+ * Required ioctl querycap. Note that the version field is prefilled with
+ * the version of the kernel.
+ */
+static int skeleton_querycap(struct file *file, void *priv,
+                            struct v4l2_capability *cap)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strlcpy(cap->card, "V4L2 PCI Skeleton", sizeof(cap->card));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
+                pci_name(skel->pdev));
+       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+                          V4L2_CAP_STREAMING;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       return 0;
+}
+
+/*
+ * Helper function to check and correct struct v4l2_pix_format. It's used
+ * not only in VIDIOC_TRY/S_FMT, but also elsewhere if changes to the SDTV
+ * standard, HDTV timings or the video input would require updating the
+ * current format.
+ */
+static void skeleton_fill_pix_format(struct skeleton *skel,
+                                    struct v4l2_pix_format *pix)
+{
+       pix->pixelformat = V4L2_PIX_FMT_YUYV;
+       if (skel->input == 0) {
+               /* S-Video input */
+               pix->width = 720;
+               pix->height = (skel->std & V4L2_STD_525_60) ? 480 : 576;
+               pix->field = V4L2_FIELD_INTERLACED;
+               pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
+       } else {
+               /* HDMI input */
+               pix->width = skel->timings.bt.width;
+               pix->height = skel->timings.bt.height;
+               if (skel->timings.bt.interlaced)
+                       pix->field = V4L2_FIELD_INTERLACED;
+               else
+                       pix->field = V4L2_FIELD_NONE;
+               pix->colorspace = V4L2_COLORSPACE_REC709;
+       }
+
+       /*
+        * The YUYV format is four bytes for every two pixels, so bytesperline
+        * is width * 2.
+        */
+       pix->bytesperline = pix->width * 2;
+       pix->sizeimage = pix->bytesperline * pix->height;
+       pix->priv = 0;
+}
+
+static int skeleton_try_fmt_vid_cap(struct file *file, void *priv,
+                                   struct v4l2_format *f)
+{
+       struct skeleton *skel = video_drvdata(file);
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+
+       /*
+        * Due to historical reasons providing try_fmt with an unsupported
+        * pixelformat will return -EINVAL for video receivers. Webcam drivers,
+        * however, will silently correct the pixelformat. Some video capture
+        * applications rely on this behavior...
+        */
+       if (pix->pixelformat != V4L2_PIX_FMT_YUYV)
+               return -EINVAL;
+       skeleton_fill_pix_format(skel, pix);
+       return 0;
+}
+
+static int skeleton_s_fmt_vid_cap(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct skeleton *skel = video_drvdata(file);
+       int ret;
+
+       ret = skeleton_try_fmt_vid_cap(file, priv, f);
+       if (ret)
+               return ret;
+
+       /*
+        * It is not allowed to change the format while buffers for use with
+        * streaming have already been allocated.
+        */
+       if (vb2_is_busy(&skel->queue))
+               return -EBUSY;
+
+       /* TODO: change format */
+       skel->format = f->fmt.pix;
+       return 0;
+}
+
+static int skeleton_g_fmt_vid_cap(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       f->fmt.pix = skel->format;
+       return 0;
+}
+
+static int skeleton_enum_fmt_vid_cap(struct file *file, void *priv,
+                                    struct v4l2_fmtdesc *f)
+{
+       if (f->index != 0)
+               return -EINVAL;
+
+       strlcpy(f->description, "4:2:2, packed, YUYV", sizeof(f->description));
+       f->pixelformat = V4L2_PIX_FMT_YUYV;
+       f->flags = 0;
+       return 0;
+}
+
+static int skeleton_s_std(struct file *file, void *priv, v4l2_std_id std)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* S_STD is not supported on the HDMI input */
+       if (skel->input)
+               return -ENODATA;
+
+       /*
+        * No change, so just return. Some applications call S_STD again after
+        * the buffers for streaming have been set up, so we have to allow for
+        * this behavior.
+        */
+       if (std == skel->std)
+               return 0;
+
+       /*
+        * Changing the standard implies a format change, which is not allowed
+        * while buffers for use with streaming have already been allocated.
+        */
+       if (vb2_is_busy(&skel->queue))
+               return -EBUSY;
+
+       /* TODO: handle changing std */
+
+       skel->std = std;
+
+       /* Update the internal format */
+       skeleton_fill_pix_format(skel, &skel->format);
+       return 0;
+}
+
+static int skeleton_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* G_STD is not supported on the HDMI input */
+       if (skel->input)
+               return -ENODATA;
+
+       *std = skel->std;
+       return 0;
+}
+
+/*
+ * Query the current standard as seen by the hardware. This function shall
+ * never actually change the standard, it just detects and reports.
+ * The framework will initially set *std to tvnorms (i.e. the set of
+ * supported standards by this input), and this function should just AND
+ * this value. If there is no signal, then *std should be set to 0.
+ */
+static int skeleton_querystd(struct file *file, void *priv, v4l2_std_id *std)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* QUERY_STD is not supported on the HDMI input */
+       if (skel->input)
+               return -ENODATA;
+
+#ifdef TODO
+       /*
+        * Query currently seen standard. Initial value of *std is
+        * V4L2_STD_ALL. This function should look something like this:
+        */
+       get_signal_info();
+       if (no_signal) {
+               *std = 0;
+               return 0;
+       }
+       /* Use signal information to reduce the number of possible standards */
+       if (signal_has_525_lines)
+               *std &= V4L2_STD_525_60;
+       else
+               *std &= V4L2_STD_625_50;
+#endif
+       return 0;
+}
+
+static int skeleton_s_dv_timings(struct file *file, void *_fh,
+                                struct v4l2_dv_timings *timings)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* S_DV_TIMINGS is not supported on the S-Video input */
+       if (skel->input == 0)
+               return -ENODATA;
+
+       /* Quick sanity check */
+       if (!v4l2_valid_dv_timings(timings, &skel_timings_cap, NULL, NULL))
+               return -EINVAL;
+
+       /* Check if the timings are part of the CEA-861 timings. */
+       if (!v4l2_find_dv_timings_cap(timings, &skel_timings_cap,
+                                     0, NULL, NULL))
+               return -EINVAL;
+
+       /* Return 0 if the new timings are the same as the current timings. */
+       if (v4l2_match_dv_timings(timings, &skel->timings, 0))
+               return 0;
+
+       /*
+        * Changing the timings implies a format change, which is not allowed
+        * while buffers for use with streaming have already been allocated.
+        */
+       if (vb2_is_busy(&skel->queue))
+               return -EBUSY;
+
+       /* TODO: Configure new timings */
+
+       /* Save timings */
+       skel->timings = *timings;
+
+       /* Update the internal format */
+       skeleton_fill_pix_format(skel, &skel->format);
+       return 0;
+}
+
+static int skeleton_g_dv_timings(struct file *file, void *_fh,
+                                struct v4l2_dv_timings *timings)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* G_DV_TIMINGS is not supported on the S-Video input */
+       if (skel->input == 0)
+               return -ENODATA;
+
+       *timings = skel->timings;
+       return 0;
+}
+
+static int skeleton_enum_dv_timings(struct file *file, void *_fh,
+                                   struct v4l2_enum_dv_timings *timings)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* ENUM_DV_TIMINGS is not supported on the S-Video input */
+       if (skel->input == 0)
+               return -ENODATA;
+
+       return v4l2_enum_dv_timings_cap(timings, &skel_timings_cap,
+                                       NULL, NULL);
+}
+
+/*
+ * Query the current timings as seen by the hardware. This function shall
+ * never actually change the timings, it just detects and reports.
+ * If no signal is detected, then return -ENOLINK. If the hardware cannot
+ * lock to the signal, then return -ENOLCK. If the signal is out of range
+ * of the capabilities of the system (e.g., it is possible that the receiver
+ * can lock but that the DMA engine it is connected to cannot handle
+ * pixelclocks above a certain frequency), then -ERANGE is returned.
+ */
+static int skeleton_query_dv_timings(struct file *file, void *_fh,
+                                    struct v4l2_dv_timings *timings)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* QUERY_DV_TIMINGS is not supported on the S-Video input */
+       if (skel->input == 0)
+               return -ENODATA;
+
+#ifdef TODO
+       /*
+        * Query currently seen timings. This function should look
+        * something like this:
+        */
+       detect_timings();
+       if (no_signal)
+               return -ENOLINK;
+       if (cannot_lock_to_signal)
+               return -ENOLCK;
+       if (signal_out_of_range_of_capabilities)
+               return -ERANGE;
+
+       /* Useful for debugging */
+       v4l2_print_dv_timings(skel->v4l2_dev.name, "query_dv_timings:",
+                       timings, true);
+#endif
+       return 0;
+}
+
+static int skeleton_dv_timings_cap(struct file *file, void *fh,
+                                  struct v4l2_dv_timings_cap *cap)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       /* DV_TIMINGS_CAP is not supported on the S-Video input */
+       if (skel->input == 0)
+               return -ENODATA;
+       *cap = skel_timings_cap;
+       return 0;
+}
+
+static int skeleton_enum_input(struct file *file, void *priv,
+                              struct v4l2_input *i)
+{
+       if (i->index > 1)
+               return -EINVAL;
+
+       i->type = V4L2_INPUT_TYPE_CAMERA;
+       if (i->index == 0) {
+               i->std = SKEL_TVNORMS;
+               strlcpy(i->name, "S-Video", sizeof(i->name));
+               i->capabilities = V4L2_IN_CAP_STD;
+       } else {
+               i->std = 0;
+               strlcpy(i->name, "HDMI", sizeof(i->name));
+               i->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+       }
+       return 0;
+}
+
+static int skeleton_s_input(struct file *file, void *priv, unsigned int i)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       if (i > 1)
+               return -EINVAL;
+
+       /*
+        * Changing the input implies a format change, which is not allowed
+        * while buffers for use with streaming have already been allocated.
+        */
+       if (vb2_is_busy(&skel->queue))
+               return -EBUSY;
+
+       skel->input = i;
+       /*
+        * Update tvnorms. The tvnorms value is used by the core to implement
+        * VIDIOC_ENUMSTD so it has to be correct. If tvnorms == 0, then
+        * ENUMSTD will return -ENODATA.
+        */
+       skel->vdev.tvnorms = i ? 0 : SKEL_TVNORMS;
+
+       /* Update the internal format */
+       skeleton_fill_pix_format(skel, &skel->format);
+       return 0;
+}
+
+static int skeleton_g_input(struct file *file, void *priv, unsigned int *i)
+{
+       struct skeleton *skel = video_drvdata(file);
+
+       *i = skel->input;
+       return 0;
+}
+
+/* The control handler. */
+static int skeleton_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       /*struct skeleton *skel =
+               container_of(ctrl->handler, struct skeleton, ctrl_handler);*/
+
+       switch (ctrl->id) {
+       case V4L2_CID_BRIGHTNESS:
+               /* TODO: set brightness to ctrl->val */
+               break;
+       case V4L2_CID_CONTRAST:
+               /* TODO: set contrast to ctrl->val */
+               break;
+       case V4L2_CID_SATURATION:
+               /* TODO: set saturation to ctrl->val */
+               break;
+       case V4L2_CID_HUE:
+               /* TODO: set hue to ctrl->val */
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/* ------------------------------------------------------------------
+       File operations for the device
+   ------------------------------------------------------------------*/
+
+static const struct v4l2_ctrl_ops skel_ctrl_ops = {
+       .s_ctrl = skeleton_s_ctrl,
+};
+
+/*
+ * The set of all supported ioctls. Note that all the streaming ioctls
+ * use the vb2 helper functions that take care of all the locking and
+ * that also do ownership tracking (i.e. only the filehandle that requested
+ * the buffers can call the streaming ioctls, all other filehandles will
+ * receive -EBUSY if they attempt to call the same streaming ioctls).
+ *
+ * The last three ioctls also use standard helper functions: these implement
+ * standard behavior for drivers with controls.
+ */
+static const struct v4l2_ioctl_ops skel_ioctl_ops = {
+       .vidioc_querycap = skeleton_querycap,
+       .vidioc_try_fmt_vid_cap = skeleton_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap = skeleton_s_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap = skeleton_g_fmt_vid_cap,
+       .vidioc_enum_fmt_vid_cap = skeleton_enum_fmt_vid_cap,
+
+       .vidioc_g_std = skeleton_g_std,
+       .vidioc_s_std = skeleton_s_std,
+       .vidioc_querystd = skeleton_querystd,
+
+       .vidioc_s_dv_timings = skeleton_s_dv_timings,
+       .vidioc_g_dv_timings = skeleton_g_dv_timings,
+       .vidioc_enum_dv_timings = skeleton_enum_dv_timings,
+       .vidioc_query_dv_timings = skeleton_query_dv_timings,
+       .vidioc_dv_timings_cap = skeleton_dv_timings_cap,
+
+       .vidioc_enum_input = skeleton_enum_input,
+       .vidioc_g_input = skeleton_g_input,
+       .vidioc_s_input = skeleton_s_input,
+
+       .vidioc_reqbufs = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs = vb2_ioctl_create_bufs,
+       .vidioc_querybuf = vb2_ioctl_querybuf,
+       .vidioc_qbuf = vb2_ioctl_qbuf,
+       .vidioc_dqbuf = vb2_ioctl_dqbuf,
+       .vidioc_expbuf = vb2_ioctl_expbuf,
+       .vidioc_streamon = vb2_ioctl_streamon,
+       .vidioc_streamoff = vb2_ioctl_streamoff,
+
+       .vidioc_log_status = v4l2_ctrl_log_status,
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+/*
+ * The set of file operations. Note that all these ops are standard core
+ * helper functions.
+ */
+static const struct v4l2_file_operations skel_fops = {
+       .owner = THIS_MODULE,
+       .open = v4l2_fh_open,
+       .release = vb2_fop_release,
+       .unlocked_ioctl = video_ioctl2,
+       .read = vb2_fop_read,
+       .mmap = vb2_fop_mmap,
+       .poll = vb2_fop_poll,
+};
+
+/*
+ * The initial setup of this device instance. Note that the initial state of
+ * the driver should be complete. So the initial format, standard, timings
+ * and video input should all be initialized to some reasonable value.
+ */
+static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       /* The initial timings are chosen to be 720p60. */
+       static const struct v4l2_dv_timings timings_def =
+               V4L2_DV_BT_CEA_1280X720P60;
+       struct skeleton *skel;
+       struct video_device *vdev;
+       struct v4l2_ctrl_handler *hdl;
+       struct vb2_queue *q;
+       int ret;
+
+       /* Enable PCI */
+       ret = pci_enable_device(pdev);
+       if (ret)
+               return ret;
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret) {
+               dev_err(&pdev->dev, "no suitable DMA available.\n");
+               goto disable_pci;
+       }
+
+       /* Allocate a new instance */
+       skel = devm_kzalloc(&pdev->dev, sizeof(struct skeleton), GFP_KERNEL);
+       if (!skel)
+               return -ENOMEM;
+
+       /* Allocate the interrupt */
+       ret = devm_request_irq(&pdev->dev, pdev->irq,
+                              skeleton_irq, 0, KBUILD_MODNAME, skel);
+       if (ret) {
+               dev_err(&pdev->dev, "request_irq failed\n");
+               goto disable_pci;
+       }
+       skel->pdev = pdev;
+
+       /* Fill in the initial format-related settings */
+       skel->timings = timings_def;
+       skel->std = V4L2_STD_625_50;
+       skeleton_fill_pix_format(skel, &skel->format);
+
+       /* Initialize the top-level structure */
+       ret = v4l2_device_register(&pdev->dev, &skel->v4l2_dev);
+       if (ret)
+               goto disable_pci;
+
+       mutex_init(&skel->lock);
+
+       /* Add the controls */
+       hdl = &skel->ctrl_handler;
+       v4l2_ctrl_handler_init(hdl, 4);
+       v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
+                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
+       v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
+                         V4L2_CID_CONTRAST, 0, 255, 1, 16);
+       v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
+                         V4L2_CID_SATURATION, 0, 255, 1, 127);
+       v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
+                         V4L2_CID_HUE, -128, 127, 1, 0);
+       if (hdl->error) {
+               ret = hdl->error;
+               goto free_hdl;
+       }
+       skel->v4l2_dev.ctrl_handler = hdl;
+
+       /* Initialize the vb2 queue */
+       q = &skel->queue;
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+       q->drv_priv = skel;
+       q->buf_struct_size = sizeof(struct skel_buffer);
+       q->ops = &skel_qops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       /*
+        * Assume that this DMA engine needs to have at least two buffers
+        * available before it can be started. The start_streaming() op
+        * won't be called until at least this many buffers are queued up.
+        */
+       q->min_buffers_needed = 2;
+       /*
+        * The serialization lock for the streaming ioctls. This is the same
+        * as the main serialization lock, but if some of the non-streaming
+        * ioctls could take a long time to execute, then you might want to
+        * have a different lock here to prevent VIDIOC_DQBUF from being
+        * blocked while waiting for another action to finish. This is
+        * generally not needed for PCI devices, but USB devices usually do
+        * want a separate lock here.
+        */
+       q->lock = &skel->lock;
+       /*
+        * Since this driver can only do 32-bit DMA we must make sure that
+        * the vb2 core will allocate the buffers in 32-bit DMA memory.
+        */
+       q->gfp_flags = GFP_DMA32;
+       ret = vb2_queue_init(q);
+       if (ret)
+               goto free_hdl;
+
+       skel->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+       if (IS_ERR(skel->alloc_ctx)) {
+               dev_err(&pdev->dev, "Can't allocate buffer context");
+               ret = PTR_ERR(skel->alloc_ctx);
+               goto free_hdl;
+       }
+       INIT_LIST_HEAD(&skel->buf_list);
+       spin_lock_init(&skel->qlock);
+
+       /* Initialize the video_device structure */
+       vdev = &skel->vdev;
+       strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
+       /*
+        * There is nothing to clean up, so release is set to an empty release
+        * function. The release callback must be non-NULL.
+        */
+       vdev->release = video_device_release_empty;
+       vdev->fops = &skel_fops,
+       vdev->ioctl_ops = &skel_ioctl_ops,
+       /*
+        * The main serialization lock. All ioctls are serialized by this
+        * lock. Exception: if q->lock is set, then the streaming ioctls
+        * are serialized by that separate lock.
+        */
+       vdev->lock = &skel->lock;
+       vdev->queue = q;
+       vdev->v4l2_dev = &skel->v4l2_dev;
+       /* Supported SDTV standards, if any */
+       vdev->tvnorms = SKEL_TVNORMS;
+       /* If this bit is set, then the v4l2 core will provide the support
+        * for the VIDIOC_G/S_PRIORITY ioctls. This flag will eventually
+        * go away once all drivers have been converted to use struct v4l2_fh.
+        */
+       set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
+       video_set_drvdata(vdev, skel);
+
+       ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+       if (ret)
+               goto free_ctx;
+
+       dev_info(&pdev->dev, "V4L2 PCI Skeleton Driver loaded\n");
+       return 0;
+
+free_ctx:
+       vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
+free_hdl:
+       v4l2_ctrl_handler_free(&skel->ctrl_handler);
+       v4l2_device_unregister(&skel->v4l2_dev);
+disable_pci:
+       pci_disable_device(pdev);
+       return ret;
+}
+
+static void skeleton_remove(struct pci_dev *pdev)
+{
+       struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
+       struct skeleton *skel = container_of(v4l2_dev, struct skeleton, v4l2_dev);
+
+       video_unregister_device(&skel->vdev);
+       v4l2_ctrl_handler_free(&skel->ctrl_handler);
+       vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
+       v4l2_device_unregister(&skel->v4l2_dev);
+       pci_disable_device(skel->pdev);
+}
+
+static struct pci_driver skeleton_driver = {
+       .name = KBUILD_MODNAME,
+       .probe = skeleton_probe,
+       .remove = skeleton_remove,
+       .id_table = skeleton_pci_tbl,
+};
+
+module_pci_driver(skeleton_driver);
index 9eeeddfa19a04ac834c27626aeb3dc6a9ea58f34..bfff89690c3adc99305af5fe37923db4748db87e 100644 (file)
@@ -824,7 +824,7 @@ ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE
 M:     Alexander Shiyan <shc_work@mail.ru>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Odd Fixes
-F:     arch/arm/mach-clps711x/
+N:     clps711x
 
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 M:     Hartley Sweeten <hsweeten@visionengravers.com>
@@ -1175,6 +1175,14 @@ L:       linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.arm.linux.org.uk/
 S:     Maintained
 
+ARM/QUALCOMM SUPPORT
+M:     Kumar Gala <galak@codeaurora.org>
+M:     David Brown <davidb@codeaurora.org>
+L:     linux-arm-msm@vger.kernel.org
+S:     Maintained
+F:     arch/arm/mach-qcom/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
+
 ARM/RADISYS ENP2611 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1283,13 +1291,21 @@ S:      Maintained
 F:     drivers/clk/socfpga/
 
 ARM/STI ARCHITECTURE
-M:     Srinivas Kandagatla <srinivas.kandagatla@st.com>
-M:     Stuart Menefy <stuart.menefy@st.com>
+M:     Srinivas Kandagatla <srinivas.kandagatla@gmail.com>
+M:     Maxime Coquelin <maxime.coquelin@st.com>
+M:     Patrice Chotard <patrice.chotard@st.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kernel@stlinux.com
 W:     http://www.stlinux.com
 S:     Maintained
 F:     arch/arm/mach-sti/
+F:     arch/arm/boot/dts/sti*
+F:     drivers/clocksource/arm_global_timer.c
+F:     drivers/reset/sti/
+F:     drivers/pinctrl/pinctrl-st.c
+F:     drivers/media/rc/st_rc.c
+F:     drivers/i2c/busses/i2c-st.c
+F:     drivers/tty/serial/st-asc.c
 
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
@@ -1894,11 +1910,19 @@ M:      Stephen Warren <swarren@wwwdotorg.org>
 L:     linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-rpi.git
 S:     Maintained
-F:     arch/arm/mach-bcm2835/
+F:     arch/arm/mach-bcm/board_bcm2835.c
 F:     arch/arm/boot/dts/bcm2835*
 F:     arch/arm/configs/bcm2835_defconfig
 F:     drivers/*/*bcm2835*
 
+BROADCOM BCM5301X ARM ARCHICTURE
+M:     Hauke Mehrtens <hauke@hauke-m.de>
+L:     linux-arm-kernel@lists.infradead.org
+S:     Maintained
+F:     arch/arm/mach-bcm/bcm_5301x.c
+F:     arch/arm/boot/dts/bcm5301x.dtsi
+F:     arch/arm/boot/dts/bcm470*
+
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 M:     Nithin Nayak Sujir <nsujir@broadcom.com>
 M:     Michael Chan <mchan@broadcom.com>
@@ -2294,7 +2318,7 @@ F:        include/uapi/linux/coda*.h
 
 COMMON CLK FRAMEWORK
 M:     Mike Turquette <mturquette@linaro.org>
-L:     linux-arm-kernel@lists.infradead.org (same as CLK API & CLKDEV)
+L:     linux-kernel@vger.kernel.org
 T:     git git://git.linaro.org/people/mturquette/linux.git
 S:     Maintained
 F:     drivers/clk/
@@ -3521,7 +3545,8 @@ F:        include/scsi/libfcoe.h
 F:     include/uapi/scsi/fc/
 
 FILE LOCKING (flock() and fcntl()/lockf())
-M:     Matthew Wilcox <matthew@wil.cx>
+M:     Jeff Layton <jlayton@redhat.com>
+M:     J. Bruce Fields <bfields@fieldses.org>
 L:     linux-fsdevel@vger.kernel.org
 S:     Maintained
 F:     include/linux/fcntl.h
@@ -4859,22 +4884,6 @@ S:       Maintained
 F:     Documentation/hwmon/it87
 F:     drivers/hwmon/it87.c
 
-IT913X MEDIA DRIVER
-M:     Malcolm Priestley <tvboxspy@gmail.com>
-L:     linux-media@vger.kernel.org
-W:     http://linuxtv.org/
-Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-S:     Maintained
-F:     drivers/media/usb/dvb-usb-v2/it913x*
-
-IT913X FE MEDIA DRIVER
-M:     Malcolm Priestley <tvboxspy@gmail.com>
-L:     linux-media@vger.kernel.org
-W:     http://linuxtv.org/
-Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-S:     Maintained
-F:     drivers/media/dvb-frontends/it913x-fe*
-
 IT913X MEDIA DRIVER
 M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
@@ -5855,6 +5864,26 @@ L:       platform-driver-x86@vger.kernel.org
 S:     Supported
 F:     drivers/platform/x86/msi-wmi.c
 
+MSI001 MEDIA DRIVER
+M:     Antti Palosaari <crope@iki.fi>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org/
+W:     http://palosaari.fi/linux/
+Q:     http://patchwork.linuxtv.org/project/linux-media/list/
+T:     git git://linuxtv.org/anttip/media_tree.git
+S:     Maintained
+F:     drivers/staging/media/msi3101/msi001*
+
+MSI3101 MEDIA DRIVER
+M:     Antti Palosaari <crope@iki.fi>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org/
+W:     http://palosaari.fi/linux/
+Q:     http://patchwork.linuxtv.org/project/linux-media/list/
+T:     git git://linuxtv.org/anttip/media_tree.git
+S:     Maintained
+F:     drivers/staging/media/msi3101/sdr-msi3101*
+
 MT9M032 APTINA SENSOR DRIVER
 M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 L:     linux-media@vger.kernel.org
@@ -7422,6 +7451,16 @@ T:       git git://linuxtv.org/anttip/media_tree.git
 S:     Maintained
 F:     drivers/media/dvb-frontends/rtl2832*
 
+RTL2832_SDR MEDIA DRIVER
+M:     Antti Palosaari <crope@iki.fi>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org/
+W:     http://palosaari.fi/linux/
+Q:     http://patchwork.linuxtv.org/project/linux-media/list/
+T:     git git://linuxtv.org/anttip/media_tree.git
+S:     Maintained
+F:     drivers/staging/media/rtl2832u_sdr/rtl2832_sdr*
+
 RTL8180 WIRELESS DRIVER
 M:     "John W. Linville" <linville@tuxdriver.com>
 L:     linux-wireless@vger.kernel.org
@@ -7954,15 +7993,13 @@ F:      drivers/media/usb/siano/
 F:     drivers/media/mmc/siano/
 
 SH_VEU V4L2 MEM2MEM DRIVER
-M:     Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 F:     drivers/media/platform/sh_veu.c
 
 SH_VOU V4L2 OUTPUT DRIVER
-M:     Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 L:     linux-media@vger.kernel.org
-S:     Odd Fixes
+S:     Orphan
 F:     drivers/media/platform/sh_vou.c
 F:     include/media/sh_vou.h
 
index 80bbb8ccd0d10b319d932d1be08a2d742f957cfa..97ff872c7accf99b3779314718fe31fd60ee1d42 100644 (file)
@@ -86,9 +86,7 @@ config KPROBES_ON_FTRACE
         optimize on top of function tracing.
 
 config UPROBES
-       bool "Transparent user-space probes (EXPERIMENTAL)"
-       depends on UPROBE_EVENT && PERF_EVENTS
-       default n
+       def_bool n
        select PERCPU_RWSEM
        help
          Uprobes is the user-space counterpart to kprobes: they
@@ -101,8 +99,6 @@ config UPROBES
            managed by the kernel and kept transparent to the probed
            application. )
 
-         If in doubt, say "N".
-
 config HAVE_64BIT_ALIGNED_ACCESS
        def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS
        help
index 503da0a2a8ea0d4cdf4046aa6813df9c4d2589d9..d7a71e3ef55fce7d2812602077495baeb25149b2 100644 (file)
@@ -113,9 +113,6 @@ config ARM_DMA_IOMMU_ALIGNMENT
 
 endif
 
-config HAVE_PWM
-       bool
-
 config MIGHT_HAVE_PCI
        bool
 
@@ -207,6 +204,9 @@ config ZONE_DMA
 config NEED_DMA_MAP_STATE
        def_bool y
 
+config ARCH_SUPPORTS_UPROBES
+       def_bool y
+
 config ARCH_HAS_DMA_SET_COHERENT_MASK
        bool
 
@@ -306,9 +306,12 @@ choice
 config ARCH_MULTIPLATFORM
        bool "Allow multiple platforms to be selected"
        depends on MMU
+       select ARCH_WANT_OPTIONAL_GPIOLIB
+       select ARM_HAS_SG_CHAIN
        select ARM_PATCH_PHYS_VIRT
        select AUTO_ZRELADDR
        select COMMON_CLK
+       select GENERIC_CLOCKEVENTS
        select MULTI_IRQ_HANDLER
        select SPARSE_IRQ
        select USE_OF
@@ -388,8 +391,6 @@ config ARCH_CLPS711X
        select CPU_ARM720T
        select GENERIC_CLOCKEVENTS
        select MFD_SYSCON
-       select MULTI_IRQ_HANDLER
-       select SPARSE_IRQ
        help
          Support for Cirrus Logic 711x/721x/731x based boards.
 
@@ -420,10 +421,8 @@ config ARCH_EFM32
        bool "Energy Micro efm32"
        depends on !MMU
        select ARCH_REQUIRE_GPIOLIB
+       select AUTO_ZRELADDR
        select ARM_NVIC
-       # CLKSRC_MMIO is wrong here, but needed until a proper fix is merged,
-       # i.e. CLKSRC_EFM32 selecting CLKSRC_MMIO
-       select CLKSRC_MMIO
        select CLKSRC_OF
        select COMMON_CLK
        select CPU_V7M
@@ -631,7 +630,6 @@ config ARCH_LPC32XX
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
        select HAVE_IDE
-       select HAVE_PWM
        select USE_OF
        help
          Support for the NXP LPC32XX family of processors
@@ -655,9 +653,8 @@ config ARCH_PXA
        help
          Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
 
-config ARCH_MSM_NODT
-       bool "Qualcomm MSM"
-       select ARCH_MSM
+config ARCH_MSM
+       bool "Qualcomm MSM (non-multiplatform)"
        select ARCH_REQUIRE_GPIOLIB
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
@@ -695,6 +692,7 @@ config ARCH_RPC
        select ARCH_MAY_HAVE_PC_FDC
        select ARCH_SPARSEMEM_ENABLE
        select ARCH_USES_GETTIMEOFFSET
+       select CPU_SA110
        select FIQ
        select HAVE_IDE
        select HAVE_PATA_PLATFORM
@@ -729,6 +727,7 @@ config ARCH_S3C24XX
        bool "Samsung S3C24XX SoCs"
        select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
+       select ATAGS
        select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
        select GENERIC_CLOCKEVENTS
@@ -751,6 +750,7 @@ config ARCH_S3C64XX
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select ARM_VIC
+       select ATAGS
        select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
        select COMMON_CLK
@@ -762,7 +762,7 @@ config ARCH_S3C64XX
        select HAVE_TCM
        select NO_IOPORT
        select PLAT_SAMSUNG
-       select PM_GENERIC_DOMAINS
+       select PM_GENERIC_DOMAINS if PM
        select S3C_DEV_NAND
        select S3C_GPIO_TRACK
        select SAMSUNG_ATAGS
@@ -773,6 +773,7 @@ config ARCH_S3C64XX
 
 config ARCH_S5P64X0
        bool "Samsung S5P6440 S5P6450"
+       select ATAGS
        select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
        select CPU_V6
@@ -791,6 +792,7 @@ config ARCH_S5P64X0
 config ARCH_S5PC100
        bool "Samsung S5PC100"
        select ARCH_REQUIRE_GPIOLIB
+       select ATAGS
        select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
        select CPU_V7
@@ -810,6 +812,7 @@ config ARCH_S5PV210
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_SPARSEMEM_ENABLE
+       select ATAGS
        select CLKDEV_LOOKUP
        select CLKSRC_SAMSUNG_PWM
        select CPU_V7
@@ -883,6 +886,12 @@ menu "Multiple platform selection"
 
 comment "CPU Core family selection"
 
+config ARCH_MULTI_V4
+       bool "ARMv4 based platforms (FA526)"
+       depends on !ARCH_MULTI_V6_V7
+       select ARCH_MULTI_V4_V5
+       select CPU_FA526
+
 config ARCH_MULTI_V4T
        bool "ARMv4T based platforms (ARM720T, ARM920T, ...)"
        depends on !ARCH_MULTI_V6_V7
@@ -895,7 +904,7 @@ config ARCH_MULTI_V5
        bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)"
        depends on !ARCH_MULTI_V6_V7
        select ARCH_MULTI_V4_V5
-       select CPU_ARM926T if (!CPU_ARM946E || CPU_ARM1020 || \
+       select CPU_ARM926T if !(CPU_ARM946E || CPU_ARM1020 || \
                CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
                CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_FEROCEON)
 
@@ -905,16 +914,18 @@ config ARCH_MULTI_V4_V5
 config ARCH_MULTI_V6
        bool "ARMv6 based platforms (ARM11)"
        select ARCH_MULTI_V6_V7
-       select CPU_V6
+       select CPU_V6K
 
 config ARCH_MULTI_V7
        bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)"
        default y
        select ARCH_MULTI_V6_V7
        select CPU_V7
+       select HAVE_SMP
 
 config ARCH_MULTI_V6_V7
        bool
+       select MIGHT_HAVE_CACHE_L2X0
 
 config ARCH_MULTI_CPU_AUTO
        def_bool !(ARCH_MULTI_V4 || ARCH_MULTI_V4T || ARCH_MULTI_V6_V7)
@@ -922,6 +933,13 @@ config ARCH_MULTI_CPU_AUTO
 
 endmenu
 
+config ARCH_VIRT
+       bool "Dummy Virtual Machine" if ARCH_MULTI_V7
+       select ARM_AMBA
+       select ARM_GIC
+       select ARM_PSCI
+       select HAVE_ARM_ARCH_TIMER
+
 #
 # This is sorted alphabetically by mach-* pathname.  However, plat-*
 # Kconfigs may be included either alphabetically (according to the
@@ -933,8 +951,6 @@ source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/mach-bcm/Kconfig"
 
-source "arch/arm/mach-bcm2835/Kconfig"
-
 source "arch/arm/mach-berlin/Kconfig"
 
 source "arch/arm/mach-clps711x/Kconfig"
@@ -1002,6 +1018,8 @@ source "arch/arm/plat-pxa/Kconfig"
 
 source "arch/arm/mach-mmp/Kconfig"
 
+source "arch/arm/mach-qcom/Kconfig"
+
 source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-rockchip/Kconfig"
@@ -1045,8 +1063,6 @@ source "arch/arm/mach-versatile/Kconfig"
 source "arch/arm/mach-vexpress/Kconfig"
 source "arch/arm/plat-versatile/Kconfig"
 
-source "arch/arm/mach-virt/Kconfig"
-
 source "arch/arm/mach-vt8500/Kconfig"
 
 source "arch/arm/mach-w90x900/Kconfig"
@@ -2271,7 +2287,7 @@ source "kernel/power/Kconfig"
 config ARCH_SUSPEND_POSSIBLE
        depends on !ARCH_S5PC100
        depends on CPU_ARM920T || CPU_ARM926T || CPU_FEROCEON || CPU_SA1100 || \
-               CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
+               CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
        def_bool y
 
 config ARM_CPU_SUSPEND
index 0531da8e5216e442ee1f9c8878e4fb9d84611581..4a2fc0bf6fc913683c29bc2113b85b1f3db9bdd3 100644 (file)
@@ -106,9 +106,14 @@ choice
                depends on ARCH_BCM2835
                select DEBUG_UART_PL01X
 
+       config DEBUG_BCM_5301X
+               bool "Kernel low-level debugging on BCM5301X UART1"
+               depends on ARCH_BCM_5301X
+               select DEBUG_UART_PL01X
+
        config DEBUG_BCM_KONA_UART
                bool "Kernel low-level debugging messages via BCM KONA UART"
-               depends on ARCH_BCM
+               depends on ARCH_BCM_MOBILE
                select DEBUG_UART_8250
                help
                  Say Y here if you want kernel low-level debugging support
@@ -171,15 +176,6 @@ choice
                  Say Y here if you want the debug print routines to direct
                  their output to UART0 serial port on DaVinci DMx devices.
 
-       config DEBUG_DAVINCI_TNETV107X_UART1
-               bool "Kernel low-level debugging on DaVinci TNETV107x using UART1"
-               depends on ARCH_DAVINCI_TNETV107X
-               select DEBUG_UART_8250
-               help
-                 Say Y here if you want the debug print routines to direct
-                 their output to UART1 serial port on DaVinci TNETV107X
-                 devices.
-
        config DEBUG_ZYNQ_UART0
                bool "Kernel low-level debugging on Xilinx Zynq using UART0"
                depends on ARCH_ZYNQ
@@ -956,7 +952,7 @@ config DEBUG_STI_UART
 
 config DEBUG_MSM_UART
        bool
-       depends on ARCH_MSM
+       depends on ARCH_MSM || ARCH_QCOM
 
 config DEBUG_LL_INCLUDE
        string
@@ -1014,7 +1010,6 @@ config DEBUG_UART_PHYS
        default 0x02530c00 if DEBUG_KEYSTONE_UART0
        default 0x02531000 if DEBUG_KEYSTONE_UART1
        default 0x03010fe0 if ARCH_RPC
-       default 0x08108300 if DEBUG_DAVINCI_TNETV107X_UART1
        default 0x10009000 if DEBUG_REALVIEW_STD_PORT || DEBUG_CNS3XXX || \
                                DEBUG_VEXPRESS_UART0_CA9
        default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
@@ -1023,6 +1018,7 @@ config DEBUG_UART_PHYS
        default 0x101f1000 if ARCH_VERSATILE
        default 0x101fb000 if DEBUG_NOMADIK_UART
        default 0x16000000 if ARCH_INTEGRATOR
+       default 0x18000300 if DEBUG_BCM_5301X
        default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
        default 0x20060000 if DEBUG_RK29_UART0
        default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
@@ -1071,6 +1067,7 @@ config DEBUG_UART_VIRT
        default 0xf0009000 if DEBUG_CNS3XXX
        default 0xf01fb000 if DEBUG_NOMADIK_UART
        default 0xf0201000 if DEBUG_BCM2835
+       default 0xf1000300 if DEBUG_BCM_5301X
        default 0xf11f1000 if ARCH_VERSATILE
        default 0xf1600000 if ARCH_INTEGRATOR
        default 0xf1c28000 if DEBUG_SUNXI_UART0
@@ -1110,7 +1107,6 @@ config DEBUG_UART_VIRT
        default 0xfed12000 if ARCH_KIRKWOOD
        default 0xfedc0000 if ARCH_EP93XX
        default 0xfee003f8 if FOOTBRIDGE
-       default 0xfee08300 if DEBUG_DAVINCI_TNETV107X_UART1
        default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
        default 0xfef36000 if DEBUG_HIGHBANK_UART
        default 0xfee82340 if ARCH_IOP13XX
@@ -1135,7 +1131,7 @@ config DEBUG_UART_8250_WORD
        default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \
                ARCH_KEYSTONE || \
                DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
-               DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 || \
+               DEBUG_DAVINCI_DA8XX_UART2 || \
                DEBUG_BCM_KONA_UART
 
 config DEBUG_UART_8250_FLOW_CONTROL
@@ -1145,7 +1141,7 @@ config DEBUG_UART_8250_FLOW_CONTROL
 
 config DEBUG_UNCOMPRESS
        bool
-       depends on ARCH_MULTIPLATFORM || ARCH_MSM
+       depends on ARCH_MULTIPLATFORM || ARCH_MSM || PLAT_SAMSUNG
        default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
                     (!DEBUG_TEGRA_UART || !ZBOOT_ROM)
        help
@@ -1161,7 +1157,8 @@ config DEBUG_UNCOMPRESS
 
 config UNCOMPRESS_INCLUDE
        string
-       default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM
+       default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
+                                       PLAT_SAMSUNG || ARCH_EFM32
        default "mach/uncompress.h"
 
 config EARLY_PRINTK
index fddf4beaee45d32a19fa020527bfc573f3b33cbd..41c1931f01552589e7939a9e8d95a9d3ad94bf53 100644 (file)
@@ -143,7 +143,6 @@ textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_AT91)            += at91
 machine-$(CONFIG_ARCH_BCM)             += bcm
-machine-$(CONFIG_ARCH_BCM2835)         += bcm2835
 machine-$(CONFIG_ARCH_BERLIN)          += berlin
 machine-$(CONFIG_ARCH_CLPS711X)                += clps711x
 machine-$(CONFIG_ARCH_CNS3XXX)         += cns3xxx
@@ -180,6 +179,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS)    += omap2
 machine-$(CONFIG_ARCH_ORION5X)         += orion5x
 machine-$(CONFIG_ARCH_PICOXCELL)       += picoxcell
 machine-$(CONFIG_ARCH_PXA)             += pxa
+machine-$(CONFIG_ARCH_QCOM)            += qcom
 machine-$(CONFIG_ARCH_REALVIEW)                += realview
 machine-$(CONFIG_ARCH_ROCKCHIP)                += rockchip
 machine-$(CONFIG_ARCH_RPC)             += rpc
@@ -199,7 +199,6 @@ machine-$(CONFIG_ARCH_U300)         += u300
 machine-$(CONFIG_ARCH_U8500)           += ux500
 machine-$(CONFIG_ARCH_VERSATILE)       += versatile
 machine-$(CONFIG_ARCH_VEXPRESS)                += vexpress
-machine-$(CONFIG_ARCH_VIRT)            += virt
 machine-$(CONFIG_ARCH_VT8500)          += vt8500
 machine-$(CONFIG_ARCH_W90X900)         += w90x900
 machine-$(CONFIG_ARCH_ZYNQ)            += zynq
index d3cb0126a102c4941e88cafb0f2d692821c4bd3f..35c146f31e46effa1b3b64cd69fd3a3b76ab38cb 100644 (file)
@@ -12,6 +12,8 @@ dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb
 dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb
 dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb
 dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb
+# sam9261
+dtb-$(CONFIG_ARCH_AT91) += at91sam9261ek.dtb
 # sam9263
 dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb
 dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb
@@ -29,6 +31,8 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb
 dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb
 # sam9n12
 dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb
+# sam9rl
+dtb-$(CONFIG_ARCH_AT91) += at91sam9rlek.dtb
 # sam9x5
 dtb-$(CONFIG_ARCH_AT91) += at91-ariag25.dtb
 dtb-$(CONFIG_ARCH_AT91) += at91-cosino_mega2560.dtb
@@ -47,19 +51,15 @@ dtb-$(CONFIG_ARCH_AT91)     += sama5d36ek.dtb
 
 dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
-dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \
-       bcm28155-ap.dtb
+dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
+       bcm21664-garnet.dtb
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
+dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
        berlin2-sony-nsz-gs7.dtb        \
        berlin2cd-google-chromecast.dtb
 dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \
        da850-evm.dtb
-dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
-       dove-cubox.dtb \
-       dove-d2plug.dtb \
-       dove-d3plug.dtb \
-       dove-dove-db.dtb
 dtb-$(CONFIG_ARCH_EFM32) += efm32gg-dk3750.dtb
 dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
        exynos4210-smdkv310.dtb \
@@ -82,14 +82,30 @@ dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
        ecx-2000.dtb
 dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
        integratorcp.dtb
-dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
-dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
+dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \
+       k2l-evm.dtb \
+       k2e-evm.dtb
+kirkwood := \
+       kirkwood-b3.dtb \
+       kirkwood-cloudbox.dtb \
        kirkwood-db-88f6281.dtb \
        kirkwood-db-88f6282.dtb \
        kirkwood-dns320.dtb \
        kirkwood-dns325.dtb \
        kirkwood-dockstar.dtb \
        kirkwood-dreamplug.dtb \
+       kirkwood-ds109.dtb \
+       kirkwood-ds110jv10.dtb \
+       kirkwood-ds111.dtb \
+       kirkwood-ds209.dtb \
+       kirkwood-ds210.dtb \
+       kirkwood-ds212.dtb \
+       kirkwood-ds212j.dtb \
+       kirkwood-ds409.dtb \
+       kirkwood-ds409slim.dtb \
+       kirkwood-ds411.dtb \
+       kirkwood-ds411j.dtb \
+       kirkwood-ds411slim.dtb \
        kirkwood-goflexnet.dtb \
        kirkwood-guruplug-server-plus.dtb \
        kirkwood-ib62x0.dtb \
@@ -112,54 +128,74 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
        kirkwood-nsa310a.dtb \
        kirkwood-openblocks_a6.dtb \
        kirkwood-openblocks_a7.dtb \
+       kirkwood-rd88f6192.dtb \
+       kirkwood-rd88f6281-a0.dtb \
+       kirkwood-rd88f6281-a1.dtb \
+       kirkwood-rs212.dtb \
+       kirkwood-rs409.dtb \
+       kirkwood-rs411.dtb \
        kirkwood-sheevaplug.dtb \
        kirkwood-sheevaplug-esata.dtb \
+       kirkwood-t5325.dtb \
        kirkwood-topkick.dtb \
        kirkwood-ts219-6281.dtb \
-       kirkwood-ts219-6282.dtb
+       kirkwood-ts219-6282.dtb \
+       kirkwood-ts419-6281.dtb \
+       kirkwood-ts419-6282.dtb
+dtb-$(CONFIG_ARCH_KIRKWOOD) += $(kirkwood)
+dtb-$(CONFIG_MACH_KIRKWOOD) += $(kirkwood)
+dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
-dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
-       qcom-msm8960-cdp.dtb \
-       qcom-apq8074-dragonboard.dtb
-dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
-       armada-370-mirabox.dtb \
-       armada-370-netgear-rn102.dtb \
-       armada-370-netgear-rn104.dtb \
-       armada-370-rd.dtb \
-       armada-xp-axpwifiap.dtb \
-       armada-xp-db.dtb \
-       armada-xp-gp.dtb \
-       armada-xp-netgear-rn2120.dtb \
-       armada-xp-matrix.dtb \
-       armada-xp-openblocks-ax3-4.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
+       imx25-eukrea-mbimxsd25-baseboard.dtb \
        imx25-karo-tx25.dtb \
        imx25-pdk.dtb \
        imx27-apf27.dtb \
        imx27-apf27dev.dtb \
        imx27-pdk.dtb \
-       imx27-phytec-phycore-som.dtb \
        imx27-phytec-phycore-rdk.dtb \
-       imx27-phytec-phycard-s-som.dtb \
        imx27-phytec-phycard-s-rdk.dtb \
        imx31-bug.dtb \
+       imx35-eukrea-mbimxsd35-baseboard.dtb \
+       imx50-evk.dtb \
        imx51-apf51.dtb \
        imx51-apf51dev.dtb \
        imx51-babbage.dtb \
+       imx51-eukrea-mbimxsd51-baseboard.dtb \
        imx53-ard.dtb \
-       imx53-evk.dtb \
        imx53-m53evk.dtb \
        imx53-mba53.dtb \
        imx53-qsb.dtb \
+       imx53-qsrb.dtb \
        imx53-smd.dtb \
+       imx53-tx53-x03x.dtb \
+       imx53-tx53-x13x.dtb \
+       imx53-voipac-bsb.dtb \
        imx6dl-cubox-i.dtb \
+       imx6dl-dfi-fs700-m60.dtb \
+       imx6dl-gw51xx.dtb \
+       imx6dl-gw52xx.dtb \
+       imx6dl-gw53xx.dtb \
+       imx6dl-gw54xx.dtb \
        imx6dl-hummingboard.dtb \
+       imx6dl-nitrogen6x.dtb \
        imx6dl-sabreauto.dtb \
+       imx6dl-sabrelite.dtb \
        imx6dl-sabresd.dtb \
        imx6dl-wandboard.dtb \
        imx6q-arm2.dtb \
+       imx6q-cm-fx6.dtb \
        imx6q-cubox-i.dtb \
+       imx6q-dfi-fs700-m60.dtb \
+       imx6q-dmo-edmqmx6.dtb \
+       imx6q-gk802.dtb \
+       imx6q-gw51xx.dtb \
+       imx6q-gw52xx.dtb \
+       imx6q-gw53xx.dtb \
+       imx6q-gw5400-a.dtb \
+       imx6q-gw54xx.dtb \
+       imx6q-nitrogen6x.dtb \
        imx6q-phytec-pbab01.dtb \
        imx6q-sabreauto.dtb \
        imx6q-sabrelite.dtb \
@@ -183,6 +219,9 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
        imx28-cfa10056.dtb \
        imx28-cfa10057.dtb \
        imx28-cfa10058.dtb \
+       imx28-duckbill.dtb \
+       imx28-eukrea-mbmx283lc.dtb \
+       imx28-eukrea-mbmx287lc.dtb \
        imx28-evk.dtb \
        imx28-m28cu3.dtb \
        imx28-m28evk.dtb \
@@ -199,6 +238,10 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        omap2420-n810-wimax.dtb \
        omap3430-sdp.dtb \
        omap3-beagle.dtb \
+       omap3-cm-t3517.dtb \
+       omap3-sbc-t3517.dtb \
+       omap3-cm-t3530.dtb \
+       omap3-sbc-t3530.dtb \
        omap3-cm-t3730.dtb \
        omap3-sbc-t3730.dtb \
        omap3-devkit8000.dtb \
@@ -209,12 +252,24 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        omap3-n900.dtb \
        omap3-n9.dtb \
        omap3-n950.dtb \
+       omap3-overo-alto35.dtb \
+       omap3-overo-storm-alto35.dtb \
+       omap3-overo-chestnut43.dtb \
+       omap3-overo-storm-chestnut43.dtb \
+       omap3-overo-gallop43.dtb \
+       omap3-overo-storm-gallop43.dtb \
+       omap3-overo-palo43.dtb \
+       omap3-overo-storm-palo43.dtb \
+       omap3-overo-summit.dtb \
+       omap3-overo-storm-summit.dtb \
        omap3-overo-tobi.dtb \
        omap3-overo-storm-tobi.dtb \
        omap3-gta04.dtb \
        omap3-igep0020.dtb \
        omap3-igep0030.dtb \
+       omap3-lilly-dbb056.dtb \
        omap3-zoom3.dtb \
+       omap4-duovero-parlor.dtb \
        omap4-panda.dtb \
        omap4-panda-a4.dtb \
        omap4-panda-es.dtb \
@@ -228,12 +283,17 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        am335x-boneblack.dtb \
        am335x-nano.dtb \
        am335x-base0033.dtb \
+       am3517-craneboard.dtb \
        am3517-evm.dtb \
        am3517_mt_ventoux.dtb \
        am43x-epos-evm.dtb \
+       am437x-gp-evm.dtb \
        dra7-evm.dtb
 dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
+       qcom-msm8960-cdp.dtb \
+       qcom-apq8074-dragonboard.dtb
 dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
        ste-hrefprev60-stuib.dtb \
        ste-hrefprev60-tvk.dtb \
@@ -284,6 +344,9 @@ dtb-$(CONFIG_ARCH_SUNXI) += \
        sun4i-a10-cubieboard.dtb \
        sun4i-a10-mini-xplus.dtb \
        sun4i-a10-hackberry.dtb \
+       sun4i-a10-inet97fv2.dtb \
+       sun4i-a10-olinuxino-lime.dtb \
+       sun4i-a10-pcduino.dtb \
        sun5i-a10s-olinuxino-micro.dtb \
        sun5i-a13-olinuxino.dtb \
        sun5i-a13-olinuxino-micro.dtb \
@@ -322,6 +385,29 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
 dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
        zynq-zc706.dtb \
        zynq-zed.dtb
+dtb-$(CONFIG_MACH_ARMADA_370) += \
+       armada-370-db.dtb \
+       armada-370-mirabox.dtb \
+       armada-370-netgear-rn102.dtb \
+       armada-370-netgear-rn104.dtb \
+       armada-370-rd.dtb
+dtb-$(CONFIG_MACH_ARMADA_375) += \
+       armada-375-db.dtb
+dtb-$(CONFIG_MACH_ARMADA_38X) += \
+       armada-385-db.dtb \
+       armada-385-rd.dtb
+dtb-$(CONFIG_MACH_ARMADA_XP) += \
+       armada-xp-axpwifiap.dtb \
+       armada-xp-db.dtb \
+       armada-xp-gp.dtb \
+       armada-xp-netgear-rn2120.dtb \
+       armada-xp-matrix.dtb \
+       armada-xp-openblocks-ax3-4.dtb
+dtb-$(CONFIG_MACH_DOVE) += dove-cm-a510.dtb \
+       dove-cubox.dtb \
+       dove-d2plug.dtb \
+       dove-d3plug.dtb \
+       dove-dove-db.dtb
 
 targets += dtbs dtbs_install
 targets += $(dtb-y)
index 7e6c64ed966d66b4bfe365db5f85186a88b49a24..28ae040e7c3d90b9094afc8c6543cf4749ffe5b0 100644 (file)
                >;
        };
 
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+               >;
+       };
+
        lcd_pins_s0: lcd_pins_s0 {
                pinctrl-single,pins = <
                        0x20 0x01       /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */
        ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
        nand@0,0 {
                reg = <0 0 0>; /* CS0, offset 0 */
-               nand-bus-width = <8>;
                ti,nand-ecc-opt = "bch8";
-               gpmc,device-nand = "true";
+               ti,elm-id = <&elm>;
+               nand-bus-width = <8>;
                gpmc,device-width = <1>;
                gpmc,sync-clk-ps = <0>;
                gpmc,cs-on-ns = <0>;
                gpmc,wait-monitoring-ns = <0>;
                gpmc,wr-access-ns = <40>;
                gpmc,wr-data-mux-bus-ns = <0>;
-
+               /* MTD partition table */
+               /* All SPL-* partitions are sized to minimal length
+                * which can be independently programmable. For
+                * NAND flash this is equal to size of erase-block */
                #address-cells = <1>;
                #size-cells = <1>;
-               elm_id = <&elm>;
-
-               /* MTD partition table */
                partition@0 {
-                       label = "SPL1";
+                       label = "NAND.SPL";
                        reg = <0x00000000 0x000020000>;
                };
-
                partition@1 {
-                       label = "SPL2";
+                       label = "NAND.SPL.backup1";
                        reg = <0x00020000 0x00020000>;
                };
-
                partition@2 {
-                       label = "SPL3";
+                       label = "NAND.SPL.backup2";
                        reg = <0x00040000 0x00020000>;
                };
-
                partition@3 {
-                       label = "SPL4";
+                       label = "NAND.SPL.backup3";
                        reg = <0x00060000 0x00020000>;
                };
-
                partition@4 {
-                       label = "U-boot";
-                       reg = <0x00080000 0x001e0000>;
+                       label = "NAND.u-boot-spl";
+                       reg = <0x00080000 0x00040000>;
                };
-
                partition@5 {
-                       label = "environment";
-                       reg = <0x00260000 0x00020000>;
+                       label = "NAND.u-boot";
+                       reg = <0x000C0000 0x00100000>;
                };
-
                partition@6 {
-                       label = "Kernel";
-                       reg = <0x00280000 0x00500000>;
+                       label = "NAND.u-boot-env";
+                       reg = <0x001C0000 0x00020000>;
                };
-
                partition@7 {
-                       label = "File-System";
-                       reg = <0x00780000 0x0F880000>;
+                       label = "NAND.u-boot-env.backup1";
+                       reg = <0x001E0000 0x00020000>;
+               };
+               partition@8 {
+                       label = "NAND.kernel";
+                       reg = <0x00200000 0x00800000>;
+               };
+               partition@9 {
+                       label = "NAND.file-system";
+                       reg = <0x00A00000 0x0F600000>;
                };
        };
 };
        status = "okay";
        vmmc-supply = <&vmmc_reg>;
        bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
 };
 
 &sham {
index 486880b7483134c88f8638a6e7fb4cc98518e7e3..ec08f6f677c3eb4a2025a096b30e941efbd706a0 100644 (file)
                regulator-boot-on;
        };
 
+       wl12xx_vmmc: fixedregulator@2 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&wl12xx_gpio>;
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1271";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpio = <&gpio1 29 0>;
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+
        leds {
                pinctrl-names = "default";
                pinctrl-0 = <&user_leds_s0>;
                        0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
                >;
        };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
+                       0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+               >;
+       };
+
+       wl12xx_gpio: pinmux_wl12xx_gpio {
+               pinctrl-single,pins = <
+                       0x7c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
+               >;
+       };
 };
 
 &uart0 {
                status = "okay";
        };
 
+       usb-phy@47401b00 {
+               status = "okay";
+       };
+
        usb@47401000 {
                status = "okay";
        };
+
+       usb@47401800 {
+               status = "okay";
+               dr_mode = "host";
+       };
+
+       dma-controller@07402000  {
+               status = "okay";
+       };
 };
 
 &epwmss2 {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = <&cpsw_default>;
        pinctrl-1 = <&cpsw_sleep>;
+       dual_emac = <1>;
 };
 
 &davinci_mdio {
 &cpsw_emac0 {
        phy_id = <&davinci_mdio>, <0>;
        phy-mode = "rgmii-txid";
+       dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
        phy_id = <&davinci_mdio>, <1>;
        phy-mode = "rgmii-txid";
+       dual_emac_res_vlan = <2>;
 };
 
 &mmc1 {
        ti,no-reset-on-init;
 };
 
+&mmc2 {
+       status = "okay";
+       vmmc-supply = <&wl12xx_vmmc>;
+       ti,non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+};
+
 &mcasp1 {
                pinctrl-names = "default";
                pinctrl-0 = <&mcasp1_pins>;
index 6d95d3df33c7913dc0feb76598f6e94ea15cf0fa..9770e35f25361644ade6c8846ba5cb7571822f0c 100644 (file)
                                275000  1125000
                        >;
                        voltage-tolerance = <2>; /* 2 percentage */
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
                        clock-latency = <300000>; /* From omap-cpufreq driver */
                };
        };
                        compatible = "ti,omap4-hwspinlock";
                        reg = <0x480ca000 0x1000>;
                        ti,hwmods = "spinlock";
+                       #hwlock-cells = <1>;
                };
 
                wdt2: wdt@44e35000 {
                        ti,timer-pwm;
                };
 
-               rtc@44e3e000 {
+               rtc: rtc@44e3e000 {
                        compatible = "ti,da830-rtc";
                        reg = <0x44e3e000 0x1000>;
                        interrupts = <75
                        ti,hwmods = "usb_otg_hs";
                        status = "disabled";
 
-                       usb_ctrl_mod: control@44e10000 {
+                       usb_ctrl_mod: control@44e10620 {
                                compatible = "ti,am335x-usb-ctrl-module";
                                reg = <0x44e10620 0x10
                                        0x44e10648 0x4>;
                                        "tx14", "tx15";
                        };
 
-                       cppi41dma: dma-controller@07402000 {
+                       cppi41dma: dma-controller@47402000 {
                                compatible = "ti,am3359-cppi41";
                                reg =  <0x47400000 0x1000
                                        0x47402000 0x1000
                                compatible = "ti,am33xx-ecap";
                                #pwm-cells = <3>;
                                reg = <0x48300100 0x80>;
+                               interrupts = <31>;
+                               interrupt-names = "ecap0";
                                ti,hwmods = "ecap0";
                                status = "disabled";
                        };
                                compatible = "ti,am33xx-ecap";
                                #pwm-cells = <3>;
                                reg = <0x48302100 0x80>;
+                               interrupts = <47>;
+                               interrupt-names = "ecap1";
                                ti,hwmods = "ecap1";
                                status = "disabled";
                        };
                                compatible = "ti,am33xx-ecap";
                                #pwm-cells = <3>;
                                reg = <0x48304100 0x80>;
+                               interrupts = <61>;
+                               interrupt-names = "ecap2";
                                ti,hwmods = "ecap2";
                                status = "disabled";
                        };
diff --git a/arch/arm/boot/dts/am3517-craneboard.dts b/arch/arm/boot/dts/am3517-craneboard.dts
new file mode 100644 (file)
index 0000000..2d40b3f
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * See craneboard.org for more details
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "am3517.dtsi"
+
+/ {
+       model = "TI AM3517 CraneBoard (TMDSEVM3517)";
+       compatible = "ti,am3517-craneboard", "ti,am3517", "ti,omap3";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>;  /* 256 MB */
+       };
+
+       vbat: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vbat";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+       };
+};
+
+&davinci_emac {
+       status = "okay";
+};
+
+&davinci_mdio {
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       tps: tps@2d {
+               reg = <0x2d>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+       /* goes to expansion connector */
+       status = "disabled";
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+       /* goes to expansion connector */
+       status = "disabled";
+};
+
+&mmc1 {
+       vmmc-supply = <&vdd2_reg>;
+       bus-width = <8>;
+};
+
+&mmc2 {
+       /* goes to expansion connector */
+       status = "disabled";
+};
+
+&mmc3 {
+       /* goes to expansion connector */
+       status = "disabled";
+};
+
+#include "tps65910.dtsi"
+
+&omap3_pmx_core {
+       tps_pins: pinmux_tps_pins {
+               pinctrl-single,pins = <
+                       0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq.sys_nirq */
+               >;
+       };
+};
+
+&tps {
+       pinctrl-names = "default";
+       pinctrl-0 = <&tps_pins>;
+
+       interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+       interrupt-parent = <&intc>;
+
+       ti,en-ck32k-xtal;
+
+       vcc1-supply = <&vbat>;
+       vcc2-supply = <&vbat>;
+       vcc3-supply = <&vbat>;
+       vcc4-supply = <&vbat>;
+       vcc5-supply = <&vbat>;
+       vcc6-supply = <&vbat>;
+       vcc7-supply = <&vbat>;
+       vccio-supply = <&vbat>;
+
+       regulators {
+               vrtc_reg: regulator@0 {
+                       regulator-always-on;
+               };
+
+               vio_reg: regulator@1 {
+                       regulator-always-on;
+               };
+
+               /*
+                * Unused:
+                * VDIG1=2.7V,300mA max
+                * VDIG2=1.8V,300mA max
+                */
+
+               vpll_reg: regulator@7 {
+                       /* VDDS_DPLL_1V8 */
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vaux1_reg: regulator@9 {
+                       /* VDDS_SRAM_1V8 */
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vaux2_reg: regulator@10 {
+                       /* VDDA1P8V_USBPHY */
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               /* VAUX33 unused */
+
+               vdac_reg: regulator@8 {
+                       /* VDDA_DAC_1V8 */
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vmmc_reg: regulator@12 {
+                       /* VDDA3P3V_USBPHY */
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vdd1_reg: regulator@2 {
+                       /* VDD_CORE */
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               vdd2_reg: regulator@3 {
+                       /* VDDSHV_3V3 */
+                       regulator-name = "vdd_shv";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               /* VDD3 unused */
+       };
+};
index c6bd4d986c290aaeb7bd4e0f78e2d48489c2bee4..36d523a268314d3e1948dd894ae6b07141ac946e 100644 (file)
@@ -8,6 +8,7 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 #include "skeleton.dtsi"
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <0>;
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
                };
        };
 
                        status = "disabled";
                };
 
+               hwspinlock: spinlock@480ca000 {
+                       compatible = "ti,omap4-hwspinlock";
+                       reg = <0x480ca000 0x1000>;
+                       ti,hwmods = "spinlock";
+                       #hwlock-cells = <1>;
+               };
+
                i2c0: i2c@44e0b000 {
                        compatible = "ti,am4372-i2c","ti,omap4-i2c";
                        reg = <0x44e0b000 0x1000>;
 
                        ecap0: ecap@48300100 {
                                compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+                               #pwm-cells = <3>;
                                reg = <0x48300100 0x80>;
                                ti,hwmods = "ecap0";
                                status = "disabled";
 
                        ehrpwm0: ehrpwm@48300200 {
                                compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               #pwm-cells = <3>;
                                reg = <0x48300200 0x80>;
                                ti,hwmods = "ehrpwm0";
                                status = "disabled";
 
                        ecap1: ecap@48302100 {
                                compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+                               #pwm-cells = <3>;
                                reg = <0x48302100 0x80>;
                                ti,hwmods = "ecap1";
                                status = "disabled";
 
                        ehrpwm1: ehrpwm@48302200 {
                                compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               #pwm-cells = <3>;
                                reg = <0x48302200 0x80>;
                                ti,hwmods = "ehrpwm1";
                                status = "disabled";
 
                        ecap2: ecap@48304100 {
                                compatible = "ti,am4372-ecap","ti,am33xx-ecap";
+                               #pwm-cells = <3>;
                                reg = <0x48304100 0x80>;
                                ti,hwmods = "ecap2";
                                status = "disabled";
 
                        ehrpwm2: ehrpwm@48304200 {
                                compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               #pwm-cells = <3>;
                                reg = <0x48304200 0x80>;
                                ti,hwmods = "ehrpwm2";
                                status = "disabled";
 
                        ehrpwm3: ehrpwm@48306200 {
                                compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               #pwm-cells = <3>;
                                reg = <0x48306200 0x80>;
                                ti,hwmods = "ehrpwm3";
                                status = "disabled";
 
                        ehrpwm4: ehrpwm@48308200 {
                                compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               #pwm-cells = <3>;
                                reg = <0x48308200 0x80>;
                                ti,hwmods = "ehrpwm4";
                                status = "disabled";
 
                        ehrpwm5: ehrpwm@4830a200 {
                                compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm";
+                               #pwm-cells = <3>;
                                reg = <0x4830a200 0x80>;
                                ti,hwmods = "ehrpwm5";
                                status = "disabled";
                               <&edma 11>;
                        dma-names = "tx", "rx";
                };
+
+               elm: elm@48080000 {
+                       compatible = "ti,am3352-elm";
+                       reg = <0x48080000 0x2000>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "elm";
+                       clocks = <&l4ls_gclk>;
+                       clock-names = "fck";
+                       status = "disabled";
+               };
+
+               gpmc: gpmc@50000000 {
+                       compatible = "ti,am3352-gpmc";
+                       ti,hwmods = "gpmc";
+                       clocks = <&l3s_gclk>;
+                       clock-names = "fck";
+                       reg = <0x50000000 0x2000>;
+                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                       gpmc,num-cs = <7>;
+                       gpmc,num-waitpins = <2>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       status = "disabled";
+               };
        };
 };
 
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
new file mode 100644 (file)
index 0000000..df8798e
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* AM437x GP EVM */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "TI AM437x GP EVM";
+       compatible = "ti,am437x-gp-evm","ti,am4372","ti,am43";
+
+       vmmcsd_fixed: fixedregulator-sd {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 51 53 56 62 75 101 152 255>;
+               default-brightness-level = <8>;
+       };
+
+       matrix_keypad: matrix_keypad@0 {
+               compatible = "gpio-matrix-keypad";
+               debounce-delay-ms = <5>;
+               col-scan-delay-us = <2>;
+
+               row-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH /* Bank3, pin21 */
+                               &gpio4 3 GPIO_ACTIVE_HIGH /* Bank4, pin3 */
+                               &gpio4 2 GPIO_ACTIVE_HIGH>; /* Bank4, pin2 */
+
+               col-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH /* Bank3, pin19 */
+                               &gpio3 20 GPIO_ACTIVE_HIGH>; /* Bank3, pin20 */
+
+               linux,keymap = <0x00000201      /* P1 */
+                               0x00010202      /* P2 */
+                               0x01000067      /* UP */
+                               0x0101006a      /* RIGHT */
+                               0x02000069      /* LEFT */
+                               0x0201006c>;      /* DOWN */
+               };
+};
+
+&am43xx_pinmux {
+       i2c0_pins: i2c0_pins {
+               pinctrl-single,pins = <
+                       0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_sda.i2c0_sda */
+                       0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)  /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       i2c1_pins: i2c1_pins {
+               pinctrl-single,pins = <
+                       0x15c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_cs0.i2c1_scl */
+                       0x158 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2)  /* spi0_d1.i2c1_sda  */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+               >;
+       };
+
+       ecap0_pins: backlight_pins {
+               pinctrl-single,pins = <
+                       0x164 MUX_MODE0       /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+               >;
+       };
+};
+
+&i2c0 {
+        status = "okay";
+        pinctrl-names = "default";
+        pinctrl-0 = <&i2c0_pins>;
+};
+
+&i2c1 {
+        status = "okay";
+        pinctrl-names = "default";
+        pinctrl-0 = <&i2c1_pins>;
+};
+
+&epwmss0 {
+       status = "okay";
+};
+
+&ecap0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&ecap0_pins>;
+};
+
+&gpio0 {
+       status = "okay";
+};
+
+&gpio3 {
+       status = "okay";
+};
+
+&gpio4 {
+       status = "okay";
+};
+
+&mmc1 {
+       status = "okay";
+       vmmc-supply = <&vmmcsd_fixed>;
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
index fbf9c4c7a94fe7f998346140d32540b6ebf3507f..167dbc8494deef2ba3bd9c63a7bf20afe9ddb21f 100644 (file)
@@ -13,6 +13,7 @@
 #include "am4372.dtsi"
 #include <dt-bindings/pinctrl/am43xx.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "TI AM43x EPOS EVM";
                                0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
                        >;
                };
+
+               nand_flash_x8: nand_flash_x8 {
+                       pinctrl-single,pins = <
+                               0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_a0.SELQSPIorNAND/GPIO */
+                               0x0  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad0.gpmc_ad0 */
+                               0x4  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad1.gpmc_ad1 */
+                               0x8  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad2.gpmc_ad2 */
+                               0xc  (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad3.gpmc_ad3 */
+                               0x10 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad4.gpmc_ad4 */
+                               0x14 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad5.gpmc_ad5 */
+                               0x18 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad6.gpmc_ad6 */
+                               0x1c (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* gpmc_ad7.gpmc_ad7 */
+                               0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
+                               0x74 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_wpn.gpmc_wpn */
+                               0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
+                               0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
+                               0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
+                               0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
+                               0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+                       >;
+               };
+
+               ecap0_pins: backlight_pins {
+                       pinctrl-single,pins = <
+                               0x164 MUX_MODE0         /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+                       >;
+               };
+
+               i2c2_pins: pinmux_i2c2_pins {
+                       pinctrl-single,pins = <
+                               0x1c0 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8)    /* i2c2_sda.i2c2_sda */
+                               0x1c4 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE8)    /* i2c2_scl.i2c2_scl */
+                       >;
+               };
+
+               spi0_pins: pinmux_spi0_pins {
+                       pinctrl-single,pins = <
+                               0x150 (PIN_INPUT | MUX_MODE0)           /* spi0_clk.spi0_clk */
+                               0x154 (PIN_OUTPUT | MUX_MODE0)           /* spi0_d0.spi0_d0 */
+                               0x158 (PIN_INPUT | MUX_MODE0)           /* spi0_d1.spi0_d1 */
+                               0x15c (PIN_OUTPUT | MUX_MODE0)          /* spi0_cs0.spi0_cs0 */
+                       >;
+               };
+
+               spi1_pins: pinmux_spi1_pins {
+                       pinctrl-single,pins = <
+                               0x190 (PIN_INPUT | MUX_MODE3)           /* mcasp0_aclkx.spi1_clk */
+                               0x194 (PIN_OUTPUT | MUX_MODE3)           /* mcasp0_fsx.spi1_d0 */
+                               0x198 (PIN_INPUT | MUX_MODE3)           /* mcasp0_axr0.spi1_d1 */
+                               0x19c (PIN_OUTPUT | MUX_MODE3)          /* mcasp0_ahclkr.spi1_cs0 */
+                       >;
+               };
+
+               mmc1_pins: pinmux_mmc1_pins {
+                       pinctrl-single,pins = <
+                               0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+                       >;
+               };
        };
 
        matrix_keypad: matrix_keypad@0 {
                                0x0203006c      /* DOWN */
                                0x03030069>;    /* LEFT */
                };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&ecap0 0 50000 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 51 53 56 62 75 101 152 255>;
+               default-brightness-level = <8>;
+       };
 };
 
 &mmc1 {
        status = "okay";
        vmmc-supply = <&vmmcsd_fixed>;
        bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
 };
 
 &mac {
        };
 };
 
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+       status = "okay";
+};
+
 &gpio0 {
        status = "okay";
 };
 &gpio3 {
        status = "okay";
 };
+
+&elm {
+       status = "okay";
+};
+
+&gpmc {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_flash_x8>;
+       ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
+       nand@0,0 {
+               reg = <0 0 0>; /* CS0, offset 0 */
+               ti,nand-ecc-opt = "bch8";
+               ti,elm-id = <&elm>;
+               nand-bus-width = <8>;
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <40>; /* tCEA + tCHZ + 1 */
+               gpmc,cs-wr-off-ns = <40>;
+               gpmc,adv-on-ns = <0>;  /* cs-on-ns */
+               gpmc,adv-rd-off-ns = <25>; /* min( tALH + tALS + 1) */
+               gpmc,adv-wr-off-ns = <25>; /* min( tALH + tALS + 1) */
+               gpmc,we-on-ns = <0>;   /* cs-on-ns */
+               gpmc,we-off-ns = <20>; /* we-on-time + tWP + 2 */
+               gpmc,oe-on-ns = <3>;  /* cs-on-ns + tRR + 2 */
+               gpmc,oe-off-ns = <30>; /* oe-on-ns + tRP + 2 */
+               gpmc,access-ns = <30>; /* tCEA + 4*/
+               gpmc,rd-cycle-ns = <40>;
+               gpmc,wr-cycle-ns = <40>;
+               gpmc,wait-on-read = "true";
+               gpmc,wait-on-write = "true";
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+               /* MTD partition table */
+               /* All SPL-* partitions are sized to minimal length
+                * which can be independently programmable. For
+                * NAND flash this is equal to size of erase-block */
+               #address-cells = <1>;
+               #size-cells = <1>;
+               partition@0 {
+                       label = "NAND.SPL";
+                       reg = <0x00000000 0x00040000>;
+               };
+               partition@1 {
+                       label = "NAND.SPL.backup1";
+                       reg = <0x00040000 0x00040000>;
+               };
+               partition@2 {
+                       label = "NAND.SPL.backup2";
+                       reg = <0x00080000 0x00040000>;
+               };
+               partition@3 {
+                       label = "NAND.SPL.backup3";
+                       reg = <0x000C0000 0x00040000>;
+               };
+               partition@4 {
+                       label = "NAND.u-boot-spl-os";
+                       reg = <0x00100000 0x00080000>;
+               };
+               partition@5 {
+                       label = "NAND.u-boot";
+                       reg = <0x00180000 0x00100000>;
+               };
+               partition@6 {
+                       label = "NAND.u-boot-env";
+                       reg = <0x00280000 0x00040000>;
+               };
+               partition@7 {
+                       label = "NAND.u-boot-env.backup1";
+                       reg = <0x002C0000 0x00040000>;
+               };
+               partition@8 {
+                       label = "NAND.kernel";
+                       reg = <0x00300000 0x00700000>;
+               };
+               partition@9 {
+                       label = "NAND.file-system";
+                       reg = <0x00800000 0x1F600000>;
+               };
+       };
+};
+
+&epwmss0 {
+       status = "okay";
+};
+
+&ecap0 {
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&ecap0_pins>;
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi0_pins>;
+       status = "okay";
+};
+
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi1_pins>;
+       status = "okay";
+};
index 08a56bcfc7248704b34ad1789418308819b3bcbf..82f238a9063ffe47d10dbe083f136e1876f8efd2 100644 (file)
                                phy-mode = "rgmii-id";
                        };
 
+                       i2c@11000 {
+                               pinctrl-0 = <&i2c0_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                               audio_codec: audio-codec@4a {
+                                       compatible = "cirrus,cs42l51";
+                                       reg = <0x4a>;
+                               };
+                       };
+
+                       audio-controller@30000 {
+                               pinctrl-0 = <&i2s_pins2>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
                        mvsdio@d4000 {
                                pinctrl-0 = <&sdio_pins1>;
                                pinctrl-names = "default";
                                broken-cd;
                        };
 
+                       pinctrl {
+                               /*
+                                * These pins might be muxed as I2S by
+                                * the bootloader, but it conflicts
+                                * with the real I2S pins that are
+                                * muxed using i2s_pins. We must mux
+                                * those pins to a function other than
+                                * I2S.
+                                */
+                               pinctrl-0 = <&hog_pins1 &hog_pins2>;
+                               pinctrl-names = "default";
+
+                               hog_pins1: hog-pins1 {
+                                       marvell,pins = "mpp6",  "mpp8", "mpp10",
+                                                      "mpp12", "mpp13";
+                                       marvell,function = "gpio";
+                               };
+
+                               hog_pins2: hog-pins2 {
+                                       marvell,pins = "mpp5", "mpp7", "mpp9";
+                                       marvell,function = "gpo";
+                               };
+                       };
+
                        usb@50000 {
                                status = "okay";
                        };
                                /* Port 0, Lane 0 */
                                status = "okay";
                        };
+
                        pcie@2,0 {
                                /* Port 1, Lane 0 */
                                status = "okay";
                        };
                };
        };
+
+       sound {
+             compatible = "marvell,a370db-audio";
+             marvell,audio-controller = <&audio_controller>;
+             marvell,audio-codec = <&audio_codec &spdif_out &spdif_in>;
+             status = "okay";
+       };
+
+       spdif_out: spdif-out {
+             compatible = "linux,spdif-dit";
+       };
+
+       spdif_in: spdif-in {
+             compatible = "linux,spdif-dir";
+       };
 };
index 944e8785b30833ea34ace20884c6844a7d3cfe15..2354fe023ee01ee6f9df5e1b0f23e6e9498acf86 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
 #include "armada-370.dtsi"
 
 / {
 
                                green_pwr_led {
                                        label = "mirabox:green:pwr";
-                                       gpios = <&gpio1 31 1>;
+                                       gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
                                        default-state = "keep";
                                };
 
                                blue_stat_led {
                                        label = "mirabox:blue:stat";
-                                       gpios = <&gpio2 0 1>;
+                                       gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
                                        default-state = "off";
                                };
 
                                green_stat_led {
                                        label = "mirabox:green:stat";
-                                       gpios = <&gpio2 1 1>;
+                                       gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
                                        default-state = "off";
                                };
                        };
index abbb807459d26d6708ed01822702f43d79d362e5..3e2c857d600008a896d3402572fedd8d68bbf624 100644 (file)
@@ -12,6 +12,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "armada-370.dtsi"
 
 / {
                                #size-cells = <0>;
                                button@1 {
                                        label = "Software Button";
-                                       linux,code = <116>;
-                                       gpios = <&gpio0 6 1>;
+                                       linux,code = <KEY_POWER>;
+                                       gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
                                };
                        };
 
index 74b5964430ac3a7d833d8fce12eb655746acba4b..bbb40f62037dbaf67ac8a585a17817997e8c1a17 100644 (file)
@@ -44,8 +44,8 @@
                #size-cells = <1>;
                controller = <&mbusc>;
                interrupt-parent = <&mpic>;
-               pcie-mem-aperture = <0xe0000000 0x8000000>;
-               pcie-io-aperture  = <0xe8000000 0x100000>;
+               pcie-mem-aperture = <0xf8000000 0x7e00000>;
+               pcie-io-aperture  = <0xffe00000 0x100000>;
 
                devbus-bootcs {
                        compatible = "marvell,mvebu-devbus";
                                interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
                        };
 
+                       watchdog@20300 {
+                               reg = <0x20300 0x34>, <0x20704 0x4>;
+                       };
+
                        usb@50000 {
                                compatible = "marvell,orion-ehci";
                                reg = <0x50000 0x500>;
index 0d8530c98cf5072f75662807f5cddcf2a40bee40..af1f11e9e5a011d526f64f8afaa60d000ef87542 100644 (file)
                                                        "mpp51", "mpp52", "mpp53";
                                        marvell,function = "sd0";
                                };
+
+                               i2c0_pins: i2c0-pins {
+                                       marvell,pins = "mpp2", "mpp3";
+                                       marvell,function = "i2c0";
+                               };
+
+                               i2s_pins1: i2s-pins1 {
+                                       marvell,pins = "mpp5", "mpp6", "mpp7",
+                                                      "mpp8", "mpp9", "mpp10",
+                                                      "mpp12", "mpp13";
+                                       marvell,function = "audio";
+                               };
+
+                               i2s_pins2: i2s-pins2 {
+                                       marvell,pins = "mpp49", "mpp47", "mpp50",
+                                                      "mpp59", "mpp57", "mpp61",
+                                                      "mpp62", "mpp60", "mpp58";
+                                       marvell,function = "audio";
+                               };
                        };
 
                        gpio0: gpio@18100 {
                                clocks = <&coreclk 2>;
                        };
 
+                       watchdog@20300 {
+                               compatible = "marvell,armada-370-wdt";
+                               clocks = <&coreclk 2>;
+                       };
+
+                       audio_controller: audio-controller@30000 {
+                               compatible = "marvell,armada370-audio";
+                               reg = <0x30000 0x4000>;
+                               interrupts = <93>;
+                               clocks = <&gateclk 0>;
+                               clock-names = "internal";
+                               status = "disabled";
+                       };
+
                        usb@50000 {
                                clocks = <&coreclk 0>;
                        };
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
new file mode 100644 (file)
index 0000000..9378d31
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Device Tree file for Marvell Armada 375 evaluation board
+ * (DB-88F6720)
+ *
+ *  Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-375.dtsi"
+
+/ {
+       model = "Marvell Armada 375 Development Board";
+       compatible = "marvell,a375-db", "marvell,armada375";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000>; /* 1 GB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+               internal-regs {
+                       spi@10600 {
+                               pinctrl-0 = <&spi0_pins>;
+                               pinctrl-names = "default";
+                               /*
+                                * SPI conflicts with NAND, so we disable it
+                                * here, and select NAND as the enabled device
+                                * by default.
+                                */
+                               status = "disabled";
+
+                               spi-flash@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       compatible = "n25q128a13";
+                                       reg = <0>; /* Chip select 0 */
+                                       spi-max-frequency = <108000000>;
+                               };
+                       };
+
+                       i2c@11000 {
+                               status = "okay";
+                               clock-frequency = <100000>;
+                               pinctrl-0 = <&i2c0_pins>;
+                               pinctrl-names = "default";
+                       };
+
+                       i2c@11100 {
+                               status = "okay";
+                               clock-frequency = <100000>;
+                               pinctrl-0 = <&i2c1_pins>;
+                               pinctrl-names = "default";
+                       };
+
+                       serial@12000 {
+                               clock-frequency = <200000000>;
+                               status = "okay";
+                       };
+
+                       pinctrl {
+                               sdio_st_pins: sdio-st-pins {
+                                       marvell,pins = "mpp44", "mpp45";
+                                       marvell,function = "gpio";
+                               };
+                       };
+
+                       nand: nand@d0000 {
+                               pinctrl-0 = <&nand_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                               num-cs = <1>;
+                               marvell,nand-keep-config;
+                               marvell,nand-enable-arbiter;
+                               nand-on-flash-bbt;
+
+                               partition@0 {
+                                       label = "U-Boot";
+                                       reg = <0 0x800000>;
+                               };
+                               partition@800000 {
+                                       label = "Linux";
+                                       reg = <0x800000 0x800000>;
+                               };
+                               partition@1000000 {
+                                       label = "Filesystem";
+                                       reg = <0x1000000 0x3f000000>;
+                               };
+                       };
+
+                       mvsdio@d4000 {
+                               pinctrl-0 = <&sdio_pins &sdio_st_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                               cd-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+                               wp-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+                       };
+               };
+
+               pcie-controller {
+                       status = "okay";
+                       /*
+                        * The two PCIe units are accessible through
+                        * standard PCIe slots on the board.
+                        */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+                       pcie@2,0 {
+                               /* Port 1, Lane 0 */
+                               status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
new file mode 100644 (file)
index 0000000..3877693
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * Device Tree Include file for Marvell Armada 375 family SoC
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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 "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+       model = "Marvell Armada 375 family SoC";
+       compatible = "marvell,armada375";
+
+       aliases {
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+       };
+
+       clocks {
+               /* 2 GHz fixed main PLL */
+               mainpll: mainpll {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <2000000000>;
+               };
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <1>;
+               };
+       };
+
+       soc {
+               compatible = "marvell,armada375-mbus", "marvell,armada370-mbus", "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               controller = <&mbusc>;
+               interrupt-parent = <&gic>;
+               pcie-mem-aperture = <0xe0000000 0x8000000>;
+               pcie-io-aperture  = <0xe8000000 0x100000>;
+
+               bootrom {
+                       compatible = "marvell,bootrom";
+                       reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
+               };
+
+               devbus-bootcs {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs0 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs1 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs2 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs3 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               internal-regs {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+                       L2: cache-controller@8000 {
+                               compatible = "arm,pl310-cache";
+                               reg = <0x8000 0x1000>;
+                               cache-unified;
+                               cache-level = <2>;
+                       };
+
+                       timer@c600 {
+                               compatible = "arm,cortex-a9-twd-timer";
+                               reg = <0xc600 0x20>;
+                               interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+                               clocks = <&coreclk 2>;
+                       };
+
+                       gic: interrupt-controller@d000 {
+                               compatible = "arm,cortex-a9-gic";
+                               #interrupt-cells = <3>;
+                               #size-cells = <0>;
+                               interrupt-controller;
+                               reg = <0xd000 0x1000>,
+                                     <0xc100 0x100>;
+                       };
+
+                       spi0: spi@10600 {
+                               compatible = "marvell,orion-spi";
+                               reg = <0x10600 0x50>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <0>;
+                               interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       spi1: spi@10680 {
+                               compatible = "marvell,orion-spi";
+                               reg = <0x10680 0x50>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <1>;
+                               interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@11000 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               reg = <0x11000 0x20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                               timeout-ms = <1000>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@11100 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               reg = <0x11100 0x20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                               timeout-ms = <1000>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       serial@12000 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0x12000 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-io-width = <1>;
+                               status = "disabled";
+                       };
+
+                       serial@12100 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0x12100 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-io-width = <1>;
+                               status = "disabled";
+                       };
+
+                       pinctrl {
+                               compatible = "marvell,mv88f6720-pinctrl";
+                               reg = <0x18000 0x24>;
+
+                               i2c0_pins: i2c0-pins {
+                                       marvell,pins = "mpp14",  "mpp15";
+                                       marvell,function = "i2c0";
+                               };
+
+                               i2c1_pins: i2c1-pins {
+                                       marvell,pins = "mpp61",  "mpp62";
+                                       marvell,function = "i2c1";
+                               };
+
+                               nand_pins: nand-pins {
+                                       marvell,pins = "mpp0", "mpp1", "mpp2",
+                                               "mpp3", "mpp4", "mpp5",
+                                               "mpp6", "mpp7", "mpp8",
+                                               "mpp9", "mpp10", "mpp11",
+                                               "mpp12", "mpp13";
+                                       marvell,function = "nand";
+                               };
+
+                               sdio_pins: sdio-pins {
+                                       marvell,pins = "mpp24",  "mpp25", "mpp26",
+                                                    "mpp27", "mpp28", "mpp29";
+                                       marvell,function = "sd";
+                               };
+
+                               spi0_pins: spi0-pins {
+                                       marvell,pins = "mpp0",  "mpp1", "mpp4",
+                                                    "mpp5", "mpp8", "mpp9";
+                                       marvell,function = "spi0";
+                               };
+                       };
+
+                       gpio0: gpio@18100 {
+                               compatible = "marvell,orion-gpio";
+                               reg = <0x18100 0x40>;
+                               ngpios = <32>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <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>;
+                       };
+
+                       gpio1: gpio@18140 {
+                               compatible = "marvell,orion-gpio";
+                               reg = <0x18140 0x40>;
+                               ngpios = <32>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               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>;
+                       };
+
+                       gpio2: gpio@18180 {
+                               compatible = "marvell,orion-gpio";
+                               reg = <0x18180 0x40>;
+                               ngpios = <3>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       system-controller@18200 {
+                               compatible = "marvell,armada-375-system-controller";
+                               reg = <0x18200 0x100>;
+                       };
+
+                       gateclk: clock-gating-control@18220 {
+                               compatible = "marvell,armada-375-gating-clock";
+                               reg = <0x18220 0x4>;
+                               clocks = <&coreclk 0>;
+                               #clock-cells = <1>;
+                       };
+
+                       mbusc: mbus-controller@20000 {
+                               compatible = "marvell,mbus-controller";
+                               reg = <0x20000 0x100>, <0x20180 0x20>;
+                       };
+
+                       mpic: interrupt-controller@20000 {
+                               compatible = "marvell,mpic";
+                               reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+                               #interrupt-cells = <1>;
+                               #size-cells = <1>;
+                               interrupt-controller;
+                               msi-controller;
+                               interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       timer@20300 {
+                               compatible = "marvell,armada-375-timer", "marvell,armada-370-timer";
+                               reg = <0x20300 0x30>, <0x21040 0x30>;
+                               interrupts-extended = <&gic  GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&gic  GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&gic  GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&gic  GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&mpic 5>,
+                                                     <&mpic 6>;
+                               clocks = <&coreclk 0>;
+                       };
+
+                       xor@60800 {
+                               compatible = "marvell,orion-xor";
+                               reg = <0x60800 0x100
+                                      0x60A00 0x100>;
+                               clocks = <&gateclk 22>;
+                               status = "okay";
+
+                               xor00 {
+                                       interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+                               xor01 {
+                                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                                       dmacap,memset;
+                               };
+                       };
+
+                       xor@60900 {
+                               compatible = "marvell,orion-xor";
+                               reg = <0x60900 0x100
+                                      0x60b00 0x100>;
+                               clocks = <&gateclk 23>;
+                               status = "okay";
+
+                               xor10 {
+                                       interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+                               xor11 {
+                                       interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                                       dmacap,memset;
+                               };
+                       };
+
+                       sata@a0000 {
+                               compatible = "marvell,orion-sata";
+                               reg = <0xa0000 0x5000>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&gateclk 14>, <&gateclk 20>;
+                               clock-names = "0", "1";
+                               status = "disabled";
+                       };
+
+                       nand@d0000 {
+                               compatible = "marvell,armada370-nand";
+                               reg = <0xd0000 0x54>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&gateclk 11>;
+                               status = "disabled";
+                       };
+
+                       mvsdio@d4000 {
+                               compatible = "marvell,orion-sdio";
+                               reg = <0xd4000 0x200>;
+                               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&gateclk 17>;
+                               bus-width = <4>;
+                               cap-sdio-irq;
+                               cap-sd-highspeed;
+                               cap-mmc-highspeed;
+                               status = "disabled";
+                       };
+
+                       coreclk: mvebu-sar@e8204 {
+                               compatible = "marvell,armada-375-core-clock";
+                               reg = <0xe8204 0x04>;
+                               #clock-cells = <1>;
+                       };
+
+                       coredivclk: corediv-clock@e8250 {
+                               compatible = "marvell,armada-375-corediv-clock";
+                               reg = <0xe8250 0xc>;
+                               #clock-cells = <1>;
+                               clocks = <&mainpll>;
+                               clock-output-names = "nand";
+                       };
+               };
+
+               pcie-controller {
+                       compatible = "marvell,armada-370-pcie";
+                       status = "disabled";
+                       device_type = "pci";
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       msi-parent = <&mpic>;
+                       bus-range = <0x00 0xff>;
+
+                       ranges =
+                              <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+                               0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+                               0x82000000 0x1 0       MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0 MEM */
+                               0x81000000 0x1 0       MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0 IO  */
+                               0x82000000 0x2 0       MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1 MEM */
+                               0x81000000 0x2 0       MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1 IO  */>;
+
+                       pcie@1,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+                               reg = <0x0800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+                                         0x81000000 0 0 0x81000000 0x1 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <0>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 5>;
+                               status = "disabled";
+                       };
+
+                       pcie@2,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+                                         0x81000000 0 0 0x81000000 0x2 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <0>;
+                               marvell,pcie-lane = <1>;
+                               clocks = <&gateclk 6>;
+                               status = "disabled";
+                       };
+
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
new file mode 100644 (file)
index 0000000..068031f
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Device Tree Include file for Marvell Armada 380 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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 "armada-38x.dtsi"
+
+/ {
+       model = "Marvell Armada 380 family SoC";
+       compatible = "marvell,armada380", "marvell,armada38x";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+               };
+       };
+
+       soc {
+               internal-regs {
+                       pinctrl {
+                               compatible = "marvell,mv88f6810-pinctrl";
+                               reg = <0x18000 0x20>;
+                       };
+               };
+
+               pcie-controller {
+                       compatible = "marvell,armada-370-pcie";
+                       status = "disabled";
+                       device_type = "pci";
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       msi-parent = <&mpic>;
+                       bus-range = <0x00 0xff>;
+
+                       ranges =
+                              <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+                               0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+                               0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+                               0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
+                               0x82000000 0x1 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
+                               0x81000000 0x1 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO  */
+                               0x82000000 0x2 0     MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
+                               0x81000000 0x2 0     MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO  */
+                               0x82000000 0x3 0     MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
+                               0x81000000 0x3 0     MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO  */>;
+
+                       /* x1 port */
+                       pcie@1,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+                               reg = <0x0800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+                                         0x81000000 0 0 0x81000000 0x1 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <0>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 8>;
+                               status = "disabled";
+                       };
+
+                       /* x1 port */
+                       pcie@2,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+                                         0x81000000 0 0 0x81000000 0x2 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <1>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 5>;
+                               status = "disabled";
+                       };
+
+                       /* x1 port */
+                       pcie@3,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+                                         0x81000000 0 0 0x81000000 0x3 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <2>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 6>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/armada-385-db.dts b/arch/arm/boot/dts/armada-385-db.dts
new file mode 100644 (file)
index 0000000..6828d77
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Device Tree file for Marvell Armada 385 evaluation board
+ * (DB-88F6820)
+ *
+ *  Copyright (C) 2014 Marvell
+ *
+ * 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.
+ */
+
+/dts-v1/;
+#include "armada-385.dtsi"
+
+/ {
+       model = "Marvell Armada 385 Development Board";
+       compatible = "marvell,a385-db", "marvell,armada385", "marvell,armada38x";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>; /* 256 MB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+               internal-regs {
+                       spi@10600 {
+                               status = "okay";
+
+                               spi-flash@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       compatible = "w25q32";
+                                       reg = <0>; /* Chip select 0 */
+                                       spi-max-frequency = <108000000>;
+                               };
+                       };
+
+                       i2c@11000 {
+                               status = "okay";
+                               clock-frequency = <100000>;
+                       };
+
+                       i2c@11100 {
+                               status = "okay";
+                               clock-frequency = <100000>;
+                       };
+
+                       serial@12000 {
+                               clock-frequency = <200000000>;
+                               status = "okay";
+                       };
+
+                       ethernet@30000 {
+                               status = "okay";
+                               phy = <&phy1>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       ethernet@70000 {
+                               status = "okay";
+                               phy = <&phy0>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       mdio {
+                               phy0: ethernet-phy@0 {
+                                       reg = <0>;
+                               };
+
+                               phy1: ethernet-phy@1 {
+                                       reg = <1>;
+                               };
+                       };
+
+                       flash@d0000 {
+                               status = "okay";
+                               num-cs = <1>;
+                               marvell,nand-keep-config;
+                               marvell,nand-enable-arbiter;
+                               nand-on-flash-bbt;
+
+                               partition@0 {
+                                       label = "U-Boot";
+                                       reg = <0 0x800000>;
+                               };
+                               partition@800000 {
+                                       label = "Linux";
+                                       reg = <0x800000 0x800000>;
+                               };
+                               partition@1000000 {
+                                       label = "Filesystem";
+                                       reg = <0x1000000 0x3f000000>;
+                               };
+                       };
+               };
+
+               pcie-controller {
+                       status = "okay";
+                       /*
+                        * The two PCIe units are accessible through
+                        * standard PCIe slots on the board.
+                        */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+                       pcie@2,0 {
+                               /* Port 1, Lane 0 */
+                               status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/armada-385-rd.dts b/arch/arm/boot/dts/armada-385-rd.dts
new file mode 100644 (file)
index 0000000..45250c8
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Device Tree file for Marvell Armada 385 Reference Design board
+ * (RD-88F6820-AP)
+ *
+ *  Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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.
+ */
+
+/dts-v1/;
+#include "armada-385.dtsi"
+
+/ {
+       model = "Marvell Armada 385 Reference Design";
+       compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada38x";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 earlyprintk";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>; /* 256 MB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+               internal-regs {
+                       spi@10600 {
+                               status = "okay";
+
+                               spi-flash@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       compatible = "st,m25p128";
+                                       reg = <0>; /* Chip select 0 */
+                                       spi-max-frequency = <108000000>;
+                               };
+                       };
+
+                       i2c@11000 {
+                               status = "okay";
+                               clock-frequency = <100000>;
+                       };
+
+                       serial@12000 {
+                               clock-frequency = <200000000>;
+                               status = "okay";
+                       };
+
+                       ethernet@30000 {
+                               status = "okay";
+                               phy = <&phy0>;
+                               phy-mode = "rgmii-id";
+                       };
+
+                       ethernet@70000 {
+                               status = "okay";
+                               phy = <&phy1>;
+                               phy-mode = "rgmii-id";
+                       };
+
+
+                       mdio {
+                               phy0: ethernet-phy@0 {
+                                       reg = <0>;
+                               };
+
+                               phy1: ethernet-phy@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               pcie-controller {
+                       status = "okay";
+                       /*
+                        * One PCIe units is accessible through
+                        * standard PCIe slot on the board.
+                        */
+                       pcie@1,0 {
+                               /* Port 0, Lane 0 */
+                               status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
new file mode 100644 (file)
index 0000000..e2919f0
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Device Tree Include file for Marvell Armada 385 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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 "armada-38x.dtsi"
+
+/ {
+       model = "Marvell Armada 385 family SoC";
+       compatible = "marvell,armada385", "marvell,armada38x";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <1>;
+               };
+       };
+
+       soc {
+               internal-regs {
+                       pinctrl {
+                               compatible = "marvell,mv88f6820-pinctrl";
+                               reg = <0x18000 0x20>;
+                       };
+               };
+
+               pcie-controller {
+                       compatible = "marvell,armada-370-pcie";
+                       status = "disabled";
+                       device_type = "pci";
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       msi-parent = <&mpic>;
+                       bus-range = <0x00 0xff>;
+
+                       ranges =
+                              <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+                               0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+                               0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+                               0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
+                               0x82000000 0x1 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
+                               0x81000000 0x1 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO  */
+                               0x82000000 0x2 0     MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
+                               0x81000000 0x2 0     MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO  */
+                               0x82000000 0x3 0     MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
+                               0x81000000 0x3 0     MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO  */
+                               0x82000000 0x4 0     MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 3 MEM */
+                               0x81000000 0x4 0     MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 3 IO  */>;
+
+                       /*
+                        * This port can be either x4 or x1. When
+                        * configured in x4 by the bootloader, then
+                        * pcie@4,0 is not available.
+                        */
+                       pcie@1,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
+                               reg = <0x0800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+                                         0x81000000 0 0 0x81000000 0x1 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <0>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 8>;
+                               status = "disabled";
+                       };
+
+                       /* x1 port */
+                       pcie@2,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+                                         0x81000000 0 0 0x81000000 0x2 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <1>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 5>;
+                               status = "disabled";
+                       };
+
+                       /* x1 port */
+                       pcie@3,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+                                         0x81000000 0 0 0x81000000 0x3 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <2>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 6>;
+                               status = "disabled";
+                       };
+
+                       /*
+                        * x1 port only available when pcie@1,0 is
+                        * configured as a x1 port
+                        */
+                       pcie@4,0 {
+                               device_type = "pci";
+                               assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
+                               reg = <0x1000 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+                                         0x81000000 0 0 0x81000000 0x4 0 1 0>;
+                               interrupt-map-mask = <0 0 0 0>;
+                               interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               marvell,pcie-port = <3>;
+                               marvell,pcie-lane = <0>;
+                               clocks = <&gateclk 7>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
new file mode 100644 (file)
index 0000000..a064f59
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * Device Tree Include file for Marvell Armada 38x family of SoCs.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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 "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+/ {
+       model = "Marvell Armada 38x family SoC";
+       compatible = "marvell,armada38x";
+
+       aliases {
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               eth0 = &eth0;
+               eth1 = &eth1;
+               eth2 = &eth2;
+       };
+
+       soc {
+               compatible = "marvell,armada380-mbus", "marvell,armada370-mbus",
+                            "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               controller = <&mbusc>;
+               interrupt-parent = <&gic>;
+               pcie-mem-aperture = <0xe0000000 0x8000000>;
+               pcie-io-aperture  = <0xe8000000 0x100000>;
+
+               bootrom {
+                       compatible = "marvell,bootrom";
+                       reg = <MBUS_ID(0x01, 0x1d) 0 0x200000>;
+               };
+
+               devbus-bootcs {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs0 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs1 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs2 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               devbus-cs3 {
+                       compatible = "marvell,mvebu-devbus";
+                       reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+                       ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&coreclk 0>;
+                       status = "disabled";
+               };
+
+               internal-regs {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+                       L2: cache-controller@8000 {
+                               compatible = "arm,pl310-cache";
+                               reg = <0x8000 0x1000>;
+                               cache-unified;
+                               cache-level = <2>;
+                       };
+
+                       timer@c600 {
+                               compatible = "arm,cortex-a9-twd-timer";
+                               reg = <0xc600 0x20>;
+                               interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>;
+                               clocks = <&coreclk 2>;
+                       };
+
+                       gic: interrupt-controller@d000 {
+                               compatible = "arm,cortex-a9-gic";
+                               #interrupt-cells = <3>;
+                               #size-cells = <0>;
+                               interrupt-controller;
+                               reg = <0xd000 0x1000>,
+                                     <0xc100 0x100>;
+                       };
+
+                       spi0: spi@10600 {
+                               compatible = "marvell,orion-spi";
+                               reg = <0x10600 0x50>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <0>;
+                               interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       spi1: spi@10680 {
+                               compatible = "marvell,orion-spi";
+                               reg = <0x10680 0x50>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <1>;
+                               interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@11000 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               reg = <0x11000 0x20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                               timeout-ms = <1000>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@11100 {
+                               compatible = "marvell,mv64xxx-i2c";
+                               reg = <0x11100 0x20>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                               timeout-ms = <1000>;
+                               clocks = <&coreclk 0>;
+                               status = "disabled";
+                       };
+
+                       serial@12000 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0x12000 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-io-width = <1>;
+                               status = "disabled";
+                       };
+
+                       serial@12100 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0x12100 0x100>;
+                               reg-shift = <2>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-io-width = <1>;
+                               status = "disabled";
+                       };
+
+                       pinctrl {
+                               compatible = "marvell,mv88f6820-pinctrl";
+                               reg = <0x18000 0x20>;
+                       };
+
+                       gpio0: gpio@18100 {
+                               compatible = "marvell,orion-gpio";
+                               reg = <0x18100 0x40>;
+                               ngpios = <32>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               interrupts = <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>;
+                       };
+
+                       gpio1: gpio@18140 {
+                               compatible = "marvell,orion-gpio";
+                               reg = <0x18140 0x40>;
+                               ngpios = <28>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               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>;
+                       };
+
+                       system-controller@18200 {
+                               compatible = "marvell,armada-380-system-controller",
+                                            "marvell,armada-370-xp-system-controller";
+                               reg = <0x18200 0x100>;
+                       };
+
+                       gateclk: clock-gating-control@18220 {
+                               compatible = "marvell,armada-380-gating-clock";
+                               reg = <0x18220 0x4>;
+                               clocks = <&coreclk 0>;
+                               #clock-cells = <1>;
+                       };
+
+                       coreclk: mvebu-sar@18600 {
+                               compatible = "marvell,armada-380-core-clock";
+                               reg = <0x18600 0x04>;
+                               #clock-cells = <1>;
+                       };
+
+                       mbusc: mbus-controller@20000 {
+                               compatible = "marvell,mbus-controller";
+                               reg = <0x20000 0x100>, <0x20180 0x20>;
+                       };
+
+                       mpic: interrupt-controller@20000 {
+                               compatible = "marvell,mpic";
+                               reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+                               #interrupt-cells = <1>;
+                               #size-cells = <1>;
+                               interrupt-controller;
+                               msi-controller;
+                               interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       timer@20300 {
+                               compatible = "marvell,armada-380-timer",
+                                            "marvell,armada-xp-timer";
+                               reg = <0x20300 0x30>, <0x21040 0x30>;
+                               interrupts-extended = <&gic  GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&gic  GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&gic  GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&gic  GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                                                     <&mpic 5>,
+                                                     <&mpic 6>;
+                               clocks = <&coreclk 2>, <&refclk>;
+                               clock-names = "nbclk", "fixed";
+                       };
+
+                       eth1: ethernet@30000 {
+                               compatible = "marvell,armada-370-neta";
+                               reg = <0x30000 0x4000>;
+                               interrupts-extended = <&mpic 10>;
+                               clocks = <&gateclk 3>;
+                               status = "disabled";
+                       };
+
+                       eth2: ethernet@34000 {
+                               compatible = "marvell,armada-370-neta";
+                               reg = <0x34000 0x4000>;
+                               interrupts-extended = <&mpic 12>;
+                               clocks = <&gateclk 2>;
+                               status = "disabled";
+                       };
+
+                       xor@60800 {
+                               compatible = "marvell,orion-xor";
+                               reg = <0x60800 0x100
+                                      0x60a00 0x100>;
+                               clocks = <&gateclk 22>;
+                               status = "okay";
+
+                               xor00 {
+                                       interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+                               xor01 {
+                                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                                       dmacap,memset;
+                               };
+                       };
+
+                       xor@60900 {
+                               compatible = "marvell,orion-xor";
+                               reg = <0x60900 0x100
+                                      0x60b00 0x100>;
+                               clocks = <&gateclk 28>;
+                               status = "okay";
+
+                               xor10 {
+                                       interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                               };
+                               xor11 {
+                                       interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmacap,memcpy;
+                                       dmacap,xor;
+                                       dmacap,memset;
+                               };
+                       };
+
+                       eth0: ethernet@70000 {
+                               compatible = "marvell,armada-370-neta";
+                               reg = <0x70000 0x4000>;
+                               interrupts-extended = <&mpic 8>;
+                               clocks = <&gateclk 4>;
+                               status = "disabled";
+                       };
+
+                       mdio {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "marvell,orion-mdio";
+                               reg = <0x72004 0x4>;
+                       };
+
+                       coredivclk: clock@e4250 {
+                               compatible = "marvell,armada-380-corediv-clock";
+                               reg = <0xe4250 0xc>;
+                               #clock-cells = <1>;
+                               clocks = <&mainpll>;
+                               clock-output-names = "nand";
+                       };
+
+                       flash@d0000 {
+                               compatible = "marvell,armada370-nand";
+                               reg = <0xd0000 0x54>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&coredivclk 0>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       clocks {
+               /* 2 GHz fixed main PLL */
+               mainpll: mainpll {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <2000000000>;
+               };
+
+               /* 25 MHz reference crystal */
+               refclk: oscillator {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <25000000>;
+               };
+       };
+};
index c5fe57269f5aca5c28f61de250dd5663298ec27e..d83d7d69ac01ff7f33c33677ff16bf7d906d5f1c 100644 (file)
@@ -16,6 +16,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include "armada-xp-mv78230.dtsi"
 
 / {
 
                button@1 {
                        label = "Factory Reset Button";
-                       linux,code = <141>; /* KEY_SETUP */
-                       gpios = <&gpio1 1 1>;
+                       linux,code = <KEY_SETUP>;
+                       gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
                };
        };
 };
index bcf6d79a57ec55febf5f037affdee94e901f3628..448373c4b0e534c1d2ce08592981f5d38bad39a8 100644 (file)
@@ -2,7 +2,7 @@
  * Device Tree file for Marvell Armada XP evaluation board
  * (DB-78460-BP)
  *
- * Copyright (C) 2012 Marvell
+ * Copyright (C) 2012-2014 Marvell
  *
  * Lior Amsalem <alior@marvell.com>
  * 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.
+  *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
  */
 
 /dts-v1/;
@@ -30,7 +39,7 @@
        };
 
        soc {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
                          MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
                          MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
 
index 274e2ad5f51c67114b99786c0c4356971cdec492..61bda687f782f65485f958adb8d8ec2822ebde35 100644 (file)
@@ -2,7 +2,7 @@
  * Device Tree file for Marvell Armada XP development board
  * (DB-MV784MP-GP)
  *
- * Copyright (C) 2013 Marvell
+ * Copyright (C) 2013-2014 Marvell
  *
  * Lior Amsalem <alior@marvell.com>
  * 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.
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
  */
 
 /dts-v1/;
                  * 8 GB of plug-in RAM modules by default.The amount
                  * of memory available can be changed by the
                  * bootloader according the size of the module
-                 * actually plugged. Only 7GB are usable because
-                 * addresses from 0xC0000000 to 0xffffffff are used by
-                 * the internal registers of the SoC.
+                 * actually plugged. However, memory between
+                 * 0xF0000000 to 0xFFFFFFFF cannot be used, as it is
+                 * the address range used for I/O (internal registers,
+                 * MBus windows).
                 */
-               reg = <0x00000000 0x00000000 0x00000000 0xC0000000>,
+               reg = <0x00000000 0x00000000 0x00000000 0xf0000000>,
                      <0x00000001 0x00000000 0x00000001 0x00000000>;
        };
 
        soc {
-               ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
                          MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
                          MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
 
index e47c49ecd55c0cd475e547d1690deeaabcd679af..c2242745b9b87a29afcfcc2fc77bf9178d5814f9 100644 (file)
 
        memory {
                device_type = "memory";
-               reg = <0 0x00000000 0 0x80000000>; /* 2 GB */
+               /*
+                * This board has 4 GB of RAM, but the last 256 MB of
+                * RAM are not usable due to the overlap with the MBus
+                * Window address range
+                */
+               reg = <0 0x00000000 0 0xf0000000>;
        };
 
        soc {
index 99bcf76e6953d3e0af3e72fe6372cdecdfbecb1f..985948ce67b3271a65c9b4a413a99e7d255b12e7 100644 (file)
@@ -11,6 +11,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include "armada-xp-mv78260.dtsi"
 
 / {
 
                                red_led {
                                        label = "red_led";
-                                       gpios = <&gpio1 17 1>;
+                                       gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
                                        default-state = "off";
                                };
 
                                yellow_led {
                                        label = "yellow_led";
-                                       gpios = <&gpio1 19 1>;
+                                       gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
                                        default-state = "off";
                                };
 
                                green_led {
                                        label = "green_led";
-                                       gpios = <&gpio1 21 1>;
+                                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
                                        default-state = "keep";
                                };
                        };
 
                                button@1 {
                                        label = "Init Button";
-                                       linux,code = <116>;
-                                       gpios = <&gpio1 28 0>;
+                                       linux,code = <KEY_POWER>;
+                                       gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
                                };
                        };
 
index b8b84a22f0f3971b7013862821ecb0e2cfc237aa..abb9f9dcc525a6a7c1583e5f1f7c65d4ff29e485 100644 (file)
                                clock-names = "nbclk", "fixed";
                        };
 
+                       watchdog@20300 {
+                               compatible = "marvell,armada-xp-wdt";
+                               clocks = <&coreclk 2>, <&refclk>;
+                               clock-names = "nbclk", "fixed";
+                       };
+
                        armada-370-xp-pmsu@22000 {
                                compatible = "marvell,armada-370-xp-pmsu";
                                reg = <0x22100 0x400>, <0x20800 0x20>;
index cce45f5177f9f0aef6b40e0e775617f47398c48e..55ab6180e350d10e9c4f816095eba4910a37cbce 100644 (file)
                        adc0: adc@f804c000 {
                                status = "okay";
                                atmel,adc-channels-used = <0xf>;
-                               atmel,adc-num-channels = <4>;
                        };
 
                        dbgu: serial@fffff200 {
index 2093c4d7cd6a7ea0d35fcb36f49c100fdaa27390..df4b7869569587991abcf5bde8be1e495f632213 100644 (file)
@@ -64,7 +64,6 @@
                        };
 
                        adc0: adc@f804c000 {
-                               atmel,adc-clock-rate = <1000000>;
                                atmel,adc-ts-wires = <4>;
                                atmel,adc-ts-pressure-threshold = <10000>;
                                status = "okay";
index f9415dd11f1759f892d47a54debab2630c192214..a542d5837a17be14c1f82547c59529d4a59f5ce7 100644 (file)
@@ -27,7 +27,6 @@
                        };
 
                        adc0: adc@f804c000 {
-                               atmel,adc-clock-rate = <1000000>;
                                atmel,adc-ts-wires = <4>;
                                atmel,adc-ts-pressure-threshold = <10000>;
                                status = "okay";
index 997901f7ed7381c77ff6c669f4f7571474ebd4b2..366fc2cbcd64c3f56495d104e5a744315c7c4345 100644 (file)
                        };
 
                        adc0: adc@fffe0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                compatible = "atmel,at91sam9260-adc";
                                reg = <0xfffe0000 0x100>;
                                interrupts = <5 IRQ_TYPE_LEVEL_HIGH 0>;
                                atmel,adc-use-external-triggers;
                                atmel,adc-channels-used = <0xf>;
                                atmel,adc-vref = <3300>;
-                               atmel,adc-num-channels = <4>;
                                atmel,adc-startup-time = <15>;
-                               atmel,adc-channel-base = <0x30>;
-                               atmel,adc-drdy-mask = <0x10000>;
-                               atmel,adc-status-register = <0x1c>;
-                               atmel,adc-trigger-register = <0x04>;
                                atmel,adc-res = <8 10>;
                                atmel,adc-res-names = "lowres", "highres";
                                atmel,adc-use-res = "highres";
 
                                trigger@0 {
+                                       reg = <0>;
                                        trigger-name = "timer-counter-0";
                                        trigger-value = <0x1>;
                                };
                                trigger@1 {
+                                       reg = <1>;
                                        trigger-name = "timer-counter-1";
                                        trigger-value = <0x3>;
                                };
 
                                trigger@2 {
+                                       reg = <2>;
                                        trigger-name = "timer-counter-2";
                                        trigger-value = <0x5>;
                                };
 
                                trigger@3 {
+                                       reg = <3>;
                                        trigger-name = "external";
                                        trigger-value = <0x13>;
                                        trigger-external;
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
new file mode 100644 (file)
index 0000000..e21dda0
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ * at91sam9261.dtsi - Device Tree Include file for AT91SAM9261 SoC
+ *
+ *  Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/at91.h>
+
+/ {
+       model = "Atmel AT91SAM9261 family SoC";
+       compatible = "atmel,at91sam9261";
+       interrupt-parent = <&aic>;
+
+       aliases {
+               serial0 = &dbgu;
+               serial1 = &usart0;
+               serial2 = &usart1;
+               serial3 = &usart2;
+               gpio0 = &pioA;
+               gpio1 = &pioB;
+               gpio2 = &pioC;
+               tcb0 = &tcb0;
+               i2c0 = &i2c0;
+               ssc0 = &ssc0;
+               ssc1 = &ssc1;
+       };
+
+       cpus {
+               #address-cells = <0>;
+               #size-cells = <0>;
+
+               cpu {
+                       compatible = "arm,arm926ej-s";
+                       device_type = "cpu";
+               };
+       };
+
+       memory {
+               reg = <0x20000000 0x08000000>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               usb0: ohci@00500000 {
+                       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+                       reg = <0x00500000 0x100000>;
+                       interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>;
+                       clocks = <&usb>, <&ohci_clk>, <&hclk0>, <&uhpck>;
+                       clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
+                       status = "disabled";
+               };
+
+               fb0: fb@0x00600000 {
+                       compatible = "atmel,at91sam9261-lcdc";
+                       reg = <0x00600000 0x1000>;
+                       interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_fb>;
+                       clocks = <&lcd_clk>, <&hclk1>;
+                       clock-names = "lcdc_clk", "hclk";
+                       status = "disabled";
+               };
+
+               nand0: nand@40000000 {
+                       compatible = "atmel,at91rm9200-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x40000000 0x10000000>;
+                       atmel,nand-addr-offset = <22>;
+                       atmel,nand-cmd-offset = <21>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_nand>;
+
+                       gpios = <&pioC 15 GPIO_ACTIVE_HIGH>,
+                               <&pioC 14 GPIO_ACTIVE_HIGH>,
+                               <0>;
+                       status = "disabled";
+               };
+
+               apb {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       tcb0: timer@fffa0000 {
+                               compatible = "atmel,at91rm9200-tcb";
+                               reg = <0xfffa0000 0x100>;
+                               interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>,
+                                            <18 IRQ_TYPE_LEVEL_HIGH 0>,
+                                            <19 IRQ_TYPE_LEVEL_HIGH 0>;
+                               clocks = <&tc0_clk>, <&tc1_clk>, <&tc2_clk>;
+                               clock-names = "t0_clk", "t1_clk", "t2_clk";
+                       };
+
+                       usb1: gadget@fffa4000 {
+                               compatible = "atmel,at91rm9200-udc";
+                               reg = <0xfffa4000 0x4000>;
+                               interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
+                               clocks = <&usb>, <&udc_clk>, <&udpck>;
+                               clock-names = "usb_clk", "udc_clk", "udpck";
+                               status = "disabled";
+                       };
+
+                       mmc0: mmc@fffa8000 {
+                               compatible = "atmel,hsmci";
+                               reg = <0xfffa8000 0x600>;
+                               interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_mmc0_clk>, <&pinctrl_mmc0_slot0_cmd_dat0>, <&pinctrl_mmc0_slot0_dat1_3>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&mci0_clk>;
+                               clock-names = "mci_clk";
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@fffac000 {
+                               compatible = "atmel,at91sam9261-i2c";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_i2c_twi>;
+                               reg = <0xfffac000 0x100>;
+                               interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&twi0_clk>;
+                               status = "disabled";
+                       };
+
+                       usart0: serial@fffb0000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffb0000 0x200>;
+                               interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart0>;
+                               clocks = <&usart0_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       usart1: serial@fffb4000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffb4000 0x200>;
+                               interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart1>;
+                               clocks = <&usart1_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       usart2: serial@fffb8000{
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffb8000 0x200>;
+                               interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart2>;
+                               clocks = <&usart2_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       ssc0: ssc@fffbc000 {
+                               compatible = "atmel,at91rm9200-ssc";
+                               reg = <0xfffbc000 0x4000>;
+                               interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+                               status = "disabled";
+                       };
+
+                       ssc1: ssc@fffc0000 {
+                               compatible = "atmel,at91rm9200-ssc";
+                               reg = <0xfffc0000 0x4000>;
+                               interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+                               status = "disabled";
+                       };
+
+                       spi0: spi@fffc8000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "atmel,at91rm9200-spi";
+                               reg = <0xfffc8000 0x200>;
+                               cs-gpios = <0>, <0>, <0>, <0>;
+                               interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_spi0>;
+                               clocks = <&spi0_clk>;
+                               clock-names = "spi_clk";
+                               status = "disabled";
+                       };
+
+                       spi1: spi@fffcc000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "atmel,at91rm9200-spi";
+                               reg = <0xfffcc000 0x200>;
+                               interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_spi1>;
+                               clocks = <&spi1_clk>;
+                               clock-names = "spi_clk";
+                               status = "disabled";
+                       };
+
+                       ramc: ramc@ffffea00 {
+                               compatible = "atmel,at91sam9260-sdramc";
+                               reg = <0xffffea00 0x200>;
+                       };
+
+                       matrix: matrix@ffffee00 {
+                               compatible = "atmel,at91sam9260-bus-matrix";
+                               reg = <0xffffee00 0x200>;
+                       };
+
+                       aic: interrupt-controller@fffff000 {
+                               #interrupt-cells = <3>;
+                               compatible = "atmel,at91rm9200-aic";
+                               interrupt-controller;
+                               reg = <0xfffff000 0x200>;
+                               atmel,external-irqs = <29 30 31>;
+                       };
+
+                       dbgu: serial@fffff200 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffff200 0x200>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_dbgu>;
+                               clocks = <&mck>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       pinctrl@fffff400 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+                               ranges = <0xfffff400 0xfffff400 0x600>;
+
+                               atmel,mux-mask =
+                                     /*    A         B     */
+                                     <0xffffffff 0xfffffff7>,  /* pioA */
+                                     <0xffffffff 0xfffffff4>,  /* pioB */
+                                     <0xffffffff 0xffffff07>;  /* pioC */
+
+                               /* shared pinctrl settings */
+                               dbgu {
+                                       pinctrl_dbgu: dbgu-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 9  AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+                                       };
+                               };
+
+                               usart0 {
+                                       pinctrl_usart0: usart0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_rts: usart0_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_cts: usart0_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               usart1 {
+                                       pinctrl_usart1: usart1-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart1_rts: usart1_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart1_cts: usart1_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               usart2 {
+                                       pinctrl_usart2: usart2-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart2_rts: usart2_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart2_cts: usart2_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               nand {
+                                       pinctrl_nand: nand-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOC 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+                                       };
+                               };
+
+                               mmc0 {
+                                       pinctrl_mmc0_clk: mmc0_clk-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
+                                       };
+
+                                       pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
+                                       };
+                                       };
+
+                               ssc0 {
+                                       pinctrl_ssc0_tx: ssc0_tx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_ssc0_rx: ssc0_rx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               ssc1 {
+                                       pinctrl_ssc1_tx: ssc1_tx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 17 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_ssc1_rx: ssc1_rx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               spi0 {
+                                       pinctrl_spi0: spi0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                                       };
+
+                               spi1 {
+                                       pinctrl_spi1: spi1-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               tcb0 {
+                                       pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+                                               atmel,pins = <AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+                                               atmel,pins = <AT91_PIOC 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+                                               atmel,pins = <AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+                                               atmel,pins = <AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+                                               atmel,pins = <AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+                                               atmel,pins = <AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+                                               atmel,pins = <AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+                                               atmel,pins = <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+                                               atmel,pins = <AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               i2c0 {
+                                       pinctrl_i2c_bitbang: i2c-0-bitbang {
+                                               atmel,pins =
+                                                       <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 8 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+                                       };
+                                       pinctrl_i2c_twi: i2c-0-twi {
+                                               atmel,pins =
+                                                       <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               fb {
+                                       pinctrl_fb: fb-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               pioA: gpio@fffff400 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff400 0x200>;
+                                       interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioA_clk>;
+                               };
+
+                               pioB: gpio@fffff600 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff600 0x200>;
+                                       interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioB_clk>;
+                               };
+
+                               pioC: gpio@fffff800 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff800 0x200>;
+                                       interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioC_clk>;
+                               };
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               compatible = "atmel,at91rm9200-pmc";
+                               reg = <0xfffffc00 0x100>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               interrupt-controller;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               #interrupt-cells = <1>;
+
+                               clk32k: slck {
+                                       compatible = "fixed-clock";
+                                       #clock-cells = <0>;
+                                       clock-frequency = <32768>;
+                               };
+
+                               main: mainck {
+                                       compatible = "atmel,at91rm9200-clk-main";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+                                       clocks = <&clk32k>;
+                               };
+
+                               plla: pllack {
+                                       compatible = "atmel,at91rm9200-clk-pll";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+                                       clocks = <&main>;
+                                       reg = <0>;
+                                       atmel,clk-input-range = <1000000 32000000>;
+                                       #atmel,pll-clk-output-range-cells = <4>;
+                                       atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
+                               };
+
+                               pllb: pllbck {
+                                       compatible = "atmel,at91rm9200-clk-pll";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_LOCKB>;
+                                       clocks = <&main>;
+                                       reg = <1>;
+                                       atmel,clk-input-range = <1000000 32000000>;
+                                       #atmel,pll-clk-output-range-cells = <4>;
+                                       atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
+                               };
+
+                               mck: masterck {
+                                       compatible = "atmel,at91rm9200-clk-master";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+                                       clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
+                                       atmel,clk-output-range = <0 94000000>;
+                                       atmel,clk-divisors = <1 2 4 3>;
+                               };
+
+                               usb: usbck {
+                                       compatible = "atmel,at91rm9200-clk-usb";
+                                       #clock-cells = <0>;
+                                       atmel,clk-divisors = <1 2 4 3>;
+                                       clocks = <&pllb>;
+                               };
+
+                               systemck {
+                                       compatible = "atmel,at91rm9200-clk-system";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       uhpck: uhpck {
+                                               #clock-cells = <0>;
+                                               reg = <6>;
+                                               clocks = <&usb>;
+                                       };
+
+                                       udpck: udpck {
+                                               #clock-cells = <0>;
+                                               reg = <7>;
+                                               clocks = <&usb>;
+                                       };
+
+                                       hclk0: hclk0 {
+                                               #clock-cells = <0>;
+                                               reg = <16>;
+                                               clocks = <&mck>;
+                                       };
+
+                                       hclk1: hclk1 {
+                                               #clock-cells = <0>;
+                                               reg = <17>;
+                                               clocks = <&mck>;
+                                       };
+                               };
+
+                               periphck {
+                                       compatible = "atmel,at91rm9200-clk-peripheral";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       clocks = <&mck>;
+
+                                       pioA_clk: pioA_clk {
+                                               #clock-cells = <0>;
+                                               reg = <2>;
+                                       };
+
+                                       pioB_clk: pioB_clk {
+                                               #clock-cells = <0>;
+                                               reg = <3>;
+                                       };
+
+                                       pioC_clk: pioC_clk {
+                                               #clock-cells = <0>;
+                                               reg = <4>;
+                                       };
+
+                                       usart0_clk: usart0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <6>;
+                                       };
+
+                                       usart1_clk: usart1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <7>;
+                                       };
+
+                                       usart2_clk: usart2_clk {
+                                               #clock-cells = <0>;
+                                               reg = <8>;
+                                       };
+
+                                       mci0_clk: mci0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <9>;
+                                       };
+
+                                       udc_clk: udc_clk {
+                                               #clock-cells = <0>;
+                                               reg = <10>;
+                                       };
+
+                                       twi0_clk: twi0_clk {
+                                               reg = <11>;
+                                               #clock-cells = <0>;
+                                       };
+
+                                       spi0_clk: spi0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <12>;
+                                       };
+
+                                       spi1_clk: spi1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <13>;
+                                       };
+
+                                       tc0_clk: tc0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <17>;
+                                       };
+
+                                       tc1_clk: tc1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <18>;
+                                       };
+
+                                       tc2_clk: tc2_clk {
+                                               #clock-cells = <0>;
+                                               reg = <19>;
+                                       };
+
+                                       ohci_clk: ohci_clk {
+                                               #clock-cells = <0>;
+                                               reg = <20>;
+                                       };
+
+                                       lcd_clk: lcd_clk {
+                                               #clock-cells = <0>;
+                                               reg = <21>;
+                                       };
+                               };
+                       };
+
+                       rstc@fffffd00 {
+                               compatible = "atmel,at91sam9260-rstc";
+                               reg = <0xfffffd00 0x10>;
+                       };
+
+                       shdwc@fffffd10 {
+                               compatible = "atmel,at91sam9260-shdwc";
+                               reg = <0xfffffd10 0x10>;
+                       };
+
+                       pit: timer@fffffd30 {
+                               compatible = "atmel,at91sam9260-pit";
+                               reg = <0xfffffd30 0xf>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               clocks = <&mck>;
+                       };
+
+                       watchdog@fffffd40 {
+                               compatible = "atmel,at91sam9260-wdt";
+                               reg = <0xfffffd40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       i2c@0 {
+               compatible = "i2c-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c_bitbang>;
+               gpios = <&pioA 7 GPIO_ACTIVE_HIGH>, /* sda */
+                       <&pioA 8 GPIO_ACTIVE_HIGH>; /* scl */
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+};
diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts
new file mode 100644 (file)
index 0000000..2ce527e
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * at91sam9261ek.dts - Device Tree file for Atmel at91sam9261 reference board
+ *
+ *  Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+/dts-v1/;
+#include "at91sam9261.dtsi"
+
+/ {
+       model = "Atmel at91sam9261ek";
+       compatible = "atmel,at91sam9261ek", "atmel,at91sam9261", "atmel,at91sam9";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 rootfstype=ubifs ubi.mtd=5 root=ubi0:rootfs rw";
+       };
+
+       memory {
+               reg = <0x20000000 0x4000000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               main_clock: clock@0 {
+                       compatible = "atmel,osc", "fixed-clock";
+                       clock-frequency = <18432000>;
+               };
+       };
+
+       ahb {
+               usb0: ohci@00500000 {
+                       status = "okay";
+               };
+
+               fb0: fb@0x00600000 {
+                       display = <&display0>;
+                       atmel,power-control-gpio = <&pioA 12 GPIO_ACTIVE_LOW>;
+                       status = "okay";
+
+                       display0: display {
+                               bits-per-pixel = <16>;
+                               atmel,lcdcon-backlight;
+                               atmel,dmacon = <0x1>;
+                               atmel,lcdcon2 = <0x80008002>;
+                               atmel,guard-time = <1>;
+                               atmel,lcd-wiring-mode = "BRG";
+
+                               display-timings {
+                                       native-mode = <&timing0>;
+                                       timing0: timing0 {
+                                               clock-frequency = <4965000>;
+                                               hactive = <240>;
+                                               vactive = <320>;
+                                               hback-porch = <1>;
+                                               hfront-porch = <33>;
+                                               vback-porch = <1>;
+                                               vfront-porch = <0>;
+                                               hsync-len = <5>;
+                                               vsync-len = <1>;
+                                               hsync-active = <1>;
+                                               vsync-active = <1>;
+                                       };
+                               };
+                       };
+               };
+
+               nand0: nand@40000000 {
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "soft";
+                       nand-on-flash-bbt;
+                       status = "okay";
+
+                       at91bootstrap@0 {
+                               label = "at91bootstrap";
+                               reg = <0x0 0x40000>;
+                       };
+
+                       bootloader@40000 {
+                               label = "bootloader";
+                               reg = <0x40000 0x80000>;
+                       };
+
+                       bootloaderenv@c0000 {
+                               label = "bootloader env";
+                               reg = <0xc0000 0xc0000>;
+                       };
+
+                       dtb@180000 {
+                               label = "device tree";
+                               reg = <0x180000 0x80000>;
+                       };
+
+                       kernel@200000 {
+                               label = "kernel";
+                               reg = <0x200000 0x600000>;
+                       };
+
+                       rootfs@800000 {
+                               label = "rootfs";
+                               reg = <0x800000 0x0f800000>;
+                       };
+               };
+
+               apb {
+                       usb1: gadget@fffa4000 {
+                               atmel,vbus-gpio = <&pioB 29 GPIO_ACTIVE_HIGH>;
+                               status = "okay";
+                       };
+
+                       spi0: spi@fffc8000 {
+                               cs-gpios = <&pioA 3 0>, <0>, <&pioA 28 0>, <0>;
+                               status = "okay";
+
+                               mtd_dataflash@0 {
+                                       compatible = "atmel,at45", "atmel,dataflash";
+                                       reg = <0>;
+                                       spi-max-frequency = <15000000>;
+                               };
+
+                               tsc2046@0 {
+                                       reg = <2>;
+                                       compatible = "ti,ads7843";
+                                       interrupts-extended = <&pioC 2 IRQ_TYPE_EDGE_BOTH>;
+                                       spi-max-frequency = <3000000>;
+                                       pendown-gpio = <&pioC 2 GPIO_ACTIVE_HIGH>;
+
+                                       ti,x-min = /bits/ 16 <150>;
+                                       ti,x-max = /bits/ 16 <3830>;
+                                       ti,y-min = /bits/ 16 <190>;
+                                       ti,y-max = /bits/ 16 <3830>;
+                                       ti,vref-delay-usecs = /bits/ 16 <450>;
+                                       ti,x-plate-ohms = /bits/ 16 <450>;
+                                       ti,y-plate-ohms = /bits/ 16 <250>;
+                                       ti,pressure-max = /bits/ 16 <15000>;
+                                       ti,debounce-rep = /bits/ 16 <0>;
+                                       ti,debounce-tol = /bits/ 16 <65535>;
+                                       ti,debounce-max = /bits/ 16 <1>;
+
+                                       linux,wakeup;
+                               };
+                       };
+
+                       dbgu: serial@fffff200 {
+                               status = "okay";
+                       };
+
+                       watchdog@fffffd40 {
+                               status = "okay";
+                       };
+
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               ds8 {
+                       label = "ds8";
+                       gpios = <&pioA 13 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "none";
+               };
+
+               ds7 {
+                       label = "ds7";
+                       gpios = <&pioA 14 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "nand-disk";
+               };
+
+               ds1 {
+                       label = "ds1";
+                       gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               button_0 {
+                       label = "button_0";
+                       gpios = <&pioA 27 GPIO_ACTIVE_LOW>;
+                       linux,code = <256>;
+                       gpio-key,wakeup;
+               };
+
+               button_1 {
+                       label = "button_1";
+                       gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+                       linux,code = <257>;
+                       gpio-key,wakeup;
+               };
+
+               button_2 {
+                       label = "button_2";
+                       gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
+                       linux,code = <258>;
+                       gpio-key,wakeup;
+               };
+
+               button_3 {
+                       label = "button_3";
+                       gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
+                       linux,code = <259>;
+                       gpio-key,wakeup;
+               };
+       };
+};
index cbcc058b26b4ebea4ba81ff24e4ff21c3edc95ee..9cdaecff13b3996932fc7564a8c4927cd97024c6 100644 (file)
                        };
 
                        adc0: adc@fffb0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                compatible = "atmel,at91sam9260-adc";
                                reg = <0xfffb0000 0x100>;
                                interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
                                atmel,adc-use-external-triggers;
                                atmel,adc-channels-used = <0xff>;
                                atmel,adc-vref = <3300>;
-                               atmel,adc-num-channels = <8>;
                                atmel,adc-startup-time = <40>;
-                               atmel,adc-channel-base = <0x30>;
-                               atmel,adc-drdy-mask = <0x10000>;
-                               atmel,adc-status-register = <0x1c>;
-                               atmel,adc-trigger-register = <0x08>;
                                atmel,adc-res = <8 10>;
                                atmel,adc-res-names = "lowres", "highres";
                                atmel,adc-use-res = "highres";
 
                                trigger@0 {
+                                       reg = <0>;
                                        trigger-name = "external-rising";
                                        trigger-value = <0x1>;
                                        trigger-external;
                                };
                                trigger@1 {
+                                       reg = <1>;
                                        trigger-name = "external-falling";
                                        trigger-value = <0x2>;
                                        trigger-external;
                                };
 
                                trigger@2 {
+                                       reg = <2>;
                                        trigger-name = "external-any";
                                        trigger-value = <0x3>;
                                        trigger-external;
                                };
 
                                trigger@3 {
+                                       reg = <3>;
                                        trigger-name = "continuous";
                                        trigger-value = <0x6>;
                                };
                              >;
                        atmel,nand-addr-offset = <21>;
                        atmel,nand-cmd-offset = <22>;
+                       atmel,nand-has-dma;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
                        gpios = <&pioC 8 GPIO_ACTIVE_HIGH
index 394e6ce2afb75547f229c55348ff527376e98927..9f04808fc697cb0cfb2712fed85d3faff3ed010c 100644 (file)
                        atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
                        atmel,nand-addr-offset = <21>;
                        atmel,nand-cmd-offset = <22>;
+                       atmel,nand-has-dma;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
                        gpios = <&pioD 5 GPIO_ACTIVE_HIGH
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
new file mode 100644 (file)
index 0000000..63e1784
--- /dev/null
@@ -0,0 +1,802 @@
+/*
+ * at91sam9rl.dtsi - Device Tree Include file for AT91SAM9RL family SoC
+ *
+ *  Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/clk/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Atmel AT91SAM9RL family SoC";
+       compatible = "atmel,at91sam9rl", "atmel,at91sam9";
+       interrupt-parent = <&aic>;
+
+       aliases {
+               serial0 = &dbgu;
+               serial1 = &usart0;
+               serial2 = &usart1;
+               serial3 = &usart2;
+               serial4 = &usart3;
+               gpio0 = &pioA;
+               gpio1 = &pioB;
+               gpio2 = &pioC;
+               gpio3 = &pioD;
+               tcb0 = &tcb0;
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               ssc0 = &ssc0;
+               ssc1 = &ssc1;
+       };
+
+       cpus {
+               #address-cells = <0>;
+               #size-cells = <0>;
+
+               cpu {
+                       compatible = "arm,arm926ej-s";
+                       device_type = "cpu";
+               };
+       };
+
+       memory {
+               reg = <0x20000000 0x04000000>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               nand0: nand@40000000 {
+                       compatible = "atmel,at91rm9200-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x40000000 0x10000000>,
+                             <0xffffe800 0x200>;
+                       atmel,nand-addr-offset = <21>;
+                       atmel,nand-cmd-offset = <22>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_nand>;
+                       gpios = <&pioD 17 GPIO_ACTIVE_HIGH>,
+                               <&pioB 6 GPIO_ACTIVE_HIGH>,
+                               <0>;
+                       status = "disabled";
+               };
+
+               apb {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       tcb0: timer@fffa0000 {
+                               compatible = "atmel,at91rm9200-tcb";
+                               reg = <0xfffa0000 0x100>;
+                               interrupts = <16 IRQ_TYPE_LEVEL_HIGH 0>,
+                                            <17 IRQ_TYPE_LEVEL_HIGH 0>,
+                                            <18 IRQ_TYPE_LEVEL_HIGH 0>;
+                               clocks = <&tc0_clk>, <&tc1_clk>, <&tc2_clk>;
+                               clock-names = "t0_clk", "t1_clk", "t2_clk";
+                       };
+
+                       mmc0: mmc@fffa4000 {
+                               compatible = "atmel,hsmci";
+                               reg = <0xfffa4000 0x600>;
+                               interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               pinctrl-names = "default";
+                               clocks = <&mci0_clk>;
+                               clock-names = "mci_clk";
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@fffa8000 {
+                               compatible = "atmel,at91sam9260-i2c";
+                               reg = <0xfffa8000 0x100>;
+                               interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&twi0_clk>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@fffac000 {
+                               compatible = "atmel,at91sam9260-i2c";
+                               reg = <0xfffac000 0x100>;
+                               interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       usart0: serial@fffb0000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffb0000 0x200>;
+                               interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart0>;
+                               clocks = <&usart0_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       usart1: serial@fffb4000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffb4000 0x200>;
+                               interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart1>;
+                               clocks = <&usart1_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       usart2: serial@fffb8000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffb8000 0x200>;
+                               interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart2>;
+                               clocks = <&usart2_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       usart3: serial@fffbc000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffbc000 0x200>;
+                               interrupts = <9 IRQ_TYPE_LEVEL_HIGH 5>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_usart3>;
+                               clocks = <&usart3_clk>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       ssc0: ssc@fffc0000 {
+                               compatible = "atmel,at91rm9200-ssc";
+                               reg = <0xfffc0000 0x4000>;
+                               interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
+                               status = "disabled";
+                       };
+
+                       ssc1: ssc@fffc4000 {
+                               compatible = "atmel,at91rm9200-ssc";
+                               reg = <0xfffc4000 0x4000>;
+                               interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
+                               status = "disabled";
+                       };
+
+                       spi0: spi@fffcc000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "atmel,at91rm9200-spi";
+                               reg = <0xfffcc000 0x200>;
+                               interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_spi0>;
+                               clocks = <&spi0_clk>;
+                               clock-names = "spi_clk";
+                               status = "disabled";
+                       };
+
+                       ramc0: ramc@ffffea00 {
+                               compatible = "atmel,at91sam9260-sdramc";
+                               reg = <0xffffea00 0x200>;
+                       };
+
+                       aic: interrupt-controller@fffff000 {
+                               #interrupt-cells = <3>;
+                               compatible = "atmel,at91rm9200-aic";
+                               interrupt-controller;
+                               reg = <0xfffff000 0x200>;
+                               atmel,external-irqs = <31>;
+                       };
+
+                       dbgu: serial@fffff200 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffff200 0x200>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_dbgu>;
+                               clocks = <&mck>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       pinctrl@fffff400 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+                               ranges = <0xfffff400 0xfffff400 0x800>;
+
+                               atmel,mux-mask =
+                                       /*    A         B     */
+                                       <0xffffffff 0xe05c6738>,  /* pioA */
+                                       <0xffffffff 0x0000c780>,  /* pioB */
+                                       <0xffffffff 0xe3ffff0e>,  /* pioC */
+                                       <0x003fffff 0x0001ff3c>;  /* pioD */
+
+                               /* shared pinctrl settings */
+                               dbgu {
+                                       pinctrl_dbgu: dbgu-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+                                       };
+                               };
+
+                               i2c_gpio0 {
+                                       pinctrl_i2c_gpio0: i2c_gpio0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 23 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>,
+                                                       <AT91_PIOA 24 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+                                       };
+                               };
+
+                               i2c_gpio1 {
+                                       pinctrl_i2c_gpio1: i2c_gpio1-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 10 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>,
+                                                       <AT91_PIOD 11 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+                                       };
+                               };
+
+                               mmc0 {
+                                       pinctrl_mmc0_clk: mmc0_clk-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+                                       };
+
+                                       pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+                                       };
+                               };
+
+                               nand {
+                                       pinctrl_nand: nand-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 17 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOB 6 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+                                       };
+
+                                       pinctrl_nand0_ale_cle: nand_ale_cle-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_nand0_oe_we: nand_oe_we-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_nand0_cs: nand_cs-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               ssc0 {
+                                       pinctrl_ssc0_tx: ssc0_tx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_ssc0_rx: ssc0_rx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               ssc1 {
+                                       pinctrl_ssc1_tx: ssc1_tx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_ssc1_rx: ssc1_rx-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               spi0 {
+                                       pinctrl_spi0: spi0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               tcb0 {
+                                       pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+                                               atmel,pins = <AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+                                               atmel,pins = <AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+                                               atmel,pins = <AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+                                               atmel,pins = <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+                                               atmel,pins = <AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+                                               atmel,pins = <AT91_PIOD 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+                                               atmel,pins = <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+                                               atmel,pins = <AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+                                               atmel,pins = <AT91_PIOD 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               usart0 {
+                                       pinctrl_usart0: usart0-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+                                       };
+
+                                       pinctrl_usart0_rts: usart0_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_cts: usart0_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_dcd: usart0_dcd-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_ri: usart0_ri-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart0_sck: usart0_sck-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               usart1 {
+                                       pinctrl_usart1: usart1-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart1_rts: usart1_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart1_cts: usart1_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart1_sck: usart1_sck-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               usart2 {
+                                       pinctrl_usart2: usart2-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart2_rts: usart2_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart2_cts: usart2_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart2_sck: usart2_sck-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               usart3 {
+                                       pinctrl_usart3: usart3-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
+                                                       <AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart3_rts: usart3_rts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart3_cts: usart3_cts-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOD 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+
+                                       pinctrl_usart3_sck: usart3_sck-0 {
+                                               atmel,pins =
+                                                       <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                                       };
+                               };
+
+                               pioA: gpio@fffff400 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff400 0x200>;
+                                       interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioA_clk>;
+                               };
+
+                               pioB: gpio@fffff600 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff600 0x200>;
+                                       interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioB_clk>;
+                               };
+
+                               pioC: gpio@fffff800 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff800 0x200>;
+                                       interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioC_clk>;
+                               };
+
+                               pioD: gpio@fffffa00 {
+                                       compatible = "atmel,at91rm9200-gpio";
+                                       reg = <0xfffffa00 0x200>;
+                                       interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pioD_clk>;
+                               };
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               compatible = "atmel,at91sam9g45-pmc";
+                               reg = <0xfffffc00 0x100>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               interrupt-controller;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               #interrupt-cells = <1>;
+
+                               clk32k: slck {
+                                       compatible = "fixed-clock";
+                                       #clock-cells = <0>;
+                                       clock-frequency = <32768>;
+                               };
+
+                               main: mainck {
+                                       compatible = "atmel,at91rm9200-clk-main";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_MOSCS>;
+                                       clocks = <&clk32k>;
+                               };
+
+                               plla: pllack {
+                                       compatible = "atmel,at91rm9200-clk-pll";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_LOCKA>;
+                                       clocks = <&main>;
+                                       reg = <0>;
+                                       atmel,clk-input-range = <1000000 32000000>;
+                                       #atmel,pll-clk-output-range-cells = <4>;
+                                       atmel,pll-clk-output-ranges = <80000000 200000000 190000000 240000000>;
+                               };
+
+                               utmi: utmick {
+                                       compatible = "atmel,at91sam9x5-clk-utmi";
+                                       #clock-cells = <0>;
+                                       interrupt-parent = <&pmc>;
+                                       interrupts = <AT91_PMC_LOCKU>;
+                                       clocks = <&main>;
+                               };
+
+                               mck: masterck {
+                                       compatible = "atmel,at91rm9200-clk-master";
+                                       #clock-cells = <0>;
+                                       interrupts-extended = <&pmc AT91_PMC_MCKRDY>;
+                                       clocks = <&clk32k>, <&main>, <&plla>, <&utmi>;
+                                       atmel,clk-output-range = <0 94000000>;
+                                       atmel,clk-divisors = <1 2 4 3>;
+                               };
+
+                               prog: progck {
+                                       compatible = "atmel,at91rm9200-clk-programmable";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       interrupt-parent = <&pmc>;
+                                       clocks = <&clk32k>, <&main>, <&plla>, <&utmi>, <&mck>;
+
+                                       prog0: prog0 {
+                                               #clock-cells = <0>;
+                                               reg = <0>;
+                                               interrupts = <AT91_PMC_PCKRDY(0)>;
+                                       };
+
+                                       prog1: prog1 {
+                                               #clock-cells = <0>;
+                                               reg = <1>;
+                                               interrupts = <AT91_PMC_PCKRDY(1)>;
+                                       };
+                               };
+
+                               systemck {
+                                       compatible = "atmel,at91rm9200-clk-system";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       pck0: pck0 {
+                                               #clock-cells = <0>;
+                                               reg = <8>;
+                                               clocks = <&prog0>;
+                                       };
+
+                                       pck1: pck1 {
+                                               #clock-cells = <0>;
+                                               reg = <9>;
+                                               clocks = <&prog1>;
+                                       };
+
+                               };
+
+                               periphck {
+                                       compatible = "atmel,at91rm9200-clk-peripheral";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       clocks = <&mck>;
+
+                                       pioA_clk: pioA_clk {
+                                               #clock-cells = <0>;
+                                               reg = <2>;
+                                       };
+
+                                       pioB_clk: pioB_clk {
+                                               #clock-cells = <0>;
+                                               reg = <3>;
+                                       };
+
+                                       pioC_clk: pioC_clk {
+                                               #clock-cells = <0>;
+                                               reg = <4>;
+                                       };
+
+                                       pioD_clk: pioD_clk {
+                                               #clock-cells = <0>;
+                                               reg = <5>;
+                                       };
+
+                                       usart0_clk: usart0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <6>;
+                                       };
+
+                                       usart1_clk: usart1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <7>;
+                                       };
+
+                                       usart2_clk: usart2_clk {
+                                               #clock-cells = <0>;
+                                               reg = <8>;
+                                       };
+
+                                       usart3_clk: usart3_clk {
+                                               #clock-cells = <0>;
+                                               reg = <9>;
+                                       };
+
+                                       mci0_clk: mci0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <10>;
+                                       };
+
+                                       twi0_clk: twi0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <11>;
+                                       };
+
+                                       twi1_clk: twi1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <12>;
+                                       };
+
+                                       spi0_clk: spi0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <13>;
+                                       };
+
+                                       ssc0_clk: ssc0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <14>;
+                                       };
+
+                                       ssc1_clk: ssc1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <15>;
+                                       };
+
+                                       tc0_clk: tc0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <16>;
+                                       };
+
+                                       tc1_clk: tc1_clk {
+                                               #clock-cells = <0>;
+                                               reg = <17>;
+                                       };
+
+                                       tc2_clk: tc2_clk {
+                                               #clock-cells = <0>;
+                                               reg = <18>;
+                                       };
+
+                                       pwm_clk: pwm_clk {
+                                               #clock-cells = <0>;
+                                               reg = <19>;
+                                       };
+
+                                       adc_clk: adc_clk {
+                                               #clock-cells = <0>;
+                                               reg = <20>;
+                                       };
+
+                                       dma0_clk: dma0_clk {
+                                               #clock-cells = <0>;
+                                               reg = <21>;
+                                       };
+
+                                       udphs_clk: udphs_clk {
+                                               #clock-cells = <0>;
+                                               reg = <22>;
+                                       };
+
+                                       lcd_clk: lcd_clk {
+                                               #clock-cells = <0>;
+                                               reg = <23>;
+                                       };
+                               };
+                       };
+
+                       rstc@fffffd00 {
+                               compatible = "atmel,at91sam9260-rstc";
+                               reg = <0xfffffd00 0x10>;
+                       };
+
+                       shdwc@fffffd10 {
+                               compatible = "atmel,at91sam9260-shdwc";
+                               reg = <0xfffffd10 0x10>;
+                       };
+
+                       pit: timer@fffffd30 {
+                               compatible = "atmel,at91sam9260-pit";
+                               reg = <0xfffffd30 0xf>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               clocks = <&mck>;
+                       };
+
+                       watchdog@fffffd40 {
+                               compatible = "atmel,at91sam9260-wdt";
+                               reg = <0xfffffd40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       i2c@0 {
+               compatible = "i2c-gpio";
+               gpios = <&pioA 23 GPIO_ACTIVE_HIGH>, /* sda */
+                       <&pioA 24 GPIO_ACTIVE_HIGH>; /* scl */
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c_gpio0>;
+               status = "disabled";
+       };
+
+       i2c@1 {
+               compatible = "i2c-gpio";
+               gpios = <&pioD 10 GPIO_ACTIVE_HIGH>, /* sda */
+                       <&pioD 11 GPIO_ACTIVE_HIGH>; /* scl */
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c_gpio1>;
+               status = "disabled";
+       };
+};
diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts
new file mode 100644 (file)
index 0000000..cddb378
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * at91sam9rlek.dts - Device Tree file for Atmel at91sam9rl reference board
+ *
+ *  Copyright (C) 2014  Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+#include "at91sam9rl.dtsi"
+
+/ {
+       model = "Atmel at91sam9rlek";
+       compatible = "atmel,at91sam9rlek", "atmel,at91sam9rl", "atmel,at91sam9";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 rootfstype=ubifs root=ubi0:rootfs ubi.mtd=5 rw";
+       };
+
+       memory {
+               reg = <0x20000000 0x4000000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               main_clock: clock {
+                       compatible = "atmel,osc", "fixed-clock";
+                       clock-frequency = <12000000>;
+               };
+       };
+
+       ahb {
+               nand0: nand@40000000 {
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "soft";
+                       nand-on-flash-bbt = <1>;
+                       status = "okay";
+
+                       at91bootstrap@0 {
+                               label = "at91bootstrap";
+                               reg = <0x0 0x40000>;
+                       };
+
+                       bootloader@40000 {
+                               label = "bootloader";
+                               reg = <0x40000 0x80000>;
+                       };
+
+                       bootloaderenv@c0000 {
+                               label = "bootloader env";
+                               reg = <0xc0000 0xc0000>;
+                       };
+
+                       dtb@180000 {
+                               label = "device tree";
+                               reg = <0x180000 0x80000>;
+                       };
+
+                       kernel@200000 {
+                               label = "kernel";
+                               reg = <0x200000 0x600000>;
+                       };
+
+                       rootfs@800000 {
+                               label = "rootfs";
+                               reg = <0x800000 0x0f800000>;
+                       };
+               };
+
+               apb {
+                       mmc0: mmc@fffa4000 {
+                               pinctrl-0 = <
+                                       &pinctrl_board_mmc0
+                                       &pinctrl_mmc0_clk
+                                       &pinctrl_mmc0_slot0_cmd_dat0
+                                       &pinctrl_mmc0_slot0_dat1_3>;
+                               status = "okay";
+                               slot@0 {
+                                       reg = <0>;
+                                       bus-width = <4>;
+                                       cd-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
+                               };
+                       };
+
+                       usart0: serial@fffb0000 {
+                               pinctrl-0 = <
+                                       &pinctrl_usart0
+                                       &pinctrl_usart0_rts
+                                       &pinctrl_usart0_cts>;
+                               status = "okay";
+                       };
+
+                       dbgu: serial@fffff200 {
+                               status = "okay";
+                       };
+
+                       pinctrl@fffff400 {
+                               mmc0 {
+                                       pinctrl_board_mmc0: mmc0-board {
+                                               atmel,pins =
+                                                       <AT91_PIOA 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+                                       };
+                               };
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               main: mainck {
+                                       clock-frequency = <12000000>;
+                               };
+                       };
+
+                       watchdog@fffffd40 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               ds1 {
+                       label = "ds1";
+                       gpios = <&pioD 15 GPIO_ACTIVE_LOW>;
+               };
+
+               ds2 {
+                       label = "ds2";
+                       gpios = <&pioD 16 GPIO_ACTIVE_LOW>;
+               };
+
+               ds3 {
+                       label = "ds3";
+                       gpios = <&pioD 14 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               right_click {
+                       label = "right_click";
+                       gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
+                       linux,code = <273>;
+                       gpio-key,wakeup;
+               };
+
+               left_click {
+                       label = "left_click";
+                       gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <272>;
+                       gpio-key,wakeup;
+               };
+       };
+};
index 174219de92fa7380d4e6dc8a2a9916fa05e70a6e..fc13c9240da85c43c98f5aacdfc1bf76c1b955dc 100644 (file)
                        };
 
                        adc0: adc@f804c000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
                                compatible = "atmel,at91sam9260-adc";
                                reg = <0xf804c000 0x100>;
                                interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>;
-                               atmel,adc-use-external;
+                               atmel,adc-use-external-triggers;
                                atmel,adc-channels-used = <0xffff>;
                                atmel,adc-vref = <3300>;
-                               atmel,adc-num-channels = <12>;
                                atmel,adc-startup-time = <40>;
-                               atmel,adc-channel-base = <0x50>;
-                               atmel,adc-drdy-mask = <0x1000000>;
-                               atmel,adc-status-register = <0x30>;
-                               atmel,adc-trigger-register = <0xc0>;
                                atmel,adc-res = <8 10>;
                                atmel,adc-res-names = "lowres", "highres";
                                atmel,adc-use-res = "highres";
 
                                trigger@0 {
+                                       reg = <0>;
                                        trigger-name = "external-rising";
                                        trigger-value = <0x1>;
                                        trigger-external;
                                };
 
                                trigger@1 {
+                                       reg = <1>;
                                        trigger-name = "external-falling";
                                        trigger-value = <0x2>;
                                        trigger-external;
                                };
 
                                trigger@2 {
+                                       reg = <2>;
                                        trigger-name = "external-any";
                                        trigger-value = <0x3>;
                                        trigger-external;
                                };
 
                                trigger@3 {
+                                       reg = <3>;
                                        trigger-name = "continuous";
                                        trigger-value = <0x6>;
                                };
                        atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
                        atmel,nand-addr-offset = <21>;
                        atmel,nand-cmd-offset = <22>;
+                       atmel,nand-has-dma;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
                        gpios = <&pioD 5 GPIO_ACTIVE_HIGH
index 0c81dc945aed91f202ad374fe8d1d0d1aaeeca0c..55d3f79c2ef599f3d898905b86f16161cafc3e80 100644 (file)
                                #clock-cells = <1>;
                        };
 
-                       reset-controller@88010000 {
+                       rstc: reset-controller@88010000 {
                                compatible = "sirf,prima2-rstc";
                                reg = <0x88010000 0x1000>;
+                               #reset-cells = <1>;
                        };
 
                        rsc-controller@88020000 {
diff --git a/arch/arm/boot/dts/bcm11351-brt.dts b/arch/arm/boot/dts/bcm11351-brt.dts
deleted file mode 100644 (file)
index 396b704..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-
-#include "bcm11351.dtsi"
-
-/ {
-       model = "BCM11351 BRT board";
-       compatible = "brcm,bcm11351-brt", "brcm,bcm11351";
-
-       memory {
-               reg = <0x80000000 0x40000000>; /* 1 GB */
-       };
-
-       uart@3e000000 {
-               status = "okay";
-       };
-
-       sdio1: sdio@3f180000 {
-               max-frequency = <48000000>;
-               status = "okay";
-       };
-
-       sdio2: sdio@3f190000 {
-               non-removable;
-               max-frequency = <48000000>;
-               status = "okay";
-       };
-
-       sdio4: sdio@3f1b0000 {
-               max-frequency = <48000000>;
-               cd-gpios = <&gpio 14 0>;
-               status = "okay";
-       };
-
-       usbotg: usb@3f120000 {
-               status = "okay";
-       };
-
-       usbphy: usb-phy@3f130000 {
-               status = "okay";
-       };
-};
index 792fde1b7f752a93ffa42f2e5f8c7083dc1bb55c..64d069bcc4094fc3756be15b723e80183b824d50 100644 (file)
@@ -14,6 +14,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
+#include "dt-bindings/clock/bcm281xx.h"
+
 #include "skeleton.dtsi"
 
 / {
@@ -43,7 +45,7 @@
                compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
                status = "disabled";
                reg = <0x3e000000 0x1000>;
-               clocks = <&uartb_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB>;
                interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
                reg-shift = <2>;
                reg-io-width = <4>;
@@ -53,7 +55,7 @@
                compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
                status = "disabled";
                reg = <0x3e001000 0x1000>;
-               clocks = <&uartb2_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB2>;
                interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
                reg-shift = <2>;
                reg-io-width = <4>;
@@ -63,7 +65,7 @@
                compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
                status = "disabled";
                reg = <0x3e002000 0x1000>;
-               clocks = <&uartb3_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>;
                interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                reg-shift = <2>;
                reg-io-width = <4>;
@@ -73,7 +75,7 @@
                compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
                status = "disabled";
                reg = <0x3e003000 0x1000>;
-               clocks = <&uartb4_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB4>;
                interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
                reg-shift = <2>;
                reg-io-width = <4>;
@@ -95,7 +97,7 @@
                compatible = "brcm,kona-timer";
                reg = <0x35006000 0x1000>;
                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&hub_timer_clk>;
+               clocks = <&aon_ccu BCM281XX_AON_CCU_HUB_TIMER>;
        };
 
        gpio: gpio@35003000 {
                compatible = "brcm,kona-sdhci";
                reg = <0x3f180000 0x10000>;
                interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sdio1_clk>;
+               clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO1>;
                status = "disabled";
        };
 
                compatible = "brcm,kona-sdhci";
                reg = <0x3f190000 0x10000>;
                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sdio2_clk>;
+               clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO2>;
                status = "disabled";
        };
 
                compatible = "brcm,kona-sdhci";
                reg = <0x3f1a0000 0x10000>;
                interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sdio3_clk>;
+               clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO3>;
                status = "disabled";
        };
 
                compatible = "brcm,kona-sdhci";
                reg = <0x3f1b0000 0x10000>;
                interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sdio4_clk>;
+               clocks = <&master_ccu BCM281XX_MASTER_CCU_SDIO4>;
                status = "disabled";
        };
 
                interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&bsc1_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_BSC1>;
                status = "disabled";
        };
 
                interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&bsc2_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_BSC2>;
                status = "disabled";
        };
 
                interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&bsc3_clk>;
+               clocks = <&slave_ccu BCM281XX_SLAVE_CCU_BSC3>;
                status = "disabled";
        };
 
                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&pmu_bsc_clk>;
+               clocks = <&aon_ccu BCM281XX_AON_CCU_PMU_BSC>;
                status = "disabled";
        };
 
        clocks {
-               bsc1_clk: bsc1 {
-                       compatible = "fixed-clock";
-                       clock-frequency = <13000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               root_ccu: root_ccu {
+                       compatible = "brcm,bcm11351-root-ccu";
+                       reg = <0x35001000 0x0f00>;
+                       #clock-cells = <1>;
+                       clock-output-names = "frac_1m";
+               };
+
+               hub_ccu: hub_ccu {
+                       compatible = "brcm,bcm11351-hub-ccu";
+                       reg = <0x34000000 0x0f00>;
+                       #clock-cells = <1>;
+                       clock-output-names = "tmon_1m";
+               };
+
+               aon_ccu: aon_ccu {
+                       compatible = "brcm,bcm11351-aon-ccu";
+                       reg = <0x35002000 0x0f00>;
+                       #clock-cells = <1>;
+                       clock-output-names = "hub_timer",
+                                            "pmu_bsc",
+                                            "pmu_bsc_var";
+               };
+
+               master_ccu: master_ccu {
+                       compatible = "brcm,bcm11351-master-ccu";
+                       reg = <0x3f001000 0x0f00>;
+                       #clock-cells = <1>;
+                       clock-output-names = "sdio1",
+                                            "sdio2",
+                                            "sdio3",
+                                            "sdio4",
+                                            "usb_ic",
+                                            "hsic2_48m",
+                                            "hsic2_12m";
+               };
+
+               slave_ccu: slave_ccu {
+                       compatible = "brcm,bcm11351-slave-ccu";
+                       reg = <0x3e011000 0x0f00>;
+                       #clock-cells = <1>;
+                       clock-output-names = "uartb",
+                                            "uartb2",
+                                            "uartb3",
+                                            "uartb4",
+                                            "ssp0",
+                                            "ssp2",
+                                            "bsc1",
+                                            "bsc2",
+                                            "bsc3",
+                                            "pwm";
+               };
+
+               ref_1m_clk: ref_1m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <1000000>;
                };
 
-               bsc2_clk: bsc2 {
+               ref_32k_clk: ref_32k {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <13000000>;
+                       clock-frequency = <32768>;
+               };
+
+               bbl_32k_clk: bbl_32k {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <32768>;
                };
 
-               bsc3_clk: bsc3 {
+               ref_13m_clk: ref_13m {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <13000000>;
-                       #clock-cells = <0>;
                };
 
-               pmu_bsc_clk: pmu_bsc {
+               var_13m_clk: var_13m {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <13000000>;
-                       #clock-cells = <0>;
                };
 
-               hub_timer_clk: hub_timer {
-                       compatible = "fixed-clock";
-                       clock-frequency = <32768>;
+               dft_19_5m_clk: dft_19_5m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <19500000>;
                };
 
-               pwm_clk: pwm {
+               ref_crystal_clk: ref_crystal {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <26000000>;
-                       #clock-cells = <0>;
                };
 
-               sdio1_clk: sdio1 {
-                       compatible = "fixed-clock";
-                       clock-frequency = <48000000>;
+               ref_cx40_clk: ref_cx40 {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <40000000>;
                };
 
-               sdio2_clk: sdio2 {
-                       compatible = "fixed-clock";
-                       clock-frequency = <48000000>;
+               ref_52m_clk: ref_52m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <52000000>;
                };
 
-               sdio3_clk: sdio3 {
-                       compatible = "fixed-clock";
-                       clock-frequency = <48000000>;
+               var_52m_clk: var_52m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <52000000>;
                };
 
-               sdio4_clk: sdio4 {
+               usb_otg_ahb_clk: usb_otg_ahb {
                        compatible = "fixed-clock";
-                       clock-frequency = <48000000>;
+                       clock-frequency = <52000000>;
                        #clock-cells = <0>;
                };
 
-               tmon_1m_clk: tmon_1m {
-                       compatible = "fixed-clock";
-                       clock-frequency = <1000000>;
+               ref_96m_clk: ref_96m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <96000000>;
                };
 
-               uartb_clk: uartb {
-                       compatible = "fixed-clock";
-                       clock-frequency = <13000000>;
+               var_96m_clk: var_96m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <96000000>;
                };
 
-               uartb2_clk: uartb2 {
+               ref_104m_clk: ref_104m {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <13000000>;
+                       clock-frequency = <104000000>;
+               };
+
+               var_104m_clk: var_104m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <104000000>;
                };
 
-               uartb3_clk: uartb3 {
+               ref_156m_clk: ref_156m {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <13000000>;
+                       clock-frequency = <156000000>;
+               };
+
+               var_156m_clk: var_156m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <156000000>;
                };
 
-               uartb4_clk: uartb4 {
+               ref_208m_clk: ref_208m {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <13000000>;
+                       clock-frequency = <208000000>;
+               };
+
+               var_208m_clk: var_208m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <208000000>;
                };
 
-               usb_otg_ahb_clk: usb_otg_ahb {
+               ref_312m_clk: ref_312m {
+                       #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <52000000>;
+                       clock-frequency = <312000000>;
+               };
+
+               var_312m_clk: var_312m {
                        #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <312000000>;
                };
        };
 
diff --git a/arch/arm/boot/dts/bcm21664-garnet.dts b/arch/arm/boot/dts/bcm21664-garnet.dts
new file mode 100644 (file)
index 0000000..e87cb26
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "bcm21664.dtsi"
+
+/ {
+       model = "BCM21664 Garnet board";
+       compatible = "brcm,bcm21664-garnet", "brcm,bcm21664";
+
+       memory {
+               reg = <0x80000000 0x40000000>; /* 1 GB */
+       };
+
+       uart@3e000000 {
+               status = "okay";
+       };
+
+       sdio1: sdio@3f180000 {
+               max-frequency = <48000000>;
+               status = "okay";
+       };
+
+       sdio2: sdio@3f190000 {
+               non-removable;
+               max-frequency = <48000000>;
+               status = "okay";
+       };
+
+       sdio4: sdio@3f1b0000 {
+               max-frequency = <48000000>;
+               cd-gpios = <&gpio 91 GPIO_ACTIVE_LOW>;
+               status = "okay";
+       };
+
+       usbotg: usb@3f120000 {
+               status = "okay";
+       };
+
+       usbphy: usb-phy@3f130000 {
+               status = "okay";
+       };
+};
diff --git a/arch/arm/boot/dts/bcm21664.dtsi b/arch/arm/boot/dts/bcm21664.dtsi
new file mode 100644 (file)
index 0000000..08a44d4
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+       model = "BCM21664 SoC";
+       compatible = "brcm,bcm21664";
+       interrupt-parent = <&gic>;
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gic: interrupt-controller@3ff00100 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0x3ff01000 0x1000>,
+                     <0x3ff00100 0x100>;
+       };
+
+       smc@0x3404e000 {
+               compatible = "brcm,bcm21664-smc", "brcm,kona-smc";
+               reg = <0x3404e000 0x400>; /* 1 KiB in SRAM */
+       };
+
+       uart@3e000000 {
+               compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
+               status = "disabled";
+               reg = <0x3e000000 0x118>;
+               clocks = <&uartb_clk>;
+               interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
+
+       uart@3e001000 {
+               compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
+               status = "disabled";
+               reg = <0x3e001000 0x118>;
+               clocks = <&uartb2_clk>;
+               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
+
+       uart@3e002000 {
+               compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
+               status = "disabled";
+               reg = <0x3e002000 0x118>;
+               clocks = <&uartb3_clk>;
+               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
+
+       L2: l2-cache {
+               compatible = "arm,pl310-cache";
+               reg = <0x3ff20000 0x1000>;
+               cache-unified;
+               cache-level = <2>;
+       };
+
+       brcm,resetmgr@35001f00 {
+               compatible = "brcm,bcm21664-resetmgr";
+               reg = <0x35001f00 0x24>;
+       };
+
+       timer@35006000 {
+               compatible = "brcm,kona-timer";
+               reg = <0x35006000 0x1c>;
+               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&hub_timer_clk>;
+       };
+
+       gpio: gpio@35003000 {
+               compatible = "brcm,bcm21664-gpio", "brcm,kona-gpio";
+               reg = <0x35003000 0x524>;
+               interrupts =
+                      <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH
+                       GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+               #gpio-cells = <2>;
+               #interrupt-cells = <2>;
+               gpio-controller;
+               interrupt-controller;
+       };
+
+       sdio1: sdio@3f180000 {
+               compatible = "brcm,kona-sdhci";
+               reg = <0x3f180000 0x801c>;
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&sdio1_clk>;
+               status = "disabled";
+       };
+
+       sdio2: sdio@3f190000 {
+               compatible = "brcm,kona-sdhci";
+               reg = <0x3f190000 0x801c>;
+               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&sdio2_clk>;
+               status = "disabled";
+       };
+
+       sdio3: sdio@3f1a0000 {
+               compatible = "brcm,kona-sdhci";
+               reg = <0x3f1a0000 0x801c>;
+               interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&sdio3_clk>;
+               status = "disabled";
+       };
+
+       sdio4: sdio@3f1b0000 {
+               compatible = "brcm,kona-sdhci";
+               reg = <0x3f1b0000 0x801c>;
+               interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&sdio4_clk>;
+               status = "disabled";
+       };
+
+       i2c@3e016000 {
+               compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+               reg = <0x3e016000 0x70>;
+               interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&bsc1_clk>;
+               status = "disabled";
+       };
+
+       i2c@3e017000 {
+               compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+               reg = <0x3e017000 0x70>;
+               interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&bsc2_clk>;
+               status = "disabled";
+       };
+
+       i2c@3e018000 {
+               compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+               reg = <0x3e018000 0x70>;
+               interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&bsc3_clk>;
+               status = "disabled";
+       };
+
+       i2c@3e01c000 {
+               compatible = "brcm,bcm21664-i2c", "brcm,kona-i2c";
+               reg = <0x3e01c000 0x70>;
+               interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&bsc4_clk>;
+               status = "disabled";
+       };
+
+       clocks {
+               bsc1_clk: bsc1 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               bsc2_clk: bsc2 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               bsc3_clk: bsc3 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               bsc4_clk: bsc4 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               pmu_bsc_clk: pmu_bsc {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               hub_timer_clk: hub_timer {
+                       compatible = "fixed-clock";
+                       clock-frequency = <32768>;
+                       #clock-cells = <0>;
+               };
+
+               pwm_clk: pwm {
+                       compatible = "fixed-clock";
+                       clock-frequency = <26000000>;
+                       #clock-cells = <0>;
+               };
+
+               sdio1_clk: sdio1 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+
+               sdio2_clk: sdio2 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+
+               sdio3_clk: sdio3 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+
+               sdio4_clk: sdio4 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <48000000>;
+                       #clock-cells = <0>;
+               };
+
+               tmon_1m_clk: tmon_1m {
+                       compatible = "fixed-clock";
+                       clock-frequency = <1000000>;
+                       #clock-cells = <0>;
+               };
+
+               uartb_clk: uartb {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               uartb2_clk: uartb2 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               uartb3_clk: uartb3 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <13000000>;
+                       #clock-cells = <0>;
+               };
+
+               usb_otg_ahb_clk: usb_otg_ahb {
+                       compatible = "fixed-clock";
+                       clock-frequency = <52000000>;
+                       #clock-cells = <0>;
+               };
+       };
+
+       usbotg: usb@3f120000 {
+               compatible = "snps,dwc2";
+               reg = <0x3f120000 0x10000>;
+               interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&usb_otg_ahb_clk>;
+               clock-names = "otg";
+               phys = <&usbphy>;
+               phy-names = "usb2-phy";
+               status = "disabled";
+       };
+
+       usbphy: usb-phy@3f130000 {
+               compatible = "brcm,kona-usb2-phy";
+               reg = <0x3f130000 0x28>;
+               #phy-cells = <0>;
+               status = "disabled";
+       };
+};
index 5ff2382a49e4136eb15a087e3a253803906794eb..af3da55eef496897695e168ac76c3a4f77b1bab3 100644 (file)
 
        i2c@3500d000 {
                status="okay";
-               clock-frequency = <400000>;
-       };
+               clock-frequency = <100000>;
 
-       sdio1: sdio@3f180000 {
-               max-frequency = <48000000>;
-               status = "okay";
+               pmu: pmu@8 {
+                       reg = <0x08>;
+               };
        };
 
        sdio2: sdio@3f190000 {
                non-removable;
                max-frequency = <48000000>;
+               vmmc-supply = <&camldo1_reg>;
+               vqmmc-supply = <&iosr1_reg>;
                status = "okay";
        };
 
        sdio4: sdio@3f1b0000 {
                max-frequency = <48000000>;
                cd-gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+               vmmc-supply = <&sdldo_reg>;
+               vqmmc-supply = <&sdxldo_reg>;
                status = "okay";
        };
 
        usbotg: usb@3f120000 {
+               vusb_d-supply = <&usbldo_reg>;
+               vusb_a-supply = <&iosr1_reg>;
                status = "okay";
        };
 
                status = "okay";
        };
 };
+
+#include "bcm59056.dtsi"
+
+&pmu {
+       compatible = "brcm,bcm59056";
+       interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+       regulators {
+               camldo1_reg: camldo1 {
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               sdldo_reg: sdldo {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+               };
+
+               sdxldo_reg: sdxldo {
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+
+               usbldo_reg: usbldo {
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               iosr1_reg: iosr1 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+       };
+};
index b021c96d3ba18225660185b037b5a5e1d65f68d5..b8473c43e88827de921d727001ef7871704736c7 100644 (file)
                #size-cells = <1>;
                ranges = <0x7e000000 0x20000000 0x02000000>;
 
-               timer {
+               timer@7e003000 {
                        compatible = "brcm,bcm2835-system-timer";
                        reg = <0x7e003000 0x1000>;
                        interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
                        clock-frequency = <1000000>;
                };
 
-               intc: interrupt-controller {
+               dma: dma@7e007000 {
+                       compatible = "brcm,bcm2835-dma";
+                       reg = <0x7e007000 0xf00>;
+                       interrupts = <1 16>,
+                                    <1 17>,
+                                    <1 18>,
+                                    <1 19>,
+                                    <1 20>,
+                                    <1 21>,
+                                    <1 22>,
+                                    <1 23>,
+                                    <1 24>,
+                                    <1 25>,
+                                    <1 26>,
+                                    <1 27>,
+                                    <1 28>;
+
+                       #dma-cells = <1>;
+                       brcm,dma-channel-mask = <0x7f35>;
+               };
+
+               intc: interrupt-controller@7e00b200 {
                        compatible = "brcm,bcm2835-armctrl-ic";
                        reg = <0x7e00b200 0x200>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                };
 
-               watchdog {
+               watchdog@7e100000 {
                        compatible = "brcm,bcm2835-pm-wdt";
                        reg = <0x7e100000 0x28>;
                };
 
-               rng {
+               rng@7e104000 {
                        compatible = "brcm,bcm2835-rng";
                        reg = <0x7e104000 0x10>;
                };
 
-               uart@20201000 {
-                       compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
-                       reg = <0x7e201000 0x1000>;
-                       interrupts = <2 25>;
-                       clock-frequency = <3000000>;
-                       arm,primecell-periphid = <0x00241011>;
-               };
-
-               gpio: gpio {
+               gpio: gpio@7e200000 {
                        compatible = "brcm,bcm2835-gpio";
                        reg = <0x7e200000 0xb4>;
                        /*
                        #interrupt-cells = <2>;
                };
 
-               spi: spi@20204000 {
+               uart@7e201000 {
+                       compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+                       reg = <0x7e201000 0x1000>;
+                       interrupts = <2 25>;
+                       clock-frequency = <3000000>;
+                       arm,primecell-periphid = <0x00241011>;
+               };
+
+               i2s: i2s@7e203000 {
+                       compatible = "brcm,bcm2835-i2s";
+                       reg = <0x7e203000 0x20>,
+                             <0x7e101098 0x02>;
+
+                       dmas = <&dma 2>,
+                              <&dma 3>;
+                       dma-names = "tx", "rx";
+               };
+
+               spi: spi@7e204000 {
                        compatible = "brcm,bcm2835-spi";
                        reg = <0x7e204000 0x1000>;
                        interrupts = <2 22>;
                        status = "disabled";
                };
 
-               i2c1: i2c@20804000 {
+               sdhci: sdhci@7e300000 {
+                       compatible = "brcm,bcm2835-sdhci";
+                       reg = <0x7e300000 0x100>;
+                       interrupts = <2 30>;
+                       clocks = <&clk_mmc>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@7e804000 {
                        compatible = "brcm,bcm2835-i2c";
                        reg = <0x7e804000 0x1000>;
                        interrupts = <2 21>;
                        status = "disabled";
                };
 
-               sdhci: sdhci {
-                       compatible = "brcm,bcm2835-sdhci";
-                       reg = <0x7e300000 0x100>;
-                       interrupts = <2 30>;
-                       clocks = <&clk_mmc>;
-                       status = "disabled";
-               };
-
-               usb {
+               usb@7e980000 {
                        compatible = "brcm,bcm2835-usb";
                        reg = <0x7e980000 0x10000>;
                        interrupts = <1 9>;
                };
+
+               arm-pmu {
+                       compatible = "arm,arm1176-pmu";
+               };
        };
 
        clocks {
                #address-cells = <1>;
                #size-cells = <0>;
 
-               clk_mmc: mmc {
+               clk_mmc: clock@0 {
                        compatible = "fixed-clock";
                        reg = <0>;
                        #clock-cells = <0>;
+                       clock-output-names = "mmc";
                        clock-frequency = <100000000>;
                };
 
-               clk_i2c: i2c {
+               clk_i2c: clock@1 {
                        compatible = "fixed-clock";
                        reg = <1>;
                        #clock-cells = <0>;
+                       clock-output-names = "i2c";
                        clock-frequency = <250000000>;
                };
 
-               clk_spi: spi {
+               clk_spi: clock@2 {
                        compatible = "fixed-clock";
                        reg = <2>;
                        #clock-cells = <0>;
+                       clock-output-names = "spi";
                        clock-frequency = <250000000>;
                };
        };
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
new file mode 100644 (file)
index 0000000..3b5259d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Broadcom BCM470X / BCM5301X arm platform code.
+ * DTS for Netgear R6250 V1
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+       compatible = "netgear,r6250v1", "brcm,bcm4708";
+       model = "Netgear R6250 V1 (BCM4708)";
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+       };
+
+       memory {
+               reg = <0x00000000 0x08000000>;
+       };
+
+       chipcommonA {
+               uart0: serial@0300 {
+                       status = "okay";
+               };
+
+               uart1: serial@0400 {
+                       status = "okay";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/bcm4708.dtsi b/arch/arm/boot/dts/bcm4708.dtsi
new file mode 100644 (file)
index 0000000..31141e8
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for BCM4708 SoC.
+ *
+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcm5301x.dtsi"
+
+/ {
+       compatible = "brcm,bcm4708";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       next-level-cache = <&L2>;
+                       reg = <0x1>;
+               };
+       };
+
+};
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
new file mode 100644 (file)
index 0000000..53c624f
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
+ * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
+ *
+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+       interrupt-parent = <&gic>;
+
+       chipcommonA {
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x18000000 0x00001000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               uart0: serial@0300 {
+                       compatible = "ns16550";
+                       reg = <0x0300 0x100>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <100000000>;
+                       status = "disabled";
+               };
+
+               uart1: serial@0400 {
+                       compatible = "ns16550";
+                       reg = <0x0400 0x100>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <100000000>;
+                       status = "disabled";
+               };
+       };
+
+       mpcore {
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x19020000 0x00003000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               scu@0000 {
+                       compatible = "arm,cortex-a9-scu";
+                       reg = <0x0000 0x100>;
+               };
+
+               timer@0200 {
+                       compatible = "arm,cortex-a9-global-timer";
+                       reg = <0x0200 0x100>;
+                       interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk_periph>;
+               };
+
+               local-timer@0600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x0600 0x100>;
+                       interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk_periph>;
+               };
+
+               gic: interrupt-controller@1000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+                       interrupt-controller;
+                       reg = <0x1000 0x1000>,
+                             <0x0100 0x100>;
+               };
+
+               L2: cache-controller@2000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x2000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* As long as we do not have a real clock driver us this
+                * fixed clock */
+               clk_periph: periph {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <400000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/bcm59056.dtsi b/arch/arm/boot/dts/bcm59056.dtsi
new file mode 100644 (file)
index 0000000..dfadaaa
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+* Copyright 2014 Linaro Limited
+* Author: Matt Porter <mporter@linaro.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.
+*/
+
+&pmu {
+       compatible = "brcm,bcm59056";
+       regulators {
+               rfldo_reg: rfldo {
+               };
+
+               camldo1_reg: camldo1 {
+               };
+
+               camldo2_reg: camldo2 {
+               };
+
+               simldo1_reg: simldo1 {
+               };
+
+               simldo2_reg: simldo2 {
+               };
+
+               sdldo_reg: sdldo {
+               };
+
+               sdxldo_reg: sdxldo {
+               };
+
+               mmcldo1_reg: mmcldo1 {
+               };
+
+               mmcldo2_reg: mmcldo2 {
+               };
+
+               audldo_reg: audldo {
+               };
+
+               micldo_reg: micldo {
+               };
+
+               usbldo_reg: usbldo {
+               };
+
+               vibldo_reg: vibldo {
+               };
+
+               csr_reg: csr {
+               };
+
+               iosr1_reg: iosr1 {
+               };
+
+               iosr2_reg: iosr2 {
+               };
+
+               msr_reg: msr {
+               };
+
+               sdsr1_reg: sdsr1 {
+               };
+
+               sdsr2_reg: sdsr2 {
+               };
+
+               vsr_reg: vsr {
+               };
+       };
+};
index 187fd46b7b5ef018c2985e7db5298784338f0507..3b891dd209933551b82a36aa04c6213214fb672c 100644 (file)
                                reg = <0x20000 0x80>, <0x800100 0x8>;
                        };
 
+                       sysc: system-ctrl@20000 {
+                               compatible = "marvell,orion-system-controller";
+                               reg = <0x20000 0x110>;
+                       };
+
                        bridge_intc: bridge-interrupt-ctrl@20110 {
                                compatible = "marvell,orion-bridge-intc";
                                interrupt-controller;
                                clocks = <&core_clk 0>;
                        };
 
+                       watchdog@20300 {
+                               compatible = "marvell,orion-wdt";
+                               reg = <0x20300 0x28>, <0x20108 0x4>;
+                               interrupt-parent = <&bridge_intc>;
+                               interrupts = <3>;
+                               clocks = <&core_clk 0>;
+                       };
+
                        crypto: crypto-engine@30000 {
                                compatible = "marvell,orion-crypto";
                                reg = <0x30000 0x10000>,
 
                        pinctrl: pin-ctrl@d0200 {
                                compatible = "marvell,dove-pinctrl";
-                               reg = <0xd0200 0x10>;
+                               reg = <0xd0200 0x14>,
+                                     <0xd0440 0x04>;
                                clocks = <&gate_clk 22>;
 
                                pmx_gpio_0: pmx-gpio-0 {
                                reg = <0xd8500 0x20>;
                        };
 
+                       gconf: global-config@e802c {
+                               compatible = "marvell,dove-global-config",
+                                            "syscon";
+                               reg = <0xe802c 0x14>;
+                       };
+
                        gpio2: gpio-ctrl@e8400 {
                                compatible = "marvell,orion-gpio";
                                #gpio-cells = <2>;
index 1fd75aa4639da23c8e1b05bd1c5e28730f01c791..9e3caf3d19fbcf34187495a14eda3daf17aade4a 100644 (file)
                                1000000 1060000
                                1176000 1160000
                                >;
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
                };
                cpu@1 {
                        device_type = "cpu";
                        ti,hwmods = "wd_timer2";
                };
 
+               hwspinlock: spinlock@4a0f6000 {
+                       compatible = "ti,omap4-hwspinlock";
+                       reg = <0x4a0f6000 0x1000>;
+                       ti,hwmods = "spinlock";
+                       #hwlock-cells = <1>;
+               };
+
+               dmm@4e000000 {
+                       compatible = "ti,omap5-dmm";
+                       reg = <0x4e000000 0x800>;
+                       interrupts = <0 113 0x4>;
+                       ti,hwmods = "dmm";
+               };
+
                i2c1: i2c@48070000 {
                        compatible = "ti,omap4-i2c";
                        reg = <0x48070000 0x100>;
                        status = "disabled";
                };
 
+               abb_mpu: regulator-abb-mpu {
+                       compatible = "ti,abb-v3";
+                       regulator-name = "abb_mpu";
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       clocks = <&sys_clkin1>;
+                       ti,settling-time = <50>;
+                       ti,clock-cycles = <16>;
+
+                       reg = <0x4ae07ddc 0x4>, <0x4ae07de0 0x4>,
+                             <0x4ae06014 0x4>, <0x4a003b20 0x8>,
+                             <0x4ae0c158 0x4>;
+                       reg-names = "setup-address", "control-address",
+                                   "int-address", "efuse-address",
+                                   "ldo-address";
+                       ti,tranxdone-status-mask = <0x80>;
+                       /* LDOVBBMPU_FBB_MUX_CTRL */
+                       ti,ldovbb-override-mask = <0x400>;
+                       /* LDOVBBMPU_FBB_VSET_OUT */
+                       ti,ldovbb-vset-mask = <0x1F>;
+
+                       /*
+                        * NOTE: only FBB mode used but actual vset will
+                        * determine final biasing
+                        */
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m fbb_m     vset_m*/
+                       1060000         0       0x0     0 0x02000000 0x01F00000
+                       1160000         0       0x4     0 0x02000000 0x01F00000
+                       1210000         0       0x8     0 0x02000000 0x01F00000
+                       >;
+               };
+
+               abb_ivahd: regulator-abb-ivahd {
+                       compatible = "ti,abb-v3";
+                       regulator-name = "abb_ivahd";
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       clocks = <&sys_clkin1>;
+                       ti,settling-time = <50>;
+                       ti,clock-cycles = <16>;
+
+                       reg = <0x4ae07e34 0x4>, <0x4ae07e24 0x4>,
+                             <0x4ae06010 0x4>, <0x4a0025cc 0x8>,
+                             <0x4a002470 0x4>;
+                       reg-names = "setup-address", "control-address",
+                                   "int-address", "efuse-address",
+                                   "ldo-address";
+                       ti,tranxdone-status-mask = <0x40000000>;
+                       /* LDOVBBIVA_FBB_MUX_CTRL */
+                       ti,ldovbb-override-mask = <0x400>;
+                       /* LDOVBBIVA_FBB_VSET_OUT */
+                       ti,ldovbb-vset-mask = <0x1F>;
+
+                       /*
+                        * NOTE: only FBB mode used but actual vset will
+                        * determine final biasing
+                        */
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m fbb_m     vset_m*/
+                       1055000         0       0x0     0 0x02000000 0x01F00000
+                       1150000         0       0x4     0 0x02000000 0x01F00000
+                       1250000         0       0x8     0 0x02000000 0x01F00000
+                       >;
+               };
+
+               abb_dspeve: regulator-abb-dspeve {
+                       compatible = "ti,abb-v3";
+                       regulator-name = "abb_dspeve";
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       clocks = <&sys_clkin1>;
+                       ti,settling-time = <50>;
+                       ti,clock-cycles = <16>;
+
+                       reg = <0x4ae07e30 0x4>, <0x4ae07e20 0x4>,
+                             <0x4ae06010 0x4>, <0x4a0025e0 0x8>,
+                             <0x4a00246c 0x4>;
+                       reg-names = "setup-address", "control-address",
+                                   "int-address", "efuse-address",
+                                   "ldo-address";
+                       ti,tranxdone-status-mask = <0x20000000>;
+                       /* LDOVBBDSPEVE_FBB_MUX_CTRL */
+                       ti,ldovbb-override-mask = <0x400>;
+                       /* LDOVBBDSPEVE_FBB_VSET_OUT */
+                       ti,ldovbb-vset-mask = <0x1F>;
+
+                       /*
+                        * NOTE: only FBB mode used but actual vset will
+                        * determine final biasing
+                        */
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m fbb_m     vset_m*/
+                       1055000         0       0x0     0 0x02000000 0x01F00000
+                       1150000         0       0x4     0 0x02000000 0x01F00000
+                       1250000         0       0x8     0 0x02000000 0x01F00000
+                       >;
+               };
+
+               abb_gpu: regulator-abb-gpu {
+                       compatible = "ti,abb-v3";
+                       regulator-name = "abb_gpu";
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       clocks = <&sys_clkin1>;
+                       ti,settling-time = <50>;
+                       ti,clock-cycles = <16>;
+
+                       reg = <0x4ae07de4 0x4>, <0x4ae07de8 0x4>,
+                             <0x4ae06010 0x4>, <0x4a003b08 0x8>,
+                             <0x4ae0c154 0x4>;
+                       reg-names = "setup-address", "control-address",
+                                   "int-address", "efuse-address",
+                                   "ldo-address";
+                       ti,tranxdone-status-mask = <0x10000000>;
+                       /* LDOVBBGPU_FBB_MUX_CTRL */
+                       ti,ldovbb-override-mask = <0x400>;
+                       /* LDOVBBGPU_FBB_VSET_OUT */
+                       ti,ldovbb-vset-mask = <0x1F>;
+
+                       /*
+                        * NOTE: only FBB mode used but actual vset will
+                        * determine final biasing
+                        */
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m fbb_m     vset_m*/
+                       1090000         0       0x0     0 0x02000000 0x01F00000
+                       1210000         0       0x4     0 0x02000000 0x01F00000
+                       1280000         0       0x8     0 0x02000000 0x01F00000
+                       >;
+               };
+
                mcspi1: spi@48098000 {
                        compatible = "ti,omap4-mcspi";
                        reg = <0x48098000 0x200>;
index aa5c0f6363d6cec92f5556cef929849484b75b2a..b4031fa4a567610b2a58086f98bddfaf253e77bd 100644 (file)
@@ -26,7 +26,7 @@
                };
 
                i2c@4000a000 {
-                       location = <3>;
+                       efm32,location = <3>;
                        status = "ok";
 
                        temp@48 {
index a342ab0e6e4f9098df459d0824c3dafa21868075..106d505c5d3d816fb096ab6c5e2e23843e134bfd 100644 (file)
@@ -84,7 +84,7 @@
                        status = "disabled";
                };
 
-               spi2: spi@40x4000c800 { /* USART2 */
+               spi2: spi@4000c800 { /* USART2 */
                        #address-cells = <1>;
                        #size-cells = <0>;
                        compatible = "efm32,spi";
                        status = "disabled";
                };
 
-               uart2: uart@40x4000c800 { /* USART2 */
+               uart2: uart@4000c800 { /* USART2 */
                        compatible = "efm32,uart";
                        reg = <0x4000c800 0x400>;
                        interrupts = <18 19>;
index 08452e183b57a642581d37fdff11f5d0f651a4db..0401f4dba2a226717bce178e34268a69a163be73 100644 (file)
@@ -19,6 +19,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <dt-bindings/clock/exynos4.h>
 #include "skeleton.dtsi"
 
 / {
                reg = <0x10023CE0 0x20>;
        };
 
+       pd_gps_alive: gps-alive-power-domain@10023D00 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10023D00 0x20>;
+       };
+
        gic: interrupt-controller@10490000 {
                compatible = "arm,cortex-a9-gic";
                #interrupt-cells = <3>;
                        compatible = "samsung,exynos4210-fimc";
                        reg = <0x11800000 0x1000>;
                        interrupts = <0 84 0>;
-                       clocks = <&clock 256>, <&clock 128>;
+                       clocks = <&clock CLK_FIMC0>, <&clock CLK_SCLK_FIMC0>;
                        clock-names = "fimc", "sclk_fimc";
                        samsung,power-domain = <&pd_cam>;
                        samsung,sysreg = <&sys_reg>;
                        compatible = "samsung,exynos4210-fimc";
                        reg = <0x11810000 0x1000>;
                        interrupts = <0 85 0>;
-                       clocks = <&clock 257>, <&clock 129>;
+                       clocks = <&clock CLK_FIMC1>, <&clock CLK_SCLK_FIMC1>;
                        clock-names = "fimc", "sclk_fimc";
                        samsung,power-domain = <&pd_cam>;
                        samsung,sysreg = <&sys_reg>;
                        compatible = "samsung,exynos4210-fimc";
                        reg = <0x11820000 0x1000>;
                        interrupts = <0 86 0>;
-                       clocks = <&clock 258>, <&clock 130>;
+                       clocks = <&clock CLK_FIMC2>, <&clock CLK_SCLK_FIMC2>;
                        clock-names = "fimc", "sclk_fimc";
                        samsung,power-domain = <&pd_cam>;
                        samsung,sysreg = <&sys_reg>;
                        compatible = "samsung,exynos4210-fimc";
                        reg = <0x11830000 0x1000>;
                        interrupts = <0 87 0>;
-                       clocks = <&clock 259>, <&clock 131>;
+                       clocks = <&clock CLK_FIMC3>, <&clock CLK_SCLK_FIMC3>;
                        clock-names = "fimc", "sclk_fimc";
                        samsung,power-domain = <&pd_cam>;
                        samsung,sysreg = <&sys_reg>;
                        compatible = "samsung,exynos4210-csis";
                        reg = <0x11880000 0x4000>;
                        interrupts = <0 78 0>;
-                       clocks = <&clock 260>, <&clock 134>;
+                       clocks = <&clock CLK_CSIS0>, <&clock CLK_SCLK_CSIS0>;
                        clock-names = "csis", "sclk_csis";
                        bus-width = <4>;
                        samsung,power-domain = <&pd_cam>;
                        compatible = "samsung,exynos4210-csis";
                        reg = <0x11890000 0x4000>;
                        interrupts = <0 80 0>;
-                       clocks = <&clock 261>, <&clock 135>;
+                       clocks = <&clock CLK_CSIS1>, <&clock CLK_SCLK_CSIS1>;
                        clock-names = "csis", "sclk_csis";
                        bus-width = <2>;
                        samsung,power-domain = <&pd_cam>;
                compatible = "samsung,s3c2410-wdt";
                reg = <0x10060000 0x100>;
                interrupts = <0 43 0>;
-               clocks = <&clock 345>;
+               clocks = <&clock CLK_WDT>;
                clock-names = "watchdog";
                status = "disabled";
        };
                compatible = "samsung,s3c6410-rtc";
                reg = <0x10070000 0x100>;
                interrupts = <0 44 0>, <0 45 0>;
-               clocks = <&clock 346>;
+               clocks = <&clock CLK_RTC>;
                clock-names = "rtc";
                status = "disabled";
        };
                compatible = "samsung,s5pv210-keypad";
                reg = <0x100A0000 0x100>;
                interrupts = <0 109 0>;
-               clocks = <&clock 347>;
+               clocks = <&clock CLK_KEYIF>;
                clock-names = "keypad";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12510000 0x100>;
                interrupts = <0 73 0>;
-               clocks = <&clock 297>, <&clock 145>;
+               clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
                clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12520000 0x100>;
                interrupts = <0 74 0>;
-               clocks = <&clock 298>, <&clock 146>;
+               clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
                clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12530000 0x100>;
                interrupts = <0 75 0>;
-               clocks = <&clock 299>, <&clock 147>;
+               clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
                clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12540000 0x100>;
                interrupts = <0 76 0>;
-               clocks = <&clock 300>, <&clock 148>;
+               clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
                clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-ehci";
                reg = <0x12580000 0x100>;
                interrupts = <0 70 0>;
-               clocks = <&clock 304>;
+               clocks = <&clock CLK_USB_HOST>;
                clock-names = "usbhost";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-ohci";
                reg = <0x12590000 0x100>;
                interrupts = <0 70 0>;
-               clocks = <&clock 304>;
+               clocks = <&clock CLK_USB_HOST>;
                clock-names = "usbhost";
                status = "disabled";
        };
                reg = <0x13400000 0x10000>;
                interrupts = <0 94 0>;
                samsung,power-domain = <&pd_mfc>;
-               clocks = <&clock 273>;
+               clocks = <&clock CLK_MFC>;
                clock-names = "mfc";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-uart";
                reg = <0x13800000 0x100>;
                interrupts = <0 52 0>;
-               clocks = <&clock 312>, <&clock 151>;
+               clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
                clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-uart";
                reg = <0x13810000 0x100>;
                interrupts = <0 53 0>;
-               clocks = <&clock 313>, <&clock 152>;
+               clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
                clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-uart";
                reg = <0x13820000 0x100>;
                interrupts = <0 54 0>;
-               clocks = <&clock 314>, <&clock 153>;
+               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
                compatible = "samsung,exynos4210-uart";
                reg = <0x13830000 0x100>;
                interrupts = <0 55 0>;
-               clocks = <&clock 315>, <&clock 154>;
+               clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
                clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13860000 0x100>;
                interrupts = <0 58 0>;
-               clocks = <&clock 317>;
+               clocks = <&clock CLK_I2C0>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c0_bus>;
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13870000 0x100>;
                interrupts = <0 59 0>;
-               clocks = <&clock 318>;
+               clocks = <&clock CLK_I2C1>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c1_bus>;
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13880000 0x100>;
                interrupts = <0 60 0>;
-               clocks = <&clock 319>;
+               clocks = <&clock CLK_I2C2>;
                clock-names = "i2c";
                status = "disabled";
        };
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13890000 0x100>;
                interrupts = <0 61 0>;
-               clocks = <&clock 320>;
+               clocks = <&clock CLK_I2C3>;
                clock-names = "i2c";
                status = "disabled";
        };
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138A0000 0x100>;
                interrupts = <0 62 0>;
-               clocks = <&clock 321>;
+               clocks = <&clock CLK_I2C4>;
                clock-names = "i2c";
                status = "disabled";
        };
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138B0000 0x100>;
                interrupts = <0 63 0>;
-               clocks = <&clock 322>;
+               clocks = <&clock CLK_I2C5>;
                clock-names = "i2c";
                status = "disabled";
        };
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138C0000 0x100>;
                interrupts = <0 64 0>;
-               clocks = <&clock 323>;
+               clocks = <&clock CLK_I2C6>;
                clock-names = "i2c";
                status = "disabled";
        };
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138D0000 0x100>;
                interrupts = <0 65 0>;
-               clocks = <&clock 324>;
+               clocks = <&clock CLK_I2C7>;
                clock-names = "i2c";
                status = "disabled";
        };
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 327>, <&clock 159>;
+               clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
                clock-names = "spi", "spi_busclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&spi0_bus>;
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 328>, <&clock 160>;
+               clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
                clock-names = "spi", "spi_busclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&spi1_bus>;
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 329>, <&clock 161>;
+               clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
                clock-names = "spi", "spi_busclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&spi2_bus>;
                compatible = "samsung,exynos4210-pwm";
                reg = <0x139D0000 0x1000>;
                interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
-               clocks = <&clock 336>;
+               clocks = <&clock CLK_PWM>;
                clock-names = "timers";
                #pwm-cells = <2>;
                status = "disabled";
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12680000 0x1000>;
                        interrupts = <0 35 0>;
-                       clocks = <&clock 292>;
+                       clocks = <&clock CLK_PDMA0>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12690000 0x1000>;
                        interrupts = <0 36 0>;
-                       clocks = <&clock 293>;
+                       clocks = <&clock CLK_PDMA1>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12850000 0x1000>;
                        interrupts = <0 34 0>;
-                       clocks = <&clock 279>;
+                       clocks = <&clock CLK_MDMA>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                reg = <0x11c00000 0x20000>;
                interrupt-names = "fifo", "vsync", "lcd_sys";
                interrupts = <11 0>, <11 1>, <11 2>;
-               clocks = <&clock 140>, <&clock 283>;
+               clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
                clock-names = "sclk_fimd", "fimd";
                samsung,power-domain = <&pd_lcd0>;
                status = "disabled";
index 2aa13cb3bbed00053c910ddae2246ebf426cdd29..72fb11f7ea213038c789e40e431c3268673da033 100644 (file)
@@ -19,7 +19,7 @@
 
 / {
        model = "Insignal Origen evaluation board based on Exynos4210";
-       compatible = "insignal,origen", "samsung,exynos4210";
+       compatible = "insignal,origen", "samsung,exynos4210", "samsung,exynos4";
 
        memory {
                reg = <0x40000000 0x10000000
index 9c01b718d29de58bc6dfda6cad014d8ea121fc59..636d16684750e4f342048d3bf3207a8929581b42 100644 (file)
@@ -19,7 +19,7 @@
 
 / {
        model = "Samsung smdkv310 evaluation board based on Exynos4210";
-       compatible = "samsung,smdkv310", "samsung,exynos4210";
+       compatible = "samsung,smdkv310", "samsung,exynos4210", "samsung,exynos4";
 
        memory {
                reg = <0x40000000 0x80000000>;
index 63cc571ca30794b04f53239efc5f8393af8f3022..361cb58052bf28990285275222e6fd9b1c095148 100644 (file)
@@ -17,7 +17,7 @@
 
 / {
        model = "Samsung Trats based on Exynos4210";
-       compatible = "samsung,trats", "samsung,exynos4210";
+       compatible = "samsung,trats", "samsung,exynos4210", "samsung,exynos4";
 
        memory {
                reg =  <0x40000000 0x10000000
index d2e3f5f5916dad4c325ab4dc3f71ff0ef34d9b39..27d3b70ee9e3afa822fba7a925b3693eae38dee4 100644 (file)
@@ -17,7 +17,7 @@
 
 / {
        model = "Samsung Universal C210 based on Exynos4210 rev0";
-       compatible = "samsung,universal_c210", "samsung,exynos4210";
+       compatible = "samsung,universal_c210", "samsung,exynos4210", "samsung,exynos4";
 
        memory {
                reg =  <0x40000000 0x10000000
index 48ecd7a755ab90cdca387a2a8de9898c180bd849..cacf6140dd2f58be5351f797d889d8b0563e461c 100644 (file)
@@ -23,7 +23,7 @@
 #include "exynos4210-pinctrl.dtsi"
 
 / {
-       compatible = "samsung,exynos4210";
+       compatible = "samsung,exynos4210", "samsung,exynos4";
 
        aliases {
                pinctrl0 = &pinctrl_0;
@@ -53,7 +53,7 @@
                reg = <0x10050000 0x800>;
                interrupt-parent = <&mct_map>;
                interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
-               clocks = <&clock 3>, <&clock 344>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                clock-names = "fin_pll", "mct";
 
                mct_map: mct-map {
                interrupt-parent = <&combiner>;
                reg = <0x100C0000 0x100>;
                interrupts = <2 4>;
-               clocks = <&clock 383>;
+               clocks = <&clock CLK_TMU_APBIF>;
                clock-names = "tmu_apbif";
                status = "disabled";
        };
                compatible = "samsung,s5pv210-g2d";
                reg = <0x12800000 0x1000>;
                interrupts = <0 89 0>;
-               clocks = <&clock 177>, <&clock 277>;
+               clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
                clock-names = "sclk_fimg2d", "fimg2d";
                status = "disabled";
        };
 
        camera {
-               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>;
+               clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
+                        <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
                clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
 
                fimc_0: fimc@11800000 {
index 94a43f9a05e2684a4fc311404b4c46d72afe4e4e..3c00e6ec93027f8ca410c1ee39b3b5d3200c3cd7 100644 (file)
 #include "exynos4x12.dtsi"
 
 / {
-       compatible = "samsung,exynos4212";
+       compatible = "samsung,exynos4212", "samsung,exynos4";
 
-       gic: interrupt-controller@10490000 {
-               cpu-offset = <0x8000>;
+       combiner: interrupt-controller@10440000 {
+               samsung,combiner-nr = <18>;
        };
 
-       interrupt-controller@10440000 {
-               samsung,combiner-nr = <18>;
-               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
-                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
-                            <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
-                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
-                            <0 107 0>, <0 108 0>;
+       gic: interrupt-controller@10490000 {
+               cpu-offset = <0x8000>;
        };
 };
index 9804fcb71f8cb22338ffa1ddd92426f3c3bf98f3..31db28a4bb33e86f18233fa8336a3a0cee28ca87 100644 (file)
@@ -16,7 +16,7 @@
 
 / {
        model = "Hardkernel ODROID-X board based on Exynos4412";
-       compatible = "hardkernel,odroid-x", "samsung,exynos4412";
+       compatible = "hardkernel,odroid-x", "samsung,exynos4412", "samsung,exynos4";
 
        memory {
                reg = <0x40000000 0x40000000>;
                                buck2_reg: BUCK2 {
                                        regulator-name = "vdd_arm";
                                        regulator-min-microvolt = <900000>;
-                                       regulator-max-microvolt = <1300000>;
+                                       regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
                                        regulator-boot-on;
                                };
index 6bc053924e9e69a70cc30eca78cd365c5fcafc6a..e2c0dcab4d81d576d417489d9f97ce58228c66dc 100644 (file)
@@ -17,7 +17,7 @@
 
 / {
        model = "Insignal Origen evaluation board based on Exynos4412";
-       compatible = "insignal,origen4412", "samsung,exynos4412";
+       compatible = "insignal,origen4412", "samsung,exynos4412", "samsung,exynos4";
 
        memory {
                reg = <0x40000000 0x40000000>;
 
                                buck2_reg: BUCK2 {
                                        regulator-name = "vdd_arm";
-                                       regulator-min-microvolt = <925000>;
-                                       regulator-max-microvolt = <1300000>;
+                                       regulator-min-microvolt = <900000>;
+                                       regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
                                        regulator-boot-on;
                                        op_mode = <1>; /* Normal Mode */
index ad316a1ee9e09af700d38a435e596f1a64c9f48b..ded0b70f764485bc0ab4fc6e4cc23f895b509f4b 100644 (file)
@@ -17,7 +17,7 @@
 
 / {
        model = "Samsung SMDK evaluation board based on Exynos4412";
-       compatible = "samsung,smdk4412", "samsung,exynos4412";
+       compatible = "samsung,smdk4412", "samsung,exynos4412", "samsung,exynos4";
 
        memory {
                reg = <0x40000000 0x40000000>;
index 0a9831256b33308e6f5b6bb97147df2c532b1736..ea6929d9c6212ff75943df09cee7fb49cc196020 100644 (file)
@@ -16,7 +16,7 @@
 
 / {
        model = "FriendlyARM TINY4412 board based on Exynos4412";
-       compatible = "friendlyarm,tiny4412", "samsung,exynos4412";
+       compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
 
        memory {
                reg = <0x40000000 0x40000000>;
index 4f851ccf40eb48831ebb78474dd458eebf873b58..c16b3159b8138a4d0d0222114d638c77e1184227 100644 (file)
@@ -17,7 +17,7 @@
 
 / {
        model = "Samsung Trats 2 based on Exynos4412";
-       compatible = "samsung,trats2", "samsung,exynos4412";
+       compatible = "samsung,trats2", "samsung,exynos4412", "samsung,exynos4";
 
        aliases {
                i2c8 = &i2c_ak8975;
                };
        };
 
+       adc: adc@126C0000 {
+               vdd-supply = <&ldo3_reg>;
+               status = "okay";
+       };
+
        i2c@13890000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-slave-addr = <0x10>;
                        };
                };
        };
+
+       thermistor-ap@0 {
+               compatible = "ntc,ncp15wb473";
+               pullup-uv = <1800000>;   /* VCC_1.8V_AP */
+               pullup-ohm = <100000>;   /* 100K */
+               pulldown-ohm = <100000>; /* 100K */
+               io-channels = <&adc 1>;  /* AP temperature */
+       };
+
+       thermistor-battery@1 {
+               compatible = "ntc,ncp15wb473";
+               pullup-uv = <1800000>;   /* VCC_1.8V_AP */
+               pullup-ohm = <100000>;   /* 100K */
+               pulldown-ohm = <100000>; /* 100K */
+               io-channels = <&adc 2>;  /* Battery temperature */
+       };
 };
index 87b339c739de708beaf5d2ed818e3a424c8fcc7a..15d3c0ac2f5f77d337f4f4c0f1424d9e56e5a350 100644 (file)
 #include "exynos4x12.dtsi"
 
 / {
-       compatible = "samsung,exynos4412";
+       compatible = "samsung,exynos4412", "samsung,exynos4";
 
-       gic: interrupt-controller@10490000 {
-               cpu-offset = <0x4000>;
-       };
-
-       interrupt-controller@10440000 {
+       combiner: interrupt-controller@10440000 {
                samsung,combiner-nr = <20>;
-               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
-                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
-                            <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
-                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
-                            <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
        };
 
+       gic: interrupt-controller@10490000 {
+               cpu-offset = <0x4000>;
+       };
 };
index 5c412aa147382fb44ba6be6333f5d08485d28b5f..c4a9306f8529ab84ce3836781d1795b83c735e15 100644 (file)
                mshc0 = &mshc_0;
        };
 
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupt-parent = <&combiner>;
+               interrupts = <2 2>, <3 2>, <18 2>, <19 2>;
+       };
+
        pd_isp: isp-power-domain@10023CA0 {
                compatible = "samsung,exynos4210-pd";
                reg = <0x10023CA0 0x20>;
@@ -47,7 +53,7 @@
                reg = <0x10050000 0x800>;
                interrupt-parent = <&mct_map>;
                interrupts = <0>, <1>, <2>, <3>, <4>;
-               clocks = <&clock 3>, <&clock 344>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                clock-names = "fin_pll", "mct";
 
                mct_map: mct-map {
                };
        };
 
+       combiner: interrupt-controller@10440000 {
+               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+                            <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+                            <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
+       };
+
        pinctrl_0: pinctrl@11400000 {
                compatible = "samsung,exynos4x12-pinctrl";
                reg = <0x11400000 0x1000>;
                };
        };
 
+       adc: adc@126C0000 {
+               compatible = "samsung,exynos-adc-v1";
+               reg = <0x126C0000 0x100>, <0x10020718 0x4>;
+               interrupt-parent = <&combiner>;
+               interrupts = <10 3>;
+               clocks = <&clock CLK_TSADC>;
+               clock-names = "adc";
+               #io-channel-cells = <1>;
+               io-channel-ranges;
+               status = "disabled";
+       };
+
        pinctrl_2: pinctrl@03860000 {
                compatible = "samsung,exynos4x12-pinctrl";
                reg = <0x03860000 0x1000>;
                compatible = "samsung,exynos4212-g2d";
                reg = <0x10800000 0x1000>;
                interrupts = <0 89 0>;
-               clocks = <&clock 177>, <&clock 277>;
+               clocks = <&clock CLK_SCLK_FIMG2D>, <&clock CLK_G2D>;
                clock-names = "sclk_fimg2d", "fimg2d";
                status = "disabled";
        };
 
        camera {
-               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>;
+               clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
+                        <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
                clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
 
                fimc_0: fimc@11800000 {
                        reg = <0x12390000 0x1000>;
                        interrupts = <0 105 0>;
                        samsung,power-domain = <&pd_isp>;
-                       clocks = <&clock 353>;
+                       clocks = <&clock CLK_FIMC_LITE0>;
                        clock-names = "flite";
                        status = "disabled";
                };
                        reg = <0x123A0000 0x1000>;
                        interrupts = <0 106 0>;
                        samsung,power-domain = <&pd_isp>;
-                       clocks = <&clock 354>;
+                       clocks = <&clock CLK_FIMC_LITE1>;
                        clock-names = "flite";
                        status = "disabled";
                };
                        reg = <0x12000000 0x260000>;
                        interrupts = <0 90 0>, <0 95 0>;
                        samsung,power-domain = <&pd_isp>;
-                       clocks = <&clock 353>, <&clock 354>, <&clock 355>,
-                               <&clock 356>, <&clock 17>, <&clock 357>,
-                               <&clock 358>, <&clock 359>, <&clock 360>,
-                               <&clock 450>,<&clock 451>, <&clock 452>,
-                               <&clock 453>, <&clock 176>, <&clock 13>,
-                               <&clock 454>, <&clock 395>, <&clock 455>;
+                       clocks = <&clock CLK_FIMC_LITE0>,
+                                <&clock CLK_FIMC_LITE1>, <&clock CLK_PPMUISPX>,
+                                <&clock CLK_PPMUISPMX>,
+                                <&clock CLK_MOUT_MPLL_USER_T>,
+                                <&clock CLK_FIMC_ISP>, <&clock CLK_FIMC_DRC>,
+                                <&clock CLK_FIMC_FD>, <&clock CLK_MCUISP>,
+                                <&clock CLK_DIV_ISP0>,<&clock CLK_DIV_ISP1>,
+                                <&clock CLK_DIV_MCUISP0>,
+                                <&clock CLK_DIV_MCUISP1>,
+                                <&clock CLK_SCLK_UART_ISP>,
+                                <&clock CLK_ACLK200>, <&clock CLK_DIV_ACLK200>,
+                                <&clock CLK_ACLK400_MCUISP>,
+                                <&clock CLK_DIV_ACLK400_MCUISP>;
                        clock-names = "lite0", "lite1", "ppmuispx",
                                      "ppmuispmx", "mpll", "isp",
                                      "drc", "fd", "mcuisp",
                        i2c1_isp: i2c-isp@12140000 {
                                compatible = "samsung,exynos4212-i2c-isp";
                                reg = <0x12140000 0x100>;
-                               clocks = <&clock 370>;
+                               clocks = <&clock CLK_I2C1_ISP>;
                                clock-names = "i2c_isp";
                                #address-cells = <1>;
                                #size-cells = <0>;
                #address-cells = <1>;
                #size-cells = <0>;
                fifo-depth = <0x80>;
-               clocks = <&clock 301>, <&clock 149>;
+               clocks = <&clock CLK_SDMMC4>, <&clock CLK_SCLK_MMC4>;
                clock-names = "biu", "ciu";
                status = "disabled";
        };
index 258dca441f36c9991152ab75403a2f4056699349..79d0608d6dcc44ae895251086a665afcde2cf2e9 100644 (file)
                status = "disabled";
        };
 
-       watchdog {
-               compatible = "samsung,s3c2410-wdt";
-               reg = <0x101D0000 0x100>;
-               interrupts = <0 42 0>;
-               status = "disabled";
-       };
-
        fimd@14400000 {
                compatible = "samsung,exynos5250-fimd";
                interrupt-parent = <&combiner>;
index b42e658876e5f0f3313e8ca07c3e19c55fa92924..090f9830b129b72259e4976be890917182b8a6f5 100644 (file)
@@ -15,7 +15,7 @@
 
 / {
        model = "Insignal Arndale evaluation board based on EXYNOS5250";
-       compatible = "insignal,arndale", "samsung,exynos5250";
+       compatible = "insignal,arndale", "samsung,exynos5250", "samsung,exynos5";
 
        memory {
                reg = <0x40000000 0x80000000>;
                bootargs = "console=ttySAC2,115200";
        };
 
+       rtc@101E0000 {
+               status = "okay";
+       };
+
        codec@11000000 {
                samsung,mfc-r = <0x43000000 0x800000>;
                samsung,mfc-l = <0x51000000 0x800000>;
                                        regulator-name = "vdd_g3d";
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
                                        regulator-boot-on;
                                        op_mode = <1>;
                                };
                };
        };
 
+       i2c@121D0000 {
+               status = "okay";
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <40000>;
+               samsung,i2c-slave-addr = <0x38>;
+
+               sata_phy_i2c:sata-phy@38 {
+                       compatible = "samsung,exynos-sataphy-i2c";
+                       reg = <0x38>;
+               };
+       };
+
+       sata@122F0000 {
+               status = "okay";
+       };
+
+       sata-phy@12170000 {
+               status = "okay";
+               samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+       };
+
        mmc_0: mmc@12200000 {
                status = "okay";
                num-slots = <1>;
index 3e69837c435c6b49ca81643f9717ae78d16a2403..a794a705d4040ec220c7b380e09dbc83a9193025 100644 (file)
@@ -14,7 +14,7 @@
 
 / {
        model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
-       compatible = "samsung,smdk5250", "samsung,exynos5250";
+       compatible = "samsung,smdk5250", "samsung,exynos5250", "samsung,exynos5";
 
        aliases {
        };
                bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
        };
 
+       rtc@101E0000 {
+               status = "okay";
+       };
+
        i2c@12C60000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <20000>;
                        compatible = "samsung,s524ad0xd1";
                        reg = <0x50>;
                };
+
+               max77686@09 {
+                       compatible = "maxim,max77686";
+                       reg = <0x09>;
+
+                       voltage-regulators {
+                               ldo1_reg: LDO1 {
+                                       regulator-name = "P1.0V_LDO_OUT1";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo2_reg: LDO2 {
+                                       regulator-name = "P1.2V_LDO_OUT2";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "P1.8V_LDO_OUT3";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo4_reg: LDO4 {
+                                       regulator-name = "P2.8V_LDO_OUT4";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo5_reg: LDO5 {
+                                       regulator-name = "P1.8V_LDO_OUT5";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo6_reg: LDO6 {
+                                       regulator-name = "P1.1V_LDO_OUT6";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "P1.1V_LDO_OUT7";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "P1.0V_LDO_OUT8";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "P1.8V_LDO_OUT10";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo11_reg: LDO11 {
+                                       regulator-name = "P1.8V_LDO_OUT11";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "P3.0V_LDO_OUT12";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                               };
+
+                               ldo13_reg: LDO13 {
+                                       regulator-name = "P1.8V_LDO_OUT13";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo14_reg: LDO14 {
+                                       regulator-name = "P1.8V_LDO_OUT14";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "P1.0V_LDO_OUT15";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "P1.8V_LDO_OUT16";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "vdd_mif";
+                                       regulator-min-microvolt = <950000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vdd_arm";
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "vdd_int";
+                                       regulator-min-microvolt = <900000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "vdd_g3d";
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck5_reg: BUCK5 {
+                                       regulator-name = "P1.8V_BUCK_OUT5";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+                       };
+               };
        };
 
        vdd: fixed-regulator@0 {
                samsung,i2c-slave-addr = <0x38>;
                status = "okay";
 
-               sata-phy {
-                       compatible = "samsung,sata-phy";
+               sata_phy_i2c:sata-phy@38 {
+                       compatible = "samsung,exynos-sataphy-i2c";
                        reg = <0x38>;
                };
        };
 
-       sata@122F0000 {
-               samsung,sata-freq = <66>;
-       };
-
        i2c@12C80000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <66000>;
                };
        };
 
+       sata@122F0000 {
+               status = "okay";
+       };
+
+       sata-phy@12170000 {
+               status = "okay";
+               samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+       };
+
        mmc@12200000 {
                status = "okay";
                num-slots = <1>;
                };
        };
 
-       spi_0: spi@12d20000 {
-               status = "disabled";
-       };
-
        spi_1: spi@12d30000 {
                status = "okay";
 
index 7e45eea2d78f1a29670342272dfe950a812d5209..1ce1088a00fb5828e168888fcc0bab677cb1844f 100644 (file)
 
 / {
        model = "Google Snow";
-       compatible = "google,snow", "samsung,exynos5250";
+       compatible = "google,snow", "samsung,exynos5250", "samsung,exynos5";
 
        aliases {
                i2c104 = &i2c_104;
        };
 
+       rtc@101E0000 {
+               status = "okay";
+       };
+
        pinctrl@11400000 {
                sd3_clk: sd3-clk {
                        samsung,pin-drv = <0>;
index b7dec41e32afd7ac6cce4d02022b0929b98aacac..37423314a02826a66670776c03109f1526449bc7 100644 (file)
  * published by the Free Software Foundation.
 */
 
+#include <dt-bindings/clock/exynos5250.h>
 #include "exynos5.dtsi"
 #include "exynos5250-pinctrl.dtsi"
 
-#include <dt-bindings/clk/exynos-audss-clk.h>
+#include <dt-bindings/clock/exynos-audss-clk.h>
 
 / {
-       compatible = "samsung,exynos5250";
+       compatible = "samsung,exynos5250", "samsung,exynos5";
 
        aliases {
                spi0 = &spi_0;
@@ -46,6 +47,7 @@
                i2c6 = &i2c_6;
                i2c7 = &i2c_7;
                i2c8 = &i2c_8;
+               i2c9 = &i2c_9;
                pinctrl0 = &pinctrl_0;
                pinctrl1 = &pinctrl_1;
                pinctrl2 = &pinctrl_2;
@@ -90,7 +92,8 @@
                compatible = "samsung,exynos5250-audss-clock";
                reg = <0x03810000 0x0C>;
                #clock-cells = <1>;
-               clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
+                        <&clock CLK_SCLK_AUDIO0>, <&clock CLK_DIV_PCM0>;
                clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
        };
 
                interrupt-parent = <&mct_map>;
                interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
                             <4 0>, <5 0>;
-               clocks = <&clock 1>, <&clock 335>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                clock-names = "fin_pll", "mct";
 
                mct_map: mct-map {
                interrupts = <0 47 0>;
        };
 
-       watchdog {
-               clocks = <&clock 336>;
+       pmu_system_controller: system-controller@10040000 {
+               compatible = "samsung,exynos5250-pmu", "syscon";
+               reg = <0x10040000 0x5000>;
+       };
+
+       watchdog@101D0000 {
+               compatible = "samsung,exynos5250-wdt";
+               reg = <0x101D0000 0x100>;
+               interrupts = <0 42 0>;
+               clocks = <&clock CLK_WDT>;
                clock-names = "watchdog";
+               samsung,syscon-phandle = <&pmu_system_controller>;
        };
 
        g2d@10850000 {
                compatible = "samsung,exynos5250-g2d";
                reg = <0x10850000 0x1000>;
                interrupts = <0 91 0>;
-               clocks = <&clock 345>;
+               clocks = <&clock CLK_G2D>;
                clock-names = "fimg2d";
        };
 
                reg = <0x11000000 0x10000>;
                interrupts = <0 96 0>;
                samsung,power-domain = <&pd_mfc>;
-               clocks = <&clock 266>;
+               clocks = <&clock CLK_MFC>;
                clock-names = "mfc";
        };
 
        rtc@101E0000 {
-               clocks = <&clock 337>;
+               clocks = <&clock CLK_RTC>;
                clock-names = "rtc";
-               status = "okay";
+               status = "disabled";
        };
 
        tmu@10060000 {
                compatible = "samsung,exynos5250-tmu";
                reg = <0x10060000 0x100>;
                interrupts = <0 65 0>;
-               clocks = <&clock 338>;
+               clocks = <&clock CLK_TMU>;
                clock-names = "tmu_apbif";
        };
 
        serial@12C00000 {
-               clocks = <&clock 289>, <&clock 146>;
+               clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C10000 {
-               clocks = <&clock 290>, <&clock 147>;
+               clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C20000 {
-               clocks = <&clock 291>, <&clock 148>;
+               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C30000 {
-               clocks = <&clock 292>, <&clock 149>;
+               clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        sata@122F0000 {
-               compatible = "samsung,exynos5-sata-ahci";
+               compatible = "snps,dwc-ahci";
+               samsung,sata-freq = <66>;
                reg = <0x122F0000 0x1ff>;
                interrupts = <0 115 0>;
-               clocks = <&clock 277>, <&clock 143>;
+               clocks = <&clock CLK_SATA>, <&clock CLK_SCLK_SATA>;
                clock-names = "sata", "sclk_sata";
+               phys = <&sata_phy>;
+               phy-names = "sata-phy";
+               status = "disabled";
        };
 
-       sata-phy@12170000 {
-               compatible = "samsung,exynos5-sata-phy";
+       sata_phy: sata-phy@12170000 {
+               compatible = "samsung,exynos5250-sata-phy";
                reg = <0x12170000 0x1ff>;
+               clocks = <&clock 287>;
+               clock-names = "sata_phyctrl";
+               #phy-cells = <0>;
+               samsung,syscon-phandle = <&pmu_system_controller>;
+               status = "disabled";
        };
 
        i2c_0: i2c@12C60000 {
                interrupts = <0 56 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 294>;
+               clocks = <&clock CLK_I2C0>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c0_bus>;
                interrupts = <0 57 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 295>;
+               clocks = <&clock CLK_I2C1>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c1_bus>;
                interrupts = <0 58 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 296>;
+               clocks = <&clock CLK_I2C2>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c2_bus>;
                interrupts = <0 59 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 297>;
+               clocks = <&clock CLK_I2C3>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c3_bus>;
                interrupts = <0 60 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 298>;
+               clocks = <&clock CLK_I2C4>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c4_bus>;
                interrupts = <0 61 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 299>;
+               clocks = <&clock CLK_I2C5>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c5_bus>;
                interrupts = <0 62 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 300>;
+               clocks = <&clock CLK_I2C6>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c6_bus>;
                interrupts = <0 63 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 301>;
+               clocks = <&clock CLK_I2C7>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c7_bus>;
                interrupts = <0 64 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 302>;
+               clocks = <&clock CLK_I2C_HDMI>;
                clock-names = "i2c";
                status = "disabled";
        };
 
-       i2c@121D0000 {
+       i2c_9: i2c@121D0000 {
                 compatible = "samsung,exynos5-sata-phy-i2c";
                 reg = <0x121D0000 0x100>;
                 #address-cells = <1>;
                 #size-cells = <0>;
-               clocks = <&clock 288>;
+               clocks = <&clock CLK_SATA_PHYI2C>;
                clock-names = "i2c";
                status = "disabled";
        };
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 304>, <&clock 154>;
+               clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
                clock-names = "spi", "spi_busclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&spi0_bus>;
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 305>, <&clock 155>;
+               clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
                clock-names = "spi", "spi_busclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&spi1_bus>;
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 306>, <&clock 156>;
+               clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
                clock-names = "spi", "spi_busclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&spi2_bus>;
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x12200000 0x1000>;
-               clocks = <&clock 280>, <&clock 139>;
+               clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x80>;
                status = "disabled";
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x12210000 0x1000>;
-               clocks = <&clock 281>, <&clock 140>;
+               clocks = <&clock CLK_SDMMC1>, <&clock CLK_SCLK_MMC1>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x80>;
                status = "disabled";
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x12220000 0x1000>;
-               clocks = <&clock 282>, <&clock 141>;
+               clocks = <&clock CLK_SDMMC2>, <&clock CLK_SCLK_MMC2>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x80>;
                status = "disabled";
                interrupts = <0 78 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 283>, <&clock 142>;
+               clocks = <&clock CLK_SDMMC3>, <&clock CLK_SCLK_MMC3>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x80>;
                status = "disabled";
                dmas = <&pdma1 12
                        &pdma1 11>;
                dma-names = "tx", "rx";
-               clocks = <&clock 307>, <&clock 157>;
+               clocks = <&clock CLK_I2S1>, <&clock CLK_DIV_I2S1>;
                clock-names = "iis", "i2s_opclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&i2s1_bus>;
                dmas = <&pdma0 12
                        &pdma0 11>;
                dma-names = "tx", "rx";
-               clocks = <&clock 308>, <&clock 158>;
+               clocks = <&clock CLK_I2S2>, <&clock CLK_DIV_I2S2>;
                clock-names = "iis", "i2s_opclk0";
                pinctrl-names = "default";
                pinctrl-0 = <&i2s2_bus>;
 
        usb@12000000 {
                compatible = "samsung,exynos5250-dwusb3";
-               clocks = <&clock 286>;
+               clocks = <&clock CLK_USB3>;
                clock-names = "usbdrd30";
                #address-cells = <1>;
                #size-cells = <1>;
        usb3_phy: usbphy@12100000 {
                compatible = "samsung,exynos5250-usb3phy";
                reg = <0x12100000 0x100>;
-               clocks = <&clock 1>, <&clock 286>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_USB3>;
                clock-names = "ext_xtal", "usbdrd30";
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <0x12110000 0x100>;
                interrupts = <0 71 0>;
 
-               clocks = <&clock 285>;
+               clocks = <&clock CLK_USB2>;
                clock-names = "usbhost";
        };
 
                reg = <0x12120000 0x100>;
                interrupts = <0 71 0>;
 
-               clocks = <&clock 285>;
+               clocks = <&clock CLK_USB2>;
                clock-names = "usbhost";
        };
 
        usb2_phy: usbphy@12130000 {
                compatible = "samsung,exynos5250-usb2phy";
                reg = <0x12130000 0x100>;
-               clocks = <&clock 1>, <&clock 285>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_USB2>;
                clock-names = "ext_xtal", "usbhost";
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <0x12dd0000 0x100>;
                samsung,pwm-outputs = <0>, <1>, <2>, <3>;
                #pwm-cells = <3>;
-               clocks = <&clock 311>;
+               clocks = <&clock CLK_PWM>;
                clock-names = "timers";
        };
 
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121A0000 0x1000>;
                        interrupts = <0 34 0>;
-                       clocks = <&clock 275>;
+                       clocks = <&clock CLK_PDMA0>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121B0000 0x1000>;
                        interrupts = <0 35 0>;
-                       clocks = <&clock 276>;
+                       clocks = <&clock CLK_PDMA1>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x10800000 0x1000>;
                        interrupts = <0 33 0>;
-                       clocks = <&clock 346>;
+                       clocks = <&clock CLK_MDMA0>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x11C10000 0x1000>;
                        interrupts = <0 124 0>;
-                       clocks = <&clock 271>;
+                       clocks = <&clock CLK_MDMA1>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                reg = <0x13e00000 0x1000>;
                interrupts = <0 85 0>;
                samsung,power-domain = <&pd_gsc>;
-               clocks = <&clock 256>;
+               clocks = <&clock CLK_GSCL0>;
                clock-names = "gscl";
        };
 
                reg = <0x13e10000 0x1000>;
                interrupts = <0 86 0>;
                samsung,power-domain = <&pd_gsc>;
-               clocks = <&clock 257>;
+               clocks = <&clock CLK_GSCL1>;
                clock-names = "gscl";
        };
 
                reg = <0x13e20000 0x1000>;
                interrupts = <0 87 0>;
                samsung,power-domain = <&pd_gsc>;
-               clocks = <&clock 258>;
+               clocks = <&clock CLK_GSCL2>;
                clock-names = "gscl";
        };
 
                reg = <0x13e30000 0x1000>;
                interrupts = <0 88 0>;
                samsung,power-domain = <&pd_gsc>;
-               clocks = <&clock 259>;
+               clocks = <&clock CLK_GSCL3>;
                clock-names = "gscl";
        };
 
                compatible = "samsung,exynos4212-hdmi";
                reg = <0x14530000 0x70000>;
                interrupts = <0 95 0>;
-               clocks = <&clock 344>, <&clock 136>, <&clock 137>,
-                               <&clock 159>, <&clock 1024>;
+               clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+                        <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
+                        <&clock CLK_MOUT_HDMI>;
                clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
                                "sclk_hdmiphy", "mout_hdmi";
        };
                compatible = "samsung,exynos5250-mixer";
                reg = <0x14450000 0x10000>;
                interrupts = <0 94 0>;
-               clocks = <&clock 343>, <&clock 136>;
+               clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>;
                clock-names = "mixer", "sclk_hdmi";
        };
 
        };
 
        dp-controller@145B0000 {
-               clocks = <&clock 342>;
+               clocks = <&clock CLK_DP>;
                clock-names = "dp";
                phys = <&dp_phy>;
                phy-names = "dp";
        };
 
        fimd@14400000 {
-               clocks = <&clock 133>, <&clock 339>;
+               clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
                clock-names = "sclk_fimd", "fimd";
        };
 
                compatible = "samsung,exynos-adc-v1";
                reg = <0x12D10000 0x100>, <0x10040718 0x4>;
                interrupts = <0 106 0>;
-               clocks = <&clock 303>;
+               clocks = <&clock CLK_ADC>;
                clock-names = "adc";
                #io-channel-cells = <1>;
                io-channel-ranges;
                status = "disabled";
        };
+
+       sss@10830000 {
+               compatible = "samsung,exynos4210-secss";
+               reg = <0x10830000 0x10000>;
+               interrupts = <0 112 0>;
+               clocks = <&clock 348>;
+               clock-names = "secss";
+       };
 };
index 7340745ff979a44d15adb64df82135709524e954..80a3bf4c59865e0403a4197abb5ae6f0bc00d363 100644 (file)
 
 /dts-v1/;
 #include "exynos5420.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
 
 / {
        model = "Insignal Arndale Octa evaluation board based on EXYNOS5420";
-       compatible = "insignal,arndale-octa", "samsung,exynos5420";
+       compatible = "insignal,arndale-octa", "samsung,exynos5420", "samsung,exynos5";
 
        memory {
                reg = <0x20000000 0x80000000>;
                };
        };
 
+       rtc@101E0000 {
+               status = "okay";
+       };
+
        mmc@12200000 {
                status = "okay";
                broken-cd;
@@ -41,6 +47,7 @@
                samsung,dw-mshc-ddr-timing = <0 2>;
                pinctrl-names = "default";
                pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+               vmmc-supply = <&ldo10_reg>;
 
                slot@0 {
                        reg = <0>;
                samsung,dw-mshc-ddr-timing = <1 2>;
                pinctrl-names = "default";
                pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+               vmmc-supply = <&ldo10_reg>;
 
                slot@0 {
                        reg = <0>;
                        bus-width = <4>;
                };
        };
+
+       hsi2c_4: i2c@12CA0000 {
+               status = "okay";
+
+               s2mps11_pmic@66 {
+                       compatible = "samsung,s2mps11-pmic";
+                       reg = <0x66>;
+                       s2mps11,buck2-ramp-delay = <12>;
+                       s2mps11,buck34-ramp-delay = <12>;
+                       s2mps11,buck16-ramp-delay = <12>;
+                       s2mps11,buck6-ramp-enable = <1>;
+                       s2mps11,buck2-ramp-enable = <1>;
+                       s2mps11,buck3-ramp-enable = <1>;
+                       s2mps11,buck4-ramp-enable = <1>;
+
+                       interrupt-parent = <&gpx3>;
+                       interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+
+                       s2mps11_osc: clocks {
+                               #clock-cells = <1>;
+                               clock-output-names = "s2mps11_ap",
+                                               "s2mps11_cp", "s2mps11_bt";
+                       };
+
+                       regulators {
+                               ldo1_reg: LDO1 {
+                                       regulator-name = "PVDD_ALIVE_1V0";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo2_reg: LDO2 {
+                                       regulator-name = "PVDD_APIO_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "PVDD_APIO_MMCON_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo4_reg: LDO4 {
+                                       regulator-name = "PVDD_ADC_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo5_reg: LDO5 {
+                                       regulator-name = "PVDD_PLL_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo6_reg: LDO6 {
+                                       regulator-name = "PVDD_ANAIP_1V0";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "PVDD_ANAIP_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "PVDD_ABB_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo9_reg: LDO9 {
+                                       regulator-name = "PVDD_USB_3V3";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "PVDD_PRE_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo11_reg: LDO11 {
+                                       regulator-name = "PVDD_USB_1V0";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "PVDD_HSIC_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo13_reg: LDO13 {
+                                       regulator-name = "PVDD_APIO_MMCOFF_2V8";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "PVDD_PERI_2V8";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "PVDD_PERI_3V3";
+                                       regulator-min-microvolt = <2200000>;
+                                       regulator-max-microvolt = <2200000>;
+                               };
+
+                               ldo18_reg: LDO18 {
+                                       regulator-name = "PVDD_EMMC_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo19_reg: LDO19 {
+                                       regulator-name = "PVDD_TFLASH_2V8";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo20_reg: LDO20 {
+                                       regulator-name = "PVDD_BTWIFI_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo21_reg: LDO21 {
+                                       regulator-name = "PVDD_CAM1IO_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo23_reg: LDO23 {
+                                       regulator-name = "PVDD_MIFS_1V1";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo24_reg: LDO24 {
+                                       regulator-name = "PVDD_CAM1_AVDD_2V8";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               ldo26_reg: LDO26 {
+                                       regulator-name = "PVDD_CAM0_AF_2V8";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                               };
+
+                               ldo27_reg: LDO27 {
+                                       regulator-name = "PVDD_G3DS_1V0";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                               };
+
+                               ldo28_reg: LDO28 {
+                                       regulator-name = "PVDD_TSP_3V3";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                               };
+
+                               ldo29_reg: LDO29 {
+                                       regulator-name = "PVDD_AUDIO_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo31_reg: LDO31 {
+                                       regulator-name = "PVDD_PERI_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo32_reg: LDO32 {
+                                       regulator-name = "PVDD_LCD_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo33_reg: LDO33 {
+                                       regulator-name = "PVDD_CAM0IO_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               ldo35_reg: LDO35 {
+                                       regulator-name = "PVDD_CAM0_DVDD_1V2";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                               };
+
+                               ldo38_reg: LDO38 {
+                                       regulator-name = "PVDD_CAM0_AVDD_2V8";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "PVDD_MIF_1V1";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vdd_arm";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "PVDD_INT_1V0";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "PVDD_G3D_1V0";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1000000>;
+                               };
+
+                               buck5_reg: BUCK5 {
+                                       regulator-name = "PVDD_LPDDR3_1V2";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               buck6_reg: BUCK6 {
+                                       regulator-name = "PVDD_KFC_1V0";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               buck7_reg: BUCK7 {
+                                       regulator-name = "VIN_LLDO_1V4";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1400000>;
+                                       regulator-always-on;
+                               };
+
+                               buck8_reg: BUCK8 {
+                                       regulator-name = "VIN_MLDO_2V0";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <2000000>;
+                                       regulator-always-on;
+                               };
+
+                               buck9_reg: BUCK9 {
+                                       regulator-name = "VIN_HLDO_3V5";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3500000>;
+                                       regulator-always-on;
+                               };
+
+                               buck10_reg: BUCK10 {
+                                       regulator-name = "PVDD_EMMCF_2V8";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                               };
+                       };
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               wakeup {
+                       label = "SW-TACT1";
+                       gpios = <&gpx2 7 1>;
+                       linux,code = <KEY_WAKEUP>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       amba {
+               mdma1: mdma@11C10000 {
+                       /*
+                        * MDMA1 can support both secure and non-secure
+                        * AXI transactions. When this is enabled in the kernel
+                        * for boards that run in secure mode, we are getting
+                        * imprecise external aborts causing the kernel to oops.
+                        */
+                       status = "disabled";
+               };
+       };
 };
index fb5a1e25c632d3a4cbb3544e5e44ee67a0c1d8aa..69104850eb5ec172b6dcc5bd5256b0f759202abf 100644 (file)
@@ -14,7 +14,7 @@
 
 / {
        model = "Samsung SMDK5420 board based on EXYNOS5420";
-       compatible = "samsung,smdk5420", "samsung,exynos5420";
+       compatible = "samsung,smdk5420", "samsung,exynos5420", "samsung,exynos5";
 
        memory {
                reg = <0x20000000 0x80000000>;
                };
        };
 
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vdd: fixed-regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "vdd-supply";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               dbvdd: fixed-regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "dbvdd-supply";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               spkvdd: fixed-regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "spkvdd-supply";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+       };
+
+       rtc@101E0000 {
+               status = "okay";
+       };
+
        mmc@12200000 {
                status = "okay";
                broken-cd;
                        reg = <0x50>;
                };
        };
+
+       hsi2c_4: i2c@12CA0000 {
+               status = "okay";
+
+               s2mps11_pmic@66 {
+                       compatible = "samsung,s2mps11-pmic";
+                       reg = <0x66>;
+                       s2mps11,buck2-ramp-delay = <12>;
+                       s2mps11,buck34-ramp-delay = <12>;
+                       s2mps11,buck16-ramp-delay = <12>;
+                       s2mps11,buck6-ramp-enable = <1>;
+                       s2mps11,buck2-ramp-enable = <1>;
+                       s2mps11,buck3-ramp-enable = <1>;
+                       s2mps11,buck4-ramp-enable = <1>;
+
+                       s2mps11_osc: clocks {
+                               #clock-cells = <1>;
+                               clock-output-names = "s2mps11_ap",
+                                               "s2mps11_cp", "s2mps11_bt";
+                       };
+
+                       regulators {
+                               ldo1_reg: LDO1 {
+                                       regulator-name = "vdd_ldo1";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "vdd_ldo3";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo5_reg: LDO5 {
+                                       regulator-name = "vdd_ldo5";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo6_reg: LDO6 {
+                                       regulator-name = "vdd_ldo6";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "vdd_ldo7";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "vdd_ldo8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo9_reg: LDO9 {
+                                       regulator-name = "vdd_ldo9";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "vdd_ldo10";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo11_reg: LDO11 {
+                                       regulator-name = "vdd_ldo11";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "vdd_ldo12";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo13_reg: LDO13 {
+                                       regulator-name = "vdd_ldo13";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "vdd_ldo15";
+                                       regulator-min-microvolt = <3100000>;
+                                       regulator-max-microvolt = <3100000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "vdd_ldo16";
+                                       regulator-min-microvolt = <2200000>;
+                                       regulator-max-microvolt = <2200000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo17_reg: LDO17 {
+                                       regulator-name = "tsp_avdd";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo19_reg: LDO19 {
+                                       regulator-name = "vdd_sd";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo24_reg: LDO24 {
+                                       regulator-name = "tsp_io";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "vdd_mif";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vdd_arm";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "vdd_int";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1400000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "vdd_g3d";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1400000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck5_reg: BUCK5 {
+                                       regulator-name = "vdd_mem";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1400000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck6_reg: BUCK6 {
+                                       regulator-name = "vdd_kfc";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck7_reg: BUCK7 {
+                                       regulator-name = "vdd_1.0v_ldo";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck8_reg: BUCK8 {
+                                       regulator-name = "vdd_1.8v_ldo";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck9_reg: BUCK9 {
+                                       regulator-name = "vdd_2.8v_ldo";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3750000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck10_reg: BUCK10 {
+                                       regulator-name = "vdd_vmem";
+                                       regulator-min-microvolt = <2850000>;
+                                       regulator-max-microvolt = <2850000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+                       };
+               };
+       };
 };
index 8db792b26f79c1046523c584c4b2e9c910438d73..c3a9a66c57678f9a5dddd75e11e55be913e3c3c0 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <dt-bindings/clock/exynos5420.h>
 #include "exynos5.dtsi"
 #include "exynos5420-pinctrl.dtsi"
 
-#include <dt-bindings/clk/exynos-audss-clk.h>
+#include <dt-bindings/clock/exynos-audss-clk.h>
 
 / {
-       compatible = "samsung,exynos5420";
+       compatible = "samsung,exynos5420", "samsung,exynos5";
 
        aliases {
                mshc0 = &mmc_0;
                compatible = "samsung,exynos5420-audss-clock";
                reg = <0x03810000 0x0C>;
                #clock-cells = <1>;
-               clocks = <&clock 1>, <&clock 5>, <&clock 148>, <&clock 149>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
+                        <&clock CLK_SCLK_MAUDIO0>, <&clock CLK_SCLK_MAUPCM0>;
                clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
        };
 
                compatible = "samsung,mfc-v7";
                reg = <0x11000000 0x10000>;
                interrupts = <0 96 0>;
-               clocks = <&clock 401>;
+               clocks = <&clock CLK_MFC>;
                clock-names = "mfc";
        };
 
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x12200000 0x2000>;
-               clocks = <&clock 351>, <&clock 132>;
+               clocks = <&clock CLK_MMC0>, <&clock CLK_SCLK_MMC0>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x40>;
                status = "disabled";
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x12210000 0x2000>;
-               clocks = <&clock 352>, <&clock 133>;
+               clocks = <&clock CLK_MMC1>, <&clock CLK_SCLK_MMC1>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x40>;
                status = "disabled";
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x12220000 0x1000>;
-               clocks = <&clock 353>, <&clock 134>;
+               clocks = <&clock CLK_MMC2>, <&clock CLK_SCLK_MMC2>;
                clock-names = "biu", "ciu";
                fifo-depth = <0x40>;
                status = "disabled";
                interrupt-parent = <&mct_map>;
                interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>,
                                <8>, <9>, <10>, <11>;
-               clocks = <&clock 1>, <&clock 315>;
+               clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MCT>;
                clock-names = "fin_pll", "mct";
 
                mct_map: mct-map {
        };
 
        rtc@101E0000 {
-               clocks = <&clock 317>;
+               clocks = <&clock CLK_RTC>;
                clock-names = "rtc";
-               status = "okay";
+               status = "disabled";
        };
 
        amba {
                interrupt-parent = <&gic>;
                ranges;
 
+               adma: adma@03880000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x03880000 0x1000>;
+                       interrupts = <0 110 0>;
+                       clocks = <&clock_audss EXYNOS_ADMA>;
+                       clock-names = "apb_pclk";
+                       #dma-cells = <1>;
+                       #dma-channels = <6>;
+                       #dma-requests = <16>;
+               };
+
                pdma0: pdma@121A0000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121A0000 0x1000>;
                        interrupts = <0 34 0>;
-                       clocks = <&clock 362>;
+                       clocks = <&clock CLK_PDMA0>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121B0000 0x1000>;
                        interrupts = <0 35 0>;
-                       clocks = <&clock 363>;
+                       clocks = <&clock CLK_PDMA1>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x10800000 0x1000>;
                        interrupts = <0 33 0>;
-                       clocks = <&clock 473>;
+                       clocks = <&clock CLK_MDMA0>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x11C10000 0x1000>;
                        interrupts = <0 124 0>;
-                       clocks = <&clock 442>;
+                       clocks = <&clock CLK_MDMA1>;
                        clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                };
        };
 
+       i2s0: i2s@03830000 {
+               compatible = "samsung,exynos5420-i2s";
+               reg = <0x03830000 0x100>;
+               dmas = <&adma 0
+                       &adma 2
+                       &adma 1>;
+               dma-names = "tx", "rx", "tx-sec";
+               clocks = <&clock_audss EXYNOS_I2S_BUS>,
+                       <&clock_audss EXYNOS_I2S_BUS>,
+                       <&clock_audss EXYNOS_SCLK_I2S>;
+               clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+               samsung,idma-addr = <0x03000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s0_bus>;
+               status = "disabled";
+       };
+
+       i2s1: i2s@12D60000 {
+               compatible = "samsung,exynos5420-i2s";
+               reg = <0x12D60000 0x100>;
+               dmas = <&pdma1 12
+                       &pdma1 11>;
+               dma-names = "tx", "rx";
+               clocks = <&clock CLK_I2S1>, <&clock CLK_SCLK_I2S1>;
+               clock-names = "iis", "i2s_opclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s1_bus>;
+               status = "disabled";
+       };
+
+       i2s2: i2s@12D70000 {
+               compatible = "samsung,exynos5420-i2s";
+               reg = <0x12D70000 0x100>;
+               dmas = <&pdma0 12
+                       &pdma0 11>;
+               dma-names = "tx", "rx";
+               clocks = <&clock CLK_I2S2>, <&clock CLK_SCLK_I2S2>;
+               clock-names = "iis", "i2s_opclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s2_bus>;
+               status = "disabled";
+       };
+
        spi_0: spi@12d20000 {
                compatible = "samsung,exynos4210-spi";
                reg = <0x12d20000 0x100>;
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&spi0_bus>;
-               clocks = <&clock 271>, <&clock 135>;
+               clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
                clock-names = "spi", "spi_busclk0";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&spi1_bus>;
-               clocks = <&clock 272>, <&clock 136>;
+               clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
                clock-names = "spi", "spi_busclk0";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&spi2_bus>;
-               clocks = <&clock 273>, <&clock 137>;
+               clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
                clock-names = "spi", "spi_busclk0";
                status = "disabled";
        };
 
        serial@12C00000 {
-               clocks = <&clock 257>, <&clock 128>;
+               clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C10000 {
-               clocks = <&clock 258>, <&clock 129>;
+               clocks = <&clock CLK_UART1>, <&clock CLK_SCLK_UART1>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C20000 {
-               clocks = <&clock 259>, <&clock 130>;
+               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C30000 {
-               clocks = <&clock 260>, <&clock 131>;
+               clocks = <&clock CLK_UART3>, <&clock CLK_SCLK_UART3>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
                reg = <0x12dd0000 0x100>;
                samsung,pwm-outputs = <0>, <1>, <2>, <3>;
                #pwm-cells = <3>;
-               clocks = <&clock 279>;
+               clocks = <&clock CLK_PWM>;
                clock-names = "timers";
        };
 
        };
 
        dp-controller@145B0000 {
-               clocks = <&clock 412>;
+               clocks = <&clock CLK_DP1>;
                clock-names = "dp";
                phys = <&dp_phy>;
                phy-names = "dp";
 
        fimd@14400000 {
                samsung,power-domain = <&disp_pd>;
-               clocks = <&clock 147>, <&clock 421>;
+               clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
                clock-names = "sclk_fimd", "fimd";
        };
 
                compatible = "samsung,exynos-adc-v2";
                reg = <0x12D10000 0x100>, <0x10040720 0x4>;
                interrupts = <0 106 0>;
-               clocks = <&clock 270>;
+               clocks = <&clock CLK_TSADC>;
                clock-names = "adc";
                #io-channel-cells = <1>;
                io-channel-ranges;
                interrupts = <0 56 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 261>;
+               clocks = <&clock CLK_I2C0>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c0_bus>;
                interrupts = <0 57 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 262>;
+               clocks = <&clock CLK_I2C1>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c1_bus>;
                interrupts = <0 58 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 263>;
+               clocks = <&clock CLK_I2C2>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c2_bus>;
                interrupts = <0 59 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 264>;
+               clocks = <&clock CLK_I2C3>;
                clock-names = "i2c";
                pinctrl-names = "default";
                pinctrl-0 = <&i2c3_bus>;
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c4_hs_bus>;
-               clocks = <&clock 265>;
+               clocks = <&clock CLK_I2C4>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c5_hs_bus>;
-               clocks = <&clock 266>;
+               clocks = <&clock CLK_I2C5>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c6_hs_bus>;
-               clocks = <&clock 267>;
+               clocks = <&clock CLK_I2C6>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c7_hs_bus>;
-               clocks = <&clock 268>;
+               clocks = <&clock CLK_I2C7>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c8_hs_bus>;
-               clocks = <&clock 281>;
+               clocks = <&clock CLK_I2C8>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c9_hs_bus>;
-               clocks = <&clock 282>;
+               clocks = <&clock CLK_I2C9>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                #size-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&i2c10_hs_bus>;
-               clocks = <&clock 283>;
+               clocks = <&clock CLK_I2C10>;
                clock-names = "hsi2c";
                status = "disabled";
        };
                compatible = "samsung,exynos4212-hdmi";
                reg = <0x14530000 0x70000>;
                interrupts = <0 95 0>;
-               clocks = <&clock 413>, <&clock 143>, <&clock 768>,
-                       <&clock 158>, <&clock 640>;
+               clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+                        <&clock CLK_DOUT_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
+                        <&clock CLK_MOUT_HDMI>;
                clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
                        "sclk_hdmiphy", "mout_hdmi";
                status = "disabled";
                compatible = "samsung,exynos5420-mixer";
                reg = <0x14450000 0x10000>;
                interrupts = <0 94 0>;
-               clocks = <&clock 431>, <&clock 143>;
+               clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>;
                clock-names = "mixer", "sclk_hdmi";
        };
 
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e00000 0x1000>;
                interrupts = <0 85 0>;
-               clocks = <&clock 465>;
+               clocks = <&clock CLK_GSCL0>;
                clock-names = "gscl";
                samsung,power-domain = <&gsc_pd>;
        };
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e10000 0x1000>;
                interrupts = <0 86 0>;
-               clocks = <&clock 466>;
+               clocks = <&clock CLK_GSCL1>;
                clock-names = "gscl";
                samsung,power-domain = <&gsc_pd>;
        };
 
+       pmu_system_controller: system-controller@10040000 {
+               compatible = "samsung,exynos5420-pmu", "syscon";
+               reg = <0x10040000 0x5000>;
+       };
+
        tmu_cpu0: tmu@10060000 {
                compatible = "samsung,exynos5420-tmu";
                reg = <0x10060000 0x100>;
                interrupts = <0 65 0>;
-               clocks = <&clock 318>;
+               clocks = <&clock CLK_TMU>;
                clock-names = "tmu_apbif";
        };
 
                compatible = "samsung,exynos5420-tmu";
                reg = <0x10064000 0x100>;
                interrupts = <0 183 0>;
-               clocks = <&clock 318>;
+               clocks = <&clock CLK_TMU>;
                clock-names = "tmu_apbif";
        };
 
                compatible = "samsung,exynos5420-tmu-ext-triminfo";
                reg = <0x10068000 0x100>, <0x1006c000 0x4>;
                interrupts = <0 184 0>;
-               clocks = <&clock 318>, <&clock 318>;
+               clocks = <&clock CLK_TMU>, <&clock CLK_TMU>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
        };
 
                compatible = "samsung,exynos5420-tmu-ext-triminfo";
                reg = <0x1006c000 0x100>, <0x100a0000 0x4>;
                interrupts = <0 185 0>;
-               clocks = <&clock 318>, <&clock 319>;
+               clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
        };
 
                compatible = "samsung,exynos5420-tmu-ext-triminfo";
                reg = <0x100a0000 0x100>, <0x10068000 0x4>;
                interrupts = <0 215 0>;
-               clocks = <&clock 319>, <&clock 318>;
+               clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
        };
+
+        watchdog@101D0000 {
+               compatible = "samsung,exynos5420-wdt";
+               reg = <0x101D0000 0x100>;
+               interrupts = <0 42 0>;
+               clocks = <&clock CLK_WDT>;
+               clock-names = "watchdog";
+               samsung,syscon-phandle = <&pmu_system_controller>;
+        };
+
+       sss@10830000 {
+               compatible = "samsung,exynos4210-secss";
+               reg = <0x10830000 0x10000>;
+               interrupts = <0 112 0>;
+               clocks = <&clock 471>;
+               clock-names = "secss";
+               samsung,power-domain = <&g2d_pd>;
+       };
 };
index 777fb1c2c70f322b00b3075472a8a412e5c42509..268609a42b2c04c7a1db748cf6e899a0cded2be3 100644 (file)
@@ -14,7 +14,7 @@
 
 / {
        model = "SAMSUNG SD5v1 board based on EXYNOS5440";
-       compatible = "samsung,sd5v1", "samsung,exynos5440";
+       compatible = "samsung,sd5v1", "samsung,exynos5440", "samsung,exynos5";
 
        chosen {
                bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
index d58cb787061af4a85e7d60e90222c659dbc8d412..ff55dac6e2193b837bcb64754d39b62d4ee5cabf 100644 (file)
@@ -14,7 +14,7 @@
 
 / {
        model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
-       compatible = "samsung,ssdk5440", "samsung,exynos5440";
+       compatible = "samsung,ssdk5440", "samsung,exynos5440", "samsung,exynos5";
 
        chosen {
                bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel earlyprintk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
index 02a0a1226cef7a81b4f5e629d0d2bb58d734e3a9..84f77c2fe4d4cfe55d254ccc3c8bf7c48f73041e 100644 (file)
@@ -9,10 +9,11 @@
  * published by the Free Software Foundation.
 */
 
+#include <dt-bindings/clock/exynos5440.h>
 #include "skeleton.dtsi"
 
 / {
-       compatible = "samsung,exynos5440";
+       compatible = "samsung,exynos5440", "samsung,exynos5";
 
        interrupt-parent = <&gic>;
 
                compatible = "samsung,exynos4210-uart";
                reg = <0xB0000 0x1000>;
                interrupts = <0 2 0>;
-               clocks = <&clock 21>, <&clock 21>;
+               clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
                compatible = "samsung,exynos4210-uart";
                reg = <0xC0000 0x1000>;
                interrupts = <0 3 0>;
-               clocks = <&clock 21>, <&clock 21>;
+               clocks = <&clock CLK_B_125>, <&clock CLK_B_125>;
                clock-names = "uart", "clk_uart_baud0";
        };
 
                #size-cells = <0>;
                samsung,spi-src-clk = <0>;
                num-cs = <1>;
-               clocks = <&clock 21>, <&clock 16>;
+               clocks = <&clock CLK_B_125>, <&clock CLK_SPI_BAUD>;
                clock-names = "spi", "spi_busclk0";
        };
 
                interrupts = <0 5 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "i2c";
        };
 
                interrupts = <0 6 0>;
                #address-cells = <1>;
                #size-cells = <0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "i2c";
        };
 
                compatible = "samsung,s3c2410-wdt";
                reg = <0x110000 0x1000>;
                interrupts = <0 1 0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "watchdog";
        };
 
                interrupts = <0 31 4>;
                interrupt-names = "macirq";
                phy-mode = "sgmii";
-               clocks = <&clock 25>;
+               clocks = <&clock CLK_GMAC0>;
                clock-names = "stmmaceth";
        };
 
                compatible = "samsung,s3c6410-rtc";
                reg = <0x130000 0x1000>;
                interrupts = <0 17 0>, <0 16 0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "rtc";
        };
 
                compatible = "samsung,exynos5440-tmu";
                reg = <0x160118 0x230>, <0x160368 0x10>;
                interrupts = <0 58 0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "tmu_apbif";
        };
 
                compatible = "samsung,exynos5440-tmu";
                reg = <0x16011C 0x230>, <0x160368 0x10>;
                interrupts = <0 58 0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "tmu_apbif";
        };
 
                compatible = "samsung,exynos5440-tmu";
                reg = <0x160120 0x230>, <0x160368 0x10>;
                interrupts = <0 58 0>;
-               clocks = <&clock 21>;
+               clocks = <&clock CLK_B_125>;
                clock-names = "tmu_apbif";
        };
 
                compatible = "snps,exynos5440-ahci";
                reg = <0x210000 0x10000>;
                interrupts = <0 30 0>;
-               clocks = <&clock 23>;
+               clocks = <&clock CLK_SATA>;
                clock-names = "sata";
        };
 
                compatible = "samsung,exynos5440-ohci";
                reg = <0x220000 0x1000>;
                interrupts = <0 29 0>;
-               clocks = <&clock 24>;
+               clocks = <&clock CLK_USB>;
                clock-names = "usbhost";
        };
 
                compatible = "samsung,exynos5440-ehci";
                reg = <0x221000 0x1000>;
                interrupts = <0 29 0>;
-               clocks = <&clock 24>;
+               clocks = <&clock CLK_USB>;
                clock-names = "usbhost";
        };
 
                        0x270000 0x1000
                        0x271000 0x40>;
                interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
-               clocks = <&clock 28>, <&clock 27>;
+               clocks = <&clock CLK_PR0_250_O>, <&clock CLK_PB0_250_O>;
                clock-names = "pcie", "pcie_bus";
                #address-cells = <3>;
                #size-cells = <2>;
                        0x272000 0x1000
                        0x271040 0x40>;
                interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
-               clocks = <&clock 29>, <&clock 27>;
+               clocks = <&clock CLK_PR1_250_O>, <&clock CLK_PB0_250_O>;
                clock-names = "pcie", "pcie_bus";
                #address-cells = <3>;
                #size-cells = <2>;
index 1f026adefd451e594628d1855acf949f9cd7d7cf..a33f66c11b73edbf3671f02017e7780704c36b05 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio1 29 0>;
                };
 
-               reg_lcd_3v3: lcd-3v3 {
+               reg_lcd_3v3: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "lcd-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index 526bfdbd87f9f84f08747c6c045c059a657d2cbc..7e6eef2488e807c12c36aaebfd3e64b076f7622f 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index cb64e2b191ea1ae48098c1c79ced4afe6f57b521..455169e99d49b5ad5388e8122012f3f6f6e27f72 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index 581b75433be68b8bf01c44a48a8d8299cac95285..bbcfb5a19c77009e2cf77253f1e49cee8c6d7035 100644 (file)
@@ -23,6 +23,7 @@
                serial1 = &auart1;
                spi0 = &ssp0;
                spi1 = &ssp1;
+               usbphy0 = &usbphy0;
        };
 
        cpus {
                                status = "disabled";
                        };
 
-                       lradc@80050000 {
+                       lradc: lradc@80050000 {
                                compatible = "fsl,imx23-lradc";
                                reg = <0x80050000 0x2000>;
                                interrupts = <36 37 38 39 40 41 42 43 44>;
                        status = "disabled";
                };
        };
+
+       iio_hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&lradc 8>;
+       };
 };
diff --git a/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi b/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi
new file mode 100644 (file)
index 0000000..d6f2764
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "imx25.dtsi"
+
+/ {
+       model = "Eukrea CPUIMX25";
+       compatible = "eukrea,cpuimx25", "fsl,imx25";
+
+       memory {
+               reg = <0x80000000 0x4000000>; /* 64M */
+       };
+};
+
+&fec {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&iomuxc {
+       imx25-eukrea-cpuimx25 {
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX25_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX25_PAD_FEC_MDIO__FEC_MDIO             0x400001e0
+                               MX25_PAD_FEC_TDATA0__FEC_TDATA0         0x80000000
+                               MX25_PAD_FEC_TDATA1__FEC_TDATA1         0x80000000
+                               MX25_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX25_PAD_FEC_RDATA0__FEC_RDATA0         0x80000000
+                               MX25_PAD_FEC_RDATA1__FEC_RDATA1         0x80000000
+                               MX25_PAD_FEC_RX_DV__FEC_RX_DV           0x80000000
+                               MX25_PAD_FEC_TX_CLK__FEC_TX_CLK         0x1c0
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX25_PAD_I2C1_CLK__I2C1_CLK             0x80000000
+                               MX25_PAD_I2C1_DAT__I2C1_DAT             0x80000000
+                       >;
+               };
+       };
+};
+
+&nfc {
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
new file mode 100644 (file)
index 0000000..62fb3da
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx25-eukrea-cpuimx25.dtsi"
+
+/ {
+       model = "Eukrea MBIMXSD25";
+       compatible = "eukrea,mbimxsd25-baseboard", "eukrea,cpuimx25", "fsl,imx25";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiokeys>;
+
+               bp1 {
+                       label = "BP1";
+                       gpios = <&gpio3 18 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_MISC>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpioled>;
+
+               led1 {
+                       label = "led1";
+                       gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       sound {
+               compatible = "eukrea,asoc-tlv320";
+               eukrea,model = "imx25-eukrea-tlv320aic23";
+               ssi-controller = <&ssi1>;
+               fsl,mux-int-port = <1>;
+               fsl,mux-ext-port = <5>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       cd-gpios = <&gpio1 20>;
+       status = "okay";
+};
+
+&i2c1 {
+       tlv320aic23: codec@1a {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1a>;
+       };
+};
+
+&iomuxc {
+       imx25-eukrea-mbimxsd25-baseboard {
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX25_PAD_KPP_COL3__AUD5_TXFS            0xe0
+                               MX25_PAD_KPP_COL2__AUD5_TXC             0xe0
+                               MX25_PAD_KPP_COL1__AUD5_RXD             0xe0
+                               MX25_PAD_KPP_COL0__AUD5_TXD             0xe0
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX25_PAD_SD1_CMD__SD1_CMD               0x400000c0
+                               MX25_PAD_SD1_CLK__SD1_CLK               0x400000c0
+                               MX25_PAD_SD1_DATA0__SD1_DATA0           0x400000c0
+                               MX25_PAD_SD1_DATA1__SD1_DATA1           0x400000c0
+                               MX25_PAD_SD1_DATA2__SD1_DATA2           0x400000c0
+                               MX25_PAD_SD1_DATA3__SD1_DATA3           0x400000c0
+                       >;
+               };
+
+               pinctrl_gpiokeys: gpiokeysgrp {
+                       fsl,pins = <MX25_PAD_VSTBY_ACK__GPIO_3_18 0x80000000>;
+               };
+
+               pinctrl_gpioled: gpioledgrp {
+                       fsl,pins = <MX25_PAD_POWER_FAIL__GPIO_3_19 0x80000000>;
+               };
+
+               pinctrl_lcdc: lcdcgrp {
+                       fsl,pins = <
+                               MX25_PAD_LD0__LD0                       0x1
+                               MX25_PAD_LD1__LD1                       0x1
+                               MX25_PAD_LD2__LD2                       0x1
+                               MX25_PAD_LD3__LD3                       0x1
+                               MX25_PAD_LD4__LD4                       0x1
+                               MX25_PAD_LD5__LD5                       0x1
+                               MX25_PAD_LD6__LD6                       0x1
+                               MX25_PAD_LD7__LD7                       0x1
+                               MX25_PAD_LD8__LD8                       0x1
+                               MX25_PAD_LD9__LD9                       0x1
+                               MX25_PAD_LD10__LD10                     0x1
+                               MX25_PAD_LD11__LD11                     0x1
+                               MX25_PAD_LD12__LD12                     0x1
+                               MX25_PAD_LD13__LD13                     0x1
+                               MX25_PAD_LD14__LD14                     0x1
+                               MX25_PAD_LD15__LD15                     0x1
+                               MX25_PAD_GPIO_E__LD16                   0x1
+                               MX25_PAD_GPIO_F__LD17                   0x1
+                               MX25_PAD_HSYNC__HSYNC                   0x80000000
+                               MX25_PAD_VSYNC__VSYNC                   0x80000000
+                               MX25_PAD_LSCLK__LSCLK                   0x80000000
+                               MX25_PAD_OE_ACD__OE_ACD                 0x80000000
+                               MX25_PAD_CONTRAST__CONTRAST             0x80000000
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX25_PAD_UART1_RTS__UART1_RTS           0xe0
+                               MX25_PAD_UART1_CTS__UART1_CTS           0xe0
+                               MX25_PAD_UART1_TXD__UART1_TXD           0x80000000
+                               MX25_PAD_UART1_RXD__UART1_RXD           0xc0
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX25_PAD_UART2_RXD__UART2_RXD           0x80000000
+                               MX25_PAD_UART2_TXD__UART2_TXD           0x80000000
+                               MX25_PAD_UART2_RTS__UART2_RTS           0x80000000
+                               MX25_PAD_UART2_CTS__UART2_CTS           0x80000000
+                       >;
+               };
+       };
+};
+
+&ssi1 {
+       codec-handle = <&tlv320aic23>;
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h
new file mode 100644 (file)
index 0000000..9238a95
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ * Based on imx35-pinfunc.h in the same directory Which is:
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX25_PINFUNC_H
+#define __DTS_IMX25_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX25_PAD_A10__A10                      0x008 0x000 0x000 0x00 0x000
+#define MX25_PAD_A10__GPIO_4_0                 0x008 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_A13__A13                      0x00c 0x22C 0x000 0x00 0x000
+#define MX25_PAD_A13__GPIO_4_1                 0x00c 0x22C 0x000 0x05 0x000
+
+#define MX25_PAD_A14__A14                      0x010 0x230 0x000 0x10 0x000
+#define MX25_PAD_A14__GPIO_2_0                 0x010 0x230 0x000 0x15 0x000
+
+#define MX25_PAD_A15__A15                      0x014 0x234 0x000 0x10 0x000
+#define MX25_PAD_A15__GPIO_2_1                 0x014 0x234 0x000 0x15 0x000
+
+#define MX25_PAD_A16__A16                      0x018 0x000 0x000 0x10 0x000
+#define MX25_PAD_A16__GPIO_2_2                 0x018 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_A17__A17                      0x01c 0x238 0x000 0x10 0x000
+#define MX25_PAD_A17__GPIO_2_3                 0x01c 0x238 0x000 0x15 0x000
+
+#define MX25_PAD_A18__A18                      0x020 0x23c 0x000 0x10 0x000
+#define MX25_PAD_A18__GPIO_2_4                 0x020 0x23c 0x000 0x15 0x000
+#define MX25_PAD_A18__FEC_COL                  0x020 0x23c 0x504 0x17 0x000
+
+#define MX25_PAD_A19__A19                      0x024 0x240 0x000 0x10 0x000
+#define MX25_PAD_A19__FEC_RX_ER                        0x024 0x240 0x518 0x17 0x000
+#define MX25_PAD_A19__GPIO_2_5                 0x024 0x240 0x000 0x15 0x000
+
+#define MX25_PAD_A20__A20                      0x028 0x244 0x000 0x10 0x000
+#define MX25_PAD_A20__GPIO_2_6                 0x028 0x244 0x000 0x15 0x000
+#define MX25_PAD_A20__FEC_RDATA2               0x028 0x244 0x50c 0x17 0x000
+
+#define MX25_PAD_A21__A21                      0x02c 0x248 0x000 0x10 0x000
+#define MX25_PAD_A21__GPIO_2_7                 0x02c 0x248 0x000 0x15 0x000
+#define MX25_PAD_A21__FEC_RDATA3               0x02c 0x248 0x510 0x17 0x000
+
+#define MX25_PAD_A22__A22                      0x030 0x000 0x000 0x10 0x000
+#define MX25_PAD_A22__GPIO_2_8                 0x030 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_A23__A23                      0x034 0x24c 0x000 0x10 0x000
+#define MX25_PAD_A23__GPIO_2_9                 0x034 0x24c 0x000 0x15 0x000
+
+#define MX25_PAD_A24__A24                      0x038 0x250 0x000 0x10 0x000
+#define MX25_PAD_A24__GPIO_2_10                        0x038 0x250 0x000 0x15 0x000
+#define MX25_PAD_A24__FEC_RX_CLK               0x038 0x250 0x514 0x17 0x000
+
+#define MX25_PAD_A25__A25                      0x03c 0x254 0x000 0x10 0x000
+#define MX25_PAD_A25__GPIO_2_11                        0x03c 0x254 0x000 0x15 0x000
+#define MX25_PAD_A25__FEC_CRS                  0x03c 0x254 0x508 0x17 0x000
+
+#define MX25_PAD_EB0__EB0                      0x040 0x258 0x000 0x10 0x000
+#define MX25_PAD_EB0__AUD4_TXD                 0x040 0x258 0x464 0x14 0x000
+#define MX25_PAD_EB0__GPIO_2_12                        0x040 0x258 0x000 0x15 0x000
+
+#define MX25_PAD_EB1__EB1                      0x044 0x25c 0x000 0x10 0x000
+#define MX25_PAD_EB1__AUD4_RXD                 0x044 0x25c 0x460 0x14 0x000
+#define MX25_PAD_EB1__GPIO_2_13                        0x044 0x25c 0x000 0x15 0x000
+
+#define MX25_PAD_OE__OE                                0x048 0x260 0x000 0x10 0x000
+#define MX25_PAD_OE__AUD4_TXC                  0x048 0x260 0x000 0x14 0x000
+#define MX25_PAD_OE__GPIO_2_14                 0x048 0x260 0x000 0x15 0x000
+
+#define MX25_PAD_CS0__CS0                      0x04c 0x000 0x000 0x00 0x000
+#define MX25_PAD_CS0__GPIO_4_2                 0x04c 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_CS1__CS1                      0x050 0x000 0x000 0x00 0x000
+#define MX25_PAD_CS1__NF_CE3                   0x050 0x000 0x000 0x01 0x000
+#define MX25_PAD_CS1__GPIO_4_3                 0x050 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_CS4__CS4                      0x054 0x264 0x000 0x10 0x000
+#define MX25_PAD_CS4__NF_CE1                   0x054 0x264 0x000 0x01 0x000
+#define MX25_PAD_CS4__UART5_CTS                        0x054 0x264 0x000 0x13 0x000
+#define MX25_PAD_CS4__GPIO_3_20                        0x054 0x264 0x000 0x15 0x000
+
+#define MX25_PAD_CS5__CS5                      0x058 0x268 0x000 0x10 0x000
+#define MX25_PAD_CS5__NF_CE2                   0x058 0x268 0x000 0x01 0x000
+#define MX25_PAD_CS5__UART5_RTS                        0x058 0x268 0x574 0x13 0x000
+#define MX25_PAD_CS5__GPIO_3_21                        0x058 0x268 0x000 0x15 0x000
+
+#define MX25_PAD_NF_CE0__NF_CE0                        0x05c 0x26c 0x000 0x10 0x000
+#define MX25_PAD_NF_CE0__GPIO_3_22             0x05c 0x26c 0x000 0x15 0x000
+
+#define MX25_PAD_ECB__ECB                      0x060 0x270 0x000 0x10 0x000
+#define MX25_PAD_ECB__UART5_TXD_MUX            0x060 0x270 0x000 0x13 0x000
+#define MX25_PAD_ECB__GPIO_3_23                        0x060 0x270 0x000 0x15 0x000
+
+#define MX25_PAD_LBA__LBA                      0x064 0x274 0x000 0x10 0x000
+#define MX25_PAD_LBA__UART5_RXD_MUX            0x064 0x274 0x578 0x13 0x000
+#define MX25_PAD_LBA__GPIO_3_24                        0x064 0x274 0x000 0x15 0x000
+
+#define MX25_PAD_BCLK__BCLK                    0x068 0x000 0x000 0x00 0x000
+#define MX25_PAD_BCLK__GPIO_4_4                        0x068 0x000 0x000 0x05 0x000
+
+#define MX25_PAD_RW__RW                                0x06c 0x278 0x000 0x10 0x000
+#define MX25_PAD_RW__AUD4_TXFS                 0x06c 0x278 0x474 0x14 0x000
+#define MX25_PAD_RW__GPIO_3_25                 0x06c 0x278 0x000 0x15 0x000
+
+#define MX25_PAD_NFWE_B__NFWE_B                        0x070 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFWE_B__GPIO_3_26             0x070 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFRE_B__NFRE_B                        0x074 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFRE_B__GPIO_3_27             0x074 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFALE__NFALE                  0x078 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFALE__GPIO_3_28              0x078 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFCLE__NFCLE                  0x07c 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFCLE__GPIO_3_29              0x07c 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFWP_B__NFWP_B                        0x080 0x000 0x000 0x10 0x000
+#define MX25_PAD_NFWP_B__GPIO_3_30             0x080 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_NFRB__NFRB                    0x084 0x27c 0x000 0x10 0x000
+#define MX25_PAD_NFRB__GPIO_3_31               0x084 0x27c 0x000 0x15 0x000
+
+#define MX25_PAD_D15__D15                      0x088 0x280 0x000 0x00 0x000
+#define MX25_PAD_D15__LD16                     0x088 0x280 0x000 0x01 0x000
+#define MX25_PAD_D15__GPIO_4_5                 0x088 0x280 0x000 0x05 0x000
+
+#define MX25_PAD_D14__D14                      0x08c 0x284 0x000 0x00 0x000
+#define MX25_PAD_D14__LD17                     0x08c 0x284 0x000 0x01 0x000
+#define MX25_PAD_D14__GPIO_4_6                 0x08c 0x284 0x000 0x05 0x000
+
+#define MX25_PAD_D13__D13                      0x090 0x288 0x000 0x00 0x000
+#define MX25_PAD_D13__LD18                     0x090 0x288 0x000 0x01 0x000
+#define MX25_PAD_D13__GPIO_4_7                 0x090 0x288 0x000 0x05 0x000
+
+#define MX25_PAD_D12__D12                      0x094 0x28c 0x000 0x00 0x000
+#define MX25_PAD_D12__GPIO_4_8                 0x094 0x28c 0x000 0x05 0x000
+
+#define MX25_PAD_D11__D11                      0x098 0x290 0x000 0x00 0x000
+#define MX25_PAD_D11__GPIO_4_9                 0x098 0x290 0x000 0x05 0x000
+
+#define MX25_PAD_D10__D10                      0x09c 0x294 0x000 0x00 0x000
+#define MX25_PAD_D10__GPIO_4_10                        0x09c 0x294 0x000 0x05 0x000
+#define MX25_PAD_D10__USBOTG_OC                        0x09c 0x294 0x57c 0x06 0x000
+
+#define MX25_PAD_D9__D9                                0x0a0 0x298 0x000 0x00 0x000
+#define MX25_PAD_D9__GPIO_4_11                 0x0a0 0x298 0x000 0x05 0x000
+#define MX25_PAD_D9__USBH2_PWR                 0x0a0 0x298 0x000 0x06 0x000
+
+#define MX25_PAD_D8__D8                                0x0a4 0x29c 0x000 0x00 0x000
+#define MX25_PAD_D8__GPIO_4_12                 0x0a4 0x29c 0x000 0x05 0x000
+#define MX25_PAD_D8__USBH2_OC                  0x0a4 0x29c 0x580 0x06 0x000
+
+#define MX25_PAD_D7__D7                                0x0a8 0x2a0 0x000 0x00 0x000
+#define MX25_PAD_D7__GPIO_4_13                 0x0a8 0x2a0 0x000 0x05 0x000
+
+#define MX25_PAD_D6__D6                                0x0ac 0x2a4 0x000 0x00 0x000
+#define MX25_PAD_D6__GPIO_4_14                 0x0ac 0x2a4 0x000 0x05 0x000
+
+#define MX25_PAD_D5__D5                                0x0b0 0x2a8 0x000 0x00 0x000
+#define MX25_PAD_D5__GPIO_4_15                 0x0b0 0x2a8 0x000 0x05 0x000
+
+#define MX25_PAD_D4__D4                                0x0b4 0x2ac 0x000 0x00 0x000
+#define MX25_PAD_D4__GPIO_4_16                 0x0b4 0x2ac 0x000 0x05 0x000
+
+#define MX25_PAD_D3__D3                                0x0b8 0x2b0 0x000 0x00 0x000
+#define MX25_PAD_D3__GPIO_4_17                 0x0b8 0x2b0 0x000 0x05 0x000
+
+#define MX25_PAD_D2__D2                                0x0bc 0x2b4 0x000 0x00 0x000
+#define MX25_PAD_D2__GPIO_4_18                 0x0bc 0x2b4 0x000 0x05 0x000
+
+#define MX25_PAD_D1__D1                                0x0c0 0x2b8 0x000 0x00 0x000
+#define MX25_PAD_D1__GPIO_4_19                 0x0c0 0x2b8 0x000 0x05 0x000
+
+#define MX25_PAD_D0__D0                                0x0c4 0x2bc 0x000 0x00 0x000
+#define MX25_PAD_D0__GPIO_4_20                 0x0c4 0x2bc 0x000 0x05 0x000
+
+#define MX25_PAD_LD0__LD0                      0x0c8 0x2c0 0x000 0x10 0x000
+#define MX25_PAD_LD0__CSI_D0                   0x0c8 0x2c0 0x488 0x12 0x000
+#define MX25_PAD_LD0__GPIO_2_15                        0x0c8 0x2c0 0x000 0x15 0x000
+
+#define MX25_PAD_LD1__LD1                      0x0cc 0x2c4 0x000 0x10 0x000
+#define MX25_PAD_LD1__CSI_D1                   0x0cc 0x2c4 0x48c 0x12 0x000
+#define MX25_PAD_LD1__GPIO_2_16                        0x0cc 0x2c4 0x000 0x15 0x000
+
+#define MX25_PAD_LD2__LD2                      0x0d0 0x2c8 0x000 0x10 0x000
+#define MX25_PAD_LD2__GPIO_2_17                        0x0d0 0x2c8 0x000 0x15 0x000
+
+#define MX25_PAD_LD3__LD3                      0x0d4 0x2cc 0x000 0x10 0x000
+#define MX25_PAD_LD3__GPIO_2_18                        0x0d4 0x2cc 0x000 0x15 0x000
+
+#define MX25_PAD_LD4__LD4                      0x0d8 0x2d0 0x000 0x10 0x000
+#define MX25_PAD_LD4__GPIO_2_19                        0x0d8 0x2d0 0x000 0x15 0x000
+
+#define MX25_PAD_LD5__LD5                      0x0dc 0x2d4 0x000 0x10 0x000
+#define MX25_PAD_LD5__GPIO_1_19                        0x0dc 0x2d4 0x000 0x15 0x000
+
+#define MX25_PAD_LD6__LD6                      0x0e0 0x2d8 0x000 0x10 0x000
+#define MX25_PAD_LD6__GPIO_1_20                        0x0e0 0x2d8 0x000 0x15 0x000
+
+#define MX25_PAD_LD7__LD7                      0x0e4 0x2dc 0x000 0x10 0x000
+#define MX25_PAD_LD7__GPIO_1_21                        0x0e4 0x2dc 0x000 0x15 0x000
+
+#define MX25_PAD_LD8__LD8                      0x0e8 0x2e0 0x000 0x10 0x000
+#define MX25_PAD_LD8__FEC_TX_ERR               0x0e8 0x2e0 0x000 0x15 0x000
+
+#define MX25_PAD_LD9__LD9                      0x0ec 0x2e4 0x000 0x10 0x000
+#define MX25_PAD_LD9__FEC_COL                  0x0ec 0x2e4 0x504 0x15 0x001
+
+#define MX25_PAD_LD10__LD10                    0x0f0 0x2e8 0x000 0x10 0x000
+#define MX25_PAD_LD10__FEC_RX_ER               0x0f0 0x2e8 0x518 0x15 0x001
+
+#define MX25_PAD_LD11__LD11                    0x0f4 0x2ec 0x000 0x10 0x000
+#define MX25_PAD_LD11__FEC_RDATA2              0x0f4 0x2ec 0x50c 0x15 0x001
+
+#define MX25_PAD_LD12__LD12                    0x0f8 0x2f0 0x000 0x10 0x000
+#define MX25_PAD_LD12__FEC_RDATA3              0x0f8 0x2f0 0x510 0x15 0x001
+
+#define MX25_PAD_LD13__LD13                    0x0fc 0x2f4 0x000 0x10 0x000
+#define MX25_PAD_LD13__FEC_TDATA2              0x0fc 0x2f4 0x000 0x15 0x000
+
+#define MX25_PAD_LD14__LD14                    0x100 0x2f8 0x000 0x10 0x000
+#define MX25_PAD_LD14__FEC_TDATA3              0x100 0x2f8 0x000 0x15 0x000
+
+#define MX25_PAD_LD15__LD15                    0x104 0x2fc 0x000 0x10 0x000
+#define MX25_PAD_LD15__FEC_RX_CLK              0x104 0x2fc 0x514 0x15 0x001
+
+#define MX25_PAD_HSYNC__HSYNC                  0x108 0x300 0x000 0x10 0x000
+#define MX25_PAD_HSYNC__GPIO_1_22              0x108 0x300 0x000 0x15 0x000
+
+#define MX25_PAD_VSYNC__VSYNC                  0x10c 0x304 0x000 0x10 0x000
+#define MX25_PAD_VSYNC__GPIO_1_23              0x10c 0x304 0x000 0x15 0x000
+
+#define MX25_PAD_LSCLK__LSCLK                  0x110 0x308 0x000 0x10 0x000
+#define MX25_PAD_LSCLK__GPIO_1_24              0x110 0x308 0x000 0x15 0x000
+
+#define MX25_PAD_OE_ACD__OE_ACD                        0x114 0x30c 0x000 0x10 0x000
+#define MX25_PAD_OE_ACD__GPIO_1_25             0x114 0x30c 0x000 0x15 0x000
+
+#define MX25_PAD_CONTRAST__CONTRAST            0x118 0x310 0x000 0x10 0x000
+#define MX25_PAD_CONTRAST__PWM4_PWMO           0x118 0x310 0x000 0x14 0x000
+#define MX25_PAD_CONTRAST__FEC_CRS             0x118 0x310 0x508 0x15 0x001
+
+#define MX25_PAD_PWM__PWM                      0x11c 0x314 0x000 0x10 0x000
+#define MX25_PAD_PWM__GPIO_1_26                        0x11c 0x314 0x000 0x15 0x000
+#define MX25_PAD_PWM__USBH2_OC                 0x11c 0x314 0x580 0x16 0x001
+
+#define MX25_PAD_CSI_D2__CSI_D2                        0x120 0x318 0x000 0x10 0x000
+#define MX25_PAD_CSI_D2__UART5_RXD_MUX         0x120 0x318 0x578 0x11 0x001
+#define MX25_PAD_CSI_D2__GPIO_1_27             0x120 0x318 0x000 0x15 0x000
+#define MX25_PAD_CSI_D2__CSPI3_MOSI            0x120 0x318 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D3__CSI_D3                        0x124 0x31c 0x000 0x10 0x000
+#define MX25_PAD_CSI_D3__GPIO_1_28             0x124 0x31c 0x000 0x15 0x000
+#define MX25_PAD_CSI_D3__CSPI3_MISO            0x124 0x31c 0x4b4 0x17 0x001
+
+#define MX25_PAD_CSI_D4__CSI_D4                        0x128 0x320 0x000 0x10 0x000
+#define MX25_PAD_CSI_D4__UART5_RTS             0x128 0x320 0x574 0x11 0x001
+#define MX25_PAD_CSI_D4__GPIO_1_29             0x128 0x320 0x000 0x15 0x000
+#define MX25_PAD_CSI_D4__CSPI3_SCLK            0x128 0x320 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D5__CSI_D5                        0x12c 0x324 0x000 0x10 0x000
+#define MX25_PAD_CSI_D5__GPIO_1_30             0x12c 0x324 0x000 0x15 0x000
+#define MX25_PAD_CSI_D5__CSPI3_RDY             0x12c 0x324 0x000 0x17 0x000
+
+#define MX25_PAD_CSI_D6__CSI_D6                        0x130 0x328 0x000 0x10 0x000
+#define MX25_PAD_CSI_D6__GPIO_1_31             0x130 0x328 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D7__CSI_D7                        0x134 0x32c 0x000 0x10 0x000
+#define MX25_PAD_CSI_D7__GPIO_1_6              0x134 0x32c 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D8__CSI_D8                        0x138 0x330 0x000 0x10 0x000
+#define MX25_PAD_CSI_D8__GPIO_1_7              0x138 0x330 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_D9__CSI_D9                        0x13c 0x334 0x000 0x10 0x000
+#define MX25_PAD_CSI_D9__GPIO_4_21             0x13c 0x334 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_MCLK__CSI_MCLK            0x140 0x338 0x000 0x10 0x000
+#define MX25_PAD_CSI_MCLK__GPIO_1_8            0x140 0x338 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_VSYNC__CSI_VSYNC          0x144 0x33c 0x000 0x10 0x000
+#define MX25_PAD_CSI_VSYNC__GPIO_1_9           0x144 0x33c 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_HSYNC__CSI_HSYNC          0x148 0x340 0x000 0x10 0x000
+#define MX25_PAD_CSI_HSYNC__GPIO_1_10          0x148 0x340 0x000 0x15 0x000
+
+#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK                0x14c 0x344 0x000 0x10 0x000
+#define MX25_PAD_CSI_PIXCLK__GPIO_1_11         0x14c 0x344 0x000 0x15 0x000
+
+#define MX25_PAD_I2C1_CLK__I2C1_CLK            0x150 0x348 0x000 0x10 0x000
+#define MX25_PAD_I2C1_CLK__GPIO_1_12           0x150 0x348 0x000 0x15 0x000
+
+#define MX25_PAD_I2C1_DAT__I2C1_DAT            0x154 0x34c 0x000 0x10 0x000
+#define MX25_PAD_I2C1_DAT__GPIO_1_13           0x154 0x34c 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI                0x158 0x350 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_MOSI__GPIO_1_14         0x158 0x350 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_MISO__CSPI1_MISO                0x15c 0x354 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_MISO__GPIO_1_15         0x15c 0x354 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SS0__CSPI1_SS0          0x160 0x358 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SS0__GPIO_1_16          0x160 0x358 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SS1__CSPI1_SS1          0x164 0x35c 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SS1__GPIO_1_17          0x164 0x35c 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK                0x168 0x360 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_SCLK__GPIO_1_18         0x168 0x360 0x000 0x15 0x000
+
+#define MX25_PAD_CSPI1_RDY__CSPI1_RDY          0x16c 0x364 0x000 0x10 0x000
+#define MX25_PAD_CSPI1_RDY__GPIO_2_22          0x16c 0x364 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_RXD__UART1_RXD          0x170 0x368 0x000 0x10 0x000
+#define MX25_PAD_UART1_RXD__GPIO_4_22          0x170 0x368 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_TXD__UART1_TXD          0x174 0x36c 0x000 0x10 0x000
+#define MX25_PAD_UART1_TXD__GPIO_4_23          0x174 0x36c 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_RTS__UART1_RTS          0x178 0x370 0x000 0x10 0x000
+#define MX25_PAD_UART1_RTS__CSI_D0             0x178 0x370 0x488 0x11 0x001
+#define MX25_PAD_UART1_RTS__GPIO_4_24          0x178 0x370 0x000 0x15 0x000
+
+#define MX25_PAD_UART1_CTS__UART1_CTS          0x17c 0x374 0x000 0x10 0x000
+#define MX25_PAD_UART1_CTS__CSI_D1             0x17c 0x374 0x48c 0x11 0x001
+#define MX25_PAD_UART1_CTS__GPIO_4_25          0x17c 0x374 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_RXD__UART2_RXD          0x180 0x378 0x000 0x10 0x000
+#define MX25_PAD_UART2_RXD__GPIO_4_26          0x180 0x378 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_TXD__UART2_TXD          0x184 0x37c 0x000 0x10 0x000
+#define MX25_PAD_UART2_TXD__GPIO_4_27          0x184 0x37c 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_RTS__UART2_RTS          0x188 0x380 0x000 0x10 0x000
+#define MX25_PAD_UART2_RTS__FEC_COL            0x188 0x380 0x504 0x12 0x002
+#define MX25_PAD_UART2_RTS__GPIO_4_28          0x188 0x380 0x000 0x15 0x000
+
+#define MX25_PAD_UART2_CTS__FEC_RX_ER          0x18c 0x384 0x518 0x12 0x002
+#define MX25_PAD_UART2_CTS__UART2_CTS          0x18c 0x384 0x000 0x10 0x000
+#define MX25_PAD_UART2_CTS__GPIO_4_29          0x18c 0x384 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_CMD__SD1_CMD              0x190 0x388 0x000 0x10 0x000
+#define MX25_PAD_SD1_CMD__FEC_RDATA2           0x190 0x388 0x50c 0x12 0x002
+#define MX25_PAD_SD1_CMD__GPIO_2_23            0x190 0x388 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_CLK__SD1_CLK              0x194 0x38c 0x000 0x10 0x000
+#define MX25_PAD_SD1_CLK__FEC_RDATA3           0x194 0x38c 0x510 0x12 0x002
+#define MX25_PAD_SD1_CLK__GPIO_2_24            0x194 0x38c 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA0__SD1_DATA0          0x198 0x390 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA0__GPIO_2_25          0x198 0x390 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA1__SD1_DATA1          0x19c 0x394 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA1__AUD7_RXD           0x19c 0x394 0x478 0x13 0x000
+#define MX25_PAD_SD1_DATA1__GPIO_2_26          0x19c 0x394 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA2__SD1_DATA2          0x1a0 0x398 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA2__FEC_RX_CLK         0x1a0 0x398 0x514 0x15 0x002
+#define MX25_PAD_SD1_DATA2__GPIO_2_27          0x1a0 0x398 0x000 0x15 0x000
+
+#define MX25_PAD_SD1_DATA3__SD1_DATA3          0x1a4 0x39c 0x000 0x10 0x000
+#define MX25_PAD_SD1_DATA3__FEC_CRS            0x1a4 0x39c 0x508 0x10 0x002
+#define MX25_PAD_SD1_DATA3__GPIO_2_28          0x1a4 0x39c 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW0__KPP_ROW0            0x1a8 0x3a0 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW0__GPIO_2_29           0x1a8 0x3a0 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW1__KPP_ROW1            0x1ac 0x3a4 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW1__GPIO_2_30           0x1ac 0x3a4 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW2__KPP_ROW2            0x1b0 0x3a8 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW2__CSI_D0              0x1b0 0x3a8 0x488 0x13 0x002
+#define MX25_PAD_KPP_ROW2__GPIO_2_31           0x1b0 0x3a8 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_ROW3__KPP_ROW3            0x1b4 0x3ac 0x000 0x10 0x000
+#define MX25_PAD_KPP_ROW3__CSI_LD1             0x1b4 0x3ac 0x48c 0x13 0x002
+#define MX25_PAD_KPP_ROW3__GPIO_3_0            0x1b4 0x3ac 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL0__KPP_COL0            0x1b8 0x3b0 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL0__UART4_RXD_MUX       0x1b8 0x3b0 0x570 0x11 0x001
+#define MX25_PAD_KPP_COL0__AUD5_TXD            0x1b8 0x3b0 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL0__GPIO_3_1            0x1b8 0x3b0 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL1__KPP_COL1            0x1bc 0x3b4 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL1__UART4_TXD_MUX       0x1bc 0x3b4 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL1__AUD5_RXD            0x1bc 0x3b4 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL1__GPIO_3_2            0x1bc 0x3b4 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL2__KPP_COL2            0x1c0 0x3b8 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL2__UART4_RTS           0x1c0 0x3b8 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL2__AUD5_TXC            0x1c0 0x3b8 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL2__GPIO_3_3            0x1c0 0x3b8 0x000 0x15 0x000
+
+#define MX25_PAD_KPP_COL3__KPP_COL3            0x1c4 0x3bc 0x000 0x10 0x000
+#define MX25_PAD_KPP_COL3__UART4_CTS           0x1c4 0x3bc 0x000 0x11 0x000
+#define MX25_PAD_KPP_COL3__AUD5_TXFS           0x1c4 0x3bc 0x000 0x12 0x000
+#define MX25_PAD_KPP_COL3__GPIO_3_4            0x1c4 0x3bc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_MDC__FEC_MDC              0x1c8 0x3c0 0x000 0x10 0x000
+#define MX25_PAD_FEC_MDC__AUD4_TXD             0x1c8 0x3c0 0x464 0x12 0x001
+#define MX25_PAD_FEC_MDC__GPIO_3_5             0x1c8 0x3c0 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_MDIO__FEC_MDIO            0x1cc 0x3c4 0x000 0x10 0x000
+#define MX25_PAD_FEC_MDIO__AUD4_RXD            0x1cc 0x3c4 0x460 0x12 0x001
+#define MX25_PAD_FEC_MDIO__GPIO_3_6            0x1cc 0x3c4 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TDATA0__FEC_TDATA0                0x1d0 0x3c8 0x000 0x10 0x000
+#define MX25_PAD_FEC_TDATA0__GPIO_3_7          0x1d0 0x3c8 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TDATA1__FEC_TDATA1                0x1d4 0x3cc 0x000 0x10 0x000
+#define MX25_PAD_FEC_TDATA1__AUD4_TXFS         0x1d4 0x3cc 0x474 0x12 0x001
+#define MX25_PAD_FEC_TDATA1__GPIO_3_8          0x1d4 0x3cc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TX_EN__FEC_TX_EN          0x1d8 0x3d0 0x000 0x10 0x000
+#define MX25_PAD_FEC_TX_EN__GPIO_3_9           0x1d8 0x3d0 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RDATA0__FEC_RDATA0                0x1dc 0x3d4 0x000 0x10 0x000
+#define MX25_PAD_FEC_RDATA0__GPIO_3_10         0x1dc 0x3d4 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RDATA1__FEC_RDATA1                0x1e0 0x3d8 0x000 0x10 0x000
+#define MX25_PAD_FEC_RDATA1__GPIO_3_11         0x1e0 0x3d8 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_RX_DV__FEC_RX_DV          0x1e4 0x3dc 0x000 0x10 0x000
+#define MX25_PAD_FEC_RX_DV__CAN2_RX            0x1e4 0x3dc 0x484 0x14 0x000
+#define MX25_PAD_FEC_RX_DV__GPIO_3_12          0x1e4 0x3dc 0x000 0x15 0x000
+
+#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK                0x1e8 0x3e0 0x000 0x10 0x000
+#define MX25_PAD_FEC_TX_CLK__GPIO_3_13         0x1e8 0x3e0 0x000 0x15 0x000
+
+#define MX25_PAD_RTCK__RTCK                    0x1ec 0x3e4 0x000 0x10 0x000
+#define MX25_PAD_RTCK__OWIRE                   0x1ec 0x3e4 0x000 0x11 0x000
+#define MX25_PAD_RTCK__GPIO_3_14               0x1ec 0x3e4 0x000 0x15 0x000
+
+#define MX25_PAD_DE_B__DE_B                    0x1f0 0x3ec 0x000 0x10 0x000
+#define MX25_PAD_DE_B__GPIO_2_20               0x1f0 0x3ec 0x000 0x15 0x000
+
+#define MX25_PAD_TDO__TDO                      0x000 0x3e8 0x000 0x00 0x000
+
+#define MX25_PAD_GPIO_A__GPIO_A                        0x1f4 0x3f0 0x000 0x10 0x000
+#define MX25_PAD_GPIO_A__CAN1_TX               0x1f4 0x3f0 0x000 0x16 0x000
+#define MX25_PAD_GPIO_A__USBOTG_PWR            0x1f4 0x3f0 0x000 0x12 0x000
+
+#define MX25_PAD_GPIO_B__GPIO_B                        0x1f8 0x3f4 0x000 0x10 0x000
+#define MX25_PAD_GPIO_B__CAN1_RX               0x1f8 0x3f4 0x480 0x16 0x001
+#define MX25_PAD_GPIO_B__USBOTG_OC             0x1f8 0x3f4 0x57c 0x12 0x001
+
+#define MX25_PAD_GPIO_C__GPIO_C                        0x1fc 0x3f8 0x000 0x10 0x000
+#define MX25_PAD_GPIO_C__CAN2_TX               0x1fc 0x3f8 0x000 0x16 0x000
+
+#define MX25_PAD_GPIO_D__GPIO_D                        0x200 0x3fc 0x000 0x10 0x000
+#define MX25_PAD_GPIO_E__LD16                  0x204 0x400 0x000 0x02 0x000
+#define MX25_PAD_GPIO_D__CAN2_RX               0x200 0x3fc 0x484 0x16 0x001
+
+#define MX25_PAD_GPIO_E__GPIO_E                        0x204 0x400 0x000 0x10 0x000
+#define MX25_PAD_GPIO_F__LD17                  0x208 0x404 0x000 0x02 0x000
+#define MX25_PAD_GPIO_E__AUD7_TXD              0x204 0x400 0x000 0x14 0x000
+
+#define MX25_PAD_GPIO_F__GPIO_F                        0x208 0x404 0x000 0x10 0x000
+#define MX25_PAD_GPIO_F__AUD7_TXC              0x208 0x404 0x000 0x14 0x000
+
+#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK                0x20c 0x000 0x000 0x10 0x000
+#define MX25_PAD_EXT_ARMCLK__GPIO_3_15         0x20c 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK      0x210 0x000 0x000 0x10 0x000
+#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16                0x210 0x000 0x000 0x15 0x000
+
+#define MX25_PAD_VSTBY_REQ__VSTBY_REQ          0x214 0x408 0x000 0x10 0x000
+#define MX25_PAD_VSTBY_REQ__AUD7_TXFS          0x214 0x408 0x000 0x14 0x000
+#define MX25_PAD_VSTBY_REQ__GPIO_3_17          0x214 0x408 0x000 0x15 0x000
+#define MX25_PAD_VSTBY_ACK__VSTBY_ACK          0x218 0x40c 0x000 0x10 0x000
+#define MX25_PAD_VSTBY_ACK__GPIO_3_18          0x218 0x40c 0x000 0x15 0x000
+
+#define MX25_PAD_POWER_FAIL__POWER_FAIL                0x21c 0x410 0x000 0x10 0x000
+#define MX25_PAD_POWER_FAIL__AUD7_RXD          0x21c 0x410 0x478 0x14 0x001
+#define MX25_PAD_POWER_FAIL__GPIO_3_19         0x21c 0x410 0x000 0x15 0x000
+
+#define MX25_PAD_CLKO__CLKO                    0x220 0x414 0x000 0x10 0x000
+#define MX25_PAD_CLKO__GPIO_2_21               0x220 0x414 0x000 0x15 0x000
+
+#define MX25_PAD_BOOT_MODE0__BOOT_MODE0                0x224 0x000 0x000 0x00 0x000
+#define MX25_PAD_BOOT_MODE0__GPIO_4_30         0x224 0x000 0x000 0x05 0x000
+#define MX25_PAD_BOOT_MODE1__BOOT_MODE1                0x228 0x000 0x000 0x00 0x000
+#define MX25_PAD_BOOT_MODE1__GPIO_4_31         0x228 0x000 0x000 0x05 0x000
+
+#endif /* __DTS_IMX25_PINFUNC_H */
index 737ed5da8f715fec5180c60a6bdd33e9c6fefc9a..32f760e24898df9010b22b9efd21f400e5da5ab8 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "skeleton.dtsi"
+#include "imx25-pinfunc.h"
 
 / {
        aliases {
                                status = "disabled";
                        };
 
-                       iomuxc@43fac000{
+                       iomuxc: iomuxc@43fac000 {
                                compatible = "fsl,imx25-iomuxc";
                                reg = <0x43fac000 0x4000>;
                        };
 
-                       audmux@43fb0000 {
+                       audmux: audmux@43fb0000 {
                                compatible = "fsl,imx25-audmux", "fsl,imx31-audmux";
                                reg = <0x43fb0000 0x4000>;
                                status = "disabled";
                                compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
                                reg = <0x50014000 0x4000>;
                                interrupts = <11>;
+                               clocks = <&clks 118>;
+                               clock-names = "ipg";
+                               dmas = <&sdma 24 1 0>,
+                                      <&sdma 25 1 0>;
+                               dma-names = "rx", "tx";
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
                                reg = <0x50034000 0x4000>;
                                interrupts = <12>;
+                               clocks = <&clks 117>;
+                               clock-names = "ipg";
+                               dmas = <&sdma 28 1 0>,
+                                      <&sdma 29 1 0>;
+                               dma-names = "rx", "tx";
                                status = "disabled";
                        };
 
                                #interrupt-cells = <2>;
                        };
 
-                       sdma@53fd4000 {
+                       sdma: sdma@53fd4000 {
                                compatible = "fsl,imx25-sdma", "fsl,imx35-sdma";
                                reg = <0x53fd4000 0x4000>;
                                clocks = <&clks 112>, <&clks 68>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                interrupts = <34>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx25.bin";
                        };
 
                        wdog@53fdc000 {
index ba4c6df08ece2ec6e4cd0ce05437b61ffe407b2d..09f57b39e3ef37e7df1abd4321213bcca8626db5 100644 (file)
        };
 };
 
+&iomuxc {
+       imx27-apf27 {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <
+                               MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+                               MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+                               MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+                               MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+                               MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+                               MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+                               MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+                               MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+                               MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+                               MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+                               MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+                               MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+                               MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+                               MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+                               MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+                               MX27_PAD_ATA_DATA13__FEC_COL 0x0
+                               MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+                               MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX27_PAD_UART1_TXD__UART1_TXD 0x0
+                               MX27_PAD_UART1_RXD__UART1_RXD 0x0
+                       >;
+               };
+       };
+};
+
 &uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
        status = "okay";
 };
 
index 47c8c26012e4d24661124f15ff8396f428136797..2b6d489dae69f750280d5ea8ce04de1c489b78bf 100644 (file)
                bits-per-pixel = <16>;  /* non-standard but required */
                fsl,pcr = <0xfae80083>; /* non-standard but required */
                display-timings {
-                       timing0: 640x480 {
+                       timing0: 800x480 {
                                clock-frequency = <33000033>;
                                hactive = <800>;
-                               vactive = <640>;
+                               vactive = <480>;
                                hback-porch = <96>;
                                hfront-porch = <96>;
                                vback-porch = <20>;
 
        gpio-keys {
                compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
 
                user-key {
                        label = "user";
-                       gpios = <&gpio6 13 0>;
+                       gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
                        linux,code = <276>; /* BTN_EXTRA */
                };
        };
 
        leds {
                compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
 
                user {
                        label = "Heartbeat";
-                       gpios = <&gpio6 14 0>;
+                       gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>;
                        linux,default-trigger = "heartbeat";
                };
        };
 
 &cspi1 {
        fsl,spi-num-chipselects = <1>;
-       cs-gpios = <&gpio4 28 1>;
+       cs-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi1 &pinctrl_cspi1_cs>;
        status = "okay";
 };
 
 &cspi2 {
        fsl,spi-num-chipselects = <3>;
-       cs-gpios = <&gpio4 21 1>, <&gpio4 27 1>,
-                       <&gpio2 17 1>;
+       cs-gpios = <&gpio4 21 GPIO_ACTIVE_LOW>,
+                  <&gpio4 27 GPIO_ACTIVE_LOW>,
+                  <&gpio2 17 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi2 &pinctrl_cspi2_cs>;
        status = "okay";
 };
 
 &fb {
        display = <&display>;
        fsl,dmacr = <0x00020010>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_imxfb1>;
        status = "okay";
 };
 
 &i2c1 {
        clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        rtc@68 {
 };
 
 &i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 };
+
+&iomuxc {
+       imx27-apf27dev {
+               pinctrl_cspi1: cspi1grp {
+                       fsl,pins = <
+                               MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x0
+                               MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x0
+                               MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x0
+                       >;
+               };
+
+               pinctrl_cspi1_cs: cspi1csgrp {
+                       fsl,pins = <MX27_PAD_CSPI1_SS0__GPIO4_28 0x0>;
+               };
+
+               pinctrl_cspi2: cspi2grp {
+                       fsl,pins = <
+                               MX27_PAD_CSPI2_MISO__CSPI2_MISO 0x0
+                               MX27_PAD_CSPI2_MOSI__CSPI2_MOSI 0x0
+                               MX27_PAD_CSPI2_SCLK__CSPI2_SCLK 0x0
+                       >;
+               };
+
+               pinctrl_cspi2_cs: cspi2csgrp {
+                       fsl,pins = <
+                               MX27_PAD_CSI_D5__GPIO2_17 0x0
+                               MX27_PAD_CSPI2_SS0__GPIO4_21 0x0
+                               MX27_PAD_CSPI1_SS1__GPIO4_27 0x0
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <MX27_PAD_PC_VS1__GPIO6_14 0x0>;
+               };
+
+               pinctrl_gpio_keys: gpiokeysgrp {
+                       fsl,pins = <MX27_PAD_PC_VS2__GPIO6_13 0x0>;
+               };
+
+               pinctrl_imxfb1: imxfbgrp {
+                       fsl,pins = <
+                               MX27_PAD_CLS__CLS 0x0
+                               MX27_PAD_CONTRAST__CONTRAST 0x0
+                               MX27_PAD_LD0__LD0 0x0
+                               MX27_PAD_LD1__LD1 0x0
+                               MX27_PAD_LD2__LD2 0x0
+                               MX27_PAD_LD3__LD3 0x0
+                               MX27_PAD_LD4__LD4 0x0
+                               MX27_PAD_LD5__LD5 0x0
+                               MX27_PAD_LD6__LD6 0x0
+                               MX27_PAD_LD7__LD7 0x0
+                               MX27_PAD_LD8__LD8 0x0
+                               MX27_PAD_LD9__LD9 0x0
+                               MX27_PAD_LD10__LD10 0x0
+                               MX27_PAD_LD11__LD11 0x0
+                               MX27_PAD_LD12__LD12 0x0
+                               MX27_PAD_LD13__LD13 0x0
+                               MX27_PAD_LD14__LD14 0x0
+                               MX27_PAD_LD15__LD15 0x0
+                               MX27_PAD_LD16__LD16 0x0
+                               MX27_PAD_LD17__LD17 0x0
+                               MX27_PAD_LSCLK__LSCLK 0x0
+                               MX27_PAD_OE_ACD__OE_ACD 0x0
+                               MX27_PAD_PS__PS 0x0
+                               MX27_PAD_REV__REV 0x0
+                               MX27_PAD_SPL_SPR__SPL_SPR 0x0
+                               MX27_PAD_HSYNC__HSYNC 0x0
+                               MX27_PAD_VSYNC__VSYNC 0x0
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX27_PAD_I2C_DATA__I2C_DATA 0x0
+                               MX27_PAD_I2C_CLK__I2C_CLK 0x0
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+                               MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+                       >;
+               };
+
+               pinctrl_pwm: pwmgrp {
+                       fsl,pins = <
+                               MX27_PAD_PWMO__PWMO 0x0
+                       >;
+               };
+
+               pinctrl_sdhc2: sdhc2grp {
+                       fsl,pins = <
+                               MX27_PAD_SD2_CLK__SD2_CLK 0x0
+                               MX27_PAD_SD2_CMD__SD2_CMD 0x0
+                               MX27_PAD_SD2_D0__SD2_D0 0x0
+                               MX27_PAD_SD2_D1__SD2_D1 0x0
+                               MX27_PAD_SD2_D2__SD2_D2 0x0
+                               MX27_PAD_SD2_D3__SD2_D3 0x0
+                       >;
+               };
+
+               pinctrl_sdhc2_cd: sdhc2cdgrp {
+                       fsl,pins = <MX27_PAD_TOUT__GPIO3_14 0x0>;
+               };
+       };
+};
+
+&sdhci2 {
+       bus-width = <4>;
+       cd-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdhc2 &pinctrl_sdhc2_cd>;
+       status = "okay";
+};
+
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm>;
+};
index 5a31c776513f5705e94a5f1a5f306740e898c201..3c3964a996376e6aa125adb72784b7ebd40fba70 100644 (file)
@@ -9,7 +9,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-#include "imx27-phytec-phycard-s-som.dts"
+#include "imx27-phytec-phycard-s-som.dtsi"
 
 / {
        model = "Phytec pca100 rapid development kit";
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3v3: 3v3 {
+               reg_3v3: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3V3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
@@ -54,6 +57,8 @@
 };
 
 &i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        rtc@51 {
        };
 };
 
+&iomuxc {
+       imx27-phycard-s-rdk {
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+                               MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+                       >;
+               };
+
+               pinctrl_owire1: owire1grp {
+                       fsl,pins = <
+                               MX27_PAD_RTCK__OWIRE 0x0
+                       >;
+               };
+
+               pinctrl_sdhc2: sdhc2grp {
+                       fsl,pins = <
+                               MX27_PAD_SD2_CLK__SD2_CLK 0x0
+                               MX27_PAD_SD2_CMD__SD2_CMD 0x0
+                               MX27_PAD_SD2_D0__SD2_D0 0x0
+                               MX27_PAD_SD2_D1__SD2_D1 0x0
+                               MX27_PAD_SD2_D2__SD2_D2 0x0
+                               MX27_PAD_SD2_D3__SD2_D3 0x0
+                               MX27_PAD_SSI3_RXDAT__GPIO3_29 0x0 /* CD */
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX27_PAD_UART1_TXD__UART1_TXD 0x0
+                               MX27_PAD_UART1_RXD__UART1_RXD 0x0
+                               MX27_PAD_UART1_CTS__UART1_CTS 0x0
+                               MX27_PAD_UART1_RTS__UART1_RTS 0x0
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX27_PAD_UART2_TXD__UART2_TXD 0x0
+                               MX27_PAD_UART2_RXD__UART2_RXD 0x0
+                               MX27_PAD_UART2_CTS__UART2_CTS 0x0
+                               MX27_PAD_UART2_RTS__UART2_RTS 0x0
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX27_PAD_UART3_TXD__UART3_TXD 0x0
+                               MX27_PAD_UART3_RXD__UART3_RXD 0x0
+                               MX27_PAD_UART3_CTS__UART3_CTS 0x0
+                               MX27_PAD_UART3_RTS__UART3_RTS 0x0
+                       >;
+               };
+       };
+};
+
 &owire {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_owire1>;
        status = "okay";
 };
 
 &sdhci2 {
-       cd-gpios = <&gpio3 29 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdhc2>;
+       cd-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
 &uart1 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart2 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &uart3 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dts b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dts
deleted file mode 100644 (file)
index c8d57d1..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012 Sascha Hauer, Uwe Kleine-König, Steffen Trumtrar
- * and Markus Pargmann, Pengutronix
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/dts-v1/;
-#include "imx27.dtsi"
-
-/ {
-       model = "Phytec pca100";
-       compatible = "phytec,imx27-pca100", "fsl,imx27";
-
-       memory {
-               reg = <0xa0000000 0x08000000>; /* 128MB */
-       };
-};
-
-&cspi1 {
-       fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio4 28 0>,
-               <&gpio4 27 0>;
-       status = "okay";
-};
-
-&fec {
-       status = "okay";
-};
-
-&i2c2 {
-       status = "okay";
-
-       at24@52 {
-               compatible = "at,24c32";
-               pagesize = <32>;
-               reg = <0x52>;
-       };
-};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi
new file mode 100644 (file)
index 0000000..1b62480
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 Sascha Hauer, Uwe Kleine-König, Steffen Trumtrar
+ * and Markus Pargmann, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+       model = "Phytec pca100";
+       compatible = "phytec,imx27-pca100", "fsl,imx27";
+
+       memory {
+               reg = <0xa0000000 0x08000000>; /* 128MB */
+       };
+};
+
+&cspi1 {
+       fsl,spi-num-chipselects = <2>;
+       cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 27 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       at24@52 {
+               compatible = "at,24c32";
+               pagesize = <32>;
+               reg = <0x52>;
+       };
+};
+
+&iomuxc {
+       imx27-phycard-s-som {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <
+                               MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+                               MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+                               MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+                               MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+                               MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+                               MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+                               MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+                               MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+                               MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+                               MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+                               MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+                               MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+                               MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+                               MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+                               MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+                               MX27_PAD_ATA_DATA13__FEC_COL 0x0
+                               MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+                               MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+                               MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+                       >;
+               };
+
+               pinctrl_nfc: nfcgrp {
+                       fsl,pins = <
+                               MX27_PAD_NFRB__NFRB 0x0
+                               MX27_PAD_NFCLE__NFCLE 0x0
+                               MX27_PAD_NFWP_B__NFWP_B 0x0
+                               MX27_PAD_NFCE_B__NFCE_B 0x0
+                               MX27_PAD_NFALE__NFALE 0x0
+                               MX27_PAD_NFRE_B__NFRE_B 0x0
+                               MX27_PAD_NFWE_B__NFWE_B 0x0
+                       >;
+               };
+       };
+};
+
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_nfc>;
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
index 0fc6551786c6817216045c8ddfc86a6c5790d58e..df3b2e7318358e6dc65cdee4459f4714873bc301 100644 (file)
@@ -7,7 +7,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-#include "imx27-phytec-phycore-som.dts"
+#include "imx27-phytec-phycore-som.dtsi"
 
 / {
        model = "Phytec pcm970";
 
 &cspi1 {
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio4 28 0>, <&gpio4 27 0>;
+       cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 27 GPIO_ACTIVE_LOW>;
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       camgpio: pca9536@41 {
+               compatible = "nxp,pca9536";
+               reg = <0x41>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&iomuxc {
+       imx27_phycore_rdk {
+               pinctrl_i2c1: i2c1grp {
+                       /* Add pullup to DATA line */
+                       fsl,pins = <
+                               MX27_PAD_I2C_DATA__I2C_DATA     0x1
+                               MX27_PAD_I2C_CLK__I2C_CLK       0x0
+                       >;
+               };
+
+               pinctrl_owire1: owire1grp {
+                       fsl,pins = <
+                               MX27_PAD_RTCK__OWIRE 0x0
+                       >;
+               };
+
+               pinctrl_sdhc2: sdhc2grp {
+                       fsl,pins = <
+                               MX27_PAD_SD2_CLK__SD2_CLK 0x0
+                               MX27_PAD_SD2_CMD__SD2_CMD 0x0
+                               MX27_PAD_SD2_D0__SD2_D0 0x0
+                               MX27_PAD_SD2_D1__SD2_D1 0x0
+                               MX27_PAD_SD2_D2__SD2_D2 0x0
+                               MX27_PAD_SD2_D3__SD2_D3 0x0
+                               MX27_PAD_SSI3_FS__GPIO3_28      0x0 /* WP */
+                               MX27_PAD_SSI3_RXDAT__GPIO3_29   0x0 /* CD */
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX27_PAD_UART1_TXD__UART1_TXD 0x0
+                               MX27_PAD_UART1_RXD__UART1_RXD 0x0
+                               MX27_PAD_UART1_CTS__UART1_CTS 0x0
+                               MX27_PAD_UART1_RTS__UART1_RTS 0x0
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX27_PAD_UART2_TXD__UART2_TXD 0x0
+                               MX27_PAD_UART2_RXD__UART2_RXD 0x0
+                               MX27_PAD_UART2_CTS__UART2_CTS 0x0
+                               MX27_PAD_UART2_RTS__UART2_RTS 0x0
+                       >;
+               };
+
+               pinctrl_usbh2: usbh2grp {
+                       fsl,pins = <
+                               MX27_PAD_USBH2_CLK__USBH2_CLK 0x0
+                               MX27_PAD_USBH2_DIR__USBH2_DIR 0x0
+                               MX27_PAD_USBH2_NXT__USBH2_NXT 0x0
+                               MX27_PAD_USBH2_STP__USBH2_STP 0x0
+                               MX27_PAD_CSPI2_SCLK__USBH2_DATA0 0x0
+                               MX27_PAD_CSPI2_MOSI__USBH2_DATA1 0x0
+                               MX27_PAD_CSPI2_MISO__USBH2_DATA2 0x0
+                               MX27_PAD_CSPI2_SS1__USBH2_DATA3 0x0
+                               MX27_PAD_CSPI2_SS2__USBH2_DATA4 0x0
+                               MX27_PAD_CSPI1_SS2__USBH2_DATA5 0x0
+                               MX27_PAD_CSPI2_SS0__USBH2_DATA6 0x0
+                               MX27_PAD_USBH2_DATA7__USBH2_DATA7 0x0
+                       >;
+               };
+
+               pinctrl_weim: weimgrp {
+                       fsl,pins = <
+                               MX27_PAD_CS4_B__CS4_B           0x0 /* CS4 */
+                               MX27_PAD_SD1_D1__GPIO5_19       0x0 /* CAN IRQ */
+                       >;
+               };
+       };
+};
+
+&owire {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_owire1>;
+       status = "okay";
+};
+
+&pmicleds {
+       ledr1: led@3 {
+               reg = <3>;
+               label = "system:red1:user";
+       };
+
+       ledg1: led@4 {
+               reg = <4>;
+               label = "system:green1:user";
+       };
+
+       ledb1: led@5 {
+               reg = <5>;
+               label = "system:blue1:user";
+       };
+
+       ledr2: led@6 {
+               reg = <6>;
+               label = "system:red2:user";
+       };
+
+       ledg2: led@7 {
+               reg = <7>;
+               label = "system:green2:user";
+       };
+
+       ledb2: led@8 {
+               reg = <8>;
+               label = "system:blue2:user";
+       };
+
+       ledr3: led@9 {
+               reg = <9>;
+               label = "system:red3:nand";
+               linux,default-trigger = "nand-disk";
+       };
+
+       ledg3: led@10 {
+               reg = <10>;
+               label = "system:green3:live";
+               linux,default-trigger = "heartbeat";
+       };
+
+       ledb3: led@11 {
+               reg = <11>;
+               label = "system:blue3:cpu";
+               linux,default-trigger = "cpu0";
+       };
 };
 
 &sdhci2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdhc2>;
        bus-width = <4>;
-       cd-gpios = <&gpio3 29 0>;
-       wp-gpios = <&gpio3 28 0>;
+       cd-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+       wp-gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
        vmmc-supply = <&vmmc1_reg>;
        status = "okay";
 };
 
 &uart1 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
 };
 
 &uart2 {
        fsl,uart-has-rtscts;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbh2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh2>;
+       dr_mode = "host";
+       phy_type = "ulpi";
+       vbus-supply = <&reg_5v0>;
+       disable-over-current;
        status = "okay";
 };
 
+&usbphy2 {
+       vcc-supply = <&reg_5v0>;
+};
+
 &weim {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_weim>;
+
        can@d4000000 {
                compatible = "nxp,sja1000";
                reg = <4 0x00000000 0x00000100>;
                interrupt-parent = <&gpio5>;
-               interrupts = <19 0x2>;
+               interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
                nxp,external-clock-frequency = <16000000>;
                nxp,tx-output-config = <0x16>;
                nxp,no-comparator-bypass;
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-som.dts b/arch/arm/boot/dts/imx27-phytec-phycore-som.dts
deleted file mode 100644 (file)
index 4ec402c..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2012 Sascha Hauer, Pengutronix
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/dts-v1/;
-#include "imx27.dtsi"
-
-/ {
-       model = "Phytec pcm038";
-       compatible = "phytec,imx27-pcm038", "fsl,imx27";
-
-       memory {
-               reg = <0xa0000000 0x08000000>;
-       };
-};
-
-&audmux {
-       status = "okay";
-
-       /* SSI0 <=> PINS_4 (MC13783 Audio) */
-       ssi0 {
-               fsl,audmux-port = <0>;
-               fsl,port-config = <0xcb205000>;
-       };
-
-       pins4 {
-               fsl,audmux-port = <2>;
-               fsl,port-config = <0x00001000>;
-       };
-};
-
-&cspi1 {
-       fsl,spi-num-chipselects = <1>;
-       cs-gpios = <&gpio4 28 0>;
-       status = "okay";
-
-       pmic: mc13783@0 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "fsl,mc13783";
-               spi-max-frequency = <20000000>;
-               reg = <0>;
-               interrupt-parent = <&gpio2>;
-               interrupts = <23 0x4>;
-               fsl,mc13xxx-uses-adc;
-               fsl,mc13xxx-uses-rtc;
-
-               regulators {
-                       /* SW1A and SW1B joined operation */
-                       sw1_reg: sw1a {
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <1520000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       /* SW2A and SW2B joined operation */
-                       sw2_reg: sw2a {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       sw3_reg: sw3 {
-                               regulator-min-microvolt = <5000000>;
-                               regulator-max-microvolt = <5000000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       vaudio_reg: vaudio {
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       violo_reg: violo {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       viohi_reg: viohi {
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       vgen_reg: vgen {
-                               regulator-min-microvolt = <1500000>;
-                               regulator-max-microvolt = <1500000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       vcam_reg: vcam {
-                               regulator-min-microvolt = <2800000>;
-                               regulator-max-microvolt = <2800000>;
-                       };
-
-                       vrf1_reg: vrf1 {
-                               regulator-min-microvolt = <2775000>;
-                               regulator-max-microvolt = <2775000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       vrf2_reg: vrf2 {
-                               regulator-min-microvolt = <2775000>;
-                               regulator-max-microvolt = <2775000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                       };
-
-                       vmmc1_reg: vmmc1 {
-                               regulator-min-microvolt = <1600000>;
-                               regulator-max-microvolt = <3000000>;
-                       };
-
-                       gpo1_reg: gpo1 { };
-
-                       pwgt1spi_reg: pwgt1spi {
-                               regulator-always-on;
-                       };
-               };
-       };
-};
-
-&fec {
-       phy-reset-gpios = <&gpio3 30 0>;
-       status = "okay";
-};
-
-&i2c2 {
-       clock-frequency = <400000>;
-       status = "okay";
-
-       at24@52 {
-               compatible = "at,24c32";
-               pagesize = <32>;
-               reg = <0x52>;
-       };
-
-       pcf8563@51 {
-               compatible = "nxp,pcf8563";
-               reg = <0x51>;
-       };
-
-       lm75@4a {
-               compatible = "national,lm75";
-               reg = <0x4a>;
-       };
-};
-
-&nfc {
-       nand-bus-width = <8>;
-       nand-ecc-mode = "hw";
-       status = "okay";
-};
-
-&uart1 {
-       status = "okay";
-};
-
-&weim {
-       status = "okay";
-
-       nor: nor@c0000000 {
-               compatible = "cfi-flash";
-               reg = <0 0x00000000 0x02000000>;
-               bank-width = <2>;
-               linux,mtd-name = "physmap-flash.0";
-               fsl,weim-cs-timing = <0x22c2cf00 0x75000d01 0x00000900>;
-               #address-cells = <1>;
-               #size-cells = <1>;
-       };
-
-       sram: sram@c8000000 {
-               compatible = "mtd-ram";
-               reg = <1 0x00000000 0x00800000>;
-               bank-width = <2>;
-               linux,mtd-name = "mtd-ram.0";
-               fsl,weim-cs-timing = <0x0000d843 0x22252521 0x22220a00>;
-               #address-cells = <1>;
-               #size-cells = <1>;
-       };
-};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi
new file mode 100644 (file)
index 0000000..cefaa69
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+       model = "Phytec pcm038";
+       compatible = "phytec,imx27-pcm038", "fsl,imx27";
+
+       memory {
+               reg = <0xa0000000 0x08000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3v3: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+
+               reg_5v0: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "5V0";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+               };
+       };
+};
+
+&audmux {
+       status = "okay";
+
+       /* SSI0 <=> PINS_4 (MC13783 Audio) */
+       ssi0 {
+               fsl,audmux-port = <0>;
+               fsl,port-config = <0xcb205000>;
+       };
+
+       pins4 {
+               fsl,audmux-port = <2>;
+               fsl,port-config = <0x00001000>;
+       };
+};
+
+&cspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi1>;
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+
+       pmic: mc13783@0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "fsl,mc13783";
+               reg = <0>;
+               spi-cs-high;
+               spi-max-frequency = <20000000>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
+               fsl,mc13xxx-uses-adc;
+               fsl,mc13xxx-uses-rtc;
+
+               pmicleds: leds {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       led-control = <0x001 0x000 0x000 0x000 0x000 0x000>;
+               };
+
+               regulators {
+                       /* SW1A and SW1B joined operation */
+                       sw1_reg: sw1a {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1520000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       /* SW2A and SW2B joined operation */
+                       sw2_reg: sw2a {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       sw3_reg: sw3 {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vaudio_reg: vaudio {
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       violo_reg: violo {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       viohi_reg: viohi {
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vgen_reg: vgen {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vcam_reg: vcam {
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                       };
+
+                       vrf1_reg: vrf1 {
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vrf2_reg: vrf2 {
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vmmc1_reg: vmmc1 {
+                               regulator-min-microvolt = <1600000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+
+                       gpo1_reg: gpo1 { };
+
+                       pwgt1spi_reg: pwgt1spi {
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&fec {
+       phy-mode = "mii";
+       phy-reset-gpios = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+       phy-supply = <&reg_3v3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       status = "okay";
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       at24@52 {
+               compatible = "at,24c32";
+               pagesize = <32>;
+               reg = <0x52>;
+       };
+
+       pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+
+       lm75@4a {
+               compatible = "national,lm75";
+               reg = <0x4a>;
+       };
+};
+
+&iomuxc {
+       imx27_phycore_som {
+               pinctrl_cspi1: cspi1grp {
+                       fsl,pins = <
+                               MX27_PAD_CSPI1_MISO__CSPI1_MISO 0x0
+                               MX27_PAD_CSPI1_MOSI__CSPI1_MOSI 0x0
+                               MX27_PAD_CSPI1_SCLK__CSPI1_SCLK 0x0
+                               MX27_PAD_CSPI1_SS0__GPIO4_28    0x0 /* SPI1 CS0 */
+                               MX27_PAD_USB_PWR__GPIO2_23      0x0 /* PMIC IRQ */
+                       >;
+               };
+
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <
+                               MX27_PAD_SD3_CMD__FEC_TXD0 0x0
+                               MX27_PAD_SD3_CLK__FEC_TXD1 0x0
+                               MX27_PAD_ATA_DATA0__FEC_TXD2 0x0
+                               MX27_PAD_ATA_DATA1__FEC_TXD3 0x0
+                               MX27_PAD_ATA_DATA2__FEC_RX_ER 0x0
+                               MX27_PAD_ATA_DATA3__FEC_RXD1 0x0
+                               MX27_PAD_ATA_DATA4__FEC_RXD2 0x0
+                               MX27_PAD_ATA_DATA5__FEC_RXD3 0x0
+                               MX27_PAD_ATA_DATA6__FEC_MDIO 0x0
+                               MX27_PAD_ATA_DATA7__FEC_MDC 0x0
+                               MX27_PAD_ATA_DATA8__FEC_CRS 0x0
+                               MX27_PAD_ATA_DATA9__FEC_TX_CLK 0x0
+                               MX27_PAD_ATA_DATA10__FEC_RXD0 0x0
+                               MX27_PAD_ATA_DATA11__FEC_RX_DV 0x0
+                               MX27_PAD_ATA_DATA12__FEC_RX_CLK 0x0
+                               MX27_PAD_ATA_DATA13__FEC_COL 0x0
+                               MX27_PAD_ATA_DATA14__FEC_TX_ER 0x0
+                               MX27_PAD_ATA_DATA15__FEC_TX_EN 0x0
+                               MX27_PAD_SSI3_TXDAT__GPIO3_30   0x0 /* FEC RST */
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX27_PAD_I2C2_SDA__I2C2_SDA 0x0
+                               MX27_PAD_I2C2_SCL__I2C2_SCL 0x0
+                       >;
+               };
+
+               pinctrl_nfc: nfcgrp {
+                       fsl,pins = <
+                               MX27_PAD_NFRB__NFRB 0x0
+                               MX27_PAD_NFCLE__NFCLE 0x0
+                               MX27_PAD_NFWP_B__NFWP_B 0x0
+                               MX27_PAD_NFCE_B__NFCE_B 0x0
+                               MX27_PAD_NFALE__NFALE 0x0
+                               MX27_PAD_NFRE_B__NFRE_B 0x0
+                               MX27_PAD_NFWE_B__NFWE_B 0x0
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX27_PAD_USBOTG_CLK__USBOTG_CLK 0x0
+                               MX27_PAD_USBOTG_DIR__USBOTG_DIR 0x0
+                               MX27_PAD_USBOTG_NXT__USBOTG_NXT 0x0
+                               MX27_PAD_USBOTG_STP__USBOTG_STP 0x0
+                               MX27_PAD_USBOTG_DATA0__USBOTG_DATA0 0x0
+                               MX27_PAD_USBOTG_DATA1__USBOTG_DATA1 0x0
+                               MX27_PAD_USBOTG_DATA2__USBOTG_DATA2 0x0
+                               MX27_PAD_USBOTG_DATA3__USBOTG_DATA3 0x0
+                               MX27_PAD_USBOTG_DATA4__USBOTG_DATA4 0x0
+                               MX27_PAD_USBOTG_DATA5__USBOTG_DATA5 0x0
+                               MX27_PAD_USBOTG_DATA6__USBOTG_DATA6 0x0
+                               MX27_PAD_USBOTG_DATA7__USBOTG_DATA7 0x0
+                       >;
+               };
+       };
+};
+
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_nfc>;
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
+
+&usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       dr_mode = "otg";
+       phy_type = "ulpi";
+       vbus-supply = <&sw3_reg>;
+       status = "okay";
+};
+
+&usbphy0 {
+       vcc-supply = <&sw3_reg>;
+};
+
+&weim {
+       status = "okay";
+
+       nor: nor@c0000000 {
+               compatible = "cfi-flash";
+               reg = <0 0x00000000 0x02000000>;
+               bank-width = <2>;
+               linux,mtd-name = "physmap-flash.0";
+               fsl,weim-cs-timing = <0x22c2cf00 0x75000d01 0x00000900>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       sram: sram@c8000000 {
+               compatible = "mtd-ram";
+               reg = <1 0x00000000 0x00800000>;
+               bank-width = <2>;
+               linux,mtd-name = "mtd-ram.0";
+               fsl,weim-cs-timing = <0x0000d843 0x22252521 0x22220a00>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
diff --git a/arch/arm/boot/dts/imx27-pinfunc.h b/arch/arm/boot/dts/imx27-pinfunc.h
new file mode 100644 (file)
index 0000000..f5387b4
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2013 Markus Pargmann <mpa@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+#ifndef __DTS_IMX27_PINFUNC_H
+#define __DTS_IMX27_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <pin mux_id>
+ * mux_id consists of
+ * function + (direction << 2) + (gpio_oconf << 4) + (gpio_iconfa << 8) + (gpio_iconfb << 10)
+ *
+ * function:      0 - Primary function
+ *                1 - Alternate function
+ *                2 - GPIO
+ * direction:     0 - Input
+ *                1 - Output
+ * gpio_oconf:    0 - A_IN
+ *                1 - B_IN
+ *                2 - C_IN
+ *                3 - Data Register
+ * gpio_iconfa/b: 0 - GPIO_IN
+ *                1 - Interrupt Status Register
+ *                2 - 0
+ *                3 - 1
+ *
+ * 'pin' is an integer between 0 and 0xbf. imx27 has 6 ports with 32 configurable
+ * configurable pins each. 'pin' is PORT * 32 + PORT_PIN, PORT_PIN is the pin
+ * number on the specific port (between 0 and 31).
+ */
+
+#define MX27_PAD_USBH2_CLK__USBH2_CLK                      0x00 0x000
+#define MX27_PAD_USBH2_CLK__GPIO1_0                        0x00 0x032
+#define MX27_PAD_USBH2_DIR__USBH2_DIR                      0x01 0x000
+#define MX27_PAD_USBH2_DIR__GPIO1_1                        0x01 0x032
+#define MX27_PAD_USBH2_DATA7__USBH2_DATA7                  0x02 0x004
+#define MX27_PAD_USBH2_DATA7__GPIO1_2                      0x02 0x032
+#define MX27_PAD_USBH2_NXT__USBH2_NXT                      0x03 0x000
+#define MX27_PAD_USBH2_NXT__GPIO1_3                        0x03 0x032
+#define MX27_PAD_USBH2_STP__USBH2_STP                      0x04 0x004
+#define MX27_PAD_USBH2_STP__GPIO1_4                        0x04 0x032
+#define MX27_PAD_LSCLK__LSCLK                              0x05 0x004
+#define MX27_PAD_LSCLK__GPIO1_5                            0x05 0x032
+#define MX27_PAD_LD0__LD0                                  0x06 0x004
+#define MX27_PAD_LD0__GPIO1_6                              0x06 0x032
+#define MX27_PAD_LD1__LD1                                  0x07 0x004
+#define MX27_PAD_LD1__GPIO1_7                              0x07 0x032
+#define MX27_PAD_LD2__LD2                                  0x08 0x004
+#define MX27_PAD_LD2__GPIO1_8                              0x08 0x032
+#define MX27_PAD_LD3__LD3                                  0x09 0x004
+#define MX27_PAD_LD3__GPIO1_9                              0x09 0x032
+#define MX27_PAD_LD4__LD4                                  0x0a 0x004
+#define MX27_PAD_LD4__GPIO1_10                             0x0a 0x032
+#define MX27_PAD_LD5__LD5                                  0x0b 0x004
+#define MX27_PAD_LD5__GPIO1_11                             0x0b 0x032
+#define MX27_PAD_LD6__LD6                                  0x0c 0x004
+#define MX27_PAD_LD6__GPIO1_12                             0x0c 0x032
+#define MX27_PAD_LD7__LD7                                  0x0d 0x004
+#define MX27_PAD_LD7__GPIO1_13                             0x0d 0x032
+#define MX27_PAD_LD8__LD8                                  0x0e 0x004
+#define MX27_PAD_LD8__GPIO1_14                             0x0e 0x032
+#define MX27_PAD_LD9__LD9                                  0x0f 0x004
+#define MX27_PAD_LD9__GPIO1_15                             0x0f 0x032
+#define MX27_PAD_LD10__LD10                                0x10 0x004
+#define MX27_PAD_LD10__GPIO1_16                            0x10 0x032
+#define MX27_PAD_LD11__LD11                                0x11 0x004
+#define MX27_PAD_LD11__GPIO1_17                            0x11 0x032
+#define MX27_PAD_LD12__LD12                                0x12 0x004
+#define MX27_PAD_LD12__GPIO1_18                            0x12 0x032
+#define MX27_PAD_LD13__LD13                                0x13 0x004
+#define MX27_PAD_LD13__GPIO1_19                            0x13 0x032
+#define MX27_PAD_LD14__LD14                                0x14 0x004
+#define MX27_PAD_LD14__GPIO1_20                            0x14 0x032
+#define MX27_PAD_LD15__LD15                                0x15 0x004
+#define MX27_PAD_LD15__GPIO1_21                            0x15 0x032
+#define MX27_PAD_LD16__LD16                                0x16 0x004
+#define MX27_PAD_LD16__GPIO1_22                            0x16 0x032
+#define MX27_PAD_LD17__LD17                                0x17 0x004
+#define MX27_PAD_LD17__GPIO1_23                            0x17 0x032
+#define MX27_PAD_REV__REV                                  0x18 0x004
+#define MX27_PAD_REV__GPIO1_24                             0x18 0x032
+#define MX27_PAD_CLS__CLS                                  0x19 0x004
+#define MX27_PAD_CLS__GPIO1_25                             0x19 0x032
+#define MX27_PAD_PS__PS                                    0x1a 0x004
+#define MX27_PAD_PS__GPIO1_26                              0x1a 0x032
+#define MX27_PAD_SPL_SPR__SPL_SPR                          0x1b 0x004
+#define MX27_PAD_SPL_SPR__GPIO1_27                         0x1b 0x032
+#define MX27_PAD_HSYNC__HSYNC                              0x1c 0x004
+#define MX27_PAD_HSYNC__GPIO1_28                           0x1c 0x032
+#define MX27_PAD_VSYNC__VSYNC                              0x1d 0x004
+#define MX27_PAD_VSYNC__GPIO1_29                           0x1d 0x032
+#define MX27_PAD_CONTRAST__CONTRAST                        0x1e 0x004
+#define MX27_PAD_CONTRAST__GPIO1_30                        0x1e 0x032
+#define MX27_PAD_OE_ACD__OE_ACD                            0x1f 0x004
+#define MX27_PAD_OE_ACD__GPIO1_31                          0x1f 0x032
+#define MX27_PAD_UNUSED0__UNUSED0                          0x20 0x004
+#define MX27_PAD_UNUSED0__GPIO2_0                          0x20 0x032
+#define MX27_PAD_UNUSED1__UNUSED1                          0x21 0x004
+#define MX27_PAD_UNUSED1__GPIO2_1                          0x21 0x032
+#define MX27_PAD_UNUSED2__UNUSED2                          0x22 0x004
+#define MX27_PAD_UNUSED2__GPIO2_2                          0x22 0x032
+#define MX27_PAD_UNUSED3__UNUSED3                          0x23 0x004
+#define MX27_PAD_UNUSED3__GPIO2_3                          0x23 0x032
+#define MX27_PAD_SD2_D0__SD2_D0                            0x24 0x004
+#define MX27_PAD_SD2_D0__MSHC_DATA0                        0x24 0x005
+#define MX27_PAD_SD2_D0__GPIO2_4                           0x24 0x032
+#define MX27_PAD_SD2_D1__SD2_D1                            0x25 0x004
+#define MX27_PAD_SD2_D1__MSHC_DATA1                        0x25 0x005
+#define MX27_PAD_SD2_D1__GPIO2_5                           0x25 0x032
+#define MX27_PAD_SD2_D2__SD2_D2                            0x26 0x004
+#define MX27_PAD_SD2_D2__MSHC_DATA2                        0x26 0x005
+#define MX27_PAD_SD2_D2__GPIO2_6                           0x26 0x032
+#define MX27_PAD_SD2_D3__SD2_D3                            0x27 0x004
+#define MX27_PAD_SD2_D3__MSHC_DATA3                        0x27 0x005
+#define MX27_PAD_SD2_D3__GPIO2_7                           0x27 0x032
+#define MX27_PAD_SD2_CMD__SD2_CMD                          0x28 0x004
+#define MX27_PAD_SD2_CMD__MSHC_BS                          0x28 0x005
+#define MX27_PAD_SD2_CMD__GPIO2_8                          0x28 0x032
+#define MX27_PAD_SD2_CLK__SD2_CLK                          0x29 0x004
+#define MX27_PAD_SD2_CLK__MSHC_SCLK                        0x29 0x005
+#define MX27_PAD_SD2_CLK__GPIO2_9                          0x29 0x032
+#define MX27_PAD_CSI_D0__CSI_D0                            0x2a 0x000
+#define MX27_PAD_CSI_D0__UART6_TXD                         0x2a 0x005
+#define MX27_PAD_CSI_D0__GPIO2_10                          0x2a 0x032
+#define MX27_PAD_CSI_D1__CSI_D1                            0x2b 0x000
+#define MX27_PAD_CSI_D1__UART6_RXD                         0x2b 0x001
+#define MX27_PAD_CSI_D1__GPIO2_11                          0x2b 0x032
+#define MX27_PAD_CSI_D2__CSI_D2                            0x2c 0x000
+#define MX27_PAD_CSI_D2__UART6_CTS                         0x2c 0x005
+#define MX27_PAD_CSI_D2__GPIO2_12                          0x2c 0x032
+#define MX27_PAD_CSI_D3__CSI_D3                            0x2d 0x000
+#define MX27_PAD_CSI_D3__UART6_RTS                         0x2d 0x001
+#define MX27_PAD_CSI_D3__GPIO2_13                          0x2d 0x032
+#define MX27_PAD_CSI_D4__CSI_D4                            0x2e 0x000
+#define MX27_PAD_CSI_D4__GPIO2_14                          0x2e 0x032
+#define MX27_PAD_CSI_MCLK__CSI_MCLK                        0x2f 0x004
+#define MX27_PAD_CSI_MCLK__GPIO2_15                        0x2f 0x032
+#define MX27_PAD_CSI_PIXCLK__CSI_PIXCLK                    0x30 0x000
+#define MX27_PAD_CSI_PIXCLK__GPIO2_16                      0x30 0x032
+#define MX27_PAD_CSI_D5__CSI_D5                            0x31 0x000
+#define MX27_PAD_CSI_D5__GPIO2_17                          0x31 0x032
+#define MX27_PAD_CSI_D6__CSI_D6                            0x32 0x000
+#define MX27_PAD_CSI_D6__UART5_TXD                         0x32 0x005
+#define MX27_PAD_CSI_D6__GPIO2_18                          0x32 0x032
+#define MX27_PAD_CSI_D7__CSI_D7                            0x33 0x000
+#define MX27_PAD_CSI_D7__UART5_RXD                         0x33 0x001
+#define MX27_PAD_CSI_D7__GPIO2_19                          0x33 0x032
+#define MX27_PAD_CSI_VSYNC__CSI_VSYNC                      0x34 0x000
+#define MX27_PAD_CSI_VSYNC__UART5_CTS                      0x34 0x005
+#define MX27_PAD_CSI_VSYNC__GPIO2_20                       0x34 0x032
+#define MX27_PAD_CSI_HSYNC__CSI_HSYNC                      0x35 0x000
+#define MX27_PAD_CSI_HSYNC__UART5_RTS                      0x35 0x001
+#define MX27_PAD_CSI_HSYNC__GPIO2_21                       0x35 0x032
+#define MX27_PAD_USBH1_SUSP__USBH1_SUSP                    0x36 0x004
+#define MX27_PAD_USBH1_SUSP__GPIO2_22                      0x36 0x032
+#define MX27_PAD_USB_PWR__USB_PWR                          0x37 0x004
+#define MX27_PAD_USB_PWR__GPIO2_23                         0x37 0x032
+#define MX27_PAD_USB_OC_B__USB_OC_B                        0x38 0x000
+#define MX27_PAD_USB_OC_B__GPIO2_24                        0x38 0x032
+#define MX27_PAD_USBH1_RCV__USBH1_RCV                      0x39 0x004
+#define MX27_PAD_USBH1_RCV__GPIO2_25                       0x39 0x032
+#define MX27_PAD_USBH1_FS__USBH1_FS                        0x3a 0x004
+#define MX27_PAD_USBH1_FS__UART4_RTS                       0x3a 0x001
+#define MX27_PAD_USBH1_FS__GPIO2_26                        0x3a 0x032
+#define MX27_PAD_USBH1_OE_B__USBH1_OE_B                    0x3b 0x004
+#define MX27_PAD_USBH1_OE_B__GPIO2_27                      0x3b 0x032
+#define MX27_PAD_USBH1_TXDM__USBH1_TXDM                    0x3c 0x004
+#define MX27_PAD_USBH1_TXDM__UART4_TXD                     0x3c 0x005
+#define MX27_PAD_USBH1_TXDM__GPIO2_28                      0x3c 0x032
+#define MX27_PAD_USBH1_TXDP__USBH1_TXDP                    0x3d 0x004
+#define MX27_PAD_USBH1_TXDP__UART4_CTS                     0x3d 0x005
+#define MX27_PAD_USBH1_TXDP__GPIO2_29                      0x3d 0x032
+#define MX27_PAD_USBH1_RXDM__USBH1_RXDM                    0x3e 0x004
+#define MX27_PAD_USBH1_RXDM__GPIO2_30                      0x3e 0x032
+#define MX27_PAD_USBH1_RXDP__USBH1_RXDP                    0x3f 0x004
+#define MX27_PAD_USBH1_RXDP__UART4_RXD                     0x3f 0x001
+#define MX27_PAD_USBH1_RXDP__GPIO2_31                      0x3f 0x032
+#define MX27_PAD_UNUSED4__UNUSED4                          0x40 0x004
+#define MX27_PAD_UNUSED4__GPIO3_0                          0x40 0x032
+#define MX27_PAD_UNUSED5__UNUSED5                          0x41 0x004
+#define MX27_PAD_UNUSED5__GPIO3_1                          0x41 0x032
+#define MX27_PAD_UNUSED6__UNUSED6                          0x42 0x004
+#define MX27_PAD_UNUSED6__GPIO3_2                          0x42 0x032
+#define MX27_PAD_UNUSED7__UNUSED7                          0x43 0x004
+#define MX27_PAD_UNUSED7__GPIO3_3                          0x43 0x032
+#define MX27_PAD_UNUSED8__UNUSED8                          0x44 0x004
+#define MX27_PAD_UNUSED8__GPIO3_4                          0x44 0x032
+#define MX27_PAD_I2C2_SDA__I2C2_SDA                        0x45 0x004
+#define MX27_PAD_I2C2_SDA__GPIO3_5                         0x45 0x032
+#define MX27_PAD_I2C2_SCL__I2C2_SCL                        0x46 0x004
+#define MX27_PAD_I2C2_SCL__GPIO3_6                         0x46 0x032
+#define MX27_PAD_USBOTG_DATA5__USBOTG_DATA5                0x47 0x004
+#define MX27_PAD_USBOTG_DATA5__GPIO3_7                     0x47 0x032
+#define MX27_PAD_USBOTG_DATA6__USBOTG_DATA6                0x48 0x004
+#define MX27_PAD_USBOTG_DATA6__GPIO3_8                     0x48 0x032
+#define MX27_PAD_USBOTG_DATA0__USBOTG_DATA0                0x49 0x004
+#define MX27_PAD_USBOTG_DATA0__GPIO3_9                     0x49 0x032
+#define MX27_PAD_USBOTG_DATA2__USBOTG_DATA2                0x4a 0x004
+#define MX27_PAD_USBOTG_DATA2__GPIO3_10                    0x4a 0x032
+#define MX27_PAD_USBOTG_DATA1__USBOTG_DATA1                0x4b 0x004
+#define MX27_PAD_USBOTG_DATA1__GPIO3_11                    0x4b 0x032
+#define MX27_PAD_USBOTG_DATA4__USBOTG_DATA4                0x4c 0x004
+#define MX27_PAD_USBOTG_DATA4__GPIO3_12                    0x4c 0x032
+#define MX27_PAD_USBOTG_DATA3__USBOTG_DATA3                0x4d 0x004
+#define MX27_PAD_USBOTG_DATA3__GPIO3_13                    0x4d 0x032
+#define MX27_PAD_TOUT__TOUT                                0x4e 0x004
+#define MX27_PAD_TOUT__GPIO3_14                            0x4e 0x032
+#define MX27_PAD_TIN__TIN                                  0x4f 0x000
+#define MX27_PAD_TIN__GPIO3_15                             0x4f 0x032
+#define MX27_PAD_SSI4_FS__SSI4_FS                          0x50 0x004
+#define MX27_PAD_SSI4_FS__GPIO3_16                         0x50 0x032
+#define MX27_PAD_SSI4_RXDAT__SSI4_RXDAT                    0x51 0x004
+#define MX27_PAD_SSI4_RXDAT__GPIO3_17                      0x51 0x032
+#define MX27_PAD_SSI4_TXDAT__SSI4_TXDAT                    0x52 0x004
+#define MX27_PAD_SSI4_TXDAT__GPIO3_18                      0x52 0x032
+#define MX27_PAD_SSI4_CLK__SSI4_CLK                        0x53 0x004
+#define MX27_PAD_SSI4_CLK__GPIO3_19                        0x53 0x032
+#define MX27_PAD_SSI1_FS__SSI1_FS                          0x54 0x004
+#define MX27_PAD_SSI1_FS__GPIO3_20                         0x54 0x032
+#define MX27_PAD_SSI1_RXDAT__SSI1_RXDAT                    0x55 0x004
+#define MX27_PAD_SSI1_RXDAT__GPIO3_21                      0x55 0x032
+#define MX27_PAD_SSI1_TXDAT__SSI1_TXDAT                    0x56 0x004
+#define MX27_PAD_SSI1_TXDAT__GPIO3_22                      0x56 0x032
+#define MX27_PAD_SSI1_CLK__SSI1_CLK                        0x57 0x004
+#define MX27_PAD_SSI1_CLK__GPIO3_23                        0x57 0x032
+#define MX27_PAD_SSI2_FS__SSI2_FS                          0x58 0x004
+#define MX27_PAD_SSI2_FS__GPT5_TOUT                        0x58 0x005
+#define MX27_PAD_SSI2_FS__GPIO3_24                         0x58 0x032
+#define MX27_PAD_SSI2_RXDAT__SSI2_RXDAT                    0x59 0x004
+#define MX27_PAD_SSI2_RXDAT__GPTS_TIN                      0x59 0x001
+#define MX27_PAD_SSI2_RXDAT__GPIO3_25                      0x59 0x032
+#define MX27_PAD_SSI2_TXDAT__SSI2_TXDAT                    0x5a 0x004
+#define MX27_PAD_SSI2_TXDAT__GPT4_TOUT                     0x5a 0x005
+#define MX27_PAD_SSI2_TXDAT__GPIO3_26                      0x5a 0x032
+#define MX27_PAD_SSI2_CLK__SSI2_CLK                        0x5b 0x004
+#define MX27_PAD_SSI2_CLK__GPT4_TIN                        0x5b 0x001
+#define MX27_PAD_SSI2_CLK__GPIO3_27                        0x5b 0x032
+#define MX27_PAD_SSI3_FS__SSI3_FS                          0x5c 0x004
+#define MX27_PAD_SSI3_FS__SLCDC2_D0                        0x5c 0x001
+#define MX27_PAD_SSI3_FS__GPIO3_28                         0x5c 0x032
+#define MX27_PAD_SSI3_RXDAT__SSI3_RXDAT                    0x5d 0x004
+#define MX27_PAD_SSI3_RXDAT__SLCDC2_RS                     0x5d 0x001
+#define MX27_PAD_SSI3_RXDAT__GPIO3_29                      0x5d 0x032
+#define MX27_PAD_SSI3_TXDAT__SSI3_TXDAT                    0x5e 0x004
+#define MX27_PAD_SSI3_TXDAT__SLCDC2_CS                     0x5e 0x001
+#define MX27_PAD_SSI3_TXDAT__GPIO3_30                      0x5e 0x032
+#define MX27_PAD_SSI3_CLK__SSI3_CLK                        0x5f 0x004
+#define MX27_PAD_SSI3_CLK__SLCDC2_CLK                      0x5f 0x001
+#define MX27_PAD_SSI3_CLK__GPIO3_31                        0x5f 0x032
+#define MX27_PAD_SD3_CMD__SD3_CMD                          0x60 0x004
+#define MX27_PAD_SD3_CMD__FEC_TXD0                         0x60 0x006
+#define MX27_PAD_SD3_CMD__GPIO4_0                          0x60 0x032
+#define MX27_PAD_SD3_CLK__SD3_CLK                          0x61 0x004
+#define MX27_PAD_SD3_CLK__ETMTRACEPKT15                    0x61 0x005
+#define MX27_PAD_SD3_CLK__FEC_TXD1                         0x61 0x006
+#define MX27_PAD_SD3_CLK__GPIO4_1                          0x61 0x032
+#define MX27_PAD_ATA_DATA0__ATA_DATA0                      0x62 0x004
+#define MX27_PAD_ATA_DATA0__SD3_D0                         0x62 0x005
+#define MX27_PAD_ATA_DATA0__FEC_TXD2                       0x62 0x006
+#define MX27_PAD_ATA_DATA0__GPIO4_2                        0x62 0x032
+#define MX27_PAD_ATA_DATA1__ATA_DATA1                      0x63 0x004
+#define MX27_PAD_ATA_DATA1__SD3_D1                         0x63 0x005
+#define MX27_PAD_ATA_DATA1__FEC_TXD3                       0x63 0x006
+#define MX27_PAD_ATA_DATA1__GPIO4_3                        0x63 0x032
+#define MX27_PAD_ATA_DATA2__ATA_DATA2                      0x64 0x004
+#define MX27_PAD_ATA_DATA2__SD3_D2                         0x64 0x005
+#define MX27_PAD_ATA_DATA2__FEC_RX_ER                      0x64 0x002
+#define MX27_PAD_ATA_DATA2__GPIO4_4                        0x64 0x032
+#define MX27_PAD_ATA_DATA3__ATA_DATA3                      0x65 0x004
+#define MX27_PAD_ATA_DATA3__SD3_D3                         0x65 0x005
+#define MX27_PAD_ATA_DATA3__FEC_RXD1                       0x65 0x002
+#define MX27_PAD_ATA_DATA3__GPIO4_5                        0x65 0x032
+#define MX27_PAD_ATA_DATA4__ATA_DATA4                      0x66 0x004
+#define MX27_PAD_ATA_DATA4__ETMTRACEPKT14                  0x66 0x005
+#define MX27_PAD_ATA_DATA4__FEC_RXD2                       0x66 0x002
+#define MX27_PAD_ATA_DATA4__GPIO4_6                        0x66 0x032
+#define MX27_PAD_ATA_DATA5__ATA_DATA5                      0x67 0x004
+#define MX27_PAD_ATA_DATA5__ETMTRACEPKT13                  0x67 0x005
+#define MX27_PAD_ATA_DATA5__FEC_RXD3                       0x67 0x002
+#define MX27_PAD_ATA_DATA5__GPIO4_7                        0x67 0x032
+#define MX27_PAD_ATA_DATA6__ATA_DATA6                      0x68 0x004
+#define MX27_PAD_ATA_DATA6__FEC_MDIO                       0x68 0x005
+#define MX27_PAD_ATA_DATA6__GPIO4_8                        0x68 0x032
+#define MX27_PAD_ATA_DATA7__ATA_DATA7                      0x69 0x004
+#define MX27_PAD_ATA_DATA7__ETMTRACEPKT12                  0x69 0x005
+#define MX27_PAD_ATA_DATA7__FEC_MDC                        0x69 0x006
+#define MX27_PAD_ATA_DATA7__GPIO4_9                        0x69 0x032
+#define MX27_PAD_ATA_DATA8__ATA_DATA8                      0x6a 0x004
+#define MX27_PAD_ATA_DATA8__ETMTRACEPKT11                  0x6a 0x005
+#define MX27_PAD_ATA_DATA8__FEC_CRS                        0x6a 0x002
+#define MX27_PAD_ATA_DATA8__GPIO4_10                       0x6a 0x032
+#define MX27_PAD_ATA_DATA9__ATA_DATA9                      0x6b 0x004
+#define MX27_PAD_ATA_DATA9__ETMTRACEPKT10                  0x6b 0x005
+#define MX27_PAD_ATA_DATA9__FEC_TX_CLK                     0x6b 0x002
+#define MX27_PAD_ATA_DATA9__GPIO4_11                       0x6b 0x032
+#define MX27_PAD_ATA_DATA10__ATA_DATA10                    0x6c 0x004
+#define MX27_PAD_ATA_DATA10__ETMTRACEPKT9                  0x6c 0x005
+#define MX27_PAD_ATA_DATA10__FEC_RXD0                      0x6c 0x002
+#define MX27_PAD_ATA_DATA10__GPIO4_12                      0x6c 0x032
+#define MX27_PAD_ATA_DATA11__ATA_DATA11                    0x6d 0x004
+#define MX27_PAD_ATA_DATA11__ETMTRACEPKT8                  0x6d 0x005
+#define MX27_PAD_ATA_DATA11__FEC_RX_DV                     0x6d 0x002
+#define MX27_PAD_ATA_DATA11__GPIO4_13                      0x6d 0x032
+#define MX27_PAD_ATA_DATA12__ATA_DATA12                    0x6e 0x004
+#define MX27_PAD_ATA_DATA12__ETMTRACEPKT7                  0x6e 0x005
+#define MX27_PAD_ATA_DATA12__FEC_RX_CLK                    0x6e 0x002
+#define MX27_PAD_ATA_DATA12__GPIO4_14                      0x6e 0x032
+#define MX27_PAD_ATA_DATA13__ATA_DATA13                    0x6f 0x004
+#define MX27_PAD_ATA_DATA13__ETMTRACEPKT6                  0x6f 0x005
+#define MX27_PAD_ATA_DATA13__FEC_COL                       0x6f 0x002
+#define MX27_PAD_ATA_DATA13__GPIO4_15                      0x6f 0x032
+#define MX27_PAD_ATA_DATA14__ATA_DATA14                    0x70 0x004
+#define MX27_PAD_ATA_DATA14__ETMTRACEPKT5                  0x70 0x005
+#define MX27_PAD_ATA_DATA14__FEC_TX_ER                     0x70 0x006
+#define MX27_PAD_ATA_DATA14__GPIO4_16                      0x70 0x032
+#define MX27_PAD_I2C_DATA__I2C_DATA                        0x71 0x004
+#define MX27_PAD_I2C_DATA__GPIO4_17                        0x71 0x032
+#define MX27_PAD_I2C_CLK__I2C_CLK                          0x72 0x004
+#define MX27_PAD_I2C_CLK__GPIO4_18                         0x72 0x032
+#define MX27_PAD_CSPI2_SS2__CSPI2_SS2                      0x73 0x004
+#define MX27_PAD_CSPI2_SS2__USBH2_DATA4                    0x73 0x005
+#define MX27_PAD_CSPI2_SS2__GPIO4_19                       0x73 0x032
+#define MX27_PAD_CSPI2_SS1__CSPI2_SS1                      0x74 0x004
+#define MX27_PAD_CSPI2_SS1__USBH2_DATA3                    0x74 0x005
+#define MX27_PAD_CSPI2_SS1__GPIO4_20                       0x74 0x032
+#define MX27_PAD_CSPI2_SS0__CSPI2_SS0                      0x75 0x004
+#define MX27_PAD_CSPI2_SS0__USBH2_DATA6                    0x75 0x005
+#define MX27_PAD_CSPI2_SS0__GPIO4_21                       0x75 0x032
+#define MX27_PAD_CSPI2_SCLK__CSPI2_SCLK                    0x76 0x004
+#define MX27_PAD_CSPI2_SCLK__USBH2_DATA0                   0x76 0x005
+#define MX27_PAD_CSPI2_SCLK__GPIO4_22                      0x76 0x032
+#define MX27_PAD_CSPI2_MISO__CSPI2_MISO                    0x77 0x004
+#define MX27_PAD_CSPI2_MISO__USBH2_DATA2                   0x77 0x005
+#define MX27_PAD_CSPI2_MISO__GPIO4_23                      0x77 0x032
+#define MX27_PAD_CSPI2_MOSI__CSPI2_MOSI                    0x78 0x004
+#define MX27_PAD_CSPI2_MOSI__USBH2_DATA1                   0x78 0x005
+#define MX27_PAD_CSPI2_MOSI__GPIO4_24                      0x78 0x032
+#define MX27_PAD_CSPI1_RDY__CSPI1_RDY                      0x79 0x000
+#define MX27_PAD_CSPI1_RDY__GPIO4_25                       0x79 0x032
+#define MX27_PAD_CSPI1_SS2__CSPI1_SS2                      0x7a 0x004
+#define MX27_PAD_CSPI1_SS2__USBH2_DATA5                    0x7a 0x005
+#define MX27_PAD_CSPI1_SS2__GPIO4_26                       0x7a 0x032
+#define MX27_PAD_CSPI1_SS1__CSPI1_SS1                      0x7b 0x004
+#define MX27_PAD_CSPI1_SS1__GPIO4_27                       0x7b 0x032
+#define MX27_PAD_CSPI1_SS0__CSPI1_SS0                      0x7c 0x004
+#define MX27_PAD_CSPI1_SS0__GPIO4_28                       0x7c 0x032
+#define MX27_PAD_CSPI1_SCLK__CSPI1_SCLK                    0x7d 0x004
+#define MX27_PAD_CSPI1_SCLK__GPIO4_29                      0x7d 0x032
+#define MX27_PAD_CSPI1_MISO__CSPI1_MISO                    0x7e 0x004
+#define MX27_PAD_CSPI1_MISO__GPIO4_30                      0x7e 0x032
+#define MX27_PAD_CSPI1_MOSI__CSPI1_MOSI                    0x7f 0x004
+#define MX27_PAD_CSPI1_MOSI__GPIO4_31                      0x7f 0x032
+#define MX27_PAD_USBOTG_NXT__USBOTG_NXT                    0x80 0x000
+#define MX27_PAD_USBOTG_NXT__KP_COL6A                      0x80 0x005
+#define MX27_PAD_USBOTG_NXT__GPIO5_0                       0x80 0x032
+#define MX27_PAD_USBOTG_STP__USBOTG_STP                    0x81 0x004
+#define MX27_PAD_USBOTG_STP__KP_ROW6A                      0x81 0x005
+#define MX27_PAD_USBOTG_STP__GPIO5_1                       0x81 0x032
+#define MX27_PAD_USBOTG_DIR__USBOTG_DIR                    0x82 0x000
+#define MX27_PAD_USBOTG_DIR__KP_ROW7A                      0x82 0x005
+#define MX27_PAD_USBOTG_DIR__GPIO5_2                       0x82 0x032
+#define MX27_PAD_UART2_CTS__UART2_CTS                      0x83 0x004
+#define MX27_PAD_UART2_CTS__KP_COL7                        0x83 0x005
+#define MX27_PAD_UART2_CTS__GPIO5_3                        0x83 0x032
+#define MX27_PAD_UART2_RTS__UART2_RTS                      0x84 0x000
+#define MX27_PAD_UART2_RTS__KP_ROW7                        0x84 0x005
+#define MX27_PAD_UART2_RTS__GPIO5_4                        0x84 0x032
+#define MX27_PAD_PWMO__PWMO                                0x85 0x004
+#define MX27_PAD_PWMO__GPIO5_5                             0x85 0x032
+#define MX27_PAD_UART2_TXD__UART2_TXD                      0x86 0x004
+#define MX27_PAD_UART2_TXD__KP_COL6                        0x86 0x005
+#define MX27_PAD_UART2_TXD__GPIO5_6                        0x86 0x032
+#define MX27_PAD_UART2_RXD__UART2_RXD                      0x87 0x000
+#define MX27_PAD_UART2_RXD__KP_ROW6                        0x87 0x005
+#define MX27_PAD_UART2_RXD__GPIO5_7                        0x87 0x032
+#define MX27_PAD_UART3_TXD__UART3_TXD                      0x88 0x004
+#define MX27_PAD_UART3_TXD__GPIO5_8                        0x88 0x032
+#define MX27_PAD_UART3_RXD__UART3_RXD                      0x89 0x000
+#define MX27_PAD_UART3_RXD__GPIO5_9                        0x89 0x032
+#define MX27_PAD_UART3_CTS__UART3_CTS                      0x8a 0x004
+#define MX27_PAD_UART3_CTS__GPIO5_10                       0x8a 0x032
+#define MX27_PAD_UART3_RTS__UART3_RTS                      0x8b 0x000
+#define MX27_PAD_UART3_RTS__GPIO5_11                       0x8b 0x032
+#define MX27_PAD_UART1_TXD__UART1_TXD                      0x8c 0x004
+#define MX27_PAD_UART1_TXD__GPIO5_12                       0x8c 0x032
+#define MX27_PAD_UART1_RXD__UART1_RXD                      0x8d 0x000
+#define MX27_PAD_UART1_RXD__GPIO5_13                       0x8d 0x032
+#define MX27_PAD_UART1_CTS__UART1_CTS                      0x8e 0x004
+#define MX27_PAD_UART1_CTS__GPIO5_14                       0x8e 0x032
+#define MX27_PAD_UART1_RTS__UART1_RTS                      0x8f 0x000
+#define MX27_PAD_UART1_RTS__GPIO5_15                       0x8f 0x032
+#define MX27_PAD_RTCK__RTCK                                0x90 0x004
+#define MX27_PAD_RTCK__OWIRE                               0x90 0x005
+#define MX27_PAD_RTCK__GPIO5_16                            0x90 0x032
+#define MX27_PAD_RESET_OUT_B__RESET_OUT_B                  0x91 0x004
+#define MX27_PAD_RESET_OUT_B__GPIO5_17                     0x91 0x032
+#define MX27_PAD_SD1_D0__SD1_D0                            0x92 0x004
+#define MX27_PAD_SD1_D0__CSPI3_MISO                        0x92 0x001
+#define MX27_PAD_SD1_D0__GPIO5_18                          0x92 0x032
+#define MX27_PAD_SD1_D1__SD1_D1                            0x93 0x004
+#define MX27_PAD_SD1_D1__GPIO5_19                          0x93 0x032
+#define MX27_PAD_SD1_D2__SD1_D2                            0x94 0x004
+#define MX27_PAD_SD1_D2__GPIO5_20                          0x94 0x032
+#define MX27_PAD_SD1_D3__SD1_D3                            0x95 0x004
+#define MX27_PAD_SD1_D3__CSPI3_SS                          0x95 0x005
+#define MX27_PAD_SD1_D3__GPIO5_21                          0x95 0x032
+#define MX27_PAD_SD1_CMD__SD1_CMD                          0x96 0x004
+#define MX27_PAD_SD1_CMD__CSPI3_MOSI                       0x96 0x005
+#define MX27_PAD_SD1_CMD__GPIO5_22                         0x96 0x032
+#define MX27_PAD_SD1_CLK__SD1_CLK                          0x97 0x004
+#define MX27_PAD_SD1_CLK__CSPI3_SCLK                       0x97 0x005
+#define MX27_PAD_SD1_CLK__GPIO5_23                         0x97 0x032
+#define MX27_PAD_USBOTG_CLK__USBOTG_CLK                    0x98 0x000
+#define MX27_PAD_USBOTG_CLK__GPIO5_24                      0x98 0x032
+#define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7                0x99 0x004
+#define MX27_PAD_USBOTG_DATA7__GPIO5_25                    0x99 0x032
+#define MX27_PAD_UNUSED9__UNUSED9                          0x9a 0x004
+#define MX27_PAD_UNUSED9__GPIO5_26                         0x9a 0x032
+#define MX27_PAD_UNUSED10__UNUSED10                        0x9b 0x004
+#define MX27_PAD_UNUSED10__GPIO5_27                        0x9b 0x032
+#define MX27_PAD_UNUSED11__UNUSED11                        0x9c 0x004
+#define MX27_PAD_UNUSED11__GPIO5_28                        0x9c 0x032
+#define MX27_PAD_UNUSED12__UNUSED12                        0x9d 0x004
+#define MX27_PAD_UNUSED12__GPIO5_29                        0x9d 0x032
+#define MX27_PAD_UNUSED13__UNUSED13                        0x9e 0x004
+#define MX27_PAD_UNUSED13__GPIO5_30                        0x9e 0x032
+#define MX27_PAD_UNUSED14__UNUSED14                        0x9f 0x004
+#define MX27_PAD_UNUSED14__GPIO5_31                        0x9f 0x032
+#define MX27_PAD_NFRB__NFRB                                0xa0 0x000
+#define MX27_PAD_NFRB__ETMTRACEPKT3                        0xa0 0x005
+#define MX27_PAD_NFRB__GPIO6_0                             0xa0 0x032
+#define MX27_PAD_NFCLE__NFCLE                              0xa1 0x004
+#define MX27_PAD_NFCLE__ETMTRACEPKT0                       0xa1 0x005
+#define MX27_PAD_NFCLE__GPIO6_1                            0xa1 0x032
+#define MX27_PAD_NFWP_B__NFWP_B                            0xa2 0x004
+#define MX27_PAD_NFWP_B__ETMTRACEPKT1                      0xa2 0x005
+#define MX27_PAD_NFWP_B__GPIO6_2                           0xa2 0x032
+#define MX27_PAD_NFCE_B__NFCE_B                            0xa3 0x004
+#define MX27_PAD_NFCE_B__ETMTRACEPKT2                      0xa3 0x005
+#define MX27_PAD_NFCE_B__GPIO6_3                           0xa3 0x032
+#define MX27_PAD_NFALE__NFALE                              0xa4 0x004
+#define MX27_PAD_NFALE__ETMPIPESTAT0                       0xa4 0x005
+#define MX27_PAD_NFALE__GPIO6_4                            0xa4 0x032
+#define MX27_PAD_NFRE_B__NFRE_B                            0xa5 0x004
+#define MX27_PAD_NFRE_B__ETMPIPESTAT1                      0xa5 0x005
+#define MX27_PAD_NFRE_B__GPIO6_5                           0xa5 0x032
+#define MX27_PAD_NFWE_B__NFWE_B                            0xa6 0x004
+#define MX27_PAD_NFWE_B__ETMPIPESTAT2                      0xa6 0x005
+#define MX27_PAD_NFWE_B__GPIO6_6                           0xa6 0x032
+#define MX27_PAD_PC_POE__PC_POE                            0xa7 0x004
+#define MX27_PAD_PC_POE__ATA_BUFFER_EN                     0xa7 0x005
+#define MX27_PAD_PC_POE__GPIO6_7                           0xa7 0x032
+#define MX27_PAD_PC_RW_B__PC_RW_B                          0xa8 0x004
+#define MX27_PAD_PC_RW_B__ATA_IORDY                        0xa8 0x001
+#define MX27_PAD_PC_RW_B__GPIO6_8                          0xa8 0x032
+#define MX27_PAD_IOIS16__IOIS16                            0xa9 0x000
+#define MX27_PAD_IOIS16__ATA_INTRQ                         0xa9 0x001
+#define MX27_PAD_IOIS16__GPIO6_9                           0xa9 0x032
+#define MX27_PAD_PC_RST__PC_RST                            0xaa 0x004
+#define MX27_PAD_PC_RST__ATA_RESET_B                       0xaa 0x005
+#define MX27_PAD_PC_RST__GPIO6_10                          0xaa 0x032
+#define MX27_PAD_PC_BVD2__PC_BVD2                          0xab 0x000
+#define MX27_PAD_PC_BVD2__ATA_DMACK                        0xab 0x005
+#define MX27_PAD_PC_BVD2__GPIO6_11                         0xab 0x032
+#define MX27_PAD_PC_BVD1__PC_BVD1                          0xac 0x000
+#define MX27_PAD_PC_BVD1__ATA_DMARQ                        0xac 0x001
+#define MX27_PAD_PC_BVD1__GPIO6_12                         0xac 0x032
+#define MX27_PAD_PC_VS2__PC_VS2                            0xad 0x000
+#define MX27_PAD_PC_VS2__ATA_DA0                           0xad 0x005
+#define MX27_PAD_PC_VS2__GPIO6_13                          0xad 0x032
+#define MX27_PAD_PC_VS1__PC_VS1                            0xae 0x000
+#define MX27_PAD_PC_VS1__ATA_DA1                           0xae 0x005
+#define MX27_PAD_PC_VS1__GPIO6_14                          0xae 0x032
+#define MX27_PAD_CLKO__CLKO                                0xaf 0x004
+#define MX27_PAD_CLKO__GPIO6_15                            0xaf 0x032
+#define MX27_PAD_PC_PWRON__PC_PWRON                        0xb0 0x000
+#define MX27_PAD_PC_PWRON__ATA_DA2                         0xb0 0x005
+#define MX27_PAD_PC_PWRON__GPIO6_16                        0xb0 0x032
+#define MX27_PAD_PC_READY__PC_READY                        0xb1 0x000
+#define MX27_PAD_PC_READY__ATA_CS0                         0xb1 0x005
+#define MX27_PAD_PC_READY__GPIO6_17                        0xb1 0x032
+#define MX27_PAD_PC_WAIT_B__PC_WAIT_B                      0xb2 0x000
+#define MX27_PAD_PC_WAIT_B__ATA_CS1                        0xb2 0x005
+#define MX27_PAD_PC_WAIT_B__GPIO6_18                       0xb2 0x032
+#define MX27_PAD_PC_CD2_B__PC_CD2_B                        0xb3 0x000
+#define MX27_PAD_PC_CD2_B__ATA_DIOW                        0xb3 0x005
+#define MX27_PAD_PC_CD2_B__GPIO6_19                        0xb3 0x032
+#define MX27_PAD_PC_CD1_B__PC_CD1_B                        0xb4 0x000
+#define MX27_PAD_PC_CD1_B__ATA_DIOR                        0xb4 0x005
+#define MX27_PAD_PC_CD1_B__GPIO6_20                        0xb4 0x032
+#define MX27_PAD_CS4_B__CS4_B                              0xb5 0x004
+#define MX27_PAD_CS4_B__ETMTRACESYNC                       0xb5 0x005
+#define MX27_PAD_CS4_B__GPIO6_21                           0xb5 0x032
+#define MX27_PAD_CS5_B__CS5_B                              0xb6 0x004
+#define MX27_PAD_CS5_B__ETMTRACECLK                        0xb6 0x005
+#define MX27_PAD_CS5_B__GPIO6_22                           0xb6 0x032
+#define MX27_PAD_ATA_DATA15__ATA_DATA15                    0xb7 0x004
+#define MX27_PAD_ATA_DATA15__ETMTRACEPKT4                  0xb7 0x005
+#define MX27_PAD_ATA_DATA15__FEC_TX_EN                     0xb7 0x006
+#define MX27_PAD_ATA_DATA15__GPIO6_23                      0xb7 0x032
+#define MX27_PAD_UNUSED15__UNUSED15                        0xb8 0x004
+#define MX27_PAD_UNUSED15__GPIO6_24                        0xb8 0x032
+#define MX27_PAD_UNUSED16__UNUSED16                        0xb9 0x004
+#define MX27_PAD_UNUSED16__GPIO6_25                        0xb9 0x032
+#define MX27_PAD_UNUSED17__UNUSED17                        0xba 0x004
+#define MX27_PAD_UNUSED17__GPIO6_26                        0xba 0x032
+#define MX27_PAD_UNUSED18__UNUSED18                        0xbb 0x004
+#define MX27_PAD_UNUSED18__GPIO6_27                        0xbb 0x032
+#define MX27_PAD_UNUSED19__UNUSED19                        0xbc 0x004
+#define MX27_PAD_UNUSED19__GPIO6_28                        0xbc 0x032
+#define MX27_PAD_UNUSED20__UNUSED20                        0xbd 0x004
+#define MX27_PAD_UNUSED20__GPIO6_29                        0xbd 0x032
+#define MX27_PAD_UNUSED21__UNUSED21                        0xbe 0x004
+#define MX27_PAD_UNUSED21__GPIO6_30                        0xbe 0x032
+#define MX27_PAD_UNUSED22__UNUSED22                        0xbf 0x004
+#define MX27_PAD_UNUSED22__GPIO6_31                        0xbf 0x032
+
+#endif /* __DTS_IMX27_PINFUNC_H */
index 826231eb44466f9187a564b3a587c7b18d686b28..6279e0b4f7683106439c062209e3c9101f0ea7ad 100644 (file)
@@ -10,6 +10,9 @@
  */
 
 #include "skeleton.dtsi"
+#include "imx27-pinfunc.h"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        aliases {
                };
        };
 
+       usbphy {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usbphy0: usbphy@0 {
+                       compatible = "usb-nop-xceiv";
+                       reg = <0>;
+                       clocks = <&clks 75>;
+                       clock-names = "main_clk";
+               };
+
+               usbphy2: usbphy@2 {
+                       compatible = "usb-nop-xceiv";
+                       reg = <2>;
+                       clocks = <&clks 75>;
+                       clock-names = "main_clk";
+               };
+       };
+
        soc {
                #address-cells = <1>;
                #size-cells = <1>;
                                status = "disabled";
                        };
 
+                       ssi1: ssi@10010000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx27-ssi", "fsl,imx21-ssi";
+                               reg = <0x10010000 0x1000>;
+                               interrupts = <14>;
+                               clocks = <&clks 26>;
+                               dmas = <&dma 12>, <&dma 13>, <&dma 14>, <&dma 15>;
+                               dma-names = "rx0", "tx0", "rx1", "tx1";
+                               fsl,fifo-depth = <8>;
+                               status = "disabled";
+                       };
+
+                       ssi2: ssi@10011000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx27-ssi", "fsl,imx21-ssi";
+                               reg = <0x10011000 0x1000>;
+                               interrupts = <13>;
+                               clocks = <&clks 25>;
+                               dmas = <&dma 8>, <&dma 9>, <&dma 10>, <&dma 11>;
+                               dma-names = "rx0", "tx0", "rx1", "tx1";
+                               fsl,fifo-depth = <8>;
+                               status = "disabled";
+                       };
+
                        i2c1: i2c@10012000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                status = "disabled";
                        };
 
-                       gpio1: gpio@10015000 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015000 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio2: gpio@10015100 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015100 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio3: gpio@10015200 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015200 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio4: gpio@10015300 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015300 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio5: gpio@10015400 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015400 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                       };
-
-                       gpio6: gpio@10015500 {
-                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
-                               reg = <0x10015500 0x100>;
-                               interrupts = <8>;
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
+                       iomuxc: iomuxc@10015000 {
+                               compatible = "fsl,imx27-iomuxc";
+                               reg = <0x10015000 0x600>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges;
+
+                               gpio1: gpio@10015000 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015000 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio2: gpio@10015100 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015100 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio3: gpio@10015200 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015200 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio4: gpio@10015300 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015300 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio5: gpio@10015400 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015400 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio6: gpio@10015500 {
+                                       compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                                       reg = <0x10015500 0x100>;
+                                       interrupts = <8>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
                        };
 
                        audmux: audmux@10016000 {
                                iram = <&iram>;
                        };
 
+                       usbotg: usb@10024000 {
+                               compatible = "fsl,imx27-usb";
+                               reg = <0x10024000 0x200>;
+                               interrupts = <56>;
+                               clocks = <&clks 15>;
+                               fsl,usbmisc = <&usbmisc 0>;
+                               fsl,usbphy = <&usbphy0>;
+                               status = "disabled";
+                       };
+
+                       usbh1: usb@10024200 {
+                               compatible = "fsl,imx27-usb";
+                               reg = <0x10024200 0x200>;
+                               interrupts = <54>;
+                               clocks = <&clks 15>;
+                               fsl,usbmisc = <&usbmisc 1>;
+                               status = "disabled";
+                       };
+
+                       usbh2: usb@10024400 {
+                               compatible = "fsl,imx27-usb";
+                               reg = <0x10024400 0x200>;
+                               interrupts = <55>;
+                               clocks = <&clks 15>;
+                               fsl,usbmisc = <&usbmisc 2>;
+                               fsl,usbphy = <&usbphy2>;
+                               status = "disabled";
+                       };
+
+                       usbmisc: usbmisc@10024600 {
+                               #index-cells = <1>;
+                               compatible = "fsl,imx27-usbmisc";
+                               reg = <0x10024600 0x200>;
+                               clocks = <&clks 62>;
+                       };
+
                        sahara2: sahara@10025000 {
                                compatible = "fsl,imx27-sahara";
                                reg = <0x10025000 0x1000>;
index e2efd8d89c4fb82bca3602274380c7a81a515518..221cac4fb2cdd94b1d634f76688989c136daf346 100644 (file)
@@ -48,6 +48,7 @@
                                                MX28_PAD_LCD_D20__GPIO_1_20
                                                MX28_PAD_LCD_D21__GPIO_1_21
                                                MX28_PAD_LCD_D22__GPIO_1_22
+                                               MX28_PAD_GPMI_CE1N__GPIO_0_17
                                        >;
                                        fsl,drive-strength = <MXS_DRIVE_4mA>;
                                        fsl,voltage = <MXS_VOLTAGE_HIGH>;
                                        fsl,voltage = <MXS_VOLTAGE_HIGH>;
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
+
+                               usb0_otg_apf28dev: otg-apf28dev@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_D23__GPIO_1_23
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
                        };
 
                        lcdif@80030000 {
 
        ahb@80080000 {
                usb0: usb@80080000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb0_otg_apf28dev>;
                        vbus-supply = <&reg_usb0_vbus>;
                        status = "okay";
                };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio1 23 1>;
+                       enable-active-high;
                };
        };
 
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
        };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               user-button {
+                       label = "User button";
+                       gpios = <&gpio0 17 0>;
+                       linux,code = <0x100>;
+               };
+       };
 };
index 6f254ca816cbd42b3ff80d61c3bfdb86c6f8438d..e1ce9179db63b612839a85d35b5122fd3fd4dd59 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index cabb6171a19d925c214442daa47473a6a2be31a5..ae7c3390e65a5ddc6210c4d256b406719e624d14 100644 (file)
                usb0: usb@80080000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb0_otg_cfa10036>;
+                       dr_mode = "peripheral";
+                       phy_type = "utmi";
                        status = "okay";
                };
        };
index f93e9a700e52b39287ff6761cf9c2ffdc21ea617..e5beaa58bb40262fcd42297615f476a9881eff17 100644 (file)
@@ -54,7 +54,7 @@
        ahb@80080000 {
                usb1: usb@80090000 {
                        vbus-supply = <&reg_usb1_vbus>;
-                       pinctrl-0 = <&usbphy1_pins_a>;
+                       pinctrl-0 = <&usb1_pins_a>;
                        pinctrl-names = "default";
                        status = "okay";
                };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10037>;
                        regulator-name = "usb1_vbus";
index 7087b4bf6a8f88e5748a70747af337de3524a5c0..7d51459de5e82038d391ce03c115410787815482 100644 (file)
                                i2c-parent = <&i2c1>;
 
                                i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
                                        reg = <0>;
+
+                                       adc0: nau7802@2a {
+                                               compatible = "nuvoton,nau7802";
+                                               reg = <0x2a>;
+                                               nuvoton,vldo = <3000>;
+                                       };
                                };
 
                                i2c@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
                                        reg = <1>;
+
+                                       adc1: nau7802@2a {
+                                               compatible = "nuvoton,nau7802";
+                                               reg = <0x2a>;
+                                               nuvoton,vldo = <3000>;
+                                       };
                                };
 
                                i2c@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
                                        reg = <2>;
+
+                                       adc2: nau7802@2a {
+                                               compatible = "nuvoton,nau7802";
+                                               reg = <0x2a>;
+                                               nuvoton,vldo = <3000>;
+                                       };
                                };
 
                                i2c@3 {
        ahb@80080000 {
                usb1: usb@80090000 {
                        vbus-supply = <&reg_usb1_vbus>;
-                       pinctrl-0 = <&usbphy1_pins_a>;
+                       pinctrl-0 = <&usb1_pins_a>;
                        pinctrl-names = "default";
                        status = "okay";
                };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10049>;
                        regulator-name = "usb1_vbus";
index 3c1312885ae0dafc1642e30d27a58cc3cf49d12b..c4e00ce4b6daf19b2cdb0ead0c299899b154a1dd 100644 (file)
        ahb@80080000 {
                usb1: usb@80090000 {
                        vbus-supply = <&reg_usb1_vbus>;
-                       pinctrl-0 = <&usbphy1_pins_a>;
+                       pinctrl-0 = <&usb1_pins_a>;
                        pinctrl-names = "default";
                        status = "okay";
                };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10057>;
                        regulator-name = "usb1_vbus";
index 2469d34df0ae1499de3236f13e180969dd78eed7..7c9cc783f0d1a4c93d4385aabaab508c786dc465 100644 (file)
        ahb@80080000 {
                usb1: usb@80090000 {
                        vbus-supply = <&reg_usb1_vbus>;
-                       pinctrl-0 = <&usbphy1_pins_a>;
+                       pinctrl-0 = <&usb1_pins_a>;
                        pinctrl-names = "default";
                        status = "okay";
                };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@0 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&usb_pins_cfa10058>;
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
diff --git a/arch/arm/boot/dts/imx28-duckbill.dts b/arch/arm/boot/dts/imx28-duckbill.dts
new file mode 100644 (file)
index 0000000..5f326c1
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 Michael Heimpold <mhei@heimpold.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx28.dtsi"
+
+/ {
+       model = "I2SE Duckbill";
+       compatible = "i2se,duckbill", "fsl,imx28";
+
+       memory {
+               reg = <0x40000000 0x08000000>;
+       };
+
+       apb@80000000 {
+               apbh@80000000 {
+                       ssp0: ssp@80010000 {
+                               compatible = "fsl,imx28-mmc";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&mmc0_8bit_pins_a
+                                       &mmc0_cd_cfg &mmc0_sck_cfg>;
+                               bus-width = <8>;
+                               vmmc-supply = <&reg_3p3v>;
+                               status = "okay";
+                       };
+
+                       pinctrl@80018000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&hog_pins_a>;
+
+                               hog_pins_a: hog@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_ENET0_RX_CLK__GPIO_4_13 /* PHY Reset */
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
+                               led_pins_a: led_gpio@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART1_RX__GPIO_3_4
+                                               MX28_PAD_AUART1_TX__GPIO_3_5
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+                       };
+               };
+
+               apbx@80040000 {
+                       duart: serial@80074000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&duart_pins_a>;
+                               status = "okay";
+                       };
+
+                       usbphy0: usbphy@8007c000 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ahb@80080000 {
+               usb0: usb@80080000 {
+                       status = "okay";
+               };
+
+               mac0: ethernet@800f0000 {
+                       phy-mode = "rmii";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mac0_pins_a>;
+                       phy-supply = <&reg_3p3v>;
+                       phy-reset-gpios = <&gpio4 13 0>;
+                       phy-reset-duration = <100>;
+                       status = "okay";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_a>;
+
+               status {
+                       label = "duckbill:green:status";
+                       gpios = <&gpio3 5 0>;
+               };
+
+               failure {
+                       label = "duckbill:red:status";
+                       gpios = <&gpio3 4 0>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts b/arch/arm/boot/dts/imx28-eukrea-mbmx283lc.dts
new file mode 100644 (file)
index 0000000..7c1572c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <eric@eukrea.com>
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.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.
+ */
+
+/*
+ * Module contains : i.MX282 + 64MB DDR2 + NAND + Ethernet PHY + RTC
+ */
+
+/dts-v1/;
+#include "imx28-eukrea-mbmx28lc.dtsi"
+
+/ {
+       model = "Eukrea Electromatique MBMX283LC";
+       compatible = "eukrea,mbmx283lc", "eukrea,mbmx28lc", "fsl,imx28";
+
+       memory {
+               reg = <0x40000000 0x04000000>;
+       };
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpmi_pins_a>;
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       status = "okay";
+
+       pcf8563: rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+
+&mac0 {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mac0_pins_a>;
+       phy-reset-gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&pinctrl{
+       pinctrl-names = "default";
+       pinctrl-0 = <&hog_pins_cpuimx283>;
+
+       hog_pins_cpuimx283: hog-cpuimx283@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_ENET0_RX_CLK__GPIO_4_13
+                       MX28_PAD_ENET0_TX_CLK__GPIO_4_5
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_ENABLE>;
+       };
+};
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts b/arch/arm/boot/dts/imx28-eukrea-mbmx287lc.dts
new file mode 100644 (file)
index 0000000..e773144
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <eric@eukrea.com>
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.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.
+ */
+
+/*
+ * Module contains : i.MX287 + 128MB DDR2 + NAND + 2 x Ethernet PHY + RTC
+ */
+
+#include "imx28-eukrea-mbmx283lc.dts"
+
+/ {
+       model = "Eukrea Electromatique MBMX287LC";
+       compatible = "eukrea,mbmx287lc", "eukrea,mbmx283lc", "eukrea,mbmx28lc", "fsl,imx28";
+
+       memory {
+               reg = <0x40000000 0x08000000>;
+       };
+};
+
+&mac1 {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mac1_pins_a>;
+       phy-reset-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hog_pins_cpuimx283 &hog_pins_cpuimx287>;
+       hog_pins_cpuimx287: hog-cpuimx287@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_SPDIF__GPIO_3_27
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_ENABLE>;
+       };
+};
diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi
new file mode 100644 (file)
index 0000000..927b391
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <eric@eukrea.com>
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx28.dtsi"
+
+/ {
+       model = "Eukrea Electromatique MBMX28LC";
+       compatible = "eukrea,mbmx28lc", "fsl,imx28";
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 4 1000000>;
+               brightness-levels = <0 25 50 75 100 125 150 175 200 225 255>;
+               default-brightness-level = <10>;
+       };
+
+       button-sw3 {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_button_sw3_pins_mbmx28lc>;
+
+               sw3 {
+                       label = "SW3";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_MISC>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       button-sw4 {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_button_sw4_pins_mbmx28lc>;
+
+               sw4 {
+                       label = "SW4";
+                       gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_MISC>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       led-d6 {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_d6_pins_mbmx28lc>;
+
+               led1 {
+                       label = "d6";
+                       gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       led-d7 {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_d7_pins_mbmx28lc>;
+
+               led1 {
+                       label = "d7";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-on";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_lcd_3v3: regulator@1 {
+                       compatible = "regulator-fixed";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&reg_lcd_3v3_pins_mbmx28lc>;
+                       regulator-name = "lcd-3v3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+
+               reg_usb0_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&reg_usb0_vbus_pins_mbmx28lc>;
+                       regulator-name = "usb0_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+
+               reg_usb1_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&reg_usb1_vbus_pins_mbmx28lc>;
+                       regulator-name = "usb1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio1 19 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx28-mbmx28lc-sgtl5000",
+                            "fsl,mxs-audio-sgtl5000";
+               model = "imx28-mbmx28lc-sgtl5000";
+               saif-controllers = <&saif0 &saif1>;
+               audio-codec = <&sgtl5000>;
+       };
+};
+
+&duart {
+       pinctrl-names = "default";
+       pinctrl-0 = <&duart_4pins_a>;
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       status = "okay";
+
+       sgtl5000: codec@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_3p3v>;
+               VDDIO-supply = <&reg_3p3v>;
+               clocks = <&saif0>;
+       };
+};
+
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&lcdif_18bit_pins_a &lcdif_pins_mbmx28lc>;
+       lcd-supply = <&reg_lcd_3v3>;
+       display = <&display0>;
+       status = "okay";
+
+       display0: display0 {
+               model = "43WVF1G-0";
+               bits-per-pixel = <16>;
+               bus-width = <18>;
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: timing0 {
+                               clock-frequency = <9072000>;
+                               hactive = <480>;
+                               vactive = <272>;
+                               hback-porch = <10>;
+                               hfront-porch = <5>;
+                               vback-porch = <8>;
+                               vfront-porch = <8>;
+                               hsync-len = <40>;
+                               vsync-len = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+               };
+       };
+};
+
+&lradc {
+       fsl,lradc-touchscreen-wires = <4>;
+       status = "okay";
+};
+
+&pinctrl {
+       gpio_button_sw3_pins_mbmx28lc: gpio-button-sw3-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D21__GPIO_1_21
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       gpio_button_sw4_pins_mbmx28lc: gpio-button-sw4-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D20__GPIO_1_20
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       lcdif_pins_mbmx28lc: lcdif-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_VSYNC__LCD_VSYNC
+                       MX28_PAD_LCD_HSYNC__LCD_HSYNC
+                       MX28_PAD_LCD_DOTCLK__LCD_DOTCLK
+                       MX28_PAD_LCD_ENABLE__LCD_ENABLE
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       led_d6_pins_mbmx28lc: led-d6-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D23__GPIO_1_23
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       led_d7_pins_mbmx28lc: led-d7-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D22__GPIO_1_22
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       reg_lcd_3v3_pins_mbmx28lc: lcd-3v3-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_RESET__GPIO_3_30
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       reg_usb0_vbus_pins_mbmx28lc: reg-usb0-vbus-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D18__GPIO_1_18
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+
+       reg_usb1_vbus_pins_mbmx28lc: reg-usb1-vbus-mbmx28lc@0 {
+               reg = <0>;
+               fsl,pinmux-ids = <
+                       MX28_PAD_LCD_D19__GPIO_1_19
+               >;
+               fsl,drive-strength = <MXS_DRIVE_4mA>;
+               fsl,voltage = <MXS_VOLTAGE_HIGH>;
+               fsl,pull-up = <MXS_PULL_DISABLE>;
+       };
+};
+
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm4_pins_a>;
+       status = "okay";
+};
+
+&saif0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&saif0_pins_a>;
+       status = "okay";
+};
+
+&saif1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&saif1_pins_a>;
+       fsl,saif-master = <&saif0>;
+       status = "okay";
+};
+
+&ssp0 {
+       compatible = "fsl,imx28-mmc";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_cd_cfg &mmc0_sck_cfg>;
+       bus-width = <4>;
+       cd-inverted;
+       status = "okay";
+};
+
+&usb0 {
+       disable-over-current;
+       vbus-supply = <&reg_usb0_vbus>;
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb0_id_pins_b>;
+};
+
+&usb1 {
+       vbus-supply = <&reg_usb1_vbus>;
+       status = "okay";
+};
+
+&usbphy0 {
+       status = "okay";
+};
+
+&usbphy1 {
+       status = "okay";
+};
index 4267c2b05d600ac8bfb9cf2612a3b72977d7dc0e..e4cc44c98585f415744e30a41fd4d066797043a3 100644 (file)
                        i2c0: i2c@80058000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&i2c0_pins_a>;
+                               clock-frequency = <400000>;
                                status = "okay";
 
                                sgtl5000: codec@0a {
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio3 28 0>;
                };
 
-               reg_fec_3v3: fec-3v3 {
+               reg_fec_3v3: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "fec-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio2 15 0>;
                };
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@4 {
                        compatible = "regulator-fixed";
+                       reg = <4>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_lcd_3v3: lcd-3v3 {
+               reg_lcd_3v3: regulator@5 {
                        compatible = "regulator-fixed";
+                       reg = <5>;
                        regulator-name = "lcd-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        enable-active-high;
                };
 
-               reg_can_3v3: can-3v3 {
+               reg_can_3v3: regulator@6 {
                        compatible = "regulator-fixed";
+                       reg = <6>;
                        regulator-name = "can-3v3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index d3958da60bd72e95052ff08af73a46b83b461c58..9348ce59dda47c947ca1df5442b05f0f849dc90c 100644 (file)
                                pinctrl-0 = <&lcdif_24bit_pins_a
                                             &lcdif_pins_m28>;
                                display = <&display>;
-                               reset-active-high;
                                status = "okay";
 
                                display: display0 {
                usb1: usb@80090000 {
                        vbus-supply = <&reg_usb1_vbus>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&usbphy1_pins_a>;
+                       pinctrl-0 = <&usb1_pins_a>;
                        disable-over-current;
                        status = "okay";
                };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio3 29 0>;
                };
 
-               reg_vddio_sd1: vddio-sd1 {
+               reg_vddio_sd1: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "vddio-sd1";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio2 19 0>;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index 8e2477fbe1d70963d583973ed4c46a6554c99104..f0ad7b9b9d9a1617eeb64d2d42a1dae872642f32 100644 (file)
                                };
 
                                rtc: rtc@68 {
-                                       compatible = "stm,mt41t62";
+                                       compatible = "stm,m41t62";
                                        reg = <0x68>;
                                };
                        };
                usb0: usb@80080000 {
                        vbus-supply = <&reg_usb0_vbus>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&usbphy0_pins_a>;
+                       pinctrl-0 = <&usb0_pins_a>;
                        status = "okay";
                };
 
                usb1: usb@80090000 {
                        vbus-supply = <&reg_usb1_vbus>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&usbphy1_pins_a>;
+                       pinctrl-0 = <&usb1_pins_a>;
                        status = "okay";
                };
 
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_vddio_sd0: vddio-sd0 {
+               reg_vddio_sd0: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "vddio-sd0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio3 28 0>;
                };
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio3 12 0>;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index 4870f07bf56a86423c6a910a5c86ce6fce1624a4..0ce3cb8e7914ecebdaccd0b576bdd2f3420329e8 100644 (file)
                usb0: usb@80080000 {
                        vbus-supply = <&reg_usb0_vbus>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&usbphy0_pins_b>;
+                       pinctrl-0 = <&usb0_pins_b>;
                        status = "okay";
                };
 
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index be5a0550d58c3312d37f36e04c937d5739c7f181..e14bd86f3e9999a50e0f60a7b443ed2b06ecbd07 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb0_vbus: usb0_vbus {
+               reg_usb0_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb0_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -53,8 +56,9 @@
                        enable-active-high;
                };
 
-               reg_usb1_vbus: usb1_vbus {
+               reg_usb1_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_2p5v: 2p5v {
+               reg_2p5v: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "2P5V";
                        regulator-min-microvolt = <2500000>;
                        regulator-max-microvolt = <2500000>;
                        regulator-always-on;
                };
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@3 {
                        compatible = "regulator-fixed";
+                       reg = <3>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
 
-               reg_can_xcvr: can-xcvr {
+               reg_can_xcvr: regulator@4 {
                        compatible = "regulator-fixed";
+                       reg = <4>;
                        regulator-name = "CAN XCVR";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio1 0 0>;
-                       enable-active-low;
                        pinctrl-names = "default";
                        pinctrl-0 = <&tx28_flexcan_xcvr_pins>;
                };
 
-               reg_lcd: lcd-power {
+               reg_lcd: regulator@5 {
                        compatible = "regulator-fixed";
+                       reg = <5>;
                        regulator-name = "LCD POWER";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        enable-active-high;
                };
 
-               reg_lcd_reset: lcd-reset {
+               reg_lcd_reset: regulator@6 {
                        compatible = "regulator-fixed";
+                       reg = <6>;
                        regulator-name = "LCD RESET";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
index f8e9b20f69820c6948bd84b11a14166db6b4bdd3..90a579532b8b7619c334b77ef740ec3b0f6b233e 100644 (file)
@@ -32,6 +32,8 @@
                serial4 = &auart4;
                spi0 = &ssp1;
                spi1 = &ssp2;
+               usbphy0 = &usbphy0;
+               usbphy1 = &usbphy1;
        };
 
        cpus {
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
+                               auart2_pins_a: auart2-pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_AUART2_RX__AUART2_RX
+                                               MX28_PAD_AUART2_TX__AUART2_TX
+                                               MX28_PAD_AUART2_CTS__AUART2_CTS
+                                               MX28_PAD_AUART2_RTS__AUART2_RTS
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
                                auart3_pins_a: auart3@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
+                               lcdif_18bit_pins_a: lcdif-18bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_LCD_D00__LCD_D0
+                                               MX28_PAD_LCD_D01__LCD_D1
+                                               MX28_PAD_LCD_D02__LCD_D2
+                                               MX28_PAD_LCD_D03__LCD_D3
+                                               MX28_PAD_LCD_D04__LCD_D4
+                                               MX28_PAD_LCD_D05__LCD_D5
+                                               MX28_PAD_LCD_D06__LCD_D6
+                                               MX28_PAD_LCD_D07__LCD_D7
+                                               MX28_PAD_LCD_D08__LCD_D8
+                                               MX28_PAD_LCD_D09__LCD_D9
+                                               MX28_PAD_LCD_D10__LCD_D10
+                                               MX28_PAD_LCD_D11__LCD_D11
+                                               MX28_PAD_LCD_D12__LCD_D12
+                                               MX28_PAD_LCD_D13__LCD_D13
+                                               MX28_PAD_LCD_D14__LCD_D14
+                                               MX28_PAD_LCD_D15__LCD_D15
+                                               MX28_PAD_LCD_D16__LCD_D16
+                                               MX28_PAD_LCD_D17__LCD_D17
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_4mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_DISABLE>;
+                               };
+
                                lcdif_16bit_pins_a: lcdif-16bit@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
-                               usbphy0_pins_a: usbphy0@0 {
+                               usb0_pins_a: usb0@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
                                                MX28_PAD_SSP2_SS2__USB0_OVERCURRENT
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
-                               usbphy0_pins_b: usbphy0@1 {
+                               usb0_pins_b: usb0@1 {
                                        reg = <1>;
                                        fsl,pinmux-ids = <
                                                MX28_PAD_AUART1_CTS__USB0_OVERCURRENT
                                        fsl,pull-up = <MXS_PULL_DISABLE>;
                                };
 
-                               usbphy1_pins_a: usbphy1@0 {
+                               usb1_pins_a: usb1@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
                                                MX28_PAD_SSP2_SS1__USB1_OVERCURRENT
                                        fsl,voltage = <MXS_VOLTAGE_HIGH>;
                                        fsl,pull-up = <MXS_PULL_ENABLE>;
                                };
+
+                               usb0_id_pins_b: usb0id1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               MX28_PAD_PWM2__USB0_ID
+                                       >;
+                                       fsl,drive-strength = <MXS_DRIVE_12mA>;
+                                       fsl,voltage = <MXS_VOLTAGE_HIGH>;
+                                       fsl,pull-up = <MXS_PULL_ENABLE>;
+                               };
+
                        };
 
                        digctl: digctl@8001c000 {
                                                20 21 22 23 24 25>;
                                status = "disabled";
                                clocks = <&clks 41>;
+                               #io-channel-cells = <1>;
                        };
 
                        spdif: spdif@80054000 {
                        status = "disabled";
                };
        };
+
+       iio_hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&lradc 8>;
+       };
 };
diff --git a/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi b/arch/arm/boot/dts/imx35-eukrea-cpuimx35.dtsi
new file mode 100644 (file)
index 0000000..906ae93
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "imx35.dtsi"
+
+/ {
+       model = "Eukrea CPUIMX35";
+       compatible = "eukrea,cpuimx35", "fsl,imx35";
+
+       memory {
+               reg = <0x80000000 0x8000000>; /* 128M */
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&iomuxc {
+       imx35-eukrea {
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX35_PAD_FEC_TX_CLK__FEC_TX_CLK         0x80000000
+                               MX35_PAD_FEC_RX_CLK__FEC_RX_CLK         0x80000000
+                               MX35_PAD_FEC_RX_DV__FEC_RX_DV           0x80000000
+                               MX35_PAD_FEC_COL__FEC_COL               0x80000000
+                               MX35_PAD_FEC_RDATA0__FEC_RDATA_0        0x80000000
+                               MX35_PAD_FEC_TDATA0__FEC_TDATA_0        0x80000000
+                               MX35_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX35_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX35_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX35_PAD_FEC_TX_ERR__FEC_TX_ERR         0x80000000
+                               MX35_PAD_FEC_RX_ERR__FEC_RX_ERR         0x80000000
+                               MX35_PAD_FEC_CRS__FEC_CRS               0x80000000
+                               MX35_PAD_FEC_RDATA1__FEC_RDATA_1        0x80000000
+                               MX35_PAD_FEC_TDATA1__FEC_TDATA_1        0x80000000
+                               MX35_PAD_FEC_RDATA2__FEC_RDATA_2        0x80000000
+                               MX35_PAD_FEC_TDATA2__FEC_TDATA_2        0x80000000
+                               MX35_PAD_FEC_RDATA3__FEC_RDATA_3        0x80000000
+                               MX35_PAD_FEC_TDATA3__FEC_TDATA_3        0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX35_PAD_I2C1_CLK__I2C1_SCL             0x80000000
+                               MX35_PAD_I2C1_DAT__I2C1_SDA             0x80000000
+                       >;
+               };
+       };
+};
+
+&nfc {
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts
new file mode 100644 (file)
index 0000000..1bdec21
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.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.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx35-eukrea-cpuimx35.dtsi"
+
+/ {
+       model = "Eukrea CPUIMX35";
+       compatible = "eukrea,mbimxsd35-baseboard", "eukrea,cpuimx35", "fsl,imx35";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_bp1>;
+
+               bp1 {
+                       label = "BP1";
+                       gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_MISC>;
+                       gpio-key,wakeup;
+                       linux,input-type = <1>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_led1>;
+
+               led1 {
+                       label = "led1";
+                       gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       cd-gpios = <&gpio3 24>;
+       status = "okay";
+};
+
+&i2c1 {
+       tlv320aic23: codec@1a {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1a>;
+       };
+};
+
+&iomuxc {
+       imx35-eukrea {
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS       0x80000000
+                               MX35_PAD_STXD4__AUDMUX_AUD4_TXD         0x80000000
+                               MX35_PAD_SRXD4__AUDMUX_AUD4_RXD         0x80000000
+                               MX35_PAD_SCK4__AUDMUX_AUD4_TXC          0x80000000
+                       >;
+               };
+
+               pinctrl_bp1: bp1grp {
+                       fsl,pins = <MX35_PAD_LD19__GPIO3_25  0x80000000>;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX35_PAD_SD1_CMD__ESDHC1_CMD            0x80000000
+                               MX35_PAD_SD1_CLK__ESDHC1_CLK            0x80000000
+                               MX35_PAD_SD1_DATA0__ESDHC1_DAT0         0x80000000
+                               MX35_PAD_SD1_DATA1__ESDHC1_DAT1         0x80000000
+                               MX35_PAD_SD1_DATA2__ESDHC1_DAT2         0x80000000
+                               MX35_PAD_SD1_DATA3__ESDHC1_DAT3         0x80000000
+                               MX35_PAD_LD18__GPIO3_24                 0x80000000 /* CD */
+                       >;
+               };
+
+               pinctrl_led1: led1grp {
+                       fsl,pins = <MX35_PAD_LD23__GPIO3_29  0x80000000>;
+               };
+
+               pinctrl_reg_lcd_3v3: reg-lcd-3v3 {
+                       fsl,pins = <MX35_PAD_D3_CLS__GPIO1_4 0x80000000>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX35_PAD_TXD1__UART1_TXD_MUX            0x1c5
+                               MX35_PAD_RXD1__UART1_RXD_MUX            0x1c5
+                               MX35_PAD_CTS1__UART1_CTS                0x1c5
+                               MX35_PAD_RTS1__UART1_RTS                0x1c5
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX35_PAD_RXD2__UART2_RXD_MUX            0x1c5
+                               MX35_PAD_TXD2__UART2_TXD_MUX            0x1c5
+                               MX35_PAD_RTS2__UART2_RTS                0x1c5
+                               MX35_PAD_CTS2__UART2_CTS                0x1c5
+                       >;
+               };
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi
new file mode 100644 (file)
index 0000000..88b218f
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2012 Steffen Trumtrar, Pengutronix
+ *
+ * based on imx27.dtsi
+ *
+ * This program is free software; you can 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 "skeleton.dtsi"
+#include "imx35-pinfunc.h"
+
+/ {
+       aliases {
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               spi0 = &spi1;
+               spi1 = &spi2;
+       };
+
+       cpus {
+               #address-cells = <0>;
+               #size-cells = <0>;
+
+               cpu {
+                       compatible = "arm,arm1136";
+                       device_type = "cpu";
+               };
+       };
+
+       avic: avic-interrupt-controller@68000000 {
+               compatible = "fsl,imx35-avic", "fsl,avic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0x68000000 0x10000000>;
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&avic>;
+               ranges;
+
+               L2: l2-cache@30000000 {
+                       compatible = "arm,l210-cache";
+                       reg = <0x30000000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               aips1: aips@43f00000 {
+                       compatible = "fsl,aips", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x43f00000 0x100000>;
+                       ranges;
+
+                       i2c1: i2c@43f80000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx35-i2c", "fsl,imx1-i2c";
+                               reg = <0x43f80000 0x4000>;
+                               clocks = <&clks 51>;
+                               clock-names = "ipg_per";
+                               interrupts = <10>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@43f84000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx35-i2c", "fsl,imx1-i2c";
+                               reg = <0x43f84000 0x4000>;
+                               clocks = <&clks 53>;
+                               clock-names = "ipg_per";
+                               interrupts = <3>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@43f90000 {
+                               compatible = "fsl,imx35-uart", "fsl,imx21-uart";
+                               reg = <0x43f90000 0x4000>;
+                               clocks = <&clks 9>, <&clks 70>;
+                               clock-names = "ipg", "per";
+                               interrupts = <45>;
+                               status = "disabled";
+                       };
+
+                       uart2: serial@43f94000 {
+                               compatible = "fsl,imx35-uart", "fsl,imx21-uart";
+                               reg = <0x43f94000 0x4000>;
+                               clocks = <&clks 9>, <&clks 71>;
+                               clock-names = "ipg", "per";
+                               interrupts = <32>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@43f98000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx35-i2c", "fsl,imx1-i2c";
+                               reg = <0x43f98000 0x4000>;
+                               clocks = <&clks 52>;
+                               clock-names = "ipg_per";
+                               interrupts = <4>;
+                               status = "disabled";
+                       };
+
+                       ssi1: ssi@43fa0000 {
+                               compatible = "fsl,imx35-ssi", "fsl,imx21-ssi";
+                               reg = <0x43fa0000 0x4000>;
+                               interrupts = <11>;
+                               clocks = <&clks 68>;
+                               dmas = <&sdma 28 0 0>,
+                                      <&sdma 29 0 0>;
+                               dma-names = "rx", "tx";
+                               fsl,fifo-depth = <15>;
+                               status = "disabled";
+                       };
+
+                       spi1: cspi@43fa4000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx35-cspi";
+                               reg = <0x43fa4000 0x4000>;
+                               clocks = <&clks 35 &clks 35>;
+                               clock-names = "ipg", "per";
+                               interrupts = <14>;
+                               status = "disabled";
+                       };
+
+                       iomuxc: iomuxc@43fac000 {
+                               compatible = "fsl,imx35-iomuxc";
+                               reg = <0x43fac000 0x4000>;
+                       };
+               };
+
+               spba: spba-bus@50000000 {
+                       compatible = "fsl,spba-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x50000000 0x100000>;
+                       ranges;
+
+                       uart3: serial@5000c000 {
+                               compatible = "fsl,imx35-uart", "fsl,imx21-uart";
+                               reg = <0x5000c000 0x4000>;
+                               clocks = <&clks 9>, <&clks 72>;
+                               clock-names = "ipg", "per";
+                               interrupts = <18>;
+                               status = "disabled";
+                       };
+
+                       spi2: cspi@50010000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx35-cspi";
+                               reg = <0x50010000 0x4000>;
+                               interrupts = <13>;
+                               clocks = <&clks 36 &clks 36>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       fec: fec@50038000 {
+                               compatible = "fsl,imx35-fec", "fsl,imx27-fec";
+                               reg = <0x50038000 0x4000>;
+                               clocks = <&clks 46>, <&clks 8>;
+                               clock-names = "ipg", "ahb";
+                               interrupts = <57>;
+                               status = "disabled";
+                       };
+               };
+
+               aips2: aips@53f00000 {
+                       compatible = "fsl,aips", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x53f00000 0x100000>;
+                       ranges;
+
+                       clks: ccm@53f80000 {
+                               compatible = "fsl,imx35-ccm";
+                               reg = <0x53f80000 0x4000>;
+                               interrupts = <31>;
+                               #clock-cells = <1>;
+                       };
+
+                       gpio3: gpio@53fa4000 {
+                               compatible = "fsl,imx35-gpio", "fsl,imx31-gpio";
+                               reg = <0x53fa4000 0x4000>;
+                               interrupts = <56>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       esdhc1: esdhc@53fb4000 {
+                               compatible = "fsl,imx35-esdhc";
+                               reg = <0x53fb4000 0x4000>;
+                               interrupts = <7>;
+                               clocks = <&clks 9>, <&clks 8>, <&clks 43>;
+                               clock-names = "ipg", "ahb", "per";
+                               status = "disabled";
+                       };
+
+                       esdhc2: esdhc@53fb8000 {
+                               compatible = "fsl,imx35-esdhc";
+                               reg = <0x53fb8000 0x4000>;
+                               interrupts = <8>;
+                               clocks = <&clks 9>, <&clks 8>, <&clks 44>;
+                               clock-names = "ipg", "ahb", "per";
+                               status = "disabled";
+                       };
+
+                       esdhc3: esdhc@53fbc000 {
+                               compatible = "fsl,imx35-esdhc";
+                               reg = <0x53fbc000 0x4000>;
+                               interrupts = <9>;
+                               clocks = <&clks 9>, <&clks 8>, <&clks 45>;
+                               clock-names = "ipg", "ahb", "per";
+                               status = "disabled";
+                       };
+
+                       audmux: audmux@53fc4000 {
+                               compatible = "fsl,imx35-audmux", "fsl,imx31-audmux";
+                               reg = <0x53fc4000 0x4000>;
+                               status = "disabled";
+                       };
+
+                       gpio1: gpio@53fcc000 {
+                               compatible = "fsl,imx35-gpio", "fsl,imx31-gpio";
+                               reg = <0x53fcc000 0x4000>;
+                               interrupts = <52>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@53fd0000 {
+                               compatible = "fsl,imx35-gpio", "fsl,imx31-gpio";
+                               reg = <0x53fd0000 0x4000>;
+                               interrupts = <51>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       sdma: sdma@53fd4000 {
+                               compatible = "fsl,imx35-sdma";
+                               reg = <0x53fd4000 0x4000>;
+                               clocks = <&clks 9>, <&clks 65>;
+                               clock-names = "ipg", "ahb";
+                               #dma-cells = <3>;
+                               interrupts = <34>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx35.bin";
+                       };
+
+                       wdog: wdog@53fdc000 {
+                               compatible = "fsl,imx35-wdt", "fsl,imx21-wdt";
+                               reg = <0x53fdc000 0x4000>;
+                               clocks = <&clks 74>;
+                               clock-names = "";
+                               interrupts = <55>;
+                       };
+
+                       can1: can@53fe4000 {
+                               compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan";
+                               reg = <0x53fe4000 0x1000>;
+                               clocks = <&clks 33>;
+                               clock-names = "ipg";
+                               interrupts = <43>;
+                               status = "disabled";
+                       };
+
+                       can2: can@53fe8000 {
+                               compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan";
+                               reg = <0x53fe8000 0x1000>;
+                               clocks = <&clks 34>;
+                               clock-names = "ipg";
+                               interrupts = <44>;
+                               status = "disabled";
+                       };
+
+                       usbotg: usb@53ff4000 {
+                               compatible = "fsl,imx35-usb", "fsl,imx27-usb";
+                               reg = <0x53ff4000 0x0200>;
+                               interrupts = <37>;
+                               clocks = <&clks 9>, <&clks 73>, <&clks 28>;
+                               clock-names = "ipg", "ahb", "per";
+                               fsl,usbmisc = <&usbmisc 0>;
+                               status = "disabled";
+                       };
+
+                       usbhost1: usb@53ff4400 {
+                               compatible = "fsl,imx35-usb", "fsl,imx27-usb";
+                               reg = <0x53ff4400 0x0200>;
+                               interrupts = <35>;
+                               clocks = <&clks 9>, <&clks 73>, <&clks 28>;
+                               clock-names = "ipg", "ahb", "per";
+                               fsl,usbmisc = <&usbmisc 1>;
+                               status = "disabled";
+                       };
+
+                       usbmisc: usbmisc@53ff4600 {
+                               #index-cells = <1>;
+                               compatible = "fsl,imx35-usbmisc";
+                               clocks = <&clks 9>, <&clks 73>, <&clks 28>;
+                               clock-names = "ipg", "ahb", "per";
+                               reg = <0x53ff4600 0x00f>;
+                       };
+               };
+
+               emi@80000000 { /* External Memory Interface */
+                       compatible = "fsl,emi", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80000000 0x40000000>;
+                       ranges;
+
+                       nfc: nand@bb000000 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "fsl,imx35-nand", "fsl,imx25-nand";
+                               reg = <0xbb000000 0x2000>;
+                               clocks = <&clks 29>;
+                               clock-names = "";
+                               interrupts = <33>;
+                               status = "disabled";
+                       };
+
+                       weim: weim@b8002000 {
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               clocks = <&clks 0>;
+                               compatible = "fsl,imx35-weim", "fsl,imx27-weim";
+                               reg = <0xb8002000 0x1000>;
+                               ranges = <
+                                       0 0 0xa0000000 0x8000000
+                                       1 0 0xa8000000 0x8000000
+                                       2 0 0xb0000000 0x2000000
+                                       3 0 0xb2000000 0x2000000
+                                       4 0 0xb4000000 0x2000000
+                                       5 0 0xb6000000 0x2000000
+                               >;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts
new file mode 100644 (file)
index 0000000..1b22512
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx50.dtsi"
+
+/ {
+       model = "Freescale i.MX50 Evaluation Kit";
+       compatible = "fsl,imx50-evk", "fsl,imx50";
+
+       memory {
+               reg = <0x70000000 0x80000000>;
+       };
+};
+
+&cspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cspi>;
+       fsl,spi-num-chipselects = <2>;
+       cs-gpios = <&gpio4 11 0>, <&gpio4 13 0>;
+       status = "okay";
+
+       flash: m25p32@1 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "m25p32", "m25p80";
+               spi-max-frequency = <25000000>;
+               reg = <1>;
+
+               partition@0 {
+                       label = "bootloader";
+                       reg = <0x0 0x100000>;
+                       read-only;
+               };
+
+               partition@100000 {
+                       label = "kernel";
+                       reg = <0x100000 0x300000>;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "rmii";
+       phy-reset-gpios = <&gpio4 12 0>;
+       status = "okay";
+};
+
+&iomuxc {
+       imx50-evk {
+               pinctrl_cspi: cspigrp {
+                       fsl,pins = <
+                               MX50_PAD_CSPI_SCLK__CSPI_SCLK           0x00
+                               MX50_PAD_CSPI_MISO__CSPI_MISO           0x00
+                               MX50_PAD_CSPI_MOSI__CSPI_MOSI           0x00
+                               MX50_PAD_CSPI_SS0__GPIO4_11             0xc4
+                               MX50_PAD_ECSPI1_MOSI__CSPI_SS1          0xf4
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX50_PAD_SSI_RXFS__FEC_MDC              0x80
+                               MX50_PAD_SSI_RXC__FEC_MDIO              0x80
+                               MX50_PAD_DISP_D0__FEC_TX_CLK            0x80
+                               MX50_PAD_DISP_D1__FEC_RX_ERR            0x80
+                               MX50_PAD_DISP_D2__FEC_RX_DV             0x80
+                               MX50_PAD_DISP_D3__FEC_RDATA_1           0x80
+                               MX50_PAD_DISP_D4__FEC_RDATA_0           0x80
+                               MX50_PAD_DISP_D5__FEC_TX_EN             0x80
+                               MX50_PAD_DISP_D6__FEC_TDATA_1           0x80
+                               MX50_PAD_DISP_D7__FEC_TDATA_0           0x80
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX50_PAD_UART1_TXD__UART1_TXD_MUX       0x1e4
+                               MX50_PAD_UART1_RXD__UART1_RXD_MUX       0x1e4
+                               MX50_PAD_UART1_RTS__UART1_RTS           0x1e4
+                               MX50_PAD_UART1_CTS__UART1_CTS           0x1e4
+                       >;
+               };
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbh2 {
+       status = "okay";
+};
+
+&usbh3 {
+       status = "okay";
+};
+
+&usbotg {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx50-pinfunc.h b/arch/arm/boot/dts/imx50-pinfunc.h
new file mode 100644 (file)
index 0000000..97e6e7f
--- /dev/null
@@ -0,0 +1,923 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX50_PINFUNC_H
+#define __DTS_IMX50_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX50_PAD_KEY_COL0__KPP_COL_0                           0x020 0x2cc 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL0__GPIO4_0                             0x020 0x2cc 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL0__EIM_NANDF_CLE                       0x020 0x2cc 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL0__CTI_TRIGIN7                         0x020 0x2cc 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL0__USBPHY1_TXREADY                     0x020 0x2cc 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW0__KPP_ROW_0                           0x024 0x2d0 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW0__GPIO4_1                             0x024 0x2d0 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW0__EIM_NANDF_ALE                       0x024 0x2d0 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW0__CTI_TRIGIN_ACK7                     0x024 0x2d0 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW0__USBPHY1_RXVALID                     0x024 0x2d0 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL1__KPP_COL_1                           0x028 0x2d4 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL1__GPIO4_2                             0x028 0x2d4 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL1__EIM_NANDF_CEN_0                     0x028 0x2d4 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL1__CTI_TRIGOUT_ACK6                    0x028 0x2d4 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL1__USBPHY1_RXACTIVE                    0x028 0x2d4 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW1__KPP_ROW_1                           0x02c 0x2d8 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW1__GPIO4_3                             0x02c 0x2d8 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW1__EIM_NANDF_CEN_1                     0x02c 0x2d8 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW1__CTI_TRIGOUT_ACK7                    0x02c 0x2d8 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW1__USBPHY1_RXERROR                     0x02c 0x2d8 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL2__KPP_COL_1                           0x030 0x2dc 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL2__GPIO4_4                             0x030 0x2dc 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL2__EIM_NANDF_CEN_2                     0x030 0x2dc 0x000 0x2 0x0
+#define MX50_PAD_KEY_COL2__CTI_TRIGOUT6                                0x030 0x2dc 0x000 0x6 0x0
+#define MX50_PAD_KEY_COL2__USBPHY1_SIECLOCK                    0x030 0x2dc 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW2__KPP_ROW_2                           0x034 0x2e0 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW2__GPIO4_5                             0x034 0x2e0 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW2__EIM_NANDF_CEN_3                     0x034 0x2e0 0x000 0x2 0x0
+#define MX50_PAD_KEY_ROW2__CTI_TRIGOUT7                                0x034 0x2e0 0x000 0x6 0x0
+#define MX50_PAD_KEY_ROW2__USBPHY1_LINESTATE_0                 0x034 0x2e0 0x000 0x7 0x0
+#define MX50_PAD_KEY_COL3__KPP_COL_2                           0x038 0x2e4 0x000 0x0 0x0
+#define MX50_PAD_KEY_COL3__GPIO4_6                             0x038 0x2e4 0x000 0x1 0x0
+#define MX50_PAD_KEY_COL3__EIM_NANDF_READY0                    0x038 0x2e4 0x7b4 0x2 0x0
+#define MX50_PAD_KEY_COL3__SDMA_EXT_EVENT_0                    0x038 0x2e4 0x7b8 0x6 0x0
+#define MX50_PAD_KEY_COL3__USBPHY1_LINESTATE_1                 0x038 0x2e4 0x000 0x7 0x0
+#define MX50_PAD_KEY_ROW3__KPP_ROW_3                           0x03c 0x2e8 0x000 0x0 0x0
+#define MX50_PAD_KEY_ROW3__GPIO4_7                             0x03c 0x2e8 0x000 0x1 0x0
+#define MX50_PAD_KEY_ROW3__EIM_NANDF_DQS                       0x03c 0x2e8 0x7b0 0x2 0x0
+#define MX50_PAD_KEY_ROW3__SDMA_EXT_EVENT_1                    0x03c 0x2e8 0x7bc 0x6 0x0
+#define MX50_PAD_KEY_ROW3__USBPHY1_VBUSVALID                   0x03c 0x2e8 0x000 0x7 0x0
+#define MX50_PAD_I2C1_SCL__I2C1_SCL                            0x040 0x2ec 0x000 0x0 0x0
+#define MX50_PAD_I2C1_SCL__GPIO6_18                            0x040 0x2ec 0x000 0x1 0x0
+#define MX50_PAD_I2C1_SCL__UART2_TXD_MUX                       0x040 0x2ec 0x7cc 0x2 0x0
+#define MX50_PAD_I2C1_SDA__I2C1_SDA                            0x044 0x2f0 0x000 0x0 0x0
+#define MX50_PAD_I2C1_SDA__GPIO6_19                            0x044 0x2f0 0x000 0x1 0x0
+#define MX50_PAD_I2C1_SDA__UART2_RXD_MUX                       0x044 0x2f0 0x7cc 0x2 0x1
+#define MX50_PAD_I2C2_SCL__I2C2_SCL                            0x048 0x2f4 0x000 0x0 0x0
+#define MX50_PAD_I2C2_SCL__GPIO6_20                            0x048 0x2f4 0x000 0x1 0x0
+#define MX50_PAD_I2C2_SCL__UART2_CTS                           0x048 0x2f4 0x000 0x2 0x0
+#define MX50_PAD_I2C2_SDA__I2C2_SDA                            0x04c 0x2f8 0x000 0x0 0x0
+#define MX50_PAD_I2C2_SDA__GPIO6_21                            0x04c 0x2f8 0x000 0x1 0x0
+#define MX50_PAD_I2C2_SDA__UART2_RTS                           0x04c 0x2f8 0x7c8 0x2 0x1
+#define MX50_PAD_I2C3_SCL__I2C3_SCL                            0x050 0x2fc 0x000 0x0 0x0
+#define MX50_PAD_I2C3_SCL__GPIO6_22                            0x050 0x2fc 0x000 0x1 0x0
+#define MX50_PAD_I2C3_SCL__FEC_MDC                             0x050 0x2fc 0x000 0x2 0x0
+#define MX50_PAD_I2C3_SCL__GPC_PMIC_RDY                                0x050 0x2fc 0x000 0x3 0x0
+#define MX50_PAD_I2C3_SCL__GPT_CAPIN1                          0x050 0x2fc 0x000 0x5 0x0
+#define MX50_PAD_I2C3_SCL__OBSERVE_MUX_OBSRV_INT_OUT0          0x050 0x2fc 0x000 0x6 0x0
+#define MX50_PAD_I2C3_SCL__USBOH1_USBOTG_OC                    0x050 0x2fc 0x7e8 0x7 0x0
+#define MX50_PAD_I2C3_SDA__I2C3_SDA                            0x054 0x300 0x000 0x0 0x0
+#define MX50_PAD_I2C3_SDA__GPIO6_23                            0x054 0x300 0x000 0x1 0x0
+#define MX50_PAD_I2C3_SDA__FEC_MDIO                            0x054 0x300 0x774 0x2 0x0
+#define MX50_PAD_I2C3_SDA__TZIC_PWRFAIL_INT                    0x054 0x300 0x000 0x3 0x0
+#define MX50_PAD_I2C3_SDA__SRTC_ALARM_DEB                      0x054 0x300 0x000 0x4 0x0
+#define MX50_PAD_I2C3_SDA__GPT_CAPIN2                          0x054 0x300 0x000 0x5 0x0
+#define MX50_PAD_I2C3_SDA__OBSERVE_MUX_OBSRV_INT_OUT1          0x054 0x300 0x000 0x6 0x0
+#define MX50_PAD_I2C3_SDA__USBOH1_USBOTG_PWR                   0x054 0x300 0x000 0x7 0x0
+#define MX50_PAD_PWM1__PWM1_PWMO                               0x058 0x304 0x000 0x0 0x0
+#define MX50_PAD_PWM1__GPIO6_24                                        0x058 0x304 0x000 0x1 0x0
+#define MX50_PAD_PWM1__USBOH1_USBOTG_OC                                0x058 0x304 0x7e8 0x2 0x1
+#define MX50_PAD_PWM1__GPT_CMPOUT1                             0x058 0x304 0x000 0x5 0x0
+#define MX50_PAD_PWM1__OBSERVE_MUX_OBSRV_INT_OUT2              0x058 0x304 0x000 0x6 0x0
+#define MX50_PAD_PWM1__SJC_FAIL                                        0x058 0x304 0x000 0x7 0x0
+#define MX50_PAD_PWM2__PWM2_PWMO                               0x05c 0x308 0x000 0x0 0x0
+#define MX50_PAD_PWM2__GPIO6_25                                        0x05c 0x308 0x000 0x1 0x0
+#define MX50_PAD_PWM2__USBOH1_USBOTG_PWR                       0x05c 0x308 0x000 0x2 0x0
+#define MX50_PAD_PWM2__GPT_CMPOUT2                             0x05c 0x308 0x000 0x5 0x0
+#define MX50_PAD_PWM2__OBSERVE_MUX_OBSRV_INT_OUT3              0x05c 0x308 0x000 0x6 0x0
+#define MX50_PAD_PWM2__SRC_ANY_PU_RST                          0x05c 0x308 0x000 0x7 0x0
+#define MX50_PAD_OWIRE__OWIRE_LINE                             0x060 0x30c 0x000 0x0 0x0
+#define MX50_PAD_OWIRE__GPIO6_26                               0x060 0x30c 0x000 0x1 0x0
+#define MX50_PAD_OWIRE__USBOH1_USBH1_OC                                0x060 0x30c 0x000 0x2 0x0
+#define MX50_PAD_OWIRE__CCM_SSI_EXT1_CLK                       0x060 0x30c 0x000 0x3 0x0
+#define MX50_PAD_OWIRE__EPDC_PWRIRQ                            0x060 0x30c 0x000 0x4 0x0
+#define MX50_PAD_OWIRE__GPT_CMPOUT3                            0x060 0x30c 0x000 0x5 0x0
+#define MX50_PAD_OWIRE__OBSERVE_MUX_OBSRV_INT_OUT4             0x060 0x30c 0x000 0x6 0x0
+#define MX50_PAD_OWIRE__SJC_JTAG_ACT                           0x060 0x30c 0x000 0x7 0x0
+#define MX50_PAD_EPITO__EPIT1_EPITO                            0x064 0x310 0x000 0x0 0x0
+#define MX50_PAD_EPITO__GPIO6_27                               0x064 0x310 0x000 0x1 0x0
+#define MX50_PAD_EPITO__USBOH1_USBH1_PWR                       0x064 0x310 0x000 0x2 0x0
+#define MX50_PAD_EPITO__CCM_SSI_EXT2_CLK                       0x064 0x310 0x000 0x3 0x0
+#define MX50_PAD_EPITO__DPLLIP1_TOG_EN                         0x064 0x310 0x000 0x4 0x0
+#define MX50_PAD_EPITO__GPT_CLK_IN                             0x064 0x310 0x000 0x5 0x0
+#define MX50_PAD_EPITO__PMU_IRQ_B                              0x064 0x310 0x000 0x6 0x0
+#define MX50_PAD_EPITO__SJC_DE_B                               0x064 0x310 0x000 0x7 0x0
+#define MX50_PAD_WDOG__WDOG1_WDOG_B                            0x068 0x314 0x000 0x0 0x0
+#define MX50_PAD_WDOG__GPIO6_28                                        0x068 0x314 0x000 0x1 0x0
+#define MX50_PAD_WDOG__WDOG1_WDOG_RST_B_DEB                    0x068 0x314 0x000 0x2 0x0
+#define MX50_PAD_WDOG__CCM_XTAL32K                             0x068 0x314 0x000 0x6 0x0
+#define MX50_PAD_WDOG__SJC_DONE                                        0x068 0x314 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXFS__AUDMUX_AUD3_TXFS                    0x06c 0x318 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXFS__GPIO6_0                             0x06c 0x318 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXFS__SRC_BT_FUSE_RSV_1                   0x06c 0x318 0x000 0x6 0x0
+#define MX50_PAD_SSI_TXFS__USBPHY1_DATAOUT_8                   0x06c 0x318 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXC__AUDMUX_AUD3_TXC                      0x070 0x31c 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXC__GPIO6_1                              0x070 0x31c 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXC__SRC_BT_FUSE_RSV_0                    0x070 0x31c 0x000 0x6 0x0
+#define MX50_PAD_SSI_TXC__USBPHY1_DATAOUT_9                    0x070 0x31c 0x000 0x7 0x0
+#define MX50_PAD_SSI_TXD__AUDMUX_AUD3_TXD                      0x074 0x320 0x000 0x0 0x0
+#define MX50_PAD_SSI_TXD__GPIO6_2                              0x074 0x320 0x000 0x1 0x0
+#define MX50_PAD_SSI_TXD__CSPI_RDY                             0x074 0x320 0x6e8 0x4 0x0
+#define MX50_PAD_SSI_TXD__USBPHY1_DATAOUT_10                   0x074 0x320 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXD__AUDMUX_AUD3_RXD                      0x078 0x324 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXD__GPIO6_3                              0x078 0x324 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXD__CSPI_SS3                             0x078 0x324 0x6f4 0x4 0x0
+#define MX50_PAD_SSI_RXD__USBPHY1_DATAOUT_11                   0x078 0x324 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXFS__AUDMUX_AUD3_RXFS                    0x07c 0x328 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXFS__GPIO6_4                             0x07c 0x328 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXFS__UART5_TXD_MUX                       0x07c 0x328 0x7e4 0x2 0x0
+#define MX50_PAD_SSI_RXFS__EIM_WEIM_D_6                                0x07c 0x328 0x804 0x3 0x0
+#define MX50_PAD_SSI_RXFS__CSPI_SS2                            0x07c 0x328 0x6f0 0x4 0x0
+#define MX50_PAD_SSI_RXFS__FEC_COL                             0x07c 0x328 0x770 0x5 0x0
+#define MX50_PAD_SSI_RXFS__FEC_MDC                             0x07c 0x328 0x000 0x6 0x0
+#define MX50_PAD_SSI_RXFS__USBPHY1_DATAOUT_12                  0x07c 0x328 0x000 0x7 0x0
+#define MX50_PAD_SSI_RXC__AUDMUX_AUD3_RXC                      0x080 0x32c 0x000 0x0 0x0
+#define MX50_PAD_SSI_RXC__GPIO6_5                              0x080 0x32c 0x000 0x1 0x0
+#define MX50_PAD_SSI_RXC__UART5_RXD_MUX                                0x080 0x32c 0x7e4 0x2 0x1
+#define MX50_PAD_SSI_RXC__EIM_WEIM_D_7                         0x080 0x32c 0x808 0x3 0x0
+#define MX50_PAD_SSI_RXC__CSPI_SS1                             0x080 0x32c 0x6ec 0x4 0x0
+#define MX50_PAD_SSI_RXC__FEC_RX_CLK                           0x080 0x32c 0x780 0x5 0x0
+#define MX50_PAD_SSI_RXC__FEC_MDIO                             0x080 0x32c 0x774 0x6 0x1
+#define MX50_PAD_SSI_RXC__USBPHY1_DATAOUT_13                   0x080 0x32c 0x000 0x7 0x0
+#define MX50_PAD_UART1_TXD__UART1_TXD_MUX                      0x084 0x330 0x7c4 0x0 0x0
+#define MX50_PAD_UART1_TXD__GPIO6_6                            0x084 0x330 0x000 0x1 0x0
+#define MX50_PAD_UART1_TXD__USBPHY1_DATAOUT_14                 0x084 0x330 0x000 0x7 0x0
+#define MX50_PAD_UART1_RXD__UART1_RXD_MUX                      0x088 0x334 0x7c4 0x0 0x1
+#define MX50_PAD_UART1_RXD__GPIO6_7                            0x088 0x334 0x000 0x1 0x0
+#define MX50_PAD_UART1_RXD__USBPHY1_DATAOUT_15                 0x088 0x334 0x000 0x7 0x0
+#define MX50_PAD_UART1_CTS__UART1_CTS                          0x08c 0x338 0x000 0x0 0x0
+#define MX50_PAD_UART1_CTS__GPIO6_8                            0x08c 0x338 0x000 0x1 0x0
+#define MX50_PAD_UART1_CTS__UART5_TXD_MUX                      0x08c 0x338 0x7e4 0x2 0x2
+#define MX50_PAD_UART1_CTS__ESDHC4_DAT4                                0x08c 0x338 0x760 0x4 0x0
+#define MX50_PAD_UART1_CTS__ESDHC4_CMD                         0x08c 0x338 0x74c 0x5 0x0
+#define MX50_PAD_UART1_CTS__USBPHY2_DATAOUT_8                  0x08c 0x338 0x000 0x7 0x0
+#define MX50_PAD_UART1_RTS__UART1_RTS                          0x090 0x33c 0x7c0 0x0 0x3
+#define MX50_PAD_UART1_RTS__GPIO6_9                            0x090 0x33c 0x000 0x1 0x0
+#define MX50_PAD_UART1_RTS__UART5_RXD_MUX                      0x090 0x33c 0x7e4 0x2 0x3
+#define MX50_PAD_UART1_RTS__ESDHC4_DAT5                                0x090 0x33c 0x764 0x4 0x0
+#define MX50_PAD_UART1_RTS__ESDHC4_CLK                         0x090 0x33c 0x748 0x5 0x0
+#define MX50_PAD_UART1_RTS__USBPHY2_DATAOUT_9                  0x090 0x33c 0x000 0x7 0x0
+#define MX50_PAD_UART2_TXD__UART2_TXD_MUX                      0x094 0x340 0x7cc 0x0 0x2
+#define MX50_PAD_UART2_TXD__GPIO6_10                           0x094 0x340 0x000 0x1 0x0
+#define MX50_PAD_UART2_TXD__ESDHC4_DAT6                                0x094 0x340 0x768 0x4 0x0
+#define MX50_PAD_UART2_TXD__ESDHC4_DAT4                                0x094 0x340 0x760 0x5 0x1
+#define MX50_PAD_UART2_TXD__USBPHY2_DATAOUT_10                 0x094 0x340 0x000 0x7 0x0
+#define MX50_PAD_UART2_RXD__UART2_RXD_MUX                      0x098 0x344 0x7cc 0x0 0x3
+#define MX50_PAD_UART2_RXD__GPIO6_11                           0x098 0x344 0x000 0x1 0x0
+#define MX50_PAD_UART2_RXD__ESDHC4_DAT7                                0x098 0x344 0x76c 0x4 0x0
+#define MX50_PAD_UART2_RXD__ESDHC4_DAT5                                0x098 0x344 0x764 0x5 0x1
+#define MX50_PAD_UART2_RXD__USBPHY2_DATAOUT_11                 0x098 0x344 0x000 0x7 0x0
+#define MX50_PAD_UART2_CTS__UART2_CTS                          0x09c 0x348 0x000 0x0 0x0
+#define MX50_PAD_UART2_CTS__GPIO6_12                           0x09c 0x348 0x000 0x1 0x0
+#define MX50_PAD_UART2_CTS__ESDHC4_CMD                         0x09c 0x348 0x74c 0x4 0x1
+#define MX50_PAD_UART2_CTS__ESDHC4_DAT6                                0x09c 0x348 0x768 0x5 0x1
+#define MX50_PAD_UART2_CTS__USBPHY2_DATAOUT_12                 0x09c 0x348 0x000 0x7 0x0
+#define MX50_PAD_UART2_RTS__UART2_RTS                          0x0a0 0x34c 0x7c8 0x0 0x2
+#define MX50_PAD_UART2_RTS__GPIO6_13                           0x0a0 0x34c 0x000 0x1 0x0
+#define MX50_PAD_UART2_RTS__ESDHC4_CLK                         0x0a0 0x34c 0x748 0x4 0x1
+#define MX50_PAD_UART2_RTS__ESDHC4_DAT7                                0x0a0 0x34c 0x76c 0x5 0x1
+#define MX50_PAD_UART2_RTS__USBPHY2_DATAOUT_13                 0x0a0 0x34c 0x000 0x7 0x0
+#define MX50_PAD_UART3_TXD__UART3_TXD_MUX                      0x0a4 0x350 0x7d4 0x0 0x0
+#define MX50_PAD_UART3_TXD__GPIO6_14                           0x0a4 0x350 0x000 0x1 0x0
+#define MX50_PAD_UART3_TXD__ESDHC1_DAT4                                0x0a4 0x350 0x000 0x3 0x0
+#define MX50_PAD_UART3_TXD__ESDHC4_DAT0                                0x0a4 0x350 0x000 0x4 0x0
+#define MX50_PAD_UART3_TXD__ESDHC2_WP                          0x0a4 0x350 0x744 0x5 0x0
+#define MX50_PAD_UART3_TXD__EIM_WEIM_D_12                      0x0a4 0x350 0x81c 0x6 0x0
+#define MX50_PAD_UART3_TXD__USBPHY2_DATAOUT_14                 0x0a4 0x350 0x000 0x7 0x0
+#define MX50_PAD_UART3_RXD__UART3_RXD_MUX                      0x0a8 0x354 0x7d4 0x0 0x1
+#define MX50_PAD_UART3_RXD__GPIO6_15                           0x0a8 0x354 0x000 0x1 0x0
+#define MX50_PAD_UART3_RXD__ESDHC1_DAT5                                0x0a8 0x354 0x000 0x3 0x0
+#define MX50_PAD_UART3_RXD__ESDHC4_DAT1                                0x0a8 0x354 0x754 0x4 0x0
+#define MX50_PAD_UART3_RXD__ESDHC2_CD                          0x0a8 0x354 0x740 0x5 0x0
+#define MX50_PAD_UART3_RXD__EIM_WEIM_D_13                      0x0a8 0x354 0x820 0x6 0x0
+#define MX50_PAD_UART3_RXD__USBPHY2_DATAOUT_15                 0x0a8 0x354 0x000 0x7 0x0
+#define MX50_PAD_UART4_TXD__UART4_TXD_MUX                      0x0ac 0x358 0x7dc 0x0 0x0
+#define MX50_PAD_UART4_TXD__GPIO6_16                           0x0ac 0x358 0x000 0x1 0x0
+#define MX50_PAD_UART4_TXD__UART3_CTS                          0x0ac 0x358 0x7d0 0x2 0x0
+#define MX50_PAD_UART4_TXD__ESDHC1_DAT6                                0x0ac 0x358 0x000 0x3 0x0
+#define MX50_PAD_UART4_TXD__ESDHC4_DAT2                                0x0ac 0x358 0x758 0x4 0x0
+#define MX50_PAD_UART4_TXD__ESDHC2_LCTL                                0x0ac 0x358 0x000 0x5 0x0
+#define MX50_PAD_UART4_TXD__EIM_WEIM_D_14                      0x0ac 0x358 0x824 0x6 0x0
+#define MX50_PAD_UART4_RXD__UART4_RXD_MUX                      0x0b0 0x35c 0x7dc 0x0 0x1
+#define MX50_PAD_UART4_RXD__GPIO6_17                           0x0b0 0x35c 0x000 0x1 0x0
+#define MX50_PAD_UART4_RXD__UART3_RTS                          0x0b0 0x35c 0x7d0 0x2 0x1
+#define MX50_PAD_UART4_RXD__ESDHC1_DAT7                                0x0b0 0x35c 0x000 0x3 0x0
+#define MX50_PAD_UART4_RXD__ESDHC4_DAT3                                0x0b0 0x35c 0x75c 0x4 0x0
+#define MX50_PAD_UART4_RXD__ESDHC1_LCTL                                0x0b0 0x35c 0x000 0x5 0x0
+#define MX50_PAD_UART4_RXD__EIM_WEIM_D_15                      0x0b0 0x35c 0x828 0x6 0x0
+#define MX50_PAD_CSPI_SCLK__CSPI_SCLK                          0x0b4 0x360 0x000 0x0 0x0
+#define MX50_PAD_CSPI_SCLK__GPIO4_8                            0x0b4 0x360 0x000 0x1 0x0
+#define MX50_PAD_CSPI_MOSI__CSPI_MOSI                          0x0b8 0x364 0x000 0x0 0x0
+#define MX50_PAD_CSPI_MOSI__GPIO4_9                            0x0b8 0x364 0x000 0x1 0x0
+#define MX50_PAD_CSPI_MISO__CSPI_MISO                          0x0bc 0x368 0x000 0x0 0x0
+#define MX50_PAD_CSPI_MISO__GPIO4_10                           0x0bc 0x368 0x000 0x1 0x0
+#define MX50_PAD_CSPI_SS0__CSPI_SS0                            0x0c0 0x36c 0x000 0x0 0x0
+#define MX50_PAD_CSPI_SS0__GPIO4_11                            0x0c0 0x36c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK                      0x0c4 0x370 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_SCLK__GPIO4_12                         0x0c4 0x370 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SCLK__CSPI_RDY                         0x0c4 0x370 0x6e8 0x2 0x1
+#define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY                       0x0c4 0x370 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_SCLK__UART3_RTS                                0x0c4 0x370 0x7d0 0x4 0x2
+#define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE_6                      0x0c4 0x370 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_SCLK__EIM_WEIM_D_8                     0x0c4 0x370 0x80c 0x7 0x0
+#define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI                      0x0c8 0x374 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_MOSI__GPIO4_13                         0x0c8 0x374 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_MOSI__CSPI_SS1                         0x0c8 0x374 0x6ec 0x2 0x1
+#define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1                       0x0c8 0x374 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_MOSI__UART3_CTS                                0x0c8 0x374 0x000 0x4 0x0
+#define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE_7                      0x0c8 0x374 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_MOSI__EIM_WEIM_D_9                     0x0c8 0x374 0x810 0x7 0x0
+#define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO                      0x0cc 0x378 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_MISO__GPIO4_14                         0x0cc 0x378 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_MISO__CSPI_SS2                         0x0cc 0x378 0x6f0 0x2 0x1
+#define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2                       0x0cc 0x378 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_MISO__UART4_RTS                                0x0cc 0x378 0x7d8 0x4 0x0
+#define MX50_PAD_ECSPI1_MISO__EPDC_SDCE_8                      0x0cc 0x378 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_MISO__EIM_WEIM_D_10                    0x0cc 0x378 0x814 0x7 0x0
+#define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0                                0x0d0 0x37c 0x000 0x0 0x0
+#define MX50_PAD_ECSPI1_SS0__GPIO4_15                          0x0d0 0x37c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI1_SS0__CSPI_SS3                          0x0d0 0x37c 0x6f4 0x2 0x1
+#define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3                                0x0d0 0x37c 0x000 0x3 0x0
+#define MX50_PAD_ECSPI1_SS0__UART4_CTS                         0x0d0 0x37c 0x000 0x4 0x0
+#define MX50_PAD_ECSPI1_SS0__EPDC_SDCE_9                       0x0d0 0x37c 0x000 0x5 0x0
+#define MX50_PAD_ECSPI1_SS0__EIM_WEIM_D_11                     0x0d0 0x37c 0x818 0x7 0x0
+#define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK                      0x0d4 0x380 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_SCLK__GPIO4_16                         0x0d4 0x380 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR_RWN                    0x0d4 0x380 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY                       0x0d4 0x380 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_SCLK__UART5_RTS                                0x0d4 0x380 0x7e0 0x4 0x0
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK                    0x0d4 0x380 0x000 0x5 0x0
+#define MX50_PAD_ECSPI2_SCLK__EIM_NANDF_CEN_4                  0x0d4 0x380 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_SCLK__EIM_WEIM_D_8                     0x0d4 0x380 0x80c 0x7 0x1
+#define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI                      0x0d8 0x384 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_MOSI__GPIO4_17                         0x0d8 0x384 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_RE_E                      0x0d8 0x384 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1                       0x0d8 0x384 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_MOSI__UART5_CTS                                0x0d8 0x384 0x7e0 0x4 0x1
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_ENABLE                    0x0d8 0x384 0x000 0x5 0x0
+#define MX50_PAD_ECSPI2_MOSI__EIM_NANDF_CEN_5                  0x0d8 0x384 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_MOSI__EIM_WEIM_D_9                     0x0d8 0x384 0x810 0x7 0x1
+#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO                      0x0dc 0x388 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_MISO__GPIO4_18                         0x0dc 0x388 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_RS                                0x0dc 0x388 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2                       0x0dc 0x388 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_MISO__UART5_TXD_MUX                    0x0dc 0x388 0x7e4 0x4 0x4
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC                     0x0dc 0x388 0x73c 0x5 0x0
+#define MX50_PAD_ECSPI2_MISO__EIM_NANDF_CEN_6                  0x0dc 0x388 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_MISO__EIM_WEIM_D_10                    0x0dc 0x388 0x814 0x7 0x1
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0                                0x0e0 0x38c 0x000 0x0 0x0
+#define MX50_PAD_ECSPI2_SS0__GPIO4_19                          0x0e0 0x38c 0x000 0x1 0x0
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_CS                         0x0e0 0x38c 0x000 0x2 0x0
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS3                                0x0e0 0x38c 0x000 0x3 0x0
+#define MX50_PAD_ECSPI2_SS0__UART5_RXD_MUX                     0x0e0 0x38c 0x7e4 0x4 0x5
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC                      0x0e0 0x38c 0x6f8 0x5 0x0
+#define MX50_PAD_ECSPI2_SS0__EIM_NANDF_CEN_7                   0x0e0 0x38c 0x000 0x6 0x0
+#define MX50_PAD_ECSPI2_SS0__EIM_WEIM_D_11                     0x0e0 0x38c 0x818 0x7 0x1
+#define MX50_PAD_SD1_CLK__ESDHC1_CLK                           0x0e4 0x390 0x000 0x0 0x0
+#define MX50_PAD_SD1_CLK__GPIO5_0                              0x0e4 0x390 0x000 0x1 0x0
+#define MX50_PAD_SD1_CLK__CCM_CLKO                             0x0e4 0x390 0x000 0x7 0x0
+#define MX50_PAD_SD1_CMD__ESDHC1_CMD                           0x0e8 0x394 0x000 0x0 0x0
+#define MX50_PAD_SD1_CMD__GPIO5_1                              0x0e8 0x394 0x000 0x1 0x0
+#define MX50_PAD_SD1_CMD__CCM_CLKO2                            0x0e8 0x394 0x000 0x7 0x0
+#define MX50_PAD_SD1_D0__ESDHC1_DAT0                           0x0ec 0x398 0x000 0x0 0x0
+#define MX50_PAD_SD1_D0__GPIO5_2                               0x0ec 0x398 0x000 0x1 0x0
+#define MX50_PAD_SD1_D0__CCM_PLL1_BYP                          0x0ec 0x398 0x6dc 0x7 0x0
+#define MX50_PAD_SD1_D1__ESDHC1_DAT1                           0x0f0 0x39c 0x000 0x0 0x0
+#define MX50_PAD_SD1_D1__GPIO5_3                               0x0f0 0x39c 0x000 0x1 0x0
+#define MX50_PAD_SD1_D1__CCM_PLL2_BYP                          0x0f0 0x39c 0x000 0x7 0x0
+#define MX50_PAD_SD1_D2__ESDHC1_DAT2                           0x0f4 0x3a0 0x000 0x0 0x0
+#define MX50_PAD_SD1_D2__GPIO5_4                               0x0f4 0x3a0 0x000 0x1 0x0
+#define MX50_PAD_SD1_D2__CCM_PLL3_BYP                          0x0f4 0x3a0 0x6e4 0x7 0x0
+#define MX50_PAD_SD1_D3__ESDHC1_DAT3                           0x0f8 0x3a4 0x000 0x0 0x0
+#define MX50_PAD_SD1_D3__GPIO5_5                               0x0f8 0x3a4 0x000 0x1 0x0
+#define MX50_PAD_SD2_CLK__ESDHC2_CLK                           0x0fc 0x3a8 0x000 0x0 0x0
+#define MX50_PAD_SD2_CLK__GPIO5_6                              0x0fc 0x3a8 0x000 0x1 0x0
+#define MX50_PAD_SD2_CLK__MSHC_SCLK                            0x0fc 0x3a8 0x000 0x2 0x0
+#define MX50_PAD_SD2_CMD__ESDHC2_CMD                           0x100 0x3ac 0x000 0x0 0x0
+#define MX50_PAD_SD2_CMD__GPIO5_7                              0x100 0x3ac 0x000 0x1 0x0
+#define MX50_PAD_SD2_CMD__MSHC_BS                              0x100 0x3ac 0x000 0x2 0x0
+#define MX50_PAD_SD2_D0__ESDHC2_DAT0                           0x104 0x3b0 0x000 0x0 0x0
+#define MX50_PAD_SD2_D0__GPIO5_8                               0x104 0x3b0 0x000 0x1 0x0
+#define MX50_PAD_SD2_D0__MSHC_DATA_0                           0x104 0x3b0 0x000 0x2 0x0
+#define MX50_PAD_SD2_D0__KPP_COL_4                             0x104 0x3b0 0x790 0x3 0x0
+#define MX50_PAD_SD2_D1__ESDHC2_DAT1                           0x108 0x3b4 0x000 0x0 0x0
+#define MX50_PAD_SD2_D1__GPIO5_9                               0x108 0x3b4 0x000 0x1 0x0
+#define MX50_PAD_SD2_D1__MSHC_DATA_1                           0x108 0x3b4 0x000 0x2 0x0
+#define MX50_PAD_SD2_D1__KPP_ROW_4                             0x108 0x3b4 0x7a0 0x3 0x0
+#define MX50_PAD_SD2_D2__ESDHC2_DAT2                           0x10c 0x3b8 0x000 0x0 0x0
+#define MX50_PAD_SD2_D2__GPIO5_10                              0x10c 0x3b8 0x000 0x1 0x0
+#define MX50_PAD_SD2_D2__MSHC_DATA_2                           0x10c 0x3b8 0x000 0x2 0x0
+#define MX50_PAD_SD2_D2__KPP_COL_5                             0x10c 0x3b8 0x794 0x3 0x0
+#define MX50_PAD_SD2_D3__ESDHC2_DAT3                           0x110 0x3bc 0x000 0x0 0x0
+#define MX50_PAD_SD2_D3__GPIO5_11                              0x110 0x3bc 0x000 0x1 0x0
+#define MX50_PAD_SD2_D3__MSHC_DATA_3                           0x110 0x3bc 0x000 0x2 0x0
+#define MX50_PAD_SD2_D3__KPP_ROW_5                             0x110 0x3bc 0x7a4 0x3 0x0
+#define MX50_PAD_SD2_D4__ESDHC2_DAT4                           0x114 0x3c0 0x000 0x0 0x0
+#define MX50_PAD_SD2_D4__GPIO5_12                              0x114 0x3c0 0x000 0x1 0x0
+#define MX50_PAD_SD2_D4__AUDMUX_AUD4_RXFS                      0x114 0x3c0 0x6d0 0x2 0x0
+#define MX50_PAD_SD2_D4__KPP_COL_6                             0x114 0x3c0 0x798 0x3 0x0
+#define MX50_PAD_SD2_D4__EIM_WEIM_D_0                          0x114 0x3c0 0x7ec 0x4 0x0
+#define MX50_PAD_SD2_D4__CCM_CCM_OUT_0                         0x114 0x3c0 0x000 0x7 0x0
+#define MX50_PAD_SD2_D5__ESDHC2_DAT5                           0x118 0x3c4 0x000 0x0 0x0
+#define MX50_PAD_SD2_D5__GPIO5_13                              0x118 0x3c4 0x000 0x1 0x0
+#define MX50_PAD_SD2_D5__AUDMUX_AUD4_RXC                       0x118 0x3c4 0x6cc 0x2 0x0
+#define MX50_PAD_SD2_D5__KPP_ROW_6                             0x118 0x3c4 0x7a8 0x3 0x0
+#define MX50_PAD_SD2_D5__EIM_WEIM_D_1                          0x118 0x3c4 0x7f0 0x4 0x0
+#define MX50_PAD_SD2_D5__CCM_CCM_OUT_1                         0x118 0x3c4 0x000 0x7 0x0
+#define MX50_PAD_SD2_D6__ESDHC2_DAT6                           0x11c 0x3c8 0x000 0x0 0x0
+#define MX50_PAD_SD2_D6__GPIO5_14                              0x11c 0x3c8 0x000 0x1 0x0
+#define MX50_PAD_SD2_D6__AUDMUX_AUD4_RXD                       0x11c 0x3c8 0x6c4 0x2 0x0
+#define MX50_PAD_SD2_D6__KPP_COL_7                             0x11c 0x3c8 0x79c 0x3 0x0
+#define MX50_PAD_SD2_D6__EIM_WEIM_D_2                          0x11c 0x3c8 0x7f4 0x4 0x0
+#define MX50_PAD_SD2_D6__CCM_CCM_OUT_2                         0x11c 0x3c8 0x000 0x7 0x0
+#define MX50_PAD_SD2_D7__ESDHC2_DAT7                           0x120 0x3cc 0x000 0x0 0x0
+#define MX50_PAD_SD2_D7__GPIO5_15                              0x120 0x3cc 0x000 0x1 0x0
+#define MX50_PAD_SD2_D7__AUDMUX_AUD4_TXFS                      0x120 0x3cc 0x6d8 0x2 0x0
+#define MX50_PAD_SD2_D7__KPP_ROW_7                             0x120 0x3cc 0x7ac 0x3 0x0
+#define MX50_PAD_SD2_D7__EIM_WEIM_D_3                          0x120 0x3cc 0x7f8 0x4 0x0
+#define MX50_PAD_SD2_D7__CCM_STOP                              0x120 0x3cc 0x000 0x7 0x0
+#define MX50_PAD_SD2_WP__ESDHC2_WP                             0x124 0x3d0 0x744 0x0 0x1
+#define MX50_PAD_SD2_WP__GPIO5_16                              0x124 0x3d0 0x000 0x1 0x0
+#define MX50_PAD_SD2_WP__AUDMUX_AUD4_TXD                       0x124 0x3d0 0x6c8 0x2 0x0
+#define MX50_PAD_SD2_WP__EIM_WEIM_D_4                          0x124 0x3d0 0x7fc 0x4 0x0
+#define MX50_PAD_SD2_WP__CCM_WAIT                              0x124 0x3d0 0x000 0x7 0x0
+#define MX50_PAD_SD2_CD__ESDHC2_CD                             0x128 0x3d4 0x740 0x0 0x1
+#define MX50_PAD_SD2_CD__GPIO5_17                              0x128 0x3d4 0x000 0x1 0x0
+#define MX50_PAD_SD2_CD__AUDMUX_AUD4_TXC                       0x128 0x3d4 0x6d4 0x2 0x0
+#define MX50_PAD_SD2_CD__EIM_WEIM_D_5                          0x128 0x3d4 0x800 0x4 0x0
+#define MX50_PAD_SD2_CD__CCM_REF_EN_B                          0x128 0x3d4 0x000 0x7 0x0
+#define MX50_PAD_DISP_D0__ELCDIF_DAT_0                         0x12c 0x40c 0x6fc 0x0 0x0
+#define MX50_PAD_DISP_D0__GPIO2_0                              0x12c 0x40c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D0__FEC_TX_CLK                           0x12c 0x40c 0x78c 0x2 0x0
+#define MX50_PAD_DISP_D0__EIM_WEIM_A_16                                0x12c 0x40c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D0__SDMA_DEBUG_PC_0                      0x12c 0x40c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D0__USBPHY1_VSTATUS_0                    0x12c 0x40c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D1__ELCDIF_DAT_1                         0x130 0x410 0x700 0x0 0x0
+#define MX50_PAD_DISP_D1__GPIO2_1                              0x130 0x410 0x000 0x1 0x0
+#define MX50_PAD_DISP_D1__FEC_RX_ERR                           0x130 0x410 0x788 0x2 0x0
+#define MX50_PAD_DISP_D1__EIM_WEIM_A_17                                0x130 0x410 0x000 0x3 0x0
+#define MX50_PAD_DISP_D1__SDMA_DEBUG_PC_1                      0x130 0x410 0x000 0x6 0x0
+#define MX50_PAD_DISP_D1__USBPHY1_VSTATUS_1                    0x130 0x410 0x000 0x7 0x0
+#define MX50_PAD_DISP_D2__ELCDIF_DAT_2                         0x134 0x414 0x704 0x0 0x0
+#define MX50_PAD_DISP_D2__GPIO2_2                              0x134 0x414 0x000 0x1 0x0
+#define MX50_PAD_DISP_D2__FEC_RX_DV                            0x134 0x414 0x784 0x2 0x0
+#define MX50_PAD_DISP_D2__EIM_WEIM_A_18                                0x134 0x414 0x000 0x3 0x0
+#define MX50_PAD_DISP_D2__SDMA_DEBUG_PC_2                      0x134 0x414 0x000 0x6 0x0
+#define MX50_PAD_DISP_D2__USBPHY1_VSTATUS_2                    0x134 0x414 0x000 0x7 0x0
+#define MX50_PAD_DISP_D3__ELCDIF_DAT_3                         0x138 0x418 0x708 0x0 0x0
+#define MX50_PAD_DISP_D3__GPIO2_3                              0x138 0x418 0x000 0x1 0x0
+#define MX50_PAD_DISP_D3__FEC_RDATA_1                          0x138 0x418 0x77c 0x2 0x0
+#define MX50_PAD_DISP_D3__EIM_WEIM_A_19                                0x138 0x418 0x000 0x3 0x0
+#define MX50_PAD_DISP_D3__FEC_COL                              0x138 0x418 0x770 0x4 0x1
+#define MX50_PAD_DISP_D3__SDMA_DEBUG_PC_3                      0x138 0x418 0x000 0x6 0x0
+#define MX50_PAD_DISP_D3__USBPHY1_VSTATUS_3                    0x138 0x418 0x000 0x7 0x0
+#define MX50_PAD_DISP_D4__ELCDIF_DAT_4                         0x13c 0x41c 0x70c 0x0 0x0
+#define MX50_PAD_DISP_D4__GPIO2_4                              0x13c 0x41c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D4__FEC_RDATA_0                          0x13c 0x41c 0x778 0x2 0x0
+#define MX50_PAD_DISP_D4__EIM_WEIM_A_20                                0x13c 0x41c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D4__SDMA_DEBUG_PC_4                      0x13c 0x41c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D4__USBPHY1_VSTATUS_4                    0x13c 0x41c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D5__ELCDIF_DAT_5                         0x140 0x420 0x710 0x0 0x0
+#define MX50_PAD_DISP_D5__GPIO2_5                              0x140 0x420 0x000 0x1 0x0
+#define MX50_PAD_DISP_D5__FEC_TX_EN                            0x140 0x420 0x000 0x2 0x0
+#define MX50_PAD_DISP_D5__EIM_WEIM_A_21                                0x140 0x420 0x000 0x3 0x0
+#define MX50_PAD_DISP_D5__SDMA_DEBUG_PC_5                      0x140 0x420 0x000 0x6 0x0
+#define MX50_PAD_DISP_D5__USBPHY1_VSTATUS_5                    0x140 0x420 0x000 0x7 0x0
+#define MX50_PAD_DISP_D6__ELCDIF_DAT_6                         0x144 0x424 0x714 0x0 0x0
+#define MX50_PAD_DISP_D6__GPIO2_6                              0x144 0x424 0x000 0x1 0x0
+#define MX50_PAD_DISP_D6__FEC_TDATA_1                          0x144 0x424 0x000 0x2 0x0
+#define MX50_PAD_DISP_D6__EIM_WEIM_A_22                                0x144 0x424 0x000 0x3 0x0
+#define MX50_PAD_DISP_D6__FEC_RX_CLK                           0x144 0x424 0x780 0x4 0x1
+#define MX50_PAD_DISP_D6__SDMA_DEBUG_PC_6                      0x144 0x424 0x000 0x6 0x0
+#define MX50_PAD_DISP_D6__USBPHY1_VSTATUS_6                    0x144 0x424 0x000 0x7 0x0
+#define MX50_PAD_DISP_D7__ELCDIF_DAT_7                         0x148 0x428 0x718 0x0 0x0
+#define MX50_PAD_DISP_D7__GPIO2_7                              0x148 0x428 0x000 0x1 0x0
+#define MX50_PAD_DISP_D7__FEC_TDATA_0                          0x148 0x428 0x000 0x2 0x0
+#define MX50_PAD_DISP_D7__EIM_WEIM_A_23                                0x148 0x428 0x000 0x3 0x0
+#define MX50_PAD_DISP_D7__SDMA_DEBUG_PC_7                      0x148 0x428 0x000 0x6 0x0
+#define MX50_PAD_DISP_D7__USBPHY1_VSTATUS_7                    0x148 0x428 0x000 0x7 0x0
+#define MX50_PAD_DISP_WR__ELCDIF_WR_RWN                                0x14c 0x42c 0x000 0x0 0x0
+#define MX50_PAD_DISP_WR__GPIO2_16                             0x14c 0x42c 0x000 0x1 0x0
+#define MX50_PAD_DISP_WR__ELCDIF_DOTCLK                                0x14c 0x42c 0x000 0x2 0x0
+#define MX50_PAD_DISP_WR__EIM_WEIM_A_24                                0x14c 0x42c 0x000 0x3 0x0
+#define MX50_PAD_DISP_WR__SDMA_DEBUG_PC_8                      0x14c 0x42c 0x000 0x6 0x0
+#define MX50_PAD_DISP_WR__USBPHY1_AVALID                       0x14c 0x42c 0x000 0x7 0x0
+#define MX50_PAD_DISP_RD__ELCDIF_RD_E                          0x150 0x430 0x000 0x0 0x0
+#define MX50_PAD_DISP_RD__GPIO2_19                             0x150 0x430 0x000 0x1 0x0
+#define MX50_PAD_DISP_RD__ELCDIF_ENABLE                                0x150 0x430 0x000 0x2 0x0
+#define MX50_PAD_DISP_RD__EIM_WEIM_A_25                                0x150 0x430 0x000 0x3 0x0
+#define MX50_PAD_DISP_RD__SDMA_DEBUG_PC_9                      0x150 0x430 0x000 0x6 0x0
+#define MX50_PAD_DISP_RD__USBPHY1_BVALID                       0x150 0x430 0x000 0x7 0x0
+#define MX50_PAD_DISP_RS__ELCDIF_RS                            0x154 0x434 0x000 0x0 0x0
+#define MX50_PAD_DISP_RS__GPIO2_17                             0x154 0x434 0x000 0x1 0x0
+#define MX50_PAD_DISP_RS__ELCDIF_VSYNC                         0x154 0x434 0x73c 0x2 0x1
+#define MX50_PAD_DISP_RS__EIM_WEIM_A_26                                0x154 0x434 0x000 0x3 0x0
+#define MX50_PAD_DISP_RS__SDMA_DEBUG_PC_10                     0x154 0x434 0x000 0x6 0x0
+#define MX50_PAD_DISP_RS__USBPHY1_ENDSESSION                   0x154 0x434 0x000 0x7 0x0
+#define MX50_PAD_DISP_CS__ELCDIF_CS                            0x158 0x438 0x000 0x0 0x0
+#define MX50_PAD_DISP_CS__GPIO2_21                             0x158 0x438 0x000 0x1 0x0
+#define MX50_PAD_DISP_CS__ELCDIF_HSYNC                         0x158 0x438 0x6f8 0x2 0x1
+#define MX50_PAD_DISP_CS__EIM_WEIM_A_27                                0x158 0x438 0x000 0x3 0x0
+#define MX50_PAD_DISP_CS__EIM_WEIM_CS_3                                0x158 0x438 0x000 0x4 0x0
+#define MX50_PAD_DISP_CS__SDMA_DEBUG_PC_11                     0x158 0x438 0x000 0x6 0x0
+#define MX50_PAD_DISP_CS__USBPHY1_IDDIG                                0x158 0x438 0x000 0x7 0x0
+#define MX50_PAD_DISP_BUSY__ELCDIF_BUSY                                0x15c 0x43c 0x6f8 0x0 0x2
+#define MX50_PAD_DISP_BUSY__GPIO2_18                           0x15c 0x43c 0x000 0x1 0x0
+#define MX50_PAD_DISP_BUSY__EIM_WEIM_CS_3                      0x15c 0x43c 0x000 0x4 0x0
+#define MX50_PAD_DISP_BUSY__SDMA_DEBUG_PC_12                   0x15c 0x43c 0x000 0x6 0x0
+#define MX50_PAD_DISP_BUSY__USBPHY2_HOSTDISCONNECT             0x15c 0x43c 0x000 0x7 0x0
+#define MX50_PAD_DISP_RESET__ELCDIF_RESET                      0x160 0x440 0x000 0x0 0x0
+#define MX50_PAD_DISP_RESET__GPIO2_20                          0x160 0x440 0x000 0x1 0x0
+#define MX50_PAD_DISP_RESET__EIM_WEIM_CS_3                     0x160 0x440 0x000 0x4 0x0
+#define MX50_PAD_DISP_RESET__SDMA_DEBUG_PC_13                  0x160 0x440 0x000 0x6 0x0
+#define MX50_PAD_DISP_RESET__USBPHY2_BISTOK                    0x160 0x440 0x000 0x7 0x0
+#define MX50_PAD_SD3_CMD__ESDHC3_CMD                           0x164 0x444 0x000 0x0 0x0
+#define MX50_PAD_SD3_CMD__GPIO5_18                             0x164 0x444 0x000 0x1 0x0
+#define MX50_PAD_SD3_CMD__EIM_NANDF_WRN                                0x164 0x444 0x000 0x2 0x0
+#define MX50_PAD_SD3_CMD__SSP_CMD                              0x164 0x444 0x000 0x3 0x0
+#define MX50_PAD_SD3_CLK__ESDHC3_CLK                           0x168 0x448 0x000 0x0 0x0
+#define MX50_PAD_SD3_CLK__GPIO5_19                             0x168 0x448 0x000 0x1 0x0
+#define MX50_PAD_SD3_CLK__EIM_NANDF_RDN                                0x168 0x448 0x000 0x2 0x0
+#define MX50_PAD_SD3_CLK__SSP_CLK                              0x168 0x448 0x000 0x3 0x0
+#define MX50_PAD_SD3_D0__ESDHC3_DAT0                           0x16c 0x44c 0x000 0x0 0x0
+#define MX50_PAD_SD3_D0__GPIO5_20                              0x16c 0x44c 0x000 0x1 0x0
+#define MX50_PAD_SD3_D0__EIM_NANDF_D_4                         0x16c 0x44c 0x000 0x2 0x0
+#define MX50_PAD_SD3_D0__SSP_D0                                        0x16c 0x44c 0x000 0x3 0x0
+#define MX50_PAD_SD3_D0__CCM_PLL1_BYP                          0x16c 0x44c 0x6dc 0x7 0x1
+#define MX50_PAD_SD3_D1__ESDHC3_DAT1                           0x170 0x450 0x000 0x0 0x0
+#define MX50_PAD_SD3_D1__GPIO5_21                              0x170 0x450 0x000 0x1 0x0
+#define MX50_PAD_SD3_D1__EIM_NANDF_D_5                         0x170 0x450 0x000 0x2 0x0
+#define MX50_PAD_SD3_D1__SSP_D1                                        0x170 0x450 0x000 0x3 0x0
+#define MX50_PAD_SD3_D1__CCM_PLL2_BYP                          0x170 0x450 0x000 0x7 0x0
+#define MX50_PAD_SD3_D2__ESDHC3_DAT2                           0x174 0x454 0x000 0x0 0x0
+#define MX50_PAD_SD3_D2__GPIO5_22                              0x174 0x454 0x000 0x1 0x0
+#define MX50_PAD_SD3_D2__EIM_NANDF_D_6                         0x174 0x454 0x000 0x2 0x0
+#define MX50_PAD_SD3_D2__SSP_D2                                        0x174 0x454 0x000 0x3 0x0
+#define MX50_PAD_SD3_D2__CCM_PLL3_BYP                          0x174 0x454 0x6e4 0x7 0x1
+#define MX50_PAD_SD3_D3__ESDHC3_DAT3                           0x178 0x458 0x000 0x0 0x0
+#define MX50_PAD_SD3_D3__GPIO5_23                              0x178 0x458 0x000 0x1 0x0
+#define MX50_PAD_SD3_D3__EIM_NANDF_D_7                         0x178 0x458 0x000 0x2 0x0
+#define MX50_PAD_SD3_D3__SSP_D3                                        0x178 0x458 0x000 0x3 0x0
+#define MX50_PAD_SD3_D4__ESDHC3_DAT4                           0x17c 0x45c 0x000 0x0 0x0
+#define MX50_PAD_SD3_D4__GPIO5_24                              0x17c 0x45c 0x000 0x1 0x0
+#define MX50_PAD_SD3_D4__EIM_NANDF_D_0                         0x17c 0x45c 0x000 0x2 0x0
+#define MX50_PAD_SD3_D4__SSP_D4                                        0x17c 0x45c 0x000 0x3 0x0
+#define MX50_PAD_SD3_D5__ESDHC3_DAT5                           0x180 0x460 0x000 0x0 0x0
+#define MX50_PAD_SD3_D5__GPIO5_25                              0x180 0x460 0x000 0x1 0x0
+#define MX50_PAD_SD3_D5__EIM_NANDF_D_1                         0x180 0x460 0x000 0x2 0x0
+#define MX50_PAD_SD3_D5__SSP_D5                                        0x180 0x460 0x000 0x3 0x0
+#define MX50_PAD_SD3_D6__ESDHC3_DAT6                           0x184 0x464 0x000 0x0 0x0
+#define MX50_PAD_SD3_D6__GPIO5_26                              0x184 0x464 0x000 0x1 0x0
+#define MX50_PAD_SD3_D6__EIM_NANDF_D_2                         0x184 0x464 0x000 0x2 0x0
+#define MX50_PAD_SD3_D6__SSP_D6                                        0x184 0x464 0x000 0x3 0x0
+#define MX50_PAD_SD3_D7__ESDHC3_DAT7                           0x188 0x468 0x000 0x0 0x0
+#define MX50_PAD_SD3_D7__GPIO5_27                              0x188 0x468 0x000 0x1 0x0
+#define MX50_PAD_SD3_D7__EIM_NANDF_D_3                         0x188 0x468 0x000 0x2 0x0
+#define MX50_PAD_SD3_D7__SSP_D7                                        0x188 0x468 0x000 0x3 0x0
+#define MX50_PAD_SD3_WP__ESDHC3_WP                             0x18c 0x46C 0x000 0x0 0x0
+#define MX50_PAD_SD3_WP__GPIO5_28                              0x18c 0x46C 0x000 0x1 0x0
+#define MX50_PAD_SD3_WP__EIM_NANDF_RESETN                      0x18c 0x46C 0x000 0x2 0x0
+#define MX50_PAD_SD3_WP__SSP_CD                                        0x18c 0x46C 0x000 0x3 0x0
+#define MX50_PAD_SD3_WP__ESDHC4_LCTL                           0x18c 0x46C 0x000 0x4 0x0
+#define MX50_PAD_SD3_WP__EIM_WEIM_CS_3                         0x18c 0x46C 0x000 0x5 0x0
+#define MX50_PAD_DISP_D8__ELCDIF_DAT_8                         0x190 0x470 0x71c 0x0 0x0
+#define MX50_PAD_DISP_D8__GPIO2_8                              0x190 0x470 0x000 0x1 0x0
+#define MX50_PAD_DISP_D8__EIM_NANDF_CLE                                0x190 0x470 0x000 0x2 0x0
+#define MX50_PAD_DISP_D8__ESDHC1_LCTL                          0x190 0x470 0x000 0x3 0x0
+#define MX50_PAD_DISP_D8__ESDHC4_CMD                           0x190 0x470 0x74c 0x4 0x2
+#define MX50_PAD_DISP_D8__KPP_COL_4                            0x190 0x470 0x790 0x5 0x1
+#define MX50_PAD_DISP_D8__FEC_TX_CLK                           0x190 0x470 0x78c 0x6 0x1
+#define MX50_PAD_DISP_D8__USBPHY1_DATAOUT_0                    0x190 0x470 0x000 0x7 0x0
+#define MX50_PAD_DISP_D9__ELCDIF_DAT_9                         0x194 0x474 0x720 0x0 0x0
+#define MX50_PAD_DISP_D9__GPIO2_9                              0x194 0x474 0x000 0x1 0x0
+#define MX50_PAD_DISP_D9__EIM_NANDF_ALE                                0x194 0x474 0x000 0x2 0x0
+#define MX50_PAD_DISP_D9__ESDHC2_LCTL                          0x194 0x474 0x000 0x3 0x0
+#define MX50_PAD_DISP_D9__ESDHC4_CLK                           0x194 0x474 0x748 0x4 0x2
+#define MX50_PAD_DISP_D9__KPP_ROW_4                            0x194 0x474 0x7a0 0x5 0x1
+#define MX50_PAD_DISP_D9__FEC_RX_ER                            0x194 0x474 0x788 0x6 0x1
+#define MX50_PAD_DISP_D9__USBPHY1_DATAOUT_1                    0x194 0x474 0x000 0x7 0x0
+#define MX50_PAD_DISP_D10__ELCDIF_DAT_10                       0x198 0x478 0x724 0x0 0x0
+#define MX50_PAD_DISP_D10__GPIO2_10                            0x198 0x478 0x000 0x1 0x0
+#define MX50_PAD_DISP_D10__EIM_NANDF_CEN_0                     0x198 0x478 0x000 0x2 0x0
+#define MX50_PAD_DISP_D10__ESDHC3_LCTL                         0x198 0x478 0x000 0x3 0x0
+#define MX50_PAD_DISP_D10__ESDHC4_DAT0                         0x198 0x478 0x000 0x4 0x0
+#define MX50_PAD_DISP_D10__KPP_COL_5                           0x198 0x478 0x794 0x5 0x1
+#define MX50_PAD_DISP_D10__FEC_RX_DV                           0x198 0x478 0x784 0x6 0x1
+#define MX50_PAD_DISP_D10__USBPHY1_DATAOUT_2                   0x198 0x478 0x000 0x7 0x0
+#define MX50_PAD_DISP_D11__ELCDIF_DAT_11                       0x19c 0x47c 0x728 0x0 0x0
+#define MX50_PAD_DISP_D11__GPIO2_11                            0x19c 0x47c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D11__EIM_NANDF_CEN_1                     0x19c 0x47c 0x000 0x2 0x0
+#define MX50_PAD_DISP_D11__ESDHC4_DAT1                         0x19c 0x47c 0x754 0x4 0x1
+#define MX50_PAD_DISP_D11__KPP_ROW_5                           0x19c 0x47c 0x7a4 0x5 0x1
+#define MX50_PAD_DISP_D11__FEC_RDATA_1                         0x19c 0x47c 0x77c 0x6 0x1
+#define MX50_PAD_DISP_D11__USBPHY1_DATAOUT_3                   0x19c 0x47c 0x000 0x7 0x0
+#define MX50_PAD_DISP_D12__ELCDIF_DAT_12                       0x1a0 0x480 0x72c 0x0 0x0
+#define MX50_PAD_DISP_D12__GPIO2_12                            0x1a0 0x480 0x000 0x1 0x0
+#define MX50_PAD_DISP_D12__EIM_NANDF_CEN_2                     0x1a0 0x480 0x000 0x2 0x0
+#define MX50_PAD_DISP_D12__ESDHC1_CD                           0x1a0 0x480 0x000 0x3 0x0
+#define MX50_PAD_DISP_D12__ESDHC4_DAT2                         0x1a0 0x480 0x758 0x4 0x1
+#define MX50_PAD_DISP_D12__KPP_COL_6                           0x1a0 0x480 0x798 0x5 0x1
+#define MX50_PAD_DISP_D12__FEC_RDATA_0                         0x1a0 0x480 0x778 0x6 0x1
+#define MX50_PAD_DISP_D12__USBPHY1_DATAOUT_4                   0x1a0 0x480 0x000 0x7 0x0
+#define MX50_PAD_DISP_D13__ELCDIF_DAT_13                       0x1a4 0x484 0x730 0x0 0x0
+#define MX50_PAD_DISP_D13__GPIO2_13                            0x1a4 0x484 0x000 0x1 0x0
+#define MX50_PAD_DISP_D13__EIM_NANDF_CEN_3                     0x1a4 0x484 0x000 0x2 0x0
+#define MX50_PAD_DISP_D13__ESDHC3_CD                           0x1a4 0x484 0x000 0x3 0x0
+#define MX50_PAD_DISP_D13__ESDHC4_DAT3                         0x1a4 0x484 0x75c 0x4 0x1
+#define MX50_PAD_DISP_D13__KPP_ROW_6                           0x1a4 0x484 0x7a8 0x5 0x1
+#define MX50_PAD_DISP_D13__FEC_TX_EN                           0x1a4 0x484 0x000 0x6 0x0
+#define MX50_PAD_DISP_D13__USBPHY1_DATAOUT_5                   0x1a4 0x484 0x000 0x7 0x0
+#define MX50_PAD_DISP_D14__ELCDIF_DAT_14                       0x1a8 0x488 0x734 0x0 0x0
+#define MX50_PAD_DISP_D14__GPIO2_14                            0x1a8 0x488 0x000 0x1 0x0
+#define MX50_PAD_DISP_D14__EIM_NANDF_READY0                    0x1a8 0x488 0x7b4 0x2 0x1
+#define MX50_PAD_DISP_D14__ESDHC1_WP                           0x1a8 0x488 0x000 0x3 0x0
+#define MX50_PAD_DISP_D14__ESDHC4_WP                           0x1a8 0x488 0x000 0x4 0x0
+#define MX50_PAD_DISP_D14__KPP_COL_7                           0x1a8 0x488 0x79c 0x5 0x1
+#define MX50_PAD_DISP_D14__FEC_TDATA_1                         0x1a8 0x488 0x000 0x6 0x0
+#define MX50_PAD_DISP_D14__USBPHY1_DATAOUT_6                   0x1a8 0x488 0x000 0x7 0x0
+#define MX50_PAD_DISP_D15__ELCDIF_DAT_15                       0x1ac 0x48c 0x738 0x0 0x0
+#define MX50_PAD_DISP_D15__GPIO2_15                            0x1ac 0x48c 0x000 0x1 0x0
+#define MX50_PAD_DISP_D15__EIM_NANDF_DQS                       0x1ac 0x48c 0x7b0 0x2 0x1
+#define MX50_PAD_DISP_D15__ESDHC3_RST                          0x1ac 0x48c 0x000 0x3 0x0
+#define MX50_PAD_DISP_D15__ESDHC4_CD                           0x1ac 0x48c 0x000 0x4 0x0
+#define MX50_PAD_DISP_D15__KPP_ROW_7                           0x1ac 0x48c 0x7ac 0x5 0x1
+#define MX50_PAD_DISP_D15__FEC_TDATA_0                         0x1ac 0x48c 0x000 0x6 0x0
+#define MX50_PAD_DISP_D15__USBPHY1_DATAOUT_7                   0x1ac 0x48c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D0__EPDC_SDDO_0                          0x1b0 0x54c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D0__GPIO3_0                              0x1b0 0x54c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D0__EIM_WEIM_D_0                         0x1b0 0x54c 0x7ec 0x2 0x1
+#define MX50_PAD_EPDC_D0__ELCDIF_RS                            0x1b0 0x54c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D0__ELCDIF_DOTCLK                                0x1b0 0x54c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D0__SDMA_DEBUG_EVT_CHN_LINES_0           0x1b0 0x54c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D0__USBPHY2_DATAOUT_0                    0x1b0 0x54c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D1__EPDC_SDDO_1                          0x1b4 0x550 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D1__GPIO3_1                              0x1b4 0x550 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D1__EIM_WEIM_D_1                         0x1b4 0x550 0x7f0 0x2 0x1
+#define MX50_PAD_EPDC_D1__ELCDIF_CS                            0x1b4 0x550 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D1__ELCDIF_ENABLE                                0x1b4 0x550 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D1__SDMA_DEBUG_EVT_CHN_LINES_1           0x1b4 0x550 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D1__USBPHY2_DATAOUT_1                    0x1b4 0x550 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D2__EPDC_SDDO_2                          0x1b8 0x554 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D2__GPIO3_2                              0x1b8 0x554 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D2__EIM_WEIM_D_2                         0x1b8 0x554 0x7f4 0x2 0x1
+#define MX50_PAD_EPDC_D2__ELCDIF_WR_RWN                                0x1b8 0x554 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D2__ELCDIF_VSYNC                         0x1b8 0x554 0x73c 0x4 0x2
+#define MX50_PAD_EPDC_D2__SDMA_DEBUG_EVT_CHN_LINES_2           0x1b8 0x554 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D2__USBPHY2_DATAOUT_2                    0x1b8 0x554 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D3__EPDC_SDDO_3                          0x1bc 0x558 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D3__GPIO3_3                              0x1bc 0x558 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D3__EIM_WEIM_D_3                         0x1bc 0x558 0x7f8 0x2 0x1
+#define MX50_PAD_EPDC_D3__ELCDIF_RD_E                          0x1bc 0x558 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D3__ELCDIF_HSYNC                         0x1bc 0x558 0x6f8 0x4 0x3
+#define MX50_PAD_EPDC_D3__SDMA_DEBUG_EVT_CHN_LINES_3           0x1bc 0x558 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D3__USBPHY2_DATAOUT_3                    0x1bc 0x558 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D4__EPDC_SDDO_4                          0x1c0 0x55c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D4__GPIO3_4                              0x1c0 0x55c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D4__EIM_WEIM_D_4                         0x1c0 0x55c 0x7fc 0x2 0x1
+#define MX50_PAD_EPDC_D4__SDMA_DEBUG_EVT_CHN_LINES_4           0x1c0 0x55c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D4__USBPHY2_DATAOUT_4                    0x1c0 0x55c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D5__EPDC_SDDO_5                          0x1c4 0x560 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D5__GPIO3_5                              0x1c4 0x560 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D5__EIM_WEIM_D_5                         0x1c4 0x560 0x800 0x2 0x1
+#define MX50_PAD_EPDC_D5__SDMA_DEBUG_EVT_CHN_LINES_5           0x1c4 0x560 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D5__USBPHY2_DATAOUT_5                    0x1c4 0x560 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D6__EPDC_SDDO_6                          0x1c8 0x564 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D6__GPIO3_6                              0x1c8 0x564 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D6__EIM_WEIM_D_6                         0x1c8 0x564 0x804 0x2 0x1
+#define MX50_PAD_EPDC_D6__SDMA_DEBUG_EVT_CHN_LINES_6           0x1c8 0x564 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D6__USBPHY2_DATAOUT_6                    0x1c8 0x564 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D7__EPDC_SDDO_7                          0x1cc 0x568 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D7__GPIO3_7                              0x1cc 0x568 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D7__EIM_WEIM_D_7                         0x1cc 0x568 0x808 0x2 0x1
+#define MX50_PAD_EPDC_D7__SDMA_DEBUG_EVT_CHN_LINES_7           0x1cc 0x568 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D7__USBPHY2_DATAOUT_7                    0x1cc 0x568 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D8__EPDC_SDDO_8                          0x1d0 0x56c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D8__GPIO3_8                              0x1d0 0x56c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D8__EIM_WEIM_D_8                         0x1d0 0x56c 0x80c 0x2 0x2
+#define MX50_PAD_EPDC_D8__ELCDIF_DAT_24                                0x1d0 0x56c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D8__SDMA_DEBUG_MATCHED_DMBUS             0x1d0 0x56c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D8__USBPHY2_VSTATUS_0                    0x1d0 0x56c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D9__EPDC_SDDO_9                          0x1d4 0x570 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D9__GPIO3_9                              0x1d4 0x570 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D9__EIM_WEIM_D_9                         0x1d4 0x570 0x810 0x2 0x2
+#define MX50_PAD_EPDC_D9__ELCDIF_DAT_25                                0x1d4 0x570 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D9__SDMA_DEBUG_EVENT_CHANNEL_SEL         0x1d4 0x570 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D9__USBPHY2_VSTATUS_1                    0x1d4 0x570 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D10__EPDC_SDDO_10                                0x1d8 0x574 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D10__GPIO3_10                            0x1d8 0x574 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D10__EIM_WEIM_D_10                       0x1d8 0x574 0x814 0x2 0x2
+#define MX50_PAD_EPDC_D10__ELCDIF_DAT_26                       0x1d8 0x574 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D10__SDMA_DEBUG_EVENT_CHANNEL_0          0x1d8 0x574 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D10__USBPHY2_VSTATUS_2                   0x1d8 0x574 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D11__EPDC_SDDO_11                                0x1dc 0x578 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D11__GPIO3_11                            0x1dc 0x578 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D11__EIM_WEIM_D_11                       0x1dc 0x578 0x818 0x2 0x2
+#define MX50_PAD_EPDC_D11__ELCDIF_DAT_27                       0x1dc 0x578 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D11__SDMA_DEBUG_EVENT_CHANNEL_1          0x1dc 0x578 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D11__USBPHY2_VSTATUS_3                   0x1dc 0x578 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D12__EPDC_SDDO_12                                0x1e0 0x57c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D12__GPIO3_12                            0x1e0 0x57c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D12__EIM_WEIM_D_12                       0x1e0 0x57c 0x81c 0x2 0x1
+#define MX50_PAD_EPDC_D12__ELCDIF_DAT_28                       0x1e0 0x57c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D12__SDMA_DEBUG_EVENT_CHANNEL_2          0x1e0 0x57c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D12__USBPHY2_VSTATUS_4                   0x1e0 0x57c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D13__EPDC_SDDO_13                                0x1e4 0x580 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D13__GPIO3_13                            0x1e4 0x580 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D13__EIM_WEIM_D_13                       0x1e4 0x580 0x820 0x2 0x1
+#define MX50_PAD_EPDC_D13__ELCDIF_DAT_29                       0x1e4 0x580 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D13__SDMA_DEBUG_EVENT_CHANNEL_3          0x1e4 0x580 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D13__USBPHY2_VSTATUS_5                   0x1e4 0x580 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D14__EPDC_SDDO_14                                0x1e8 0x584 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D14__GPIO3_14                            0x1e8 0x584 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D14__EIM_WEIM_D_14                       0x1e8 0x584 0x824 0x2 0x1
+#define MX50_PAD_EPDC_D14__ELCDIF_DAT_30                       0x1e8 0x584 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D14__AUDMUX_AUD6_TXD                     0x1e8 0x584 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D14__SDMA_DEBUG_EVENT_CHANNEL_4          0x1e8 0x584 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D14__USBPHY2_VSTATUS_6                   0x1e8 0x584 0x000 0x7 0x0
+#define MX50_PAD_EPDC_D15__EPDC_SDDO_15                                0x1ec 0x588 0x000 0x0 0x0
+#define MX50_PAD_EPDC_D15__GPIO3_15                            0x1ec 0x588 0x000 0x1 0x0
+#define MX50_PAD_EPDC_D15__EIM_WEIM_D_15                       0x1ec 0x588 0x828 0x2 0x1
+#define MX50_PAD_EPDC_D15__ELCDIF_DAT_31                       0x1ec 0x588 0x000 0x3 0x0
+#define MX50_PAD_EPDC_D15__AUDMUX_AUD6_TXC                     0x1ec 0x588 0x000 0x4 0x0
+#define MX50_PAD_EPDC_D15__SDMA_DEBUG_EVENT_CHANNEL_5          0x1ec 0x588 0x000 0x6 0x0
+#define MX50_PAD_EPDC_D15__USBPHY2_VSTATUS_7                   0x1ec 0x588 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK                                0x1f0 0x58c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDCLK__GPIO3_16                          0x1f0 0x58c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDCLK__EIM_WEIM_D_16                     0x1f0 0x58c 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDCLK__ELCDIF_DAT_16                     0x1f0 0x58c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDCLK__AUDMUX_AUD6_TXFS                  0x1f0 0x58c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDCLK__SDMA_DEBUG_CORE_STATE_0           0x1f0 0x58c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDCLK__USBPHY2_BISTOK                    0x1f0 0x58c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDSP__EPCD_GDSP                          0x1f4 0x590 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDSP__GPIO3_17                           0x1f4 0x590 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDSP__EIM_WEIM_D_17                      0x1f4 0x590 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDSP__ELCDIF_DAT_17                      0x1f4 0x590 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDSP__AUDMUX_AUD6_RXD                    0x1f4 0x590 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDSP__SDMA_DEBUG_CORE_STATE_1            0x1f4 0x590 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDSP__USBPHY2_BVALID                     0x1f4 0x590 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDOE__EPCD_GDOE                          0x1f8 0x594 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDOE__GPIO3_18                           0x1f8 0x594 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDOE__EIM_WEIM_D_18                      0x1f8 0x594 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDOE__ELCDIF_DAT_18                      0x1f8 0x594 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDOE__AUDMUX_AUD6_RXC                    0x1f8 0x594 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDOE__SDMA_DEBUG_CORE_STATE_2            0x1f8 0x594 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDOE__USBPHY2_ENDSESSION                 0x1f8 0x594 0x000 0x7 0x0
+#define MX50_PAD_EPDC_GDRL__EPCD_GDRL                          0x1fc 0x598 0x000 0x0 0x0
+#define MX50_PAD_EPDC_GDRL__GPIO3_19                           0x1fc 0x598 0x000 0x1 0x0
+#define MX50_PAD_EPDC_GDRL__EIM_WEIM_D_19                      0x1f8 0x598 0x000 0x2 0x0
+#define MX50_PAD_EPDC_GDRL__ELCDIF_DAT_19                      0x1fc 0x598 0x000 0x3 0x0
+#define MX50_PAD_EPDC_GDRL__AUDMUX_AUD6_RXFS                   0x1fc 0x598 0x000 0x4 0x0
+#define MX50_PAD_EPDC_GDRL__SDMA_DEBUG_CORE_STATE_3            0x1fc 0x598 0x000 0x6 0x0
+#define MX50_PAD_EPDC_GDRL__USBPHY2_IDDIG                      0x1fc 0x598 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDCLK__EPCD_SDCLK                                0x200 0x59c 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCLK__GPIO3_20                          0x200 0x59c 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCLK__EIM_WEIM_D_20                     0x200 0x59c 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDCLK__ELCDIF_DAT_20                     0x200 0x59c 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDCLK__AUDMUX_AUD5_TXD                   0x200 0x59c 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDCLK__SDMA_DEBUG_BUS_DEVICE_0           0x200 0x59c 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDCLK__USBPHY2_HOSTDISCONNECT            0x200 0x59c 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOEZ__EPCD_SDOEZ                                0x204 0x5a0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOEZ__GPIO3_21                          0x204 0x5a0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOEZ__EIM_WEIM_D_21                     0x204 0x5a0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOEZ__ELCDIF_DAT_21                     0x204 0x5a0 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOEZ__AUDMUX_AUD5_TXC                   0x204 0x5a0 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOEZ__SDMA_DEBUG_BUS_DEVICE_1           0x204 0x5a0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOEZ__USBPHY2_TXREADY                   0x204 0x5a0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOED__EPCD_SDOED                                0x208 0x5a4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOED__GPIO3_22                          0x208 0x5a4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOED__EIM_WEIM_D_22                     0x208 0x5a4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOED__ELCDIF_DAT_22                     0x208 0x5a4 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOED__AUDMUX_AUD5_TXFS                  0x208 0x5a4 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOED__SDMA_DEBUG_BUS_DEVICE_2           0x208 0x5a4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOED__USBPHY2_RXVALID                   0x208 0x5a4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDOE__EPCD_SDOE                          0x20c 0x5a8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDOE__GPIO3_23                           0x20c 0x5a8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDOE__EIM_WEIM_D_23                      0x20c 0x5a8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDOE__ELCDIF_DAT_23                      0x20c 0x5a8 0x000 0x3 0x0
+#define MX50_PAD_EPDC_SDOE__AUDMUX_AUD5_RXD                    0x20c 0x5a8 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDOE__SDMA_DEBUG_BUS_DEVICE_3            0x20c 0x5a8 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDOE__USBPHY2_RXACTIVE                   0x20c 0x5a8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDLE__EPCD_SDLE                          0x210 0x5ac 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDLE__GPIO3_24                           0x210 0x5ac 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDLE__EIM_WEIM_D_24                      0x210 0x5ac 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDLE__ELCDIF_DAT_8                       0x210 0x5ac 0x71c 0x3 0x1
+#define MX50_PAD_EPDC_SDLE__AUDMUX_AUD5_RXC                    0x210 0x5ac 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDLE__SDMA_DEBUG_BUS_DEVICE_4            0x210 0x5ac 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDLE__USBPHY2_RXERROR                    0x210 0x5ac 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDCLKN__EPCD_SDCLKN                      0x214 0x5b0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCLKN__GPIO3_25                         0x214 0x5b0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCLKN__EIM_WEIM_D_25                    0x214 0x5b0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDCLKN__ELCDIF_DAT_9                     0x214 0x5b0 0x720 0x3 0x1
+#define MX50_PAD_EPDC_SDCLKN__AUDMUX_AUD5_RXFS                 0x214 0x5b0 0x000 0x4 0x0
+#define MX50_PAD_EPDC_SDCLKN__SDMA_DEBUG_BUS_ERROR             0x214 0x5b0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDCLKN__USBPHY2_SIECLOCK                 0x214 0x5b0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_SDSHR__EPCD_SDSHR                                0x218 0x5b4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDSHR__GPIO3_26                          0x218 0x5b4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDSHR__EIM_WEIM_D_26                     0x218 0x5b4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_SDSHR__ELCDIF_DAT_10                     0x218 0x5b4 0x724 0x3 0x1
+#define MX50_PAD_EPDC_SDSHR__AUDMUX_AUD4_TXD                   0x218 0x5b4 0x6c8 0x4 0x1
+#define MX50_PAD_EPDC_SDSHR__SDMA_DEBUG_BUS_RWB                        0x218 0x5b4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_SDSHR__USBPHY2_LINESTATE_0               0x218 0x5b4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCOM__EPCD_PWRCOM                      0x21c 0x5b8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCOM__GPIO3_27                         0x21c 0x5b8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCOM__EIM_WEIM_D_27                    0x21c 0x5b8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCOM__ELCDIF_DAT_11                    0x21c 0x5b8 0x728 0x3 0x1
+#define MX50_PAD_EPDC_PWRCOM__AUDMUX_AUD4_TXC                  0x21c 0x5b8 0x6d4 0x4 0x1
+#define MX50_PAD_EPDC_PWRCOM__SDMA_DEBUG_CORE_RUN              0x21c 0x5b8 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCOM__USBPHY2_LINESTATE_1              0x21c 0x5b8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRSTAT__EPCD_PWRSTAT                    0x220 0x5bc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRSTAT__GPIO3_28                                0x220 0x5bc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRSTAT__EIM_WEIM_D_28                   0x220 0x5bc 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRSTAT__ELCDIF_DAT_12                   0x220 0x5bc 0x72c 0x3 0x1
+#define MX50_PAD_EPDC_PWRSTAT__AUDMUX_AUD4_TXFS                        0x220 0x5bc 0x6d8 0x4 0x1
+#define MX50_PAD_EPDC_PWRSTAT__SDMA_DEBUG_MODE                 0x220 0x5bc 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRSTAT__USBPHY2_VBUSVALID               0x220 0x5bc 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__EPCD_PWRCTRL0                  0x224 0x5c0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__GPIO3_29                       0x224 0x5c0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__EIM_WEIM_D_29                  0x224 0x5c0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_DAT_13                  0x224 0x5c0 0x730 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL0__AUDMUX_AUD4_RXD                        0x224 0x5c0 0x6c4 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL0__SDMA_DEBUG_RTBUFFER_WRITE      0x224 0x5c0 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCTRL0__USBPHY2_AVALID                 0x224 0x5c0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__EPCD_PWRCTRL1                  0x228 0x5c4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__GPIO3_30                       0x228 0x5c4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__EIM_WEIM_D_30                  0x228 0x5c4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_DAT_14                  0x228 0x5c4 0x734 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL1__AUDMUX_AUD4_RXC                        0x228 0x5c4 0x6cc 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL1__SDMA_DEBUG_YIELD               0x228 0x5c4 0x000 0x6 0x0
+#define MX50_PAD_EPDC_PWRCTRL1__USBPHY1_ONBIST                 0x228 0x5c4 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__EPCD_PWRCTRL2                  0x22c 0x5c8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__GPIO3_31                       0x22c 0x5c8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__EIM_WEIM_D_31                  0x22c 0x5c8 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_DAT_15                  0x22c 0x5c8 0x738 0x3 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__AUDMUX_AUD4_RXFS               0x22c 0x5c8 0x6d0 0x4 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT_EVENT_0               0x22c 0x5c8 0x7b8 0x6 0x1
+#define MX50_PAD_EPDC_PWRCTRL2__USBPHY2_ONBIST                 0x22c 0x5c8 0x000 0x7 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__EPCD_PWRCTRL3                  0x230 0x5cc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__GPIO4_20                       0x230 0x5cc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__EIM_WEIM_EB_2                  0x230 0x5cc 0x000 0x2 0x0
+#define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT_EVENT_1               0x230 0x5cc 0x7bc 0x6 0x1
+#define MX50_PAD_EPDC_PWRCTRL3__USBPHY1_BISTOK                 0x230 0x5cc 0x000 0x7 0x0
+#define MX50_PAD_EPDC_VCOM0__EPCD_VCOM_0                       0x234 0x5d0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_VCOM0__GPIO4_21                          0x234 0x5d0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_VCOM0__EIM_WEIM_EB_3                     0x234 0x5d0 0x000 0x2 0x0
+#define MX50_PAD_EPDC_VCOM0__USBPHY2_BISTOK                    0x234 0x5d0 0x000 0x7 0x0
+#define MX50_PAD_EPDC_VCOM1__EPCD_VCOM_1                       0x238 0x5d4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_VCOM1__GPIO4_22                          0x238 0x5d4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_VCOM1__EIM_WEIM_CS_3                     0x238 0x5d4 0x000 0x2 0x0
+#define MX50_PAD_EPDC_BDR0__EPCD_BDR_0                         0x23c 0x5d8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_BDR0__GPIO4_23                           0x23c 0x5d8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_BDR0__ELCDIF_DAT_7                       0x23c 0x5d8 0x718 0x3 0x1
+#define MX50_PAD_EPDC_BDR1__EPCD_BDR_1                         0x240 0x5dc 0x000 0x0 0x0
+#define MX50_PAD_EPDC_BDR1__GPIO4_24                           0x240 0x5dc 0x000 0x1 0x0
+#define MX50_PAD_EPDC_BDR1__ELCDIF_DAT_6                       0x240 0x5dc 0x714 0x3 0x1
+#define MX50_PAD_EPDC_SDCE0__EPCD_SDCE_0                       0x244 0x5e0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE0__GPIO4_25                          0x244 0x5e0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE0__ELCDIF_DAT_5                      0x244 0x5e0 0x710 0x3 0x1
+#define MX50_PAD_EPDC_SDCE1__EPCD_SDCE_1                       0x248 0x5e4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE1__GPIO4_26                          0x248 0x5e4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE1__ELCDIF_DAT_4                      0x248 0x5e4 0x70c 0x3 0x0
+#define MX50_PAD_EPDC_SDCE2__EPCD_SDCE_2                       0x24c 0x5e8 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE2__GPIO4_27                          0x24c 0x5e8 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT_3                      0x24c 0x5e8 0x708 0x3 0x1
+#define MX50_PAD_EPDC_SDCE3__EPCD_SDCE_3                       0x250 0x5ec 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE3__GPIO4_28                          0x250 0x5ec 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE3__ELCDIF_DAT_2                      0x250 0x5ec 0x704 0x3 0x1
+#define MX50_PAD_EPDC_SDCE4__EPCD_SDCE_4                       0x254 0x5f0 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE4__GPIO4_29                          0x254 0x5f0 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE4__ELCDIF_DAT_1                      0x254 0x5f0 0x700 0x3 0x1
+#define MX50_PAD_EPDC_SDCE5__EPCD_SDCE_5                       0x258 0x5f4 0x000 0x0 0x0
+#define MX50_PAD_EPDC_SDCE5__GPIO4_30                          0x258 0x5f4 0x000 0x1 0x0
+#define MX50_PAD_EPDC_SDCE5__ELCDIF_DAT_0                      0x258 0x5f4 0x6fc 0x3 0x1
+#define MX50_PAD_EIM_DA0__EIM_WEIM_A_0                         0x25c 0x5f8 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA0__GPIO1_0                              0x25c 0x5f8 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA0__KPP_COL_4                            0x25c 0x5f8 0x790 0x3 0x2
+#define MX50_PAD_EIM_DA0__TPIU_TRACE_0                         0x25c 0x5f8 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA0__SRC_BT_CFG1_0                                0x25c 0x5f8 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA1__EIM_WEIM_A_1                         0x260 0x5fc 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA1__GPIO1_1                              0x260 0x5fc 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA1__KPP_ROW_4                            0x260 0x5fc 0x7a0 0x3 0x2
+#define MX50_PAD_EIM_DA1__TPIU_TRACE_1                         0x260 0x5fc 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA1__SRC_BT_CFG1_1                                0x260 0x5fc 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA2__EIM_WEIM_A_2                         0x264 0x600 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA2__GPIO1_2                              0x264 0x600 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA2__KPP_COL_5                            0x264 0x600 0x794 0x3 0x2
+#define MX50_PAD_EIM_DA2__TPIU_TRACE_2                         0x264 0x600 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA2__SRC_BT_CFG1_2                                0x264 0x600 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA3__EIM_WEIM_A_3                         0x268 0x604 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA3__GPIO1_3                              0x268 0x604 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA3__KPP_ROW_5                            0x268 0x604 0x7a4 0x3 0x2
+#define MX50_PAD_EIM_DA3__TPIU_TRACE_3                         0x268 0x604 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA3__SRC_BT_CFG1_3                                0x268 0x604 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA4__EIM_WEIM_A_4                         0x26c 0x608 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA4__GPIO1_4                              0x26c 0x608 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA4__KPP_COL_6                            0x26c 0x608 0x798 0x3 0x2
+#define MX50_PAD_EIM_DA4__TPIU_TRACE_4                         0x26c 0x608 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA4__SRC_BT_CFG1_4                                0x26c 0x608 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA5__EIM_WEIM_A_5                         0x270 0x60c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA5__GPIO1_5                              0x270 0x60c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA5__KPP_ROW_6                            0x270 0x60c 0x7a8 0x3 0x2
+#define MX50_PAD_EIM_DA5__TPIU_TRACE_5                         0x270 0x60c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA5__SRC_BT_CFG1_5                                0x270 0x60c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA6__EIM_WEIM_A_6                         0x274 0x610 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA6__GPIO1_6                              0x274 0x610 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA6__KPP_COL_7                            0x274 0x610 0x79c 0x3 0x2
+#define MX50_PAD_EIM_DA6__TPIU_TRACE_6                         0x274 0x610 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA6__SRC_BT_CFG1_6                                0x274 0x610 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA7__EIM_WEIM_A_7                         0x278 0x614 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA7__GPIO1_7                              0x278 0x614 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA7__KPP_ROW_7                            0x278 0x614 0x7ac 0x3 0x2
+#define MX50_PAD_EIM_DA7__TPIU_TRACE_7                         0x278 0x614 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA7__SRC_BT_CFG1_7                                0x278 0x614 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA8__EIM_WEIM_A_8                         0x27c 0x618 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA8__GPIO1_8                              0x27c 0x618 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA8__EIM_NANDF_CLE                                0x27c 0x618 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA8__TPIU_TRACE_8                         0x27c 0x618 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA8__SRC_BT_CFG2_0                                0x27c 0x618 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA9__EIM_WEIM_A_9                         0x280 0x61c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA9__GPIO1_9                              0x280 0x61c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA9__EIM_NANDF_ALE                                0x280 0x61c 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA9__TPIU_TRACE_9                         0x280 0x61c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA9__SRC_BT_CFG2_1                                0x280 0x61c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA10__EIM_WEIM_A_10                       0x284 0x620 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA10__GPIO1_10                            0x284 0x620 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA10__EIM_NANDF_CEN_0                     0x284 0x620 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA10__TPIU_TRACE_10                       0x284 0x620 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA10__SRC_BT_CFG2_2                       0x284 0x620 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA11__EIM_WEIM_A_11                       0x288 0x624 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA11__GPIO1_11                            0x288 0x624 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA11__EIM_NANDF_CEN_1                     0x288 0x624 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA11__TPIU_TRACE_11                       0x288 0x624 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA11__SRC_BT_CFG2_3                       0x288 0x624 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA12__EIM_WEIM_A_12                       0x28c 0x628 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA12__GPIO1_12                            0x28c 0x628 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA12__EIM_NANDF_CEN_2                     0x28c 0x628 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA12__EPDC_SDCE_6                         0x28c 0x628 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA12__TPIU_TRACE_12                       0x28c 0x628 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA12__SRC_BT_CFG2_4                       0x28c 0x628 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA13__EIM_WEIM_A_13                       0x290 0x62c 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA13__GPIO1_13                            0x290 0x62c 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA13__EIM_NANDF_CEN_3                     0x290 0x62c 0x000 0x2 0x0
+#define MX50_PAD_EIM_DA13__EPDC_SDCE_7                         0x290 0x62c 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA13__TPIU_TRACE_13                       0x290 0x62c 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA13__SRC_BT_CFG2_5                       0x290 0x62c 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA14__EIM_WEIM_A_14                       0x294 0x630 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA14__GPIO1_14                            0x294 0x630 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA14__EIM_NANDF_READY0                    0x294 0x630 0x7b4 0x2 0x2
+#define MX50_PAD_EIM_DA14__EPDC_SDCE_8                         0x294 0x630 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA14__TPIU_TRACE_14                       0x294 0x630 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA14__SRC_BT_CFG2_6                       0x294 0x630 0x000 0x7 0x0
+#define MX50_PAD_EIM_DA15__EIM_WEIM_A_15                       0x298 0x634 0x000 0x0 0x0
+#define MX50_PAD_EIM_DA15__GPIO1_15                            0x298 0x634 0x000 0x1 0x0
+#define MX50_PAD_EIM_DA15__EIM_NANDF_DQS                       0x298 0x634 0x7b0 0x2 0x2
+#define MX50_PAD_EIM_DA15__EPDC_SDCE_9                         0x298 0x634 0x000 0x3 0x0
+#define MX50_PAD_EIM_DA15__TPIU_TRACE_15                       0x298 0x634 0x000 0x6 0x0
+#define MX50_PAD_EIM_DA15__SRC_BT_CFG2_7                       0x298 0x634 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS2__EIM_WEIM_CS_2                                0x29c 0x638 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS2__GPIO1_16                             0x29c 0x638 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS2__EIM_WEIM_A_27                                0x29c 0x638 0x000 0x2 0x0
+#define MX50_PAD_EIM_CS2__TPIU_TRCLK                           0x29c 0x638 0x000 0x6 0x0
+#define MX50_PAD_EIM_CS2__SRC_BT_CFG3_0                                0x29c 0x638 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS1__EIM_WEIM_CS_1                                0x2a0 0x63c 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS1__GPIO1_17                             0x2a0 0x63c 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS1__TPIU_TRCTL                           0x2a0 0x63c 0x000 0x6 0x0
+#define MX50_PAD_EIM_CS1__SRC_BT_CFG3_1                                0x2a0 0x63c 0x000 0x7 0x0
+#define MX50_PAD_EIM_CS0__EIM_WEIM_CS_0                                0x2a4 0x640 0x000 0x0 0x0
+#define MX50_PAD_EIM_CS0__GPIO1_18                             0x2a4 0x640 0x000 0x1 0x0
+#define MX50_PAD_EIM_CS0__SRC_BT_CFG3_2                                0x2a4 0x640 0x000 0x7 0x0
+#define MX50_PAD_EIM_EB0__EIM_WEIM_EB_0                                0x2a8 0x644 0x000 0x0 0x0
+#define MX50_PAD_EIM_EB0__GPIO1_19                             0x2a8 0x644 0x000 0x1 0x0
+#define MX50_PAD_EIM_EB0__SRC_BT_CFG3_3                                0x2a8 0x644 0x000 0x7 0x0
+#define MX50_PAD_EIM_EB1__EIM_WEIM_EB_1                                0x2ac 0x648 0x000 0x0 0x0
+#define MX50_PAD_EIM_EB1__GPIO1_20                             0x2ac 0x648 0x000 0x1 0x0
+#define MX50_PAD_EIM_EB1__SRC_BT_CFG3_4                                0x2ac 0x648 0x000 0x7 0x0
+#define MX50_PAD_EIM_WAIT__EIM_WEIM_WAIT                       0x2b0 0x64c 0x000 0x0 0x0
+#define MX50_PAD_EIM_WAIT__GPIO1_21                            0x2b0 0x64c 0x000 0x1 0x0
+#define MX50_PAD_EIM_WAIT__EIM_WEIM_DTACK_B                    0x2b0 0x64c 0x000 0x2 0x0
+#define MX50_PAD_EIM_WAIT__SRC_BT_CFG3_5                       0x2b0 0x64c 0x000 0x7 0x0
+#define MX50_PAD_EIM_BCLK__EIM_WEIM_BCLK                       0x2b4 0x650 0x000 0x0 0x0
+#define MX50_PAD_EIM_BCLK__GPIO1_22                            0x2b4 0x650 0x000 0x1 0x0
+#define MX50_PAD_EIM_BCLK__SRC_BT_CFG3_6                       0x2b4 0x650 0x000 0x7 0x0
+#define MX50_PAD_EIM_RDY__EIM_WEIM_RDY                         0x2b8 0x654 0x000 0x0 0x0
+#define MX50_PAD_EIM_RDY__GPIO1_23                             0x2b8 0x654 0x000 0x1 0x0
+#define MX50_PAD_EIM_RDY__SRC_BT_CFG3_7                                0x2b8 0x654 0x000 0x7 0x0
+#define MX50_PAD_EIM_OE__EIM_WEIM_OE                           0x2bc 0x658 0x000 0x0 0x0
+#define MX50_PAD_EIM_OE__GPIO1_24                              0x2bc 0x658 0x000 0x1 0x0
+#define MX50_PAD_EIM_OE__INT_BOOT                              0x2bc 0x658 0x000 0x7 0x0
+#define MX50_PAD_EIM_RW__EIM_WEIM_RW                           0x2c0 0x65c 0x000 0x0 0x0
+#define MX50_PAD_EIM_RW__GPIO1_25                              0x2c0 0x65c 0x000 0x1 0x0
+#define MX50_PAD_EIM_RW__SYSTEM_RST                            0x2c0 0x65c 0x000 0x7 0x0
+#define MX50_PAD_EIM_LBA__EIM_WEIM_LBA                         0x2c4 0x660 0x000 0x0 0x0
+#define MX50_PAD_EIM_LBA__GPIO1_26                             0x2c4 0x660 0x000 0x1 0x0
+#define MX50_PAD_EIM_LBA__TESTER_ACK                           0x2c4 0x660 0x000 0x7 0x0
+#define MX50_PAD_EIM_CRE__EIM_WEIM_CRE                         0x2c8 0x664 0x000 0x0 0x0
+#define MX50_PAD_EIM_CRE__GPIO1_27                             0x2c8 0x664 0x000 0x1 0x0
+
+#endif /* __DTS_IMX50_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
new file mode 100644 (file)
index 0000000..0c75fe3
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * Copyright 2013 Greg Ungerer <gerg@uclinux.org>
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "skeleton.dtsi"
+#include "imx50-pinfunc.h"
+#include <dt-bindings/clock/imx5-clock.h>
+
+/ {
+       aliases {
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a8";
+                       reg = <0x0>;
+               };
+       };
+
+       tzic: tz-interrupt-controller@0fffc000 {
+               compatible = "fsl,imx50-tzic", "fsl,imx53-tzic", "fsl,tzic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0x0fffc000 0x4000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ckil {
+                       compatible = "fsl,imx-ckil", "fixed-clock";
+                       clock-frequency = <32768>;
+               };
+
+               ckih1 {
+                       compatible = "fsl,imx-ckih1", "fixed-clock";
+                       clock-frequency = <22579200>;
+               };
+
+               ckih2 {
+                       compatible = "fsl,imx-ckih2", "fixed-clock";
+                       clock-frequency = <0>;
+               };
+
+               osc {
+                       compatible = "fsl,imx-osc", "fixed-clock";
+                       clock-frequency = <24000000>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&tzic>;
+               ranges;
+
+               aips@50000000 { /* AIPS1 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x50000000 0x10000000>;
+                       ranges;
+
+                       spba@50000000 {
+                               compatible = "fsl,spba-bus", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x50000000 0x40000>;
+                               ranges;
+
+                               esdhc1: esdhc@50004000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50004000 0x4000>;
+                                       interrupts = <1>;
+                                       clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC1_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+
+                               esdhc2: esdhc@50008000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50008000 0x4000>;
+                                       interrupts = <2>;
+                                       clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC2_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+
+                               uart3: serial@5000c000 {
+                                       compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                                       reg = <0x5000c000 0x4000>;
+                                       interrupts = <33>;
+                                       clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+                                                <&clks IMX5_CLK_UART3_PER_GATE>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi1: ecspi@50010000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x50010000 0x4000>;
+                                       interrupts = <36>;
+                                       clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+                                                <&clks IMX5_CLK_ECSPI1_PER_GATE>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ssi2: ssi@50014000 {
+                                       compatible = "fsl,imx50-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
+                                       reg = <0x50014000 0x4000>;
+                                       interrupts = <30>;
+                                       clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
+                                       fsl,fifo-depth = <15>;
+                                       fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
+                                       status = "disabled";
+                               };
+
+                               esdhc3: esdhc@50020000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50020000 0x4000>;
+                                       interrupts = <3>;
+                                       clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC3_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+
+                               esdhc4: esdhc@50024000 {
+                                       compatible = "fsl,imx50-esdhc";
+                                       reg = <0x50024000 0x4000>;
+                                       interrupts = <4>;
+                                       clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC4_PER_GATE>;
+                                       clock-names = "ipg", "ahb", "per";
+                                       bus-width = <4>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       usbotg: usb@53f80000 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80000 0x0200>;
+                               interrupts = <18>;
+                               clocks = <&clks IMX5_CLK_USB_PHY1_GATE>;
+                               status = "disabled";
+                       };
+
+                       usbh1: usb@53f80200 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80200 0x0200>;
+                               interrupts = <14>;
+                               clocks = <&clks IMX5_CLK_USB_PHY2_GATE>;
+                               status = "disabled";
+                       };
+
+                       usbh2: usb@53f80400 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80400 0x0200>;
+                               interrupts = <16>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+                               status = "disabled";
+                       };
+
+                       usbh3: usb@53f80600 {
+                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
+                               reg = <0x53f80600 0x0200>;
+                               interrupts = <17>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
+                               status = "disabled";
+                       };
+
+                       gpio1: gpio@53f84000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f84000 0x4000>;
+                               interrupts = <50 51>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@53f88000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f88000 0x4000>;
+                               interrupts = <52 53>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio@53f8c000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f8c000 0x4000>;
+                               interrupts = <54 55>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio4: gpio@53f90000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53f90000 0x4000>;
+                               interrupts = <56 57>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       wdog1: wdog@53f98000 {
+                               compatible = "fsl,imx50-wdt", "fsl,imx21-wdt";
+                               reg = <0x53f98000 0x4000>;
+                               interrupts = <58>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
+                       };
+
+                       gpt: timer@53fa0000 {
+                               compatible = "fsl,imx50-gpt", "fsl,imx31-gpt";
+                               reg = <0x53fa0000 0x4000>;
+                               interrupts = <39>;
+                               clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+                                        <&clks IMX5_CLK_GPT_HF_GATE>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       iomuxc: iomuxc@53fa8000 {
+                               compatible = "fsl,imx50-iomuxc", "fsl,imx53-iomuxc";
+                               reg = <0x53fa8000 0x4000>;
+                       };
+
+                       gpr: iomuxc-gpr@53fa8000 {
+                               compatible = "fsl,imx50-iomuxc-gpr", "syscon";
+                               reg = <0x53fa8000 0xc>;
+                       };
+
+                       pwm1: pwm@53fb4000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fb4000 0x4000>;
+                               clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM1_HF_GATE>;
+                               clock-names = "ipg", "per";
+                               interrupts = <61>;
+                       };
+
+                       pwm2: pwm@53fb8000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx50-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fb8000 0x4000>;
+                               clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM2_HF_GATE>;
+                               clock-names = "ipg", "per";
+                               interrupts = <94>;
+                       };
+
+                       uart1: serial@53fbc000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x53fbc000 0x4000>;
+                               interrupts = <31>;
+                               clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART1_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart2: serial@53fc0000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x53fc0000 0x4000>;
+                               interrupts = <32>;
+                               clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART2_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       src: src@53fd0000 {
+                               compatible = "fsl,imx50-src", "fsl,imx51-src";
+                               reg = <0x53fd0000 0x4000>;
+                               #reset-cells = <1>;
+                       };
+
+                       clks: ccm@53fd4000{
+                               compatible = "fsl,imx50-ccm";
+                               reg = <0x53fd4000 0x4000>;
+                               interrupts = <0 71 0x04 0 72 0x04>;
+                               #clock-cells = <1>;
+                       };
+
+                       gpio5: gpio@53fdc000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53fdc000 0x4000>;
+                               interrupts = <103 104>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio6: gpio@53fe0000 {
+                               compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
+                               reg = <0x53fe0000 0x4000>;
+                               interrupts = <105 106>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       i2c3: i2c@53fec000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+                               reg = <0x53fec000 0x4000>;
+                               interrupts = <64>;
+                               clocks = <&clks IMX5_CLK_I2C3_GATE>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@53ff0000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x53ff0000 0x4000>;
+                               interrupts = <13>;
+                               clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART4_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+               };
+
+               aips@60000000 { /* AIPS2 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x60000000 0x10000000>;
+                       ranges;
+
+                       uart5: serial@63f90000 {
+                               compatible = "fsl,imx50-uart", "fsl,imx21-uart";
+                               reg = <0x63f90000 0x4000>;
+                               interrupts = <86>;
+                               clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART5_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       owire: owire@63fa4000 {
+                               compatible = "fsl,imx50-owire", "fsl,imx21-owire";
+                               reg = <0x63fa4000 0x4000>;
+                               clocks = <&clks IMX5_CLK_OWIRE_GATE>;
+                               status = "disabled";
+                       };
+
+                       ecspi2: ecspi@63fac000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
+                               reg = <0x63fac000 0x4000>;
+                               interrupts = <37>;
+                               clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+                                        <&clks IMX5_CLK_ECSPI2_PER_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       sdma: sdma@63fb0000 {
+                               compatible = "fsl,imx50-sdma", "fsl,imx35-sdma";
+                               reg = <0x63fb0000 0x4000>;
+                               interrupts = <6>;
+                               clocks = <&clks IMX5_CLK_SDMA_GATE>,
+                                        <&clks IMX5_CLK_SDMA_GATE>;
+                               clock-names = "ipg", "ahb";
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx50.bin";
+                       };
+
+                       cspi: cspi@63fc0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-cspi", "fsl,imx35-cspi";
+                               reg = <0x63fc0000 0x4000>;
+                               interrupts = <38>;
+                               clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+                                        <&clks IMX5_CLK_CSPI_IPG_GATE>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@63fc4000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+                               reg = <0x63fc4000 0x4000>;
+                               interrupts = <63>;
+                               clocks = <&clks IMX5_CLK_I2C2_GATE>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@63fc8000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx50-i2c", "fsl,imx21-i2c";
+                               reg = <0x63fc8000 0x4000>;
+                               interrupts = <62>;
+                               clocks = <&clks IMX5_CLK_I2C1_GATE>;
+                               status = "disabled";
+                       };
+
+                       ssi1: ssi@63fcc000 {
+                               compatible = "fsl,imx50-ssi", "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
+                               reg = <0x63fcc000 0x4000>;
+                               interrupts = <29>;
+                               clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
+                               fsl,fifo-depth = <15>;
+                               fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
+                               status = "disabled";
+                       };
+
+                       audmux: audmux@63fd0000 {
+                               compatible = "fsl,imx50-audmux", "fsl,imx31-audmux";
+                               reg = <0x63fd0000 0x4000>;
+                               status = "disabled";
+                       };
+
+                       fec: ethernet@63fec000 {
+                               compatible = "fsl,imx53-fec", "fsl,imx25-fec";
+                               reg = <0x63fec000 0x4000>;
+                               interrupts = <87>;
+                               clocks = <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>;
+                               clock-names = "ipg", "ahb", "ptp";
+                               status = "disabled";
+                       };
+               };
+       };
+};
index b3606993f2e8db4e4327305f52fddec70249e9f3..e88b2a6be079d855a985ca8bb18677895f7a7494 100644 (file)
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_2>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "mii";
-       phy-reset-gpios = <&gpio3 0 0>;
+       phy-reset-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
        phy-reset-duration = <1>;
        status = "okay";
 };
 
+&iomuxc {
+       imx51-apf51 {
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX51_PAD_DI_GP3__FEC_TX_ER              0x80000000
+                               MX51_PAD_DI2_PIN4__FEC_CRS              0x80000000
+                               MX51_PAD_DI2_PIN2__FEC_MDC              0x80000000
+                               MX51_PAD_DI2_PIN3__FEC_MDIO             0x80000000
+                               MX51_PAD_DI2_DISP_CLK__FEC_RDATA1       0x80000000
+                               MX51_PAD_DI_GP4__FEC_RDATA2             0x80000000
+                               MX51_PAD_DISP2_DAT0__FEC_RDATA3         0x80000000
+                               MX51_PAD_DISP2_DAT1__FEC_RX_ER          0x80000000
+                               MX51_PAD_DISP2_DAT6__FEC_TDATA1         0x80000000
+                               MX51_PAD_DISP2_DAT7__FEC_TDATA2         0x80000000
+                               MX51_PAD_DISP2_DAT8__FEC_TDATA3         0x80000000
+                               MX51_PAD_DISP2_DAT9__FEC_TX_EN          0x80000000
+                               MX51_PAD_DISP2_DAT10__FEC_COL           0x80000000
+                               MX51_PAD_DISP2_DAT11__FEC_RX_CLK        0x80000000
+                               MX51_PAD_DISP2_DAT12__FEC_RX_DV         0x80000000
+                               MX51_PAD_DISP2_DAT13__FEC_TX_CLK        0x80000000
+                               MX51_PAD_DISP2_DAT14__FEC_RDATA0        0x80000000
+                               MX51_PAD_DISP2_DAT15__FEC_TDATA0        0x80000000
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX51_PAD_UART3_RXD__UART3_RXD           0x1c5
+                               MX51_PAD_UART3_TXD__UART3_TXD           0x1c5
+                       >;
+               };
+       };
+};
+
 &nfc {
        nand-bus-width = <8>;
        nand-ecc-mode = "hw";
@@ -50,6 +84,6 @@
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_2>;
+       pinctrl-0 = <&pinctrl_uart3>;
        status = "okay";
 };
index d3f98141462cb3eb183185c54b30ac08e9149455..c5a9a24c280a48941bf004ee7370e39ce3c23068 100644 (file)
@@ -20,7 +20,7 @@
                compatible = "fsl,imx-parallel-display";
                interface-pix-fmt = "bgr666";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp1>;
 
                display-timings {
                        lw700 {
@@ -53,7 +53,7 @@
 
                user-key {
                        label = "user";
-                       gpios = <&gpio1 3 0>;
+                       gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
                        linux,code = <256>; /* BTN_0 */
                };
        };
@@ -63,7 +63,7 @@
 
                user {
                        label = "Heartbeat";
-                       gpios = <&gpio1 2 0>;
+                       gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
                        linux,default-trigger = "heartbeat";
                };
        };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio4 24 0>, <&gpio4 25 0>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 25 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
 &ecspi2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi2_1>;
+       pinctrl-0 = <&pinctrl_ecspi2>;
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio3 28 1>, <&gpio3 27 1>;
+       cs-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>,
+                  <&gpio3 27 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
-       cd-gpios = <&gpio2 29 0>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       cd-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
        bus-width = <4>;
        status = "okay";
 };
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
+       pinctrl-0 = <&pinctrl_esdhc2>;
        bus-width = <4>;
        non-removable;
        status = "okay";
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_2>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx51-apf51dev {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX51_PAD_EIM_EB2__GPIO2_22   0x0C5
                                MX51_PAD_GPIO1_3__GPIO1_3    0x0C5
                        >;
                };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX51_PAD_CSPI1_MISO__ECSPI1_MISO        0x185
+                               MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI        0x185
+                               MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK        0x185
+                       >;
+               };
+
+               pinctrl_ecspi2: ecspi2grp {
+                       fsl,pins = <
+                               MX51_PAD_NANDF_RB3__ECSPI2_MISO         0x185
+                               MX51_PAD_NANDF_D15__ECSPI2_MOSI         0x185
+                               MX51_PAD_NANDF_RB2__ECSPI2_SCLK         0x185
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX51_PAD_SD1_CMD__SD1_CMD               0x400020d5
+                               MX51_PAD_SD1_CLK__SD1_CLK               0x20d5
+                               MX51_PAD_SD1_DATA0__SD1_DATA0           0x20d5
+                               MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
+                               MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
+                               MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       >;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <
+                               MX51_PAD_SD2_CMD__SD2_CMD               0x400020d5
+                               MX51_PAD_SD2_CLK__SD2_CLK               0x20d5
+                               MX51_PAD_SD2_DATA0__SD2_DATA0           0x20d5
+                               MX51_PAD_SD2_DATA1__SD2_DATA1           0x20d5
+                               MX51_PAD_SD2_DATA2__SD2_DATA2           0x20d5
+                               MX51_PAD_SD2_DATA3__SD2_DATA3           0x20d5
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX51_PAD_EIM_D27__I2C2_SCL              0x400001ed
+                               MX51_PAD_EIM_D24__I2C2_SDA              0x400001ed
+                       >;
+               };
+
+               pinctrl_ipu_disp1: ipudisp1grp {
+                       fsl,pins = <
+                               MX51_PAD_DISP1_DAT0__DISP1_DAT0         0x5
+                               MX51_PAD_DISP1_DAT1__DISP1_DAT1         0x5
+                               MX51_PAD_DISP1_DAT2__DISP1_DAT2         0x5
+                               MX51_PAD_DISP1_DAT3__DISP1_DAT3         0x5
+                               MX51_PAD_DISP1_DAT4__DISP1_DAT4         0x5
+                               MX51_PAD_DISP1_DAT5__DISP1_DAT5         0x5
+                               MX51_PAD_DISP1_DAT6__DISP1_DAT6         0x5
+                               MX51_PAD_DISP1_DAT7__DISP1_DAT7         0x5
+                               MX51_PAD_DISP1_DAT8__DISP1_DAT8         0x5
+                               MX51_PAD_DISP1_DAT9__DISP1_DAT9         0x5
+                               MX51_PAD_DISP1_DAT10__DISP1_DAT10       0x5
+                               MX51_PAD_DISP1_DAT11__DISP1_DAT11       0x5
+                               MX51_PAD_DISP1_DAT12__DISP1_DAT12       0x5
+                               MX51_PAD_DISP1_DAT13__DISP1_DAT13       0x5
+                               MX51_PAD_DISP1_DAT14__DISP1_DAT14       0x5
+                               MX51_PAD_DISP1_DAT15__DISP1_DAT15       0x5
+                               MX51_PAD_DISP1_DAT16__DISP1_DAT16       0x5
+                               MX51_PAD_DISP1_DAT17__DISP1_DAT17       0x5
+                               MX51_PAD_DISP1_DAT18__DISP1_DAT18       0x5
+                               MX51_PAD_DISP1_DAT19__DISP1_DAT19       0x5
+                               MX51_PAD_DISP1_DAT20__DISP1_DAT20       0x5
+                               MX51_PAD_DISP1_DAT21__DISP1_DAT21       0x5
+                               MX51_PAD_DISP1_DAT22__DISP1_DAT22       0x5
+                               MX51_PAD_DISP1_DAT23__DISP1_DAT23       0x5
+                               MX51_PAD_DI1_PIN2__DI1_PIN2             0x5
+                               MX51_PAD_DI1_PIN3__DI1_PIN3             0x5
+                       >;
+               };
        };
 };
 
index 671927145632925776fa17bbdb5489a3177beac6..9e9deb244b76ff1dfb5b4952b1d16294f1ed652f 100644 (file)
@@ -25,7 +25,7 @@
                compatible = "fsl,imx-parallel-display";
                interface-pix-fmt = "rgb24";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp1>;
                display-timings {
                        native-mode = <&timing0>;
                        timing0: dvi {
@@ -52,7 +52,7 @@
                compatible = "fsl,imx-parallel-display";
                interface-pix-fmt = "rgb565";
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+               pinctrl-0 = <&pinctrl_ipu_disp2>;
                status = "disabled";
                display-timings {
                        native-mode = <&timing1>;
 
                power {
                        label = "Power Button";
-                       gpios = <&gpio2 21 0>;
+                       gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
                        linux,code = <116>; /* KEY_POWER */
                        gpio-key,wakeup;
                };
        };
 
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led-diagnostic {
+                       label = "diagnostic";
+                       gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
        sound {
                compatible = "fsl,imx51-babbage-sgtl5000",
                             "fsl,imx-audio-sgtl5000";
                        reg=<0>;
                        #clock-cells = <0>;
                        clock-frequency = <26000000>;
-                       gpios = <&gpio4 26 1>;
+                       gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
                };
        };
 };
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        fsl,cd-controller;
        fsl,wp-controller;
        status = "okay";
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
-       cd-gpios = <&gpio1 6 0>;
-       wp-gpios = <&gpio1 5 0>;
+       pinctrl-0 = <&pinctrl_esdhc2>;
+       cd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+       wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1 &pinctrl_uart3_rtscts_1>;
+       pinctrl-0 = <&pinctrl_uart3>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio4 24 0>, <&gpio4 25 0>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 25 GPIO_ACTIVE_LOW>;
        status = "okay";
 
        pmic: mc13892@0 {
                spi-cs-high;
                reg = <0>;
                interrupt-parent = <&gpio1>;
-               interrupts = <8 0x4>;
+               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
 
                regulators {
                        sw1_reg: sw1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx51-babbage {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX51_PAD_GPIO1_0__SD1_CD     0x20d5
                                MX51_PAD_CSPI1_RDY__GPIO4_26 0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX51_PAD_AUD3_BB_TXD__AUD3_TXD          0x80000000
+                               MX51_PAD_AUD3_BB_RXD__AUD3_RXD          0x80000000
+                               MX51_PAD_AUD3_BB_CK__AUD3_TXC           0x80000000
+                               MX51_PAD_AUD3_BB_FS__AUD3_TXFS          0x80000000
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX51_PAD_CSPI1_MISO__ECSPI1_MISO        0x185
+                               MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI        0x185
+                               MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK        0x185
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX51_PAD_SD1_CMD__SD1_CMD               0x400020d5
+                               MX51_PAD_SD1_CLK__SD1_CLK               0x20d5
+                               MX51_PAD_SD1_DATA0__SD1_DATA0           0x20d5
+                               MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
+                               MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
+                               MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       >;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <
+                               MX51_PAD_SD2_CMD__SD2_CMD               0x400020d5
+                               MX51_PAD_SD2_CLK__SD2_CLK               0x20d5
+                               MX51_PAD_SD2_DATA0__SD2_DATA0           0x20d5
+                               MX51_PAD_SD2_DATA1__SD2_DATA1           0x20d5
+                               MX51_PAD_SD2_DATA2__SD2_DATA2           0x20d5
+                               MX51_PAD_SD2_DATA3__SD2_DATA3           0x20d5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX51_PAD_EIM_EB2__FEC_MDIO              0x80000000
+                               MX51_PAD_EIM_EB3__FEC_RDATA1            0x80000000
+                               MX51_PAD_EIM_CS2__FEC_RDATA2            0x80000000
+                               MX51_PAD_EIM_CS3__FEC_RDATA3            0x80000000
+                               MX51_PAD_EIM_CS4__FEC_RX_ER             0x80000000
+                               MX51_PAD_EIM_CS5__FEC_CRS               0x80000000
+                               MX51_PAD_NANDF_RB2__FEC_COL             0x80000000
+                               MX51_PAD_NANDF_RB3__FEC_RX_CLK          0x80000000
+                               MX51_PAD_NANDF_D9__FEC_RDATA0           0x80000000
+                               MX51_PAD_NANDF_D8__FEC_TDATA0           0x80000000
+                               MX51_PAD_NANDF_CS2__FEC_TX_ER           0x80000000
+                               MX51_PAD_NANDF_CS3__FEC_MDC             0x80000000
+                               MX51_PAD_NANDF_CS4__FEC_TDATA1          0x80000000
+                               MX51_PAD_NANDF_CS5__FEC_TDATA2          0x80000000
+                               MX51_PAD_NANDF_CS6__FEC_TDATA3          0x80000000
+                               MX51_PAD_NANDF_CS7__FEC_TX_EN           0x80000000
+                               MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK      0x80000000
+                               MX51_PAD_EIM_A20__GPIO2_14 0x85 /* Reset */
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               MX51_PAD_EIM_D22__GPIO2_6               0x80000000
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX51_PAD_KEY_COL4__I2C2_SCL             0x400001ed
+                               MX51_PAD_KEY_COL5__I2C2_SDA             0x400001ed
+                       >;
+               };
+
+               pinctrl_ipu_disp1: ipudisp1grp {
+                       fsl,pins = <
+                               MX51_PAD_DISP1_DAT0__DISP1_DAT0         0x5
+                               MX51_PAD_DISP1_DAT1__DISP1_DAT1         0x5
+                               MX51_PAD_DISP1_DAT2__DISP1_DAT2         0x5
+                               MX51_PAD_DISP1_DAT3__DISP1_DAT3         0x5
+                               MX51_PAD_DISP1_DAT4__DISP1_DAT4         0x5
+                               MX51_PAD_DISP1_DAT5__DISP1_DAT5         0x5
+                               MX51_PAD_DISP1_DAT6__DISP1_DAT6         0x5
+                               MX51_PAD_DISP1_DAT7__DISP1_DAT7         0x5
+                               MX51_PAD_DISP1_DAT8__DISP1_DAT8         0x5
+                               MX51_PAD_DISP1_DAT9__DISP1_DAT9         0x5
+                               MX51_PAD_DISP1_DAT10__DISP1_DAT10       0x5
+                               MX51_PAD_DISP1_DAT11__DISP1_DAT11       0x5
+                               MX51_PAD_DISP1_DAT12__DISP1_DAT12       0x5
+                               MX51_PAD_DISP1_DAT13__DISP1_DAT13       0x5
+                               MX51_PAD_DISP1_DAT14__DISP1_DAT14       0x5
+                               MX51_PAD_DISP1_DAT15__DISP1_DAT15       0x5
+                               MX51_PAD_DISP1_DAT16__DISP1_DAT16       0x5
+                               MX51_PAD_DISP1_DAT17__DISP1_DAT17       0x5
+                               MX51_PAD_DISP1_DAT18__DISP1_DAT18       0x5
+                               MX51_PAD_DISP1_DAT19__DISP1_DAT19       0x5
+                               MX51_PAD_DISP1_DAT20__DISP1_DAT20       0x5
+                               MX51_PAD_DISP1_DAT21__DISP1_DAT21       0x5
+                               MX51_PAD_DISP1_DAT22__DISP1_DAT22       0x5
+                               MX51_PAD_DISP1_DAT23__DISP1_DAT23       0x5
+                               MX51_PAD_DI1_PIN2__DI1_PIN2             0x5
+                               MX51_PAD_DI1_PIN3__DI1_PIN3             0x5
+                       >;
+               };
+
+               pinctrl_ipu_disp2: ipudisp2grp {
+                       fsl,pins = <
+                               MX51_PAD_DISP2_DAT0__DISP2_DAT0         0x5
+                               MX51_PAD_DISP2_DAT1__DISP2_DAT1         0x5
+                               MX51_PAD_DISP2_DAT2__DISP2_DAT2         0x5
+                               MX51_PAD_DISP2_DAT3__DISP2_DAT3         0x5
+                               MX51_PAD_DISP2_DAT4__DISP2_DAT4         0x5
+                               MX51_PAD_DISP2_DAT5__DISP2_DAT5         0x5
+                               MX51_PAD_DISP2_DAT6__DISP2_DAT6         0x5
+                               MX51_PAD_DISP2_DAT7__DISP2_DAT7         0x5
+                               MX51_PAD_DISP2_DAT8__DISP2_DAT8         0x5
+                               MX51_PAD_DISP2_DAT9__DISP2_DAT9         0x5
+                               MX51_PAD_DISP2_DAT10__DISP2_DAT10       0x5
+                               MX51_PAD_DISP2_DAT11__DISP2_DAT11       0x5
+                               MX51_PAD_DISP2_DAT12__DISP2_DAT12       0x5
+                               MX51_PAD_DISP2_DAT13__DISP2_DAT13       0x5
+                               MX51_PAD_DISP2_DAT14__DISP2_DAT14       0x5
+                               MX51_PAD_DISP2_DAT15__DISP2_DAT15       0x5
+                               MX51_PAD_DI2_PIN2__DI2_PIN2             0x5
+                               MX51_PAD_DI2_PIN3__DI2_PIN3             0x5
+                               MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK     0x5
+                               MX51_PAD_DI_GP4__DI2_PIN15              0x5
+                       >;
+               };
+
+               pinctrl_kpp: kppgrp {
+                       fsl,pins = <
+                               MX51_PAD_KEY_ROW0__KEY_ROW0             0xe0
+                               MX51_PAD_KEY_ROW1__KEY_ROW1             0xe0
+                               MX51_PAD_KEY_ROW2__KEY_ROW2             0xe0
+                               MX51_PAD_KEY_ROW3__KEY_ROW3             0xe0
+                               MX51_PAD_KEY_COL0__KEY_COL0             0xe8
+                               MX51_PAD_KEY_COL1__KEY_COL1             0xe8
+                               MX51_PAD_KEY_COL2__KEY_COL2             0xe8
+                               MX51_PAD_KEY_COL3__KEY_COL3             0xe8
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX51_PAD_UART1_RXD__UART1_RXD           0x1c5
+                               MX51_PAD_UART1_TXD__UART1_TXD           0x1c5
+                               MX51_PAD_UART1_RTS__UART1_RTS           0x1c5
+                               MX51_PAD_UART1_CTS__UART1_CTS           0x1c5
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX51_PAD_UART2_RXD__UART2_RXD           0x1c5
+                               MX51_PAD_UART2_TXD__UART2_TXD           0x1c5
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX51_PAD_EIM_D25__UART3_RXD             0x1c5
+                               MX51_PAD_EIM_D26__UART3_TXD             0x1c5
+                               MX51_PAD_EIM_D27__UART3_RTS             0x1c5
+                               MX51_PAD_EIM_D24__UART3_CTS             0x1c5
+                       >;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1 &pinctrl_uart1_rtscts_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        sgtl5000: codec@0a {
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "mii";
+       phy-reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <1>;
        status = "okay";
 };
 
 &kpp {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_kpp_1>;
-       linux,keymap = <0x00000067      /* KEY_UP */
-                       0x0001006c      /* KEY_DOWN */
-                       0x00020072      /* KEY_VOLUMEDOWN */
-                       0x00030066      /* KEY_HOME */
-                       0x0100006a      /* KEY_RIGHT */
-                       0x01010069      /* KEY_LEFT */
-                       0x0102001c      /* KEY_ENTER */
-                       0x01030073      /* KEY_VOLUMEUP */
-                       0x02000040      /* KEY_F6 */
-                       0x02010042      /* KEY_F8 */
-                       0x02020043      /* KEY_F9 */
-                       0x02030044      /* KEY_F10 */
-                       0x0300003b      /* KEY_F1 */
-                       0x0301003c      /* KEY_F2 */
-                       0x0302003d      /* KEY_F3 */
-                       0x03030074>;    /* KEY_POWER */
+       pinctrl-0 = <&pinctrl_kpp>;
+       linux,keymap = <
+               MATRIX_KEY(0, 0, KEY_UP)
+               MATRIX_KEY(0, 1, KEY_DOWN)
+               MATRIX_KEY(0, 2, KEY_VOLUMEDOWN)
+               MATRIX_KEY(0, 3, KEY_HOME)
+               MATRIX_KEY(1, 0, KEY_RIGHT)
+               MATRIX_KEY(1, 1, KEY_LEFT)
+               MATRIX_KEY(1, 2, KEY_ENTER)
+               MATRIX_KEY(1, 3, KEY_VOLUMEUP)
+               MATRIX_KEY(2, 0, KEY_F6)
+               MATRIX_KEY(2, 1, KEY_F8)
+               MATRIX_KEY(2, 2, KEY_F9)
+               MATRIX_KEY(2, 3, KEY_F10)
+               MATRIX_KEY(3, 0, KEY_F1)
+               MATRIX_KEY(3, 1, KEY_F2)
+               MATRIX_KEY(3, 2, KEY_F3)
+               MATRIX_KEY(3, 3, KEY_POWER)
+               >;
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
new file mode 100644 (file)
index 0000000..9b3acf6
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "imx51.dtsi"
+
+/ {
+       model = "Eukrea CPUIMX51";
+       compatible = "eukrea,cpuimx51", "fsl,imx51";
+
+       memory {
+               reg = <0x90000000 0x10000000>; /* 256M */
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&iomuxc {
+       imx51-eukrea {
+               pinctrl_tsc2007_1: tsc2007grp-1 {
+                       fsl,pins = <
+                               MX51_PAD_GPIO_NAND__GPIO_NAND 0x1f5
+                               MX51_PAD_NANDF_D8__GPIO4_0 0x1f5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX51_PAD_DI_GP3__FEC_TX_ER              0x80000000
+                               MX51_PAD_DI2_PIN4__FEC_CRS              0x80000000
+                               MX51_PAD_DI2_PIN2__FEC_MDC              0x80000000
+                               MX51_PAD_DI2_PIN3__FEC_MDIO             0x80000000
+                               MX51_PAD_DI2_DISP_CLK__FEC_RDATA1       0x80000000
+                               MX51_PAD_DI_GP4__FEC_RDATA2             0x80000000
+                               MX51_PAD_DISP2_DAT0__FEC_RDATA3         0x80000000
+                               MX51_PAD_DISP2_DAT1__FEC_RX_ER          0x80000000
+                               MX51_PAD_DISP2_DAT6__FEC_TDATA1         0x80000000
+                               MX51_PAD_DISP2_DAT7__FEC_TDATA2         0x80000000
+                               MX51_PAD_DISP2_DAT8__FEC_TDATA3         0x80000000
+                               MX51_PAD_DISP2_DAT9__FEC_TX_EN          0x80000000
+                               MX51_PAD_DISP2_DAT10__FEC_COL           0x80000000
+                               MX51_PAD_DISP2_DAT11__FEC_RX_CLK        0x80000000
+                               MX51_PAD_DISP2_DAT12__FEC_RX_DV         0x80000000
+                               MX51_PAD_DISP2_DAT13__FEC_TX_CLK        0x80000000
+                               MX51_PAD_DISP2_DAT14__FEC_RDATA0        0x80000000
+                               MX51_PAD_DISP2_DAT15__FEC_TDATA0        0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX51_PAD_SD2_CMD__I2C1_SCL              0x400001ed
+                               MX51_PAD_SD2_CLK__I2C1_SDA              0x400001ed
+                       >;
+               };
+       };
+};
+
+&nfc {
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts
new file mode 100644 (file)
index 0000000..5cec4f3
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2013 Eukréa Electromatique <denis@eukrea.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/dts-v1/;
+#include "imx51-eukrea-cpuimx51.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Eukrea CPUIMX51";
+       compatible = "eukrea,mbimxsd51","eukrea,cpuimx51", "fsl,imx51";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiokeys_1>;
+
+               button-1 {
+                       label = "BP1";
+                       gpios = <&gpio3 31 GPIO_ACTIVE_LOW>;
+                       linux,code = <256>;
+                       gpio-key,wakeup;
+                       linux,input-type = <1>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpioled>;
+
+               led1 {
+                       label = "led1";
+                       gpios = <&gpio3 30 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       sound {
+               compatible = "eukrea,asoc-tlv320";
+               eukrea,model = "imx51-eukrea-tlv320aic23";
+               ssi-controller = <&ssi2>;
+               fsl,mux-int-port = <2>;
+               fsl,mux-ext-port = <3>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1 &pinctrl_esdhc1_cd>;
+       fsl,cd-controller;
+       status = "okay";
+};
+
+&i2c1 {
+       tlv320aic23: codec@1a {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1a>;
+       };
+};
+
+&iomuxc {
+       imx51-eukrea {
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX51_PAD_AUD3_BB_TXD__AUD3_TXD          0x80000000
+                               MX51_PAD_AUD3_BB_RXD__AUD3_RXD          0x80000000
+                               MX51_PAD_AUD3_BB_CK__AUD3_TXC           0x80000000
+                               MX51_PAD_AUD3_BB_FS__AUD3_TXFS          0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX51_PAD_SD1_CMD__SD1_CMD               0x400020d5
+                               MX51_PAD_SD1_CLK__SD1_CLK               0x20d5
+                               MX51_PAD_SD1_DATA0__SD1_DATA0           0x20d5
+                               MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
+                               MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
+                               MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX51_PAD_UART1_RXD__UART1_RXD           0x1c5
+                               MX51_PAD_UART1_TXD__UART1_TXD           0x1c5
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX51_PAD_UART3_RXD__UART3_RXD           0x1c5
+                               MX51_PAD_UART3_TXD__UART3_TXD           0x1c5
+                       >;
+               };
+
+               pinctrl_uart3_rtscts: uart3rtsctsgrp {
+                       fsl,pins = <
+                               MX51_PAD_KEY_COL4__UART3_RTS            0x1c5
+                               MX51_PAD_KEY_COL5__UART3_CTS            0x1c5
+                       >;
+               };
+
+               pinctrl_backlight_1: backlightgrp-1 {
+                       fsl,pins = <
+                               MX51_PAD_DI1_D1_CS__GPIO3_4 0x1f5
+                       >;
+               };
+
+               pinctrl_esdhc1_cd: esdhc1_cd {
+                       fsl,pins = <
+                               MX51_PAD_GPIO1_0__SD1_CD 0x20d5
+                       >;
+               };
+
+               pinctrl_gpiokeys_1: gpiokeysgrp-1 {
+                       fsl,pins = <
+                               MX51_PAD_NANDF_D9__GPIO3_31 0x1f5
+                       >;
+               };
+
+               pinctrl_gpioled: gpioledgrp-1 {
+                       fsl,pins = <
+                               MX51_PAD_NANDF_D10__GPIO3_30 0x80000000
+                       >;
+               };
+
+               pinctrl_reg_lcd_3v3: reg_lcd_3v3 {
+                       fsl,pins = <
+                               MX51_PAD_CSI1_D9__GPIO3_13 0x1f5
+                       >;
+               };
+       };
+};
+
+&ssi2 {
+       codec-handle = <&tlv320aic23>;
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3 &pinctrl_uart3_rtscts>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
index 28c96aada80b6fb6edd531270bac66fe5a8afa01..5f8216d08f6b5f4ff98e13df047ab9b27ee83706 100644 (file)
 
 #include "skeleton.dtsi"
 #include "imx51-pinfunc.h"
+#include <dt-bindings/clock/imx5-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        aliases {
                gpio3 = &gpio4;
                i2c0 = &i2c1;
                i2c1 = &i2c2;
+               mmc0 = &esdhc1;
+               mmc1 = &esdhc2;
+               mmc2 = &esdhc3;
+               mmc3 = &esdhc4;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
-               cpu@0 {
+               cpu: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a8";
                        reg = <0>;
-                       clock-latency = <61036>; /* two CLK32 periods */
-                       clocks = <&clks 24>;
+                       clock-latency = <62500>;
+                       clocks = <&clks IMX5_CLK_CPU_PODF>;
                        clock-names = "cpu";
                        operating-points = <
-                               /* kHz  uV (No regulator support) */
-                               160000  0
-                               800000  0
+                               166000  1000000
+                               600000  1050000
+                               800000  1100000
                        >;
+                       voltage-tolerance = <5>;
+               };
+       };
+
+       usbphy {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "simple-bus";
+
+               usbphy0: usbphy@0 {
+                       compatible = "usb-nop-xceiv";
+                       reg = <0>;
+                       clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
+                       clock-names = "main_clk";
                };
        };
 
                        compatible = "fsl,imx51-ipu";
                        reg = <0x40000000 0x20000000>;
                        interrupts = <11 10>;
-                       clocks = <&clks 59>, <&clks 110>, <&clks 61>;
+                       clocks = <&clks IMX5_CLK_IPU_GATE>,
+                                <&clks IMX5_CLK_IPU_DI0_GATE>,
+                                <&clks IMX5_CLK_IPU_DI1_GATE>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 2>;
 
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70004000 0x4000>;
                                        interrupts = <1>;
-                                       clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+                                       clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC1_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70008000 0x4000>;
                                        interrupts = <2>;
-                                       clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+                                       clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC2_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx51-uart", "fsl,imx21-uart";
                                        reg = <0x7000c000 0x4000>;
                                        interrupts = <33>;
-                                       clocks = <&clks 32>, <&clks 33>;
+                                       clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+                                                <&clks IMX5_CLK_UART3_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx51-ecspi";
                                        reg = <0x70010000 0x4000>;
                                        interrupts = <36>;
-                                       clocks = <&clks 51>, <&clks 52>;
+                                       clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+                                                <&clks IMX5_CLK_ECSPI1_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
                                        reg = <0x70014000 0x4000>;
                                        interrupts = <30>;
-                                       clocks = <&clks 49>;
+                                       clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
                                        dmas = <&sdma 24 1 0>,
                                               <&sdma 25 1 0>;
                                        dma-names = "rx", "tx";
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70020000 0x4000>;
                                        interrupts = <3>;
-                                       clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+                                       clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC3_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx51-esdhc";
                                        reg = <0x70024000 0x4000>;
                                        interrupts = <4>;
-                                       clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+                                       clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC4_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                };
                        };
 
-                       usbphy0: usbphy@0 {
-                               compatible = "usb-nop-xceiv";
-                               clocks = <&clks 75>;
-                               clock-names = "main_clk";
-                               status = "okay";
-                       };
-
                        usbotg: usb@73f80000 {
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80000 0x0200>;
                                interrupts = <18>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 0>;
                                fsl,usbphy = <&usbphy0>;
                                status = "disabled";
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80200 0x0200>;
                                interrupts = <14>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 1>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80400 0x0200>;
                                interrupts = <16>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80600 0x0200>;
                                interrupts = <17>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 3>;
                                status = "disabled";
                        };
                                #index-cells = <1>;
                                compatible = "fsl,imx51-usbmisc";
                                reg = <0x73f80800 0x200>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                        };
 
                        gpio1: gpio@73f84000 {
                                compatible = "fsl,imx51-kpp", "fsl,imx21-kpp";
                                reg = <0x73f94000 0x4000>;
                                interrupts = <60>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
                                reg = <0x73f98000 0x4000>;
                                interrupts = <58>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                        };
 
                        wdog2: wdog@73f9c000 {
                                compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
                                reg = <0x73f9c000 0x4000>;
                                interrupts = <59>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-gpt", "fsl,imx31-gpt";
                                reg = <0x73fa0000 0x4000>;
                                interrupts = <39>;
-                               clocks = <&clks 36>, <&clks 41>;
+                               clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+                                        <&clks IMX5_CLK_GPT_HF_GATE>;
                                clock-names = "ipg", "per";
                        };
 
                                #pwm-cells = <2>;
                                compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
                                reg = <0x73fb4000 0x4000>;
-                               clocks = <&clks 37>, <&clks 38>;
+                               clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM1_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <61>;
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
                                reg = <0x73fb8000 0x4000>;
-                               clocks = <&clks 39>, <&clks 40>;
+                               clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM2_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <94>;
                        };
                                compatible = "fsl,imx51-uart", "fsl,imx21-uart";
                                reg = <0x73fbc000 0x4000>;
                                interrupts = <31>;
-                               clocks = <&clks 28>, <&clks 29>;
+                               clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART1_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-uart", "fsl,imx21-uart";
                                reg = <0x73fc0000 0x4000>;
                                interrupts = <32>;
-                               clocks = <&clks 30>, <&clks 31>;
+                               clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-iim", "fsl,imx27-iim";
                                reg = <0x83f98000 0x4000>;
                                interrupts = <69>;
-                               clocks = <&clks 107>;
+                               clocks = <&clks IMX5_CLK_IIM_GATE>;
                        };
 
                        owire: owire@83fa4000 {
                                compatible = "fsl,imx51-owire", "fsl,imx21-owire";
                                reg = <0x83fa4000 0x4000>;
                                interrupts = <88>;
-                               clocks = <&clks 159>;
+                               clocks = <&clks IMX5_CLK_OWIRE_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-ecspi";
                                reg = <0x83fac000 0x4000>;
                                interrupts = <37>;
-                               clocks = <&clks 53>, <&clks 54>;
+                               clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+                                        <&clks IMX5_CLK_ECSPI2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
                                reg = <0x83fb0000 0x4000>;
                                interrupts = <6>;
-                               clocks = <&clks 56>, <&clks 56>;
+                               clocks = <&clks IMX5_CLK_SDMA_GATE>,
+                                        <&clks IMX5_CLK_SDMA_GATE>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
                                compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
                                reg = <0x83fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 55>;
+                               clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+                                        <&clks IMX5_CLK_CSPI_IPG_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
                                reg = <0x83fc4000 0x4000>;
                                interrupts = <63>;
-                               clocks = <&clks 35>;
+                               clocks = <&clks IMX5_CLK_I2C2_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
                                reg = <0x83fc8000 0x4000>;
                                interrupts = <62>;
-                               clocks = <&clks 34>;
+                               clocks = <&clks IMX5_CLK_I2C1_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
                                reg = <0x83fcc000 0x4000>;
                                interrupts = <29>;
-                               clocks = <&clks 48>;
+                               clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
                                dmas = <&sdma 28 0 0>,
                                       <&sdma 29 0 0>;
                                dma-names = "rx", "tx";
                        audmux: audmux@83fd0000 {
                                compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
                                reg = <0x83fd0000 0x4000>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
+                               clock-names = "audmux";
                                status = "disabled";
                        };
 
                                #size-cells = <1>;
                                compatible = "fsl,imx51-weim";
                                reg = <0x83fda000 0x1000>;
-                               clocks = <&clks 57>;
+                               clocks = <&clks IMX5_CLK_EMI_SLOW_GATE>;
                                ranges = <
                                        0 0 0xb0000000 0x08000000
                                        1 0 0xb8000000 0x08000000
                                compatible = "fsl,imx51-nand";
                                reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
                                interrupts = <8>;
-                               clocks = <&clks 60>;
+                               clocks = <&clks IMX5_CLK_NFC_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-pata", "fsl,imx27-pata";
                                reg = <0x83fe0000 0x4000>;
                                interrupts = <70>;
-                               clocks = <&clks 172>;
+                               clocks = <&clks IMX5_CLK_PATA_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
                                reg = <0x83fe8000 0x4000>;
                                interrupts = <96>;
-                               clocks = <&clks 50>;
+                               clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>;
                                dmas = <&sdma 46 0 0>,
                                       <&sdma 47 0 0>;
                                dma-names = "rx", "tx";
                                compatible = "fsl,imx51-fec", "fsl,imx27-fec";
                                reg = <0x83fec000 0x4000>;
                                interrupts = <87>;
-                               clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+                               clocks = <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
                        };
                };
        };
 };
-
-&iomuxc {
-       audmux {
-               pinctrl_audmux_1: audmuxgrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x80000000
-                               MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x80000000
-                               MX51_PAD_AUD3_BB_CK__AUD3_TXC  0x80000000
-                               MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x80000000
-                       >;
-               };
-       };
-
-       fec {
-               pinctrl_fec_1: fecgrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_EB2__FEC_MDIO         0x80000000
-                               MX51_PAD_EIM_EB3__FEC_RDATA1       0x80000000
-                               MX51_PAD_EIM_CS2__FEC_RDATA2       0x80000000
-                               MX51_PAD_EIM_CS3__FEC_RDATA3       0x80000000
-                               MX51_PAD_EIM_CS4__FEC_RX_ER        0x80000000
-                               MX51_PAD_EIM_CS5__FEC_CRS          0x80000000
-                               MX51_PAD_NANDF_RB2__FEC_COL        0x80000000
-                               MX51_PAD_NANDF_RB3__FEC_RX_CLK     0x80000000
-                               MX51_PAD_NANDF_D9__FEC_RDATA0      0x80000000
-                               MX51_PAD_NANDF_D8__FEC_TDATA0      0x80000000
-                               MX51_PAD_NANDF_CS2__FEC_TX_ER      0x80000000
-                               MX51_PAD_NANDF_CS3__FEC_MDC        0x80000000
-                               MX51_PAD_NANDF_CS4__FEC_TDATA1     0x80000000
-                               MX51_PAD_NANDF_CS5__FEC_TDATA2     0x80000000
-                               MX51_PAD_NANDF_CS6__FEC_TDATA3     0x80000000
-                               MX51_PAD_NANDF_CS7__FEC_TX_EN      0x80000000
-                               MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 0x80000000
-                       >;
-               };
-
-               pinctrl_fec_2: fecgrp-2 {
-                       fsl,pins = <
-                               MX51_PAD_DI_GP3__FEC_TX_ER        0x80000000
-                               MX51_PAD_DI2_PIN4__FEC_CRS        0x80000000
-                               MX51_PAD_DI2_PIN2__FEC_MDC        0x80000000
-                               MX51_PAD_DI2_PIN3__FEC_MDIO       0x80000000
-                               MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x80000000
-                               MX51_PAD_DI_GP4__FEC_RDATA2       0x80000000
-                               MX51_PAD_DISP2_DAT0__FEC_RDATA3   0x80000000
-                               MX51_PAD_DISP2_DAT1__FEC_RX_ER    0x80000000
-                               MX51_PAD_DISP2_DAT6__FEC_TDATA1   0x80000000
-                               MX51_PAD_DISP2_DAT7__FEC_TDATA2   0x80000000
-                               MX51_PAD_DISP2_DAT8__FEC_TDATA3   0x80000000
-                               MX51_PAD_DISP2_DAT9__FEC_TX_EN    0x80000000
-                               MX51_PAD_DISP2_DAT10__FEC_COL     0x80000000
-                               MX51_PAD_DISP2_DAT11__FEC_RX_CLK  0x80000000
-                               MX51_PAD_DISP2_DAT12__FEC_RX_DV   0x80000000
-                               MX51_PAD_DISP2_DAT13__FEC_TX_CLK  0x80000000
-                               MX51_PAD_DISP2_DAT14__FEC_RDATA0  0x80000000
-                               MX51_PAD_DISP2_DAT15__FEC_TDATA0  0x80000000
-                       >;
-               };
-       };
-
-       ecspi1 {
-               pinctrl_ecspi1_1: ecspi1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
-                               MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
-                               MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
-                       >;
-               };
-       };
-
-       ecspi2 {
-               pinctrl_ecspi2_1: ecspi2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_NANDF_RB3__ECSPI2_MISO 0x185
-                               MX51_PAD_NANDF_D15__ECSPI2_MOSI 0x185
-                               MX51_PAD_NANDF_RB2__ECSPI2_SCLK 0x185
-                       >;
-               };
-       };
-
-       esdhc1 {
-               pinctrl_esdhc1_1: esdhc1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_SD1_CMD__SD1_CMD     0x400020d5
-                               MX51_PAD_SD1_CLK__SD1_CLK     0x20d5
-                               MX51_PAD_SD1_DATA0__SD1_DATA0 0x20d5
-                               MX51_PAD_SD1_DATA1__SD1_DATA1 0x20d5
-                               MX51_PAD_SD1_DATA2__SD1_DATA2 0x20d5
-                               MX51_PAD_SD1_DATA3__SD1_DATA3 0x20d5
-                       >;
-               };
-       };
-
-       esdhc2 {
-               pinctrl_esdhc2_1: esdhc2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_SD2_CMD__SD2_CMD     0x400020d5
-                               MX51_PAD_SD2_CLK__SD2_CLK     0x20d5
-                               MX51_PAD_SD2_DATA0__SD2_DATA0 0x20d5
-                               MX51_PAD_SD2_DATA1__SD2_DATA1 0x20d5
-                               MX51_PAD_SD2_DATA2__SD2_DATA2 0x20d5
-                               MX51_PAD_SD2_DATA3__SD2_DATA3 0x20d5
-                       >;
-               };
-       };
-
-       i2c2 {
-               pinctrl_i2c2_1: i2c2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_KEY_COL4__I2C2_SCL 0x400001ed
-                               MX51_PAD_KEY_COL5__I2C2_SDA 0x400001ed
-                       >;
-               };
-
-               pinctrl_i2c2_2: i2c2grp-2 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D27__I2C2_SCL 0x400001ed
-                               MX51_PAD_EIM_D24__I2C2_SDA 0x400001ed
-                       >;
-               };
-
-               pinctrl_i2c2_3: i2c2grp-3 {
-                       fsl,pins = <
-                               MX51_PAD_GPIO1_2__I2C2_SCL 0x400001ed
-                               MX51_PAD_GPIO1_3__I2C2_SDA 0x400001ed
-                       >;
-               };
-       };
-
-       ipu_disp1 {
-               pinctrl_ipu_disp1_1: ipudisp1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_DISP1_DAT0__DISP1_DAT0   0x5
-                               MX51_PAD_DISP1_DAT1__DISP1_DAT1   0x5
-                               MX51_PAD_DISP1_DAT2__DISP1_DAT2   0x5
-                               MX51_PAD_DISP1_DAT3__DISP1_DAT3   0x5
-                               MX51_PAD_DISP1_DAT4__DISP1_DAT4   0x5
-                               MX51_PAD_DISP1_DAT5__DISP1_DAT5   0x5
-                               MX51_PAD_DISP1_DAT6__DISP1_DAT6   0x5
-                               MX51_PAD_DISP1_DAT7__DISP1_DAT7   0x5
-                               MX51_PAD_DISP1_DAT8__DISP1_DAT8   0x5
-                               MX51_PAD_DISP1_DAT9__DISP1_DAT9   0x5
-                               MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x5
-                               MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x5
-                               MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x5
-                               MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x5
-                               MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x5
-                               MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x5
-                               MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x5
-                               MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x5
-                               MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x5
-                               MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x5
-                               MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x5
-                               MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x5
-                               MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x5
-                               MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x5
-                               MX51_PAD_DI1_PIN2__DI1_PIN2       0x5 /* hsync */
-                               MX51_PAD_DI1_PIN3__DI1_PIN3       0x5 /* vsync */
-                       >;
-               };
-       };
-
-       ipu_disp2 {
-               pinctrl_ipu_disp2_1: ipudisp2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_DISP2_DAT0__DISP2_DAT0     0x5
-                               MX51_PAD_DISP2_DAT1__DISP2_DAT1     0x5
-                               MX51_PAD_DISP2_DAT2__DISP2_DAT2     0x5
-                               MX51_PAD_DISP2_DAT3__DISP2_DAT3     0x5
-                               MX51_PAD_DISP2_DAT4__DISP2_DAT4     0x5
-                               MX51_PAD_DISP2_DAT5__DISP2_DAT5     0x5
-                               MX51_PAD_DISP2_DAT6__DISP2_DAT6     0x5
-                               MX51_PAD_DISP2_DAT7__DISP2_DAT7     0x5
-                               MX51_PAD_DISP2_DAT8__DISP2_DAT8     0x5
-                               MX51_PAD_DISP2_DAT9__DISP2_DAT9     0x5
-                               MX51_PAD_DISP2_DAT10__DISP2_DAT10   0x5
-                               MX51_PAD_DISP2_DAT11__DISP2_DAT11   0x5
-                               MX51_PAD_DISP2_DAT12__DISP2_DAT12   0x5
-                               MX51_PAD_DISP2_DAT13__DISP2_DAT13   0x5
-                               MX51_PAD_DISP2_DAT14__DISP2_DAT14   0x5
-                               MX51_PAD_DISP2_DAT15__DISP2_DAT15   0x5
-                               MX51_PAD_DI2_PIN2__DI2_PIN2         0x5 /* hsync */
-                               MX51_PAD_DI2_PIN3__DI2_PIN3         0x5 /* vsync */
-                               MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x5 /* CLK */
-                               MX51_PAD_DI_GP4__DI2_PIN15          0x5 /* DE */
-                       >;
-               };
-       };
-
-       kpp {
-               pinctrl_kpp_1: kppgrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_KEY_ROW0__KEY_ROW0 0xe0
-                               MX51_PAD_KEY_ROW1__KEY_ROW1 0xe0
-                               MX51_PAD_KEY_ROW2__KEY_ROW2 0xe0
-                               MX51_PAD_KEY_ROW3__KEY_ROW3 0xe0
-                               MX51_PAD_KEY_COL0__KEY_COL0 0xe8
-                               MX51_PAD_KEY_COL1__KEY_COL1 0xe8
-                               MX51_PAD_KEY_COL2__KEY_COL2 0xe8
-                               MX51_PAD_KEY_COL3__KEY_COL3 0xe8
-                       >;
-               };
-       };
-
-       pata {
-               pinctrl_pata_1: patagrp-1 {
-                       fsl,pins = <
-                               MX51_PAD_NANDF_WE_B__PATA_DIOW     0x2004
-                               MX51_PAD_NANDF_RE_B__PATA_DIOR     0x2004
-                               MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 0x2004
-                               MX51_PAD_NANDF_CLE__PATA_RESET_B   0x2004
-                               MX51_PAD_NANDF_WP_B__PATA_DMACK    0x2004
-                               MX51_PAD_NANDF_RB0__PATA_DMARQ     0x2004
-                               MX51_PAD_NANDF_RB1__PATA_IORDY     0x2004
-                               MX51_PAD_GPIO_NAND__PATA_INTRQ     0x2004
-                               MX51_PAD_NANDF_CS2__PATA_CS_0      0x2004
-                               MX51_PAD_NANDF_CS3__PATA_CS_1      0x2004
-                               MX51_PAD_NANDF_CS4__PATA_DA_0      0x2004
-                               MX51_PAD_NANDF_CS5__PATA_DA_1      0x2004
-                               MX51_PAD_NANDF_CS6__PATA_DA_2      0x2004
-                               MX51_PAD_NANDF_D15__PATA_DATA15    0x2004
-                               MX51_PAD_NANDF_D14__PATA_DATA14    0x2004
-                               MX51_PAD_NANDF_D13__PATA_DATA13    0x2004
-                               MX51_PAD_NANDF_D12__PATA_DATA12    0x2004
-                               MX51_PAD_NANDF_D11__PATA_DATA11    0x2004
-                               MX51_PAD_NANDF_D10__PATA_DATA10    0x2004
-                               MX51_PAD_NANDF_D9__PATA_DATA9      0x2004
-                               MX51_PAD_NANDF_D8__PATA_DATA8      0x2004
-                               MX51_PAD_NANDF_D7__PATA_DATA7      0x2004
-                               MX51_PAD_NANDF_D6__PATA_DATA6     0x2004
-                               MX51_PAD_NANDF_D5__PATA_DATA5     0x2004
-                               MX51_PAD_NANDF_D4__PATA_DATA4     0x2004
-                               MX51_PAD_NANDF_D3__PATA_DATA3     0x2004
-                               MX51_PAD_NANDF_D2__PATA_DATA2     0x2004
-                               MX51_PAD_NANDF_D1__PATA_DATA1     0x2004
-                               MX51_PAD_NANDF_D0__PATA_DATA0     0x2004
-                       >;
-               };
-       };
-
-       uart1 {
-               pinctrl_uart1_1: uart1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_UART1_RXD__UART1_RXD 0x1c5
-                               MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
-                       >;
-               };
-
-               pinctrl_uart1_rtscts_1: uart1rtscts-1 {
-                       fsl,pins = <
-                               MX51_PAD_UART1_RTS__UART1_RTS 0x1c5
-                               MX51_PAD_UART1_CTS__UART1_CTS 0x1c5
-                       >;
-               };
-       };
-
-       uart2 {
-               pinctrl_uart2_1: uart2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_UART2_RXD__UART2_RXD 0x1c5
-                               MX51_PAD_UART2_TXD__UART2_TXD 0x1c5
-                       >;
-               };
-       };
-
-       uart3 {
-               pinctrl_uart3_1: uart3grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D25__UART3_RXD 0x1c5
-                               MX51_PAD_EIM_D26__UART3_TXD 0x1c5
-                       >;
-               };
-
-               pinctrl_uart3_rtscts_1: uart3rtscts-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D27__UART3_RTS 0x1c5
-                               MX51_PAD_EIM_D24__UART3_CTS 0x1c5
-                       >;
-               };
-
-               pinctrl_uart3_2: uart3grp-2 {
-                       fsl,pins = <
-                               MX51_PAD_UART3_RXD__UART3_RXD 0x1c5
-                               MX51_PAD_UART3_TXD__UART3_TXD 0x1c5
-                       >;
-               };
-       };
-
-       usbh1 {
-               pinctrl_usbh1_1: usbh1grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x1e5
-                               MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x1e5
-                               MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x1e5
-                               MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x1e5
-                               MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x1e5
-                               MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x1e5
-                               MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x1e5
-                               MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x1e5
-                               MX51_PAD_USBH1_CLK__USBH1_CLK     0x1e5
-                               MX51_PAD_USBH1_DIR__USBH1_DIR     0x1e5
-                               MX51_PAD_USBH1_NXT__USBH1_NXT     0x1e5
-                               MX51_PAD_USBH1_STP__USBH1_STP     0x1e5
-                       >;
-               };
-       };
-
-       usbh2 {
-               pinctrl_usbh2_1: usbh2grp-1 {
-                       fsl,pins = <
-                               MX51_PAD_EIM_D16__USBH2_DATA0 0x1e5
-                               MX51_PAD_EIM_D17__USBH2_DATA1 0x1e5
-                               MX51_PAD_EIM_D18__USBH2_DATA2 0x1e5
-                               MX51_PAD_EIM_D19__USBH2_DATA3 0x1e5
-                               MX51_PAD_EIM_D20__USBH2_DATA4 0x1e5
-                               MX51_PAD_EIM_D21__USBH2_DATA5 0x1e5
-                               MX51_PAD_EIM_D22__USBH2_DATA6 0x1e5
-                               MX51_PAD_EIM_D23__USBH2_DATA7 0x1e5
-                               MX51_PAD_EIM_A24__USBH2_CLK   0x1e5
-                               MX51_PAD_EIM_A25__USBH2_DIR   0x1e5
-                               MX51_PAD_EIM_A27__USBH2_NXT   0x1e5
-                               MX51_PAD_EIM_A26__USBH2_STP   0x1e5
-                       >;
-               };
-       };
-};
index 174f86938c89c6917b0eccfa13b799cb9c8917ec..e9337ad52f59b2159a9419b7d177f2cf6baccfe3 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_2>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio1 1 0>;
        wp-gpios = <&gpio1 9 0>;
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-ard {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_GPIO_1__GPIO1_1             0x80000000
                                MX53_PAD_EIM_CS1__EMI_WEIM_CS_1      0x80000000
                        >;
                };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA0__ESDHC1_DAT0         0x1d5
+                               MX53_PAD_SD1_DATA1__ESDHC1_DAT1         0x1d5
+                               MX53_PAD_SD1_DATA2__ESDHC1_DAT2         0x1d5
+                               MX53_PAD_SD1_DATA3__ESDHC1_DAT3         0x1d5
+                               MX53_PAD_PATA_DATA8__ESDHC1_DAT4        0x1d5
+                               MX53_PAD_PATA_DATA9__ESDHC1_DAT5        0x1d5
+                               MX53_PAD_PATA_DATA10__ESDHC1_DAT6       0x1d5
+                               MX53_PAD_PATA_DATA11__ESDHC1_DAT7       0x1d5
+                               MX53_PAD_SD1_CMD__ESDHC1_CMD            0x1d5
+                               MX53_PAD_SD1_CLK__ESDHC1_CLK            0x1d5
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DIOW__UART1_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_DMACK__UART1_RXD_MUX      0x1e4
+                       >;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx53-evk.dts b/arch/arm/boot/dts/imx53-evk.dts
deleted file mode 100644 (file)
index 801fda7..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc.
- * Copyright 2011 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/dts-v1/;
-#include "imx53.dtsi"
-
-/ {
-       model = "Freescale i.MX53 Evaluation Kit";
-       compatible = "fsl,imx53-evk", "fsl,imx53";
-
-       memory {
-               reg = <0x70000000 0x80000000>;
-       };
-
-       leds {
-               compatible = "gpio-leds";
-
-               green {
-                       label = "Heartbeat";
-                       gpios = <&gpio7 7 0>;
-                       linux,default-trigger = "heartbeat";
-               };
-       };
-};
-
-&esdhc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
-       cd-gpios = <&gpio3 13 0>;
-       wp-gpios = <&gpio3 14 0>;
-       status = "okay";
-};
-
-&ecspi1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
-       fsl,spi-num-chipselects = <2>;
-       cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
-       status = "okay";
-
-       flash: at45db321d@1 {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
-               spi-max-frequency = <25000000>;
-               reg = <1>;
-
-               partition@0 {
-                       label = "U-Boot";
-                       reg = <0x0 0x40000>;
-                       read-only;
-               };
-
-               partition@40000 {
-                       label = "Kernel";
-                       reg = <0x40000 0x3c0000>;
-               };
-       };
-};
-
-&esdhc3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
-       cd-gpios = <&gpio3 11 0>;
-       wp-gpios = <&gpio3 12 0>;
-       status = "okay";
-};
-
-&iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_hog>;
-
-       hog {
-               pinctrl_hog: hoggrp {
-                       fsl,pins = <
-                               MX53_PAD_EIM_EB2__GPIO2_30  0x80000000
-                               MX53_PAD_EIM_D19__GPIO3_19  0x80000000
-                               MX53_PAD_EIM_DA11__GPIO3_11 0x80000000
-                               MX53_PAD_EIM_DA12__GPIO3_12 0x80000000
-                               MX53_PAD_EIM_DA13__GPIO3_13 0x80000000
-                               MX53_PAD_EIM_DA14__GPIO3_14 0x80000000
-                               MX53_PAD_PATA_DA_0__GPIO7_6 0x80000000
-                               MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000
-                       >;
-               };
-       };
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
-       status = "okay";
-};
-
-&i2c2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
-       status = "okay";
-
-       pmic: mc13892@08 {
-               compatible = "fsl,mc13892", "fsl,mc13xxx";
-               reg = <0x08>;
-       };
-
-       codec: sgtl5000@0a {
-               compatible = "fsl,sgtl5000";
-               reg = <0x0a>;
-       };
-};
-
-&fec {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
-       phy-mode = "rmii";
-       phy-reset-gpios = <&gpio7 6 0>;
-       status = "okay";
-};
index 0298adc73bb700739c29bd34b1259ad12a0f1e31..f6d3ac3e55872657601c8a1785c8dd1e65707632 100644 (file)
@@ -25,7 +25,7 @@
                        compatible = "fsl,imx-parallel-display";
                        interface-pix-fmt = "bgr666";
                        pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+                       pinctrl-0 = <&pinctrl_ipu_disp1>;
 
                        display-timings {
                                800x480p60 {
@@ -56,6 +56,7 @@
                pwms = <&pwm1 0 3000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
+               power-supply = <&reg_backlight>;
        };
 
        leds {
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p2v: 3p2v {
+               reg_3p2v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P2V";
                        regulator-min-microvolt = <3200000>;
                        regulator-max-microvolt = <3200000>;
                        regulator-always-on;
                };
+
+
+               reg_backlight: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "lcd-supply";
+                       regulator-min-microvolt = <3200000>;
+                       regulator-max-microvolt = <3200000>;
+                       regulator-always-on;
+               };
+
+               reg_usbh1_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio1 2 0>;
+               };
        };
 
        sound {
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &can1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can1_3>;
+       pinctrl-0 = <&pinctrl_can1>;
        status = "okay";
 };
 
 &can2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can2_1>;
+       pinctrl-0 = <&pinctrl_can2>;
        status = "okay";
 };
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio1 1 0>;
        wp-gpios = <&gpio1 9 0>;
        status = "okay";
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        status = "okay";
 };
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_2>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        sgtl5000: codec@0a {
                reg = <0x0a>;
                VDDA-supply = <&reg_3p2v>;
                VDDIO-supply = <&reg_3p2v>;
-               clocks = <&clks 150>;
+               clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
        };
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_2>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        clock-frequency = <400000>;
        status = "okay";
 
 
 &i2c3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_1>;
+       pinctrl-0 = <&pinctrl_i2c3>;
        status = "okay";
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-m53evk {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK       0x80000000
                                MX53_PAD_EIM_EB3__GPIO2_31              0x80000000
                                MX53_PAD_PATA_DA_0__GPIO7_6             0x80000000
-                               MX53_PAD_DISP0_DAT8__PWM1_PWMO          0x5
-
+                               MX53_PAD_GPIO_2__GPIO1_2                0x80000000
+                               MX53_PAD_GPIO_3__USBOH3_USBH1_OC        0x80000000
                        >;
                };
 
                                MX53_PAD_PATA_DATA9__GPIO2_9            0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC     0x80000000
+                               MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD     0x80000000
+                               MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS    0x80000000
+                               MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD     0x80000000
+                       >;
+               };
+
+               pinctrl_can1: can1grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_7__CAN1_TXCAN             0x80000000
+                               MX53_PAD_GPIO_8__CAN1_RXCAN             0x80000000
+                       >;
+               };
+
+               pinctrl_can2: can2grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL4__CAN2_TXCAN           0x80000000
+                               MX53_PAD_KEY_ROW4__CAN2_RXCAN           0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA0__ESDHC1_DAT0         0x1d5
+                               MX53_PAD_SD1_DATA1__ESDHC1_DAT1         0x1d5
+                               MX53_PAD_SD1_DATA2__ESDHC1_DAT2         0x1d5
+                               MX53_PAD_SD1_DATA3__ESDHC1_DAT3         0x1d5
+                               MX53_PAD_SD1_CMD__ESDHC1_CMD            0x1d5
+                               MX53_PAD_SD1_CLK__ESDHC1_CLK            0x1d5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX53_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX53_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX53_PAD_FEC_REF_CLK__FEC_TX_CLK        0x80000000
+                               MX53_PAD_FEC_RX_ER__FEC_RX_ER           0x80000000
+                               MX53_PAD_FEC_CRS_DV__FEC_RX_DV          0x80000000
+                               MX53_PAD_FEC_RXD1__FEC_RDATA_1          0x80000000
+                               MX53_PAD_FEC_RXD0__FEC_RDATA_0          0x80000000
+                               MX53_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX53_PAD_FEC_TXD1__FEC_TDATA_1          0x80000000
+                               MX53_PAD_FEC_TXD0__FEC_TDATA_0          0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D21__I2C1_SCL              0xc0000000
+                               MX53_PAD_EIM_D28__I2C1_SDA              0xc0000000
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D16__I2C2_SDA              0xc0000000
+                               MX53_PAD_EIM_EB2__I2C2_SCL              0xc0000000
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_6__I2C3_SDA               0xc0000000
+                               MX53_PAD_GPIO_5__I2C3_SCL               0xc0000000
+                       >;
+               };
+
+               pinctrl_ipu_disp1: ipudisp1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0       0x5
+                               MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1       0x5
+                               MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2       0x5
+                               MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3       0x5
+                               MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4       0x5
+                               MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5       0x5
+                               MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6       0x5
+                               MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7       0x5
+                               MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8       0x5
+                               MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9       0x5
+                               MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10      0x5
+                               MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11      0x5
+                               MX53_PAD_EIM_A17__IPU_DISP1_DAT_12      0x5
+                               MX53_PAD_EIM_A18__IPU_DISP1_DAT_13      0x5
+                               MX53_PAD_EIM_A19__IPU_DISP1_DAT_14      0x5
+                               MX53_PAD_EIM_A20__IPU_DISP1_DAT_15      0x5
+                               MX53_PAD_EIM_A21__IPU_DISP1_DAT_16      0x5
+                               MX53_PAD_EIM_A22__IPU_DISP1_DAT_17      0x5
+                               MX53_PAD_EIM_A23__IPU_DISP1_DAT_18      0x5
+                               MX53_PAD_EIM_A24__IPU_DISP1_DAT_19      0x5
+                               MX53_PAD_EIM_D31__IPU_DISP1_DAT_20      0x5
+                               MX53_PAD_EIM_D30__IPU_DISP1_DAT_21      0x5
+                               MX53_PAD_EIM_D26__IPU_DISP1_DAT_22      0x5
+                               MX53_PAD_EIM_D27__IPU_DISP1_DAT_23      0x5
+                               MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK      0x5
+                               MX53_PAD_EIM_DA13__IPU_DI1_D0_CS        0x5
+                               MX53_PAD_EIM_DA14__IPU_DI1_D1_CS        0x5
+                               MX53_PAD_EIM_DA15__IPU_DI1_PIN1         0x5
+                               MX53_PAD_EIM_DA11__IPU_DI1_PIN2         0x5
+                               MX53_PAD_EIM_DA12__IPU_DI1_PIN3         0x5
+                               MX53_PAD_EIM_A25__IPU_DI1_PIN12         0x5
+                               MX53_PAD_EIM_DA10__IPU_DI1_PIN15        0x5
+                       >;
+               };
+
+               pinctrl_nand: nandgrp {
+                       fsl,pins = <
+                               MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B     0x4
+                               MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B     0x4
+                               MX53_PAD_NANDF_CLE__EMI_NANDF_CLE       0x4
+                               MX53_PAD_NANDF_ALE__EMI_NANDF_ALE       0x4
+                               MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B     0xe0
+                               MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0      0xe0
+                               MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0      0x4
+                               MX53_PAD_PATA_DATA0__EMI_NANDF_D_0      0xa4
+                               MX53_PAD_PATA_DATA1__EMI_NANDF_D_1      0xa4
+                               MX53_PAD_PATA_DATA2__EMI_NANDF_D_2      0xa4
+                               MX53_PAD_PATA_DATA3__EMI_NANDF_D_3      0xa4
+                               MX53_PAD_PATA_DATA4__EMI_NANDF_D_4      0xa4
+                               MX53_PAD_PATA_DATA5__EMI_NANDF_D_5      0xa4
+                               MX53_PAD_PATA_DATA6__EMI_NANDF_D_6      0xa4
+                               MX53_PAD_PATA_DATA7__EMI_NANDF_D_7      0xa4
+                       >;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <
+                               MX53_PAD_DISP0_DAT8__PWM1_PWMO          0x5
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DIOW__UART1_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_DMACK__UART1_RXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX  0x1e4
+                               MX53_PAD_PATA_DMARQ__UART2_TXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_CS_0__UART3_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_CS_1__UART3_RXD_MUX       0x1e4
+                               MX53_PAD_PATA_DA_1__UART3_CTS           0x1e4
+                               MX53_PAD_PATA_DA_2__UART3_RTS           0x1e4
+                       >;
+               };
        };
 };
 
 
 &nfc {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_nand_1>;
+       pinctrl-0 = <&pinctrl_nand>;
        nand-bus-width = <8>;
        nand-ecc-mode = "hw";
        status = "okay";
 
 &pwm1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm1_1>;
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
+&sata {
        status = "okay";
 };
 
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1>;
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usbh1_vbus>;
+       phy_type = "utmi";
+       status = "okay";
+};
+
+&usbotg {
+       dr_mode = "peripheral";
        status = "okay";
 };
index a5b55c6035918a2e7554104cc6ab07806588b8b3..7c8c129698929151512f282c5baad14c69f51309 100644 (file)
        model = "TQ MBa53 starter kit";
        compatible = "tq,mba53", "tq,tqma53", "fsl,imx53";
 
-       reg_backlight: fixed@0 {
-               compatible = "regulator-fixed";
-               regulator-name = "lcd-supply";
-               gpio = <&gpio2 5 0>;
-               startup-delay-us = <5000>;
-               enable-active-low;
-       };
-
        backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm2 0 50000>;
                };
        };
 
-       reg_3p2v: 3p2v {
-               compatible = "regulator-fixed";
-               regulator-name = "3P2V";
-               regulator-min-microvolt = <3200000>;
-               regulator-max-microvolt = <3200000>;
-               regulator-always-on;
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_backlight: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "lcd-supply";
+                       gpio = <&gpio2 5 0>;
+                       startup-delay-us = <5000>;
+               };
+
+               reg_3p2v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P2V";
+                       regulator-min-microvolt = <3200000>;
+                       regulator-max-microvolt = <3200000>;
+                       regulator-always-on;
+               };
        };
 
        sound {
 &audmux {
        status = "okay";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
+       pinctrl-0 = <&pinctrl_audmux>;
 };
 
 &i2c2 {
        codec: sgtl5000@a {
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
-               clocks = <&clks 150>;
+               clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
                VDDA-supply = <&reg_3p2v>;
                VDDIO-supply = <&reg_3p2v>;
        };
diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi
new file mode 100644 (file)
index 0000000..3f825a6
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "imx53.dtsi"
+
+/ {
+       memory {
+               reg = <0x70000000 0x40000000>;
+       };
+
+       display0: display@di0 {
+               compatible = "fsl,imx-parallel-display";
+               interface-pix-fmt = "rgb565";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ipu_disp0>;
+               status = "disabled";
+               display-timings {
+                       claawvga {
+                               native-mode;
+                               clock-frequency = <27000000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hback-porch = <40>;
+                               hfront-porch = <60>;
+                               vback-porch = <10>;
+                               vfront-porch = <10>;
+                               hsync-len = <20>;
+                               vsync-len = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <0>;
+                       };
+               };
+
+               port {
+                       display0_in: endpoint {
+                               remote-endpoint = <&ipu_di0_disp0>;
+                       };
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "Power Button";
+                       gpios = <&gpio1 8 0>;
+                       linux,code = <116>; /* KEY_POWER */
+               };
+
+               volume-up {
+                       label = "Volume Up";
+                       gpios = <&gpio2 14 0>;
+                       linux,code = <115>; /* KEY_VOLUMEUP */
+                       gpio-key,wakeup;
+               };
+
+               volume-down {
+                       label = "Volume Down";
+                       gpios = <&gpio2 15 0>;
+                       linux,code = <114>; /* KEY_VOLUMEDOWN */
+                       gpio-key,wakeup;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pin_gpio7_7>;
+
+               user {
+                       label = "Heartbeat";
+                       gpios = <&gpio7 7 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p2v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P2V";
+                       regulator-min-microvolt = <3200000>;
+                       regulator-max-microvolt = <3200000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio7 8 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx53-qsb-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx53-qsb-sgtl5000";
+               ssi-controller = <&ssi2>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <2>;
+               mux-ext-port = <5>;
+       };
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       status = "okay";
+};
+
+&ipu_di0_disp0 {
+       remote-endpoint = <&display0_in>;
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&esdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc3>;
+       cd-gpios = <&gpio3 11 0>;
+       wp-gpios = <&gpio3 12 0>;
+       bus-width = <8>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx53-qsb {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000
+                               MX53_PAD_GPIO_8__GPIO1_8          0x80000000
+                               MX53_PAD_PATA_DATA14__GPIO2_14    0x80000000
+                               MX53_PAD_PATA_DATA15__GPIO2_15    0x80000000
+                               MX53_PAD_EIM_DA11__GPIO3_11       0x80000000
+                               MX53_PAD_EIM_DA12__GPIO3_12       0x80000000
+                               MX53_PAD_PATA_DA_0__GPIO7_6       0x80000000
+                               MX53_PAD_PATA_DA_2__GPIO7_8       0x80000000
+                               MX53_PAD_GPIO_16__GPIO7_11        0x80000000
+                       >;
+               };
+
+               led_pin_gpio7_7: led_gpio7_7@0 {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000
+                       >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC      0x80000000
+                               MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD      0x80000000
+                               MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS     0x80000000
+                               MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD      0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA0__ESDHC1_DAT0         0x1d5
+                               MX53_PAD_SD1_DATA1__ESDHC1_DAT1         0x1d5
+                               MX53_PAD_SD1_DATA2__ESDHC1_DAT2         0x1d5
+                               MX53_PAD_SD1_DATA3__ESDHC1_DAT3         0x1d5
+                               MX53_PAD_SD1_CMD__ESDHC1_CMD            0x1d5
+                               MX53_PAD_SD1_CLK__ESDHC1_CLK            0x1d5
+                       >;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DATA8__ESDHC3_DAT0        0x1d5
+                               MX53_PAD_PATA_DATA9__ESDHC3_DAT1        0x1d5
+                               MX53_PAD_PATA_DATA10__ESDHC3_DAT2       0x1d5
+                               MX53_PAD_PATA_DATA11__ESDHC3_DAT3       0x1d5
+                               MX53_PAD_PATA_DATA0__ESDHC3_DAT4        0x1d5
+                               MX53_PAD_PATA_DATA1__ESDHC3_DAT5        0x1d5
+                               MX53_PAD_PATA_DATA2__ESDHC3_DAT6        0x1d5
+                               MX53_PAD_PATA_DATA3__ESDHC3_DAT7        0x1d5
+                               MX53_PAD_PATA_RESET_B__ESDHC3_CMD       0x1d5
+                               MX53_PAD_PATA_IORDY__ESDHC3_CLK         0x1d5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX53_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX53_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX53_PAD_FEC_REF_CLK__FEC_TX_CLK        0x80000000
+                               MX53_PAD_FEC_RX_ER__FEC_RX_ER           0x80000000
+                               MX53_PAD_FEC_CRS_DV__FEC_RX_DV          0x80000000
+                               MX53_PAD_FEC_RXD1__FEC_RDATA_1          0x80000000
+                               MX53_PAD_FEC_RXD0__FEC_RDATA_0          0x80000000
+                               MX53_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX53_PAD_FEC_TXD1__FEC_TDATA_1          0x80000000
+                               MX53_PAD_FEC_TXD0__FEC_TDATA_0          0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT8__I2C1_SDA            0xc0000000
+                               MX53_PAD_CSI0_DAT9__I2C1_SCL            0xc0000000
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_ROW3__I2C2_SDA             0xc0000000
+                               MX53_PAD_KEY_COL3__I2C2_SCL             0xc0000000
+                       >;
+               };
+
+               pinctrl_ipu_disp0: ipudisp0grp {
+                       fsl,pins = <
+                               MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5
+                               MX53_PAD_DI0_PIN15__IPU_DI0_PIN15       0x5
+                               MX53_PAD_DI0_PIN2__IPU_DI0_PIN2         0x5
+                               MX53_PAD_DI0_PIN3__IPU_DI0_PIN3         0x5
+                               MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0    0x5
+                               MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1    0x5
+                               MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2    0x5
+                               MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3    0x5
+                               MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4    0x5
+                               MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5    0x5
+                               MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6    0x5
+                               MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7    0x5
+                               MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8    0x5
+                               MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9    0x5
+                               MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10  0x5
+                               MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11  0x5
+                               MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12  0x5
+                               MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13  0x5
+                               MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14  0x5
+                               MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15  0x5
+                               MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16  0x5
+                               MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17  0x5
+                               MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18  0x5
+                               MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19  0x5
+                               MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20  0x5
+                               MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21  0x5
+                               MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22  0x5
+                               MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23  0x5
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT10__UART1_TXD_MUX      0x1e4
+                               MX53_PAD_CSI0_DAT11__UART1_RXD_MUX      0x1e4
+                       >;
+               };
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       sgtl5000: codec@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_3p2v>;
+               VDDIO-supply = <&reg_3p2v>;
+               clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       accelerometer: mma8450@1c {
+               compatible = "fsl,mma8450";
+               reg = <0x1c>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "rmii";
+       phy-reset-gpios = <&gpio7 6 0>;
+       status = "okay";
+};
+
+&sata {
+       status = "okay";
+};
+
+&vpu {
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_vbus>;
+       phy_type = "utmi";
+       status = "okay";
+};
+
+&usbotg {
+       dr_mode = "peripheral";
+       status = "okay";
+};
index 8b254289344ff44ed189e3d148c3c995060990e5..dec4b073ceb138e93a545815f0dce636cf7f6092 100644 (file)
  */
 
 /dts-v1/;
-#include "imx53.dtsi"
+#include "imx53-qsb-common.dtsi"
 
 / {
        model = "Freescale i.MX53 Quick Start Board";
        compatible = "fsl,imx53-qsb", "fsl,imx53";
-
-       memory {
-               reg = <0x70000000 0x40000000>;
-       };
-
-       display0: display@di0 {
-               compatible = "fsl,imx-parallel-display";
-               interface-pix-fmt = "rgb565";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ipu_disp0_1>;
-               status = "disabled";
-               display-timings {
-                       claawvga {
-                               native-mode;
-                               clock-frequency = <27000000>;
-                               hactive = <800>;
-                               vactive = <480>;
-                               hback-porch = <40>;
-                               hfront-porch = <60>;
-                               vback-porch = <10>;
-                               vfront-porch = <10>;
-                               hsync-len = <20>;
-                               vsync-len = <10>;
-                               hsync-active = <0>;
-                               vsync-active = <0>;
-                               de-active = <1>;
-                               pixelclk-active = <0>;
-                       };
-               };
-
-               port {
-                       display0_in: endpoint {
-                               remote-endpoint = <&ipu_di0_disp0>;
-                       };
-               };
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-
-               power {
-                       label = "Power Button";
-                       gpios = <&gpio1 8 0>;
-                       linux,code = <116>; /* KEY_POWER */
-               };
-
-               volume-up {
-                       label = "Volume Up";
-                       gpios = <&gpio2 14 0>;
-                       linux,code = <115>; /* KEY_VOLUMEUP */
-                       gpio-key,wakeup;
-               };
-
-               volume-down {
-                       label = "Volume Down";
-                       gpios = <&gpio2 15 0>;
-                       linux,code = <114>; /* KEY_VOLUMEDOWN */
-                       gpio-key,wakeup;
-               };
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               pinctrl-names = "default";
-               pinctrl-0 = <&led_pin_gpio7_7>;
-
-               user {
-                       label = "Heartbeat";
-                       gpios = <&gpio7 7 0>;
-                       linux,default-trigger = "heartbeat";
-               };
-       };
-
-       regulators {
-               compatible = "simple-bus";
-
-               reg_3p2v: 3p2v {
-                       compatible = "regulator-fixed";
-                       regulator-name = "3P2V";
-                       regulator-min-microvolt = <3200000>;
-                       regulator-max-microvolt = <3200000>;
-                       regulator-always-on;
-               };
-
-               reg_usb_vbus: usb_vbus {
-                       compatible = "regulator-fixed";
-                       regulator-name = "usb_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio7 8 0>;
-                       enable-active-high;
-               };
-       };
-
-       sound {
-               compatible = "fsl,imx53-qsb-sgtl5000",
-                            "fsl,imx-audio-sgtl5000";
-               model = "imx53-qsb-sgtl5000";
-               ssi-controller = <&ssi2>;
-               audio-codec = <&sgtl5000>;
-               audio-routing =
-                       "MIC_IN", "Mic Jack",
-                       "Mic Jack", "Mic Bias",
-                       "Headphone Jack", "HP_OUT";
-               mux-int-port = <2>;
-               mux-ext-port = <5>;
-       };
-};
-
-&esdhc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
-       status = "okay";
-};
-
-&ipu_di0_disp0 {
-       remote-endpoint = <&display0_in>;
-};
-
-&ssi2 {
-       fsl,mode = "i2s-slave";
-       status = "okay";
-};
-
-&esdhc3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
-       cd-gpios = <&gpio3 11 0>;
-       wp-gpios = <&gpio3 12 0>;
-       bus-width = <8>;
-       status = "okay";
-};
-
-&iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_hog>;
-
-       hog {
-               pinctrl_hog: hoggrp {
-                       fsl,pins = <
-                               MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000
-                               MX53_PAD_GPIO_8__GPIO1_8          0x80000000
-                               MX53_PAD_PATA_DATA14__GPIO2_14    0x80000000
-                               MX53_PAD_PATA_DATA15__GPIO2_15    0x80000000
-                               MX53_PAD_EIM_DA11__GPIO3_11       0x80000000
-                               MX53_PAD_EIM_DA12__GPIO3_12       0x80000000
-                               MX53_PAD_PATA_DA_0__GPIO7_6       0x80000000
-                               MX53_PAD_PATA_DA_2__GPIO7_8       0x80000000
-                               MX53_PAD_GPIO_16__GPIO7_11        0x80000000
-                       >;
-               };
-
-               led_pin_gpio7_7: led_gpio7_7@0 {
-                       fsl,pins = <
-                               MX53_PAD_PATA_DA_1__GPIO7_7 0x80000000
-                       >;
-               };
-       };
-
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
-       status = "okay";
-};
-
-&i2c2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
-       status = "okay";
-
-       sgtl5000: codec@0a {
-               compatible = "fsl,sgtl5000";
-               reg = <0x0a>;
-               VDDA-supply = <&reg_3p2v>;
-               VDDIO-supply = <&reg_3p2v>;
-               clocks = <&clks 150>;
-       };
 };
 
 &i2c1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
-       status = "okay";
-
-       accelerometer: mma8450@1c {
-               compatible = "fsl,mma8450";
-               reg = <0x1c>;
-       };
-
        pmic: dialog@48 {
                compatible = "dlg,da9053-aa", "dlg,da9052";
                reg = <0x48>;
                };
        };
 };
-
-&audmux {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
-       status = "okay";
-};
-
-&fec {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
-       phy-mode = "rmii";
-       phy-reset-gpios = <&gpio7 6 0>;
-       status = "okay";
-};
-
-&vpu {
-       status = "okay";
-};
-
-&usbh1 {
-       vbus-supply = <&reg_usb_vbus>;
-       phy_type = "utmi";
-       status = "okay";
-};
-
-&usbotg {
-       dr_mode = "peripheral";
-       status = "okay";
-};
diff --git a/arch/arm/boot/dts/imx53-qsrb.dts b/arch/arm/boot/dts/imx53-qsrb.dts
new file mode 100644 (file)
index 0000000..f1bbf9a
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+
+#include "imx53-qsb-common.dtsi"
+
+/ {
+       model = "Freescale i.MX53 Quick Start-R Board";
+       compatible = "fsl,imx53-qsrb", "fsl,imx53";
+};
+
+&iomuxc {
+       i2c1 {
+               /* open drain */
+               pinctrl_i2c1_qsrb: i2c1grp-1 {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT8__I2C1_SDA      0x400001ec
+                               MX53_PAD_CSI0_DAT9__I2C1_SCL      0x400001ec
+                       >;
+               };
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1_qsrb>;
+       status = "okay";
+
+       pmic: mc34708@8 {
+               compatible = "fsl,mc34708";
+               reg = <0x08>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <23 0x8>;
+               regulators {
+                       sw1_reg: sw1a {
+                               regulator-name = "SW1";
+                               regulator-min-microvolt = <650000>;
+                               regulator-max-microvolt = <1437500>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw1b_reg: sw1b {
+                               regulator-name = "SW1B";
+                               regulator-min-microvolt = <650000>;
+                               regulator-max-microvolt = <1437500>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-name = "SW2";
+                               regulator-min-microvolt = <650000>;
+                               regulator-max-microvolt = <1437500>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: sw3 {
+                               regulator-name = "SW3";
+                               regulator-min-microvolt = <650000>;
+                               regulator-max-microvolt = <1425000>;
+                               regulator-boot-on;
+                       };
+
+                       sw4a_reg: sw4a {
+                               regulator-name = "SW4A";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4b_reg: sw4b {
+                               regulator-name = "SW4B";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw5_reg: sw5 {
+                               regulator-name = "SW5";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-name = "SWBST";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vpll_reg: vpll {
+                               regulator-name = "VPLL";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                       };
+
+                       vrefddr_reg: vrefddr {
+                               regulator-name = "VREFDDR";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vusb_reg: vusb {
+                               regulator-name = "VUSB";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vusb2_reg: vusb2 {
+                               regulator-name = "VUSB2";
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vdac_reg: vdac {
+                               regulator-name = "VDAC";
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-name = "VGEN1";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1550000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-name = "VGEN2";
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
index a9b6e10de0a5f52ebadb707e1f99179e6e19ae88..5ec1590ff7bcc328540b0c92609c26a75cccc52b 100644 (file)
@@ -40,7 +40,7 @@
 
 &esdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_1>;
+       pinctrl-0 = <&pinctrl_esdhc1>;
        cd-gpios = <&gpio3 13 0>;
        wp-gpios = <&gpio4 11 0>;
        status = "okay";
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
+       pinctrl-0 = <&pinctrl_esdhc2>;
        non-removable;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1>;
+       pinctrl-0 = <&pinctrl_uart3>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <2>;
        cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
        status = "okay";
@@ -95,7 +95,7 @@
 
 &esdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
+       pinctrl-0 = <&pinctrl_esdhc3>;
        non-removable;
        status = "okay";
 };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx53-smd {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX53_PAD_PATA_DATA14__GPIO2_14 0x80000000
                                MX53_PAD_PATA_DA_0__GPIO7_6    0x80000000
                        >;
                };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D16__ECSPI1_SCLK           0x80000000
+                               MX53_PAD_EIM_D17__ECSPI1_MISO           0x80000000
+                               MX53_PAD_EIM_D18__ECSPI1_MOSI           0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA0__ESDHC1_DAT0         0x1d5
+                               MX53_PAD_SD1_DATA1__ESDHC1_DAT1         0x1d5
+                               MX53_PAD_SD1_DATA2__ESDHC1_DAT2         0x1d5
+                               MX53_PAD_SD1_DATA3__ESDHC1_DAT3         0x1d5
+                               MX53_PAD_SD1_CMD__ESDHC1_CMD            0x1d5
+                               MX53_PAD_SD1_CLK__ESDHC1_CLK            0x1d5
+                       >;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <
+                               MX53_PAD_SD2_CMD__ESDHC2_CMD            0x1d5
+                               MX53_PAD_SD2_CLK__ESDHC2_CLK            0x1d5
+                               MX53_PAD_SD2_DATA0__ESDHC2_DAT0         0x1d5
+                               MX53_PAD_SD2_DATA1__ESDHC2_DAT1         0x1d5
+                               MX53_PAD_SD2_DATA2__ESDHC2_DAT2         0x1d5
+                               MX53_PAD_SD2_DATA3__ESDHC2_DAT3         0x1d5
+                       >;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DATA8__ESDHC3_DAT0        0x1d5
+                               MX53_PAD_PATA_DATA9__ESDHC3_DAT1        0x1d5
+                               MX53_PAD_PATA_DATA10__ESDHC3_DAT2       0x1d5
+                               MX53_PAD_PATA_DATA11__ESDHC3_DAT3       0x1d5
+                               MX53_PAD_PATA_DATA0__ESDHC3_DAT4        0x1d5
+                               MX53_PAD_PATA_DATA1__ESDHC3_DAT5        0x1d5
+                               MX53_PAD_PATA_DATA2__ESDHC3_DAT6        0x1d5
+                               MX53_PAD_PATA_DATA3__ESDHC3_DAT7        0x1d5
+                               MX53_PAD_PATA_RESET_B__ESDHC3_CMD       0x1d5
+                               MX53_PAD_PATA_IORDY__ESDHC3_CLK         0x1d5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX53_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX53_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX53_PAD_FEC_REF_CLK__FEC_TX_CLK        0x80000000
+                               MX53_PAD_FEC_RX_ER__FEC_RX_ER           0x80000000
+                               MX53_PAD_FEC_CRS_DV__FEC_RX_DV          0x80000000
+                               MX53_PAD_FEC_RXD1__FEC_RDATA_1          0x80000000
+                               MX53_PAD_FEC_RXD0__FEC_RDATA_0          0x80000000
+                               MX53_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX53_PAD_FEC_TXD1__FEC_TDATA_1          0x80000000
+                               MX53_PAD_FEC_TXD0__FEC_TDATA_0          0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT8__I2C1_SDA            0xc0000000
+                               MX53_PAD_CSI0_DAT9__I2C1_SCL            0xc0000000
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_ROW3__I2C2_SDA             0xc0000000
+                               MX53_PAD_KEY_COL3__I2C2_SCL             0xc0000000
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT10__UART1_TXD_MUX      0x1e4
+                               MX53_PAD_CSI0_DAT11__UART1_RXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX  0x1e4
+                               MX53_PAD_PATA_DMARQ__UART2_TXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_CS_0__UART3_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_CS_1__UART3_RXD_MUX       0x1e4
+                               MX53_PAD_PATA_DA_1__UART3_CTS           0x1e4
+                               MX53_PAD_PATA_DA_2__UART3_RTS           0x1e4
+                       >;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        codec: sgtl5000@0a {
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        accelerometer: mma8450@1c {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        phy-reset-gpios = <&gpio7 6 0>;
        status = "okay";
index abd72af545bf0409ce9556afdb47dcffbf8fcea0..4f1f0e2868bf12816ec93f545a8f592e43e7f64d 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
@@ -35,8 +38,8 @@
 
 &esdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>,
-                   <&pinctrl_tqma53_esdhc2_2>;
+       pinctrl-0 = <&pinctrl_esdhc2>,
+                   <&pinctrl_esdhc2_cdwp>;
        vmmc-supply = <&reg_3p3v>;
        wp-gpios = <&gpio1 2 0>;
        cd-gpios = <&gpio1 4 0>;
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_2>;
+       pinctrl-0 = <&pinctrl_uart3>;
        status = "disabled";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        fsl,spi-num-chipselects = <4>;
        cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>,
                   <&gpio3 24 0>, <&gpio3 25 0>;
@@ -60,7 +63,7 @@
 
 &esdhc3 { /* EMMC */
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc3_1>;
+       pinctrl-0 = <&pinctrl_esdhc3>;
        vmmc-supply = <&reg_3p3v>;
        non-removable;
        bus-width = <8>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       esdhc2_2 {
-               pinctrl_tqma53_esdhc2_2: esdhc2-tqma53-grp2 {
-                       fsl,pins = <
-                               MX53_PAD_GPIO_4__GPIO1_4        0x80000000 /* SD2_CD */
-                               MX53_PAD_GPIO_2__GPIO1_2        0x80000000 /* SD2_WP */
-                       >;
-               };
-       };
-
-       i2s {
-               pinctrl_i2s_1: i2s-grp1 {
-                       fsl,pins = <
-                                MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC  0x80000000 /* I2S_SCLK */
-                                MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD  0x80000000 /* I2S_DOUT */
-                                MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000 /* I2S_LRCLK */
-                                MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x80000000 /* I2S_DIN */
-                       >;
-               };
-       };
-
-       hog {
+       imx53-tqma53 {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                 MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000 /* SSI_MCLK */
                                 MX53_PAD_GPIO_1__PWM2_PWMO      0x80000000 /* LCD_CONTRAST */
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC      0x80000000
+                               MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD      0x80000000
+                               MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS     0x80000000
+                               MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD      0x80000000
+                       >;
+               };
+
+               pinctrl_can1: can1grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL2__CAN1_TXCAN           0x80000000
+                               MX53_PAD_KEY_ROW2__CAN1_RXCAN           0x80000000
+                       >;
+               };
+
+               pinctrl_can2: can2grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL4__CAN2_TXCAN           0x80000000
+                               MX53_PAD_KEY_ROW4__CAN2_RXCAN           0x80000000
+                       >;
+               };
+
+               pinctrl_cspi: cspigrp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA0__CSPI_MISO           0x1d5
+                               MX53_PAD_SD1_CMD__CSPI_MOSI             0x1d5
+                               MX53_PAD_SD1_CLK__CSPI_SCLK             0x1d5
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D16__ECSPI1_SCLK           0x80000000
+                               MX53_PAD_EIM_D17__ECSPI1_MISO           0x80000000
+                               MX53_PAD_EIM_D18__ECSPI1_MOSI           0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <
+                               MX53_PAD_SD2_CMD__ESDHC2_CMD            0x1d5
+                               MX53_PAD_SD2_CLK__ESDHC2_CLK            0x1d5
+                               MX53_PAD_SD2_DATA0__ESDHC2_DAT0         0x1d5
+                               MX53_PAD_SD2_DATA1__ESDHC2_DAT1         0x1d5
+                               MX53_PAD_SD2_DATA2__ESDHC2_DAT2         0x1d5
+                               MX53_PAD_SD2_DATA3__ESDHC2_DAT3         0x1d5
+                       >;
+               };
+
+               pinctrl_esdhc2_cdwp: esdhc2cdwp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_4__GPIO1_4        0x80000000 /* SD2_CD */
+                               MX53_PAD_GPIO_2__GPIO1_2        0x80000000 /* SD2_WP */
+                       >;
+               };
+
+               pinctrl_esdhc3: esdhc3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DATA8__ESDHC3_DAT0        0x1d5
+                               MX53_PAD_PATA_DATA9__ESDHC3_DAT1        0x1d5
+                               MX53_PAD_PATA_DATA10__ESDHC3_DAT2       0x1d5
+                               MX53_PAD_PATA_DATA11__ESDHC3_DAT3       0x1d5
+                               MX53_PAD_PATA_DATA0__ESDHC3_DAT4        0x1d5
+                               MX53_PAD_PATA_DATA1__ESDHC3_DAT5        0x1d5
+                               MX53_PAD_PATA_DATA2__ESDHC3_DAT6        0x1d5
+                               MX53_PAD_PATA_DATA3__ESDHC3_DAT7        0x1d5
+                               MX53_PAD_PATA_RESET_B__ESDHC3_CMD       0x1d5
+                               MX53_PAD_PATA_IORDY__ESDHC3_CLK         0x1d5
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX53_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX53_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX53_PAD_FEC_REF_CLK__FEC_TX_CLK        0x80000000
+                               MX53_PAD_FEC_RX_ER__FEC_RX_ER           0x80000000
+                               MX53_PAD_FEC_CRS_DV__FEC_RX_DV          0x80000000
+                               MX53_PAD_FEC_RXD1__FEC_RDATA_1          0x80000000
+                               MX53_PAD_FEC_RXD0__FEC_RDATA_0          0x80000000
+                               MX53_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX53_PAD_FEC_TXD1__FEC_TDATA_1          0x80000000
+                               MX53_PAD_FEC_TXD0__FEC_TDATA_0          0x80000000
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_ROW3__I2C2_SDA             0xc0000000
+                               MX53_PAD_KEY_COL3__I2C2_SCL             0xc0000000
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_6__I2C3_SDA               0xc0000000
+                               MX53_PAD_GPIO_5__I2C3_SCL               0xc0000000
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DIOW__UART1_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_DMACK__UART1_RXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX  0x1e4
+                               MX53_PAD_PATA_DMARQ__UART2_TXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_CS_0__UART3_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_CS_1__UART3_RXD_MUX       0x1e4
+                       >;
+               };
        };
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>;
+       pinctrl-0 = <&pinctrl_uart1>;
        fsl,uart-has-rtscts;
        status = "disabled";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "disabled";
 };
 
 &can1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can1_2>;
+       pinctrl-0 = <&pinctrl_can1>;
        status = "disabled";
 };
 
 &can2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can2_1>;
+       pinctrl-0 = <&pinctrl_can2>;
        status = "disabled";
 };
 
 &i2c3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_1>;
+       pinctrl-0 = <&pinctrl_i2c3>;
        status = "disabled";
 };
 
 &cspi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_cspi_1>;
+       pinctrl-0 = <&pinctrl_cspi>;
        fsl,spi-num-chipselects = <3>;
        cs-gpios = <&gpio1 18 0>, <&gpio1 19 0>,
                   <&gpio1 21 0>;
 
 &i2c2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_1>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        pmic: mc34708@8 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        status = "disabled";
 };
diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts
new file mode 100644 (file)
index 0000000..0217dde
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2013 Lothar Waßmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53-tx53.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       model = "Ka-Ro electronics TX53 module (LCD)";
+       compatible = "karo,tx53", "fsl,imx53";
+
+       aliases {
+               display = &display;
+       };
+
+       soc {
+               display: display@di0 {
+                       compatible = "fsl,imx-parallel-display";
+                       crtcs = <&ipu 0>;
+                       interface-pix-fmt = "rgb24";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_rgb24_vga1>;
+                       status = "okay";
+
+                       display-timings {
+                               VGA {
+                                       clock-frequency = <25200000>;
+                                       hactive = <640>;
+                                       vactive = <480>;
+                                       hback-porch = <48>;
+                                       hsync-len = <96>;
+                                       hfront-porch = <16>;
+                                       vback-porch = <31>;
+                                       vsync-len = <2>;
+                                       vfront-porch = <12>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <0>;
+                               };
+
+                               ETV570 {
+                                       clock-frequency = <25200000>;
+                                       hactive = <640>;
+                                       vactive = <480>;
+                                       hback-porch = <114>;
+                                       hsync-len = <30>;
+                                       hfront-porch = <16>;
+                                       vback-porch = <32>;
+                                       vsync-len = <3>;
+                                       vfront-porch = <10>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <0>;
+                               };
+
+                               ET0350 {
+                                       clock-frequency = <6413760>;
+                                       hactive = <320>;
+                                       vactive = <240>;
+                                       hback-porch = <34>;
+                                       hsync-len = <34>;
+                                       hfront-porch = <20>;
+                                       vback-porch = <15>;
+                                       vsync-len = <3>;
+                                       vfront-porch = <4>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <0>;
+                               };
+
+                               ET0430 {
+                                       clock-frequency = <9009000>;
+                                       hactive = <480>;
+                                       vactive = <272>;
+                                       hback-porch = <2>;
+                                       hsync-len = <41>;
+                                       hfront-porch = <2>;
+                                       vback-porch = <2>;
+                                       vsync-len = <10>;
+                                       vfront-porch = <2>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <1>;
+                               };
+
+                               ET0500 {
+                                       clock-frequency = <33264000>;
+                                       hactive = <800>;
+                                       vactive = <480>;
+                                       hback-porch = <88>;
+                                       hsync-len = <128>;
+                                       hfront-porch = <40>;
+                                       vback-porch = <33>;
+                                       vsync-len = <2>;
+                                       vfront-porch = <10>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <0>;
+                               };
+
+                               ET0700 { /* same as ET0500 */
+                                       clock-frequency = <33264000>;
+                                       hactive = <800>;
+                                       vactive = <480>;
+                                       hback-porch = <88>;
+                                       hsync-len = <128>;
+                                       hfront-porch = <40>;
+                                       vback-porch = <33>;
+                                       vsync-len = <2>;
+                                       vfront-porch = <10>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <0>;
+                               };
+
+                               ETQ570 {
+                                       clock-frequency = <6596040>;
+                                       hactive = <320>;
+                                       vactive = <240>;
+                                       hback-porch = <38>;
+                                       hsync-len = <30>;
+                                       hfront-porch = <30>;
+                                       vback-porch = <16>;
+                                       vsync-len = <3>;
+                                       vfront-porch = <4>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                                       de-active = <1>;
+                                       pixelclk-active = <0>;
+                               };
+                       };
+               };
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>;
+               power-supply = <&reg_3v3>;
+               brightness-levels = <
+                         0  1  2  3  4  5  6  7  8  9
+                        10 11 12 13 14 15 16 17 18 19
+                        20 21 22 23 24 25 26 27 28 29
+                        30 31 32 33 34 35 36 37 38 39
+                        40 41 42 43 44 45 46 47 48 49
+                        50 51 52 53 54 55 56 57 58 59
+                        60 61 62 63 64 65 66 67 68 69
+                        70 71 72 73 74 75 76 77 78 79
+                        80 81 82 83 84 85 86 87 88 89
+                        90 91 92 93 94 95 96 97 98 99
+                       100
+               >;
+               default-brightness-level = <50>;
+       };
+
+       regulators {
+               reg_lcd_pwr: regulator@5 {
+                       compatible = "regulator-fixed";
+                       reg = <5>;
+                       regulator-name = "LCD POWER";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+               };
+
+               reg_lcd_reset: regulator@6 {
+                       compatible = "regulator-fixed";
+                       reg = <6>;
+                       regulator-name = "LCD RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+               };
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       sgtl5000: codec@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_2v5>;
+               VDDIO-supply = <&reg_3v3>;
+               clocks = <&mclk>;
+       };
+
+       polytouch: edt-ft5x06@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_edt_ft5x06_1>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <15 0>;
+               reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+               wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+       };
+
+       touchscreen: tsc2007@48 {
+               compatible = "ti,tsc2007";
+               reg = <0x48>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_tsc2007>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <26 0>;
+               gpios = <&gpio3 26 GPIO_ACTIVE_LOW>;
+               ti,x-plate-ohms = <660>;
+               linux,wakeup;
+       };
+};
+
+&iomuxc {
+       imx53-tx53-x03x {
+               pinctrl_edt_ft5x06_1: edt-ft5x06grp-1 {
+                       fsl,pins = <
+                               MX53_PAD_NANDF_CS2__GPIO6_15 0x1f0 /* Interrupt */
+                               MX53_PAD_EIM_A16__GPIO2_22   0x04 /* Reset */
+                               MX53_PAD_EIM_A17__GPIO2_21   0x04 /* Wake */
+                       >;
+               };
+
+               pinctrl_kpp: kppgrp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_9__KPP_COL_6 0x1f4
+                               MX53_PAD_GPIO_4__KPP_COL_7 0x1f4
+                               MX53_PAD_KEY_COL2__KPP_COL_2 0x1f4
+                               MX53_PAD_KEY_COL3__KPP_COL_3 0x1f4
+                               MX53_PAD_GPIO_2__KPP_ROW_6 0x1f4
+                               MX53_PAD_GPIO_5__KPP_ROW_7 0x1f4
+                               MX53_PAD_KEY_ROW2__KPP_ROW_2 0x1f4
+                               MX53_PAD_KEY_ROW3__KPP_ROW_3 0x1f4
+                       >;
+               };
+
+               pinctrl_rgb24_vga1: rgb24-vgagrp1 {
+                       fsl,pins = <
+                               MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK         0x5
+                               MX53_PAD_DI0_PIN15__IPU_DI0_PIN15               0x5
+                               MX53_PAD_DI0_PIN2__IPU_DI0_PIN2                 0x5
+                               MX53_PAD_DI0_PIN3__IPU_DI0_PIN3                 0x5
+                               MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0            0x5
+                               MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1            0x5
+                               MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2            0x5
+                               MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3            0x5
+                               MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4            0x5
+                               MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5            0x5
+                               MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6            0x5
+                               MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7            0x5
+                               MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8            0x5
+                               MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9            0x5
+                               MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10          0x5
+                               MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11          0x5
+                               MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12          0x5
+                               MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13          0x5
+                               MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14          0x5
+                               MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15          0x5
+                               MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16          0x5
+                               MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17          0x5
+                               MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18          0x5
+                               MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19          0x5
+                               MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20          0x5
+                               MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21          0x5
+                               MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22          0x5
+                               MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23          0x5
+                       >;
+               };
+
+               pinctrl_tsc2007: tsc2007grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D26__GPIO3_26 0x1f0 /* Interrupt */
+                       >;
+               };
+       };
+};
+
+&kpp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_kpp>;
+       /* sample keymap */
+       /* row/col 0,1 are mapped to KPP row/col 6,7 */
+       linux,keymap = <
+               MATRIX_KEY(6, 6, KEY_POWER)
+               MATRIX_KEY(6, 7, KEY_KP0)
+               MATRIX_KEY(6, 2, KEY_KP1)
+               MATRIX_KEY(6, 3, KEY_KP2)
+               MATRIX_KEY(7, 6, KEY_KP3)
+               MATRIX_KEY(7, 7, KEY_KP4)
+               MATRIX_KEY(7, 2, KEY_KP5)
+               MATRIX_KEY(7, 3, KEY_KP6)
+               MATRIX_KEY(2, 6, KEY_KP7)
+               MATRIX_KEY(2, 7, KEY_KP8)
+               MATRIX_KEY(2, 2, KEY_KP9)
+       >;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-tx53-x13x.dts b/arch/arm/boot/dts/imx53-tx53-x13x.dts
new file mode 100644 (file)
index 0000000..6480471
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2013 Lothar Waßmann <LW@KARO-electronics.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 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53-tx53.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Ka-Ro electronics TX53 module (LVDS)";
+       compatible = "karo,tx53", "fsl,imx53";
+
+       aliases {
+               display = &lvds0;
+               lvds0 = &lvds0;
+               lvds1 = &lvds1;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <&pwm2 0 500000 0>;
+               power-supply = <&reg_3v3>;
+               brightness-levels = <
+                         0  1  2  3  4  5  6  7  8  9
+                        10 11 12 13 14 15 16 17 18 19
+                        20 21 22 23 24 25 26 27 28 29
+                        30 31 32 33 34 35 36 37 38 39
+                        40 41 42 43 44 45 46 47 48 49
+                        50 51 52 53 54 55 56 57 58 59
+                        60 61 62 63 64 65 66 67 68 69
+                        70 71 72 73 74 75 76 77 78 79
+                        80 81 82 83 84 85 86 87 88 89
+                        90 91 92 93 94 95 96 97 98 99
+                       100
+               >;
+               default-brightness-level = <50>;
+       };
+
+       backlight1: backlight1 {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 500000 0>;
+               power-supply = <&reg_3v3>;
+               brightness-levels = <
+                         0  1  2  3  4  5  6  7  8  9
+                        10 11 12 13 14 15 16 17 18 19
+                        20 21 22 23 24 25 26 27 28 29
+                        30 31 32 33 34 35 36 37 38 39
+                        40 41 42 43 44 45 46 47 48 49
+                        50 51 52 53 54 55 56 57 58 59
+                        60 61 62 63 64 65 66 67 68 69
+                        70 71 72 73 74 75 76 77 78 79
+                        80 81 82 83 84 85 86 87 88 89
+                        90 91 92 93 94 95 96 97 98 99
+                       100
+               >;
+               default-brightness-level = <50>;
+       };
+
+       regulators {
+               reg_lcd_pwr0: regulator@5 {
+                       compatible = "regulator-fixed";
+                       reg = <5>;
+                       regulator-name = "LVDS0 POWER";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+               };
+
+               reg_lcd_pwr1: regulator@6 {
+                       compatible = "regulator-fixed";
+                       reg = <6>;
+                       regulator-name = "LVDS1 POWER";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+               };
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       touchscreen2: eeti@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_eeti2>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <23 0>;
+               wakeup-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+               linux,wakeup;
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       sgtl5000: codec@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_2v5>;
+               VDDIO-supply = <&reg_3v3>;
+               clocks = <&mclk>;
+       };
+
+       touchscreen1: eeti@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_eeti1>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <22 0>;
+               wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+               linux,wakeup;
+       };
+};
+
+&iomuxc {
+       imx53-tx53-x13x {
+               pinctrl_i2c2: i2c2-grp1 {
+                       fsl,pins = <
+                               MX53_PAD_KEY_ROW3__I2C2_SDA             0xc0000000
+                               MX53_PAD_KEY_COL3__I2C2_SCL             0xc0000000
+                       >;
+               };
+
+               pinctrl_lvds0: lvds0grp {
+                       fsl,pins = <
+                               MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x80000000
+                               MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x80000000
+                               MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x80000000
+                               MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x80000000
+                               MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x80000000
+                       >;
+               };
+
+               pinctrl_lvds1: lvds1grp {
+                       fsl,pins = <
+                               MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 0x80000000
+                               MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 0x80000000
+                               MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 0x80000000
+                               MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 0x80000000
+                               MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 0x80000000
+                       >;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <MX53_PAD_GPIO_9__PWM1_PWMO 0x04>;
+               };
+
+               pinctrl_eeti1: eeti1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D22__GPIO3_22 0x1f0 /* Interrupt */
+                       >;
+               };
+
+               pinctrl_eeti2: eeti2grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D23__GPIO3_23 0x1f0 /* Interrupt */
+                       >;
+               };
+       };
+};
+
+&ldb {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lvds0 &pinctrl_lvds1>;
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               fsl,data-mapping = "jeida";
+               fsl,data-width = <24>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&lvds_timing0>;
+                       lvds_timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hsync-len = <60>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vsync-len = <10>;
+                               vfront-porch = <7>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <0>;
+                       };
+               };
+       };
+
+       lvds1: lvds-channel@1 {
+               fsl,data-mapping = "jeida";
+               fsl,data-width = <24>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&lvds_timing1>;
+                       lvds_timing1: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hsync-len = <60>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vsync-len = <10>;
+                               vfront-porch = <7>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <0>;
+                       };
+               };
+       };
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+};
+
+&sata {
+       status = "okay";
+};
index f494766700a3d7b48e735ce1dc79fa550036c7a2..e348796ba68957bcfba56d1ab75f5a73374e71c4 100644 (file)
 /*
- * Copyright 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright 2012 <LW@KARO-electronics.de>
+ * based on imx53-qsb.dts
+ *   Copyright 2011 Freescale Semiconductor, Inc.
+ *   Copyright 2011 Linaro Ltd.
  *
  * 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:
+ * Version 2 at the following locations:
  *
  * http://www.opensource.org/licenses/gpl-license.html
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-/include/ "imx53.dtsi"
+#include "imx53.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
-       model = "Ka-Ro TX53";
+       model = "Ka-Ro electronics TX53 module";
        compatible = "karo,tx53", "fsl,imx53";
 
-       memory {
-               reg = <0x70000000 0x40000000>; /* Up to 1GiB */
+       aliases {
+               can0 = &can2; /* Make the can interface indices consistent with TX28/TX48 modules */
+               can1 = &can1;
+               ipu = &ipu;
+               reg_can_xcvr = &reg_can_xcvr;
+               usbh1 = &usbh1;
+               usbotg = &usbotg;
+       };
+
+       clocks {
+               ckih1 {
+                       clock-frequency = <0>;
+               };
+
+               mclk: clock@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <27000000>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_key>;
+
+               power {
+                       label = "Power Button";
+                       gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+                       linux,code = <116>; /* KEY_POWER */
+                       gpio-key,wakeup;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_stk5led>;
+
+               user {
+                       label = "Heartbeat";
+                       gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
        };
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_2v5: regulator@0 {
                        compatible = "regulator-fixed";
-                       regulator-name = "3P3V";
+                       reg = <0>;
+                       regulator-name = "2V5";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+               };
+
+               reg_3v3: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3V3";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
-                       regulator-always-on;
                };
+
+               reg_can_xcvr: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "CAN XCVR";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_can_xcvr>;
+                       gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+               };
+
+               reg_usbh1_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usbh1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usbh1_vbus>;
+                       gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+
+               reg_usbotg_vbus: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "usbotg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usbotg_vbus>;
+                       gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "karo,tx53-audio-sgtl5000", "fsl,imx-audio-sgtl5000";
+               model = "tx53-audio-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               /* '1' based port numbers according to datasheet names */
+               mux-int-port = <1>;
+               mux-ext-port = <5>;
        };
 };
 
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ssi1>;
+       status = "okay";
+};
+
 &can1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can1_2>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_can1>;
+       xceiver-supply = <&reg_can_xcvr>;
+       status = "okay";
 };
 
 &can2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_can2_1>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_can2>;
+       xceiver-supply = <&reg_can_xcvr>;
+       status = "okay";
 };
 
 &ecspi1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_2>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       fsl,spi-num-chipselects = <2>;
+       status = "okay";
+
+       cs-gpios = <
+               &gpio2 30 GPIO_ACTIVE_HIGH
+               &gpio3 19 GPIO_ACTIVE_HIGH
+       >;
+
+       spidev0: spi@0 {
+               compatible = "spidev";
+               reg = <0>;
+               spi-max-frequency = <54000000>;
+       };
+
+       spidev1: spi@1 {
+               compatible = "spidev";
+               reg = <1>;
+               spi-max-frequency = <54000000>;
+       };
 };
 
 &esdhc1 {
+       cd-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+       fsl,wp-controller;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc1_2>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       status = "okay";
 };
 
 &esdhc2 {
+       cd-gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+       fsl,wp-controller;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_esdhc2_1>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_esdhc2>;
+       status = "okay";
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
-       status = "disabled";
+       phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>;
+       phy-handle = <&phy0>;
+       mac-address = [000000000000]; /* placeholder; will be overwritten by bootloader */
+       status = "okay";
+
+       phy0: ethernet-phy@0 {
+               interrupt-parent = <&gpio2>;
+               interrupts = <4>;
+               device_type = "ethernet-phy";
+       };
 };
 
-&i2c3 {
+&i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_2>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       clock-frequency = <400000>;
+       status = "okay";
+
+       rtc1: ds1339@68 {
+               compatible = "dallas,ds1339";
+               reg = <0x68>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ds1339>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <20 0>;
+       };
 };
 
-&owire {
+&iomuxc {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_owire_1>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx53-tx53 {
+               pinctrl_hog: hoggrp {
+                       /* pins not in use by any device on the Starterkit board series */
+                       fsl,pins = <
+                               /* CMOS Sensor Interface */
+                               MX53_PAD_CSI0_DAT12__GPIO5_30 0x1f4
+                               MX53_PAD_CSI0_DAT13__GPIO5_31 0x1f4
+                               MX53_PAD_CSI0_DAT14__GPIO6_0 0x1f4
+                               MX53_PAD_CSI0_DAT15__GPIO6_1 0x1f4
+                               MX53_PAD_CSI0_DAT16__GPIO6_2 0x1f4
+                               MX53_PAD_CSI0_DAT17__GPIO6_3 0x1f4
+                               MX53_PAD_CSI0_DAT18__GPIO6_4 0x1f4
+                               MX53_PAD_CSI0_DAT19__GPIO6_5 0x1f4
+                               MX53_PAD_CSI0_MCLK__GPIO5_19 0x1f4
+                               MX53_PAD_CSI0_VSYNC__GPIO5_21 0x1f4
+                               MX53_PAD_CSI0_PIXCLK__GPIO5_18 0x1f4
+                               MX53_PAD_GPIO_0__GPIO1_0 0x1f4
+                               /* Module Specific Signal */
+                               /* MX53_PAD_NANDF_CS2__GPIO6_15 0x1f4 maybe used by EDT-FT5x06 */
+                               /* MX53_PAD_EIM_A16__GPIO2_22 0x1f4 maybe used by EDT-FT5x06 */
+                               MX53_PAD_EIM_D29__GPIO3_29 0x1f4
+                               MX53_PAD_EIM_EB3__GPIO2_31 0x1f4
+                               /* MX53_PAD_EIM_A17__GPIO2_21 0x1f4 maybe used by EDT-FT5x06 */
+                               /* MX53_PAD_EIM_A18__GPIO2_20 0x1f4 used by LED */
+                               MX53_PAD_EIM_A19__GPIO2_19 0x1f4
+                               MX53_PAD_EIM_A20__GPIO2_18 0x1f4
+                               MX53_PAD_EIM_A21__GPIO2_17 0x1f4
+                               MX53_PAD_EIM_A22__GPIO2_16 0x1f4
+                               MX53_PAD_EIM_A23__GPIO6_6 0x1f4
+                               MX53_PAD_EIM_A24__GPIO5_4 0x1f4
+                               MX53_PAD_CSI0_DAT8__GPIO5_26 0x1f4
+                               MX53_PAD_CSI0_DAT9__GPIO5_27 0x1f4
+                               MX53_PAD_CSI0_DAT10__GPIO5_28 0x1f4
+                               MX53_PAD_CSI0_DAT11__GPIO5_29 0x1f4
+                               /* MX53_PAD_EIM_D22__GPIO3_22 0x1f4 maybe used by EETI touchpanel driver */
+                               /* MX53_PAD_EIM_D23__GPIO3_23 0x1f4 maybe used by EETI touchpanel driver */
+                               MX53_PAD_GPIO_13__GPIO4_3 0x1f4
+                               MX53_PAD_EIM_CS0__GPIO2_23 0x1f4
+                               MX53_PAD_EIM_CS1__GPIO2_24 0x1f4
+                               MX53_PAD_CSI0_DATA_EN__GPIO5_20 0x1f4
+                               MX53_PAD_EIM_WAIT__GPIO5_0 0x1f4
+                               MX53_PAD_EIM_EB0__GPIO2_28 0x1f4
+                               MX53_PAD_EIM_EB1__GPIO2_29 0x1f4
+                               MX53_PAD_EIM_OE__GPIO2_25 0x1f4
+                               MX53_PAD_EIM_LBA__GPIO2_27 0x1f4
+                               MX53_PAD_EIM_RW__GPIO2_26 0x1f4
+                               MX53_PAD_EIM_DA8__GPIO3_8 0x1f4
+                               MX53_PAD_EIM_DA9__GPIO3_9 0x1f4
+                               MX53_PAD_EIM_DA10__GPIO3_10 0x1f4
+                               MX53_PAD_EIM_DA11__GPIO3_11 0x1f4
+                               MX53_PAD_EIM_DA12__GPIO3_12 0x1f4
+                               MX53_PAD_EIM_DA13__GPIO3_13 0x1f4
+                               MX53_PAD_EIM_DA14__GPIO3_14 0x1f4
+                               MX53_PAD_EIM_DA15__GPIO3_15 0x1f4
+                               >;
+               };
+
+               pinctrl_can1: can1grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_7__CAN1_TXCAN             0x80000000
+                               MX53_PAD_GPIO_8__CAN1_RXCAN             0x80000000
+                       >;
+               };
+
+               pinctrl_can2: can2grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL4__CAN2_TXCAN           0x80000000
+                               MX53_PAD_KEY_ROW4__CAN2_RXCAN           0x80000000
+                       >;
+               };
+
+               pinctrl_can_xcvr: can-xcvrgrp {
+                       fsl,pins = <MX53_PAD_DISP0_DAT0__GPIO4_21 0xe0>; /* Flexcan XCVR enable */
+               };
+
+               pinctrl_ds1339: ds1339grp {
+                       fsl,pins = <MX53_PAD_DI0_PIN4__GPIO4_20 0xe0>;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_19__ECSPI1_RDY            0x80000000
+                               MX53_PAD_EIM_EB2__ECSPI1_SS0            0x80000000
+                               MX53_PAD_EIM_D16__ECSPI1_SCLK           0x80000000
+                               MX53_PAD_EIM_D17__ECSPI1_MISO           0x80000000
+                               MX53_PAD_EIM_D18__ECSPI1_MOSI           0x80000000
+                               MX53_PAD_EIM_D19__ECSPI1_SS1            0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc1: esdhc1grp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA0__ESDHC1_DAT0         0x1d5
+                               MX53_PAD_SD1_DATA1__ESDHC1_DAT1         0x1d5
+                               MX53_PAD_SD1_DATA2__ESDHC1_DAT2         0x1d5
+                               MX53_PAD_SD1_DATA3__ESDHC1_DAT3         0x1d5
+                               MX53_PAD_SD1_CMD__ESDHC1_CMD            0x1d5
+                               MX53_PAD_SD1_CLK__ESDHC1_CLK            0x1d5
+                               MX53_PAD_EIM_D24__GPIO3_24 0x1f0
+                       >;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <
+                               MX53_PAD_SD2_CMD__ESDHC2_CMD            0x1d5
+                               MX53_PAD_SD2_CLK__ESDHC2_CLK            0x1d5
+                               MX53_PAD_SD2_DATA0__ESDHC2_DAT0         0x1d5
+                               MX53_PAD_SD2_DATA1__ESDHC2_DAT1         0x1d5
+                               MX53_PAD_SD2_DATA2__ESDHC2_DAT2         0x1d5
+                               MX53_PAD_SD2_DATA3__ESDHC2_DAT3         0x1d5
+                               MX53_PAD_EIM_D25__GPIO3_25 0x1f0
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX53_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX53_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX53_PAD_FEC_REF_CLK__FEC_TX_CLK        0x80000000
+                               MX53_PAD_FEC_RX_ER__FEC_RX_ER           0x80000000
+                               MX53_PAD_FEC_CRS_DV__FEC_RX_DV          0x80000000
+                               MX53_PAD_FEC_RXD1__FEC_RDATA_1          0x80000000
+                               MX53_PAD_FEC_RXD0__FEC_RDATA_0          0x80000000
+                               MX53_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX53_PAD_FEC_TXD1__FEC_TDATA_1          0x80000000
+                               MX53_PAD_FEC_TXD0__FEC_TDATA_0          0x80000000
+                       >;
+               };
+
+               pinctrl_gpio_key: gpio-keygrp {
+                       fsl,pins = <MX53_PAD_EIM_A25__GPIO5_2 0x1f4>;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D21__I2C1_SCL              0xc0000000
+                               MX53_PAD_EIM_D28__I2C1_SDA              0xc0000000
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_3__I2C3_SCL               0xc0000000
+                               MX53_PAD_GPIO_6__I2C3_SDA               0xc0000000
+                       >;
+               };
+
+               pinctrl_nand: nandgrp {
+                       fsl,pins = <
+                               MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B     0x4
+                               MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B     0x4
+                               MX53_PAD_NANDF_CLE__EMI_NANDF_CLE       0x4
+                               MX53_PAD_NANDF_ALE__EMI_NANDF_ALE       0x4
+                               MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B     0xe0
+                               MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0      0xe0
+                               MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0      0x4
+                               MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0    0xa4
+                               MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1    0xa4
+                               MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2    0xa4
+                               MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3    0xa4
+                               MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4    0xa4
+                               MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5    0xa4
+                               MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6    0xa4
+                               MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7    0xa4
+                       >;
+               };
+
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_1__PWM2_PWMO              0x80000000
+                       >;
+               };
+
+               pinctrl_ssi1: ssi1grp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC      0x80000000
+                               MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD      0x80000000
+                               MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS     0x80000000
+                               MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD      0x80000000
+                       >;
+               };
+
+               pinctrl_ssi2: ssi2grp {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC     0x80000000
+                               MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD     0x80000000
+                               MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS    0x80000000
+                               MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD     0x80000000
+                               MX53_PAD_EIM_D27__GPIO3_27 0x1f0
+                       >;
+               };
+
+               pinctrl_stk5led: stk5ledgrp {
+                       fsl,pins = <MX53_PAD_EIM_A18__GPIO2_20 0xc0>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DIOW__UART1_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_DMACK__UART1_RXD_MUX      0x1e4
+                               MX53_PAD_PATA_RESET_B__UART1_CTS        0x1c5
+                               MX53_PAD_PATA_IORDY__UART1_RTS          0x1c5
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX  0x1c5
+                               MX53_PAD_PATA_DMARQ__UART2_TXD_MUX      0x1c5
+                               MX53_PAD_PATA_DIOR__UART2_RTS           0x1c5
+                               MX53_PAD_PATA_INTRQ__UART2_CTS          0x1c5
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_CS_0__UART3_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_CS_1__UART3_RXD_MUX       0x1e4
+                               MX53_PAD_PATA_DA_1__UART3_CTS           0x1e4
+                               MX53_PAD_PATA_DA_2__UART3_RTS           0x1e4
+                       >;
+               };
+
+               pinctrl_usbh1: usbh1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D30__GPIO3_30 0x100 /* OC */
+                       >;
+               };
+
+               pinctrl_usbh1_vbus: usbh1-vbusgrp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D31__GPIO3_31 0xe0 /* VBUS ENABLE */
+                       >;
+               };
+
+               pinctrl_usbotg_vbus: usbotg-vbusgrp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_7__GPIO1_7 0xe0 /* VBUS ENABLE */
+                               MX53_PAD_GPIO_8__GPIO1_8 0x100 /* OC */
+                       >;
+               };
+       };
+};
+
+&ipu {
+       status = "okay";
+};
+
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_nand>;
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
 };
 
 &pwm2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm2_1>;
-       status = "disabled";
+       pinctrl-0 = <&pinctrl_pwm2>;
+       #pwm-cells = <3>;
+};
+
+&sdma {
+       fsl,sdma-ram-script-name = "sdma-imx53.bin";
 };
 
 &ssi1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
-       status = "disabled";
+       fsl,mode = "i2s-slave";
+       codec-handle = <&sgtl5000>;
+       status = "okay";
 };
 
 &ssi2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
        status = "disabled";
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_2>,
-                   <&pinctrl_uart1_3>;
+       pinctrl-0 = <&pinctrl_uart1>;
        fsl,uart-has-rtscts;
-       status = "disabled";
+       status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_2>;
+       pinctrl-0 = <&pinctrl_uart2>;
        fsl,uart-has-rtscts;
-       status = "disabled";
+       status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_1>;
+       pinctrl-0 = <&pinctrl_uart3>;
        fsl,uart-has-rtscts;
-       status = "disabled";
+       status = "okay";
+};
+
+&usbh1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh1>;
+       phy_type = "utmi";
+       disable-over-current;
+       vbus-supply = <&reg_usbh1_vbus>;
+       status = "okay";
+};
+
+&usbotg {
+       phy_type = "utmi";
+       dr_mode = "peripheral";
+       disable-over-current;
+       vbus-supply = <&reg_usbotg_vbus>;
+       status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx53-voipac-bsb.dts b/arch/arm/boot/dts/imx53-voipac-bsb.dts
new file mode 100644 (file)
index 0000000..7f6711a
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2013 Rostislav Lisovy <lisovy@gmail.com>, PiKRON s.r.o.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53-voipac-dmm-668.dtsi"
+
+/ {
+       sound {
+               compatible = "fsl,imx53-voipac-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx53-voipac-sgtl5000";
+               ssi-controller = <&ssi2>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <2>;
+               mux-ext-port = <5>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pin_gpio>;
+
+               led1 {
+                       label = "led-red";
+                       gpios = <&gpio3 29 0>;
+                       default-state = "off";
+               };
+
+               led2 {
+                       label = "led-orange";
+                       gpios = <&gpio2 31 0>;
+                       default-state = "off";
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx53-voipac {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* SD2_CD */
+                               MX53_PAD_EIM_D25__GPIO3_25      0x80000000
+                               /* SD2_WP */
+                               MX53_PAD_EIM_A19__GPIO2_19      0x80000000
+                       >;
+               };
+
+               led_pin_gpio: led_gpio {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D29__GPIO3_29      0x80000000
+                               MX53_PAD_EIM_EB3__GPIO2_31      0x80000000
+                       >;
+               };
+
+               /* Keyboard controller */
+               pinctrl_kpp_1: kppgrp-1 {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_9__KPP_COL_6      0xe8
+                               MX53_PAD_GPIO_4__KPP_COL_7      0xe8
+                               MX53_PAD_KEY_COL2__KPP_COL_2    0xe8
+                               MX53_PAD_KEY_COL3__KPP_COL_3    0xe8
+                               MX53_PAD_KEY_COL4__KPP_COL_4    0xe8
+                               MX53_PAD_GPIO_2__KPP_ROW_6      0xe0
+                               MX53_PAD_GPIO_5__KPP_ROW_7      0xe0
+                               MX53_PAD_KEY_ROW2__KPP_ROW_2    0xe0
+                               MX53_PAD_KEY_ROW3__KPP_ROW_3    0xe0
+                               MX53_PAD_KEY_ROW4__KPP_ROW_4    0xe0
+                       >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC      0x80000000
+                               MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD      0x80000000
+                               MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS     0x80000000
+                               MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD      0x80000000
+                       >;
+               };
+
+               pinctrl_esdhc2: esdhc2grp {
+                       fsl,pins = <
+                               MX53_PAD_SD2_CMD__ESDHC2_CMD            0x1d5
+                               MX53_PAD_SD2_CLK__ESDHC2_CLK            0x1d5
+                               MX53_PAD_SD2_DATA0__ESDHC2_DAT0         0x1d5
+                               MX53_PAD_SD2_DATA1__ESDHC2_DAT1         0x1d5
+                               MX53_PAD_SD2_DATA2__ESDHC2_DAT2         0x1d5
+                               MX53_PAD_SD2_DATA3__ESDHC2_DAT3         0x1d5
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_3__I2C3_SCL               0xc0000000
+                               MX53_PAD_GPIO_6__I2C3_SDA               0xc0000000
+                       >;
+               };
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>; /* SSI1 */
+       status = "okay";
+};
+
+&esdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc2>;
+       cd-gpios = <&gpio3 25 0>;
+       wp-gpios = <&gpio2 19 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       sgtl5000: codec@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_3p3v>;
+               VDDIO-supply = <&reg_3p3v>;
+               clocks = <&clks 150>;
+       };
+};
+
+&kpp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_kpp_1>;
+       linux,keymap = <
+                       0x0203003b      /* KEY_F1 */
+                       0x0603003c      /* KEY_F2 */
+                       0x0207003d      /* KEY_F3 */
+                       0x0607003e      /* KEY_F4 */
+                       >;
+       keypad,num-rows = <8>;
+       keypad,num-columns = <1>;
+       status = "okay";
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi
new file mode 100644 (file)
index 0000000..ba689fb
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2013 Rostislav Lisovy <lisovy@gmail.com>, PiKRON s.r.o.
+ *
+ * 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 "imx53.dtsi"
+
+/ {
+       model = "Voipac i.MX53 X53-DMM-668";
+       compatible = "voipac,imx53-dmm-668", "fsl,imx53";
+
+       memory@70000000 {
+               device_type = "memory";
+               reg = <0x70000000 0x20000000>;
+       };
+
+       memory@b0000000 {
+               device_type = "memory";
+               reg = <0xb0000000 0x20000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 31 0>; /* PEN */
+                       enable-active-high;
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx53-voipac {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* Make DA9053 regulator functional */
+                               MX53_PAD_GPIO_16__GPIO7_11      0x80000000
+                               /* FEC Power enable */
+                               MX53_PAD_GPIO_11__GPIO4_1       0x80000000
+                               /* FEC RST */
+                               MX53_PAD_GPIO_12__GPIO4_2       0x80000000
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D16__ECSPI1_SCLK           0x80000000
+                               MX53_PAD_EIM_D17__ECSPI1_MISO           0x80000000
+                               MX53_PAD_EIM_D18__ECSPI1_MOSI           0x80000000
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX53_PAD_FEC_MDC__FEC_MDC               0x80000000
+                               MX53_PAD_FEC_MDIO__FEC_MDIO             0x80000000
+                               MX53_PAD_FEC_REF_CLK__FEC_TX_CLK        0x80000000
+                               MX53_PAD_FEC_RX_ER__FEC_RX_ER           0x80000000
+                               MX53_PAD_FEC_CRS_DV__FEC_RX_DV          0x80000000
+                               MX53_PAD_FEC_RXD1__FEC_RDATA_1          0x80000000
+                               MX53_PAD_FEC_RXD0__FEC_RDATA_0          0x80000000
+                               MX53_PAD_FEC_TX_EN__FEC_TX_EN           0x80000000
+                               MX53_PAD_FEC_TXD1__FEC_TDATA_1          0x80000000
+                               MX53_PAD_FEC_TXD0__FEC_TDATA_0          0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_D21__I2C1_SCL              0xc0000000
+                               MX53_PAD_EIM_D28__I2C1_SDA              0xc0000000
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX53_PAD_PATA_DIOW__UART1_TXD_MUX       0x1e4
+                               MX53_PAD_PATA_DMACK__UART1_RXD_MUX      0x1e4
+                       >;
+               };
+
+               pinctrl_nand: nandgrp {
+                       fsl,pins = <
+                               MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B     0x4
+                               MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B     0x4
+                               MX53_PAD_NANDF_CLE__EMI_NANDF_CLE       0x4
+                               MX53_PAD_NANDF_ALE__EMI_NANDF_ALE       0x4
+                               MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B     0xe0
+                               MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0      0xe0
+                               MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0      0x4
+                               MX53_PAD_PATA_DATA0__EMI_NANDF_D_0      0xa4
+                               MX53_PAD_PATA_DATA1__EMI_NANDF_D_1      0xa4
+                               MX53_PAD_PATA_DATA2__EMI_NANDF_D_2      0xa4
+                               MX53_PAD_PATA_DATA3__EMI_NANDF_D_3      0xa4
+                               MX53_PAD_PATA_DATA4__EMI_NANDF_D_4      0xa4
+                               MX53_PAD_PATA_DATA5__EMI_NANDF_D_5      0xa4
+                               MX53_PAD_PATA_DATA6__EMI_NANDF_D_6      0xa4
+                               MX53_PAD_PATA_DATA7__EMI_NANDF_D_7      0xa4
+                       >;
+               };
+       };
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       fsl,spi-num-chipselects = <4>;
+       cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>, <&gpio2 16 0>, <&gpio2 17 0>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "rmii";
+       phy-reset-gpios = <&gpio4 2 0>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic: dialog@48 {
+               compatible = "dlg,da9053-aa", "dlg,da9052";
+               reg = <0x48>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <11 0x8>; /* low-level active IRQ at GPIO7_11 */
+
+               regulators {
+                       buck1_reg: buck1 {
+                               regulator-name = "BUCKCORE";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1400000>;
+                               regulator-always-on;
+                       };
+
+                       buck2_reg: buck2 {
+                               regulator-name = "BUCKPRO";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+
+                       buck3_reg: buck3 {
+                               regulator-name = "BUCKMEM";
+                               regulator-min-microvolt = <1420000>;
+                               regulator-max-microvolt = <1580000>;
+                               regulator-always-on;
+                       };
+
+                       buck4_reg: buck4 {
+                               regulator-name = "BUCKPERI";
+                               regulator-min-microvolt = <2370000>;
+                               regulator-max-microvolt = <2630000>;
+                               regulator-always-on;
+                       };
+
+                       ldo1_reg: ldo1 {
+                               regulator-name = "ldo1_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ldo2 {
+                               regulator-name = "ldo2_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo3_reg: ldo3 {
+                               regulator-name = "ldo3_3v3";
+                               regulator-min-microvolt = <3250000>;
+                               regulator-max-microvolt = <3350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: ldo4 {
+                               regulator-name = "ldo4_2v775";
+                               regulator-min-microvolt = <2770000>;
+                               regulator-max-microvolt = <2780000>;
+                               regulator-always-on;
+                       };
+
+                       ldo5_reg: ldo5 {
+                               regulator-name = "ldo5_3v3";
+                               regulator-min-microvolt = <3250000>;
+                               regulator-max-microvolt = <3350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo6_reg: ldo6 {
+                               regulator-name = "ldo6_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+
+                       ldo7_reg: ldo7 {
+                               regulator-name = "ldo7_2v75";
+                               regulator-min-microvolt = <2700000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-always-on;
+                       };
+
+                       ldo8_reg: ldo8 {
+                               regulator-name = "ldo8_1v8";
+                               regulator-min-microvolt = <1750000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-always-on;
+                       };
+
+                       ldo9_reg: ldo9 {
+                               regulator-name = "ldo9_1v5";
+                               regulator-min-microvolt = <1450000>;
+                               regulator-max-microvolt = <1550000>;
+                               regulator-always-on;
+                       };
+
+                       ldo10_reg: ldo10 {
+                               regulator-name = "ldo10_1v3";
+                               regulator-min-microvolt = <1250000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_nand>;
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_vbus>;
+       phy_type = "utmi";
+       status = "okay";
+};
index 04d3127edfe1086f886b45c91e7f6927512825e8..b57ab57740f686a96200b9a51c63c7d982d82644 100644 (file)
@@ -12,6 +12,9 @@
 
 #include "skeleton.dtsi"
 #include "imx53-pinfunc.h"
+#include <dt-bindings/clock/imx5-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
        aliases {
                i2c0 = &i2c1;
                i2c1 = &i2c2;
                i2c2 = &i2c3;
+               mmc0 = &esdhc1;
+               mmc1 = &esdhc2;
+               mmc2 = &esdhc3;
+               mmc3 = &esdhc4;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
                interrupt-parent = <&tzic>;
                ranges;
 
+               sata: sata@10000000 {
+                       compatible = "fsl,imx53-ahci";
+                       reg = <0x10000000 0x1000>;
+                       interrupts = <28>;
+                       clocks = <&clks IMX5_CLK_SATA_GATE>,
+                                <&clks IMX5_CLK_SATA_REF>,
+                                <&clks IMX5_CLK_AHB>;
+                       clock-names = "sata_gate", "sata_ref", "ahb";
+                       status = "disabled";
+               };
+
                ipu: ipu@18000000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        compatible = "fsl,imx53-ipu";
                        reg = <0x18000000 0x080000000>;
                        interrupts = <11 10>;
-                       clocks = <&clks 59>, <&clks 110>, <&clks 61>;
+                       clocks = <&clks IMX5_CLK_IPU_GATE>,
+                                <&clks IMX5_CLK_IPU_DI0_GATE>,
+                                <&clks IMX5_CLK_IPU_DI1_GATE>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 2>;
 
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50004000 0x4000>;
                                        interrupts = <1>;
-                                       clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+                                       clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC1_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50008000 0x4000>;
                                        interrupts = <2>;
-                                       clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+                                       clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC2_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                        reg = <0x5000c000 0x4000>;
                                        interrupts = <33>;
-                                       clocks = <&clks 32>, <&clks 33>;
+                                       clocks = <&clks IMX5_CLK_UART3_IPG_GATE>,
+                                                <&clks IMX5_CLK_UART3_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
                                        compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x50010000 0x4000>;
                                        interrupts = <36>;
-                                       clocks = <&clks 51>, <&clks 52>;
+                                       clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
+                                                <&clks IMX5_CLK_ECSPI1_PER_GATE>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                                };
 
                                ssi2: ssi@50014000 {
-                                       compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+                                       compatible = "fsl,imx53-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x50014000 0x4000>;
                                        interrupts = <30>;
-                                       clocks = <&clks 49>;
+                                       clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
                                        dmas = <&sdma 24 1 0>,
                                               <&sdma 25 1 0>;
                                        dma-names = "rx", "tx";
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50020000 0x4000>;
                                        interrupts = <3>;
-                                       clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+                                       clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC3_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
                                        compatible = "fsl,imx53-esdhc";
                                        reg = <0x50024000 0x4000>;
                                        interrupts = <4>;
-                                       clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+                                       clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
+                                                <&clks IMX5_CLK_DUMMY>,
+                                                <&clks IMX5_CLK_ESDHC4_PER_GATE>;
                                        clock-names = "ipg", "ahb", "per";
                                        bus-width = <4>;
                                        status = "disabled";
 
                        usbphy0: usbphy@0 {
                                compatible = "usb-nop-xceiv";
-                               clocks = <&clks 124>;
+                               clocks = <&clks IMX5_CLK_USB_PHY1_GATE>;
                                clock-names = "main_clk";
                                status = "okay";
                        };
 
                        usbphy1: usbphy@1 {
                                compatible = "usb-nop-xceiv";
-                               clocks = <&clks 125>;
+                               clocks = <&clks IMX5_CLK_USB_PHY2_GATE>;
                                clock-names = "main_clk";
                                status = "okay";
                        };
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80000 0x0200>;
                                interrupts = <18>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 0>;
                                fsl,usbphy = <&usbphy0>;
                                status = "disabled";
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80200 0x0200>;
                                interrupts = <14>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 1>;
                                fsl,usbphy = <&usbphy1>;
                                status = "disabled";
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80400 0x0200>;
                                interrupts = <16>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-usb", "fsl,imx27-usb";
                                reg = <0x53f80600 0x0200>;
                                interrupts = <17>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                                fsl,usbmisc = <&usbmisc 3>;
                                status = "disabled";
                        };
                                #index-cells = <1>;
                                compatible = "fsl,imx53-usbmisc";
                                reg = <0x53f80800 0x200>;
-                               clocks = <&clks 108>;
+                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
                        };
 
                        gpio1: gpio@53f84000 {
                                #interrupt-cells = <2>;
                        };
 
+                       kpp: kpp@53f94000 {
+                               compatible = "fsl,imx53-kpp", "fsl,imx21-kpp";
+                               reg = <0x53f94000 0x4000>;
+                               interrupts = <60>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
+                               status = "disabled";
+                       };
+
                        wdog1: wdog@53f98000 {
                                compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
                                reg = <0x53f98000 0x4000>;
                                interrupts = <58>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                        };
 
                        wdog2: wdog@53f9c000 {
                                compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
                                reg = <0x53f9c000 0x4000>;
                                interrupts = <59>;
-                               clocks = <&clks 0>;
+                               clocks = <&clks IMX5_CLK_DUMMY>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-gpt", "fsl,imx31-gpt";
                                reg = <0x53fa0000 0x4000>;
                                interrupts = <39>;
-                               clocks = <&clks 36>, <&clks 41>;
+                               clocks = <&clks IMX5_CLK_GPT_IPG_GATE>,
+                                        <&clks IMX5_CLK_GPT_HF_GATE>;
                                clock-names = "ipg", "per";
                        };
 
                        iomuxc: iomuxc@53fa8000 {
                                compatible = "fsl,imx53-iomuxc";
                                reg = <0x53fa8000 0x4000>;
-
-                               audmux {
-                                       pinctrl_audmux_1: audmuxgrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC  0x80000000
-                                                       MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD  0x80000000
-                                                       MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
-                                                       MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_2: audmuxgrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC     0x80000000
-                                                       MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD     0x80000000
-                                                       MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS    0x80000000
-                                                       MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD     0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_3: audmuxgrp-3 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC     0x80000000
-                                                       MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD     0x80000000
-                                                       MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS    0x80000000
-                                                       MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               fec {
-                                       pinctrl_fec_1: fecgrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_FEC_MDC__FEC_MDC        0x80000000
-                                                       MX53_PAD_FEC_MDIO__FEC_MDIO      0x80000000
-                                                       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
-                                                       MX53_PAD_FEC_RX_ER__FEC_RX_ER    0x80000000
-                                                       MX53_PAD_FEC_CRS_DV__FEC_RX_DV   0x80000000
-                                                       MX53_PAD_FEC_RXD1__FEC_RDATA_1   0x80000000
-                                                       MX53_PAD_FEC_RXD0__FEC_RDATA_0   0x80000000
-                                                       MX53_PAD_FEC_TX_EN__FEC_TX_EN    0x80000000
-                                                       MX53_PAD_FEC_TXD1__FEC_TDATA_1   0x80000000
-                                                       MX53_PAD_FEC_TXD0__FEC_TDATA_0   0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_fec_2: fecgrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_FEC_MDC__FEC_MDC        0x80000000
-                                                       MX53_PAD_FEC_MDIO__FEC_MDIO      0x80000000
-                                                       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
-                                                       MX53_PAD_FEC_RX_ER__FEC_RX_ER    0x80000000
-                                                       MX53_PAD_FEC_CRS_DV__FEC_RX_DV   0x80000000
-                                                       MX53_PAD_FEC_RXD1__FEC_RDATA_1   0x80000000
-                                                       MX53_PAD_FEC_RXD0__FEC_RDATA_0   0x80000000
-                                                       MX53_PAD_FEC_TX_EN__FEC_TX_EN    0x80000000
-                                                       MX53_PAD_FEC_TXD1__FEC_TDATA_1   0x80000000
-                                                       MX53_PAD_FEC_TXD0__FEC_TDATA_0   0x80000000
-                                                       MX53_PAD_KEY_ROW1__FEC_COL       0x80000000
-                                                       MX53_PAD_KEY_COL3__FEC_CRS       0x80000000
-                                                       MX53_PAD_KEY_COL2__FEC_RDATA_2   0x80000000
-                                                       MX53_PAD_KEY_COL0__FEC_RDATA_3   0x80000000
-                                                       MX53_PAD_KEY_COL1__FEC_RX_CLK    0x80000000
-                                                       MX53_PAD_KEY_ROW2__FEC_TDATA_2   0x80000000
-                                                       MX53_PAD_GPIO_19__FEC_TDATA_3    0x80000000
-                                                       MX53_PAD_KEY_ROW0__FEC_TX_ER     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               csi {
-                                       pinctrl_csi_1: csigrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN 0x1d5
-                                                       MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC     0x1d5
-                                                       MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC      0x1d5
-                                                       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
-                                                       MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19      0x1d5
-                                                       MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18      0x1d5
-                                                       MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17      0x1d5
-                                                       MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16      0x1d5
-                                                       MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15      0x1d5
-                                                       MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14      0x1d5
-                                                       MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13      0x1d5
-                                                       MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12      0x1d5
-                                                       MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11      0x1d5
-                                                       MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10      0x1d5
-                                                       MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9        0x1d5
-                                                       MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8        0x1d5
-                                                       MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7        0x1d5
-                                                       MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6        0x1d5
-                                                       MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5        0x1d5
-                                                       MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4        0x1d5
-                                                       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
-                                               >;
-                                       };
-
-                                       pinctrl_csi_2: csigrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC     0x1d5
-                                                       MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC      0x1d5
-                                                       MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
-                                                       MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19      0x1d5
-                                                       MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18      0x1d5
-                                                       MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17      0x1d5
-                                                       MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16      0x1d5
-                                                       MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15      0x1d5
-                                                       MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14      0x1d5
-                                                       MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13      0x1d5
-                                                       MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12      0x1d5
-                                               >;
-                                       };
-                               };
-
-                               cspi {
-                                       pinctrl_cspi_1: cspigrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD1_DATA0__CSPI_MISO 0x1d5
-                                                       MX53_PAD_SD1_CMD__CSPI_MOSI   0x1d5
-                                                       MX53_PAD_SD1_CLK__CSPI_SCLK   0x1d5
-                                               >;
-                                       };
-
-                                       pinctrl_cspi_2: cspigrp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D22__CSPI_MISO 0x1d5
-                                                       MX53_PAD_EIM_D28__CSPI_MOSI 0x1d5
-                                                       MX53_PAD_EIM_D21__CSPI_SCLK 0x1d5
-                                               >;
-                                       };
-                               };
-
-                               ecspi1 {
-                                       pinctrl_ecspi1_1: ecspi1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
-                                                       MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
-                                                       MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_ecspi1_2: ecspi1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_19__ECSPI1_RDY    0x80000000
-                                                       MX53_PAD_EIM_EB2__ECSPI1_SS0    0x80000000
-                                                       MX53_PAD_EIM_D16__ECSPI1_SCLK   0x80000000
-                                                       MX53_PAD_EIM_D17__ECSPI1_MISO   0x80000000
-                                                       MX53_PAD_EIM_D18__ECSPI1_MOSI   0x80000000
-                                                       MX53_PAD_EIM_D19__ECSPI1_SS1    0x80000000
-                                               >;
-                                       };
-                               };
-
-                               ecspi2 {
-                                       pinctrl_ecspi2_1: ecspi2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_OE__ECSPI2_MISO  0x80000000
-                                                       MX53_PAD_EIM_CS1__ECSPI2_MOSI 0x80000000
-                                                       MX53_PAD_EIM_CS0__ECSPI2_SCLK 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               esdhc1 {
-                                       pinctrl_esdhc1_1: esdhc1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
-                                                       MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
-                                                       MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
-                                                       MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
-                                                       MX53_PAD_SD1_CMD__ESDHC1_CMD    0x1d5
-                                                       MX53_PAD_SD1_CLK__ESDHC1_CLK    0x1d5
-                                               >;
-                                       };
-
-                                       pinctrl_esdhc1_2: esdhc1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD1_DATA0__ESDHC1_DAT0   0x1d5
-                                                       MX53_PAD_SD1_DATA1__ESDHC1_DAT1   0x1d5
-                                                       MX53_PAD_SD1_DATA2__ESDHC1_DAT2   0x1d5
-                                                       MX53_PAD_SD1_DATA3__ESDHC1_DAT3   0x1d5
-                                                       MX53_PAD_PATA_DATA8__ESDHC1_DAT4  0x1d5
-                                                       MX53_PAD_PATA_DATA9__ESDHC1_DAT5  0x1d5
-                                                       MX53_PAD_PATA_DATA10__ESDHC1_DAT6 0x1d5
-                                                       MX53_PAD_PATA_DATA11__ESDHC1_DAT7 0x1d5
-                                                       MX53_PAD_SD1_CMD__ESDHC1_CMD      0x1d5
-                                                       MX53_PAD_SD1_CLK__ESDHC1_CLK      0x1d5
-                                               >;
-                                       };
-                               };
-
-                               esdhc2 {
-                                       pinctrl_esdhc2_1: esdhc2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_SD2_CMD__ESDHC2_CMD    0x1d5
-                                                       MX53_PAD_SD2_CLK__ESDHC2_CLK    0x1d5
-                                                       MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5
-                                                       MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5
-                                                       MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5
-                                                       MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5
-                                               >;
-                                       };
-                               };
-
-                               esdhc3 {
-                                       pinctrl_esdhc3_1: esdhc3grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_DATA8__ESDHC3_DAT0  0x1d5
-                                                       MX53_PAD_PATA_DATA9__ESDHC3_DAT1  0x1d5
-                                                       MX53_PAD_PATA_DATA10__ESDHC3_DAT2 0x1d5
-                                                       MX53_PAD_PATA_DATA11__ESDHC3_DAT3 0x1d5
-                                                       MX53_PAD_PATA_DATA0__ESDHC3_DAT4  0x1d5
-                                                       MX53_PAD_PATA_DATA1__ESDHC3_DAT5  0x1d5
-                                                       MX53_PAD_PATA_DATA2__ESDHC3_DAT6  0x1d5
-                                                       MX53_PAD_PATA_DATA3__ESDHC3_DAT7  0x1d5
-                                                       MX53_PAD_PATA_RESET_B__ESDHC3_CMD 0x1d5
-                                                       MX53_PAD_PATA_IORDY__ESDHC3_CLK   0x1d5
-                                               >;
-                                       };
-                               };
-
-                               can1 {
-                                       pinctrl_can1_1: can1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_INTRQ__CAN1_TXCAN 0x80000000
-                                                       MX53_PAD_PATA_DIOR__CAN1_RXCAN  0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_can1_2: can1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL2__CAN1_TXCAN 0x80000000
-                                                       MX53_PAD_KEY_ROW2__CAN1_RXCAN 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_can1_3: can1grp-3 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_7__CAN1_TXCAN     0x80000000
-                                                       MX53_PAD_GPIO_8__CAN1_RXCAN     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               can2 {
-                                       pinctrl_can2_1: can2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL4__CAN2_TXCAN 0x80000000
-                                                       MX53_PAD_KEY_ROW4__CAN2_RXCAN 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               i2c1 {
-                                       pinctrl_i2c1_1: i2c1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DAT8__I2C1_SDA 0xc0000000
-                                                       MX53_PAD_CSI0_DAT9__I2C1_SCL 0xc0000000
-                                               >;
-                                       };
-
-                                       pinctrl_i2c1_2: i2c1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D21__I2C1_SCL      0xc0000000
-                                                       MX53_PAD_EIM_D28__I2C1_SDA      0xc0000000
-                                               >;
-                                       };
-                               };
-
-                               i2c2 {
-                                       pinctrl_i2c2_1: i2c2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000
-                                                       MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
-                                               >;
-                                       };
-
-                                       pinctrl_i2c2_2: i2c2grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_D16__I2C2_SDA      0xc0000000
-                                                       MX53_PAD_EIM_EB2__I2C2_SCL      0xc0000000
-                                               >;
-                                       };
-                               };
-
-                               i2c3 {
-                                       pinctrl_i2c3_1: i2c3grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_6__I2C3_SDA 0xc0000000
-                                                       MX53_PAD_GPIO_5__I2C3_SCL 0xc0000000
-                                               >;
-                                       };
-                               };
-
-                               ipu_disp0 {
-                                       pinctrl_ipu_disp0_1: ipudisp0grp-1 {
-                                               fsl,pins = <
-                                               MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5
-                                               MX53_PAD_DI0_PIN15__IPU_DI0_PIN15               0x5
-                                               MX53_PAD_DI0_PIN2__IPU_DI0_PIN2         0x5
-                                               MX53_PAD_DI0_PIN3__IPU_DI0_PIN3                 0x5
-                                               MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0            0x5
-                                               MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1            0x5
-                                               MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2            0x5
-                                               MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3            0x5
-                                               MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4            0x5
-                                               MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5            0x5
-                                               MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6            0x5
-                                               MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7            0x5
-                                               MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8            0x5
-                                               MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9            0x5
-                                               MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10          0x5
-                                               MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11          0x5
-                                               MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12          0x5
-                                               MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13          0x5
-                                               MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14          0x5
-                                               MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15          0x5
-                                               MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16          0x5
-                                               MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17          0x5
-                                               MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18          0x5
-                                               MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19          0x5
-                                               MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20          0x5
-                                               MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21          0x5
-                                               MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22          0x5
-                                               MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23          0x5
-                                               >;
-                                       };
-                               };
-
-                               ipu_disp1 {
-                                       pinctrl_ipu_disp1_1: ipudisp1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0       0x5
-                                                       MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1       0x5
-                                                       MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2       0x5
-                                                       MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3       0x5
-                                                       MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4       0x5
-                                                       MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5       0x5
-                                                       MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6       0x5
-                                                       MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7       0x5
-                                                       MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8       0x5
-                                                       MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9       0x5
-                                                       MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10      0x5
-                                                       MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11      0x5
-                                                       MX53_PAD_EIM_A17__IPU_DISP1_DAT_12      0x5
-                                                       MX53_PAD_EIM_A18__IPU_DISP1_DAT_13      0x5
-                                                       MX53_PAD_EIM_A19__IPU_DISP1_DAT_14      0x5
-                                                       MX53_PAD_EIM_A20__IPU_DISP1_DAT_15      0x5
-                                                       MX53_PAD_EIM_A21__IPU_DISP1_DAT_16      0x5
-                                                       MX53_PAD_EIM_A22__IPU_DISP1_DAT_17      0x5
-                                                       MX53_PAD_EIM_A23__IPU_DISP1_DAT_18      0x5
-                                                       MX53_PAD_EIM_A24__IPU_DISP1_DAT_19      0x5
-                                                       MX53_PAD_EIM_D31__IPU_DISP1_DAT_20      0x5
-                                                       MX53_PAD_EIM_D30__IPU_DISP1_DAT_21      0x5
-                                                       MX53_PAD_EIM_D26__IPU_DISP1_DAT_22      0x5
-                                                       MX53_PAD_EIM_D27__IPU_DISP1_DAT_23      0x5
-                                                       MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK      0x5
-                                                       MX53_PAD_EIM_DA13__IPU_DI1_D0_CS        0x5
-                                                       MX53_PAD_EIM_DA14__IPU_DI1_D1_CS        0x5
-                                                       MX53_PAD_EIM_DA15__IPU_DI1_PIN1         0x5
-                                                       MX53_PAD_EIM_DA11__IPU_DI1_PIN2         0x5
-                                                       MX53_PAD_EIM_DA12__IPU_DI1_PIN3         0x5
-                                                       MX53_PAD_EIM_A25__IPU_DI1_PIN12         0x5
-                                                       MX53_PAD_EIM_DA10__IPU_DI1_PIN15        0x5
-                                               >;
-                                       };
-                               };
-
-                               ipu_disp2 {
-                                       pinctrl_ipu_disp2_1: ipudisp2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0     0x80000000
-                                                       MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1     0x80000000
-                                                       MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2     0x80000000
-                                                       MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3     0x80000000
-                                                       MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK     0x80000000
-                                                       MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0     0x80000000
-                                                       MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1     0x80000000
-                                                       MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2     0x80000000
-                                                       MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3     0x80000000
-                                                       MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK     0x80000000
-                                               >;
-                                       };
-                               };
-
-                               nand {
-                                       pinctrl_nand_1: nandgrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B     0x4
-                                                       MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B     0x4
-                                                       MX53_PAD_NANDF_CLE__EMI_NANDF_CLE       0x4
-                                                       MX53_PAD_NANDF_ALE__EMI_NANDF_ALE       0x4
-                                                       MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B     0xe0
-                                                       MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0      0xe0
-                                                       MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0      0x4
-                                                       MX53_PAD_PATA_DATA0__EMI_NANDF_D_0      0xa4
-                                                       MX53_PAD_PATA_DATA1__EMI_NANDF_D_1      0xa4
-                                                       MX53_PAD_PATA_DATA2__EMI_NANDF_D_2      0xa4
-                                                       MX53_PAD_PATA_DATA3__EMI_NANDF_D_3      0xa4
-                                                       MX53_PAD_PATA_DATA4__EMI_NANDF_D_4      0xa4
-                                                       MX53_PAD_PATA_DATA5__EMI_NANDF_D_5      0xa4
-                                                       MX53_PAD_PATA_DATA6__EMI_NANDF_D_6      0xa4
-                                                       MX53_PAD_PATA_DATA7__EMI_NANDF_D_7      0xa4
-                                               >;
-                                       };
-                               };
-
-                               owire {
-                                       pinctrl_owire_1: owiregrp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_18__OWIRE_LINE 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               pwm1 {
-                                       pinctrl_pwm1_1: pwm1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_DISP0_DAT8__PWM1_PWMO  0x5
-                                               >;
-                                       };
-                               };
-
-                               pwm2 {
-                                       pinctrl_pwm2_1: pwm2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_GPIO_1__PWM2_PWMO      0x80000000
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x1e4
-                                                       MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart1_2: uart1grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_DIOW__UART1_TXD_MUX  0x1e4
-                                                       MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart1_3: uart1grp-3 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_RESET_B__UART1_CTS 0x1c5
-                                                       MX53_PAD_PATA_IORDY__UART1_RTS   0x1c5
-                                               >;
-                                       };
-                               };
-
-                               uart2 {
-                                       pinctrl_uart2_1: uart2grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX     0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart2_2: uart2grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX  0x1c5
-                                                       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX      0x1c5
-                                                       MX53_PAD_PATA_DIOR__UART2_RTS           0x1c5
-                                                       MX53_PAD_PATA_INTRQ__UART2_CTS          0x1c5
-                                               >;
-                                       };
-                               };
-
-                               uart3 {
-                                       pinctrl_uart3_1: uart3grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_DA_1__UART3_CTS     0x1e4
-                                                       MX53_PAD_PATA_DA_2__UART3_RTS     0x1e4
-                                               >;
-                                       };
-
-                                       pinctrl_uart3_2: uart3grp-2 {
-                                               fsl,pins = <
-                                                       MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
-                                                       MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
-                                               >;
-                                       };
-
-                               };
-
-                               uart4 {
-                                       pinctrl_uart4_1: uart4grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL0__UART4_TXD_MUX 0x1e4
-                                                       MX53_PAD_KEY_ROW0__UART4_RXD_MUX 0x1e4
-                                               >;
-                                       };
-                               };
-
-                               uart5 {
-                                       pinctrl_uart5_1: uart5grp-1 {
-                                               fsl,pins = <
-                                                       MX53_PAD_KEY_COL1__UART5_TXD_MUX 0x1e4
-                                                       MX53_PAD_KEY_ROW1__UART5_RXD_MUX 0x1e4
-                                               >;
-                                       };
-                               };
                        };
 
                        gpr: iomuxc-gpr@53fa8000 {
                                compatible = "fsl,imx53-ldb";
                                reg = <0x53fa8008 0x4>;
                                gpr = <&gpr>;
-                               clocks = <&clks 122>, <&clks 120>,
-                                        <&clks 115>, <&clks 116>,
-                                        <&clks 123>, <&clks 85>;
+                               clocks = <&clks IMX5_CLK_LDB_DI0_SEL>,
+                                        <&clks IMX5_CLK_LDB_DI1_SEL>,
+                                        <&clks IMX5_CLK_IPU_DI0_SEL>,
+                                        <&clks IMX5_CLK_IPU_DI1_SEL>,
+                                        <&clks IMX5_CLK_LDB_DI0_GATE>,
+                                        <&clks IMX5_CLK_LDB_DI1_GATE>;
                                clock-names = "di0_pll", "di1_pll",
                                              "di0_sel", "di1_sel",
                                              "di0", "di1";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
                                reg = <0x53fb4000 0x4000>;
-                               clocks = <&clks 37>, <&clks 38>;
+                               clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM1_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <61>;
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
                                reg = <0x53fb8000 0x4000>;
-                               clocks = <&clks 39>, <&clks 40>;
+                               clocks = <&clks IMX5_CLK_PWM2_IPG_GATE>,
+                                        <&clks IMX5_CLK_PWM2_HF_GATE>;
                                clock-names = "ipg", "per";
                                interrupts = <94>;
                        };
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x53fbc000 0x4000>;
                                interrupts = <31>;
-                               clocks = <&clks 28>, <&clks 29>;
+                               clocks = <&clks IMX5_CLK_UART1_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART1_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x53fc0000 0x4000>;
                                interrupts = <32>;
-                               clocks = <&clks 30>, <&clks 31>;
+                               clocks = <&clks IMX5_CLK_UART2_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
                                reg = <0x53fc8000 0x4000>;
                                interrupts = <82>;
-                               clocks = <&clks 158>, <&clks 157>;
+                               clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>,
+                                        <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
                                reg = <0x53fcc000 0x4000>;
                                interrupts = <83>;
-                               clocks = <&clks 87>, <&clks 86>;
+                               clocks = <&clks IMX5_CLK_CAN2_IPG_GATE>,
+                                        <&clks IMX5_CLK_CAN2_SERIAL_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
                                reg = <0x53fec000 0x4000>;
                                interrupts = <64>;
-                               clocks = <&clks 88>;
+                               clocks = <&clks IMX5_CLK_I2C3_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x53ff0000 0x4000>;
                                interrupts = <13>;
-                               clocks = <&clks 65>, <&clks 66>;
+                               clocks = <&clks IMX5_CLK_UART4_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART4_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-iim", "fsl,imx27-iim";
                                reg = <0x63f98000 0x4000>;
                                interrupts = <69>;
-                               clocks = <&clks 107>;
+                               clocks = <&clks IMX5_CLK_IIM_GATE>;
                        };
 
                        uart5: serial@63f90000 {
                                compatible = "fsl,imx53-uart", "fsl,imx21-uart";
                                reg = <0x63f90000 0x4000>;
                                interrupts = <86>;
-                               clocks = <&clks 67>, <&clks 68>;
+                               clocks = <&clks IMX5_CLK_UART5_IPG_GATE>,
+                                        <&clks IMX5_CLK_UART5_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                        owire: owire@63fa4000 {
                                compatible = "fsl,imx53-owire", "fsl,imx21-owire";
                                reg = <0x63fa4000 0x4000>;
-                               clocks = <&clks 159>;
+                               clocks = <&clks IMX5_CLK_OWIRE_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
                                reg = <0x63fac000 0x4000>;
                                interrupts = <37>;
-                               clocks = <&clks 53>, <&clks 54>;
+                               clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
+                                        <&clks IMX5_CLK_ECSPI2_PER_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
                                reg = <0x63fb0000 0x4000>;
                                interrupts = <6>;
-                               clocks = <&clks 56>, <&clks 56>;
+                               clocks = <&clks IMX5_CLK_SDMA_GATE>,
+                                        <&clks IMX5_CLK_SDMA_GATE>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
                                compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
                                reg = <0x63fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 55>;
+                               clocks = <&clks IMX5_CLK_CSPI_IPG_GATE>,
+                                        <&clks IMX5_CLK_CSPI_IPG_GATE>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
                                reg = <0x63fc4000 0x4000>;
                                interrupts = <63>;
-                               clocks = <&clks 35>;
+                               clocks = <&clks IMX5_CLK_I2C2_GATE>;
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
                                reg = <0x63fc8000 0x4000>;
                                interrupts = <62>;
-                               clocks = <&clks 34>;
+                               clocks = <&clks IMX5_CLK_I2C1_GATE>;
                                status = "disabled";
                        };
 
                        ssi1: ssi@63fcc000 {
-                               compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+                               compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+                                               "fsl,imx21-ssi";
                                reg = <0x63fcc000 0x4000>;
                                interrupts = <29>;
-                               clocks = <&clks 48>;
+                               clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
                                dmas = <&sdma 28 0 0>,
                                       <&sdma 29 0 0>;
                                dma-names = "rx", "tx";
                                compatible = "fsl,imx53-nand";
                                reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
                                interrupts = <8>;
-                               clocks = <&clks 60>;
+                               clocks = <&clks IMX5_CLK_NFC_GATE>;
                                status = "disabled";
                        };
 
                        ssi3: ssi@63fe8000 {
-                               compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+                               compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+                                               "fsl,imx21-ssi";
                                reg = <0x63fe8000 0x4000>;
                                interrupts = <96>;
-                               clocks = <&clks 50>;
+                               clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>;
                                dmas = <&sdma 46 0 0>,
                                       <&sdma 47 0 0>;
                                dma-names = "rx", "tx";
                                compatible = "fsl,imx53-fec", "fsl,imx25-fec";
                                reg = <0x63fec000 0x4000>;
                                interrupts = <87>;
-                               clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+                               clocks = <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>,
+                                        <&clks IMX5_CLK_FEC_GATE>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
                        };
                                compatible = "fsl,imx53-tve";
                                reg = <0x63ff0000 0x1000>;
                                interrupts = <92>;
-                               clocks = <&clks 69>, <&clks 116>;
+                               clocks = <&clks IMX5_CLK_TVE_GATE>,
+                                        <&clks IMX5_CLK_IPU_DI1_SEL>;
                                clock-names = "tve", "di_sel";
                                status = "disabled";
 
                                compatible = "fsl,imx53-vpu";
                                reg = <0x63ff4000 0x1000>;
                                interrupts = <9>;
-                               clocks = <&clks 63>, <&clks 63>;
+                               clocks = <&clks IMX5_CLK_VPU_GATE>,
+                                        <&clks IMX5_CLK_VPU_GATE>;
                                clock-names = "per", "ahb";
                                iram = <&ocram>;
                                status = "disabled";
                ocram: sram@f8000000 {
                        compatible = "mmio-sram";
                        reg = <0xf8000000 0x20000>;
-                       clocks = <&clks 186>;
+                       clocks = <&clks IMX5_CLK_OCRAM>;
                };
        };
 };
diff --git a/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
new file mode 100644 (file)
index 0000000..994f96a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Sascha Hauer <s.hauer@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
+ */
+
+#ifndef __DTS_V1__
+#define __DTS_V1__
+/dts-v1/;
+#endif
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dfi-fs700-m60.dtsi"
+
+/ {
+       model = "DFI FS700-M60-6DL i.MX6dl Q7 Board";
+       compatible = "dfi,fs700-m60-6dl", "dfi,fs700e-m60", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw51xx.dts b/arch/arm/boot/dts/imx6dl-gw51xx.dts
new file mode 100644 (file)
index 0000000..4bd055f
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw51xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW51XX";
+       compatible = "gw,imx6dl-gw51xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw52xx.dts b/arch/arm/boot/dts/imx6dl-gw52xx.dts
new file mode 100644 (file)
index 0000000..c913605
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw52xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW52XX";
+       compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw53xx.dts b/arch/arm/boot/dts/imx6dl-gw53xx.dts
new file mode 100644 (file)
index 0000000..61818a1
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw53xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW53XX";
+       compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw54xx.dts b/arch/arm/boot/dts/imx6dl-gw54xx.dts
new file mode 100644 (file)
index 0000000..ab38b67
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite GW54XX";
+       compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-nitrogen6x.dts b/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
new file mode 100644 (file)
index 0000000..5f4d33c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Boundary Devices, Inc.
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-nitrogen6x.dtsi"
+
+/ {
+       model = "Freescale i.MX6 DualLite Nitrogen6x Board";
+       compatible = "fsl,imx6dl-nitrogen6x", "fsl,imx6dl";
+};
index b81a7a4ebab6758926143ebd51d59b033a51df23..0ead323fdbd2ff44f10e08eaf09d3bbd7a19fad8 100644 (file)
 #define MX6QDL_PAD_GPIO_5__I2C3_SCL                 0x230 0x600 0x878 0x6 0x2
 #define MX6QDL_PAD_GPIO_5__ARM_EVENTI               0x230 0x600 0x000 0x7 0x0
 #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK              0x234 0x604 0x840 0x0 0x1
+#define MX6QDL_PAD_GPIO_6__ENET_IRQ                0x234 0x604 0x03c 0x11 0xff000609
 #define MX6QDL_PAD_GPIO_6__I2C3_SDA                 0x234 0x604 0x87c 0x2 0x2
 #define MX6QDL_PAD_GPIO_6__GPIO1_IO06               0x234 0x604 0x000 0x5 0x0
 #define MX6QDL_PAD_GPIO_6__SD2_LCTL                 0x234 0x604 0x000 0x6 0x0
 #define MX6QDL_PAD_RGMII_TXC__GPIO6_IO19            0x2d8 0x6c0 0x000 0x5 0x0
 #define MX6QDL_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M   0x2d8 0x6c0 0x000 0x7 0x0
 #define MX6QDL_PAD_SD1_CLK__SD1_CLK                 0x2dc 0x6c4 0x928 0x0 0x1
+#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT          0x2dc 0x6c4 0x000 0x2 0x0
 #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN               0x2dc 0x6c4 0x000 0x3 0x0
 #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20              0x2dc 0x6c4 0x000 0x5 0x0
 #define MX6QDL_PAD_SD1_CMD__SD1_CMD                 0x2e0 0x6c8 0x000 0x0 0x0
diff --git a/arch/arm/boot/dts/imx6dl-sabrelite.dts b/arch/arm/boot/dts/imx6dl-sabrelite.dts
new file mode 100644 (file)
index 0000000..2de0447
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-sabrelite.dtsi"
+
+/ {
+       model = "Freescale i.MX6 DualLite SABRE Lite Board";
+       compatible = "fsl,imx6dl-sabrelite", "fsl,imx6dl";
+};
index 25bbdd6f214bf8362b79519e1a1f66e0e5183a19..5c5f574330f9ea19fb31bbd02560efc55bcc457b 100644 (file)
@@ -8,6 +8,7 @@
  *
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "imx6dl-pinfunc.h"
 #include "imx6qdl.dtsi"
 
                        device_type = "cpu";
                        reg = <0>;
                        next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               996000  1275000
+                               792000  1175000
+                               396000  1075000
+                       >;
+                       fsl,soc-operating-points = <
+                               /* ARM kHz  SOC-PU uV */
+                               996000  1175000
+                               792000  1175000
+                               396000  1175000
+                       >;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       clocks = <&clks 104>, <&clks 6>, <&clks 16>,
+                                <&clks 17>, <&clks 170>;
+                       clock-names = "arm", "pll2_pfd2_396m", "step",
+                                     "pll1_sw", "pll1_sys";
+                       arm-supply = <&reg_arm>;
+                       pu-supply = <&reg_pu>;
+                       soc-supply = <&reg_soc>;
                };
 
                cpu@1 {
 
                        pxp: pxp@020f0000 {
                                reg = <0x020f0000 0x4000>;
-                               interrupts = <0 98 0x04>;
+                               interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epdc: epdc@020f4000 {
                                reg = <0x020f4000 0x4000>;
-                               interrupts = <0 97 0x04>;
+                               interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        lcdif: lcdif@020f8000 {
                                reg = <0x020f8000 0x4000>;
-                               interrupts = <0 39 0x04>;
+                               interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                        };
                };
 
@@ -65,7 +86,7 @@
                                #size-cells = <0>;
                                compatible = "fsl,imx1-i2c";
                                reg = <0x021f8000 0x4000>;
-                               interrupts = <0 35 0x04>;
+                               interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
                        };
                };
index edf1bd9671642e9230b61d71c55a18a7b7c2a554..78df05e9d1ce61ca7d71c0825367cd8cd3757925 100644 (file)
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-always-on;
                };
+
+               reg_usb_otg_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
        };
 
        leds {
@@ -46,7 +59,7 @@
 
 &gpmi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
        status = "disabled"; /* gpmi nand conflicts with SD */
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6q-arm2 {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x80000000
                        >;
                };
-       };
 
-       arm2 {
-               pinctrl_usdhc3_arm2: usdhc3grp-arm2 {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__ENET_MDIO          0x1b0b0
+                               MX6QDL_PAD_KEY_COL2__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                               MX6QDL_PAD_SD4_DAT0__NAND_DQS           0x00b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D26__UART2_RX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D27__UART2_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B     0x1b0b1
+                               MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B     0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL0__UART4_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                               MX6QDL_PAD_SD3_DAT4__SD3_DATA4          0x17059
+                               MX6QDL_PAD_SD3_DAT5__SD3_DATA5          0x17059
+                               MX6QDL_PAD_SD3_DAT6__SD3_DATA6          0x17059
+                               MX6QDL_PAD_SD3_DAT7__SD3_DATA7          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3_cdwp: usdhc3cdwp {
                        fsl,pins = <
                                MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
                                MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
                        >;
                };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                               MX6QDL_PAD_SD4_DAT4__SD4_DATA4          0x17059
+                               MX6QDL_PAD_SD4_DAT5__SD4_DATA5          0x17059
+                               MX6QDL_PAD_SD4_DAT6__SD4_DATA6          0x17059
+                               MX6QDL_PAD_SD4_DAT7__SD4_DATA7          0x17059
+                       >;
+               };
        };
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_2>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
+       interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+                             <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
        status = "okay";
 };
 
        wp-gpios = <&gpio6 14 0>;
        vmmc-supply = <&reg_3p3v>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_1
-                    &pinctrl_usdhc3_arm2>;
+       pinctrl-0 = <&pinctrl_usdhc3
+                    &pinctrl_usdhc3_cdwp>;
        status = "okay";
 };
 
        non-removable;
        vmmc-supply = <&reg_3p3v>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc4_1>;
+       pinctrl-0 = <&pinctrl_usdhc4>;
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_2>;
+       pinctrl-0 = <&pinctrl_uart2>;
        fsl,dte-mode;
        fsl,uart-has-rtscts;
        status = "okay";
 
 &uart4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4_1>;
+       pinctrl-0 = <&pinctrl_uart4>;
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts
new file mode 100644 (file)
index 0000000..99b46f8
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2013 CompuLab Ltd.
+ *
+ * Author: Valentin Raevsky <valentin@compulab.co.il>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+       model = "CompuLab CM-FX6";
+       compatible = "compulab,cm-fx6", "fsl,imx6q";
+
+       memory {
+               reg = <0x10000000 0x80000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               heartbeat-led {
+                       label = "Heartbeat";
+                       gpios = <&gpio2 31 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&iomuxc {
+       imx6q-cm-fx6 {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                               MX6QDL_PAD_SD4_DAT0__NAND_DQS           0x00b1
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL0__UART4_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA      0x1b0b1
+                       >;
+               };
+       };
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
new file mode 100644 (file)
index 0000000..fd0ad9a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Sascha Hauer <s.hauer@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
+ */
+
+#ifndef __DTS_V1__
+#define __DTS_V1__
+/dts-v1/;
+#endif
+
+#include "imx6q.dtsi"
+#include "imx6qdl-dfi-fs700-m60.dtsi"
+
+/ {
+       model = "DFI FS700-M60-6QD i.MX6qd Q7 Board";
+       compatible = "dfi,fs700-m60-6qd", "dfi,fs700e-m60", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
new file mode 100644 (file)
index 0000000..a63bbb3
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2013 Data Modul AG
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx6q.dtsi"
+
+/ {
+       model = "Data Modul eDM-QMX6 Board";
+       compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
+
+       aliases {
+               gpio7 = &stmpe_gpio;
+       };
+
+       memory {
+               reg = <0x10000000 0x80000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio7 12 0>;
+               };
+
+               reg_usb_host1: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_host1_en";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 31 0>;
+                       enable-active-high;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+
+               led-blue {
+                       label = "blue";
+                       gpios = <&stmpe_gpio 8 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led-green {
+                       label = "green";
+                       gpios = <&stmpe_gpio 9 GPIO_ACTIVE_HIGH>;
+               };
+
+               led-pink {
+                       label = "pink";
+                       gpios = <&stmpe_gpio 10 GPIO_ACTIVE_HIGH>;
+               };
+
+               led-red {
+                       label = "red";
+                       gpios = <&stmpe_gpio 11 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio3 23 0>;
+       phy-supply = <&vgen2_1v2_eth>;
+       status = "okay";
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2
+                    &pinctrl_stmpe>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <20 8>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-always-on;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                               regulator-always-on;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_1v2_eth: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vdd_high_in: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       stmpe: stmpe1601@40 {
+               compatible = "st,stmpe1601";
+               reg = <0x40>;
+               interrupts = <30 0>;
+               interrupt-parent = <&gpio3>;
+
+               stmpe_gpio: stmpe_gpio {
+                       #gpio-cells = <2>;
+                       compatible = "st,stmpe-gpio";
+               };
+       };
+
+       temp1: ad7414@4c {
+               compatible = "ad,ad7414";
+               reg = <0x4c>;
+       };
+
+       temp2: ad7414@4d {
+               compatible = "ad,ad7414";
+               reg = <0x4d>;
+       };
+
+       rtc: m41t62@68 {
+               compatible = "stm,m41t62";
+               reg = <0x68>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-dmo-edmqmx6 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x80000000
+                               MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x80000000
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_EB2__I2C2_SCL            0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_stmpe: stmpegrp {
+                       fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D26__UART2_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D27__UART2_RX_DATA       0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                               MX6QDL_PAD_SD4_DAT4__SD4_DATA4          0x17059
+                               MX6QDL_PAD_SD4_DAT5__SD4_DATA5          0x17059
+                               MX6QDL_PAD_SD4_DAT6__SD4_DATA6          0x17059
+                               MX6QDL_PAD_SD4_DAT7__SD4_DATA7          0x17059
+                       >;
+               };
+       };
+};
+
+&sata {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_host1>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       vmmc-supply = <&reg_3p3v>;
+       non-removable;
+       bus-width = <8>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts
new file mode 100644 (file)
index 0000000..4a9b4dc
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 Philipp Zabel
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+       model = "Zealz GK802";
+       compatible = "zealz,imx6q-gk802", "fsl,imx6q";
+
+       chosen {
+               linux,stdout-path = &uart4;
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               recovery-button {
+                       label = "recovery";
+                       gpios = <&gpio3 16 1>;
+                       linux,code = <0x198>; /* KEY_RESTART */
+                       gpio-key,wakeup;
+               };
+       };
+};
+
+/* Internal I2C */
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       clock-frequency = <100000>;
+       status = "okay";
+
+       /* SDMC DM2016 1024 bit EEPROM + 128 bit OTP */
+       eeprom: dm2016@51 {
+               compatible = "sdmc,dm2016";
+               reg = <0x51>;
+       };
+};
+
+/* External I2C via HDMI */
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       clock-frequency = <100000>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-gk802 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* Recovery button, active-low */
+                               MX6QDL_PAD_EIM_D16__GPIO3_IO16  0x100b1
+                               /* RTL8192CU enable GPIO, active-low */
+                               MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_5__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_16__I2C3_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL0__UART4_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+/* External USB-A port (USBOTG) */
+&usbotg {
+       disable-over-current;
+       status = "okay";
+};
+
+/* Internal USB port (USBH1), connected to RTL8192CU */
+&usbh1 {
+       disable-over-current;
+       status = "okay";
+};
+
+/* External microSD */
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       bus-width = <4>;
+       cd-gpios = <&gpio6 11 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+/* Internal microSD */
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       bus-width = <4>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw51xx.dts b/arch/arm/boot/dts/imx6q-gw51xx.dts
new file mode 100644 (file)
index 0000000..af4929a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW51XX";
+       compatible = "gw,imx6q-gw51xx", "gw,ventana", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw52xx.dts b/arch/arm/boot/dts/imx6q-gw52xx.dts
new file mode 100644 (file)
index 0000000..5f71ddb
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw52xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW52XX";
+       compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw53xx.dts b/arch/arm/boot/dts/imx6q-gw53xx.dts
new file mode 100644 (file)
index 0000000..360c316
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw53xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW53XX";
+       compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
new file mode 100644 (file)
index 0000000..902f983
--- /dev/null
@@ -0,0 +1,546 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+
+/ {
+       model = "Gateworks Ventana GW5400-A";
+       compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
+
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               sky2 = &eth1;
+               ssi0 = &ssi1;
+               spi0 = &ecspi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 10 0>; /* 106 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 5 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_h1_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&ecspi1 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio3 19 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               compatible = "sst,w25q256";
+               spi-max-frequency = <30000000>;
+               reg = <0>;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pciclkgen: si52147@6b {
+               compatible = "sil,si52147";
+               reg = <0x6b>;
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: mma8450@1c {
+               compatible = "fsl,mma8450";
+               reg = <0x1c>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&sw4_reg>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>; /* gpio7_12 active low */
+               wakeup-gpios = <&gpio7 12 0>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-gw5400-a {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22    0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19    0x80000000 /* SPINOR_CS0# */
+                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29  0x80000000 /* PCIE RST */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_5__GPIO1_IO05     0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12    0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06   0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_COL2__GPIO4_IO10   0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15   0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD1_DAT0__GPIO1_IO16   0x80000000 /* USBHUB_RST# */
+                               MX6QDL_PAD_SD1_DAT3__GPIO1_IO21   0x80000000 /* MIPI_DIO */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_DAT0__AUD4_RXD           0x130b0
+                               MX6QDL_PAD_SD2_DAT3__AUD4_TXC           0x130b0
+                               MX6QDL_PAD_SD2_DAT2__AUD4_TXD           0x110b0
+                               MX6QDL_PAD_SD2_DAT1__AUD4_TXFS          0x130b0
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x100b1
+                               MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x100b1
+                               MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x100b1
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+       lvds-channel@0 {
+               crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw54xx.dts b/arch/arm/boot/dts/imx6q-gw54xx.dts
new file mode 100644 (file)
index 0000000..ab518d6
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw54xx.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Quad GW54XX";
+       compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6q-nitrogen6x.dts b/arch/arm/boot/dts/imx6q-nitrogen6x.dts
new file mode 100644 (file)
index 0000000..a57866b
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2013 Boundary Devices, Inc.
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-nitrogen6x.dtsi"
+
+/ {
+       model = "Freescale i.MX6 Quad Nitrogen6x Board";
+       compatible = "fsl,imx6q-nitrogen6x", "fsl,imx6q";
+};
+
+&sata {
+       status = "okay";
+};
index 7d37ec60d58d7b4ee41960f79b48b22a94731b53..5607c331fca8f4db3356a93a2aa75f97b1b2b11f 100644 (file)
        status = "okay";
 };
 
+&gpmi {
+       status = "okay";
+};
+
+&sata {
+       status = "okay";
+};
+
 &uart4 {
        status = "okay";
 };
 
+&usbh1 {
+       status = "okay";
+};
+
+&usbotg {
+       status = "okay";
+};
+
 &usdhc2 {
        status = "okay";
 };
index 1a3b50d4d8fa4632afb7e8bc28a215b389f50e26..324f1550976b6503d641c23a5da07c1187fc96c9 100644 (file)
        memory {
                reg = <0x10000000 0x80000000>;
        };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_usb_otg_vbus: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio4 15 0>;
+               };
+
+               reg_usb_h1_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio1 0 0>;
+               };
+       };
 };
 
 &ecspi3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi3_1>;
+       pinctrl-0 = <&pinctrl_ecspi3>;
        status = "okay";
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 24 0>;
@@ -36,7 +60,7 @@
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        eeprom@50 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6q-phytec-pfla02 {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
                                MX6QDL_PAD_DI0_PIN15__GPIO4_IO17  0x80000000 /* PMIC interrupt */
                        >;
                };
-       };
 
-       pfla02 {
-               pinctrl_usdhc3_pfla02: usdhc3grp-pfla02 {
+               pinctrl_ecspi3: ecspi3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                               MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                               MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN       0x1b0b0
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                               MX6QDL_PAD_SD4_DAT0__NAND_DQS           0x00b1
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL0__UART4_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbh1: usbh1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_0__USB_H1_PWR           0x80000000
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                               MX6QDL_PAD_KEY_COL4__USB_OTG_OC         0x1b0b0
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x80000000
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                               MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3_cdwp: usdhc3cdwp {
                        fsl,pins = <
                                MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
                                MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_3>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio3 23 0>;
        status = "disabled";
 };
 
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       nand-on-flash-bbt;
+       status = "disabled";
+};
+
 &uart4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4_1>;
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "disabled";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh1>;
+       status = "disabled";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
        status = "disabled";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2_2>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
        cd-gpios = <&gpio1 4 0>;
        wp-gpios = <&gpio1 2 0>;
        status = "disabled";
 
 &usdhc3 {
         pinctrl-names = "default";
-        pinctrl-0 = <&pinctrl_usdhc3_2
-                    &pinctrl_usdhc3_pfla02>;
+        pinctrl-0 = <&pinctrl_usdhc3
+                    &pinctrl_usdhc3_cdwp>;
         cd-gpios = <&gpio1 27 0>;
         wp-gpios = <&gpio1 29 0>;
         status = "disabled";
index 97ed0816a6e0c749b5bccd2562b2cbe8655ff326..9fc6120a185378ea95d439d498f7dbfdbde2b9ba 100644 (file)
 #define MX6QDL_PAD_GPIO_3__USB_H1_OC                0x22c 0x5fc 0x948 0x6 0x1
 #define MX6QDL_PAD_GPIO_3__MLB_CLK                  0x22c 0x5fc 0x900 0x7 0x1
 #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK              0x230 0x600 0x870 0x0 0x1
+#define MX6QDL_PAD_GPIO_6__ENET_IRQ                0x230 0x600 0x03c 0x11 0xff000609
 #define MX6QDL_PAD_GPIO_6__I2C3_SDA                 0x230 0x600 0x8ac 0x2 0x1
 #define MX6QDL_PAD_GPIO_6__GPIO1_IO06               0x230 0x600 0x000 0x5 0x0
 #define MX6QDL_PAD_GPIO_6__SD2_LCTL                 0x230 0x600 0x000 0x6 0x0
 #define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB      0x34c 0x734 0x000 0x6 0x0
 #define MX6QDL_PAD_SD1_CLK__SD1_CLK                 0x350 0x738 0x000 0x0 0x0
 #define MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK             0x350 0x738 0x828 0x1 0x0
+#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT          0x350 0x738 0x000 0x2 0x0
 #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN               0x350 0x738 0x000 0x3 0x0
 #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20              0x350 0x738 0x000 0x5 0x0
 #define MX6QDL_PAD_SD2_CLK__SD2_CLK                 0x354 0x73c 0x000 0x0 0x0
index f004913f7d80a1f2c0df7b229f7a011b17399818..96e4688be77c20423015883e4d0cec51bf8118ed 100644 (file)
 
 /dts-v1/;
 #include "imx6q.dtsi"
+#include "imx6qdl-sabrelite.dtsi"
 
 / {
        model = "Freescale i.MX6 Quad SABRE Lite Board";
        compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
-
-       memory {
-               reg = <0x10000000 0x40000000>;
-       };
-
-       regulators {
-               compatible = "simple-bus";
-
-               reg_2p5v: 2p5v {
-                       compatible = "regulator-fixed";
-                       regulator-name = "2P5V";
-                       regulator-min-microvolt = <2500000>;
-                       regulator-max-microvolt = <2500000>;
-                       regulator-always-on;
-               };
-
-               reg_3p3v: 3p3v {
-                       compatible = "regulator-fixed";
-                       regulator-name = "3P3V";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-always-on;
-               };
-
-               reg_usb_otg_vbus: usb_otg_vbus {
-                       compatible = "regulator-fixed";
-                       regulator-name = "usb_otg_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio3 22 0>;
-                       enable-active-high;
-               };
-       };
-
-       sound {
-               compatible = "fsl,imx6q-sabrelite-sgtl5000",
-                            "fsl,imx-audio-sgtl5000";
-               model = "imx6q-sabrelite-sgtl5000";
-               ssi-controller = <&ssi1>;
-               audio-codec = <&codec>;
-               audio-routing =
-                       "MIC_IN", "Mic Jack",
-                       "Mic Jack", "Mic Bias",
-                       "Headphone Jack", "HP_OUT";
-               mux-int-port = <1>;
-               mux-ext-port = <4>;
-       };
-};
-
-&audmux {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_1>;
-};
-
-&ecspi1 {
-       fsl,spi-num-chipselects = <1>;
-       cs-gpios = <&gpio3 19 0>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
-       status = "okay";
-
-       flash: m25p80@0 {
-               compatible = "sst,sst25vf016b";
-               spi-max-frequency = <20000000>;
-               reg = <0>;
-       };
-};
-
-&fec {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
-       phy-mode = "rgmii";
-       phy-reset-gpios = <&gpio3 23 0>;
-       status = "okay";
-};
-
-&i2c1 {
-       status = "okay";
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_1>;
-
-       codec: sgtl5000@0a {
-               compatible = "fsl,sgtl5000";
-               reg = <0x0a>;
-               clocks = <&clks 201>;
-               VDDA-supply = <&reg_2p5v>;
-               VDDIO-supply = <&reg_3p3v>;
-       };
-};
-
-&iomuxc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_hog>;
-
-       hog {
-               pinctrl_hog: hoggrp {
-                       fsl,pins = <
-                               MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x80000000
-                               MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x80000000
-                               MX6QDL_PAD_EIM_D19__GPIO3_IO19  0x80000000
-                               MX6QDL_PAD_EIM_D22__GPIO3_IO22  0x80000000
-                               MX6QDL_PAD_EIM_D23__GPIO3_IO23  0x80000000
-                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000
-                               MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0
-                               MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x80000000
-                               MX6QDL_PAD_EIM_D23__GPIO3_IO23  0x80000000
-                       >;
-               };
-       };
-};
-
-&ldb {
-       status = "okay";
-
-       lvds-channel@0 {
-               fsl,data-mapping = "spwg";
-               fsl,data-width = <18>;
-               status = "okay";
-
-               display-timings {
-                       native-mode = <&timing0>;
-                       timing0: hsd100pxn1 {
-                               clock-frequency = <65000000>;
-                               hactive = <1024>;
-                               vactive = <768>;
-                               hback-porch = <220>;
-                               hfront-porch = <40>;
-                               vback-porch = <21>;
-                               vfront-porch = <7>;
-                               hsync-len = <60>;
-                               vsync-len = <10>;
-                       };
-               };
-       };
 };
 
 &sata {
        status = "okay";
 };
-
-&ssi1 {
-       fsl,mode = "i2s-slave";
-       status = "okay";
-};
-
-&uart2 {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
-};
-
-&usbh1 {
-       status = "okay";
-};
-
-&usbotg {
-       vbus-supply = <&reg_usb_otg_vbus>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
-       disable-over-current;
-       status = "okay";
-};
-
-&usdhc3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
-       cd-gpios = <&gpio7 0 0>;
-       wp-gpios = <&gpio7 1 0>;
-       vmmc-supply = <&reg_3p3v>;
-       status = "okay";
-};
-
-&usdhc4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc4_2>;
-       cd-gpios = <&gpio2 6 0>;
-       wp-gpios = <&gpio2 7 0>;
-       vmmc-supply = <&reg_3p3v>;
-       status = "okay";
-};
index ee6addf149af988aa560ee3fdc54a3dc27817c36..86cf0936466425a67428a13bc1ca9f24a5592403 100644 (file)
        };
 };
 
+
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        status = "okay";
 };
 
+&iomuxc {
+       imx6q-sbc6x {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
+                               MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &usbotg {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        status = "okay";
 };
index 6e1ccdc019a74c1c5416ac06fbc01c4c17b5f489..ed397d149ab6533525c1e30b94fbf1770144fcf9 100644 (file)
        };
 };
 
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&iomuxc {
+       imx6q-udoo {
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D26__UART2_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D27__UART2_RX_DATA       0x1b0b1
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
 &sata {
        status = "okay";
 };
 
 &uart2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart2_1>;
+       pinctrl-0 = <&pinctrl_uart2>;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        non-removable;
        status = "okay";
 };
index 2a8d9de666c9313e62e4420b23e76cfa1c08effa..addd3f881ce2b6358cbfce34822e3273af714a63 100644 (file)
@@ -8,10 +8,15 @@
  *
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "imx6q-pinfunc.h"
 #include "imx6qdl.dtsi"
 
 / {
+       aliases {
+               spi4 = &ecspi5;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                                /* kHz    uV */
                                1200000 1275000
                                996000  1250000
+                               852000  1250000
                                792000  1150000
-                               396000  950000
+                               396000  975000
+                       >;
+                       fsl,soc-operating-points = <
+                               /* ARM kHz  SOC-PU uV */
+                               1200000 1275000
+                               996000  1250000
+                               852000  1250000
+                               792000  1175000
+                               396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
                        clocks = <&clks 104>, <&clks 6>, <&clks 16>,
@@ -74,7 +88,7 @@
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02018000 0x4000>;
-                                       interrupts = <0 35 0x04>;
+                                       interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 116>, <&clks 116>;
                                        clock-names = "ipg", "per";
                                        status = "disabled";
                sata: sata@02200000 {
                        compatible = "fsl,imx6q-ahci";
                        reg = <0x02200000 0x4000>;
-                       interrupts = <0 39 0x04>;
+                       interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                        clocks =  <&clks 154>, <&clks 187>, <&clks 105>;
                        clock-names = "sata", "sata_ref", "ahb";
                        status = "disabled";
                        #size-cells = <0>;
                        compatible = "fsl,imx6q-ipu";
                        reg = <0x02800000 0x400000>;
-                       interrupts = <0 8 0x4 0 7 0x4>;
+                       interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 7 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clks 133>, <&clks 134>, <&clks 137>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 4>;
diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
new file mode 100644 (file)
index 0000000..25cf035
--- /dev/null
@@ -0,0 +1,199 @@
+/ {
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dummy_reg: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "dummy-supply";
+               };
+
+               reg_usb_otg_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       chosen {
+               linux,stdout-path = &uart1;
+       };
+};
+
+&ecspi3 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio4 24 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "sst,sst25vf040b", "m25p80";
+               spi-max-frequency = <20000000>;
+               reg = <0>;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       status = "okay";
+       phy-mode = "rgmii";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-dfi-fs700-m60 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
+                               MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
+                               MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
+                               MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_EB2__I2C2_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D16__I2C2_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
+                               MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID       0x17059
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                               MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+                               MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* card detect */
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                               MX6QDL_PAD_SD4_DAT4__SD4_DATA4          0x17059
+                               MX6QDL_PAD_SD4_DAT5__SD4_DATA5          0x17059
+                               MX6QDL_PAD_SD4_DAT6__SD4_DATA6          0x17059
+                               MX6QDL_PAD_SD4_DAT7__SD4_DATA7          0x17059
+                       >;
+               };
+
+               pinctrl_ecspi3: ecspi3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                               MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                               MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+                               MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
+                       >;
+               };
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usdhc2 { /* module slot */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       cd-gpios = <&gpio2 2 0>;
+       status = "okay";
+};
+
+&usdhc3 { /* baseboard slot */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+};
+
+&usdhc4 { /* eMMC */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
new file mode 100644 (file)
index 0000000..98a4221
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               can0 = &can1;
+               ethernet0 = &fec;
+               led0 = &led0;
+               led1 = &led1;
+               nand = &gpmi;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x20000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_5p0v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "5P0V";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: ltc3676@3c {
+               compatible = "ltc,ltc3676";
+               reg = <0x3c>;
+
+               regulators {
+                       sw1_reg: ltc3676__sw1 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: ltc3676__sw2 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: ltc3676__sw3 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: ltc3676__sw4 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ltc3676__ldo2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: ltc3676__ldo4 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw51xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A19__GPIO2_IO19   0x80000000 /* MEZZ_DIO0 */
+                               MX6QDL_PAD_EIM_A20__GPIO2_IO18   0x80000000 /* MEZZ_DIO1 */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22   0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
+                               MX6QDL_PAD_GPIO_0__GPIO1_IO00    0x80000000 /* PCIE_RST# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06  0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07  0x80000000 /* user2 led */
+                        >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 0 0>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
new file mode 100644 (file)
index 0000000..8e99c9a
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               ethernet0 = &fec;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               ssi0 = &ssi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 - MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x20000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               /* remove this fixed regulator once ltc3676__sw2 driver available */
+               reg_1p8v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "1P8V";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_5p0v: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "5P0V";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pmic: ltc3676@3c {
+               compatible = "ltc,ltc3676";
+               reg = <0x3c>;
+
+               regulators {
+                       sw1_reg: ltc3676__sw1 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: ltc3676__sw2 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: ltc3676__sw3 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: ltc3676__sw4 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: ltc3676__ldo2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo3_reg: ltc3676__ldo3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: ltc3676__ldo4 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: fxos8700@1e {
+               compatible = "fsl,fxos8700";
+               reg = <0x13>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 169>;
+               VDDA-supply = <&reg_1p8v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>; /* gpio7_12 active low */
+               wakeup-gpios = <&gpio7 12 0>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw52xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A19__GPIO2_IO19   0x80000000 /* MEZZ_DIO0 */
+                               MX6QDL_PAD_EIM_A20__GPIO2_IO18   0x80000000 /* MEZZ_DIO1 */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22   0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_EIM_D31__GPIO3_IO31   0x80000000 /* VIDDEC_PDN# */
+                               MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE_RST# */
+                               MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_PWDN */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1     0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_2__GPIO1_IO02    0x80000000 /* USB_SEL_PCI */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12   0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06  0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07  0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15  0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD2_CMD__GPIO1_IO11   0x80000000 /* LVDS_TCH# */
+                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00  0x80000000 /* SD3_CD# */
+                               MX6QDL_PAD_SD4_DAT3__GPIO2_IO11  0x80000000 /* UART2_EN# */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_DAT0__AUD4_RXD           0x130b0
+                               MX6QDL_PAD_SD2_DAT3__AUD4_TXC           0x130b0
+                               MX6QDL_PAD_SD2_DAT2__AUD4_TXD           0x110b0
+                               MX6QDL_PAD_SD2_DAT1__AUD4_TXFS          0x130b0
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+       lvds-channel@0 {
+               crtcs = <&ipu1 0>, <&ipu1 1>;
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
new file mode 100644 (file)
index 0000000..c8e5ae0
--- /dev/null
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               can0 = &can1;
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               sky2 = &eth1;
+               ssi0 = &ssi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               /* remove when pmic 1p8 regulator available */
+               reg_1p8v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "1P8V";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_h1_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pciclkgen: si53156@6b {
+               compatible = "sil,si53156";
+               reg = <0x6b>;
+       };
+
+       pciswitch: pex8606@3f {
+               compatible = "plx,pex8606";
+               reg = <0x3f>;
+       };
+
+       pmic: ltc3676@3c {
+               compatible = "ltc,ltc3676";
+               reg = <0x3c>;
+
+               regulators {
+                       /* VDD_SOC */
+                       sw1_reg: ltc3676__sw1 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_1P8 */
+                       sw2_reg: ltc3676__sw2 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_ARM */
+                       sw3_reg: ltc3676__sw3 {
+                               regulator-min-microvolt = <1175000>;
+                               regulator-max-microvolt = <1175000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_DDR */
+                       sw4_reg: ltc3676__sw4 {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_2P5 */
+                       ldo2_reg: ltc3676__ldo2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_1P8 */
+                       ldo3_reg: ltc3676__ldo3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       /* VDD_HIGH */
+                       ldo4_reg: ltc3676__ldo4 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: fxos8700@1e {
+               compatible = "fsl,fxos8700";
+               reg = <0x1e>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&reg_1p8v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <11 2>; /* gpio1_11 active low */
+               wakeup-gpios = <&gpio1 11 0>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw53xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_A19__GPIO2_IO19    0x80000000 /* PCIE6EXP_DIO0 */
+                               MX6QDL_PAD_EIM_A20__GPIO2_IO18    0x80000000 /* PCIE6EXP_DIO1 */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22    0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_ENET_RXD0__GPIO1_IO27  0x80000000 /* GPS_SHDN */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26  0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29  0x80000000 /* PCIE RST */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_2__GPIO1_IO02     0x80000000 /* CAN_STBY */
+                               MX6QDL_PAD_GPIO_8__GPIO1_IO08     0x80000000 /* PMIC_IRQ# */
+                               MX6QDL_PAD_GPIO_9__GPIO1_IO09     0x80000000 /* HUB_RST# */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12    0x80000000 /* PCIE_WDIS# */
+                               MX6QDL_PAD_GPIO_19__GPIO4_IO05    0x80000000 /* ACCEL_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06   0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_COL4__GPIO4_IO14   0x80000000 /* USBOTG_OC# */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07   0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15   0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD2_CMD__GPIO1_IO11    0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00   0x80000000 /* SD3_DET# */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_DAT0__AUD4_RXD           0x130b0
+                               MX6QDL_PAD_SD2_DAT3__AUD4_TXC           0x130b0
+                               MX6QDL_PAD_SD2_DAT2__AUD4_TXD           0x110b0
+                               MX6QDL_PAD_SD2_DAT1__AUD4_TXFS          0x130b0
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_flexcan1: flexcan1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX        0x80000000
+                               MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX        0x80000000
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@1 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
new file mode 100644 (file)
index 0000000..2795dfc
--- /dev/null
@@ -0,0 +1,580 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * 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
+ */
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               can0 = &can1;
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               sky2 = &eth1;
+               ssi0 = &ssi1;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+               usdhc2 = &usdhc3;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               gpios = <&gpio1 26 0>;
+               status = "okay";
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_1p0v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "1P0V";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_h1_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>; /* AUD4<->sgtl5000 */
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pciclkgen: si52147@6b {
+               compatible = "sil,si52147";
+               reg = <0x6b>;
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accelerometer: fxos8700@1e {
+               compatible = "fsl,fxos8700";
+               reg = <0x1e>;
+       };
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&sw4_reg>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <12 2>; /* gpio7_12 active low */
+               wakeup-gpios = <&gpio7 12 0>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6qdl-gw54xx {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22    0x80000000 /* OTG_PWR_EN */
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19    0x80000000 /* SPINOR_CS0# */
+                               MX6QDL_PAD_ENET_RXD1__GPIO1_IO26  0x80000000 /* GPS_PPS */
+                               MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29  0x80000000 /* PCIE RST */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x000130b0 /* AUD4_MCK */
+                               MX6QDL_PAD_GPIO_2__GPIO1_IO02     0x80000000 /* CAN_STBY */
+                               MX6QDL_PAD_GPIO_17__GPIO7_IO12    0x80000000 /* TOUCH_IRQ# */
+                               MX6QDL_PAD_KEY_COL0__GPIO4_IO06   0x80000000 /* user1 led */
+                               MX6QDL_PAD_KEY_ROW0__GPIO4_IO07   0x80000000 /* user2 led */
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15   0x80000000 /* user3 led */
+                               MX6QDL_PAD_SD1_DAT0__GPIO1_IO16   0x80000000 /* USBHUB_RST# */
+                               MX6QDL_PAD_SD1_DAT3__GPIO1_IO21   0x80000000 /* MIPI_DIO */
+                        >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_DAT0__AUD4_RXD           0x130b0
+                               MX6QDL_PAD_SD2_DAT3__AUD4_TXC           0x130b0
+                               MX6QDL_PAD_SD2_DAT2__AUD4_TXD           0x110b0
+                               MX6QDL_PAD_SD2_DAT1__AUD4_TXFS          0x130b0
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_flexcan1: flexcan1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX        0x80000000
+                               MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX        0x80000000
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart5: uart5grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@1 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       reset-gpio = <&gpio1 29 0>;
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+       };
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
new file mode 100644 (file)
index 0000000..99be301
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2013 Boundary Devices, Inc.
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_2p5v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
+
+               power {
+                       label = "Power Button";
+                       gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       gpio-key,wakeup;
+               };
+
+               menu {
+                       label = "Menu";
+                       gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_MENU>;
+               };
+
+               home {
+                       label = "Home";
+                       gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOME>;
+               };
+
+               back {
+                       label = "Back";
+                       gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_BACK>;
+               };
+
+               volume-up {
+                       label = "Volume Up";
+                       gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+
+               volume-down {
+                       label = "Volume Down";
+                       gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-nitrogen6x-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-nitrogen6x-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <3>;
+       };
+
+       backlight_lcd {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               power-supply = <&reg_3p3v>;
+               status = "okay";
+       };
+
+       backlight_lvds {
+               compatible = "pwm-backlight";
+               pwms = <&pwm4 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               power-supply = <&reg_3p3v>;
+               status = "okay";
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&ecspi1 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio3 19 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               compatible = "sst,sst25vf016b";
+               spi-max-frequency = <20000000>;
+               reg = <0>;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 27 0>;
+       txen-skew-ps = <0>;
+       txc-skew-ps = <3000>;
+       rxdv-skew-ps = <0>;
+       rxc-skew-ps = <3000>;
+       rxd0-skew-ps = <0>;
+       rxd1-skew-ps = <0>;
+       rxd2-skew-ps = <0>;
+       rxd3-skew-ps = <0>;
+       txd0-skew-ps = <0>;
+       txd1-skew-ps = <0>;
+       txd2-skew-ps = <0>;
+       txd3-skew-ps = <0>;
+       interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+                             <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&reg_2p5v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-nitrogen6x {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* SGTL5000 sys_mclk */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x030b0
+                       >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
+                               MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
+                               MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
+                               MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x100b1
+                               MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x100b1
+                               MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x100b1
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19  0x000b1 /* CS */
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x100b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x100b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x100b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x100b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x100b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x100b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x100b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x100b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x100b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               /* Phy reset */
+                               MX6QDL_PAD_ENET_RXD0__GPIO1_IO27        0x000b0
+                               MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
+                       >;
+               };
+
+               pinctrl_gpio_keys: gpio_keysgrp {
+                       fsl,pins = <
+                               /* Power Button */
+                               MX6QDL_PAD_NANDF_D3__GPIO2_IO03         0x1b0b0
+                               /* Menu Button */
+                               MX6QDL_PAD_NANDF_D1__GPIO2_IO01         0x1b0b0
+                               /* Home Button */
+                               MX6QDL_PAD_NANDF_D4__GPIO2_IO04         0x1b0b0
+                               /* Back Button */
+                               MX6QDL_PAD_NANDF_D2__GPIO2_IO02         0x1b0b0
+                               /* Volume Up Button */
+                               MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x1b0b0
+                               /* Volume Down Button */
+                               MX6QDL_PAD_GPIO_19__GPIO4_IO05          0x1b0b0
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm4: pwm4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D26__UART2_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D27__UART2_RX_DATA       0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID   0x17059
+                               MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+                               /* power enable, high active */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22  0x000b0
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
+                       >;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                               MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@0 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       status = "okay";
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>;
+       status = "okay";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>;
+       status = "okay";
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       cd-gpios = <&gpio2 6 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
index ff6f1e8f2dd9bfa54a6387998421f1ac8877c841..009abd69385d854c15c4b35bc98aca87a1ef8d84 100644 (file)
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <dt-bindings/gpio/gpio.h>
+
 / {
        memory {
                reg = <0x10000000 0x80000000>;
        };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               user {
+                       label = "debug";
+                       gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       sound-spdif {
+               compatible = "fsl,imx-audio-spdif",
+                          "fsl,imx-sabreauto-spdif";
+               model = "imx-spdif";
+               spdif-controller = <&spdif>;
+               spdif-in;
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm3 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               status = "okay";
+       };
 };
 
 &ecspi1 {
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio3 19 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_sabreauto>;
+       pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
        status = "disabled"; /* pin conflict with WEIM NOR */
 
        flash: m25p80@0 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_2>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
+       interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+                             <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
        status = "okay";
 };
 
 &gpmi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
 };
 
 &iomuxc {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6qdl-sabreauto {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
                                MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
                        >;
                };
-       };
 
-       ecspi1 {
-               pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x100b1
+                               MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x100b1
+                               MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x100b1
+                       >;
+               };
+
+               pinctrl_ecspi1_cs: ecspi1cs {
                        fsl,pins = <
                                MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
                        >;
                };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__ENET_MDIO          0x1b0b0
+                               MX6QDL_PAD_KEY_COL2__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15      0x80000000
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                               MX6QDL_PAD_SD4_DAT0__NAND_DQS           0x00b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_EB2__I2C2_SCL    0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA   0x4001b8b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_spdif: spdifgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL0__UART4_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                               MX6QDL_PAD_SD3_DAT4__SD3_DATA4          0x17059
+                               MX6QDL_PAD_SD3_DAT5__SD3_DATA5          0x17059
+                               MX6QDL_PAD_SD3_DAT6__SD3_DATA6          0x17059
+                               MX6QDL_PAD_SD3_DAT7__SD3_DATA7          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170b9
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x100b9
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170b9
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170b9
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170b9
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170b9
+                               MX6QDL_PAD_SD3_DAT4__SD3_DATA4          0x170b9
+                               MX6QDL_PAD_SD3_DAT5__SD3_DATA5          0x170b9
+                               MX6QDL_PAD_SD3_DAT6__SD3_DATA6          0x170b9
+                               MX6QDL_PAD_SD3_DAT7__SD3_DATA7          0x170b9
+                       >;
+               };
+
+               pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170f9
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x100f9
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170f9
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170f9
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170f9
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170f9
+                               MX6QDL_PAD_SD3_DAT4__SD3_DATA4          0x170f9
+                               MX6QDL_PAD_SD3_DAT5__SD3_DATA5          0x170f9
+                               MX6QDL_PAD_SD3_DAT6__SD3_DATA6          0x170f9
+                               MX6QDL_PAD_SD3_DAT7__SD3_DATA7          0x170f9
+                       >;
+               };
+
+               pinctrl_weim_cs0: weimcs0grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_CS0__EIM_CS0_B           0xb0b1
+                       >;
+               };
+
+               pinctrl_weim_nor: weimnorgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_OE__EIM_OE_B             0xb0b1
+                               MX6QDL_PAD_EIM_RW__EIM_RW               0xb0b1
+                               MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B         0xb060
+                               MX6QDL_PAD_EIM_D16__EIM_DATA16          0x1b0b0
+                               MX6QDL_PAD_EIM_D17__EIM_DATA17          0x1b0b0
+                               MX6QDL_PAD_EIM_D18__EIM_DATA18          0x1b0b0
+                               MX6QDL_PAD_EIM_D19__EIM_DATA19          0x1b0b0
+                               MX6QDL_PAD_EIM_D20__EIM_DATA20          0x1b0b0
+                               MX6QDL_PAD_EIM_D21__EIM_DATA21          0x1b0b0
+                               MX6QDL_PAD_EIM_D22__EIM_DATA22          0x1b0b0
+                               MX6QDL_PAD_EIM_D23__EIM_DATA23          0x1b0b0
+                               MX6QDL_PAD_EIM_D24__EIM_DATA24          0x1b0b0
+                               MX6QDL_PAD_EIM_D25__EIM_DATA25          0x1b0b0
+                               MX6QDL_PAD_EIM_D26__EIM_DATA26          0x1b0b0
+                               MX6QDL_PAD_EIM_D27__EIM_DATA27          0x1b0b0
+                               MX6QDL_PAD_EIM_D28__EIM_DATA28          0x1b0b0
+                               MX6QDL_PAD_EIM_D29__EIM_DATA29          0x1b0b0
+                               MX6QDL_PAD_EIM_D30__EIM_DATA30          0x1b0b0
+                               MX6QDL_PAD_EIM_D31__EIM_DATA31          0x1b0b0
+                               MX6QDL_PAD_EIM_A23__EIM_ADDR23          0xb0b1
+                               MX6QDL_PAD_EIM_A22__EIM_ADDR22          0xb0b1
+                               MX6QDL_PAD_EIM_A21__EIM_ADDR21          0xb0b1
+                               MX6QDL_PAD_EIM_A20__EIM_ADDR20          0xb0b1
+                               MX6QDL_PAD_EIM_A19__EIM_ADDR19          0xb0b1
+                               MX6QDL_PAD_EIM_A18__EIM_ADDR18          0xb0b1
+                               MX6QDL_PAD_EIM_A17__EIM_ADDR17          0xb0b1
+                               MX6QDL_PAD_EIM_A16__EIM_ADDR16          0xb0b1
+                               MX6QDL_PAD_EIM_DA15__EIM_AD15           0xb0b1
+                               MX6QDL_PAD_EIM_DA14__EIM_AD14           0xb0b1
+                               MX6QDL_PAD_EIM_DA13__EIM_AD13           0xb0b1
+                               MX6QDL_PAD_EIM_DA12__EIM_AD12           0xb0b1
+                               MX6QDL_PAD_EIM_DA11__EIM_AD11           0xb0b1
+                               MX6QDL_PAD_EIM_DA10__EIM_AD10           0xb0b1
+                               MX6QDL_PAD_EIM_DA9__EIM_AD09            0xb0b1
+                               MX6QDL_PAD_EIM_DA8__EIM_AD08            0xb0b1
+                               MX6QDL_PAD_EIM_DA7__EIM_AD07            0xb0b1
+                               MX6QDL_PAD_EIM_DA6__EIM_AD06            0xb0b1
+                               MX6QDL_PAD_EIM_DA5__EIM_AD05            0xb0b1
+                               MX6QDL_PAD_EIM_DA4__EIM_AD04            0xb0b1
+                               MX6QDL_PAD_EIM_DA3__EIM_AD03            0xb0b1
+                               MX6QDL_PAD_EIM_DA2__EIM_AD02            0xb0b1
+                               MX6QDL_PAD_EIM_DA1__EIM_AD01            0xb0b1
+                               MX6QDL_PAD_EIM_DA0__EIM_AD00            0xb0b1
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@0 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
        };
 };
 
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>;
+       status = "okay";
+};
+
+&spdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spdif>;
+       status = "okay";
+};
+
 &uart4 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart4_1>;
+       pinctrl-0 = <&pinctrl_uart4>;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3_1>;
-       pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
        cd-gpios = <&gpio6 15 0>;
        wp-gpios = <&gpio1 13 0>;
        status = "okay";
 
 &weim {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
+       pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
        #address-cells = <2>;
        #size-cells = <1>;
        ranges = <0 0 0x08000000 0x08000000>;
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
new file mode 100644 (file)
index 0000000..3bec128
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_2p5v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
+
+               power {
+                       label = "Power Button";
+                       gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       gpio-key,wakeup;
+               };
+
+               menu {
+                       label = "Menu";
+                       gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_MENU>;
+               };
+
+               home {
+                       label = "Home";
+                       gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOME>;
+               };
+
+               back {
+                       label = "Back";
+                       gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_BACK>;
+               };
+
+               volume-up {
+                       label = "Volume Up";
+                       gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+
+               volume-down {
+                       label = "Volume Down";
+                       gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+
+       backlight_lcd {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               power-supply = <&reg_3p3v>;
+               status = "okay";
+       };
+
+       backlight_lvds {
+               compatible = "pwm-backlight";
+               pwms = <&pwm4 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               power-supply = <&reg_3p3v>;
+               status = "okay";
+       };
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux>;
+       status = "okay";
+};
+
+&ecspi1 {
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio3 19 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               compatible = "sst,sst25vf016b";
+               spi-max-frequency = <20000000>;
+               reg = <0>;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+       txen-skew-ps = <0>;
+       txc-skew-ps = <3000>;
+       rxdv-skew-ps = <0>;
+       rxc-skew-ps = <3000>;
+       rxd0-skew-ps = <0>;
+       rxd1-skew-ps = <0>;
+       rxd2-skew-ps = <0>;
+       rxd3-skew-ps = <0>;
+       txd0-skew-ps = <0>;
+       txd1-skew-ps = <0>;
+       txd2-skew-ps = <0>;
+       txd3-skew-ps = <0>;
+       interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+                             <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 201>;
+               VDDA-supply = <&reg_2p5v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-sabrelite {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* SGTL5000 sys_mclk */
+                               MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x030b0
+                       >;
+               };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_DAT0__AUD4_RXD           0x130b0
+                               MX6QDL_PAD_SD2_DAT3__AUD4_TXC           0x130b0
+                               MX6QDL_PAD_SD2_DAT2__AUD4_TXD           0x110b0
+                               MX6QDL_PAD_SD2_DAT1__AUD4_TXFS          0x130b0
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x100b1
+                               MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x100b1
+                               MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x100b1
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19  0x000b1 /* CS */
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x100b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x100b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x100b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x100b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x100b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x100b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x100b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x100b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x100b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               /* Phy reset */
+                               MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x000b0
+                               MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
+                       >;
+               };
+
+               pinctrl_gpio_keys: gpio_keysgrp {
+                       fsl,pins = <
+                               /* Power Button */
+                               MX6QDL_PAD_NANDF_D3__GPIO2_IO03         0x1b0b0
+                               /* Menu Button */
+                               MX6QDL_PAD_NANDF_D1__GPIO2_IO01         0x1b0b0
+                               /* Home Button */
+                               MX6QDL_PAD_NANDF_D4__GPIO2_IO04         0x1b0b0
+                               /* Back Button */
+                               MX6QDL_PAD_NANDF_D2__GPIO2_IO02         0x1b0b0
+                               /* Volume Up Button */
+                               MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x1b0b0
+                               /* Volume Down Button */
+                               MX6QDL_PAD_GPIO_19__GPIO4_IO05          0x1b0b0
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm3: pwm3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm4: pwm4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D26__UART2_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D27__UART2_RX_DATA       0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                               MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
+                               /* power enable, high active */
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22  0x000b0
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                               MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
+                               MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 /* WP */
+                       >;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x17059
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x10059
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x17059
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x17059
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x17059
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x17059
+                               MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
+                       >;
+               };
+       };
+};
+
+&ldb {
+       status = "okay";
+
+       lvds-channel@0 {
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "okay";
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       status = "okay";
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>;
+       status = "okay";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>;
+       status = "okay";
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       cd-gpios = <&gpio7 0 0>;
+       wp-gpios = <&gpio7 1 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       cd-gpios = <&gpio2 6 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
index e75e11b36dffec5ea9e695c01d8f66ac35b83dee..0d816d3be4b697a30998506be266244b78d45590 100644 (file)
@@ -10,6 +10,9 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
 / {
        memory {
                reg = <0x10000000 0x40000000>;
 
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb_otg_vbus: usb_otg_vbus {
+               reg_usb_otg_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb_otg_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -27,8 +33,9 @@
                        enable-active-high;
                };
 
-               reg_usb_h1_vbus: usb_h1_vbus {
+               reg_usb_h1_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb_h1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -36,8 +43,9 @@
                        enable-active-high;
                };
 
-               reg_audio: wm8962_supply {
+               reg_audio: regulator@2 {
                        compatible = "regulator-fixed";
+                       reg = <2>;
                        regulator-name = "wm8962-supply";
                        gpio = <&gpio4 10 0>;
                        enable-active-high;
 
        gpio-keys {
                compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
+
+               power {
+                       label = "Power Button";
+                       gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+                       gpio-key,wakeup;
+                       linux,code = <KEY_POWER>;
+               };
 
                volume-up {
                        label = "Volume Up";
-                       gpios = <&gpio1 4 0>;
+                       gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
                        gpio-key,wakeup;
-                       linux,code = <115>; /* KEY_VOLUMEUP */
+                       linux,code = <KEY_VOLUMEUP>;
                };
 
                volume-down {
                        label = "Volume Down";
-                       gpios = <&gpio1 5 0>;
+                       gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
                        gpio-key,wakeup;
-                       linux,code = <114>; /* KEY_VOLUMEDOWN */
+                       linux,code = <KEY_VOLUMEDOWN>;
                };
        };
 
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 9 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_2>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        status = "okay";
 
        flash: m25p80@0 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio1 25 0>;
        status = "okay";
 &i2c1 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c1_2>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
        codec: wm8962@1a {
        };
 };
 
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
 &i2c3 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c3_2>;
+       pinctrl-0 = <&pinctrl_i2c3>;
        status = "okay";
 
        egalax_ts@04 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6qdl-sabresd {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
-                               MX6QDL_PAD_GPIO_4__GPIO1_IO04   0x80000000
-                               MX6QDL_PAD_GPIO_5__GPIO1_IO05   0x80000000
                                MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
                                MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
                                MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
                                MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
+                               MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
+                               MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
+                               MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL1__ECSPI1_MISO        0x100b1
+                               MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI        0x100b1
+                               MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK        0x100b1
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       >;
+               };
+
+               pinctrl_gpio_keys: gpio_keysgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
+                               MX6QDL_PAD_GPIO_4__GPIO1_IO04  0x80000000
+                               MX6QDL_PAD_GPIO_5__GPIO1_IO05  0x80000000
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT8__I2C1_SDA          0x4001b8b1
+                               MX6QDL_PAD_CSI0_DAT9__I2C1_SCL          0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_DAT3__PWM1_OUT           0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
+                               MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID       0x17059
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                               MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+                               MX6QDL_PAD_NANDF_D4__SD2_DATA4          0x17059
+                               MX6QDL_PAD_NANDF_D5__SD2_DATA5          0x17059
+                               MX6QDL_PAD_NANDF_D6__SD2_DATA6          0x17059
+                               MX6QDL_PAD_NANDF_D7__SD2_DATA7          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                               MX6QDL_PAD_SD3_DAT4__SD3_DATA4          0x17059
+                               MX6QDL_PAD_SD3_DAT5__SD3_DATA5          0x17059
+                               MX6QDL_PAD_SD3_DAT6__SD3_DATA6          0x17059
+                               MX6QDL_PAD_SD3_DAT7__SD3_DATA7          0x17059
+                       >;
+               };
        };
 };
 
 
 &pwm1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_pwm0_1>;
+       pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &usbotg {
        vbus-supply = <&reg_usb_otg_vbus>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_2>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2_1>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
        bus-width = <8>;
        cd-gpios = <&gpio2 2 0>;
        wp-gpios = <&gpio2 3 0>;
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_1>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        bus-width = <8>;
        cd-gpios = <&gpio2 0 0>;
        wp-gpios = <&gpio2 1 0>;
index 35f54792916795dd85d77624289d94ee3ab97811..bdfdf89d405fcf4ae2202844445eeb4adeaa80e7 100644 (file)
 / {
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_2p5v: 2p5v {
+               reg_2p5v: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "2P5V";
                        regulator-min-microvolt = <2500000>;
                        regulator-max-microvolt = <2500000>;
                        regulator-always-on;
                };
 
-               reg_3p3v: 3p3v {
+               reg_3p3v: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "3P3V";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
 
 &audmux {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_audmux_2>;
+       pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
 };
 
 &i2c2 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2_2>;
+       pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
        codec: sgtl5000@0a {
@@ -77,7 +81,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6qdl-wandboard {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6QDL_PAD_GPIO_0__CCM_CLKO1     0x130b0
                                MX6QDL_PAD_EIM_D29__GPIO3_IO29   0x80000000
                        >;
                };
+
+               pinctrl_audmux: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
+                               MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
+                               MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
+                               MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                               MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
+                       >;
+               };
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                               MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+                       >;
+               };
+
+               pinctrl_spdif: spdifgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_RXD0__SPDIF_OUT         0x1b0b0
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
+                               MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D23__UART3_CTS_B         0x1b0b1
+                               MX6QDL_PAD_EIM_EB3__UART3_RTS_B         0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc1: usdhc1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_CMD__SD1_CMD             0x17059
+                               MX6QDL_PAD_SD1_CLK__SD1_CLK             0x10059
+                               MX6QDL_PAD_SD1_DAT0__SD1_DATA0          0x17059
+                               MX6QDL_PAD_SD1_DAT1__SD1_DATA1          0x17059
+                               MX6QDL_PAD_SD1_DAT2__SD1_DATA2          0x17059
+                               MX6QDL_PAD_SD1_DAT3__SD1_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                               MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
        };
 };
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_enet_1>;
+       pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii";
        phy-reset-gpios = <&gpio3 29 0>;
+       interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+                             <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
        status = "okay";
 };
 
 &spdif {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_spdif_3>;
+       pinctrl-0 = <&pinctrl_spdif>;
        status = "okay";
 };
 
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &uart3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart3_2>;
+       pinctrl-0 = <&pinctrl_uart3>;
        fsl,uart-has-rtscts;
        status = "okay";
 };
 
 &usbotg {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg_1>;
+       pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
        dr_mode = "peripheral";
        status = "okay";
 
 &usdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc1_2>;
+       pinctrl-0 = <&pinctrl_usdhc1>;
        cd-gpios = <&gpio1 2 0>;
        status = "okay";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2_2>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
        non-removable;
        status = "okay";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
        cd-gpios = <&gpio3 9 0>;
        status = "okay";
 };
index 64a8cbe9480f17ac8418df1b4d5c90d3e93ab2b5..55cb926fa3f7ed4fbe043587e74d57af344c7bad 100644 (file)
@@ -14,6 +14,8 @@
 
 / {
        aliases {
+               can0 = &can1;
+               can1 = &can2;
                gpio0 = &gpio1;
                gpio1 = &gpio2;
                gpio2 = &gpio3;
                i2c0 = &i2c1;
                i2c1 = &i2c2;
                i2c2 = &i2c3;
+               mmc0 = &usdhc1;
+               mmc1 = &usdhc2;
+               mmc2 = &usdhc3;
+               mmc3 = &usdhc4;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
@@ -33,6 +39,8 @@
                spi1 = &ecspi2;
                spi2 = &ecspi3;
                spi3 = &ecspi4;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
        };
 
        intc: interrupt-controller@00a01000 {
                dma_apbh: dma-apbh@00110000 {
                        compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
                        reg = <0x00110000 0x2000>;
-                       interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
+                       interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 13 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
                        #dma-cells = <1>;
                        dma-channels = <4>;
@@ -88,7 +99,7 @@
                        #size-cells = <1>;
                        reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
                        reg-names = "gpmi-nand", "bch";
-                       interrupts = <0 15 0x04>;
+                       interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "bch";
                        clocks = <&clks 152>, <&clks 153>, <&clks 151>,
                                 <&clks 150>, <&clks 149>;
                L2: l2-cache@00a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
-                       interrupts = <0 92 0x04>;
+                       interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
                        cache-unified;
                        cache-level = <2>;
                        arm,tag-latency = <4 2 3>;
                                  0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
                                  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
                        num-lanes = <1>;
-                       interrupts = <0 123 0x04>;
+                       interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
                        clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
                        status = "disabled";
 
                pmu {
                        compatible = "arm,cortex-a9-pmu";
-                       interrupts = <0 94 0x04>;
+                       interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                aips-bus@02000000 { /* AIPS1 */
                                spdif: spdif@02004000 {
                                        compatible = "fsl,imx35-spdif";
                                        reg = <0x02004000 0x4000>;
-                                       interrupts = <0 52 0x04>;
+                                       interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
                                        dmas = <&sdma 14 18 0>,
                                               <&sdma 15 18 0>;
                                        dma-names = "rx", "tx";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02008000 0x4000>;
-                                       interrupts = <0 31 0x04>;
+                                       interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 112>, <&clks 112>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x0200c000 0x4000>;
-                                       interrupts = <0 32 0x04>;
+                                       interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 113>, <&clks 113>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02010000 0x4000>;
-                                       interrupts = <0 33 0x04>;
+                                       interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 114>, <&clks 114>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02014000 0x4000>;
-                                       interrupts = <0 34 0x04>;
+                                       interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 115>, <&clks 115>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                uart1: serial@02020000 {
                                        compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02020000 0x4000>;
-                                       interrupts = <0 26 0x04>;
+                                       interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 160>, <&clks 161>;
                                        clock-names = "ipg", "per";
                                        dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
 
                                esai: esai@02024000 {
                                        reg = <0x02024000 0x4000>;
-                                       interrupts = <0 51 0x04>;
+                                       interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
                                };
 
                                ssi1: ssi@02028000 {
-                                       compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+                                       compatible = "fsl,imx6q-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x02028000 0x4000>;
-                                       interrupts = <0 46 0x04>;
+                                       interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 178>;
                                        dmas = <&sdma 37 1 0>,
                                               <&sdma 38 1 0>;
                                };
 
                                ssi2: ssi@0202c000 {
-                                       compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+                                       compatible = "fsl,imx6q-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x0202c000 0x4000>;
-                                       interrupts = <0 47 0x04>;
+                                       interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 179>;
                                        dmas = <&sdma 41 1 0>,
                                               <&sdma 42 1 0>;
                                };
 
                                ssi3: ssi@02030000 {
-                                       compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+                                       compatible = "fsl,imx6q-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x02030000 0x4000>;
-                                       interrupts = <0 48 0x04>;
+                                       interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks 180>;
                                        dmas = <&sdma 45 1 0>,
                                               <&sdma 46 1 0>;
 
                                asrc: asrc@02034000 {
                                        reg = <0x02034000 0x4000>;
-                                       interrupts = <0 50 0x04>;
+                                       interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
                                };
 
                                spba@0203c000 {
 
                        vpu: vpu@02040000 {
                                reg = <0x02040000 0x3c000>;
-                               interrupts = <0 3 0x04 0 12 0x04>;
+                               interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 12 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        aipstz@0207c000 { /* AIPSTZ1 */
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02080000 0x4000>;
-                               interrupts = <0 83 0x04>;
+                               interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 145>;
                                clock-names = "ipg", "per";
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02084000 0x4000>;
-                               interrupts = <0 84 0x04>;
+                               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 146>;
                                clock-names = "ipg", "per";
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x02088000 0x4000>;
-                               interrupts = <0 85 0x04>;
+                               interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 147>;
                                clock-names = "ipg", "per";
                        };
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
                                reg = <0x0208c000 0x4000>;
-                               interrupts = <0 86 0x04>;
+                               interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 62>, <&clks 148>;
                                clock-names = "ipg", "per";
                        };
                        can1: flexcan@02090000 {
                                compatible = "fsl,imx6q-flexcan";
                                reg = <0x02090000 0x4000>;
-                               interrupts = <0 110 0x04>;
+                               interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 108>, <&clks 109>;
                                clock-names = "ipg", "per";
+                               status = "disabled";
                        };
 
                        can2: flexcan@02094000 {
                                compatible = "fsl,imx6q-flexcan";
                                reg = <0x02094000 0x4000>;
-                               interrupts = <0 111 0x04>;
+                               interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 110>, <&clks 111>;
                                clock-names = "ipg", "per";
+                               status = "disabled";
                        };
 
                        gpt: gpt@02098000 {
                                compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
                                reg = <0x02098000 0x4000>;
-                               interrupts = <0 55 0x04>;
+                               interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 119>, <&clks 120>;
                                clock-names = "ipg", "per";
                        };
                        gpio1: gpio@0209c000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x0209c000 0x4000>;
-                               interrupts = <0 66 0x04 0 67 0x04>;
+                               interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 67 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio2: gpio@020a0000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a0000 0x4000>;
-                               interrupts = <0 68 0x04 0 69 0x04>;
+                               interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 69 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio3: gpio@020a4000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a4000 0x4000>;
-                               interrupts = <0 70 0x04 0 71 0x04>;
+                               interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 71 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio4: gpio@020a8000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020a8000 0x4000>;
-                               interrupts = <0 72 0x04 0 73 0x04>;
+                               interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 73 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio5: gpio@020ac000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020ac000 0x4000>;
-                               interrupts = <0 74 0x04 0 75 0x04>;
+                               interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 75 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio6: gpio@020b0000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020b0000 0x4000>;
-                               interrupts = <0 76 0x04 0 77 0x04>;
+                               interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 77 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio7: gpio@020b4000 {
                                compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
                                reg = <0x020b4000 0x4000>;
-                               interrupts = <0 78 0x04 0 79 0x04>;
+                               interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 79 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
 
                        kpp: kpp@020b8000 {
                                reg = <0x020b8000 0x4000>;
-                               interrupts = <0 82 0x04>;
+                               interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        wdog1: wdog@020bc000 {
                                compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
                                reg = <0x020bc000 0x4000>;
-                               interrupts = <0 80 0x04>;
+                               interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 0>;
                        };
 
                        wdog2: wdog@020c0000 {
                                compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
                                reg = <0x020c0000 0x4000>;
-                               interrupts = <0 81 0x04>;
+                               interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 0>;
                                status = "disabled";
                        };
                        clks: ccm@020c4000 {
                                compatible = "fsl,imx6q-ccm";
                                reg = <0x020c4000 0x4000>;
-                               interrupts = <0 87 0x04 0 88 0x04>;
+                               interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 88 IRQ_TYPE_LEVEL_HIGH>;
                                #clock-cells = <1>;
                        };
 
                        anatop: anatop@020c8000 {
                                compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
                                reg = <0x020c8000 0x1000>;
-                               interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+                               interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 54 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
 
                                regulator-1p1@110 {
                                        compatible = "fsl,anatop-regulator";
 
                                reg_arm: regulator-vddcore@140 {
                                        compatible = "fsl,anatop-regulator";
-                                       regulator-name = "cpu";
+                                       regulator-name = "vddarm";
                                        regulator-min-microvolt = <725000>;
                                        regulator-max-microvolt = <1450000>;
                                        regulator-always-on;
 
                        tempmon: tempmon {
                                compatible = "fsl,imx6q-tempmon";
-                               interrupts = <0 49 0x04>;
+                               interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
                                fsl,tempmon = <&anatop>;
                                fsl,tempmon-data = <&ocotp>;
+                               clocks = <&clks 172>;
                        };
 
                        usbphy1: usbphy@020c9000 {
                                compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020c9000 0x1000>;
-                               interrupts = <0 44 0x04>;
+                               interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 182>;
+                               fsl,anatop = <&anatop>;
                        };
 
                        usbphy2: usbphy@020ca000 {
                                compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020ca000 0x1000>;
-                               interrupts = <0 45 0x04>;
+                               interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 183>;
+                               fsl,anatop = <&anatop>;
                        };
 
                        snvs@020cc000 {
                                snvs-rtc-lp@34 {
                                        compatible = "fsl,sec-v4.0-mon-rtc-lp";
                                        reg = <0x34 0x58>;
-                                       interrupts = <0 19 0x04 0 20 0x04>;
+                                       interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <0 20 IRQ_TYPE_LEVEL_HIGH>;
                                };
                        };
 
                        epit1: epit@020d0000 { /* EPIT1 */
                                reg = <0x020d0000 0x4000>;
-                               interrupts = <0 56 0x04>;
+                               interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epit2: epit@020d4000 { /* EPIT2 */
                                reg = <0x020d4000 0x4000>;
-                               interrupts = <0 57 0x04>;
+                               interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        src: src@020d8000 {
                                compatible = "fsl,imx6q-src", "fsl,imx51-src";
                                reg = <0x020d8000 0x4000>;
-                               interrupts = <0 91 0x04 0 96 0x04>;
+                               interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 96 IRQ_TYPE_LEVEL_HIGH>;
                                #reset-cells = <1>;
                        };
 
                        gpc: gpc@020dc000 {
                                compatible = "fsl,imx6q-gpc";
                                reg = <0x020dc000 0x4000>;
-                               interrupts = <0 89 0x04 0 90 0x04>;
+                               interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 90 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        gpr: iomuxc-gpr@020e0000 {
                        iomuxc: iomuxc@020e0000 {
                                compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc";
                                reg = <0x020e0000 0x4000>;
-
-                               audmux {
-                                       pinctrl_audmux_1: audmux-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD2_DAT0__AUD4_RXD  0x80000000
-                                                       MX6QDL_PAD_SD2_DAT3__AUD4_TXC  0x80000000
-                                                       MX6QDL_PAD_SD2_DAT2__AUD4_TXD  0x80000000
-                                                       MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_2: audmux-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT7__AUD3_RXD  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT4__AUD3_TXC  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT5__AUD3_TXD  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_audmux_3: audmux-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DISP0_DAT16__AUD5_TXC  0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT19__AUD5_RXD  0x80000000
-                                               >;
-                                       };
-                               };
-
-                               ecspi1 {
-                                       pinctrl_ecspi1_1: ecspi1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
-                                                       MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
-                                                       MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
-                                               >;
-                                       };
-
-                                       pinctrl_ecspi1_2: ecspi1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
-                                                       MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
-                                                       MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
-                                               >;
-                                       };
-                               };
-
-                               ecspi3 {
-                                       pinctrl_ecspi3_1: ecspi3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
-                                                       MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
-                                                       MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
-                                               >;
-                                       };
-                               };
-
-                               enet {
-                                       pinctrl_enet_1: enetgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
-                                                       MX6QDL_PAD_ENET_MDC__ENET_MDC         0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK      0x4001b0a8
-                                               >;
-                                       };
-
-                                       pinctrl_enet_2: enetgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL1__ENET_MDIO        0x1b0b0
-                                                       MX6QDL_PAD_KEY_COL2__ENET_MDC         0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
-                                               >;
-                                       };
-
-                                       pinctrl_enet_3: enetgrp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
-                                                       MX6QDL_PAD_ENET_MDC__ENET_MDC         0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
-                                                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
-                                                       MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN     0x1b0b0
-                                               >;
-                                       };
-                               };
-
-                               esai {
-                                       pinctrl_esai_1: esaigrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1b030
-                                                       MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK  0x1b030
-                                                       MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS     0x1b030
-                                                       MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2  0x1b030
-                                                       MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3   0x1b030
-                                                       MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1   0x1b030
-                                                       MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0    0x1b030
-                                                       MX6QDL_PAD_NANDF_CS2__ESAI_TX0       0x1b030
-                                                       MX6QDL_PAD_NANDF_CS3__ESAI_TX1       0x1b030
-                                               >;
-                                       };
-
-                                       pinctrl_esai_2: esaigrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
-                                                       MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS    0x1b030
-                                                       MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
-                                                       MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3     0x1b030
-                                                       MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1  0x1b030
-                                                       MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0   0x1b030
-                                                       MX6QDL_PAD_GPIO_17__ESAI_TX0        0x1b030
-                                                       MX6QDL_PAD_NANDF_CS3__ESAI_TX1      0x1b030
-                                                       MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK   0x1b030
-                                                       MX6QDL_PAD_GPIO_9__ESAI_RX_FS       0x1b030
-                                               >;
-                                       };
-                               };
-
-                               flexcan1 {
-                                       pinctrl_flexcan1_1: flexcan1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
-                                                       MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_flexcan1_2: flexcan1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_7__FLEXCAN1_TX   0x80000000
-                                                       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               flexcan2 {
-                                       pinctrl_flexcan2_1: flexcan2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x80000000
-                                                       MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x80000000
-                                               >;
-                                       };
-                               };
-
-                               gpmi-nand {
-                                       pinctrl_gpmi_nand_1: gpmi-nand-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_NANDF_CLE__NAND_CLE     0xb0b1
-                                                       MX6QDL_PAD_NANDF_ALE__NAND_ALE     0xb0b1
-                                                       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B   0xb0b1
-                                                       MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
-                                                       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B   0xb0b1
-                                                       MX6QDL_PAD_NANDF_CS1__NAND_CE1_B   0xb0b1
-                                                       MX6QDL_PAD_SD4_CMD__NAND_RE_B      0xb0b1
-                                                       MX6QDL_PAD_SD4_CLK__NAND_WE_B      0xb0b1
-                                                       MX6QDL_PAD_NANDF_D0__NAND_DATA00   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D1__NAND_DATA01   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D2__NAND_DATA02   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D3__NAND_DATA03   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D4__NAND_DATA04   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D5__NAND_DATA05   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D6__NAND_DATA06   0xb0b1
-                                                       MX6QDL_PAD_NANDF_D7__NAND_DATA07   0xb0b1
-                                                       MX6QDL_PAD_SD4_DAT0__NAND_DQS      0x00b1
-                                               >;
-                                       };
-                               };
-
-                               hdmi_hdcp {
-                                       pinctrl_hdmi_hdcp_1: hdmihdcpgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_hdmi_hdcp_2: hdmihdcpgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_hdmi_hdcp_3: hdmihdcpgrp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               hdmi_cec {
-                                       pinctrl_hdmi_cec_1: hdmicecgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0
-                                               >;
-                                       };
-
-                                       pinctrl_hdmi_cec_2: hdmicecgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
-                                               >;
-                                       };
-                               };
-
-                               i2c1 {
-                                       pinctrl_i2c1_1: i2c1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c1_2: i2c1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
-                                                       MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               i2c2 {
-                                       pinctrl_i2c2_1: i2c2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c2_2: i2c2grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c2_3: i2c2grp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_EB2__I2C2_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               i2c3 {
-                                       pinctrl_i2c3_1: i2c3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c3_2: i2c3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
-                                                       MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c3_3: i2c3grp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_5__I2C3_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-
-                                       pinctrl_i2c3_4: i2c3grp-4 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_3__I2C3_SCL  0x4001b8b1
-                                                       MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
-                                               >;
-                                       };
-                               };
-
-                               ipu1 {
-                                       pinctrl_ipu1_1: ipu1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
-                                                       MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
-                                                       MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10
-                                                       MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10
-                                                       MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04        0x80000000
-                                                       MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00   0x10
-                                                       MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01   0x10
-                                                       MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02   0x10
-                                                       MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03   0x10
-                                                       MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04   0x10
-                                                       MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05   0x10
-                                                       MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06   0x10
-                                                       MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07   0x10
-                                                       MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08   0x10
-                                                       MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09   0x10
-                                                       MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10  0x10
-                                                       MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11  0x10
-                                                       MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12  0x10
-                                                       MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13  0x10
-                                                       MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14  0x10
-                                                       MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15  0x10
-                                                       MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16  0x10
-                                                       MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17  0x10
-                                                       MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18  0x10
-                                                       MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19  0x10
-                                                       MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20  0x10
-                                                       MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21  0x10
-                                                       MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22  0x10
-                                                       MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23  0x10
-                                               >;
-                                       };
-
-                                       pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18    0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19    0x80000000
-                                                       MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
-                                                       MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK   0x80000000
-                                                       MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC      0x80000000
-                                                       MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC     0x80000000
-                                               >;
-                                       };
-
-                                       pinctrl_ipu1_3: ipu1grp-3 { /* parallel port 16-bit */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09   0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18  0x80000000
-                                                       MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19  0x80000000
-                                                       MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
-                                                       MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC    0x80000000
-                                                       MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC   0x80000000
-                                               >;
-                                       };
-                               };
-
-                               mlb {
-                                       pinctrl_mlb_1: mlbgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_3__MLB_CLK  0x71
-                                                       MX6QDL_PAD_GPIO_6__MLB_SIG  0x71
-                                                       MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
-                                               >;
-                                       };
-
-                                       pinctrl_mlb_2: mlbgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x71
-                                                       MX6QDL_PAD_GPIO_6__MLB_SIG    0x71
-                                                       MX6QDL_PAD_GPIO_2__MLB_DATA   0x71
-                                               >;
-                                       };
-                               };
-
-                               pwm0 {
-                                       pinctrl_pwm0_1: pwm0grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               pwm3 {
-                                       pinctrl_pwm3_1: pwm3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               spdif {
-                                       pinctrl_spdif_1: spdifgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
-                                               >;
-                                       };
-
-                                       pinctrl_spdif_2: spdifgrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_16__SPDIF_IN  0x1b0b0
-                                                       MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
-                                               >;
-                                       };
-
-                                       pinctrl_spdif_3: spdifgrp-3 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               uart2 {
-                                       pinctrl_uart2_1: uart2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
-                                               >;
-                                       };
-
-                                       pinctrl_uart2_2: uart2grp-2 { /* DTE mode */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D26__UART2_RX_DATA   0x1b0b1
-                                                       MX6QDL_PAD_EIM_D27__UART2_TX_DATA   0x1b0b1
-                                                       MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               uart3 {
-                                       pinctrl_uart3_1: uart3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D30__UART3_CTS_B   0x1b0b1
-                                                       MX6QDL_PAD_EIM_EB3__UART3_RTS_B   0x1b0b1
-                                               >;
-                                       };
-
-                                       pinctrl_uart3_2: uart3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_EIM_D23__UART3_CTS_B   0x1b0b1
-                                                       MX6QDL_PAD_EIM_EB3__UART3_RTS_B   0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               uart4 {
-                                       pinctrl_uart4_1: uart4grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
-                                                       MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               usbotg {
-                                       pinctrl_usbotg_1: usbotggrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg_2: usbotggrp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usbh2 {
-                                       pinctrl_usbh2_1: usbh2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_TXC__USB_H2_DATA      0x40013030
-                                                       MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40013030
-                                               >;
-                                       };
-
-                                       pinctrl_usbh2_2: usbh2grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40017030
-                                               >;
-                                       };
-                               };
-
-                               usbh3 {
-                                       pinctrl_usbh3_1: usbh3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x40013030
-                                                       MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE  0x40013030
-                                               >;
-                                       };
-
-                                       pinctrl_usbh3_2: usbh3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40017030
-                                               >;
-                                       };
-                               };
-
-                               usdhc1 {
-                                       pinctrl_usdhc1_1: usdhc1grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD1_CMD__SD1_CMD    0x17059
-                                                       MX6QDL_PAD_SD1_CLK__SD1_CLK    0x10059
-                                                       MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
-                                                       MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
-                                                       MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
-                                                       MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
-                                                       MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17059
-                                                       MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17059
-                                                       MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17059
-                                                       MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc1_2: usdhc1grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD1_CMD__SD1_CMD    0x17059
-                                                       MX6QDL_PAD_SD1_CLK__SD1_CLK    0x10059
-                                                       MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
-                                                       MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
-                                                       MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
-                                                       MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc2 {
-                                       pinctrl_usdhc2_1: usdhc2grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17059
-                                                       MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10059
-                                                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                                                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                                                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                                                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                                                       MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
-                                                       MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
-                                                       MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
-                                                       MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc2_2: usdhc2grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17059
-                                                       MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10059
-                                                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                                                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                                                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                                                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc3 {
-                                       pinctrl_usdhc3_1: usdhc3grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD    0x17059
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK    0x10059
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
-                                                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
-                                                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
-                                                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
-                                                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { /* 100Mhz */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
-                                                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { /* 200Mhz */
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
-                                                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_2: usdhc3grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD3_CMD__SD3_CMD    0x17059
-                                                       MX6QDL_PAD_SD3_CLK__SD3_CLK    0x10059
-                                                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
-                                                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
-                                                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
-                                                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc4 {
-                                       pinctrl_usdhc4_1: usdhc4grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
-                                                       MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
-                                                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
-                                                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
-                                                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
-                                                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
-                                                       MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
-                                                       MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
-                                                       MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
-                                                       MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc4_2: usdhc4grp-2 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
-                                                       MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
-                                                       MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
-                                                       MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
-                                                       MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
-                                                       MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
-                                               >;
-                                       };
-                               };
-
-                               weim {
-                                       pinctrl_weim_cs0_1: weim_cs0grp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_CS0__EIM_CS0_B   0xb0b1
-                                               >;
-                                       };
-
-                                       pinctrl_weim_nor_1: weim_norgrp-1 {
-                                               fsl,pins = <
-                                                       MX6QDL_PAD_EIM_OE__EIM_OE_B     0xb0b1
-                                                       MX6QDL_PAD_EIM_RW__EIM_RW       0xb0b1
-                                                       MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
-                                                       /* data */
-                                                       MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
-                                                       MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
-                                                       /* address */
-                                                       MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
-                                                       MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
-                                                       MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
-                                                       MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
-                                                       MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
-                                                       MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
-                                                       MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
-                                                       MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
-                                                       MX6QDL_PAD_EIM_DA15__EIM_AD15  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA14__EIM_AD14  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA13__EIM_AD13  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA12__EIM_AD12  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA11__EIM_AD11  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA10__EIM_AD10  0xb0b1
-                                                       MX6QDL_PAD_EIM_DA9__EIM_AD09   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA8__EIM_AD08   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA7__EIM_AD07   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA6__EIM_AD06   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA5__EIM_AD05   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA4__EIM_AD04   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA3__EIM_AD03   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA2__EIM_AD02   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA1__EIM_AD01   0xb0b1
-                                                       MX6QDL_PAD_EIM_DA0__EIM_AD00   0xb0b1
-                                               >;
-                                       };
-                               };
                        };
 
                        ldb: ldb@020e0008 {
 
                        dcic1: dcic@020e4000 {
                                reg = <0x020e4000 0x4000>;
-                               interrupts = <0 124 0x04>;
+                               interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        dcic2: dcic@020e8000 {
                                reg = <0x020e8000 0x4000>;
-                               interrupts = <0 125 0x04>;
+                               interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        sdma: sdma@020ec000 {
                                compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
                                reg = <0x020ec000 0x4000>;
-                               interrupts = <0 2 0x04>;
+                               interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 155>, <&clks 155>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
 
                        caam@02100000 {
                                reg = <0x02100000 0x40000>;
-                               interrupts = <0 105 0x04 0 106 0x04>;
+                               interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 106 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        aipstz@0217c000 { /* AIPSTZ2 */
                        usbotg: usb@02184000 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184000 0x200>;
-                               interrupts = <0 43 0x04>;
+                               interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
                        usbh1: usb@02184200 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184200 0x200>;
-                               interrupts = <0 40 0x04>;
+                               interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
                        usbh2: usb@02184400 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184400 0x200>;
-                               interrupts = <0 41 0x04>;
+                               interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        usbh3: usb@02184600 {
                                compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
                                reg = <0x02184600 0x200>;
-                               interrupts = <0 42 0x04>;
+                               interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 162>;
                                fsl,usbmisc = <&usbmisc 3>;
                                status = "disabled";
                        fec: ethernet@02188000 {
                                compatible = "fsl,imx6q-fec";
                                reg = <0x02188000 0x4000>;
-                               interrupts = <0 118 0x04 0 119 0x04>;
+                               interrupts-extended =
+                                       <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
+                                       <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 117>, <&clks 117>, <&clks 190>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
 
                        mlb@0218c000 {
                                reg = <0x0218c000 0x4000>;
-                               interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
+                               interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 117 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 126 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        usdhc1: usdhc@02190000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02190000 0x4000>;
-                               interrupts = <0 22 0x04>;
+                               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 163>, <&clks 163>, <&clks 163>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                        usdhc2: usdhc@02194000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02194000 0x4000>;
-                               interrupts = <0 23 0x04>;
+                               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 164>, <&clks 164>, <&clks 164>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                        usdhc3: usdhc@02198000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x02198000 0x4000>;
-                               interrupts = <0 24 0x04>;
+                               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 165>, <&clks 165>, <&clks 165>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                        usdhc4: usdhc@0219c000 {
                                compatible = "fsl,imx6q-usdhc";
                                reg = <0x0219c000 0x4000>;
-                               interrupts = <0 25 0x04>;
+                               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 166>, <&clks 166>, <&clks 166>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a0000 0x4000>;
-                               interrupts = <0 36 0x04>;
+                               interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 125>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a4000 0x4000>;
-                               interrupts = <0 37 0x04>;
+                               interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 126>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
                                reg = <0x021a8000 0x4000>;
-                               interrupts = <0 38 0x04>;
+                               interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 127>;
                                status = "disabled";
                        };
                        weim: weim@021b8000 {
                                compatible = "fsl,imx6q-weim";
                                reg = <0x021b8000 0x4000>;
-                               interrupts = <0 14 0x04>;
+                               interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 196>;
                        };
 
 
                        tzasc@021d0000 { /* TZASC1 */
                                reg = <0x021d0000 0x4000>;
-                               interrupts = <0 108 0x04>;
+                               interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        tzasc@021d4000 { /* TZASC2 */
                                reg = <0x021d4000 0x4000>;
-                               interrupts = <0 109 0x04>;
+                               interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        audmux: audmux@021d8000 {
                                status = "disabled";
                        };
 
-                       mipi@021dc000 { /* MIPI-CSI */
+                       mipi_csi: mipi@021dc000 {
                                reg = <0x021dc000 0x4000>;
                        };
 
 
                        vdoa@021e4000 {
                                reg = <0x021e4000 0x4000>;
-                               interrupts = <0 18 0x04>;
+                               interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        uart2: serial@021e8000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021e8000 0x4000>;
-                               interrupts = <0 27 0x04>;
+                               interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
                        uart3: serial@021ec000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021ec000 0x4000>;
-                               interrupts = <0 28 0x04>;
+                               interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
                        uart4: serial@021f0000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021f0000 0x4000>;
-                               interrupts = <0 29 0x04>;
+                               interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
                        uart5: serial@021f4000 {
                                compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
                                reg = <0x021f4000 0x4000>;
-                               interrupts = <0 30 0x04>;
+                               interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks 160>, <&clks 161>;
                                clock-names = "ipg", "per";
                                dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
                        #size-cells = <0>;
                        compatible = "fsl,imx6q-ipu";
                        reg = <0x02400000 0x400000>;
-                       interrupts = <0 6 0x4 0 5 0x4>;
+                       interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
+                                    <0 5 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clks 130>, <&clks 131>, <&clks 132>;
                        clock-names = "bus", "di0", "di1";
                        resets = <&src 2>;
index cc68e19c51631666e8241fbc1d4965a18605ca28..864d8dfb51ca525ebc04c0769073fdeda273835b 100644 (file)
@@ -8,6 +8,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include "imx6sl.dtsi"
 
 / {
                reg = <0x80000000 0x40000000>;
        };
 
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_led>;
+
+               user {
+                       label = "debug";
+                       gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
        regulators {
                compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               reg_usb_otg1_vbus: usb_otg1_vbus {
+               reg_usb_otg1_vbus: regulator@0 {
                        compatible = "regulator-fixed";
+                       reg = <0>;
                        regulator-name = "usb_otg1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
                };
 
-               reg_usb_otg2_vbus: usb_otg2_vbus {
+               reg_usb_otg2_vbus: regulator@1 {
                        compatible = "regulator-fixed";
+                       reg = <1>;
                        regulator-name = "usb_otg2_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio4 2 0>;
                        enable-active-high;
                };
+
+               reg_aud3v: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "wm8962-supply-3v15";
+                       regulator-min-microvolt = <3150000>;
+                       regulator-max-microvolt = <3150000>;
+                       regulator-boot-on;
+               };
+
+               reg_aud4v: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "wm8962-supply-4v2";
+                       regulator-min-microvolt = <4325000>;
+                       regulator-max-microvolt = <4325000>;
+                       regulator-boot-on;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
+               model = "wm8962-audio";
+               ssi-controller = <&ssi2>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "Headphone Jack", "HPOUTL",
+                       "Headphone Jack", "HPOUTR",
+                       "Ext Spk", "SPKOUTL",
+                       "Ext Spk", "SPKOUTR",
+                       "AMIC", "MICBIAS",
+                       "IN3R", "AMIC";
+               mux-int-port = <2>;
+               mux-ext-port = <3>;
        };
 };
 
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux3>;
+       status = "okay";
+};
+
 &ecspi1 {
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio4 11 0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       pinctrl-0 = <&pinctrl_ecspi1>;
        status = "okay";
 
        flash: m25p80@0 {
 
 &fec {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec_1>;
+       pinctrl-0 = <&pinctrl_fec>;
        phy-mode = "rmii";
        status = "okay";
 };
 
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic: pfuze100@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <6250>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3a {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3b_reg: sw3b {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                               regulator-always-on;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       codec: wm8962@1a {
+               compatible = "wlf,wm8962";
+               reg = <0x1a>;
+               clocks = <&clks IMX6SL_CLK_EXTERN_AUDIO>;
+               DCVDD-supply = <&vgen3_reg>;
+               DBVDD-supply = <&reg_aud3v>;
+               AVDD-supply = <&vgen3_reg>;
+               CPVDD-supply = <&vgen3_reg>;
+               MICVDD-supply = <&reg_aud3v>;
+               PLLVDD-supply = <&vgen3_reg>;
+               SPKVDD1-supply = <&reg_aud4v>;
+               SPKVDD2-supply = <&reg_aud4v>;
+       };
+};
+
 &iomuxc {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_hog>;
 
-       hog {
+       imx6sl-evk {
                pinctrl_hog: hoggrp {
                        fsl,pins = <
                                MX6SL_PAD_KEY_ROW7__GPIO4_IO07    0x17059
                                MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
                                MX6SL_PAD_KEY_COL4__GPIO4_IO00  0x80000000
                                MX6SL_PAD_KEY_COL5__GPIO4_IO02  0x80000000
+                               MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
+                       >;
+               };
+
+               pinctrl_audmux3: audmux3grp {
+                       fsl,pins = <
+                               MX6SL_PAD_AUD_RXD__AUD3_RXD       0x4130b0
+                               MX6SL_PAD_AUD_TXC__AUD3_TXC       0x4130b0
+                               MX6SL_PAD_AUD_TXD__AUD3_TXD       0x4110b0
+                               MX6SL_PAD_AUD_TXFS__AUD3_TXFS     0x4130b0
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO      0x100b1
+                               MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI      0x100b1
+                               MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK      0x100b1
+                       >;
+               };
+
+               pinctrl_fec: fecgrp {
+                       fsl,pins = <
+                               MX6SL_PAD_FEC_MDC__FEC_MDC              0x1b0b0
+                               MX6SL_PAD_FEC_MDIO__FEC_MDIO            0x1b0b0
+                               MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV         0x1b0b0
+                               MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0        0x1b0b0
+                               MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1        0x1b0b0
+                               MX6SL_PAD_FEC_TX_EN__FEC_TX_EN          0x1b0b0
+                               MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0        0x1b0b0
+                               MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1        0x1b0b0
+                               MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT      0x4001b0a8
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6SL_PAD_I2C1_SCL__I2C1_SCL    0x4001b8b1
+                               MX6SL_PAD_I2C1_SDA__I2C1_SDA    0x4001b8b1
+                       >;
+               };
+
+
+               pinctrl_i2c2: i2c2grp {
+                       fsl,pins = <
+                               MX6SL_PAD_I2C2_SCL__I2C2_SCL    0x4001b8b1
+                               MX6SL_PAD_I2C2_SDA__I2C2_SDA    0x4001b8b1
+                       >;
+               };
+
+               pinctrl_led: ledgrp {
+                       fsl,pins = <
+                               MX6SL_PAD_HSIC_STROBE__GPIO3_IO20 0x17059
+                       >;
+               };
+
+               pinctrl_kpp: kppgrp {
+                       fsl,pins = <
+                               MX6SL_PAD_KEY_ROW0__KEY_ROW0    0x1b010
+                               MX6SL_PAD_KEY_ROW1__KEY_ROW1    0x1b010
+                               MX6SL_PAD_KEY_ROW2__KEY_ROW2    0x1b0b0
+                               MX6SL_PAD_KEY_COL0__KEY_COL0    0x110b0
+                               MX6SL_PAD_KEY_COL1__KEY_COL1    0x110b0
+                               MX6SL_PAD_KEY_COL2__KEY_COL2    0x110b0
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6SL_PAD_UART1_RXD__UART1_RX_DATA      0x1b0b1
+                               MX6SL_PAD_UART1_TXD__UART1_TX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbotg1: usbotg1grp {
+                       fsl,pins = <
+                               MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID      0x17059
+                       >;
+               };
+
+               pinctrl_usdhc1: usdhc1grp {
+                       fsl,pins = <
+                               MX6SL_PAD_SD1_CMD__SD1_CMD              0x17059
+                               MX6SL_PAD_SD1_CLK__SD1_CLK              0x10059
+                               MX6SL_PAD_SD1_DAT0__SD1_DATA0           0x17059
+                               MX6SL_PAD_SD1_DAT1__SD1_DATA1           0x17059
+                               MX6SL_PAD_SD1_DAT2__SD1_DATA2           0x17059
+                               MX6SL_PAD_SD1_DAT3__SD1_DATA3           0x17059
+                               MX6SL_PAD_SD1_DAT4__SD1_DATA4           0x17059
+                               MX6SL_PAD_SD1_DAT5__SD1_DATA5           0x17059
+                               MX6SL_PAD_SD1_DAT6__SD1_DATA6           0x17059
+                               MX6SL_PAD_SD1_DAT7__SD1_DATA7           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+                       fsl,pins = <
+                               MX6SL_PAD_SD1_CMD__SD1_CMD              0x170b9
+                               MX6SL_PAD_SD1_CLK__SD1_CLK              0x100b9
+                               MX6SL_PAD_SD1_DAT0__SD1_DATA0           0x170b9
+                               MX6SL_PAD_SD1_DAT1__SD1_DATA1           0x170b9
+                               MX6SL_PAD_SD1_DAT2__SD1_DATA2           0x170b9
+                               MX6SL_PAD_SD1_DAT3__SD1_DATA3           0x170b9
+                               MX6SL_PAD_SD1_DAT4__SD1_DATA4           0x170b9
+                               MX6SL_PAD_SD1_DAT5__SD1_DATA5           0x170b9
+                               MX6SL_PAD_SD1_DAT6__SD1_DATA6           0x170b9
+                               MX6SL_PAD_SD1_DAT7__SD1_DATA7           0x170b9
+                       >;
+               };
+
+               pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+                       fsl,pins = <
+                               MX6SL_PAD_SD1_CMD__SD1_CMD              0x170f9
+                               MX6SL_PAD_SD1_CLK__SD1_CLK              0x100f9
+                               MX6SL_PAD_SD1_DAT0__SD1_DATA0           0x170f9
+                               MX6SL_PAD_SD1_DAT1__SD1_DATA1           0x170f9
+                               MX6SL_PAD_SD1_DAT2__SD1_DATA2           0x170f9
+                               MX6SL_PAD_SD1_DAT3__SD1_DATA3           0x170f9
+                               MX6SL_PAD_SD1_DAT4__SD1_DATA4           0x170f9
+                               MX6SL_PAD_SD1_DAT5__SD1_DATA5           0x170f9
+                               MX6SL_PAD_SD1_DAT6__SD1_DATA6           0x170f9
+                               MX6SL_PAD_SD1_DAT7__SD1_DATA7           0x170f9
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6SL_PAD_SD2_CMD__SD2_CMD              0x17059
+                               MX6SL_PAD_SD2_CLK__SD2_CLK              0x10059
+                               MX6SL_PAD_SD2_DAT0__SD2_DATA0           0x17059
+                               MX6SL_PAD_SD2_DAT1__SD2_DATA1           0x17059
+                               MX6SL_PAD_SD2_DAT2__SD2_DATA2           0x17059
+                               MX6SL_PAD_SD2_DAT3__SD2_DATA3           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+                       fsl,pins = <
+                               MX6SL_PAD_SD2_CMD__SD2_CMD              0x170b9
+                               MX6SL_PAD_SD2_CLK__SD2_CLK              0x100b9
+                               MX6SL_PAD_SD2_DAT0__SD2_DATA0           0x170b9
+                               MX6SL_PAD_SD2_DAT1__SD2_DATA1           0x170b9
+                               MX6SL_PAD_SD2_DAT2__SD2_DATA2           0x170b9
+                               MX6SL_PAD_SD2_DAT3__SD2_DATA3           0x170b9
+                       >;
+               };
+
+               pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+                       fsl,pins = <
+                               MX6SL_PAD_SD2_CMD__SD2_CMD              0x170f9
+                               MX6SL_PAD_SD2_CLK__SD2_CLK              0x100f9
+                               MX6SL_PAD_SD2_DAT0__SD2_DATA0           0x170f9
+                               MX6SL_PAD_SD2_DAT1__SD2_DATA1           0x170f9
+                               MX6SL_PAD_SD2_DAT2__SD2_DATA2           0x170f9
+                               MX6SL_PAD_SD2_DAT3__SD2_DATA3           0x170f9
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6SL_PAD_SD3_CMD__SD3_CMD              0x17059
+                               MX6SL_PAD_SD3_CLK__SD3_CLK              0x10059
+                               MX6SL_PAD_SD3_DAT0__SD3_DATA0           0x17059
+                               MX6SL_PAD_SD3_DAT1__SD3_DATA1           0x17059
+                               MX6SL_PAD_SD3_DAT2__SD3_DATA2           0x17059
+                               MX6SL_PAD_SD3_DAT3__SD3_DATA3           0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+                       fsl,pins = <
+                               MX6SL_PAD_SD3_CMD__SD3_CMD              0x170b9
+                               MX6SL_PAD_SD3_CLK__SD3_CLK              0x100b9
+                               MX6SL_PAD_SD3_DAT0__SD3_DATA0           0x170b9
+                               MX6SL_PAD_SD3_DAT1__SD3_DATA1           0x170b9
+                               MX6SL_PAD_SD3_DAT2__SD3_DATA2           0x170b9
+                               MX6SL_PAD_SD3_DAT3__SD3_DATA3           0x170b9
+                       >;
+               };
+
+               pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+                       fsl,pins = <
+                               MX6SL_PAD_SD3_CMD__SD3_CMD              0x170f9
+                               MX6SL_PAD_SD3_CLK__SD3_CLK              0x100f9
+                               MX6SL_PAD_SD3_DAT0__SD3_DATA0           0x170f9
+                               MX6SL_PAD_SD3_DAT1__SD3_DATA1           0x170f9
+                               MX6SL_PAD_SD3_DAT2__SD3_DATA2           0x170f9
+                               MX6SL_PAD_SD3_DAT3__SD3_DATA3           0x170f9
                        >;
                };
        };
 };
 
+&kpp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_kpp>;
+       linux,keymap = <
+                       MATRIX_KEY(0x0, 0x0, KEY_UP)         /* ROW0, COL0 */
+                       MATRIX_KEY(0x0, 0x1, KEY_DOWN)       /* ROW0, COL1 */
+                       MATRIX_KEY(0x0, 0x2, KEY_ENTER)      /* ROW0, COL2 */
+                       MATRIX_KEY(0x1, 0x0, KEY_HOME)       /* ROW1, COL0 */
+                       MATRIX_KEY(0x1, 0x1, KEY_RIGHT)      /* ROW1, COL1 */
+                       MATRIX_KEY(0x1, 0x2, KEY_LEFT)       /* ROW1, COL2 */
+                       MATRIX_KEY(0x2, 0x0, KEY_VOLUMEDOWN) /* ROW2, COL0 */
+                       MATRIX_KEY(0x2, 0x1, KEY_VOLUMEUP)   /* ROW2, COL1 */
+       >;
+       status = "okay";
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
 
 &usbotg1 {
        vbus-supply = <&reg_usb_otg1_vbus>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usbotg1_1>;
+       pinctrl-0 = <&pinctrl_usbotg1>;
        disable-over-current;
        status = "okay";
 };
 
 &usdhc1 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc1_1>;
-       pinctrl-1 = <&pinctrl_usdhc1_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc1_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
        bus-width = <8>;
        cd-gpios = <&gpio4 7 0>;
        wp-gpios = <&gpio4 6 0>;
 
 &usdhc2 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc2_1>;
-       pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
        cd-gpios = <&gpio5 0 0>;
        wp-gpios = <&gpio4 29 0>;
        status = "okay";
 
 &usdhc3 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
-       pinctrl-0 = <&pinctrl_usdhc3_1>;
-       pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
-       pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
        cd-gpios = <&gpio3 22 0>;
        status = "okay";
 };
index 28558f1aaf2da8e67cb6b191f2d11e7964518b59..3cb4941afeef9ab6cb121b4271d78c522ff771f8 100644 (file)
@@ -7,6 +7,7 @@
  *
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "skeleton.dtsi"
 #include "imx6sl-pinfunc.h"
 #include <dt-bindings/clock/imx6sl-clock.h>
@@ -27,6 +28,8 @@
                spi1 = &ecspi2;
                spi2 = &ecspi3;
                spi3 = &ecspi4;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
        };
 
        cpus {
                        device_type = "cpu";
                        reg = <0x0>;
                        next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               996000  1275000
+                               792000  1175000
+                               396000  975000
+                       >;
+                       fsl,soc-operating-points = <
+                               /* ARM kHz      SOC-PU uV */
+                               996000          1225000
+                               792000          1175000
+                               396000          1175000
+                       >;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
+                                       <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
+                                       <&clks IMX6SL_CLK_PLL1_SYS>;
+                       clock-names = "arm", "pll2_pfd2_396m", "step",
+                                     "pll1_sw", "pll1_sys";
+                       arm-supply = <&reg_arm>;
+                       pu-supply = <&reg_pu>;
+                       soc-supply = <&reg_soc>;
                };
        };
 
                interrupt-parent = <&intc>;
                ranges;
 
+               ocram: sram@00900000 {
+                       compatible = "mmio-sram";
+                       reg = <0x00900000 0x20000>;
+                       clocks = <&clks IMX6SL_CLK_OCRAM>;
+               };
+
                L2: l2-cache@00a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
-                       interrupts = <0 92 0x04>;
+                       interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
                        cache-unified;
                        cache-level = <2>;
                        arm,tag-latency = <4 2 3>;
 
                pmu {
                        compatible = "arm,cortex-a9-pmu";
-                       interrupts = <0 94 0x04>;
+                       interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                aips1: aips-bus@02000000 {
 
                                spdif: spdif@02004000 {
                                        reg = <0x02004000 0x4000>;
-                                       interrupts = <0 52 0x04>;
+                                       interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
                                };
 
                                ecspi1: ecspi@02008000 {
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02008000 0x4000>;
-                                       interrupts = <0 31 0x04>;
+                                       interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI1>,
                                                 <&clks IMX6SL_CLK_ECSPI1>;
                                        clock-names = "ipg", "per";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x0200c000 0x4000>;
-                                       interrupts = <0 32 0x04>;
+                                       interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI2>,
                                                 <&clks IMX6SL_CLK_ECSPI2>;
                                        clock-names = "ipg", "per";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02010000 0x4000>;
-                                       interrupts = <0 33 0x04>;
+                                       interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI3>,
                                                 <&clks IMX6SL_CLK_ECSPI3>;
                                        clock-names = "ipg", "per";
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        reg = <0x02014000 0x4000>;
-                                       interrupts = <0 34 0x04>;
+                                       interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_ECSPI4>,
                                                 <&clks IMX6SL_CLK_ECSPI4>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02018000 0x4000>;
-                                       interrupts = <0 30 0x04>;
+                                       interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02020000 0x4000>;
-                                       interrupts = <0 26 0x04>;
+                                       interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02024000 0x4000>;
-                                       interrupts = <0 27 0x04>;
+                                       interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                };
 
                                ssi1: ssi@02028000 {
-                                       compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+                                       compatible = "fsl,imx6sl-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x02028000 0x4000>;
-                                       interrupts = <0 46 0x04>;
+                                       interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_SSI1>;
                                        dmas = <&sdma 37 1 0>,
                                               <&sdma 38 1 0>;
                                };
 
                                ssi2: ssi@0202c000 {
-                                       compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+                                       compatible = "fsl,imx6sl-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x0202c000 0x4000>;
-                                       interrupts = <0 47 0x04>;
+                                       interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_SSI2>;
                                        dmas = <&sdma 41 1 0>,
                                               <&sdma 42 1 0>;
                                };
 
                                ssi3: ssi@02030000 {
-                                       compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+                                       compatible = "fsl,imx6sl-ssi",
+                                                       "fsl,imx51-ssi",
+                                                       "fsl,imx21-ssi";
                                        reg = <0x02030000 0x4000>;
-                                       interrupts = <0 48 0x04>;
+                                       interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_SSI3>;
                                        dmas = <&sdma 45 1 0>,
                                               <&sdma 46 1 0>;
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02034000 0x4000>;
-                                       interrupts = <0 28 0x04>;
+                                       interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                        compatible = "fsl,imx6sl-uart",
                                                   "fsl,imx6q-uart", "fsl,imx21-uart";
                                        reg = <0x02038000 0x4000>;
-                                       interrupts = <0 29 0x04>;
+                                       interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SL_CLK_UART>,
                                                 <&clks IMX6SL_CLK_UART_SERIAL>;
                                        clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x02080000 0x4000>;
-                               interrupts = <0 83 0x04>;
+                               interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM1>,
                                         <&clks IMX6SL_CLK_PWM1>;
                                clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x02084000 0x4000>;
-                               interrupts = <0 84 0x04>;
+                               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM2>,
                                         <&clks IMX6SL_CLK_PWM2>;
                                clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x02088000 0x4000>;
-                               interrupts = <0 85 0x04>;
+                               interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM3>,
                                         <&clks IMX6SL_CLK_PWM3>;
                                clock-names = "ipg", "per";
                                #pwm-cells = <2>;
                                compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
                                reg = <0x0208c000 0x4000>;
-                               interrupts = <0 86 0x04>;
+                               interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_PWM4>,
                                         <&clks IMX6SL_CLK_PWM4>;
                                clock-names = "ipg", "per";
                        gpt: gpt@02098000 {
                                compatible = "fsl,imx6sl-gpt";
                                reg = <0x02098000 0x4000>;
-                               interrupts = <0 55 0x04>;
+                               interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_GPT>,
                                         <&clks IMX6SL_CLK_GPT_SERIAL>;
                                clock-names = "ipg", "per";
                        gpio1: gpio@0209c000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x0209c000 0x4000>;
-                               interrupts = <0 66 0x04 0 67 0x04>;
+                               interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 67 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio2: gpio@020a0000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020a0000 0x4000>;
-                               interrupts = <0 68 0x04 0 69 0x04>;
+                               interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 69 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio3: gpio@020a4000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020a4000 0x4000>;
-                               interrupts = <0 70 0x04 0 71 0x04>;
+                               interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 71 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio4: gpio@020a8000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020a8000 0x4000>;
-                               interrupts = <0 72 0x04 0 73 0x04>;
+                               interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 73 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio5: gpio@020ac000 {
                                compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
                                reg = <0x020ac000 0x4000>;
-                               interrupts = <0 74 0x04 0 75 0x04>;
+                               interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 75 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        };
 
                        kpp: kpp@020b8000 {
+                               compatible = "fsl,imx6sl-kpp", "fsl,imx21-kpp";
                                reg = <0x020b8000 0x4000>;
-                               interrupts = <0 82 0x04>;
+                               interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SL_CLK_DUMMY>;
                        };
 
                        wdog1: wdog@020bc000 {
                                compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
                                reg = <0x020bc000 0x4000>;
-                               interrupts = <0 80 0x04>;
+                               interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_DUMMY>;
                        };
 
                        wdog2: wdog@020c0000 {
                                compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
                                reg = <0x020c0000 0x4000>;
-                               interrupts = <0 81 0x04>;
+                               interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_DUMMY>;
                                status = "disabled";
                        };
                        clks: ccm@020c4000 {
                                compatible = "fsl,imx6sl-ccm";
                                reg = <0x020c4000 0x4000>;
-                               interrupts = <0 87 0x04 0 88 0x04>;
+                               interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 88 IRQ_TYPE_LEVEL_HIGH>;
                                #clock-cells = <1>;
                        };
 
                                             "fsl,imx6q-anatop",
                                             "syscon", "simple-bus";
                                reg = <0x020c8000 0x1000>;
-                               interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+                               interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 54 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
 
                                regulator-1p1@110 {
                                        compatible = "fsl,anatop-regulator";
 
                                reg_arm: regulator-vddcore@140 {
                                        compatible = "fsl,anatop-regulator";
-                                       regulator-name = "cpu";
+                                       regulator-name = "vddarm";
                                        regulator-min-microvolt = <725000>;
                                        regulator-max-microvolt = <1450000>;
                                        regulator-always-on;
                        usbphy1: usbphy@020c9000 {
                                compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020c9000 0x1000>;
-                               interrupts = <0 44 0x04>;
+                               interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBPHY1>;
+                               fsl,anatop = <&anatop>;
                        };
 
                        usbphy2: usbphy@020ca000 {
                                compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
                                reg = <0x020ca000 0x1000>;
-                               interrupts = <0 45 0x04>;
+                               interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBPHY2>;
+                               fsl,anatop = <&anatop>;
                        };
 
                        snvs@020cc000 {
                                snvs-rtc-lp@34 {
                                        compatible = "fsl,sec-v4.0-mon-rtc-lp";
                                        reg = <0x34 0x58>;
-                                       interrupts = <0 19 0x04 0 20 0x04>;
+                                       interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <0 20 IRQ_TYPE_LEVEL_HIGH>;
                                };
                        };
 
                        epit1: epit@020d0000 {
                                reg = <0x020d0000 0x4000>;
-                               interrupts = <0 56 0x04>;
+                               interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epit2: epit@020d4000 {
                                reg = <0x020d4000 0x4000>;
-                               interrupts = <0 57 0x04>;
+                               interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        src: src@020d8000 {
                                compatible = "fsl,imx6sl-src", "fsl,imx51-src";
                                reg = <0x020d8000 0x4000>;
-                               interrupts = <0 91 0x04 0 96 0x04>;
+                               interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
+                                            <0 96 IRQ_TYPE_LEVEL_HIGH>;
                                #reset-cells = <1>;
                        };
 
                        gpc: gpc@020dc000 {
                                compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
                                reg = <0x020dc000 0x4000>;
-                               interrupts = <0 89 0x04>;
+                               interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        gpr: iomuxc-gpr@020e0000 {
                        iomuxc: iomuxc@020e0000 {
                                compatible = "fsl,imx6sl-iomuxc";
                                reg = <0x020e0000 0x4000>;
-
-                               ecspi1 {
-                                       pinctrl_ecspi1_1: ecspi1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
-                                                       MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
-                                                       MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
-                                               >;
-                                       };
-                               };
-
-                               fec {
-                                       pinctrl_fec_1: fecgrp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_FEC_MDC__FEC_MDC         0x1b0b0
-                                                       MX6SL_PAD_FEC_MDIO__FEC_MDIO       0x1b0b0
-                                                       MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV    0x1b0b0
-                                                       MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0   0x1b0b0
-                                                       MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1   0x1b0b0
-                                                       MX6SL_PAD_FEC_TX_EN__FEC_TX_EN     0x1b0b0
-                                                       MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0   0x1b0b0
-                                                       MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1   0x1b0b0
-                                                       MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
-                                                       MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
-                                               >;
-                                       };
-                               };
-
-                               usbotg1 {
-                                       pinctrl_usbotg1_1: usbotg1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_2: usbotg1grp-2 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_3: usbotg1grp-3 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_4: usbotg1grp-4 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg1_5: usbotg1grp-5 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usbotg2 {
-                                       pinctrl_usbotg2_1: usbotg2grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg2_2: usbotg2grp-2 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg2_3: usbotg2grp-3 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usbotg2_4: usbotg2grp-4 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x17059
-                                               >;
-                                       };
-                               };
-
-                               usdhc1 {
-                                       pinctrl_usdhc1_1: usdhc1grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD1_CMD__SD1_CMD    0x17059
-                                                       MX6SL_PAD_SD1_CLK__SD1_CLK    0x10059
-                                                       MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
-                                                       MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
-                                                       MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
-                                                       MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
-                                                       MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
-                                                       MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
-                                                       MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
-                                                       MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc1_1_100mhz: usdhc1grp-1-100mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
-                                                       MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
-                                                       MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
-                                                       MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
-                                                       MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
-                                                       MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
-                                                       MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
-                                                       MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
-                                                       MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
-                                                       MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc1_1_200mhz: usdhc1grp-1-200mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
-                                                       MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
-                                                       MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
-                                                       MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
-                                                       MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
-                                                       MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
-                                                       MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
-                                                       MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
-                                                       MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
-                                                       MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
-                                               >;
-                                       };
-
-
-                               };
-
-                               usdhc2 {
-                                       pinctrl_usdhc2_1: usdhc2grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD2_CMD__SD2_CMD    0x17059
-                                                       MX6SL_PAD_SD2_CLK__SD2_CLK    0x10059
-                                                       MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
-                                                       MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
-                                                       MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
-                                                       MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc2_1_100mhz: usdhc2grp-1-100mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD2_CMD__SD2_CMD    0x170b9
-                                                       MX6SL_PAD_SD2_CLK__SD2_CLK    0x100b9
-                                                       MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
-                                                       MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
-                                                       MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
-                                                       MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc2_1_200mhz: usdhc2grp-1-200mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD2_CMD__SD2_CMD    0x170f9
-                                                       MX6SL_PAD_SD2_CLK__SD2_CLK    0x100f9
-                                                       MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
-                                                       MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
-                                                       MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
-                                                       MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
-                                               >;
-                                       };
-
-                               };
-
-                               usdhc3 {
-                                       pinctrl_usdhc3_1: usdhc3grp-1 {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_CMD__SD3_CMD    0x17059
-                                                       MX6SL_PAD_SD3_CLK__SD3_CLK    0x10059
-                                                       MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
-                                                       MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
-                                                       MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
-                                                       MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_CMD__SD3_CMD    0x170b9
-                                                       MX6SL_PAD_SD3_CLK__SD3_CLK    0x100b9
-                                                       MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
-                                                       MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
-                                                       MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
-                                                       MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
-                                               >;
-                                       };
-
-                                       pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz {
-                                               fsl,pins = <
-                                                       MX6SL_PAD_SD3_CMD__SD3_CMD    0x170f9
-                                                       MX6SL_PAD_SD3_CLK__SD3_CLK    0x100f9
-                                                       MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
-                                                       MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
-                                                       MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
-                                                       MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
-                                               >;
-                                       };
-                               };
                        };
 
                        csi: csi@020e4000 {
                                reg = <0x020e4000 0x4000>;
-                               interrupts = <0 7 0x04>;
+                               interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        spdc: spdc@020e8000 {
                                reg = <0x020e8000 0x4000>;
-                               interrupts = <0 6 0x04>;
+                               interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        sdma: sdma@020ec000 {
                                compatible = "fsl,imx6sl-sdma", "fsl,imx35-sdma";
                                reg = <0x020ec000 0x4000>;
-                               interrupts = <0 2 0x04>;
+                               interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_SDMA>,
                                         <&clks IMX6SL_CLK_SDMA>;
                                clock-names = "ipg", "ahb";
 
                        pxp: pxp@020f0000 {
                                reg = <0x020f0000 0x4000>;
-                               interrupts = <0 98 0x04>;
+                               interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        epdc: epdc@020f4000 {
                                reg = <0x020f4000 0x4000>;
-                               interrupts = <0 97 0x04>;
+                               interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        lcdif: lcdif@020f8000 {
                                reg = <0x020f8000 0x4000>;
-                               interrupts = <0 39 0x04>;
+                               interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        dcp: dcp@020fc000 {
                                reg = <0x020fc000 0x4000>;
-                               interrupts = <0 99 0x04>;
+                               interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
                        };
                };
 
                        usbotg1: usb@02184000 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184000 0x200>;
-                               interrupts = <0 43 0x04>;
+                               interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
                        usbotg2: usb@02184200 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184200 0x200>;
-                               interrupts = <0 42 0x04>;
+                               interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy2>;
                                fsl,usbmisc = <&usbmisc 1>;
                        usbh: usb@02184400 {
                                compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
                                reg = <0x02184400 0x200>;
-                               interrupts = <0 40 0x04>;
+                               interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USBOH3>;
                                fsl,usbmisc = <&usbmisc 2>;
                                status = "disabled";
                        fec: ethernet@02188000 {
                                compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
                                reg = <0x02188000 0x4000>;
-                               interrupts = <0 114 0x04>;
+                               interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_ENET_REF>,
                                         <&clks IMX6SL_CLK_ENET_REF>;
                                clock-names = "ipg", "ahb";
                        usdhc1: usdhc@02190000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x02190000 0x4000>;
-                               interrupts = <0 22 0x04>;
+                               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC1>,
                                         <&clks IMX6SL_CLK_USDHC1>,
                                         <&clks IMX6SL_CLK_USDHC1>;
                        usdhc2: usdhc@02194000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x02194000 0x4000>;
-                               interrupts = <0 23 0x04>;
+                               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC2>,
                                         <&clks IMX6SL_CLK_USDHC2>,
                                         <&clks IMX6SL_CLK_USDHC2>;
                        usdhc3: usdhc@02198000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x02198000 0x4000>;
-                               interrupts = <0 24 0x04>;
+                               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC3>,
                                         <&clks IMX6SL_CLK_USDHC3>,
                                         <&clks IMX6SL_CLK_USDHC3>;
                        usdhc4: usdhc@0219c000 {
                                compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
                                reg = <0x0219c000 0x4000>;
-                               interrupts = <0 25 0x04>;
+                               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_USDHC4>,
                                         <&clks IMX6SL_CLK_USDHC4>,
                                         <&clks IMX6SL_CLK_USDHC4>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
                                reg = <0x021a0000 0x4000>;
-                               interrupts = <0 36 0x04>;
+                               interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_I2C1>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
                                reg = <0x021a4000 0x4000>;
-                               interrupts = <0 37 0x04>;
+                               interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_I2C2>;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
                                reg = <0x021a8000 0x4000>;
-                               interrupts = <0 38 0x04>;
+                               interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SL_CLK_I2C3>;
                                status = "disabled";
                        };
 
                        rngb: rngb@021b4000 {
                                reg = <0x021b4000 0x4000>;
-                               interrupts = <0 5 0x04>;
+                               interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        weim: weim@021b8000 {
                                reg = <0x021b8000 0x4000>;
-                               interrupts = <0 14 0x04>;
+                               interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        ocotp: ocotp@021bc000 {
index e6be9315ff0a54033e07daba296399b8f45112ca..b10e6351da53f229a93488b34b832ea928531875 100644 (file)
                bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";
        };
 
+       /* 24 MHz chrystal on the core module */
+       xtal24mhz: xtal24mhz@24M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+       };
+
+       pclk: pclk@0 {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <1>;
+               clock-mult = <1>;
+               clocks = <&xtal24mhz>;
+       };
+
+       /* The UART clock is 14.74 MHz divided by an ICS525 */
+       uartclk: uartclk@14.74M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <14745600>;
+       };
+
        syscon {
                compatible = "arm,integrator-ap-syscon";
                reg = <0x11000000 0x100>;
 
        timer0: timer@13000000 {
                compatible = "arm,integrator-timer";
+               clocks = <&xtal24mhz>;
        };
 
        timer1: timer@13000100 {
                compatible = "arm,integrator-timer";
+               clocks = <&xtal24mhz>;
        };
 
        timer2: timer@13000200 {
                compatible = "arm,integrator-timer";
+               clocks = <&xtal24mhz>;
        };
 
        pic: pic@14000000 {
                rtc: rtc@15000000 {
                        compatible = "arm,pl030", "arm,primecell";
                        arm,primecell-periphid = <0x00041030>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
                };
 
                uart0: uart@16000000 {
                        compatible = "arm,pl010", "arm,primecell";
                        arm,primecell-periphid = <0x00041010>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
                };
 
                uart1: uart@17000000 {
                        compatible = "arm,pl010", "arm,primecell";
                        arm,primecell-periphid = <0x00041010>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
                };
 
                kmi0: kmi@18000000 {
                        compatible = "arm,pl050", "arm,primecell";
                        arm,primecell-periphid = <0x00041050>;
+                       clocks = <&xtal24mhz>, <&pclk>;
+                       clock-names = "KMIREFCLK", "apb_pclk";
                };
 
                kmi1: kmi@19000000 {
                        compatible = "arm,pl050", "arm,primecell";
                        arm,primecell-periphid = <0x00041050>;
+                       clocks = <&xtal24mhz>, <&pclk>;
+                       clock-names = "KMIREFCLK", "apb_pclk";
                };
        };
 };
index a21c17de9a5e9bcc8f1974deae775faa48aafd14..d43f15b4f79a242d2437f6ea45626556380c010c 100644 (file)
                bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
        };
 
+       /*
+        * The Integrator/CP overall clocking architecture can be found in
+        * ARM DUI 0184B page 7-28 "Integrator/CP922T system clocks" which
+        * appear to illustrate the layout used in most configurations.
+        */
+
+       /* The codec chrystal operates at 24.576 MHz */
+       xtal_codec: xtal24.576@24.576M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24576000>;
+       };
+
+       /* The chrystal is divided by 2 by the codec for the AACI bit clock */
+       aaci_bitclk: aaci_bitclk@12.288M {
+               #clock-cells = <0>;
+               compatible = "fixed-factor-clock";
+               clock-div = <2>;
+               clock-mult = <1>;
+               clocks = <&xtal_codec>;
+       };
+
+       /* This is a 25MHz chrystal on the base board */
+       xtal25mhz: xtal25mhz@25M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <25000000>;
+       };
+
+       /* The UART clock is 14.74 MHz divided from 25MHz by an ICS525 */
+       uartclk: uartclk@14.74M {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <14745600>;
+       };
+
+       /* Actually sysclk I think */
+       pclk: pclk@0 {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+       };
+
+       core-module@10000000 {
+               /* 24 MHz chrystal on the core module */
+               xtal24mhz: xtal24mhz@24M {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <24000000>;
+               };
+
+               /*
+                * External oscillator on the core module, usually used
+                * to drive video circuitry. Driven from the 24MHz clock.
+                */
+               auxosc: cm_aux_osc@25M {
+                       #clock-cells = <0>;
+                       compatible = "arm,integrator-cm-auxosc";
+                       clocks = <&xtal24mhz>;
+               };
+
+               /* The KMI clock is the 24 MHz oscillator divided to 8MHz */
+               kmiclk: kmiclk@1M {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clock-div = <3>;
+                       clock-mult = <1>;
+                       clocks = <&xtal24mhz>;
+               };
+
+               /* The timer clock is the 24 MHz oscillator divided to 1MHz */
+               timclk: timclk@1M {
+                       #clock-cells = <0>;
+                       compatible = "fixed-factor-clock";
+                       clock-div = <24>;
+                       clock-mult = <1>;
+                       clocks = <&xtal24mhz>;
+               };
+       };
+
        syscon {
                compatible = "arm,integrator-cp-syscon";
                reg = <0xcb000000 0x100>;
        };
 
        timer0: timer@13000000 {
-               /* TIMER0 runs @ 25MHz */
+               /* TIMER0 runs directly on the 25MHz chrystal */
                compatible = "arm,integrator-cp-timer";
-               status = "disabled";
+               clocks = <&xtal25mhz>;
        };
 
        timer1: timer@13000100 {
                /* TIMER1 runs @ 1MHz */
                compatible = "arm,integrator-cp-timer";
+               clocks = <&timclk>;
        };
 
        timer2: timer@13000200 {
                /* TIMER2 runs @ 1MHz */
                compatible = "arm,integrator-cp-timer";
+               clocks = <&timclk>;
        };
 
        pic: pic@14000000 {
                 */
                rtc@15000000 {
                        compatible = "arm,pl031", "arm,primecell";
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
                };
 
                uart@16000000 {
                        compatible = "arm,pl011", "arm,primecell";
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
                };
 
                uart@17000000 {
                        compatible = "arm,pl011", "arm,primecell";
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "uartclk", "apb_pclk";
                };
 
                kmi@18000000 {
                        compatible = "arm,pl050", "arm,primecell";
+                       clocks = <&kmiclk>, <&pclk>;
+                       clock-names = "KMIREFCLK", "apb_pclk";
                };
 
                kmi@19000000 {
                        compatible = "arm,pl050", "arm,primecell";
+                       clocks = <&kmiclk>, <&pclk>;
+                       clock-names = "KMIREFCLK", "apb_pclk";
                };
 
                /*
                        reg = <0x1c000000 0x1000>;
                        interrupts = <23 24>;
                        max-frequency = <515633>;
+                       clocks = <&uartclk>, <&pclk>;
+                       clock-names = "mclk", "apb_pclk";
                };
 
                aaci@1d000000 {
                        compatible = "arm,pl041", "arm,primecell";
                        reg = <0x1d000000 0x1000>;
                        interrupts = <25>;
+                       clocks = <&pclk>;
+                       clock-names = "apb_pclk";
                };
 
                clcd@c0000000 {
                        compatible = "arm,pl110", "arm,primecell";
                        reg = <0xC0000000 0x1000>;
                        interrupts = <22>;
+                       clocks = <&auxosc>, <&pclk>;
+                       clock-names = "clcd", "apb_pclk";
                };
        };
 };
diff --git a/arch/arm/boot/dts/k2e-clocks.dtsi b/arch/arm/boot/dts/k2e-clocks.dtsi
new file mode 100644 (file)
index 0000000..90774d6
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison SoC specific device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+clocks {
+       mainpllclk: mainpllclk@2310110 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,main-pll-clock";
+               clocks = <&refclksys>;
+               reg = <0x02620350 4>, <0x02310110 4>;
+               reg-names = "control", "multiplier";
+               fixed-postdiv = <2>;
+       };
+
+       papllclk: papllclk@2620358 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkpass>;
+               clock-output-names = "pa-pll-clk";
+               reg = <0x02620358 4>;
+               reg-names = "control";
+       };
+
+       ddr3apllclk: ddr3apllclk@2620360 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkddr3a>;
+               clock-output-names = "ddr-3a-pll-clk";
+               reg = <0x02620360 4>;
+               reg-names = "control";
+       };
+
+       clkusb1: clkusb1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk16>;
+               clock-output-names = "usb";
+               reg = <0x02350004 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkhyperlink0: clkhyperlink0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "hyperlink-0";
+               reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <5>;
+       };
+
+       clkpcie1: clkpcie1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "pcie";
+               reg = <0x0235006c 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <18>;
+       };
+
+       clkxge: clkxge {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "xge";
+               reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <29>;
+       };
+};
diff --git a/arch/arm/boot/dts/k2e-evm.dts b/arch/arm/boot/dts/k2e-evm.dts
new file mode 100644 (file)
index 0000000..74b3b63
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison EVM device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2e.dtsi"
+
+/ {
+       compatible =  "ti,k2e-evm","ti,keystone";
+       model = "Texas Instruments Keystone 2 Edison EVM";
+
+       soc {
+
+               clocks {
+                       refclksys: refclksys {
+                               #clock-cells = <0>;
+                               compatible = "fixed-clock";
+                               clock-frequency = <100000000>;
+                               clock-output-names = "refclk-sys";
+                       };
+
+                       refclkpass: refclkpass {
+                               #clock-cells = <0>;
+                               compatible = "fixed-clock";
+                               clock-frequency = <100000000>;
+                               clock-output-names = "refclk-pass";
+                       };
+
+                       refclkddr3a: refclkddr3a {
+                               #clock-cells = <0>;
+                               compatible = "fixed-clock";
+                               clock-frequency = <100000000>;
+                               clock-output-names = "refclk-ddr3a";
+                       };
+               };
+       };
+};
+
+&usb_phy {
+       status = "okay";
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb1_phy {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
new file mode 100644 (file)
index 0000000..03d0190
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison soc device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               interrupt-parent = <&gic>;
+
+               cpu@0 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+
+               cpu@2 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <2>;
+               };
+
+               cpu@3 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <3>;
+               };
+       };
+
+       soc {
+               /include/ "k2e-clocks.dtsi"
+
+               usb: usb@2680000 {
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+                       dwc3@2690000 {
+                               interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+                       };
+               };
+
+               usb1_phy: usb_phy@2620750 {
+                       compatible = "ti,keystone-usbphy";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x2620750 24>;
+                       status = "disabled";
+               };
+
+               usb1: usb@25000000 {
+                       compatible = "ti,keystone-dwc3";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x25000000 0x10000>;
+                       clocks = <&clkusb1>;
+                       clock-names = "usb";
+                       interrupts = <GIC_SPI 414 IRQ_TYPE_EDGE_RISING>;
+                       ranges;
+                       status = "disabled";
+
+                       dwc3@25010000 {
+                               compatible = "synopsys,dwc3";
+                               reg = <0x25010000 0x70000>;
+                               interrupts = <GIC_SPI 414 IRQ_TYPE_EDGE_RISING>;
+                               usb-phy = <&usb1_phy>, <&usb1_phy>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/k2hk-clocks.dtsi b/arch/arm/boot/dts/k2hk-clocks.dtsi
new file mode 100644 (file)
index 0000000..96e6536
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking SoC clock nodes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+clocks {
+       armpllclk: armpllclk@2620370 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkarm>;
+               clock-output-names = "arm-pll-clk";
+               reg = <0x02620370 4>;
+               reg-names = "control";
+       };
+
+       mainpllclk: mainpllclk@2310110 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,main-pll-clock";
+               clocks = <&refclksys>;
+               reg = <0x02620350 4>, <0x02310110 4>;
+               reg-names = "control", "multiplier";
+               fixed-postdiv = <2>;
+       };
+
+       papllclk: papllclk@2620358 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkpass>;
+               clock-output-names = "pa-pll-clk";
+               reg = <0x02620358 4>;
+               reg-names = "control";
+       };
+
+       ddr3apllclk: ddr3apllclk@2620360 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkddr3a>;
+               clock-output-names = "ddr-3a-pll-clk";
+               reg = <0x02620360 4>;
+               reg-names = "control";
+       };
+
+       ddr3bpllclk: ddr3bpllclk@2620368 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclkddr3b>;
+               clock-output-names = "ddr-3b-pll-clk";
+               reg = <0x02620368 4>;
+               reg-names = "control";
+       };
+
+       clktsip: clktsip {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk16>;
+               clock-output-names = "tsip";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clksrio: clksrio {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1rstiso13>;
+               clock-output-names = "srio";
+               reg = <0x0235002c 0xb00>, <0x02350010 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <4>;
+       };
+
+       clkhyperlink0: clkhyperlink0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "hyperlink-0";
+               reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <5>;
+       };
+
+       clkgem1: clkgem1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem1";
+               reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <9>;
+       };
+
+       clkgem2: clkgem2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem2";
+               reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <10>;
+       };
+
+       clkgem3: clkgem3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem3";
+               reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <11>;
+       };
+
+       clkgem4: clkgem4 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem4";
+               reg = <0x0235004c 0xb00>, <0x02350030 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <12>;
+       };
+
+       clkgem5: clkgem5 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem5";
+               reg = <0x02350050 0xb00>, <0x02350034 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <13>;
+       };
+
+       clkgem6: clkgem6 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem6";
+               reg = <0x02350054 0xb00>, <0x02350038 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <14>;
+       };
+
+       clkgem7: clkgem7 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem7";
+               reg = <0x02350058 0xb00>, <0x0235003c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <15>;
+       };
+
+       clkddr31: clkddr31 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "ddr3-1";
+               reg = <0x02350060 0xb00>, <0x02350040 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <16>;
+       };
+
+       clktac: clktac {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tac";
+               reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <17>;
+       };
+
+       clkrac01: clkrac01 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "rac-01";
+               reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <17>;
+       };
+
+       clkrac23: clkrac23 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "rac-23";
+               reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <18>;
+       };
+
+       clkfftc0: clkfftc0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-0";
+               reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <19>;
+       };
+
+       clkfftc1: clkfftc1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-1";
+               reg = <0x02350074 0xb00>, <0x0235004c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <19>;
+       };
+
+       clkfftc2: clkfftc2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-2";
+               reg = <0x02350078 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkfftc3: clkfftc3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-3";
+               reg = <0x0235007c 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkfftc4: clkfftc4 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-4";
+               reg = <0x02350080 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkfftc5: clkfftc5 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-5";
+               reg = <0x02350084 0xb00>, <0x02350050 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <20>;
+       };
+
+       clkaif: clkaif {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "aif";
+               reg = <0x02350088 0xb00>, <0x02350054 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <21>;
+       };
+
+       clktcp3d0: clktcp3d0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-0";
+               reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <22>;
+       };
+
+       clktcp3d1: clktcp3d1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-1";
+               reg = <0x02350090 0xb00>, <0x02350058 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <22>;
+       };
+
+       clktcp3d2: clktcp3d2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-2";
+               reg = <0x02350094 0xb00>, <0x0235005c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <23>;
+       };
+
+       clktcp3d3: clktcp3d3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-3";
+               reg = <0x02350098 0xb00>, <0x0235005c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <23>;
+       };
+
+       clkvcp0: clkvcp0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-0";
+               reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp1: clkvcp1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-1";
+               reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp2: clkvcp2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-2";
+               reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp3: clkvcp3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-3";
+               reg = <0x023500a8 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp4: clkvcp4 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-4";
+               reg = <0x023500ac 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkvcp5: clkvcp5 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-5";
+               reg = <0x023500b0 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkvcp6: clkvcp6 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-6";
+               reg = <0x023500b4 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkvcp7: clkvcp7 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-7";
+               reg = <0x023500b8 0xb00>, <0x02350064 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <25>;
+       };
+
+       clkbcp: clkbcp {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "bcp";
+               reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <26>;
+       };
+
+       clkdxb: clkdxb {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "dxb";
+               reg = <0x023500c0 0xb00>, <0x0235006c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <27>;
+       };
+
+       clkhyperlink1: clkhyperlink1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "hyperlink-1";
+               reg = <0x023500c4 0xb00>, <0x02350070 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <28>;
+       };
+
+       clkxge: clkxge {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "xge";
+               reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <29>;
+       };
+};
index eaefdfef65c3e322497d513eac6a5f7ff4dc94cd..c93d06f9f2a8db17e9d05b65766136c803247cff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Texas Instruments, Inc.
+ * Copyright 2013-2014 Texas Instruments, Inc.
  *
  * Keystone 2 Kepler/Hawking EVM device tree
  *
 /dts-v1/;
 
 #include "keystone.dtsi"
+#include "k2hk.dtsi"
 
 / {
-       compatible =  "ti,keystone-evm";
+       compatible =  "ti,k2hk-evm","ti,keystone";
+       model = "Texas Instruments Keystone 2 Kepler/Hawking EVM";
 
        soc {
-               clock {
+               clocks {
                        refclksys: refclksys {
                                #clock-cells = <0>;
                                compatible = "fixed-clock";
                        };
                };
        };
+
+       leds {
+               compatible = "gpio-leds";
+               debug1_1 {
+                       label = "keystone:green:debug1";
+                       gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; /* 12 */
+               };
+
+               debug1_2 {
+                       label = "keystone:red:debug1";
+                       gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; /* 13 */
+               };
+
+               debug2 {
+                       label = "keystone:blue:debug2";
+                       gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; /* 14 */
+               };
+
+               debug3 {
+                       label = "keystone:blue:debug3";
+                       gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; /* 15 */
+               };
+       };
 };
 
 &usb_phy {
 &usb {
        status = "okay";
 };
+
+&aemif {
+       cs0 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               clock-ranges;
+               ranges;
+
+               ti,cs-chipselect = <0>;
+               /* all timings in nanoseconds */
+               ti,cs-min-turnaround-ns = <12>;
+               ti,cs-read-hold-ns = <6>;
+               ti,cs-read-strobe-ns = <23>;
+               ti,cs-read-setup-ns = <9>;
+               ti,cs-write-hold-ns = <8>;
+               ti,cs-write-strobe-ns = <23>;
+               ti,cs-write-setup-ns = <8>;
+
+               nand@0,0 {
+                       compatible = "ti,keystone-nand","ti,davinci-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0 0 0x4000000
+                              1 0 0x0000100>;
+
+                       ti,davinci-chipselect = <0>;
+                       ti,davinci-mask-ale = <0x2000>;
+                       ti,davinci-mask-cle = <0x4000>;
+                       ti,davinci-mask-chipsel = <0>;
+                       nand-ecc-mode = "hw";
+                       ti,davinci-ecc-bits = <4>;
+                       nand-on-flash-bbt;
+
+                       partition@0 {
+                               label = "u-boot";
+                               reg = <0x0 0x100000>;
+                               read-only;
+                       };
+
+                       partition@100000 {
+                               label = "params";
+                               reg = <0x100000 0x80000>;
+                               read-only;
+                       };
+
+                       partition@180000 {
+                               label = "ubifs";
+                               reg = <0x180000 0x1fe80000>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/k2hk.dtsi b/arch/arm/boot/dts/k2hk.dtsi
new file mode 100644 (file)
index 0000000..c73899c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking soc specific device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               interrupt-parent = <&gic>;
+
+               cpu@0 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+
+               cpu@2 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <2>;
+               };
+
+               cpu@3 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <3>;
+               };
+       };
+
+       soc {
+               /include/ "k2hk-clocks.dtsi"
+       };
+};
diff --git a/arch/arm/boot/dts/k2l-clocks.dtsi b/arch/arm/boot/dts/k2l-clocks.dtsi
new file mode 100644 (file)
index 0000000..f584b80
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 lamarr SoC clock nodes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+clocks {
+       armpllclk: armpllclk@2620370 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclksys>;
+               clock-output-names = "arm-pll-clk";
+               reg = <0x02620370 4>;
+               reg-names = "control";
+       };
+
+       mainpllclk: mainpllclk@2310110 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,main-pll-clock";
+               clocks = <&refclksys>;
+               reg = <0x02620350 4>, <0x02310110 4>;
+               reg-names = "control", "multiplier";
+               fixed-postdiv = <2>;
+       };
+
+       papllclk: papllclk@2620358 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclksys>;
+               clock-output-names = "pa-pll-clk";
+               reg = <0x02620358 4>;
+               reg-names = "control";
+       };
+
+       ddr3apllclk: ddr3apllclk@2620360 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,pll-clock";
+               clocks = <&refclksys>;
+               clock-output-names = "ddr-3a-pll-clk";
+               reg = <0x02620360 4>;
+               reg-names = "control";
+       };
+
+       clkdfeiqnsys: clkdfeiqnsys {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "dfe";
+               reg-names = "control", "domain";
+               reg = <0x02350004 0xb00>, <0x02350000 0x400>;
+               domain-id = <0>;
+       };
+
+       clkpcie1: clkpcie1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk12>;
+               clock-output-names = "pcie";
+               reg = <0x0235002c 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <4>;
+       };
+
+       clkgem1: clkgem1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem1";
+               reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <9>;
+       };
+
+       clkgem2: clkgem2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem2";
+               reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <10>;
+       };
+
+       clkgem3: clkgem3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk1>;
+               clock-output-names = "gem3";
+               reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <11>;
+       };
+
+       clktac: clktac {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tac";
+               reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <17>;
+       };
+
+       clkrac: clkrac {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "rac";
+               reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <17>;
+       };
+
+       clkdfepd0: clkdfepd0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "dfe-pd0";
+               reg = <0x0235006c 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <18>;
+       };
+
+       clkfftc0: clkfftc0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-0";
+               reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <19>;
+       };
+
+       clkosr: clkosr {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "osr";
+               reg = <0x02350088 0xb00>, <0x0235004c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <21>;
+       };
+
+       clktcp3d0: clktcp3d0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-0";
+               reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <22>;
+       };
+
+       clktcp3d1: clktcp3d1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "tcp3d-1";
+               reg = <0x02350094 0xb00>, <0x02350058 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <23>;
+       };
+
+       clkvcp0: clkvcp0 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-0";
+               reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp1: clkvcp1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-1";
+               reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp2: clkvcp2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-2";
+               reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkvcp3: clkvcp3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "vcp-3";
+               reg = <0x023500a8 0xb00>, <0x02350060 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <24>;
+       };
+
+       clkbcp: clkbcp {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "bcp";
+               reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <26>;
+       };
+
+       clkdfepd1: clkdfepd1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "dfe-pd1";
+               reg = <0x023500c0 0xb00>, <0x02350044 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <27>;
+       };
+
+       clkfftc1: clkfftc1 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "fftc-1";
+               reg = <0x023500c4 0xb00>, <0x023504c0 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <28>;
+       };
+
+       clkiqnail: clkiqnail {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&chipclk13>;
+               clock-output-names = "iqn-ail";
+               reg = <0x023500c8 0xb00>, <0x0235004c 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <29>;
+       };
+
+       clkuart2: clkuart2 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "uart2";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
+       clkuart3: clkuart3 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "uart3";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+};
diff --git a/arch/arm/boot/dts/k2l-evm.dts b/arch/arm/boot/dts/k2l-evm.dts
new file mode 100644 (file)
index 0000000..50a7013
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Lamarr EVM device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2l.dtsi"
+
+/ {
+       compatible =  "ti,k2l-evm","ti,keystone";
+       model = "Texas Instruments Keystone 2 Lamarr EVM";
+
+       soc {
+               clocks {
+                       refclksys: refclksys {
+                               #clock-cells = <0>;
+                               compatible = "fixed-clock";
+                               clock-frequency = <122880000>;
+                               clock-output-names = "refclk-sys";
+                       };
+               };
+       };
+};
+
+&usb_phy {
+       status = "okay";
+};
+
+&usb {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/k2l.dtsi b/arch/arm/boot/dts/k2l.dtsi
new file mode 100644 (file)
index 0000000..1f7f479
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Lamarr SoC specific device tree
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               interrupt-parent = <&gic>;
+
+               cpu@0 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a15";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       soc {
+
+               /include/ "k2l-clocks.dtsi"
+
+               uart2: serial@02348400 {
+                       compatible = "ns16550a";
+                       current-speed = <115200>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       reg = <0x02348400 0x100>;
+                       clocks  = <&clkuart2>;
+                       interrupts = <GIC_SPI 432 IRQ_TYPE_EDGE_RISING>;
+               };
+
+               uart3:  serial@02348800 {
+                       compatible = "ns16550a";
+                       current-speed = <115200>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       reg = <0x02348800 0x100>;
+                       clocks  = <&clkuart3>;
+                       interrupts = <GIC_SPI 435 IRQ_TYPE_EDGE_RISING>;
+               };
+       };
+};
index ef58d1c24313541a068436c5e590378120c6bb3b..93f82c7010ab384fcf5ed5afa98e2acaa379bfac 100644 (file)
@@ -13,51 +13,6 @@ clocks {
        #size-cells = <1>;
        ranges;
 
-       mainpllclk: mainpllclk@2310110 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,main-pll-clock";
-               clocks = <&refclksys>;
-               reg = <0x02620350 4>, <0x02310110 4>;
-               reg-names = "control", "multiplier";
-               fixed-postdiv = <2>;
-       };
-
-       papllclk: papllclk@2620358 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,pll-clock";
-               clocks = <&refclkpass>;
-               clock-output-names = "pa-pll-clk";
-               reg = <0x02620358 4>;
-               reg-names = "control";
-       };
-
-       ddr3apllclk: ddr3apllclk@2620360 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,pll-clock";
-               clocks = <&refclkddr3a>;
-               clock-output-names = "ddr-3a-pll-clk";
-               reg = <0x02620360 4>;
-               reg-names = "control";
-       };
-
-       ddr3bpllclk: ddr3bpllclk@2620368 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,pll-clock";
-               clocks = <&refclkddr3b>;
-               clock-output-names = "ddr-3b-pll-clk";
-               reg = <0x02620368 4>;
-               reg-names = "control";
-       };
-
-       armpllclk: armpllclk@2620370 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,pll-clock";
-               clocks = <&refclkarm>;
-               clock-output-names = "arm-pll-clk";
-               reg = <0x02620370 4>;
-               reg-names = "control";
-       };
-
        mainmuxclk: mainmuxclk@2310108 {
                #clock-cells = <0>;
                compatible = "ti,keystone,pll-mux-clock";
@@ -244,7 +199,7 @@ clocks {
                clock-output-names = "debugss-trc";
                reg = <0x02350014 0xb00>, <0x02350000 0x400>;
                reg-names = "control", "domain";
-               domain-id = <0>;
+               domain-id = <1>;
        };
 
        clktetbtrc: clktetbtrc {
@@ -297,26 +252,6 @@ clocks {
                domain-id = <3>;
        };
 
-       clksrio: clksrio {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1rstiso13>;
-               clock-output-names = "srio";
-               reg = <0x0235002c 0xb00>, <0x02350010 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <4>;
-       };
-
-       clkhyperlink0: clkhyperlink0 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk12>;
-               clock-output-names = "hyperlink-0";
-               reg = <0x02350030 0xb00>, <0x02350014 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <5>;
-       };
-
        clksr: clksr {
                #clock-cells = <0>;
                compatible = "ti,keystone,psc-clock";
@@ -327,16 +262,6 @@ clocks {
                domain-id = <6>;
        };
 
-       clkmsmcsram: clkmsmcsram {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "msmcsram";
-               reg = <0x02350038 0xb00>, <0x0235001c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <7>;
-       };
-
        clkgem0: clkgem0 {
                #clock-cells = <0>;
                compatible = "ti,keystone,psc-clock";
@@ -347,76 +272,6 @@ clocks {
                domain-id = <8>;
        };
 
-       clkgem1: clkgem1 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem1";
-               reg = <0x02350040 0xb00>, <0x02350024 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <9>;
-       };
-
-       clkgem2: clkgem2 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem2";
-               reg = <0x02350044 0xb00>, <0x02350028 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <10>;
-       };
-
-       clkgem3: clkgem3 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem3";
-               reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <11>;
-       };
-
-       clkgem4: clkgem4 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem4";
-               reg = <0x0235004c 0xb00>, <0x02350030 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <12>;
-       };
-
-       clkgem5: clkgem5 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem5";
-               reg = <0x02350050 0xb00>, <0x02350034 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <13>;
-       };
-
-       clkgem6: clkgem6 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem6";
-               reg = <0x02350054 0xb00>, <0x02350038 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <14>;
-       };
-
-       clkgem7: clkgem7 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk1>;
-               clock-output-names = "gem7";
-               reg = <0x02350058 0xb00>, <0x0235003c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <15>;
-       };
-
        clkddr30: clkddr30 {
                #clock-cells = <0>;
                compatible = "ti,keystone,psc-clock";
@@ -427,276 +282,6 @@ clocks {
                domain-id = <16>;
        };
 
-       clkddr31: clkddr31 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "ddr3-1";
-               reg = <0x02350060 0xb00>, <0x02350040 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <16>;
-       };
-
-       clktac: clktac {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "tac";
-               reg = <0x02350064 0xb00>, <0x02350044 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <17>;
-       };
-
-       clkrac01: clktac01 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "rac-01";
-               reg = <0x02350068 0xb00>, <0x02350044 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <17>;
-       };
-
-       clkrac23: clktac23 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "rac-23";
-               reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <18>;
-       };
-
-       clkfftc0: clkfftc0 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "fftc-0";
-               reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <19>;
-       };
-
-       clkfftc1: clkfftc1 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "fftc-1";
-               reg = <0x02350074 0xb00>, <0x023504c0 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <19>;
-       };
-
-       clkfftc2: clkfftc2 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "fftc-2";
-               reg = <0x02350078 0xb00>, <0x02350050 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <20>;
-       };
-
-       clkfftc3: clkfftc3 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "fftc-3";
-               reg = <0x0235007c 0xb00>, <0x02350050 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <20>;
-       };
-
-       clkfftc4: clkfftc4 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "fftc-4";
-               reg = <0x02350080 0xb00>, <0x02350050 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <20>;
-       };
-
-       clkfftc5: clkfftc5 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "fftc-5";
-               reg = <0x02350084 0xb00>, <0x02350050 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <20>;
-       };
-
-       clkaif: clkaif {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "aif";
-               reg = <0x02350088 0xb00>, <0x02350054 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <21>;
-       };
-
-       clktcp3d0: clktcp3d0 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "tcp3d-0";
-               reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <22>;
-       };
-
-       clktcp3d1: clktcp3d1 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "tcp3d-1";
-               reg = <0x02350090 0xb00>, <0x02350058 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <22>;
-       };
-
-       clktcp3d2: clktcp3d2 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "tcp3d-2";
-               reg = <0x02350094 0xb00>, <0x0235005c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <23>;
-       };
-
-       clktcp3d3: clktcp3d3 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "tcp3d-3";
-               reg = <0x02350098 0xb00>, <0x0235005c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <23>;
-       };
-
-       clkvcp0: clkvcp0 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-0";
-               reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <24>;
-       };
-
-       clkvcp1: clkvcp1 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-1";
-               reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <24>;
-       };
-
-       clkvcp2: clkvcp2 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-2";
-               reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <24>;
-       };
-
-       clkvcp3: clkvcp3 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-3";
-               reg = <0x023500a8 0xb00>, <0x02350060 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <24>;
-       };
-
-       clkvcp4: clkvcp4 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-4";
-               reg = <0x023500ac 0xb00>, <0x02350064 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <25>;
-       };
-
-       clkvcp5: clkvcp5 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-5";
-               reg = <0x023500b0 0xb00>, <0x02350064 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <25>;
-       };
-
-       clkvcp6: clkvcp6 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-6";
-               reg = <0x023500b4 0xb00>, <0x02350064 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <25>;
-       };
-
-       clkvcp7: clkvcp7 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "vcp-7";
-               reg = <0x023500b8 0xb00>, <0x02350064 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <25>;
-       };
-
-       clkbcp: clkbcp {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "bcp";
-               reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <26>;
-       };
-
-       clkdxb: clkdxb {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "dxb";
-               reg = <0x023500c0 0xb00>, <0x0235006c 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <27>;
-       };
-
-       clkhyperlink1: clkhyperlink1 {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk12>;
-               clock-output-names = "hyperlink-1";
-               reg = <0x023500c4 0xb00>, <0x02350070 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <28>;
-       };
-
-       clkxge: clkxge {
-               #clock-cells = <0>;
-               compatible = "ti,keystone,psc-clock";
-               clocks = <&chipclk13>;
-               clock-output-names = "xge";
-               reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
-               reg-names = "control", "domain";
-               domain-id = <29>;
-       };
-
        clkwdtimer0: clkwdtimer0 {
                #clock-cells = <0>;
                compatible = "ti,keystone,psc-clock";
@@ -737,6 +322,16 @@ clocks {
                domain-id = <0>;
        };
 
+       clktimer15: clktimer15 {
+               #clock-cells = <0>;
+               compatible = "ti,keystone,psc-clock";
+               clocks = <&clkmodrst0>;
+               clock-output-names = "timer15";
+               reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+               reg-names = "control", "domain";
+               domain-id = <0>;
+       };
+
        clkuart0: clkuart0 {
                #clock-cells = <0>;
                compatible = "ti,keystone,psc-clock";
index b4202907a27b9b5904ee9356aa30eba22b66e8fc..90823eb90c1b820544ca390026305f050c74fee7 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/gpio.h>
 
 #include "skeleton.dtsi"
 
                reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
        };
 
-       cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               interrupt-parent = <&gic>;
-
-               cpu@0 {
-                       compatible = "arm,cortex-a15";
-                       device_type = "cpu";
-                       reg = <0>;
-               };
-
-               cpu@1 {
-                       compatible = "arm,cortex-a15";
-                       device_type = "cpu";
-                       reg = <1>;
-               };
-
-               cpu@2 {
-                       compatible = "arm,cortex-a15";
-                       device_type = "cpu";
-                       reg = <2>;
-               };
-
-               cpu@3 {
-                       compatible = "arm,cortex-a15";
-                       device_type = "cpu";
-                       reg = <3>;
-               };
-       };
-
        gic: interrupt-controller {
                compatible = "arm,cortex-a15-gic";
                #interrupt-cells = <3>;
                                usb-phy = <&usb_phy>, <&usb_phy>;
                        };
                };
+
+               wdt: wdt@022f0080 {
+                       compatible = "ti,keystone-wdt","ti,davinci-wdt";
+                       reg = <0x022f0080 0x80>;
+                       clocks = <&clkwdtimer0>;
+               };
+
+               clock_event: timer@22f0000 {
+                       compatible = "ti,keystone-timer";
+                       reg = <0x022f0000 0x80>;
+                       interrupts = <GIC_SPI 110 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clktimer15>;
+               };
+
+               gpio0: gpio@260bf00 {
+                       compatible = "ti,keystone-gpio";
+                       reg = <0x0260bf00 0x100>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       /* HW Interrupts mapped to GPIO pins */
+                       interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 121 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 123 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 124 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 125 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 126 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 127 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 128 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 129 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 130 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 131 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 132 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 133 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 134 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 135 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 137 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 138 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 139 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 141 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 147 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>,
+                                       <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&clkgpio>;
+                       clock-names = "gpio";
+                       ti,ngpio = <32>;
+                       ti,davinci-gpio-unbanked = <32>;
+               };
+
+               aemif: aemif@21000A00 {
+                       compatible = "ti,keystone-aemif", "ti,davinci-aemif";
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       clocks = <&clkaemif>;
+                       clock-names = "aemif";
+                       clock-ranges;
+
+                       reg = <0x21000A00 0x00000100>;
+                       ranges = <0 0 0x30000000 0x10000000
+                                 1 0 0x21000A00 0x00000100>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/kirkwood-b3.dts b/arch/arm/boot/dts/kirkwood-b3.dts
new file mode 100644 (file)
index 0000000..4079105
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Device Tree file for Excito Bubba B3
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
+ *
+ * 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.
+ *
+ * Note: This requires a new'ish version of u-boot, which disables the
+ * L2 cache. If your B3 silently fails to boot, u-boot is probably too
+ * old. Either upgrade, or consider the following email:
+ *
+ * http://lists.debian.org/debian-arm/2012/08/msg00128.html
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+       model = "Excito B3";
+       compatible = "excito,b3", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+       memory { /* 512 MB */
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk";
+       };
+
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       /* Wifi model has Atheros chipset on pcie port */
+                       pcie@1,0 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pmx_button_power: pmx-button-power {
+                               marvell,pins = "mpp39";
+                               marvell,function = "gpio";
+                       };
+                       pmx_led_green: pmx-led-green {
+                               marvell,pins = "mpp38";
+                               marvell,function = "gpio";
+                       };
+                       pmx_led_red: pmx-led-red {
+                               marvell,pins = "mpp41";
+                               marvell,function = "gpio";
+                       };
+                       pmx_led_blue: pmx-led-blue {
+                               marvell,pins = "mpp42";
+                               marvell,function = "gpio";
+                       };
+                       pmx_beeper: pmx-beeper {
+                               marvell,pins = "mpp40";
+                               marvell,function = "gpio";
+                       };
+               };
+
+               spi@10600 {
+                       status = "okay";
+                       pinctrl-0 = <&pmx_spi>;
+                       pinctrl-names = "default";
+
+                       m25p16@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "m25p16";
+                               reg = <0>;
+                               spi-max-frequency = <40000000>;
+                               mode = <0>;
+
+                               partition@0 {
+                                       reg = <0x0 0xc0000>;
+                                       label = "u-boot";
+                               };
+
+                               partition@c0000 {
+                                       reg = <0xc0000 0x20000>;
+                                       label = "u-boot env";
+                               };
+
+                               partition@e0000 {
+                                       reg = <0xe0000 0x120000>;
+                                       label = "data";
+                               };
+                       };
+               };
+
+               i2c@11000 {
+                       status = "okay";
+                       /*
+                        * There is something on the bus at address 0x64.
+                        * Not yet identified what it is, maybe the eeprom
+                        * for the Atheros WiFi chip?
+                        */
+               };
+
+
+               serial@12000 {
+                       /* Internal on test pins, 3.3v TTL
+                        * UART0_RX = Testpoint 65
+                        * UART0_TX = Testpoint 66
+                        * See the Excito Wiki for more details.
+                        */
+                       pinctrl-0 = <&pmx_uart0>;
+                       pinctrl-names = "default";
+                       status = "okay";
+               };
+
+               sata@80000 {
+                       /* One internal, the second as eSATA */
+                       status = "okay";
+                       nr-ports = <2>;
+               };
+       };
+
+       gpio-leds {
+               /*
+                * There is one LED "port" on the front and the colours
+                * mix together giving some interesting combinations.
+                */
+               compatible = "gpio-leds";
+               pinctrl-0 = < &pmx_led_green &pmx_led_red
+                             &pmx_led_blue >;
+               pinctrl-names = "default";
+
+               programming_led {
+                       label = "bubba3:green:programming";
+                       gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               error_led {
+                       label = "bubba3:red:error";
+                       gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+               };
+
+               active_led {
+                       label = "bubba3:blue:active";
+                       gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&pmx_button_power>;
+               pinctrl-names = "default";
+
+               power-button {
+                       /* On the back */
+                       label = "Power Button";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       beeper: beeper {
+               /* 4KHz Piezoelectric buzzer */
+               compatible = "gpio-beeper";
+               pinctrl-0 = <&pmx_beeper>;
+               pinctrl-names = "default";
+               gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@8 {
+               device_type = "ethernet-phy";
+               reg = <8>;
+       };
+
+       ethphy1: ethernet-phy@24 {
+               device_type = "ethernet-phy";
+               reg = <24>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
+
+&eth1 {
+       status = "okay";
+       ethernet1-port@0 {
+               phy-handle = <&ethphy1>;
+       };
+};
+
diff --git a/arch/arm/boot/dts/kirkwood-ds109.dts b/arch/arm/boot/dts/kirkwood-ds109.dts
new file mode 100644 (file)
index 0000000..772092c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS109, DS110, DS110jv20";
+       compatible = "synology,ds109", "synology,ds110jv20",
+                    "synology,ds110", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-32-35 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-1 {
+               status = "okay";
+       };
+};
+
+&rs5c372 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds110jv10.dts b/arch/arm/boot/dts/kirkwood-ds110jv10.dts
new file mode 100644 (file)
index 0000000..aabafbe
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS110j v10 and v30";
+       compatible = "synology,ds110jv10", "synology,ds110jv30",
+                    "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-32-35 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-1 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds111.dts b/arch/arm/boot/dts/kirkwood-ds111.dts
new file mode 100644 (file)
index 0000000..16ec7fb
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS111";
+       compatible = "synology,ds111", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-1 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-1 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds112.dts b/arch/arm/boot/dts/kirkwood-ds112.dts
new file mode 100644 (file)
index 0000000..cff1b23
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS111";
+       compatible = "synology,ds111", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-1 {
+               status = "okay";
+       };
+
+       gpio-leds-21-2 {
+               status = "okay";
+       };
+
+       regulators-hdd-30 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds209.dts b/arch/arm/boot/dts/kirkwood-ds209.dts
new file mode 100644 (file)
index 0000000..3304119
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS209";
+       compatible = "synology,ds209", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-32-35 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-2 {
+               status = "okay";
+       };
+
+       regulators-hdd-31 {
+               status = "okay";
+       };
+};
+
+&rs5c372 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds210.dts b/arch/arm/boot/dts/kirkwood-ds210.dts
new file mode 100644 (file)
index 0000000..6052eaa
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS210 v10, v20, v30, DS211j";
+       compatible = "synology,ds210jv10", "synology,ds210jv20",
+                    "synology,ds210jv30", "synology,ds211j",
+                    "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-32-35 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-2 {
+               status = "okay";
+       };
+
+       regulators-hdd-31 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds212.dts b/arch/arm/boot/dts/kirkwood-ds212.dts
new file mode 100644 (file)
index 0000000..7f76cd3
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS212, DS212p v10, v20, DS213air v10, DS213 v10";
+       compatible = "synology,ds212", "synology,ds212pv10",
+                    "synology,ds212pv10", "synology,ds212pv20",
+                    "synology,ds213airv10", "synology,ds213v10",
+                    "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-1 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-2 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds212j.dts b/arch/arm/boot/dts/kirkwood-ds212j.dts
new file mode 100644 (file)
index 0000000..1f83a00
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS212j v10, v20";
+       compatible = "synology,ds212jv10", "synology,ds212jv20",
+                    "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-32-35 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-21-2 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds409.dts b/arch/arm/boot/dts/kirkwood-ds409.dts
new file mode 100644 (file)
index 0000000..0a573ad
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS409, DS410j";
+       compatible = "synology,ds409", "synology,ds410j", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-15-18 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-36 {
+               status = "okay";
+       };
+
+       gpio-leds-alarm-12 {
+               status = "okay";
+       };
+};
+
+&eth1 {
+       status = "okay";
+};
+
+&rs5c372 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds409slim.dts b/arch/arm/boot/dts/kirkwood-ds409slim.dts
new file mode 100644 (file)
index 0000000..1848a62
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology 409slim";
+       compatible = "synology,ds409slim", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-32-35 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-20 {
+               status = "okay";
+       };
+};
+
+&rs5c372 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds411.dts b/arch/arm/boot/dts/kirkwood-ds411.dts
new file mode 100644 (file)
index 0000000..a1737b4
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS411, DS413jv10";
+       compatible = "synology,ds411", "synology,ds413jv10", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-1 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-36 {
+               status = "okay";
+       };
+
+       regulators-hdd-34 {
+               status = "okay";
+       };
+};
+
+&eth1 {
+       status = "okay";
+};
+
+&s35390a {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds411j.dts b/arch/arm/boot/dts/kirkwood-ds411j.dts
new file mode 100644 (file)
index 0000000..0cde914
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS411j";
+       compatible = "synology,ds411j", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-15-18 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-36 {
+               status = "okay";
+       };
+
+       gpio-leds-alarm-12 {
+               status = "okay";
+       };
+};
+
+&eth1 {
+       status = "okay";
+};
+
+&s35390a {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-ds411slim.dts b/arch/arm/boot/dts/kirkwood-ds411slim.dts
new file mode 100644 (file)
index 0000000..aef0cad
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology DS411slim";
+       compatible = "synology,ds411slim", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-1 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-36 {
+               status = "okay";
+       };
+};
+
+&eth1 {
+       status = "okay";
+};
+
+&s35390a {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
index dc86429756d79787a780946668e2a80cd50fa893..2cb0dc529165dcd88cbbba8ae7df7da2647a041f 100644 (file)
                        gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
                };
        };
+
+       dsa@0 {
+               compatible = "marvell,dsa";
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               dsa,ethernet = <&eth0>;
+               dsa,mii-bus = <&ethphy0>;
+
+               switch@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0 0>;    /* MDIO address 0, switch 0 in tree */
+
+                       port@0 {
+                               reg = <0>;
+                               label = "lan1";
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               label = "lan2";
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan3";
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan4";
+                       };
+
+                       port@4 {
+                               reg = <4>;
+                               label = "wan";
+                       };
+
+                       port@5 {
+                               reg = <5>;
+                               label = "cpu";
+                       };
+               };
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@ff {
+               reg = <0xff>;   /* No phy attached */
+               speed = <1000>;
+               duplex = <1>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
 };
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6192.dts b/arch/arm/boot/dts/kirkwood-rd88f6192.dts
new file mode 100644 (file)
index 0000000..e9dd850
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Marvell RD88F6192 Board descrition
+ *
+ * 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.
+ *
+ * This file contains the definitions that are common between the three
+ * variants of the Marvell Kirkwood Development Board.
+ */
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+
+/ {
+       model = "Marvell RD88F6192 reference design";
+       compatible = "marvell,rd88f6192", "marvell,kirkwood-88f6192", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       pcie@1,0 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pinctrl-0 = <&pmx_usb_power>;
+                       pinctrl-names = "default";
+
+                        pmx_usb_power: pmx-usb-power {
+                                marvell,pins = "mpp10";
+                                marvell,function = "gpo";
+                        };
+               };
+
+               serial@12000 {
+                       status = "okay";
+
+               };
+
+               spi@10600 {
+                       status = "okay";
+                       pinctrl-0 = <&pmx_spi>;
+                       pinctrl-names = "default";
+
+                       m25p128@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "st,m25p128";
+                               reg = <0>;
+                               spi-max-frequency = <20000000>;
+                               mode = <0>;
+                       };
+               };
+
+               sata@80000 {
+                       status = "okay";
+                       nr-ports = <2>;
+               };
+       };
+
+       regulators {
+                compatible = "simple-bus";
+                #address-cells = <1>;
+                #size-cells = <0>;
+                pinctrl-0 = <&pmx_usb_power>;
+                pinctrl-names = "default";
+
+                usb_power: regulator@0 {
+                        compatible = "regulator-fixed";
+                        reg = <0>;
+                        regulator-name = "USB VBUS";
+                        regulator-min-microvolt = <5000000>;
+                        regulator-max-microvolt = <5000000>;
+                        enable-active-high;
+                        regulator-always-on;
+                        regulator-boot-on;
+                        gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+                };
+       };
+};
+
+&mdio {
+        status = "okay";
+
+        ethphy0: ethernet-phy@8 {
+                reg = <8>;
+        };
+};
+
+&eth0 {
+        status = "okay";
+        ethernet0-port@0 {
+                phy-handle = <&ethphy0>;
+        };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281-a0.dts b/arch/arm/boot/dts/kirkwood-rd88f6281-a0.dts
new file mode 100644 (file)
index 0000000..a803bbb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Marvell RD88F6181 A0 Board descrition
+ *
+ * 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.
+ *
+ * This file contains the definitions for the board with the A0 variant of
+ * the SoC. The ethernet switch does not have a "wan" port.
+ */
+
+/dts-v1/;
+#include "kirkwood-rd88f6281.dtsi"
+
+/ {
+       model = "Marvell RD88f6281 Reference design, with A0 SoC";
+       compatible = "marvell,rd88f6281-a0", "marvell,rd88f6281","marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+       dsa@0 {
+               switch@0 {
+                       reg = <10 0>;    /* MDIO address 10, switch 0 in tree */
+               };
+       };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281-a1.dts b/arch/arm/boot/dts/kirkwood-rd88f6281-a1.dts
new file mode 100644 (file)
index 0000000..baeebbf
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Marvell RD88F6181 A1 Board descrition
+ *
+ * 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.
+ *
+ * This file contains the definitions for the board with the A1 variant of
+ * the SoC. The ethernet switch has a "wan" port.
+ */
+
+/dts-v1/;
+
+#include "kirkwood-rd88f6281.dtsi"
+
+/ {
+       model = "Marvell RD88f6281 Reference design, with A1 SoC";
+       compatible = "marvell,rd88f6281-a1", "marvell,rd88f6281","marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+       dsa@0 {
+               switch@0 {
+                       reg = <0 0>;    /* MDIO address 0, switch 0 in tree */
+                       port@4 {
+                               reg = <4>;
+                               label = "wan";
+                       };
+               };
+       };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
new file mode 100644 (file)
index 0000000..d6368c3
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Marvell RD88F6181 Common Board descrition
+ *
+ * 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.
+ *
+ * This file contains the definitions that are common between the two
+ * variants of the Marvell Kirkwood Development Board.
+ */
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       pcie@1,0 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pinctrl-0 = <&pmx_sdio_cd>;
+                       pinctrl-names = "default";
+
+                       pmx_sdio_cd: pmx-sdio-cd {
+                               marvell,pins = "mpp28";
+                               marvell,function = "gpio";
+                       };
+               };
+
+               serial@12000 {
+                       status = "okay";
+
+               };
+
+               sata@80000 {
+                       status = "okay";
+                       nr-ports = <2>;
+               };
+               mvsdio@90000 {
+                       pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>;
+                       pinctrl-names = "default";
+                       status = "okay";
+                       cd-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+                       /* No WP GPIO */
+               };
+       };
+
+       dsa@0 {
+               compatible = "marvell,dsa";
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               dsa,ethernet = <&eth0>;
+               dsa,mii-bus = <&ethphy1>;
+
+               switch@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               label = "lan1";
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               label = "lan2";
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan3";
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan4";
+                       };
+
+                       port@5 {
+                               reg = <5>;
+                               label = "cpu";
+                       };
+               };
+       };
+};
+
+&nand {
+       status = "okay";
+
+       partition@0 {
+               label = "u-boot";
+               reg = <0x0000000 0x100000>;
+               read-only;
+       };
+
+       partition@100000 {
+               label = "uImage";
+               reg = <0x0100000 0x200000>;
+       };
+
+       partition@300000 {
+               label = "data";
+               reg = <0x0300000 0x500000>;
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@ff {
+               reg = <0xff>; /* No PHY attached */
+               speed = <1000>;
+               duple = <1>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
+
+&eth1 {
+       status = "okay";
+       ethernet1-port@0 {
+               phy-handle = <&ethphy1>;
+       };
+};
diff --git a/arch/arm/boot/dts/kirkwood-rs212.dts b/arch/arm/boot/dts/kirkwood-rs212.dts
new file mode 100644 (file)
index 0000000..93ec3d0
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology RS212";
+       compatible = "synology,rs212", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-3 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-38 {
+               status = "okay";
+       };
+
+       regulators-hdd-30-2 {
+               status = "okay";
+       };
+};
+
+&s35390a {
+       status = "okay";
+};
+
+&pcie2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-rs409.dts b/arch/arm/boot/dts/kirkwood-rs409.dts
new file mode 100644 (file)
index 0000000..311df4e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology RS409";
+       compatible = "synology,rs409", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-150-15-18 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-36 {
+               status = "okay";
+       };
+};
+
+&eth1 {
+       status = "okay";
+};
+
+&rs5c372 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-rs411.dts b/arch/arm/boot/dts/kirkwood-rs411.dts
new file mode 100644 (file)
index 0000000..f90da85
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-synology.dtsi"
+
+/ {
+       model = "Synology RS411 RS812";
+       compatible = "synology,rs411", "synology,rs812", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x8000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       gpio-fan-100-15-35-3 {
+               status = "okay";
+       };
+
+       gpio-leds-hdd-36 {
+               status = "okay";
+       };
+};
+
+&eth1 {
+       status = "okay";
+};
+
+&s35390a {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/kirkwood-synology.dtsi b/arch/arm/boot/dts/kirkwood-synology.dtsi
new file mode 100644 (file)
index 0000000..4227c97
--- /dev/null
@@ -0,0 +1,871 @@
+/*
+ * Nodes for Marvell 628x Synology devices
+ *
+ * Andrew Lunn <andrew@lunn.ch>
+ * Ben Peddell <klightspeed@killerwolves.net>
+ *
+ * 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.
+ */
+
+/ {
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       pcie@1,0 {
+                               status = "okay";
+                       };
+
+                       pcie2: pcie@2,0 {
+                               status = "disabled";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pmx_alarmled_12: pmx-alarmled-12 {
+                               marvell,pins = "mpp12";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanctrl_15: pmx-fanctrl-15 {
+                               marvell,pins = "mpp15";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanctrl_16: pmx-fanctrl-16 {
+                               marvell,pins = "mpp16";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanctrl_17: pmx-fanctrl-17 {
+                               marvell,pins = "mpp17";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanalarm_18: pmx-fanalarm-18 {
+                               marvell,pins = "mpp18";
+                               marvell,function = "gpo";
+                       };
+
+                       pmx_hddled_20: pmx-hddled-20 {
+                               marvell,pins = "mpp20";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_21: pmx-hddled-21 {
+                               marvell,pins = "mpp21";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_22: pmx-hddled-22 {
+                               marvell,pins = "mpp22";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_23: pmx-hddled-23 {
+                               marvell,pins = "mpp23";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_24: pmx-hddled-24 {
+                               marvell,pins = "mpp24";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_25: pmx-hddled-25 {
+                               marvell,pins = "mpp25";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_26: pmx-hddled-26 {
+                               marvell,pins = "mpp26";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_27: pmx-hddled-27 {
+                               marvell,pins = "mpp27";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_28: pmx-hddled-28 {
+                               marvell,pins = "mpp28";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hdd1_pwr_29: pmx-hdd1-pwr-29 {
+                               marvell,pins = "mpp29";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hdd1_pwr_30: pmx-hdd-pwr-30 {
+                               marvell,pins = "mpp30";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hdd2_pwr_31: pmx-hdd2-pwr-31 {
+                               marvell,pins = "mpp31";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanctrl_32: pmx-fanctrl-32 {
+                               marvell,pins = "mpp32";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanctrl_33: pmx-fanctrl-33 {
+                               marvell,pins = "mpp33";
+                               marvell,function = "gpo";
+                       };
+
+                       pmx_fanctrl_34: pmx-fanctrl-34 {
+                               marvell,pins = "mpp34";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hdd2_pwr_34: pmx-hdd2-pwr-34 {
+                               marvell,pins = "mpp34";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanalarm_35: pmx-fanalarm-35 {
+                               marvell,pins = "mpp35";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_36: pmx-hddled-36 {
+                               marvell,pins = "mpp36";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_37: pmx-hddled-37 {
+                               marvell,pins = "mpp37";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_38: pmx-hddled-38 {
+                               marvell,pins = "mpp38";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_39: pmx-hddled-39 {
+                               marvell,pins = "mpp39";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_40: pmx-hddled-40 {
+                               marvell,pins = "mpp40";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_41: pmx-hddled-41 {
+                               marvell,pins = "mpp41";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_42: pmx-hddled-42 {
+                               marvell,pins = "mpp42";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_43: pmx-hddled-43 {
+                               marvell,pins = "mpp43";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_44: pmx-hddled-44 {
+                               marvell,pins = "mpp44";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hddled_45: pmx-hddled-45 {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hdd3_pwr_44: pmx-hdd3-pwr-44 {
+                               marvell,pins = "mpp44";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_hdd4_pwr_45: pmx-hdd4-pwr-45 {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanalarm_44: pmx-fanalarm-44 {
+                               marvell,pins = "mpp44";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_fanalarm_45: pmx-fanalarm-45 {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+               };
+
+               rtc@10300 {
+                       status = "disabled";
+               };
+
+               spi@10600 {
+                       status = "okay";
+                       pinctrl-0 = <&pmx_spi>;
+                       pinctrl-names = "default";
+
+                       m25p80@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "st,m25p80";
+                               reg = <0>;
+                               spi-max-frequency = <20000000>;
+                               mode = <0>;
+
+                               partition@00000000 {
+                                       reg = <0x00000000 0x00080000>;
+                                       label = "RedBoot";
+                               };
+
+                               partition@00080000 {
+                                       reg = <0x00080000 0x00200000>;
+                                       label = "zImage";
+                               };
+
+                               partition@00280000 {
+                                       reg = <0x00280000 0x00140000>;
+                                       label = "rd.gz";
+                               };
+
+                               partition@003c0000 {
+                                       reg = <0x003c0000 0x00010000>;
+                                       label = "vendor";
+                               };
+
+                               partition@003d0000 {
+                                       reg = <0x003d0000 0x00020000>;
+                                       label = "RedBoot config";
+                               };
+
+                               partition@003f0000 {
+                                       reg = <0x003f0000 0x00010000>;
+                                       label = "FIS directory";
+                               };
+                       };
+               };
+
+               i2c@11000 {
+                       status = "okay";
+                       clock-frequency = <400000>;
+                       pinctrl-0 = <&pmx_twsi0>;
+                       pinctrl-names = "default";
+
+                       rs5c372: rs5c372@32 {
+                               status = "disabled";
+                               compatible = "ricoh,rs5c372";
+                               reg = <0x32>;
+                       };
+
+                       s35390a: s35390a@30 {
+                               status = "disabled";
+                               compatible = "ssi,s35390a";
+                               reg = <0x30>;
+                       };
+               };
+
+               serial@12000 {
+                       status = "okay";
+                       pinctrl-0 = <&pmx_uart0>;
+                       pinctrl-names = "default";
+               };
+
+               serial@12100 {
+                       status = "okay";
+                       pinctrl-0 = <&pmx_uart1>;
+                       pinctrl-names = "default";
+               };
+
+               poweroff@12100 {
+                       compatible = "synology,power-off";
+                       reg = <0x12100 0x100>;
+                       clocks = <&gate_clk 7>;
+               };
+
+               sata@80000 {
+                       pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+                       pinctrl-names = "default";
+                       status = "okay";
+                       nr-ports = <2>;
+               };
+       };
+
+       gpio-fan-150-32-35 {
+               status = "disabled";
+               compatible = "gpio-fan";
+               pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34
+                            &pmx_fanalarm_35>;
+               pinctrl-names = "default";
+               gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
+                        &gpio1 1 GPIO_ACTIVE_HIGH
+                        &gpio1 2 GPIO_ACTIVE_HIGH>;
+               gpio-fan,speed-map = <    0 0
+                                      2200 1
+                                      2500 2
+                                      3000 4
+                                      3300 3
+                                      3700 5
+                                      3800 6
+                                      4200 7 >;
+       };
+
+       gpio-fan-150-15-18 {
+               status = "disabled";
+               compatible = "gpio-fan";
+               pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+                            &pmx_fanalarm_18>;
+               pinctrl-names = "default";
+               gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+                        &gpio0 16 GPIO_ACTIVE_HIGH
+                        &gpio0 17 GPIO_ACTIVE_HIGH>;
+               alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+               gpio-fan,speed-map = <    0 0
+                                      2200 1
+                                      2500 2
+                                      3000 4
+                                      3300 3
+                                      3700 5
+                                      3800 6
+                                      4200 7 >;
+       };
+
+       gpio-fan-100-32-35 {
+               status = "disabled";
+               compatible = "gpio-fan";
+               pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34
+                            &pmx_fanalarm_35>;
+               pinctrl-names = "default";
+               gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
+                        &gpio1 1 GPIO_ACTIVE_HIGH
+                        &gpio1 2 GPIO_ACTIVE_HIGH>;
+               alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+               gpio-fan,speed-map = <    0 0
+                                      2500 1
+                                      3100 2
+                                      3800 3
+                                      4600 4
+                                      4800 5
+                                      4900 6
+                                      5000 7 >;
+       };
+
+       gpio-fan-100-15-18 {
+               status = "disabled";
+               compatible = "gpio-fan";
+               pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+                            &pmx_fanalarm_18>;
+               pinctrl-names = "default";
+               gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+                        &gpio0 16 GPIO_ACTIVE_HIGH
+                        &gpio0 17 GPIO_ACTIVE_HIGH>;
+               alarm-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+               gpio-fan,speed-map = <    0 0
+                                      2500 1
+                                      3100 2
+                                      3800 3
+                                      4600 4
+                                      4800 5
+                                      4900 6
+                                      5000 7 >;
+       };
+
+       gpio-fan-100-15-35-1 {
+               status = "disabled";
+               compatible = "gpio-fan";
+               pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+                            &pmx_fanalarm_35>;
+               pinctrl-names = "default";
+               gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+                        &gpio0 16 GPIO_ACTIVE_HIGH
+                        &gpio0 17 GPIO_ACTIVE_HIGH>;
+               alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+               gpio-fan,speed-map = <    0 0
+                                      2500 1
+                                      3100 2
+                                      3800 3
+                                      4600 4
+                                      4800 5
+                                      4900 6
+                                      5000 7 >;
+       };
+
+       gpio-fan-100-15-35-3 {
+               status = "disabled";
+               compatible = "gpio-fan";
+               pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17
+                            &pmx_fanalarm_35 &pmx_fanalarm_44 &pmx_fanalarm_45>;
+               pinctrl-names = "default";
+               gpios = <&gpio0 15 GPIO_ACTIVE_HIGH
+                        &gpio0 16 GPIO_ACTIVE_HIGH
+                        &gpio0 17 GPIO_ACTIVE_HIGH>;
+               alarm-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH
+                              &gpio1 12 GPIO_ACTIVE_HIGH
+                              &gpio1 13 GPIO_ACTIVE_HIGH>;
+               gpio-fan,speed-map = <    0 0
+                                      2500 1
+                                      3100 2
+                                      3800 3
+                                      4600 4
+                                      4800 5
+                                      4900 6
+                                      5000 7 >;
+       };
+
+       gpio-leds-alarm-12 {
+               status = "disabled";
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_alarmled_12>;
+               pinctrl-names = "default";
+
+               hdd1-green {
+                       label = "synology:alarm";
+                       gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-leds-hdd-20 {
+               status = "disabled";
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_hddled_20 &pmx_hddled_21 &pmx_hddled_22
+                            &pmx_hddled_23 &pmx_hddled_24 &pmx_hddled_25
+                            &pmx_hddled_26 &pmx_hddled_27>;
+               pinctrl-names = "default";
+
+               hdd1-green {
+                       label = "synology:green:hdd1";
+                       gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd1-amber {
+                       label = "synology:amber:hdd1";
+                       gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-green {
+                       label = "synology:green:hdd2";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-amber {
+                       label = "synology:amber:hdd2";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd3-green {
+                       label = "synology:green:hdd3";
+                       gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd3-amber {
+                       label = "synology:amber:hdd3";
+                       gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd4-green {
+                       label = "synology:green:hdd4";
+                       gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd4-amber {
+                       label = "synology:amber:hdd4";
+                       gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-leds-hdd-21-1 {
+               status = "disabled";
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23>;
+               pinctrl-names = "default";
+
+               hdd1-green {
+                       label = "synology:green:hdd1";
+                       gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd1-amber {
+                       label = "synology:amber:hdd1";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-leds-hdd-21-2 {
+               status = "disabled";
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_hddled_21 &pmx_hddled_23 &pmx_hddled_20 &pmx_hddled_22>;
+               pinctrl-names = "default";
+
+               hdd1-green {
+                       label = "synology:green:hdd1";
+                       gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd1-amber {
+                       label = "synology:amber:hdd1";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-green {
+                       label = "synology:green:hdd2";
+                       gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-amber {
+                       label = "synology:amber:hdd2";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-leds-hdd-36 {
+               status = "disabled";
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_hddled_36 &pmx_hddled_37 &pmx_hddled_38
+                            &pmx_hddled_39 &pmx_hddled_40 &pmx_hddled_41
+                            &pmx_hddled_42 &pmx_hddled_43 &pmx_hddled_44
+                            &pmx_hddled_45>;
+               pinctrl-names = "default";
+
+               hdd1-green {
+                       label = "synology:green:hdd1";
+                       gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd1-amber {
+                       label = "synology:amber:hdd1";
+                       gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-green {
+                       label = "synology:green:hdd2";
+                       gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-amber {
+                       label = "synology:amber:hdd2";
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd3-green {
+                       label = "synology:green:hdd3";
+                       gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd3-amber {
+                       label = "synology:amber:hdd3";
+                       gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd4-green {
+                       label = "synology:green:hdd4";
+                       gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd4-amber {
+                       label = "synology:amber:hdd4";
+                       gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd5-green {
+                       label = "synology:green:hdd5";
+                       gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd5-amber {
+                       label = "synology:amber:hdd5";
+                       gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-leds-hdd-38 {
+               status = "disabled";
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pmx_hddled_38 &pmx_hddled_39 &pmx_hddled_36 &pmx_hddled_37>;
+               pinctrl-names = "default";
+
+               hdd1-green {
+                       label = "synology:green:hdd1";
+                       gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd1-amber {
+                       label = "synology:amber:hdd1";
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-green {
+                       label = "synology:green:hdd2";
+                       gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+               };
+
+               hdd2-amber {
+                       label = "synology:amber:hdd2";
+                       gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       regulators-hdd-29 {
+               status = "disabled";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_hdd1_pwr_29 &pmx_hdd2_pwr_31>;
+               pinctrl-names = "default";
+
+               regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "hdd1power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "hdd2power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       regulators-hdd-30-1 {
+               status = "disabled";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_hdd1_pwr_30>;
+               pinctrl-names = "default";
+
+               regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "hdd1power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       regulators-hdd-30-2 {
+               status = "disabled";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34>;
+               pinctrl-names = "default";
+
+               regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "hdd1power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "hdd2power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       regulators-hdd-30-4 {
+               status = "disabled";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_hdd1_pwr_30 &pmx_hdd2_pwr_34
+                            &pmx_hdd3_pwr_44 &pmx_hdd4_pwr_45>;
+               pinctrl-names = "default";
+
+               regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "hdd1power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "hdd2power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "hdd3power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "hdd4power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       regulators-hdd-31 {
+               status = "disabled";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_hdd2_pwr_31>;
+               pinctrl-names = "default";
+
+               regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "hdd2power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       regulators-hdd-34 {
+               status = "disabled";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_hdd2_pwr_34 &pmx_hdd3_pwr_44
+                            &pmx_hdd4_pwr_45>;
+               pinctrl-names = "default";
+
+               regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "hdd2power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "hdd3power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+               };
+
+               regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "hdd4power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       startup-delay-us = <5000000>;
+                       gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               device_type = "ethernet-phy";
+               reg = <8>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               device_type = "ethernet-phy";
+               reg = <9>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
+
+&eth1 {
+       status = "disabled";
+
+       ethernet1-port@0 {
+               phy-handle = <&ethphy1>;
+       };
+};
diff --git a/arch/arm/boot/dts/kirkwood-t5325.dts b/arch/arm/boot/dts/kirkwood-t5325.dts
new file mode 100644 (file)
index 0000000..7d1c767
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Device Tree file for HP t5325 Thin Client"
+ *
+ * Copyright (C) 2014
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.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.
+*/
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+       model = "HP t5325 Thin Client";
+       compatible = "hp,t5325", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8";
+       };
+
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       pcie@1,0 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pinctrl-0 = <&pmx_i2s &pmx_sysrst>;
+                       pinctrl-names = "default";
+
+                       pmx_button_power: pmx-button_power {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_power_off: pmx-power-off {
+                               marvell,pins = "mpp48";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_led: pmx-led {
+                               marvell,pins = "mpp21";
+                               marvell,function = "gpio";
+                       };
+
+                       pmx_usb_sata_power_enable: pmx-usb-sata-power-enable {
+                               marvell,pins = "mpp44";
+                               marvell,function = "gpio";
+                       };
+
+                       /*
+                        * Redefined from kirkwood-6281.dtsi, because
+                        * we don't use SPI CS on MPP0, but on MPP7.
+                        */
+                       pmx_spi: pmx-spi {
+                               marvell,pins = "mpp1", "mpp2", "mpp3", "mpp7";
+                               marvell,function = "spi";
+                       };
+
+                       pmx_sysrst: pmx-sysrst {
+                               marvell,pins = "mpp6";
+                               marvell,function = "sysrst";
+                       };
+
+                       pmx_i2s: pmx-i2s {
+                               marvell,pins = "mpp39", "mpp40", "mpp41", "mpp42",
+                                              "mpp43";
+                               marvell,function = "audio";
+                       };
+               };
+
+               spi@10600 {
+                       pinctrl-0 = <&pmx_spi>;
+                       pinctrl-names = "default";
+                       status = "okay";
+
+                       flash@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "st,m25p80";
+                               spi-max-frequency = <86000000>;
+                               reg = <0>;
+                               mode = <0>;
+
+                               partition@0 {
+                                       reg = <0x0 0x80000>;
+                                       label = "u-boot";
+                               };
+
+                               partition@1 {
+                                       reg = <0x80000 0x40000>;
+                                       label = "SSD firmware";
+                               };
+
+                               partition@2 {
+                                       reg = <0xc0000 0x10000>;
+                                       label = "u-boot env";
+                               };
+
+                               partition@3 {
+                                       reg = <0xd0000 0x10000>;
+                                       label = "permanent u-boot env";
+                               };
+
+                               partition@4 {
+                                       reg = <0xd0000 0x10000>;
+                                       label = "permanent u-boot env";
+                               };
+                       };
+               };
+
+               i2c@11000 {
+                       status = "okay";
+
+                       alc5621: alc5621@1a {
+                               compatible = "realtek,alc5621";
+                               reg = <0x1a>;
+                       };
+               };
+
+               serial@12000 {
+                       status = "okay";
+               };
+
+               sata@80000 {
+                       status = "okay";
+                       nr-ports = <2>;
+               };
+
+               audio: audio-controller@a0000 {
+                       status = "okay";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_usb_sata_power_enable>;
+               pinctrl-names = "default";
+
+               usb_power: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "USB-SATA Power";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_button_power>;
+               pinctrl-names = "default";
+
+               button@1 {
+                       label = "Power Button";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       gpio_poweroff {
+               compatible = "gpio-poweroff";
+               pinctrl-0 = <&pmx_power_off>;
+               pinctrl-names = "default";
+               gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+       };
+
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy0: ethernet-phy {
+               device_type = "ethernet-phy";
+               reg = <8>;
+       };
+};
+
+&eth0 {
+       status = "okay";
+       ethernet0-port@0 {
+               phy-handle = <&ethphy0>;
+       };
+};
diff --git a/arch/arm/boot/dts/kirkwood-ts419-6281.dts b/arch/arm/boot/dts/kirkwood-ts419-6281.dts
new file mode 100644 (file)
index 0000000..aa22aa8
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Device Tree file for QNAP TS41X with 6281 SoC
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-ts219.dtsi"
+#include "kirkwood-ts419.dtsi"
+
+&ethphy0 { reg = <8>; };
+&ethphy1 { reg = <0>; };
diff --git a/arch/arm/boot/dts/kirkwood-ts419-6282.dts b/arch/arm/boot/dts/kirkwood-ts419-6282.dts
new file mode 100644 (file)
index 0000000..d7512d4
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Device Tree file for QNAP TS41X with 6282 SoC
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-ts219.dtsi"
+#include "kirkwood-ts419.dtsi"
+
+/ {
+       mbus {
+               pcie-controller {
+                       status = "okay";
+
+                       pcie@2,0 {
+                               status = "okay";
+                       };
+               };
+       };
+};
+
+&ethphy0 { reg = <0>; };
+&ethphy1 { reg = <1>; };
diff --git a/arch/arm/boot/dts/kirkwood-ts419.dtsi b/arch/arm/boot/dts/kirkwood-ts419.dtsi
new file mode 100644 (file)
index 0000000..1a9c624
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Device Tree include file for QNAP TS41X
+ *
+ * Copyright (C) 2013, Andrew Lunn <andrew@lunn.ch>
+ *
+ * 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.
+ */
+
+/ {
+       model = "QNAP TS419 family";
+       compatible = "qnap,ts419", "marvell,kirkwood";
+
+       ocp@f1000000 {
+               pinctrl: pinctrl@10000 {
+                       pinctrl-names = "default";
+
+                       pmx_USB_copy_button: pmx-USB-copy-button {
+                               marvell,pins = "mpp43";
+                               marvell,function = "gpio";
+                       };
+                       pmx_reset_button: pmx-reset-button {
+                               marvell,pins = "mpp37";
+                               marvell,function = "gpio";
+                       };
+                       /*
+                        * JP1 indicates if an LCD module is installed
+                        * on the serial port (0), or if the port is used
+                        * as a console (1).
+                        */
+                       pmx_jumper_jp1: pmx-jumper_jp1 {
+                               marvell,pins = "mpp45";
+                               marvell,function = "gpio";
+                       };
+
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+               pinctrl-names = "default";
+
+               button@1 {
+                       label = "USB Copy";
+                       linux,code = <KEY_COPY>;
+                       gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+               };
+               button@2 {
+                       label = "Reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&mdio {
+       status = "okay";
+
+       ethphy1: ethernet-phy@1 {
+               device_type = "ethernet-phy";
+                /* overwrite reg property in board file */
+       };
+};
+
+&eth1 {
+       status = "okay";
+       ethernet1-port@0 {
+               phy-handle = <&ethphy1>;
+       };
+};
index 6abf44d257dfa3fd7cadd8ca85a005d4ad9eed8f..90384587c27843c563d2c4328ce9411f4c26458b 100644 (file)
@@ -24,6 +24,7 @@
        aliases {
               gpio0 = &gpio0;
               gpio1 = &gpio1;
+              i2c0 = &i2c0;
        };
 
        mbus {
                        clocks = <&gate_clk 7>;
                };
 
-               i2c@11000 {
+               i2c0: i2c@11000 {
                        compatible = "marvell,mv64xxx-i2c";
                        reg = <0x11000 0x20>;
                        #address-cells = <1>;
                        reg = <0x20000 0x80>, <0x1500 0x20>;
                };
 
+               system-controller@20000 {
+                       compatible = "marvell,orion-system-controller";
+                       reg = <0x20000 0x120>;
+               };
+
                bridge_intc: bridge-interrupt-ctrl@20110 {
                        compatible = "marvell,orion-bridge-intc";
                        interrupt-controller;
                        #clock-cells = <1>;
                };
 
+               l2: l2-cache@20128 {
+                       compatible = "marvell,kirkwood-cache";
+                       reg = <0x20128 0x4>;
+               };
+
                intc: main-interrupt-ctrl@20200 {
                        compatible = "marvell,orion-intc";
                        interrupt-controller;
 
                wdt: watchdog-timer@20300 {
                        compatible = "marvell,orion-wdt";
-                       reg = <0x20300 0x28>;
+                       reg = <0x20300 0x28>, <0x20108 0x4>;
                        interrupt-parent = <&bridge_intc>;
                        interrupts = <3>;
                        clocks = <&gate_clk 7>;
                        #phy-cells = <0>;
                        status = "ok";
                };
+
+               audio0: audio-controller@a0000 {
+                       compatible = "marvell,kirkwood-audio";
+                       reg = <0xa0000 0x2210>;
+                       interrupts = <24>;
+                       clocks = <&gate_clk 9>;
+                       clock-names = "internal";
+                       status = "disabled";
+               };
        };
 };
index 1579c3491ccd5fe5ee0cce9792d519d739843fe4..0c9647d28765469cb1b0ba87bc6c6d85c9565acf 100644 (file)
                        #size-cells = <1>;
                        ranges = <0xc2000000 0xc2000000 0x1000000>;
 
-                       reset-controller@c2000000 {
+                       rstc: reset-controller@c2000000 {
                                compatible = "sirf,marco-rstc";
                                reg = <0xc2000000 0x10000>;
+                               #reset-cells = <1>;
                        };
                };
 
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
new file mode 100644 (file)
index 0000000..73e272f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Common file for GPMC connected smsc9221 on omaps
+ *
+ * Compared to smsc911x, smsc9221 (and others like smsc9217
+ * or smsc 9218) has faster timings, leading to higher
+ * bandwidth.
+ *
+ * Note that the board specifc DTS file needs to specify
+ * ranges, pinctrl, reg, interrupt parent and interrupts.
+ */
+
+/ {
+       vddvario: regulator-vddvario {
+                 compatible = "regulator-fixed";
+                 regulator-name = "vddvario";
+                 regulator-always-on;
+       };
+
+       vdd33a: regulator-vdd33a {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd33a";
+               regulator-always-on;
+       };
+};
+
+&gpmc {
+       ethernet@gpmc {
+               compatible = "smsc,lan9221","smsc,lan9115";
+               bank-width = <2>;
+
+               gpmc,mux-add-data;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <42>;
+               gpmc,cs-wr-off-ns = <36>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <12>;
+               gpmc,adv-wr-off-ns = <12>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <42>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <36>;
+               gpmc,rd-cycle-ns = <60>;
+               gpmc,wr-cycle-ns = <54>;
+               gpmc,access-ns = <36>;
+               gpmc,page-burst-access-ns = <0>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,wr-data-mux-bus-ns = <18>;
+               gpmc,wr-access-ns = <42>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-diffcsen;
+
+               vddvario-supply = <&vddvario>;
+               vdd33a-supply = <&vdd33a>;
+               reg-io-width = <4>;
+               smsc,save-mac-address;
+       };
+};
index 5377ddf83bf8f99aebb33d2e5019e870ee5f2e18..22f35ea142c199082afdd8ba626bd7c5e0b6cd54 100644 (file)
                        ti,hwmods = "timer12";
                        ti,timer-pwm;
                };
+
+               dss: dss@48050000 {
+                       compatible = "ti,omap2-dss";
+                       reg = <0x48050000 0x400>;
+                       status = "disabled";
+                       ti,hwmods = "dss_core";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       dispc@48050400 {
+                               compatible = "ti,omap2-dispc";
+                               reg = <0x48050400 0x400>;
+                               interrupts = <25>;
+                               ti,hwmods = "dss_dispc";
+                       };
+
+                       rfbi: encoder@48050800 {
+                               compatible = "ti,omap2-rfbi";
+                               reg = <0x48050800 0x400>;
+                               status = "disabled";
+                               ti,hwmods = "dss_rfbi";
+                       };
+
+                       venc: encoder@48050c00 {
+                               compatible = "ti,omap2-venc";
+                               reg = <0x48050c00 0x400>;
+                               status = "disabled";
+                               ti,hwmods = "dss_venc";
+                       };
+               };
        };
 };
index 60c605de22ddcdfb9f7220669c12c443a4c218fa..85b1fb014c4314efe82eca9fcb7dfa7e482cb8d2 100644 (file)
@@ -99,6 +99,7 @@
                        dmas = <&sdma 31>,
                               <&sdma 32>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp2: mcbsp@48076000 {
                        dmas = <&sdma 33>,
                               <&sdma 34>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                msdi1: mmc@4809c000 {
index d624345666f56a1468c9e628ae1f3b971fb5d43a..9d2f028fd6872fd139a3855b4bf051411dbd9c23 100644 (file)
                        dmas = <&sdma 31>,
                               <&sdma 32>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp2: mcbsp@48076000 {
                        dmas = <&sdma 33>,
                               <&sdma 34>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp3: mcbsp@4808c000 {
                        dmas = <&sdma 17>,
                               <&sdma 18>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp4: mcbsp@4808e000 {
                        dmas = <&sdma 19>,
                               <&sdma 20>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp5: mcbsp@48096000 {
                        dmas = <&sdma 21>,
                               <&sdma 22>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mmc1: mmc@4809c000 {
index 447e714d435b66a769a05256d82cc0bebdc879b3..cf0be662297e964186c378788ddbdfa00ca80664 100644 (file)
                reg = <0x80000000 0x20000000>; /* 512 MB */
        };
 
+       aliases {
+               display0 = &dvi0;
+               display1 = &tv0;
+       };
+
        leds {
                compatible = "gpio-leds";
 
                reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */
                vcc-supply = <&hsusb2_power>;
        };
+
+       tfp410: encoder@0 {
+               compatible = "ti,tfp410";
+               powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
+
+               /* XXX pinctrl from twl */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tfp410_in: endpoint@0 {
+                                       remote-endpoint = <&dpi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tfp410_out: endpoint@0 {
+                                       remote-endpoint = <&dvi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       dvi0: connector@0 {
+               compatible = "dvi-connector";
+               label = "dvi";
+
+               digital;
+
+               ddc-i2c-bus = <&i2c3>;
+
+               port {
+                       dvi_connector_in: endpoint {
+                               remote-endpoint = <&tfp410_out>;
+                       };
+               };
+       };
+
+       tv0: connector@1 {
+               compatible = "svideo-connector";
+               label = "tv";
+
+               port {
+                       tv_connector_in: endpoint {
+                               remote-endpoint = <&venc_out>;
+                       };
+               };
+       };
 };
 
 &omap3_pmx_wkup {
                        0x0e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot2.gpio_4 */
                >;
        };
+
+       dss_dpi_pins2: pinmux_dss_dpi_pins1 {
+               pinctrl-single,pins = <
+                       0x0a (PIN_OUTPUT | MUX_MODE3)   /* sys_boot0.dss_data18 */
+                       0x0c (PIN_OUTPUT | MUX_MODE3)   /* sys_boot1.dss_data19 */
+                       0x10 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot3.dss_data20 */
+                       0x12 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot4.dss_data21 */
+                       0x14 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot5.dss_data22 */
+                       0x16 (PIN_OUTPUT | MUX_MODE3)   /* sys_boot6.dss_data23 */
+               >;
+       };
 };
 
 &omap3_pmx_core {
                        OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi2_cs1.hsusb2_data3 */
                >;
        };
+
+       dss_dpi_pins1: pinmux_dss_dpi_pins2 {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+                       OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+                       OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+                       OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+
+                       OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+
+                       OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE3)   /* dss_data18.dss_data0 */
+                       OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE3)   /* dss_data19.dss_data1 */
+                       OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE3)   /* dss_data20.dss_data2 */
+                       OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE3)   /* dss_data21.dss_data3 */
+                       OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE3)   /* dss_data22.dss_data4 */
+                       OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3)   /* dss_data23.dss_data5 */
+               >;
+       };
 };
 
 &omap3_pmx_core2 {
 
 &i2c3 {
        clock-frequency = <100000>;
-
-       /*
-        * Display monitor features are burnt in the EEPROM
-        * as EDID data.
-        */
-       eeprom@50 {
-               compatible = "ti,eeprom";
-               reg = <0x50>;
-       };
 };
 
 &mmc1 {
        regulator-max-microvolt = <1800000>;
        regulator-always-on;
 };
+
+&mcbsp2 {
+       status = "okay";
+};
+
+&dss {
+       status = "ok";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               &dss_dpi_pins1
+               &dss_dpi_pins2
+       >;
+
+       port {
+               dpi_out: endpoint {
+                       remote-endpoint = <&tfp410_in>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&venc {
+       status = "ok";
+
+       vdda-supply = <&vdac>;
+
+       port {
+               venc_out: endpoint {
+                       remote-endpoint = <&tv_connector_in>;
+                       ti,channels = <2>;
+               };
+       };
+};
index 5053766d369b696afaac39fc8dba1f811f010d41..3c3e6da1deacdaddd2ec75cfa2aa3ba8837b929e 100644 (file)
                reg = <0x80000000 0x10000000>; /* 256 MB */
        };
 
+       aliases {
+               display0 = &dvi0;
+               display1 = &tv0;
+       };
+
        leds {
                compatible = "gpio-leds";
                pmu_stat {
                };
 
        };
+
+       tfp410: encoder@0 {
+               compatible = "ti,tfp410";
+               powerdown-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>;  /* gpio_170 */
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&tfp410_pins>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tfp410_in: endpoint@0 {
+                                       remote-endpoint = <&dpi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tfp410_out: endpoint@0 {
+                                       remote-endpoint = <&dvi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       dvi0: connector@0 {
+               compatible = "dvi-connector";
+               label = "dvi";
+
+               digital;
+
+               ddc-i2c-bus = <&i2c3>;
+
+               port {
+                       dvi_connector_in: endpoint {
+                               remote-endpoint = <&tfp410_out>;
+                       };
+               };
+       };
+
+       tv0: connector@1 {
+               compatible = "svideo-connector";
+               label = "tv";
+
+               port {
+                       tv_connector_in: endpoint {
+                               remote-endpoint = <&venc_out>;
+                       };
+               };
+       };
 };
 
 &omap3_pmx_wkup {
                        0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
                >;
        };
+
+       tfp410_pins: pinmux_tfp410_pins {
+               pinctrl-single,pins = <
+                       0x194 (PIN_OUTPUT | MUX_MODE4)  /* hdq_sio.gpio_170 */
+               >;
+       };
+
+       dss_dpi_pins: pinmux_dss_dpi_pins {
+               pinctrl-single,pins = <
+                       0x0a4 (PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
+                       0x0a6 (PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
+                       0x0a8 (PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
+                       0x0aa (PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+                       0x0ac (PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
+                       0x0ae (PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
+                       0x0b0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
+                       0x0b2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
+                       0x0b4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
+                       0x0b6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
+                       0x0b8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       0x0ba (PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       0x0bc (PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       0x0be (PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       0x0c0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       0x0c2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       0x0c4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       0x0c6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       0x0c8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       0x0ca (PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       0x0cc (PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       0x0ce (PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+                       0x0d0 (PIN_OUTPUT | MUX_MODE0)   /* dss_data18.dss_data18 */
+                       0x0d2 (PIN_OUTPUT | MUX_MODE0)   /* dss_data19.dss_data19 */
+                       0x0d4 (PIN_OUTPUT | MUX_MODE0)   /* dss_data20.dss_data20 */
+                       0x0d6 (PIN_OUTPUT | MUX_MODE0)   /* dss_data21.dss_data21 */
+                       0x0d8 (PIN_OUTPUT | MUX_MODE0)   /* dss_data22.dss_data22 */
+                       0x0da (PIN_OUTPUT | MUX_MODE0)   /* dss_data23.dss_data23 */
+               >;
+       };
 };
 
 &omap3_pmx_core2 {
 #include "twl4030.dtsi"
 #include "twl4030_omap3.dtsi"
 
+&i2c3 {
+       clock-frequency = <100000>;
+};
+
 &mmc1 {
        vmmc-supply = <&vmmc1>;
        vmmc_aux-supply = <&vsim>;
        regulator-max-microvolt = <1800000>;
        regulator-always-on;
 };
+
+&mcbsp2 {
+       status = "okay";
+};
+
+/* Needed to power the DPI pins */
+&vpll2 {
+       regulator-always-on;
+};
+
+&dss {
+       status = "ok";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&dss_dpi_pins>;
+
+       port {
+               dpi_out: endpoint {
+                       remote-endpoint = <&tfp410_in>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&venc {
+       status = "ok";
+
+       vdda-supply = <&vdac>;
+
+       port {
+               venc_out: endpoint {
+                       remote-endpoint = <&tv_connector_in>;
+                       ti,channels = <2>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts
new file mode 100644 (file)
index 0000000..d00502f
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Support for CompuLab CM-T3517
+ */
+/dts-v1/;
+
+#include "am3517.dtsi"
+#include "omap3-cm-t3x.dtsi"
+
+/ {
+       model = "CompuLab CM-T3517";
+       compatible = "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3";
+
+       vmmc:  regulator-vmmc {
+                compatible = "regulator-fixed";
+                regulator-name = "vmmc";
+                regulator-min-microvolt = <3300000>;
+                regulator-max-microvolt = <3300000>;
+        };
+
+       wl12xx_vmmc2: wl12xx_vmmc2 {
+               compatible = "regulator-fixed";
+               regulator-name = "vw1271";
+               pinctrl-names = "default";
+               pinctrl-0 = <
+                               &wl12xx_wkup_pins
+                               &wl12xx_core_pins
+                           >;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpio = <&gpio1 6 GPIO_ACTIVE_HIGH >; /* gpio6 */
+               startup-delay-us = <20000>;
+               enable-active-high;
+       };
+
+       wl12xx_vaux2: wl12xx_vaux2 {
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1271_vaux2";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+};
+
+&omap3_pmx_wkup {
+
+       wl12xx_wkup_pins: pinmux_wl12xx_wkup_pins {
+               pinctrl-single,pins = <
+                       OMAP3_WKUP_IOPAD(0x2a0e, PIN_OUTPUT | MUX_MODE4)        /* sys_boot2.gpio_4 */
+                       OMAP3_WKUP_IOPAD(0x2a12, PIN_OUTPUT | MUX_MODE4)        /* sys_boot4.gpio_6 */
+               >;
+       };
+};
+
+&omap3_pmx_core {
+
+       phy1_reset_pins: pinmux_hsusb1_phy_reset_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE4)       /* uart2_tx.gpio_146 */
+               >;
+       };
+
+       phy2_reset_pins: pinmux_hsusb2_phy_reset_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x217a, PIN_OUTPUT | MUX_MODE4)       /* uart2_rx.gpio_147 */
+               >;
+       };
+
+       otg_drv_vbus: pinmux_otg_drv_vbus {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2210, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_50Mhz_clk.usb0_drvvbus */
+               >;
+       };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+               >;
+       };
+
+       wl12xx_core_pins: pinmux_wl12xx_core_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20b8, PIN_OUTPUT | MUX_MODE4)       /* gpmc_ncs5.gpio_56 */
+                       OMAP3_CORE1_IOPAD(0x2176, PIN_INPUT_PULLUP | MUX_MODE4) /* uart2_rts.gpio_145 */
+               >;
+       };
+
+       usb_hub_pins: pinmux_usb_hub_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2184, PIN_OUTPUT | MUX_MODE4)       /* mcbsp4_clkx.gpio_152 - USB HUB RST */
+               >;
+       };
+};
+
+&hsusb1_phy {
+       pinctrl-names = "default";
+       pinctrl-0 = <&phy1_reset_pins>;
+       reset-gpios = <&gpio5 18 GPIO_ACTIVE_LOW>;
+};
+
+&hsusb2_phy {
+       pinctrl-names = "default";
+       pinctrl-0 = <&phy2_reset_pins>;
+       reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>;
+};
+
+&davinci_emac {
+       status = "okay";
+};
+
+&davinci_mdio {
+       status = "okay";
+};
+
+&am35x_otg_hs {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&otg_drv_vbus>;
+};
+
+&mmc1 {
+       vmmc-supply = <&vmmc>;
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&wl12xx_vmmc2>;
+       vmmc_aux-supply = <&wl12xx_vaux2>;
+       non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+};
diff --git a/arch/arm/boot/dts/omap3-cm-t3530.dts b/arch/arm/boot/dts/omap3-cm-t3530.dts
new file mode 100644 (file)
index 0000000..d145849
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Support for CompuLab CM-T3530
+ */
+/dts-v1/;
+
+#include "omap34xx.dtsi"
+#include "omap3-cm-t3x30.dtsi"
+
+/ {
+       model = "CompuLab CM-T3530";
+       compatible = "compulab,omap3-cm-t3530", "ti,omap34xx", "ti,omap3";
+
+       /* Regulator to trigger the reset signal of the Wifi module */
+       mmc2_sdio_reset: regulator-mmc2-sdio-reset {
+               compatible = "regulator-fixed";
+               regulator-name = "regulator-mmc2-sdio-reset";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&twl_gpio 2 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&omap3_pmx_core {
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat3.sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1)               /* sdmmc2_dat4.sdmmc2_dir_dat0 */
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1)               /* sdmmc2_dat5.sdmmc2_dir_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1)               /* sdmmc2_dat6.sdmmc2_dir_cmd */
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1)                /* sdmmc2_dat7.sdmmc2_clkin */
+               >;
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&mmc2_sdio_reset>;
+       non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+};
index 486f4d6c4219176b91ce40285f9c123ed17834d1..b3f9a50b3bc8339d269307001f6cd7563205b79f 100644 (file)
 };
 
 &omap3_pmx_core {
-       mmc1_pins: pinmux_mmc1_pins {
-               pinctrl-single,pins = <
-                       0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
-                       0x116 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_cmd.sdmmc1_cmd */
-                       0x118 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat0.sdmmc1_dat0 */
-                       0x11a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat1.sdmmc1_dat1 */
-                       0x11c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat2.sdmmc1_dat2 */
-                       0x11e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc1_dat3.sdmmc1_dat3 */
-               >;
-       };
 
        mmc2_pins: pinmux_mmc2_pins {
                pinctrl-single,pins = <
-                       0x128 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_clk.sdmmc2_clk */
-                       0x12a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_cmd.sdmmc2_cmd */
-                       0x12c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat0.sdmmc2_dat0 */
-                       0x12e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat1.sdmmc2_dat1 */
-                       0x130 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat2.sdmmc2_dat2 */
-                       0x132 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc2_dat3.sdmmc2_dat3 */
-               >;
-       };
-
-       smsc1_pins: pinmux_smsc1_pins {
-               pinctrl-single,pins = <
-                       0x88 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_ncs5.gpmc_ncs5 */
-                       0x16a (PIN_INPUT_PULLUP | MUX_MODE4)    /* uart3_cts_rctx.gpio_163 */
-               >;
-       };
-
-       uart3_pins: pinmux_uart3_pins {
-               pinctrl-single,pins = <
-                       0x16e (PIN_INPUT | MUX_MODE0)           /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0)          /* uart3_tx_irtx.uart3_tx_irtx */
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
                >;
        };
 
        wl12xx_gpio: pinmux_wl12xx_gpio {
                pinctrl-single,pins = <
-                       0xb2 (PIN_OUTPUT | MUX_MODE4)           /* dss_data3.gpio_73 */
-                       0x134 (PIN_INPUT | MUX_MODE4)           /* sdmmc2_dat4.gpio_136 */
+                       OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE4)       /* dss_data3.gpio_73 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT | MUX_MODE4)        /* sdmmc2_dat4.gpio_136 */
                >;
        };
 };
 
-&mmc1 {
-       vmmc-supply = <&vmmc1>;
-       bus-width = <4>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&mmc1_pins>;
-};
-
 &mmc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc2_pins>;
        bus-width = <4>;
        cap-power-off-card;
 };
-
-&smsc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&smsc1_pins>;
-};
-
-&uart3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart3_pins>;
-};
diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
new file mode 100644 (file)
index 0000000..c671a22
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Common support for CompuLab CM-T3x CoMs
+ */
+
+/ {
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&green_led_pins>;
+               ledb {
+                       label = "cm-t3x:green";
+                       gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>;  /* gpio186 */
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       /* HS USB Port 1 Power */
+       hsusb1_power: hsusb1_power_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb1_vbus";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <70000>;
+       };
+
+       /* HS USB Port 2 Power */
+       hsusb2_power: hsusb2_power_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb2_vbus";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <70000>;
+       };
+
+       /* HS USB Host PHY on PORT 1 */
+       hsusb1_phy: hsusb1_phy {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&hsusb1_power>;
+       };
+
+       /* HS USB Host PHY on PORT 2 */
+       hsusb2_phy: hsusb2_phy {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&hsusb2_power>;
+       };
+};
+
+&omap3_pmx_core {
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT  | MUX_MODE0)       /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)       /* uart3_tx_irtx.uart3_tx_irtx */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+               >;
+       };
+
+       green_led_pins: pinmux_green_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21e2, PIN_OUTPUT | MUX_MODE4)       /* sys_clkout2.gpio_186 */
+               >;
+       };
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       bus-width = <4>;
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+};
+&usbhshost {
+       port1-mode = "ehci-phy";
+       port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <&hsusb1_phy &hsusb2_phy>;
+};
index 3a9f004d89245454836e032d25ed950fe4e5d4fe..d00055809e31d79b9d1730c06efe02c7e2e6f747 100644 (file)
@@ -1,28 +1,16 @@
 /*
- * Common support for CompuLab CM-T3530 and  CM-T3730
+ * Common support for CompuLab CM-T3x30 CoMs
  */
 
-/ {
-       memory {
-               device_type = "memory";
-               reg = <0x80000000 0x10000000>; /* 256 MB */
-       };
+#include "omap3-cm-t3x.dtsi"
 
+/ {
        cpus {
                cpu@0 {
                        cpu0-supply = <&vcc>;
                };
        };
 
-       leds {
-               compatible = "gpio-leds";
-               ledb {
-                       label = "cm-t35:green";
-                       gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>;  /* gpio186 */
-                       linux,default-trigger = "heartbeat";
-               };
-       };
-
        vddvario: regulator-vddvario {
                compatible = "regulator-fixed";
                regulator-name = "vddvario";
        };
 };
 
+&omap3_pmx_core {
+
+       smsc1_pins: pinmux_smsc1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20b8, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs5.gpmc_ncs5 */
+                       OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLUP | MUX_MODE4) /* uart3_cts_rctx.gpio_163 */
+               >;
+       };
+
+       hsusb0_pins: pinmux_hsusb0_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)               /* hsusb0_clk.hsusb0_clk */
+                       OMAP3_CORE1_IOPAD(0x21a2, PIN_OUTPUT | MUX_MODE0)               /* hsusb0_stp.hsusb0_stp */
+                       OMAP3_CORE1_IOPAD(0x21a4, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_dir.hsusb0_dir */
+                       OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_nxt.hsusb0_nxt */
+                       OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data0.hsusb2_data0 */
+                       OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data1.hsusb0_data1 */
+                       OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data2.hsusb0_data2 */
+                       OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data7.hsusb0_data3 */
+                       OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data7.hsusb0_data4 */
+                       OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data7.hsusb0_data5 */
+                       OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data7.hsusb0_data6 */
+                       OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* hsusb0_data7.hsusb0_data7 */
+               >;
+       };
+};
+
 &gpmc {
        ranges = <5 0 0x2c000000 0x01000000>;
 
        smsc1: ethernet@5,0 {
                compatible = "smsc,lan9221", "smsc,lan9115";
+               pinctrl-names = "default";
+               pinctrl-0 = <&smsc1_pins>;
                interrupt-parent = <&gpio6>;
                interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
                reg = <5 0 0xff>;
@@ -74,8 +91,6 @@
 };
 
 &i2c1 {
-       clock-frequency = <400000>;
-
        twl: twl@48 {
                reg = <0x48>;
                interrupts = <7>; /* SYS_NIRQ cascaded to intc */
 #include "twl4030.dtsi"
 #include "twl4030_omap3.dtsi"
 
-&i2c3 {
-       clock-frequency = <400000>;
+&mmc1 {
+       vmmc-supply = <&vmmc1>;
 };
 
 &twl_gpio {
        ti,use-leds;
+       /* pullups: BIT(0) */
+       ti,pullups = <0x000001>;
+};
+
+&hsusb1_phy {
+       reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>;
+};
+
+&hsusb2_phy {
+       reset-gpios = <&twl_gpio 7 GPIO_ACTIVE_LOW>;
+};
+
+&usb_otg_hs {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hsusb0_pins>;
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
 };
index 4665421bb7bc348fc549c1883a1bf8dbd5602327..bf5a515a324752d8fd36e96fb288b07d3b2f31e1 100644 (file)
        status = "disabled";
 };
 
-&mcbsp1 {
-       status = "disabled";
-};
-
-&mcbsp3 {
-       status = "disabled";
-};
-
-&mcbsp4 {
-       status = "disabled";
-};
-
-&mcbsp5 {
-       status = "disabled";
+&mcbsp2 {
+       status = "okay";
 };
 
 &gpmc {
index d3b253bbc8856a9ba0a2f1810c1860f875931462..f8ad125fa46f2658b2ff43f79b2097780ef8695d 100644 (file)
                        gpio-key,wakeup;
                };
        };
+
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "gta04";
+
+               ti,mcbsp = <&mcbsp2>;
+               ti,codec = <&twl_audio>;
+       };
 };
 
 &omap3_pmx_core {
                interrupts = <7>; /* SYS_NIRQ cascaded to intc */
                interrupt-parent = <&intc>;
        };
+
+       twl_audio: audio {
+               compatible = "ti,twl4030-audio";
+               codec {
+               };
+       };
 };
 
 #include "twl4030.dtsi"
                interrupts = <17 IRQ_TYPE_EDGE_RISING>;
        };
 
+       /* accelerometer */
+       bma180@41 {
+               compatible = "bosch,bma180";
+               reg = <0x41>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        /* leds */
        tca6507@45 {
                compatible = "ti,tca6507";
                        reg = <0x4>;
                };
        };
+
+       /* compass aka magnetometer */
+       hmc5843@1e {
+               compatible = "honeywell,hmc5843";
+               reg = <0x1e>;
+       };
+
+       /* touchscreen */
+       tsc2007@48 {
+               compatible = "ti,tsc2007";
+               reg = <0x48>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+               gpios = <&gpio6 0 GPIO_ACTIVE_LOW>;
+               ti,x-plate-ohms = <600>;
+       };
 };
 
 &i2c3 {
 };
 
 &mmc2 {
-       status = "disabled";
+       vmmc-supply = <&vaux4>;
+       bus-width = <4>;
+       ti,non-removable;
 };
 
 &mmc3 {
        pinctrl-0 = <&uart3_pins>;
 };
 
+&charger {
+       bb_uvolt = <3200000>;
+       bb_uamp = <150>;
+};
+
+&vaux4 {
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <3150000>;
+};
index c17009323520a87b62a2898bbfc65888f1d9bb2d..b97736d98a6427f087c11bd510909b1007f8c152 100644 (file)
 &mcbsp2 {
        pinctrl-names = "default";
        pinctrl-0 = <&mcbsp2_pins>;
+       status = "okay";
 };
 
 &mmc1 {
index f2779ac75872a4a44e2d03402fab7b6fe1a4b66b..7abd64f6ae21465c9ac74b22563f8f828a5d684b 100644 (file)
                reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; /* gpio_24 */
                vcc-supply = <&hsusb1_power>;
        };
+
+       tfp410: encoder@0 {
+               compatible = "ti,tfp410";
+               powerdown-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>; /* gpio_170 */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tfp410_in: endpoint@0 {
+                                       remote-endpoint = <&dpi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tfp410_out: endpoint@0 {
+                                       remote-endpoint = <&dvi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       dvi0: connector@0 {
+               compatible = "dvi-connector";
+               label = "dvi";
+
+               digital;
+
+               ddc-i2c-bus = <&i2c3>;
+
+               port {
+                       dvi_connector_in: endpoint {
+                               remote-endpoint = <&tfp410_out>;
+                       };
+               };
+       };
 };
 
 &omap3_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
                &tfp410_pins
-               &dss_pins
+               &dss_dpi_pins
        >;
 
-       tfp410_pins: tfp410_dvi_pins {
+       tfp410_pins: pinmux_tfp410_pins {
                pinctrl-single,pins = <
                        0x196 (PIN_OUTPUT | MUX_MODE4)   /* hdq_sio.gpio_170 */
                >;
        };
 
-       dss_pins: pinmux_dss_dvi_pins {
+       dss_dpi_pins: pinmux_dss_dpi_pins {
                pinctrl-single,pins = <
                        0x0a4 (PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
                        0x0a6 (PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
         /* Needed for DSS */
         regulator-name = "vdds_dsi";
 };
+
+&dss {
+       status = "ok";
+
+       port {
+               dpi_out: endpoint {
+                       remote-endpoint = <&tfp410_in>;
+                       data-lines = <24>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi
new file mode 100644 (file)
index 0000000..6369d9f
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2014 Christoph Fritz <chf.fritzc@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "omap36xx.dtsi"
+
+/ {
+       model = "INCOstartec LILLY-A83X module (DM3730)";
+       compatible = "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
+
+       chosen {
+                       bootargs = "console=ttyO0,115200n8 vt.global_cursor_default=0 consoleblank=0";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x8000000>;   /* 128 MB */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led1 {
+                       label = "lilly-a83x::led1";
+                       gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-on";
+               };
+
+       };
+
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "lilly-a83x";
+
+               ti,mcbsp = <&mcbsp2>;
+               ti,codec = <&twl_audio>;
+       };
+
+       reg_vcc3: vcc3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       hsusb1_phy: hsusb1_phy {
+               compatible = "usb-nop-xceiv";
+               vcc-supply = <&reg_vcc3>;
+       };
+};
+
+&omap3_pmx_wkup {
+       pinctrl-names = "default";
+
+       lan9221_pins: pinmux_lan9221_pins {
+               pinctrl-single,pins = <
+                       OMAP3_WKUP_IOPAD(0x2a5a, PIN_INPUT | MUX_MODE4)   /* reserved.gpio_129 */
+               >;
+       };
+
+       tsc2048_pins: pinmux_tsc2048_pins {
+               pinctrl-single,pins = <
+                       OMAP3_WKUP_IOPAD(0x2a16, PIN_INPUT_PULLUP | MUX_MODE4)   /* sys_boot6.gpio_8 */
+               >;
+       };
+
+       mmc1cd_pins: pinmux_mmc1cd_pins {
+               pinctrl-single,pins = <
+                       OMAP3_WKUP_IOPAD(0x2a56, PIN_INPUT | MUX_MODE4)   /* reserved.gpio_126 */
+               >;
+       };
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0)   /* uart1_tx.uart1_tx */
+                       OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0)   /* uart1_rts.uart1_rts */
+                       OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0)    /* uart1_cts.uart1_cts */
+                       OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0)    /* uart1_rx.uart1_rx */
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1)   /* mcbsp3_clkx.uart2_tx */
+                       OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE1)    /* mcbsp3_fsx.uart2_rx */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0)    /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)   /* uart3_tx_irtx.uart3_tx_irtx */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21ba ,PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_scl.i2c1_scl */
+                       OMAP3_CORE1_IOPAD(0x21bc ,PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c1_sda.i2c1_sda */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0)   /* i2c2_scl.i2c2_scl */
+                       OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0)   /* i2c2_sda.i2c2_sda */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)   /* i2c3_scl.i2c3_scl */
+                       OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)   /* i2c3_sda.i2c3_sda */
+               >;
+       };
+
+       hsusb1_pins: pinmux_hsusb1_pins {
+               pinctrl-single,pins = <
+
+                       /* GPIO 182 controls USB-Hub reset. But USB-Phy its
+                        * reset can't be controlled. So we clamp this GPIO to
+                        * high (PIN_OFF_OUTPUT_HIGH) to always enable USB-Hub.
+                        */
+
+                       OMAP3_CORE1_IOPAD(0x21de, PIN_OUTPUT_PULLUP | PIN_OFF_OUTPUT_HIGH | MUX_MODE4)   /* mcspi2_cs1.gpio_182 */
+               >;
+       };
+
+       hsusb_otg_pins: pinmux_hsusb_otg_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0)   /* hsusb0_clk.hsusb0_clk */
+                       OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0)  /* hsusb0_stp.hsusb0_stp */
+                       OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0)   /* hsusb0_dir.hsusb0_dir */
+                       OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0)   /* hsusb0_nxt.hsusb0_nxt */
+                       OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0)   /* hsusb0_data0.hsusb0_data0 */
+                       OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0)   /* hsusb0_data1.hsusb0_data1 */
+                       OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0)   /* hsusb0_data2.hsusb0_data2 */
+                       OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0)   /* hsusb0_data3.hsusb0_data3 */
+                       OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0)   /* hsusb0_data4.hsusb0_data4 */
+                       OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0)   /* hsusb0_data5.hsusb0_data5 */
+                       OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0)   /* hsusb0_data6.hsusb0_data6 */
+                       OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0)   /* hsusb0_data7.hsusb0_data7 */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_clk.sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_cmd.sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat0.sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat1.sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat2.sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc1_dat3.sdmmc1_dat3 */
+               >;
+       };
+
+       spi2_pins: pinmux_spi2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_clk.mcspi2_clk */
+                       OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_simo.mcspi2_simo */
+                       OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi2_somi.mcspi2_somi */
+                       OMAP3_CORE1_IOPAD(0x21dc, PIN_OUTPUT | MUX_MODE0)   /* mcspi2_cs0.mcspi2_cs0 */
+               >;
+       };
+};
+
+&omap3_pmx_core2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &hsusb1_2_pins
+       >;
+
+       hsusb1_2_pins: pinmux_hsusb1_2_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3)  /* etk_clk.hsusb1_stp */
+                       OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT | MUX_MODE3)   /* etk_ctl.hsusb1_clk */
+                       OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE3)   /* etk_d0.hsusb1_data0 */
+                       OMAP3630_CORE2_IOPAD(0x25de, PIN_INPUT | MUX_MODE3)   /* etk_d1.hsusb1_data1 */
+                       OMAP3630_CORE2_IOPAD(0x25e0, PIN_INPUT | MUX_MODE3)   /* etk_d2.hsusb1_data2 */
+                       OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT | MUX_MODE3)   /* etk_d3.hsusb1_data7 */
+                       OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE3)   /* etk_d4.hsusb1_data4 */
+                       OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT | MUX_MODE3)   /* etk_d5.hsusb1_data5 */
+                       OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT | MUX_MODE3)   /* etk_d6.hsusb1_data6 */
+                       OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE3)   /* etk_d7.hsusb1_data3 */
+                       OMAP3630_CORE2_IOPAD(0x25ec, PIN_INPUT | MUX_MODE3)   /* etk_d8.hsusb1_dir */
+                       OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE3)   /* etk_d9.hsusb1_nxt */
+               >;
+       };
+
+       gpio1_pins: pinmux_gpio1_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25fa, PIN_OUTPUT_PULLDOWN | MUX_MODE4)   /* etk_d15.gpio_29 */
+               >;
+       };
+
+};
+
+&gpio1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpio1_pins>;
+};
+
+&gpio6 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hsusb1_pins>;
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>;   /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
+                       };
+               };
+       };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&twl {
+       vmmc1: regulator-vmmc1 {
+               regulator-always-on;
+       };
+
+       vdd1: regulator-vdd1 {
+               regulator-always-on;
+       };
+
+       vdd2: regulator-vdd2 {
+               regulator-always-on;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <2600000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+};
+
+&i2c3 {
+       clock-frequency = <2600000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+               gpiom1: gpio@20 {
+                       compatible = "mcp,mcp23017";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       reg = <0x20>;
+               };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
+&uart4 {
+       status = "disabled";
+};
+
+&mmc1 {
+       cd-gpios = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>;
+       cd-inverted;
+       vmmc-supply = <&vmmc1>;
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins &mmc1cd_pins>;
+       cap-sdio-irq;
+       cap-sd-highspeed;
+       cap-mmc-highspeed;
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&mcspi2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi2_pins>;
+
+       tsc2046@0 {
+               reg = <0>;   /* CS0 */
+               compatible = "ti,tsc2046";
+               interrupt-parent = <&gpio1>;
+               interrupts = <8 0>;   /* boot6 / gpio_8 */
+               spi-max-frequency = <1000000>;
+               pendown-gpio = <&gpio1 8 0>;
+               vcc-supply = <&reg_vcc3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tsc2048_pins>;
+
+               ti,x-min = <300>;
+               ti,x-max = <3000>;
+               ti,y-min = <600>;
+               ti,y-max = <3600>;
+               ti,x-plate-ohms = <80>;
+               ti,pressure-max = <255>;
+               ti,swap-xy;
+
+               linux,wakeup;
+       };
+};
+
+&usbhsehci {
+       phys = <&hsusb1_phy>;
+};
+
+&usbhshost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hsusb1_2_pins>;
+       num-ports = <2>;
+       port1-mode = "ehci-phy";
+};
+
+&usb_otg_hs {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hsusb_otg_pins>;
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
+
+&gpmc {
+       ranges = <0 0 0x30000000 0x1000000>,
+               <7 0 0x15000000 0x01000000>;
+
+       nand@0,0 {
+               reg = <0 0 0x1000000>;
+               nand-bus-width = <16>;
+               ti,nand-ecc-opt = "bch8";
+               /* no elm on omap3 */
+
+               gpmc,mux-add-data = <0>;
+               gpmc,device-nand;
+               gpmc,device-width = <2>;
+               gpmc,wait-pin = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,burst-length= <4>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <100>;
+               gpmc,cs-wr-off-ns = <100>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <100>;
+               gpmc,adv-wr-off-ns = <100>;
+               gpmc,oe-on-ns = <5>;
+               gpmc,oe-off-ns = <75>;
+               gpmc,we-on-ns = <5>;
+               gpmc,we-off-ns = <75>;
+               gpmc,rd-cycle-ns = <100>;
+               gpmc,wr-cycle-ns = <100>;
+               gpmc,access-ns = <60>;
+               gpmc,page-burst-access-ns = <5>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-delay-ns = <50>;
+               gpmc,wr-data-mux-bus-ns = <75>;
+               gpmc,wr-access-ns = <155>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       label = "MLO";
+                       reg = <0 0x80000>;
+               };
+
+               partition@0x80000 {
+                       label = "u-boot";
+                       reg = <0x80000 0x1e0000>;
+               };
+
+               partition@0x260000 {
+                       label = "u-boot-environment";
+                       reg = <0x260000 0x20000>;
+               };
+
+               partition@0x280000 {
+                       label = "kernel";
+                       reg = <0x280000 0x500000>;
+               };
+
+               partition@0x780000 {
+                       label = "filesystem";
+                       reg = <0x780000 0xf880000>;
+               };
+       };
+
+       ethernet@7,0 {
+               compatible = "smsc,lan9221", "smsc,lan9115";
+               bank-width = <2>;
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <10>;
+               gpmc,cs-rd-off-ns = <60>;
+               gpmc,cs-wr-off-ns = <60>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <10>;
+               gpmc,adv-wr-off-ns = <10>;
+               gpmc,oe-on-ns = <10>;
+               gpmc,oe-off-ns = <60>;
+               gpmc,we-on-ns = <10>;
+               gpmc,we-off-ns = <60>;
+               gpmc,rd-cycle-ns = <100>;
+               gpmc,wr-cycle-ns = <100>;
+               gpmc,access-ns = <50>;
+               gpmc,page-burst-access-ns = <5>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <75>;
+               gpmc,wr-data-mux-bus-ns = <15>;
+               gpmc,wr-access-ns = <75>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-diffcsen;
+               vddvario-supply = <&reg_vcc3>;
+               vdd33a-supply = <&reg_vcc3>;
+               reg-io-width = <4>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <1 0x2>;
+               reg = <7 0 0xff>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&lan9221_pins>;
+               phy-mode = "mii";
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-lilly-dbb056.dts b/arch/arm/boot/dts/omap3-lilly-dbb056.dts
new file mode 100644 (file)
index 0000000..834f7c6
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 Christoph Fritz <chf.fritzc@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+/dts-v1/;
+
+#include "omap3-lilly-a83x.dtsi"
+
+/ {
+       model = "INCOstartec LILLY-DBB056 (DM3730)";
+       compatible = "incostartec,omap3-lilly-dbb056", "incostartec,omap3-lilly-a83x", "ti,omap36xx", "ti,omap3";
+};
+
+&twl {
+       vaux2: regulator-vaux2 {
+               compatible = "ti,twl4030-vaux2";
+               regulator-min-microvolt = <2800000>;
+               regulator-max-microvolt = <2800000>;
+               regulator-always-on;
+       };
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <&lcd_pins>;
+
+       lan9117_pins: pinmux_lan9117_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE4)   /* cam_fld.gpio_98 */
+               >;
+       };
+
+       gpio4_pins: pinmux_gpio4_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x212e, PIN_INPUT | MUX_MODE4)   /* cam_xclkb.gpio_111 -> sja1000 IRQ */
+               >;
+       };
+
+       gpio5_pins: pinmux_gpio5_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x218c, PIN_OUTPUT | PIN_OFF_OUTPUT_HIGH | MUX_MODE4)   /* mcbsp1_clk.gpio_156 -> enable DSS */
+               >;
+       };
+
+       lcd_pins: pinmux_lcd_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 */
+                       OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0)   /* dss_acbias.dss_acbias */
+                       OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0)   /* dss_data0.dss_data0 */
+                       OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0)   /* dss_data1.dss_data1 */
+                       OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0)   /* dss_data2.dss_data2 */
+                       OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0)   /* dss_data3.dss_data3 */
+                       OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0)   /* dss_data4.dss_data4 */
+                       OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0)   /* dss_data5.dss_data5 */
+                       OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0)   /* dss_data6.dss_data6 */
+                       OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0)   /* dss_data7.dss_data7 */
+                       OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0)   /* dss_data8.dss_data8 */
+                       OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0)   /* dss_data9.dss_data9 */
+                       OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0)   /* dss_data10.dss_data10 */
+                       OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0)   /* dss_data11.dss_data11 */
+                       OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0)   /* dss_data12.dss_data12 */
+                       OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0)   /* dss_data13.dss_data13 */
+                       OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0)   /* dss_data14.dss_data14 */
+                       OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)   /* dss_data15.dss_data15 */
+                       OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0)   /* dss_data16.dss_data16 */
+                       OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0)   /* dss_data17.dss_data17 */
+               >;
+       };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0)   /* sdmmc2_dat3.sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1)   /* sdmmc2_dat4.sdmmc2_dir_dat0 */
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1)   /* sdmmc2_dat5.sdmmc2_dir_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1)   /* sdmmc2_dat6.sdmmc2_dir_cmd */
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1)    /* sdmmc2_dat7.sdmmc2_clkin */
+                       OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLUP | MUX_MODE4)   /* uart3_cts_rctx.gpio_163 -> wp */
+                       OMAP3_CORE1_IOPAD(0x219c, PIN_INPUT_PULLUP | MUX_MODE4)   /* uart3_rts_sd.gpio_164 -> cd */
+               >;
+       };
+
+       spi1_pins: pinmux_spi1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0)   /* mcspi1_clk.mcspi1_clk */
+                       OMAP3_CORE1_IOPAD(0x21ca, PIN_INPUT | MUX_MODE0)   /* mcspi1_simo.mcspi1_simo */
+                       OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT | MUX_MODE0)   /* mcspi1_somi.mcspi1_somi */
+                       OMAP3_CORE1_IOPAD(0x21ce, PIN_INPUT_PULLDOWN | MUX_MODE0)   /* mcspi1_cs0.mcspi1_cs0 */
+               >;
+       };
+};
+
+&gpio4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpio4_pins>;
+};
+
+&gpio5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpio5_pins>;
+};
+
+&mmc2 {
+       status = "okay";
+       bus-width = <4>;
+       vmmc-supply = <&vmmc1>;
+       cd-gpios = <&gpio6 4 0>;   /* gpio_164 */
+       wp-gpios = <&gpio6 3 0>;   /* gpio_163 */
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       ti,dual-volt;
+};
+
+&mcspi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi1_pins>;
+};
+
+&gpmc {
+       ranges = <0 0 0x30000000 0x1000000>,   /* nand assigned by COM a83x */
+               <4 0 0x20000000 0x01000000>,
+               <7 0 0x15000000 0x01000000>;   /* eth assigend by COM a83x */
+
+       ethernet@4,0 {
+               compatible = "smsc,lan9117", "smsc,lan9115";
+               bank-width = <2>;
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <10>;
+               gpmc,cs-rd-off-ns = <65>;
+               gpmc,cs-wr-off-ns = <65>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <10>;
+               gpmc,adv-wr-off-ns = <10>;
+               gpmc,oe-on-ns = <10>;
+               gpmc,oe-off-ns = <65>;
+               gpmc,we-on-ns = <10>;
+               gpmc,we-off-ns = <65>;
+               gpmc,rd-cycle-ns = <100>;
+               gpmc,wr-cycle-ns = <100>;
+               gpmc,access-ns = <60>;
+               gpmc,page-burst-access-ns = <5>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <75>;
+               gpmc,wr-data-mux-bus-ns = <15>;
+               gpmc,wr-access-ns = <75>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-diffcsen;
+               vddvario-supply = <&reg_vcc3>;
+               vdd33a-supply = <&reg_vcc3>;
+               reg-io-width = <4>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <2 0x2>;
+               reg = <4 0 0xff>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&lan9117_pins>;
+               phy-mode = "mii";
+               smsc,force-internal-phy;
+       };
+};
index 0bf40c90faba626c88b539965a1f928aa09bf313..1a57b61f5e24490ea198f327ce099c50fc0d141c 100644 (file)
                };
        };
 
+       isp1704: isp1704 {
+               compatible = "nxp,isp1704";
+               nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+               usb-phy = <&usb2_phy>;
+       };
+
+       tv: connector {
+               compatible = "composite-connector";
+               label = "tv";
+
+               port {
+                       tv_connector_in: endpoint {
+                               remote-endpoint = <&venc_out>;
+                       };
+               };
+       };
 };
 
 &omap3_pmx_core {
                >;
        };
 
-       display_pins: pinmux_display_pins {
+       acx565akm_pins: pinmux_acx565akm_pins {
                pinctrl-single,pins = <
                        0x0d4 (PIN_OUTPUT | MUX_MODE4)          /* RX51_LCD_RESET_GPIO */
                >;
        };
+
+       dss_sdi_pins: pinmux_dss_sdi_pins {
+               pinctrl-single,pins = <
+                       0x0c0 (PIN_OUTPUT | MUX_MODE1)   /* dss_data10.sdi_dat1n */
+                       0x0c2 (PIN_OUTPUT | MUX_MODE1)   /* dss_data11.sdi_dat1p */
+                       0x0c4 (PIN_OUTPUT | MUX_MODE1)   /* dss_data12.sdi_dat2n */
+                       0x0c6 (PIN_OUTPUT | MUX_MODE1)   /* dss_data13.sdi_dat2p */
+
+                       0x0d8 (PIN_OUTPUT | MUX_MODE1)   /* dss_data22.sdi_clkp */
+                       0x0da (PIN_OUTPUT | MUX_MODE1)   /* dss_data23.sdi_clkn */
+               >;
+       };
 };
 
 &i2c1 {
        };
 };
 
+&twl_keypad {
+       linux,keymap = < 0x00000010 /* KEY_Q */
+                        0x00010018 /* KEY_O */
+                        0x00020019 /* KEY_P */
+                        0x00030033 /* KEY_COMMA */
+                        0x0004000e /* KEY_BACKSPACE */
+                        0x0006001e /* KEY_A */
+                        0x0007001f /* KEY_S */
+
+                        0x01000011 /* KEY_W */
+                        0x01010020 /* KEY_D */
+                        0x01020021 /* KEY_F */
+                        0x01030022 /* KEY_G */
+                        0x01040023 /* KEY_H */
+                        0x01050024 /* KEY_J */
+                        0x01060025 /* KEY_K */
+                        0x01070026 /* KEY_L */
+
+                        0x02000012 /* KEY_E */
+                        0x02010034 /* KEY_DOT */
+                        0x02020067 /* KEY_UP */
+                        0x0203001c /* KEY_ENTER */
+                        0x0205002c /* KEY_Z */
+                        0x0206002d /* KEY_X */
+                        0x0207002e /* KEY_C */
+                        0x02080043 /* KEY_F9 */
+
+                        0x03000013 /* KEY_R */
+                        0x0301002f /* KEY_V */
+                        0x03020030 /* KEY_B */
+                        0x03030031 /* KEY_N */
+                        0x03040032 /* KEY_M */
+                        0x03050039 /* KEY_SPACE */
+                        0x03060039 /* KEY_SPACE */
+                        0x03070069 /* KEY_LEFT */
+
+                        0x04000014 /* KEY_T */
+                        0x0401006c /* KEY_DOWN */
+                        0x0402006a /* KEY_RIGHT */
+                        0x0404001d /* KEY_LEFTCTRL */
+                        0x04050064 /* KEY_RIGHTALT */
+                        0x0406002a /* KEY_LEFTSHIFT */
+                        0x04080044 /* KEY_F10 */
+
+                        0x05000015 /* KEY_Y */
+                        0x05080057 /* KEY_F11 */
+
+                        0x06000016 /* KEY_U */
+
+                        0x07000017 /* KEY_I */
+                        0x07010041 /* KEY_F7 */
+                        0x07020042 /* KEY_F8 */
+                        >;
+};
+
 &twl_gpio {
        ti,pullups      = <0x0>;
        ti,pulldowns    = <0x03ff3f>; /* BIT(0..5) | BIT(8..17) */
                DVDD-supply = <&vio>;
        };
 
+       tsl2563: tsl2563@29 {
+               compatible = "amstaos,tsl2563";
+               reg = <0x29>;
+
+               amstaos,cover-comp-gain = <16>;
+       };
+
        lp5523: lp5523@32 {
                compatible = "national,lp5523";
                reg = <0x32>;
                compatible = "ti,bq27200";
                reg = <0x55>;
        };
+
+       tpa6130a2: tpa6130a2@60 {
+               compatible = "ti,tpa6130a2";
+               reg = <0x60>;
+
+               Vdd-supply = <&vmmc2>;
+
+               power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>; /* 98 */
+       };
+
+       bq24150a: bq24150a@6b {
+               compatible = "ti,bq24150a";
+               reg = <0x6b>;
+
+               ti,current-limit = <100>;
+               ti,weak-battery-voltage = <3400>;
+               ti,battery-regulation-voltage = <4200>;
+               ti,charge-current = <650>;
+               ti,termination-current = <100>;
+               ti,resistor-sense = <68>;
+
+               ti,usb-charger-detection = <&isp1704>;
+       };
 };
 
 &i2c3 {
                spi-max-frequency = <6000000>;
                reg = <0>;
        };
-       mipid@2 {
-               compatible = "acx565akm";
+
+       acx565akm@2 {
+               compatible = "sony,acx565akm";
                spi-max-frequency = <6000000>;
                reg = <2>;
 
                pinctrl-names = "default";
-               pinctrl-0 = <&display_pins>;
+               pinctrl-0 = <&acx565akm_pins>;
+
+               label = "lcd";
+               reset-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* 90 */
+
+               port {
+                       lcd_in: endpoint {
+                               remote-endpoint = <&sdi_out>;
+                       };
+               };
        };
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&uart3_pins>;
 };
+
+&dss {
+       status = "ok";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&dss_sdi_pins>;
+
+       vdds_sdi-supply = <&vaux1>;
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@1 {
+                       reg = <1>;
+
+                       sdi_out: endpoint {
+                               remote-endpoint = <&lcd_in>;
+                               datapairs = <2>;
+                       };
+               };
+       };
+};
+
+&venc {
+       status = "ok";
+
+       vdda-supply = <&vdac>;
+
+       port {
+               venc_out: endpoint {
+                       remote-endpoint = <&tv_connector_in>;
+                       ti,channels = <1>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi b/arch/arm/boot/dts/omap3-overo-alto35-common.dtsi
new file mode 100644 (file)
index 0000000..19d6486
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Alto35 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins>;
+               gpio148 {
+                       label = "overo:red:gpio148";
+                       gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>;           /* gpio 148 */
+               };
+               gpio150 {
+                       label = "overo:yellow:gpio150";
+                       gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>;           /* gpio 150 */
+               };
+               gpio151 {
+                       label = "overo:blue:gpio151";
+                       gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>;           /* gpio 151 */
+               };
+               gpio170 {
+                       label = "overo:green:gpio170";
+                       gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>;           /* gpio 170 */
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&button_pins>;
+               button0@10 {
+                       label = "button0";
+                       linux,code = <BTN_0>;
+                       gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;            /* gpio_10 */
+                       gpio-key,wakeup;
+               };
+       };
+};
+
+&omap3_pmx_core {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE4)       /* uart1_tx.gpio_148 */
+                       OMAP3_CORE1_IOPAD(0x2180, PIN_OUTPUT | MUX_MODE4)       /* uart1_cts.gpio_150 */
+                       OMAP3_CORE1_IOPAD(0x2182, PIN_OUTPUT | MUX_MODE4)       /* uart1_rx.gpio_151 */
+                       OMAP3_CORE1_IOPAD(0x21c6, PIN_OUTPUT | MUX_MODE4)       /* hdq_sio.gpio_170 */
+               >;
+       };
+};
+
+&omap3_pmx_wkup {
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3_WKUP_IOPAD(0x2a18, PIN_INPUT | MUX_MODE4)         /* sys_clkout1.gpio_10 */
+               >;
+       };
+};
+
+&usbhshost {
+       status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-alto35.dts b/arch/arm/boot/dts/omap3-overo-alto35.dts
new file mode 100644 (file)
index 0000000..a3249eb
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Alto35 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-alto35-common.dtsi"
+
+/ {
+       model = "OMAP35xx Gumstix Overo on Alto35";
+       compatible = "gumstix,omap3-overo-alto35", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi
new file mode 100644 (file)
index 0000000..d36bf02
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can 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 Gumstix Overo must be combined with an expansion board.
+ */
+
+/ {
+       pwmleds {
+               compatible = "pwm-leds";
+
+               overo {
+                       label = "overo:blue:COM";
+                       pwms = <&twl_pwmled 1 7812500>;
+                       max-brightness = <127>;
+                       linux,default-trigger = "mmc0";
+               };
+       };
+
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "overo";
+
+               ti,mcbsp = <&mcbsp2>;
+               ti,codec = <&twl_audio>;
+       };
+
+       /* HS USB Port 2 Power */
+       hsusb2_power: hsusb2_power_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb2_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio6 8 0>;                            /* gpio_168: vbus enable */
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+
+       /* HS USB Host PHY on PORT 2 */
+       hsusb2_phy: hsusb2_phy {
+               compatible = "usb-nop-xceiv";
+               reset-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;      /* gpio_183 */
+               vcc-supply = <&hsusb2_power>;
+       };
+
+       /* Regulator to trigger the nPoweron signal of the Wifi module */
+       w3cbw003c_npoweron: regulator-w3cbw003c-npoweron {
+               compatible = "regulator-fixed";
+               regulator-name = "regulator-w3cbw003c-npoweron";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 22 GPIO_ACTIVE_HIGH>;            /* gpio_54: nPoweron */
+               enable-active-high;
+       };
+
+       /* Regulator to trigger the nReset signal of the Wifi module */
+       w3cbw003c_wifi_nreset: regulator-w3cbw003c-wifi-nreset {
+               pinctrl-names = "default";
+               pinctrl-0 = <&w3cbw003c_pins &w3cbw003c_2_pins>;
+               compatible = "regulator-fixed";
+               regulator-name = "regulator-w3cbw003c-wifi-nreset";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 16 GPIO_ACTIVE_HIGH>;            /* gpio_16: WiFi nReset */
+               startup-delay-us = <10000>;
+       };
+
+       /* Regulator to trigger the nReset signal of the Bluetooth module */
+       w3cbw003c_bt_nreset: regulator-w3cbw003c-bt-nreset {
+               compatible = "regulator-fixed";
+               regulator-name = "regulator-w3cbw003c-bt-nreset";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>;             /* gpio_164: BT nReset */
+               startup-delay-us = <10000>;
+       };
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &hsusb2_pins
+       >;
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x216c, PIN_INPUT | MUX_MODE1)        /* mcbsp3_dx.uart2_cts */
+                       OMAP3_CORE1_IOPAD(0x216e, PIN_OUTPUT | MUX_MODE1)       /* mcbsp3_dr.uart2_rts */
+                       OMAP3_CORE1_IOPAD(0x2170, PIN_OUTPUT | MUX_MODE1)       /* mcbsp3_clk.uart2_tx */
+                       OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE1)        /* mcbsp3_fsx.uart2_rx */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0)                /* i2c1_scl.i2c1_scl */
+                       OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)                /* i2c1_sda.i2c1_sda */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_clk.sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_cmd.sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat0.sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat1.sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat2.sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat3.sdmmc1_dat3 */
+               >;
+       };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat3.sdmmc2_dat3 */
+               >;
+       };
+
+       /* WiFi/BT combo */
+       w3cbw003c_pins: pinmux_w3cbw003c_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20b4, PIN_OUTPUT | MUX_MODE4)               /* gpmc_ncs3.gpio_54 */
+                       OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE4)               /* uart3_rts_sd.gpio_164 */
+               >;
+       };
+
+       hsusb2_pins: pinmux_hsusb2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi1_cs3.hsusb2_data2 */
+                       OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi2_clk.hsusb2_data7 */
+                       OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi2_simo.hsusb2_data4 */
+                       OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi2_somi.hsusb2_data5 */
+                       OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi2_cs0.hsusb2_data6 */
+                       OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3)       /* mcspi2_cs1.hsusb2_data3 */
+                       OMAP3_CORE1_IOPAD(0x21be, PIN_OUTPUT | MUX_MODE4)               /* i2c2_scl.gpio_168 */
+                       OMAP3_CORE1_IOPAD(0x21c0, PIN_OUTPUT | MUX_MODE4)               /* i2c2_sda.gpio_183 */
+               >;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
+                       };
+               };
+       };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+/* i2c2 pins are used for gpio */
+&i2c2 {
+       status = "disabled";
+};
+
+/* on board microSD slot */
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&vmmc1>;
+       bus-width = <4>;
+};
+
+/* optional on board WiFi */
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&w3cbw003c_npoweron>;
+       vqmmc-supply = <&w3cbw003c_bt_nreset>;
+       vmmc_aux-supply = <&w3cbw003c_wifi_nreset>;
+       bus-width = <4>;
+       cap-sdio-irq;
+       non-removable;
+};
+
+&twl_gpio {
+       ti,use-leds;
+};
+
+&usb_otg_hs {
+       interface-type = <0>;
+       usb-phy = <&usb2_phy>;
+       phys = <&usb2_phy>;
+       phy-names = "usb2-phy";
+       mode = <3>;
+       power = <50>;
+};
+
+&usbhshost {
+       port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <0 &hsusb2_phy>;
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
new file mode 100644 (file)
index 0000000..19de6ff
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Chestnut43 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins>;
+               heartbeat {
+                       label = "overo:red:gpio21";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;            /* gpio_21 */
+                       linux,default-trigger = "heartbeat";
+               };
+               gpio22 {
+                       label = "overo:blue:gpio22";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;            /* gpio_22 */
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&button_pins>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               button0@23 {
+                       label = "button0";
+                       linux,code = <BTN_0>;
+                       gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
+                       gpio-key,wakeup;
+               };
+               button1@14 {
+                       label = "button1";
+                       linux,code = <BTN_1>;
+                       gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
+                       gpio-key,wakeup;
+               };
+       };
+};
+
+#include "omap-gpmc-smsc9221.dtsi"
+
+&gpmc {
+       ranges = <5 0 0x2c000000 0x1000000>;    /* CS5 */
+
+       ethernet@gpmc {
+               reg = <5 0 0xff>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <16 IRQ_TYPE_LEVEL_LOW>;   /* GPIO 176 */
+       };
+};
+
+&lis33de {
+       status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43.dts b/arch/arm/boot/dts/omap3-overo-chestnut43.dts
new file mode 100644 (file)
index 0000000..fe0824a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Chestnut43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-chestnut43-common.dtsi"
+
+/ {
+       model = "OMAP35xx Gumstix Overo on Chestnut43";
+       compatible = "gumstix,omap3-overo-chestnut43", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+                       OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4)    /* etk_d8.gpio_22 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4)     /* etk_d9.gpio_23 */
+                       OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4)     /* etk_d0.gpio_14 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi b/arch/arm/boot/dts/omap3-overo-common-peripherals.dtsi
new file mode 100644 (file)
index 0000000..5831bcc
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Peripherals common to all Gumstix Overo boards (Tobi, Summit, Palo43,...)
+ */
+
+/ {
+       lis33_3v3: lis33-3v3-reg {
+               compatible = "regulator-fixed";
+               regulator-name = "lis33-3v3-reg";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       lis33_1v8: lis33-1v8-reg {
+               compatible = "regulator-fixed";
+               regulator-name = "lis33-1v8-reg";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+};
+
+&omap3_pmx_core {
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0)        /* i2c3_scl.i2c3_scl */
+                       OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0)        /* i2c3_sda.i2c3_sda */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+                       OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0)               /* uart3_tx_irtx.uart3_tx_irtx */
+               >;
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+       clock-frequency = <100000>;
+
+       /* optional 1K EEPROM with revision information */
+       eeprom@51 {
+               compatible = "atmel,24c01";
+               reg = <0x51>;
+               pagesize = <8>;
+       };
+
+       lis33de: lis33de@1d {
+               compatible = "st,lis33de", "st,lis3lv02d";
+               reg = <0x1d>;
+               Vdd-supply = <&lis33_1v8>;
+               Vdd_IO-supply = <&lis33_3v3>;
+
+               st,click-single-x;
+               st,click-single-y;
+               st,click-single-z;
+               st,click-thresh-x = <10>;
+               st,click-thresh-y = <10>;
+               st,click-thresh-z = <10>;
+               st,irq1-click;
+               st,irq2-click;
+               st,wakeup-x-lo;
+               st,wakeup-x-hi;
+               st,wakeup-y-lo;
+               st,wakeup-y-hi;
+               st,wakeup-z-lo;
+               st,wakeup-z-hi;
+               st,min-limit-x = <120>;
+               st,min-limit-y = <120>;
+               st,min-limit-z = <140>;
+               st,max-limit-x = <550>;
+               st,max-limit-y = <550>;
+               st,max-limit-z = <750>;
+       };
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi b/arch/arm/boot/dts/omap3-overo-gallop43-common.dtsi
new file mode 100644 (file)
index 0000000..5e848c2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Gallop43 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins>;
+               heartbeat {
+                       label = "overo:red:gpio21";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;            /* gpio_21 */
+                       linux,default-trigger = "heartbeat";
+               };
+               gpio22 {
+                       label = "overo:blue:gpio22";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;            /* gpio_22 */
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&button_pins>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               button0@23 {
+                       label = "button0";
+                       linux,code = <BTN_0>;
+                       gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
+                       gpio-key,wakeup;
+               };
+               button1@14 {
+                       label = "button1";
+                       linux,code = <BTN_1>;
+                       gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
+                       gpio-key,wakeup;
+               };
+       };
+};
+
+&usbhshost {
+       status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-gallop43.dts b/arch/arm/boot/dts/omap3-overo-gallop43.dts
new file mode 100644 (file)
index 0000000..241f5c1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Gallop43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-gallop43-common.dtsi"
+
+/ {
+       model = "OMAP35xx Gumstix Overo on Gallop43";
+       compatible = "gumstix,omap3-overo-gallop43", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+                       OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4)    /* etk_d8.gpio_22 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4)     /* etk_d9.gpio_23 */
+                       OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4)     /* etk_d0.gpio_14 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi b/arch/arm/boot/dts/omap3-overo-palo43-common.dtsi
new file mode 100644 (file)
index 0000000..abea232
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Palo43 expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins>;
+               heartbeat {
+                       label = "overo:red:gpio21";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;            /* gpio_21 */
+                       linux,default-trigger = "heartbeat";
+               };
+               gpio22 {
+                       label = "overo:blue:gpio22";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;            /* gpio_22 */
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&button_pins>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               button0@23 {
+                       label = "button0";
+                       linux,code = <BTN_0>;
+                       gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;            /* gpio_23 */
+                       gpio-key,wakeup;
+               };
+               button1@14 {
+                       label = "button1";
+                       linux,code = <BTN_1>;
+                       gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;            /* gpio_14 */
+                       gpio-key,wakeup;
+               };
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-palo43.dts b/arch/arm/boot/dts/omap3-overo-palo43.dts
new file mode 100644 (file)
index 0000000..cedb103
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Palo43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-palo43-common.dtsi"
+
+/ {
+       model = "OMAP35xx Gumstix Overo on Palo43";
+       compatible = "gumstix,omap3-overo-palo43", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+                       OMAP3430_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4)    /* etk_d8.gpio_22 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4)     /* etk_d9.gpio_23 */
+                       OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4)     /* etk_d0.gpio_14 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-alto35.dts b/arch/arm/boot/dts/omap3-overo-storm-alto35.dts
new file mode 100644 (file)
index 0000000..e9cae52
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Alto35 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-alto35-common.dtsi"
+
+/ {
+       model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Alto35";
+       compatible = "gumstix,omap3-overo-alto35", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
diff --git a/arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts b/arch/arm/boot/dts/omap3-overo-storm-chestnut43.dts
new file mode 100644 (file)
index 0000000..7d82fdf
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Chestnut43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-chestnut43-common.dtsi"
+
+/ {
+       model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Chestnut43";
+       compatible = "gumstix,omap3-overo-chestnut43", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+                       OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4)    /* etk_d8.gpio_22 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4)     /* etk_d9.gpio_23 */
+                       OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4)     /* etk_d0.gpio_14 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-gallop43.dts b/arch/arm/boot/dts/omap3-overo-storm-gallop43.dts
new file mode 100644 (file)
index 0000000..a1b57e0
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Gallop43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-gallop43-common.dtsi"
+
+/ {
+       model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Gallop43";
+       compatible = "gumstix,omap3-overo-gallop43", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+                       OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4)    /* etk_d8.gpio_22 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4)     /* etk_d9.gpio_23 */
+                       OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4)     /* etk_d0.gpio_14 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-palo43.dts b/arch/arm/boot/dts/omap3-overo-storm-palo43.dts
new file mode 100644 (file)
index 0000000..b585d8f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Palo43 expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-palo43-common.dtsi"
+
+/ {
+       model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Palo43";
+       compatible = "gumstix,omap3-overo-palo43", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+                       OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4)    /* etk_d8.gpio_22 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE4)     /* etk_d9.gpio_23 */
+                       OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE4)     /* etk_d0.gpio_14 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-storm-summit.dts b/arch/arm/boot/dts/omap3-overo-storm-summit.dts
new file mode 100644 (file)
index 0000000..a0d7fd8
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Summit expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo-storm.dtsi"
+#include "omap3-overo-summit-common.dtsi"
+
+/ {
+       model = "OMAP36xx/AM37xx/DM37xx Gumstix Overo on Summit";
+       compatible = "gumstix,omap3-overo-summit", "gumstix,omap3-overo", "ti,omap36xx", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+               >;
+       };
+};
+
index 966b5c9cd96a458869ed989a4f4c22d266f61fce..879383acad871634919ea5f58216dd77aef1db41 100644 (file)
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-#include "omap36xx.dtsi"
+#include "omap3-overo-storm.dtsi"
 #include "omap3-overo-tobi-common.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/omap3-overo-storm.dtsi b/arch/arm/boot/dts/omap3-overo-storm.dtsi
new file mode 100644 (file)
index 0000000..6cb418b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can 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 "omap36xx.dtsi"
+#include "omap3-overo-base.dtsi"
+
+&omap3_pmx_core2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &hsusb2_2_pins
+       >;
+
+       hsusb2_2_pins: pinmux_hsusb2_2_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3)            /* etk_d10.hsusb2_clk */
+                       OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3)            /* etk_d11.hsusb2_stp */
+                       OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d12.hsusb2_dir */
+                       OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d13.hsusb2_nxt */
+                       OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d14.hsusb2_data0 */
+                       OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d15.hsusb2_data1 */
+               >;
+       };
+
+       w3cbw003c_2_pins: pinmux_w3cbw003c_2_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4)            /* etk_d2.gpio_16 */
+               >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-summit-common.dtsi b/arch/arm/boot/dts/omap3-overo-summit-common.dtsi
new file mode 100644 (file)
index 0000000..999d1cd
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Summit expansion board is manufactured by Gumstix Inc.
+ */
+
+#include "omap3-overo-common-peripherals.dtsi"
+
+/ {
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins>;
+               heartbeat {
+                       label = "overo:red:gpio21";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;            /* gpio_21 */
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&lis33de {
+       status = "disabled";
+};
+
diff --git a/arch/arm/boot/dts/omap3-overo-summit.dts b/arch/arm/boot/dts/omap3-overo-summit.dts
new file mode 100644 (file)
index 0000000..6976560
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Summit expansion board is manufactured by Gumstix Inc.
+ */
+
+/dts-v1/;
+
+#include "omap3-overo.dtsi"
+#include "omap3-overo-summit-common.dtsi"
+
+/ {
+       model = "OMAP35xx Gumstix Overo on Summit";
+       compatible = "gumstix,omap3-overo-summit", "gumstix,omap3-overo", "ti,omap3430", "ti,omap3";
+};
+
+&omap3_pmx_core2 {
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25ea, PIN_OUTPUT | MUX_MODE4)    /* etk_d7.gpio_21 */
+               >;
+       };
+};
+
index 4edc013a91c1717f3ae0757e3c2c23ce80bf383e..13df50b394423c11a67319e15374f9edc7a86259 100644 (file)
@@ -10,7 +10,7 @@
  * Tobi expansion board is manufactured by Gumstix Inc.
  */
 
-#include "omap3-overo.dtsi"
+#include "omap3-overo-common-peripherals.dtsi"
 
 / {
        leds {
                        linux,default-trigger = "heartbeat";
                };
        };
-
-       vddvario: regulator-vddvario {
-                 compatible = "regulator-fixed";
-                 regulator-name = "vddvario";
-                 regulator-always-on;
-       };
-
-       vdd33a: regulator-vdd33a {
-               compatible = "regulator-fixed";
-               regulator-name = "vdd33a";
-               regulator-always-on;
-       };
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &gpmc {
        ranges = <5 0 0x2c000000 0x1000000>;    /* CS5 */
 
-       ethernet@5,0 {
-               compatible = "smsc,lan9221", "smsc,lan9115";
+       ethernet@gpmc {
                reg = <5 0 0xff>;
-               bank-width = <2>;
-
-               gpmc,mux-add-data;
-               gpmc,cs-on-ns = <0>;
-               gpmc,cs-rd-off-ns = <42>;
-               gpmc,cs-wr-off-ns = <36>;
-               gpmc,adv-on-ns = <6>;
-               gpmc,adv-rd-off-ns = <12>;
-               gpmc,adv-wr-off-ns = <12>;
-               gpmc,oe-on-ns = <0>;
-               gpmc,oe-off-ns = <42>;
-               gpmc,we-on-ns = <0>;
-               gpmc,we-off-ns = <36>;
-               gpmc,rd-cycle-ns = <60>;
-               gpmc,wr-cycle-ns = <54>;
-               gpmc,access-ns = <36>;
-               gpmc,page-burst-access-ns = <0>;
-               gpmc,bus-turnaround-ns = <0>;
-               gpmc,cycle2cycle-delay-ns = <0>;
-               gpmc,wr-data-mux-bus-ns = <18>;
-               gpmc,wr-access-ns = <42>;
-               gpmc,cycle2cycle-samecsen;
-               gpmc,cycle2cycle-diffcsen;
-
                interrupt-parent = <&gpio6>;
                interrupts = <16 IRQ_TYPE_LEVEL_LOW>;   /* GPIO 176 */
-               reg-io-width = <4>;
        };
 };
 
-&i2c3 {
-       clock-frequency = <100000>;
-};
-
-&mmc3 {
+&lis33de {
        status = "disabled";
 };
+
index de5653e1b5ca3c47b615eb4f0be350cce339f49e..fd6400efcdee35e65abcd76a1f409012888dd4fd 100644 (file)
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-#include "omap34xx.dtsi"
+#include "omap3-overo.dtsi"
 #include "omap3-overo-tobi-common.dtsi"
 
 / {
index 597099907f8ef77423210bcf6cb2be26f8799eb5..69ca7c45bca29399ef38a52320802439bf7422bd 100644 (file)
@@ -1,94 +1,38 @@
 /*
- * Copyright (C) 2012 Florian Vaussard, EPFL Mobots group
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
  *
  * This program is free software; you can 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 Gumstix Overo must be combined with an expansion board.
- */
+#include "omap34xx.dtsi"
+#include "omap3-overo-base.dtsi"
 
-/ {
-       pwmleds {
-               compatible = "pwm-leds";
-
-               overo {
-                       label = "overo:blue:COM";
-                       pwms = <&twl_pwmled 1 7812500>;
-                       max-brightness = <127>;
-                       linux,default-trigger = "mmc0";
-               };
-       };
-
-       sound {
-               compatible = "ti,omap-twl4030";
-               ti,model = "overo";
-
-               ti,mcbsp = <&mcbsp2>;
-               ti,codec = <&twl_audio>;
-       };
-};
-
-&i2c1 {
-       clock-frequency = <2600000>;
-
-       twl: twl@48 {
-               reg = <0x48>;
-               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
-               interrupt-parent = <&intc>;
+&omap3_pmx_core2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &hsusb2_2_pins
+       >;
 
-               twl_audio: audio {
-                       compatible = "ti,twl4030-audio";
-                       codec {
-                       };
-               };
+       hsusb2_2_pins: pinmux_hsusb2_2_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3)            /* etk_d10.hsusb2_clk */
+                       OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3)            /* etk_d11.hsusb2_stp */
+                       OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d12.hsusb2_dir */
+                       OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d13.hsusb2_nxt */
+                       OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d14.hsusb2_data0 */
+                       OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3)    /* etk_d15.hsusb2_data1 */
+               >;
        };
-};
-
-#include "twl4030.dtsi"
-#include "twl4030_omap3.dtsi"
-
-/* i2c2 pins are used for gpio */
-&i2c2 {
-       status = "disabled";
-};
 
-/* on board microSD slot */
-&mmc1 {
-       vmmc-supply = <&vmmc1>;
-       bus-width = <4>;
-};
-
-/* optional on board WiFi */
-&mmc2 {
-       bus-width = <4>;
-};
-
-&twl_gpio {
-       ti,use-leds;
-};
-
-&usb_otg_hs {
-       interface-type = <0>;
-       usb-phy = <&usb2_phy>;
-       phys = <&usb2_phy>;
-       phy-names = "usb2-phy";
-       mode = <3>;
-       power = <50>;
-};
-
-&omap3_pmx_core {
-       uart3_pins: pinmux_uart3_pins {
+       w3cbw003c_2_pins: pinmux_w3cbw003c_2_pins {
                pinctrl-single,pins = <
-                       0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
-                       0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+                       OMAP3430_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4)            /* etk_d2.gpio_16 */
                >;
        };
 };
 
-&uart3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart3_pins>;
+&mcbsp2 {
+       status = "okay";
 };
index b9a2fedce7ee4e14ee3cbfd5540d1f792d9b4140..7909c51b05a5643563b4ed74405066e1a222a995 100644 (file)
@@ -2,11 +2,36 @@
  * Common support for CompuLab SB-T35 used on SBC-T3530, SBC-T3517 and SBC-T3730
  */
 
+/ {
+       vddvario_sb_t35: regulator-vddvario-sb-t35 {
+               compatible = "regulator-fixed";
+               regulator-name = "vddvario";
+               regulator-always-on;
+       };
+
+       vdd33a_sb_t35: regulator-vdd33a-sb-t35 {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd33a";
+               regulator-always-on;
+       };
+};
+
+&omap3_pmx_core {
+       smsc2_pins: pinmux_smsc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20b6, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs4.gpmc_ncs4 */
+                       OMAP3_CORE1_IOPAD(0x20d2, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_wait3.gpio_65 */
+               >;
+       };
+};
+
 &gpmc {
        ranges = <4 0 0x2d000000 0x01000000>;
 
        smsc2: ethernet@4,0 {
                compatible = "smsc,lan9221", "smsc,lan9115";
+               pinctrl-names = "default";
+               pinctrl-0 = <&smsc2_pins>;
                interrupt-parent = <&gpio3>;
                interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
                reg = <4 0 0xff>;
@@ -32,8 +57,8 @@
                gpmc,wr-access-ns = <186>;
                gpmc,cycle2cycle-samecsen;
                gpmc,cycle2cycle-diffcsen;
-               vddvario-supply = <&vddvario>;
-               vdd33a-supply = <&vdd33a>;
+               vddvario-supply = <&vddvario_sb_t35>;
+               vdd33a-supply = <&vdd33a_sb_t35>;
                reg-io-width = <4>;
                smsc,save-mac-address;
        };
diff --git a/arch/arm/boot/dts/omap3-sbc-t3517.dts b/arch/arm/boot/dts/omap3-sbc-t3517.dts
new file mode 100644 (file)
index 0000000..024c9c6
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Suppport for CompuLab SBC-T3517 with CM-T3517
+ */
+
+#include "omap3-cm-t3517.dts"
+#include "omap3-sb-t35.dtsi"
+
+/ {
+       model = "CompuLab SBC-T3517 with CM-T3517";
+       compatible = "compulab,omap3-sbc-t3517", "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3";
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &sb_t35_usb_hub_pins
+                       &usb_hub_pins
+                   >;
+
+       mmc1_aux_pins: pinmux_mmc1_aux_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20c0, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_clk.gpio_59   */
+                       OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE4) /* uart2_cts.gpio_144 */
+               >;
+       };
+
+       sb_t35_usb_hub_pins: pinmux_sb_t35_usb_hub_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21ec, PIN_OUTPUT | MUX_MODE4) /* ccdc_wen.gpio_98 - SB-T35 USB HUB RST */
+               >;
+       };
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               &mmc1_pins
+               &mmc1_aux_pins
+       >;
+
+       wp-gpios =  <&gpio2 27 GPIO_ACTIVE_HIGH>; /* gpio_59  */
+       cd-gpios =  <&gpio5 16 GPIO_ACTIVE_HIGH>; /* gpio_144 */
+};
diff --git a/arch/arm/boot/dts/omap3-sbc-t3530.dts b/arch/arm/boot/dts/omap3-sbc-t3530.dts
new file mode 100644 (file)
index 0000000..bbbeea6
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Suppport for CompuLab SBC-T3530 with CM-T3530
+ */
+
+#include "omap3-cm-t3530.dts"
+#include "omap3-sb-t35.dtsi"
+
+/ {
+       model = "CompuLab SBC-T3530 with CM-T3530";
+       compatible = "compulab,omap3-sbc-t3530", "compulab,omap3-cm-t3530", "ti,omap34xx", "ti,omap3";
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sb_t35_usb_hub_pins>;
+
+       sb_t35_usb_hub_pins: pinmux_sb_t35_usb_hub_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2130, PIN_OUTPUT | MUX_MODE4) /* ccdc_wen.gpio_167 - SB-T35 USB HUB RST */
+               >;
+       };
+};
+
+/*
+ * The following ranges correspond to SMSC9x eth chips on CM-T3530 CoM and
+ * SB-T35 baseboard respectively.
+ * This setting includes both chips in SBC-T3530 board device tree.
+ */
+&gpmc {
+       ranges = <5 0 0x2c000000 0x01000000>,
+                <4 0 0x2d000000 0x01000000>;
+};
+
+&mmc1 {
+       cd-gpios =  <&twl_gpio 0 GPIO_ACTIVE_HIGH>;
+};
index c119bd545053a51ee1d954a98e5f62ca5a825990..08e4a7086f2293c8b0343eeed752b48e477e37a9 100644 (file)
        compatible = "compulab,omap3-sbc-t3730", "compulab,omap3-cm-t3730", "ti,omap36xx", "ti,omap3";
 };
 
-&gpmc {
-       ranges = <5 0 0x2c000000 0x01000000>,
-                <4 0 0x2d000000 0x01000000>;
-};
-
-&smsc2 {
+&omap3_pmx_core {
        pinctrl-names = "default";
-       pinctrl-0 = <&smsc2_pins>;
-};
+       pinctrl-0 = <&sb_t35_usb_hub_pins>;
 
-&omap3_pmx_core {
-       smsc2_pins: pinmux_smsc2_pins {
+       sb_t35_usb_hub_pins: pinmux_sb_t35_usb_hub_pins {
                pinctrl-single,pins = <
-                       0x86 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_ncs4.gpmc_ncs4 */
-                       0xa2 (PIN_INPUT_PULLUP | MUX_MODE4)     /* gpmc_wait3.gpio_65 */
+                       OMAP3_CORE1_IOPAD(0x2130, PIN_OUTPUT | MUX_MODE4) /* ccdc_wen.gpio_167 - SB-T35 USB HUB RST */
                >;
        };
-};
\ No newline at end of file
+};
+
+&gpmc {
+       ranges = <5 0 0x2c000000 0x01000000>,
+                <4 0 0x2d000000 0x01000000>;
+};
index a5fc83b9c83545ce61738abf4695ceaa47453980..3d05eff67e25ea501410a3505788f513d20991f6 100644 (file)
                        compatible = "arm,cortex-a8";
                        device_type = "cpu";
                        reg = <0x0>;
+
+                       clocks = <&dpll1_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
                };
        };
 
                };
 
                mmu_isp: mmu@480bd400 {
-                       compatible = "ti,omap3-mmu-isp";
-                       ti,hwmods = "mmu_isp";
+                       compatible = "ti,omap2-iommu";
                        reg = <0x480bd400 0x80>;
-                       interrupts = <8>;
+                       interrupts = <24>;
+                       ti,hwmods = "mmu_isp";
+                       ti,#tlb-entries = <8>;
+               };
+
+               mmu_iva: mmu@5d000000 {
+                       compatible = "ti,omap2-iommu";
+                       reg = <0x5d000000 0x80>;
+                       interrupts = <28>;
+                       ti,hwmods = "mmu_iva";
+                       status = "disabled";
                };
 
                wdt2: wdt@48314000 {
                        dmas = <&sdma 31>,
                               <&sdma 32>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp2: mcbsp@49022000 {
                        dmas = <&sdma 33>,
                               <&sdma 34>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp3: mcbsp@49024000 {
                        dmas = <&sdma 17>,
                               <&sdma 18>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp4: mcbsp@49026000 {
                        dmas = <&sdma 19>,
                               <&sdma 20>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp5: mcbsp@48096000 {
                        dmas = <&sdma 21>,
                               <&sdma 22>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                sham: sham@480c3000 {
                        ranges;
 
                        usbhsohci: ohci@48064400 {
-                               compatible = "ti,ohci-omap3", "usb-ohci";
+                               compatible = "ti,ohci-omap3";
                                reg = <0x48064400 0x400>;
                                interrupt-parent = <&intc>;
                                interrupts = <76>;
                        };
 
                        usbhsehci: ehci@48064800 {
-                               compatible = "ti,ehci-omap", "usb-ehci";
+                               compatible = "ti,ehci-omap";
                                reg = <0x48064800 0x400>;
                                interrupt-parent = <&intc>;
                                interrupts = <77>;
                        num-eps = <16>;
                        ram-bits = <12>;
                };
+
+               dss: dss@48050000 {
+                       compatible = "ti,omap3-dss";
+                       reg = <0x48050000 0x200>;
+                       status = "disabled";
+                       ti,hwmods = "dss_core";
+                       clocks = <&dss1_alwon_fck>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       dispc@48050400 {
+                               compatible = "ti,omap3-dispc";
+                               reg = <0x48050400 0x400>;
+                               interrupts = <25>;
+                               ti,hwmods = "dss_dispc";
+                               clocks = <&dss1_alwon_fck>;
+                               clock-names = "fck";
+                       };
+
+                       dsi: encoder@4804fc00 {
+                               compatible = "ti,omap3-dsi";
+                               reg = <0x4804fc00 0x200>,
+                                     <0x4804fe00 0x40>,
+                                     <0x4804ff00 0x20>;
+                               reg-names = "proto", "phy", "pll";
+                               interrupts = <25>;
+                               status = "disabled";
+                               ti,hwmods = "dss_dsi1";
+                               clocks = <&dss1_alwon_fck>, <&dss2_alwon_fck>;
+                               clock-names = "fck", "sys_clk";
+                       };
+
+                       rfbi: encoder@48050800 {
+                               compatible = "ti,omap3-rfbi";
+                               reg = <0x48050800 0x100>;
+                               status = "disabled";
+                               ti,hwmods = "dss_rfbi";
+                               clocks = <&dss1_alwon_fck>, <&dss_ick>;
+                               clock-names = "fck", "ick";
+                       };
+
+                       venc: encoder@48050c00 {
+                               compatible = "ti,omap3-venc";
+                               reg = <0x48050c00 0x100>;
+                               status = "disabled";
+                               ti,hwmods = "dss_venc";
+                               clocks = <&dss_tv_fck>;
+                               clock-names = "fck";
+                       };
+               };
        };
 };
 
index 281914ed015136c57cb65d1039136899726bfd12..02f69f4a8fd37739cf12139861760196ed183079 100644 (file)
 &mmc1 {
        vmmc-supply = <&vmmc1>;
        vmmc_aux-supply = <&vsim>;
+       /*
+        * S6-3 must be in ON position for 8 bit mode to function
+        * Else, use 4 bit mode
+        */
        bus-width = <8>;
 };
 
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <1 0 0x08000000>;
+               ti,nand-ecc-opt = "ham1";
                nand-bus-width = <8>;
-
-               ti,nand-ecc-opt = "sw";
                gpmc,cs-on-ns = <0>;
                gpmc,cs-rd-off-ns = <36>;
                gpmc,cs-wr-off-ns = <36>;
index 02f6c7fabbec9c5f0efb11e3e7cdd9af6c521788..4c22f3a7f813a727058ebd4c283d62f1cfc04e0c 100644 (file)
                ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
        };
 
-       ssi_ssr_fck_3430es1: ssi_ssr_fck_3430es1 {
+       ssi_ssr_fck: ssi_ssr_fck_3430es1 {
                #clock-cells = <0>;
                compatible = "ti,composite-clock";
                clocks = <&ssi_ssr_gate_fck_3430es1>, <&ssi_ssr_div_fck_3430es1>;
        };
 
-       ssi_sst_fck_3430es1: ssi_sst_fck_3430es1 {
+       ssi_sst_fck: ssi_sst_fck_3430es1 {
                #clock-cells = <0>;
                compatible = "fixed-factor-clock";
-               clocks = <&ssi_ssr_fck_3430es1>;
+               clocks = <&ssi_ssr_fck>;
                clock-mult = <1>;
                clock-div = <2>;
        };
                clock-div = <1>;
        };
 
-       ssi_ick_3430es1: ssi_ick_3430es1 {
+       ssi_ick: ssi_ick_3430es1 {
                #clock-cells = <0>;
                compatible = "ti,omap3-no-wait-interface-clock";
                clocks = <&ssi_l4_ick>;
                clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>;
        };
 
-       dss1_alwon_fck_3430es1: dss1_alwon_fck_3430es1 {
+       dss1_alwon_fck: dss1_alwon_fck_3430es1 {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
                clocks = <&dpll4_m4x2_ck>;
                ti,set-rate-parent;
        };
 
-       dss_ick_3430es1: dss_ick_3430es1 {
+       dss_ick: dss_ick_3430es1 {
                #clock-cells = <0>;
                compatible = "ti,omap3-no-wait-interface-clock";
                clocks = <&l4_ick>;
        dss_clkdm: dss_clkdm {
                compatible = "ti,clockdomain";
                clocks = <&dss_tv_fck>, <&dss_96m_fck>, <&dss2_alwon_fck>,
-                        <&dss1_alwon_fck_3430es1>, <&dss_ick_3430es1>;
+                        <&dss1_alwon_fck>, <&dss_ick>;
        };
 
        d2d_clkdm: d2d_clkdm {
                         <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
                         <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
                         <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
-                        <&fshostusb_fck>, <&fac_ick>, <&ssi_ick_3430es1>;
+                        <&fshostusb_fck>, <&fac_ick>, <&ssi_ick>;
        };
 };
index af9ae5346bf2e9f2cda58bcb2aa3604ebaba3e58..080fb3f4e429bdd4e1463527bbfba42e47478593 100644 (file)
                ti,bit-shift = <30>;
        };
 
-       dss1_alwon_fck_3430es2: dss1_alwon_fck_3430es2 {
+       dss1_alwon_fck: dss1_alwon_fck_3430es2 {
                #clock-cells = <0>;
                compatible = "ti,dss-gate-clock";
                clocks = <&dpll4_m4x2_ck>;
                ti,set-rate-parent;
        };
 
-       dss_ick_3430es2: dss_ick_3430es2 {
+       dss_ick: dss_ick_3430es2 {
                #clock-cells = <0>;
                compatible = "ti,omap3-dss-interface-clock";
                clocks = <&l4_ick>;
        dss_clkdm: dss_clkdm {
                compatible = "ti,clockdomain";
                clocks = <&dss_tv_fck>, <&dss_96m_fck>, <&dss2_alwon_fck>,
-                        <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
+                        <&dss1_alwon_fck>, <&dss_ick>;
        };
 
        core_l4_clkdm: core_l4_clkdm {
index 2fcf253b677c050269cf1c48707666d6fe05ab4a..6b5280d04a0ed24baad6fa81a7f353f826f82c52 100644 (file)
        };
 };
 
+&dpll4_m2x2_mul_ck {
+       clock-mult = <1>;
+};
+
+&dpll4_m3x2_mul_ck {
+       clock-mult = <1>;
+};
+
+&dpll4_m4x2_mul_ck {
+       ti,clock-mult = <1>;
+};
+
+&dpll4_m5x2_mul_ck {
+       clock-mult = <1>;
+};
+
+&dpll4_m6x2_mul_ck {
+       clock-mult = <1>;
+};
+
 &cm_clockdomains {
        dpll4_clkdm: dpll4_clkdm {
                compatible = "ti,clockdomain";
index 8ed475dd63c982305f83c350ac41b8a87b246048..877318c283643ace96f5f162883dc644afc8f919 100644 (file)
                ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
        };
 
-       ssi_ssr_fck_3430es2: ssi_ssr_fck_3430es2 {
+       ssi_ssr_fck: ssi_ssr_fck_3430es2 {
                #clock-cells = <0>;
                compatible = "ti,composite-clock";
                clocks = <&ssi_ssr_gate_fck_3430es2>, <&ssi_ssr_div_fck_3430es2>;
        };
 
-       ssi_sst_fck_3430es2: ssi_sst_fck_3430es2 {
+       ssi_sst_fck: ssi_sst_fck_3430es2 {
                #clock-cells = <0>;
                compatible = "fixed-factor-clock";
-               clocks = <&ssi_ssr_fck_3430es2>;
+               clocks = <&ssi_ssr_fck>;
                clock-mult = <1>;
                clock-div = <2>;
        };
@@ -55,7 +55,7 @@
                clock-div = <1>;
        };
 
-       ssi_ick_3430es2: ssi_ick_3430es2 {
+       ssi_ick: ssi_ick_3430es2 {
                #clock-cells = <0>;
                compatible = "ti,omap3-ssi-interface-clock";
                clocks = <&ssi_l4_ick>;
                         <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
                         <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
                         <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
-                        <&ssi_ick_3430es2>;
+                        <&ssi_ick>;
        };
 };
index 7e8dee9175d6a4d1d796a5a9389b4a9c3300125d..22cf4647087edc27c5f67f40f028904f65859530 100644 (file)
                        clock-frequency = <48000000>;
                };
 
+               abb_mpu_iva: regulator-abb-mpu {
+                       compatible = "ti,abb-v1";
+                       regulator-name = "abb_mpu_iva";
+                       #address-cell = <0>;
+                       #size-cells = <0>;
+                       reg = <0x483072f0 0x8>, <0x48306818 0x4>;
+                       reg-names = "base-address", "int-address";
+                       ti,tranxdone-status-mask = <0x4000000>;
+                       clocks = <&sys_ck>;
+                       ti,settling-time = <30>;
+                       ti,clock-cycles = <8>;
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m   fbb_m   vset_m*/
+                       1012500         0       0       0       0       0
+                       1200000         0       0       0       0       0
+                       1325000         0       0       0       0       0
+                       1375000         1       0       0       0       0
+                       >;
+               };
+
                omap3_pmx_core2: pinmux@480025a0 {
                        compatible = "ti,omap3-padconf", "pinctrl-single";
                        reg = <0x480025a0 0x5c>;
        };
 };
 
-/include/ "omap36xx-clocks.dtsi"
+/* OMAP3630 needs dss_96m_fck for VENC */
+&venc {
+       clocks = <&dss_tv_fck>, <&dss_96m_fck>;
+       clock-names = "fck", "tv_dac_clk";
+};
+
 /include/ "omap34xx-omap36xx-clocks.dtsi"
 /include/ "omap36xx-omap3430es2plus-clocks.dtsi"
 /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
+/include/ "omap36xx-clocks.dtsi"
index cb04d4b37e7f0f241598645cd6bc2c215516530b..12be2b35dae9a249ca28b2eb4d3c4119d34d697f 100644 (file)
 
        dpll4_m4x2_mul_ck: dpll4_m4x2_mul_ck {
                #clock-cells = <0>;
-               compatible = "fixed-factor-clock";
+               compatible = "ti,fixed-factor-clock";
                clocks = <&dpll4_m4_ck>;
-               clock-mult = <2>;
-               clock-div = <1>;
+               ti,clock-mult = <2>;
+               ti,clock-div = <1>;
+               ti,set-rate-parent;
        };
 
        dpll4_m4x2_ck: dpll4_m4x2_ck {
                ti,bit-shift = <0x1d>;
                reg = <0x0d00>;
                ti,set-bit-to-disable;
+               ti,set-rate-parent;
        };
 
        dpll4_m5_ck: dpll4_m5_ck {
diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts
new file mode 100644 (file)
index 0000000..96f51d8
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "omap4-duovero.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "OMAP4430 Gumstix Duovero on Parlor";
+       compatible = "gumstix,omap4-duovero-parlor", "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4";
+
+       leds {
+               compatible = "gpio-leds";
+               led0 {
+                       label = "duovero:blue:led0";
+                       gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;   /* gpio_122 */
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               button0@121 {
+                       label = "button0";
+                       linux,code = <BTN_0>;
+                       gpios = <&gpio4 25 GPIO_ACTIVE_LOW>;    /* gpio_121 */
+                       gpio-key,wakeup;
+               };
+       };
+};
+
+&omap4_pmx_core {
+       pinctrl-0 = <
+                       &led_pins
+                       &button_pins
+                       &smsc_pins
+       >;
+
+       led_pins: pinmux_led_pins {
+               pinctrl-single,pins = <
+                       0xd6 (PIN_OUTPUT | MUX_MODE3)           /* abe_dmic_din3.gpio_122 */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       0xd4 (PIN_INPUT_PULLUP | MUX_MODE3)     /* abe_dmic_din2.gpio_121 */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       0xe6 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c2_scl */
+                       0xe8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c2_sda */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0xea (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c3_scl */
+                       0xec (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c3_sda */
+               >;
+       };
+
+       smsc_pins: pinmux_smsc_pins {
+               pinctrl-single,pins = <
+                       0x28 (PIN_INPUT | MUX_MODE3)            /* gpmc_a20.gpio_44: IRQ */
+                       0x2a (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a21.gpio_45: nReset */
+                       0x30 (PIN_INPUT_PULLUP | MUX_MODE3)     /* gpmc_a24.gpio_48: amdix enabled */
+               >;
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+
+       clock-frequency = <100000>;
+
+       /* optional 1K EEPROM with revision information */
+       eeprom@51 {
+               compatible = "atmel,24c01";
+               reg = <0x51>;
+               pagesize = <8>;
+       };
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+#include "omap-gpmc-smsc911x.dtsi"
+
+&gpmc {
+       ranges = <5 0 0x2c000000 0x1000000>;                    /* CS5 */
+
+       ethernet@gpmc {
+               reg = <5 0 0xff>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <12 IRQ_TYPE_LEVEL_LOW>;           /* gpio_44 */
+
+               phy-mode = "mii";
+
+               gpmc,cs-on-ns = <10>;
+               gpmc,cs-rd-off-ns = <50>;
+               gpmc,cs-wr-off-ns = <50>;
+               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 = <50>;
+               gpmc,we-on-ns = <15>;
+               gpmc,we-off-ns = <50>;
+               gpmc,rd-cycle-ns = <50>;
+               gpmc,wr-cycle-ns = <50>;
+               gpmc,access-ns = <50>;
+               gpmc,page-burst-access-ns = <0>;
+               gpmc,bus-turnaround-ns = <35>;
+               gpmc,cycle2cycle-delay-ns = <35>;
+               gpmc,wr-data-mux-bus-ns = <35>;
+               gpmc,wr-access-ns = <50>;
+
+               gpmc,mux-add-data = <2>;
+               gpmc,sync-read;
+               gpmc,sync-write;
+               gpmc,clk-activation-ns = <5>;
+               gpmc,sync-clk-ps = <20000>;
+       };
+};
+
+
diff --git a/arch/arm/boot/dts/omap4-duovero.dtsi b/arch/arm/boot/dts/omap4-duovero.dtsi
new file mode 100644 (file)
index 0000000..a514791
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2014 Florian Vaussard, EPFL Mobots group
+ *
+ * This program is free software; you can 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 "omap443x.dtsi"
+
+/ {
+       model = "Gumstix Duovero";
+       compatible = "gumstix,omap4-duovero", "ti,omap4430", "ti,omap4";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>; /* 1 GB */
+       };
+
+       sound {
+               compatible = "ti,abe-twl6040";
+               ti,model = "DuoVero";
+
+               ti,mclk-freq = <38400000>;
+
+               ti,mcpdm = <&mcpdm>;
+
+               ti,twl6040 = <&twl6040>;
+
+               /* Audio routing */
+               ti,audio-routing =
+                       "Headset Stereophone", "HSOL",
+                       "Headset Stereophone", "HSOR",
+                       "HSMIC", "Headset Mic",
+                       "Headset Mic", "Headset Mic Bias";
+       };
+
+       /* HS USB Host PHY on PORT 1 */
+       hsusb1_phy: hsusb1_phy {
+               compatible = "usb-nop-xceiv";
+               reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>;      /* gpio_62 */
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&hsusb1phy_pins>;
+
+               clocks = <&auxclk3_ck>;
+               clock-names = "main_clk";
+               clock-frequency = <19200000>;
+       };
+
+       /* regulator for w2cbw0015 on sdio5 */
+       w2cbw0015_vmmc: w2cbw0015_vmmc {
+               pinctrl-names = "default";
+               pinctrl-0 = <&w2cbw0015_pins>;
+               compatible = "regulator-fixed";
+               regulator-name = "w2cbw0015";
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+               gpio = <&gpio2 11 GPIO_ACTIVE_LOW>;             /* gpio_43 */
+               startup-delay-us = <70000>;
+               enable-active-high;
+               regulator-boot-on;
+       };
+};
+
+&omap4_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &twl6040_pins
+                       &mcpdm_pins
+                       &mcbsp1_pins
+                       &hsusbb1_pins
+       >;
+
+       twl6040_pins: pinmux_twl6040_pins {
+               pinctrl-single,pins = <
+                       0x126 (PIN_OUTPUT | MUX_MODE3)          /* usbb2_ulpitll_nxt.gpio_160 */
+                       0x160 (PIN_INPUT | MUX_MODE0)           /* sys_nirq2.sys_nirq2 */
+               >;
+       };
+
+       mcpdm_pins: pinmux_mcpdm_pins {
+               pinctrl-single,pins = <
+                       0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_ul_data.abe_pdm_ul_data */
+                       0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_dl_data.abe_pdm_dl_data */
+                       0xca (PIN_INPUT_PULLUP   | MUX_MODE0)   /* abe_pdm_frame.abe_pdm_frame */
+                       0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_pdm_lb_clk.abe_pdm_lb_clk */
+                       0xce (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_clks.abe_clks */
+               >;
+       };
+
+       mcbsp1_pins: pinmux_mcbsp1_pins {
+               pinctrl-single,pins = <
+                       0xbe (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+                       0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0)   /* abe_mcbsp1_dr.abe_mcbsp1_dr */
+                       0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)  /* abe_mcbsp1_dx.abe_mcbsp1_dx */
+                       0xc4 (PIN_INPUT | MUX_MODE0)            /* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
+               >;
+       };
+
+       hsusbb1_pins: pinmux_hsusbb1_pins {
+               pinctrl-single,pins = <
+                       0x82 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
+                       0x84 (PIN_OUTPUT | MUX_MODE4)           /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
+                       0x86 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
+                       0x88 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
+                       0x8a (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
+                       0x8c (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
+                       0x8e (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
+                       0x90 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
+                       0x92 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
+                       0x94 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
+                       0x96 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
+                       0x98 (PIN_INPUT_PULLDOWN | MUX_MODE4)   /* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
+               >;
+       };
+
+       hsusb1phy_pins: pinmux_hsusb1phy_pins {
+               pinctrl-single,pins = <
+                       0x4c (PIN_OUTPUT | MUX_MODE3)           /* gpmc_wait1.gpio_62 */
+               >;
+       };
+
+       w2cbw0015_pins: pinmux_w2cbw0015_pins {
+               pinctrl-single,pins = <
+                       0x26 (PIN_OUTPUT | MUX_MODE3)           /* gpmc_a19.gpio_43 */
+                       0x3a (PIN_INPUT | MUX_MODE3)            /* gpmc_ncs3.gpio_53 */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0xe2 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c1_scl */
+                       0xe4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c1_sda */
+               >;
+       };
+
+       i2c4_pins: pinmux_i2c4_pins {
+               pinctrl-single,pins = <
+                       0xee (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c4_scl */
+                       0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)     /* i2c4_sda */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0xa2 (PIN_INPUT_PULLUP | MUX_MODE0)     /* sdmmc1_clk */
+                       0xa4 (PIN_INPUT_PULLUP | MUX_MODE0)     /* sdmcc1_cmd */
+                       0xa6 (PIN_INPUT_PULLUP | MUX_MODE0)     /* sdmcc1_dat0 */
+                       0xa8 (PIN_INPUT_PULLUP | MUX_MODE0)     /* sdmmc1_dat1 */
+                       0xaa (PIN_INPUT_PULLUP | MUX_MODE0)     /* sdmmc1_dat2 */
+                       0xac (PIN_INPUT_PULLUP | MUX_MODE0)     /* sdmmc1_dat3 */
+               >;
+       };
+
+       mmc5_pins: pinmux_mmc5_pins {
+               pinctrl-single,pins = <
+                       0x108 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_clk */
+                       0x10a (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmcc5_cmd */
+                       0x10c (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmcc5_dat0 */
+                       0x10e (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat1 */
+                       0x110 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat2 */
+                       0x112 (PIN_INPUT_PULLUP | MUX_MODE0)    /* sdmmc5_dat3 */
+               >;
+       };
+};
+
+/* PMIC */
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       clock-frequency = <400000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;           /* IRQ_SYS_1N cascaded to gic */
+               interrupt-parent = <&gic>;
+       };
+
+       twl6040: twl@4b {
+               compatible = "ti,twl6040";
+               reg = <0x4b>;
+               interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;         /* IRQ_SYS_2N cascaded to gic */
+               interrupt-parent = <&gic>;
+               ti,audpwron-gpio = <&gpio6 0 GPIO_ACTIVE_HIGH>;         /* gpio_160 */
+
+               vio-supply = <&v1v8>;
+               v2v1-supply = <&v2v1>;
+               enable-active-high;
+       };
+};
+
+#include "twl6030.dtsi"
+#include "twl6030_omap4.dtsi"
+
+/* on-board bluetooth / WiFi module */
+&i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins>;
+
+       clock-frequency = <400000>;
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+
+       vmmc-supply = <&vmmc>;
+       ti,bus-width = <4>;
+       ti,non-removable;               /* FIXME: use PMIC_MMC detect */
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+/* mmc3 is available to the expansion board */
+
+&mmc4 {
+       status = "disabled";
+};
+
+/* on-board WiFi module */
+&mmc5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc5_pins>;
+
+       vmmc-supply = <&w2cbw0015_vmmc>;
+       ti,bus-width = <4>;
+       ti,non-removable;
+       cap-power-off-card;
+};
+
+&twl_usb_comparator {
+       usb-supply = <&vusb>;
+};
+
+&usb_otg_hs {
+       interface-type = <1>;
+       mode = <3>;
+       power = <50>;
+};
+
+&usbhshost {
+       port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <&hsusb1_phy>;
+};
+
index 88c6a05cab415f3cb04cdec0fb2bc3c504ec8d7f..d2c45bfaaa2c5269b996ebd9e29fcf2d8031be60 100644 (file)
                reg = <0x80000000 0x40000000>; /* 1 GB */
        };
 
+       aliases {
+               display0 = &dvi0;
+               display1 = &hdmi0;
+       };
+
        leds: leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
                compatible = "usb-nop-xceiv";
                reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>;   /* gpio_62 */
                vcc-supply = <&hsusb1_power>;
-       /**
-        * FIXME:
-        * put the right clock phandle here when available
-        *      clocks = <&auxclk3>;
-        *      clock-names = "main_clk";
-        */
+               clocks = <&auxclk3_ck>;
+               clock-names = "main_clk";
                clock-frequency = <19200000>;
        };
 
                startup-delay-us = <70000>;
                enable-active-high;
        };
+
+       tfp410: encoder@0 {
+               compatible = "ti,tfp410";
+               powerdown-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;   /* gpio_0 */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tfp410_in: endpoint@0 {
+                                       remote-endpoint = <&dpi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tfp410_out: endpoint@0 {
+                                       remote-endpoint = <&dvi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       dvi0: connector@0 {
+               compatible = "dvi-connector";
+               label = "dvi";
+
+               digital;
+
+               ddc-i2c-bus = <&i2c3>;
+
+               port {
+                       dvi_connector_in: endpoint {
+                               remote-endpoint = <&tfp410_out>;
+                       };
+               };
+       };
+
+       tpd12s015: encoder@1 {
+               compatible = "ti,tpd12s015";
+
+               gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,   /* 60, CT CP HPD */
+                       <&gpio2 9 GPIO_ACTIVE_HIGH>,    /* 41, LS OE */
+                       <&gpio2 31 GPIO_ACTIVE_HIGH>;   /* 63, HPD */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tpd12s015_in: endpoint@0 {
+                                       remote-endpoint = <&hdmi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tpd12s015_out: endpoint@0 {
+                                       remote-endpoint = <&hdmi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       hdmi0: connector@1 {
+               compatible = "hdmi-connector";
+               label = "hdmi";
+
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&tpd12s015_out>;
+                       };
+               };
+       };
 };
 
 &omap4_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
-                       &twl6040_pins
-                       &mcpdm_pins
-                       &mcbsp1_pins
                        &dss_dpi_pins
                        &tfp410_pins
                        &dss_hdmi_pins
        twl6040: twl@4b {
                compatible = "ti,twl6040";
                reg = <0x4b>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&twl6040_pins>;
+
                /* IRQ# = 119 */
                interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
                interrupt-parent = <&gic>;
        device-handle = <&elpida_ECB240ABACN>;
 };
 
-&mcbsp2 {
-       status = "disabled";
-};
-
-&mcbsp3 {
-       status = "disabled";
+&mcbsp1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp1_pins>;
+       status = "okay";
 };
 
-&dmic {
-       status = "disabled";
+&mcpdm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcpdm_pins>;
+       status = "okay";
 };
 
 &twl_usb_comparator {
 &usbhsehci {
        phys = <&hsusb1_phy>;
 };
+
+&dss {
+       status = "ok";
+
+       port {
+               dpi_out: endpoint {
+                       remote-endpoint = <&tfp410_in>;
+                       data-lines = <24>;
+               };
+       };
+};
+
+&dsi2 {
+       status = "ok";
+       vdd-supply = <&vcxio>;
+};
+
+&hdmi {
+       status = "ok";
+       vdda-supply = <&vdac>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&tpd12s015_in>;
+               };
+       };
+};
index dbc81fb6ef033428ce6b02d7287b7efa46ebfa1e..48983c8d56c22fe27271e1b6ff07b8c9f9e3cbc0 100644 (file)
                reg = <0x80000000 0x40000000>; /* 1 GB */
        };
 
+       aliases {
+               display0 = &lcd0;
+               display1 = &lcd1;
+               display2 = &hdmi0;
+       };
+
        vdd_eth: fixedregulator-vdd-eth {
                compatible = "regulator-fixed";
                regulator-name = "VDD_ETH";
                startup-delay-us = <70000>;
                enable-active-high;
        };
+
+       tpd12s015: encoder@0 {
+               compatible = "ti,tpd12s015";
+
+               gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,   /* 60, CT CP HPD */
+                       <&gpio2 9 GPIO_ACTIVE_HIGH>,    /* 41, LS OE */
+                       <&gpio2 31 GPIO_ACTIVE_HIGH>;   /* 63, HPD */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tpd12s015_in: endpoint@0 {
+                                       remote-endpoint = <&hdmi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tpd12s015_out: endpoint@0 {
+                                       remote-endpoint = <&hdmi_connector_in>;
+                               };
+                       };
+               };
+       };
+
+       hdmi0: connector@0 {
+               compatible = "hdmi-connector";
+               label = "hdmi";
+
+               type = "c";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&tpd12s015_out>;
+                       };
+               };
+       };
 };
 
 &omap4_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
-                       &twl6040_pins
-                       &mcpdm_pins
-                       &dmic_pins
-                       &mcbsp1_pins
-                       &mcbsp2_pins
                        &dss_hdmi_pins
                        &tpd12s015_pins
        >;
        twl6040: twl@4b {
                compatible = "ti,twl6040";
                reg = <0x4b>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&twl6040_pins>;
+
                /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
                interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
                interrupt-parent = <&gic>;
        pinctrl-0 = <&uart4_pins>;
 };
 
-&mcbsp3 {
-       status = "disabled";
+&mcbsp1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp1_pins>;
+       status = "okay";
+};
+
+&mcbsp2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp2_pins>;
+       status = "okay";
+};
+
+&dmic {
+       pinctrl-names = "default";
+       pinctrl-0 = <&dmic_pins>;
+       status = "okay";
+};
+
+&mcpdm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcpdm_pins>;
+       status = "okay";
 };
 
 &twl_usb_comparator {
        mode = <3>;
        power = <50>;
 };
+
+&dss {
+       status = "ok";
+};
+
+&dsi1 {
+       status = "ok";
+       vdd-supply = <&vcxio>;
+
+       port {
+               dsi1_out_ep: endpoint {
+                       remote-endpoint = <&lcd0_in>;
+                       lanes = <0 1 2 3 4 5>;
+               };
+       };
+
+       lcd0: display {
+               compatible = "tpo,taal", "panel-dsi-cm";
+               label = "lcd0";
+
+               reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;      /* 102 */
+
+               port {
+                       lcd0_in: endpoint {
+                               remote-endpoint = <&dsi1_out_ep>;
+                       };
+               };
+       };
+};
+
+&dsi2 {
+       status = "ok";
+       vdd-supply = <&vcxio>;
+
+       port {
+               dsi2_out_ep: endpoint {
+                       remote-endpoint = <&lcd1_in>;
+                       lanes = <0 1 2 3 4 5>;
+               };
+       };
+
+       lcd1: display {
+               compatible = "tpo,taal", "panel-dsi-cm";
+               label = "lcd1";
+
+               reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>;      /* 104 */
+
+               port {
+                       lcd1_in: endpoint {
+                               remote-endpoint = <&dsi2_out_ep>;
+                       };
+               };
+       };
+};
+
+&hdmi {
+       status = "ok";
+       vdda-supply = <&vdac>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&tpd12s015_in>;
+               };
+       };
+};
index d3f8a6e8ca205ef1585c279c1ce50dc8703fa6b5..2b4c1cbbce3351e1cb6b9711307bc684242c7718 100644 (file)
                        device_type = "cpu";
                        next-level-cache = <&L2>;
                        reg = <0x0>;
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
                };
                cpu@1 {
                        compatible = "arm,cortex-a9";
                        gpmc,num-waitpins = <4>;
                        ti,hwmods = "gpmc";
                        ti,no-idle-on-init;
+                       clocks = <&l3_div_ck>;
+                       clock-names = "fck";
                };
 
                uart1: serial@4806a000 {
                        compatible = "ti,omap4-hwspinlock";
                        reg = <0x4a0f6000 0x1000>;
                        ti,hwmods = "spinlock";
+                       #hwlock-cells = <1>;
                };
 
                i2c1: i2c@48070000 {
                        dma-names = "tx", "rx";
                };
 
+               mmu_dsp: mmu@4a066000 {
+                       compatible = "ti,omap4-iommu";
+                       reg = <0x4a066000 0x100>;
+                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmu_dsp";
+               };
+
+               mmu_ipu: mmu@55082000 {
+                       compatible = "ti,omap4-iommu";
+                       reg = <0x55082000 0x100>;
+                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmu_ipu";
+                       ti,iommu-bus-err-back;
+               };
+
                wdt2: wdt@4a314000 {
                        compatible = "ti,omap4-wdt", "ti,omap3-wdt";
                        reg = <0x4a314000 0x80>;
                        dmas = <&sdma 65>,
                               <&sdma 66>;
                        dma-names = "up_link", "dn_link";
+                       status = "disabled";
                };
 
                dmic: dmic@4012e000 {
                        ti,hwmods = "dmic";
                        dmas = <&sdma 67>;
                        dma-names = "up_link";
+                       status = "disabled";
                };
 
                mcbsp1: mcbsp@40122000 {
                        dmas = <&sdma 33>,
                               <&sdma 34>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp2: mcbsp@40124000 {
                        dmas = <&sdma 17>,
                               <&sdma 18>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp3: mcbsp@40126000 {
                        dmas = <&sdma 19>,
                               <&sdma 20>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp4: mcbsp@48096000 {
                        dmas = <&sdma 31>,
                               <&sdma 32>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                keypad: keypad@4a31c000 {
                        ti,hwmods = "kbd";
                };
 
+               dmm@4e000000 {
+                       compatible = "ti,omap4-dmm";
+                       reg = <0x4e000000 0x800>;
+                       interrupts = <0 113 0x4>;
+                       ti,hwmods = "dmm";
+               };
+
                emif1: emif@4c000000 {
                        compatible = "ti,emif-4d";
                        reg = <0x4c000000 0x100>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges;
+                       clocks = <&init_60m_fclk>,
+                                <&xclk60mhsp1_ck>,
+                                <&xclk60mhsp2_ck>;
+                       clock-names = "refclk_60m_int",
+                                     "refclk_60m_ext_p1",
+                                     "refclk_60m_ext_p2";
 
                        usbhsohci: ohci@4a064800 {
-                               compatible = "ti,ohci-omap3", "usb-ohci";
+                               compatible = "ti,ohci-omap3";
                                reg = <0x4a064800 0x400>;
                                interrupt-parent = <&gic>;
                                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        usbhsehci: ehci@4a064c00 {
-                               compatible = "ti,ehci-omap", "usb-ehci";
+                               compatible = "ti,ehci-omap";
                                reg = <0x4a064c00 0x400>;
                                interrupt-parent = <&gic>;
                                interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
                        dmas = <&sdma 117>, <&sdma 116>;
                        dma-names = "tx", "rx";
                };
+
+               abb_mpu: regulator-abb-mpu {
+                       compatible = "ti,abb-v2";
+                       regulator-name = "abb_mpu";
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       ti,tranxdone-status-mask = <0x80>;
+                       clocks = <&sys_clkin_ck>;
+                       ti,settling-time = <50>;
+                       ti,clock-cycles = <16>;
+
+                       status = "disabled";
+               };
+
+               abb_iva: regulator-abb-iva {
+                       compatible = "ti,abb-v2";
+                       regulator-name = "abb_iva";
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       ti,tranxdone-status-mask = <0x80000000>;
+                       clocks = <&sys_clkin_ck>;
+                       ti,settling-time = <50>;
+                       ti,clock-cycles = <16>;
+
+                       status = "disabled";
+               };
+
+               dss: dss@58000000 {
+                       compatible = "ti,omap4-dss";
+                       reg = <0x58000000 0x80>;
+                       status = "disabled";
+                       ti,hwmods = "dss_core";
+                       clocks = <&dss_dss_clk>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       dispc@58001000 {
+                               compatible = "ti,omap4-dispc";
+                               reg = <0x58001000 0x1000>;
+                               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,hwmods = "dss_dispc";
+                               clocks = <&dss_dss_clk>;
+                               clock-names = "fck";
+                       };
+
+                       rfbi: encoder@58002000  {
+                               compatible = "ti,omap4-rfbi";
+                               reg = <0x58002000 0x1000>;
+                               status = "disabled";
+                               ti,hwmods = "dss_rfbi";
+                               clocks = <&dss_dss_clk>, <&dss_fck>;
+                               clock-names = "fck", "ick";
+                       };
+
+                       venc: encoder@58003000 {
+                               compatible = "ti,omap4-venc";
+                               reg = <0x58003000 0x1000>;
+                               status = "disabled";
+                               ti,hwmods = "dss_venc";
+                               clocks = <&dss_tv_clk>;
+                               clock-names = "fck";
+                       };
+
+                       dsi1: encoder@58004000 {
+                               compatible = "ti,omap4-dsi";
+                               reg = <0x58004000 0x200>,
+                                     <0x58004200 0x40>,
+                                     <0x58004300 0x20>;
+                               reg-names = "proto", "phy", "pll";
+                               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                               ti,hwmods = "dss_dsi1";
+                               clocks = <&dss_dss_clk>, <&dss_sys_clk>;
+                               clock-names = "fck", "sys_clk";
+                       };
+
+                       dsi2: encoder@58005000 {
+                               compatible = "ti,omap4-dsi";
+                               reg = <0x58005000 0x200>,
+                                     <0x58005200 0x40>,
+                                     <0x58005300 0x20>;
+                               reg-names = "proto", "phy", "pll";
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                               ti,hwmods = "dss_dsi2";
+                               clocks = <&dss_dss_clk>, <&dss_sys_clk>;
+                               clock-names = "fck", "sys_clk";
+                       };
+
+                       hdmi: encoder@58006000 {
+                               compatible = "ti,omap4-hdmi";
+                               reg = <0x58006000 0x200>,
+                                     <0x58006200 0x100>,
+                                     <0x58006300 0x100>,
+                                     <0x58006400 0x1000>;
+                               reg-names = "wp", "pll", "phy", "core";
+                               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                               ti,hwmods = "dss_hdmi";
+                               clocks = <&dss_48mhz_clk>, <&dss_sys_clk>;
+                               clock-names = "fck", "sys_clk";
+                       };
+               };
        };
 };
 
index 8c1cfad30d603714ce267820186dd8c6635ff923..0adfa1d1ef204e1430e80930d46f47f46ca83c6c 100644 (file)
                        #thermal-sensor-cells = <0>;
                };
        };
+
+       ocp {
+               abb_mpu: regulator-abb-mpu {
+                       status = "okay";
+
+                       reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>;
+                       reg-names = "base-address", "int-address";
+
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m   fbb_m   vset_m*/
+                       1025000         0       0       0       0       0
+                       1200000         0       0       0       0       0
+                       1313000         0       0       0       0       0
+                       1375000         1       0       0       0       0
+                       1389000         1       0       0       0       0
+                       >;
+               };
+
+               /* Default unused, just provide register info for record */
+               abb_iva: regulator-abb-iva {
+                       reg = <0x4a307bd8 0x8>, <0x4a306010 0x4>;
+                       reg-names = "base-address", "int-address";
+               };
+
+       };
+
 };
 
 /include/ "omap443x-clocks.dtsi"
index 6b32f520741a9cb1398bf586a614a9358f04d3e5..194f9ef0a009d933355c802250ebce85da1bf679 100644 (file)
 
                        #thermal-sensor-cells = <0>;
                };
+
+               abb_mpu: regulator-abb-mpu {
+                       status = "okay";
+
+                       reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>,
+                             <0x4A002268 0x4>;
+                       reg-names = "base-address", "int-address",
+                                   "efuse-address";
+
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m   fbb_m   vset_m*/
+                       1025000         0       0       0       0       0
+                       1200000         0       0       0       0       0
+                       1313000         0       0       0x100000 0x40000 0
+                       1375000         1       0       0       0       0
+                       1389000         1       0       0       0       0
+                       >;
+               };
+
+               abb_iva: regulator-abb-iva {
+                       status = "okay";
+
+                       reg = <0x4a307bd8 0x8>, <0x4a306010 0x4>,
+                             <0x4A002268 0x4>;
+                       reg-names = "base-address", "int-address",
+                                   "efuse-address";
+
+                       ti,abb_info = <
+                       /*uV            ABB     efuse   rbb_m   fbb_m   vset_m*/
+                       950000          0       0       0       0       0
+                       1140000         0       0       0       0       0
+                       1291000         0       0       0x200000 0      0
+                       1375000         1       0       0       0       0
+                       1376000         1       0       0       0       0
+                       >;
+               };
        };
+
 };
 
 /include/ "omap446x-clocks.dtsi"
index 002fa70180a5bf38eaa66564cedd21f16897d626..3b99ec25b7489d56948f54f7ce90c7a0e25cab2c 100644 (file)
        hsusb2_phy: hsusb2_phy {
                compatible = "usb-nop-xceiv";
                reset-gpios = <&gpio3 16 GPIO_ACTIVE_LOW>; /* gpio3_80 HUB_NRESET */
-       /**
-         * FIXME
-         * Put the right clock phandle here when available
-         *     clocks = <&auxclk1>;
-         *     clock-names = "main_clk";
-         */
+               clocks = <&auxclk1_ck>;
+               clock-names = "main_clk";
                clock-frequency = <19200000>;
        };
 
index a72813a9663eccd7075b185489cbda4694fd0003..19155bb8483502dc4505c2d08e55dea8228b007b 100644 (file)
                                1000000 1060000
                                1500000 1250000
                        >;
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
+
                        /* cooling options */
                        cooling-min-level = <0>;
                        cooling-max-level = <2>;
                        gpmc,num-cs = <8>;
                        gpmc,num-waitpins = <4>;
                        ti,hwmods = "gpmc";
+                       clocks = <&l3_iclk_div>;
+                       clock-names = "fck";
                };
 
                i2c1: i2c@48070000 {
                        compatible = "ti,omap4-hwspinlock";
                        reg = <0x4a0f6000 0x1000>;
                        ti,hwmods = "spinlock";
+                       #hwlock-cells = <1>;
                };
 
                mcspi1: spi@48098000 {
                        dma-names = "tx", "rx";
                };
 
+               mmu_dsp: mmu@4a066000 {
+                       compatible = "ti,omap4-iommu";
+                       reg = <0x4a066000 0x100>;
+                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmu_dsp";
+               };
+
+               mmu_ipu: mmu@55082000 {
+                       compatible = "ti,omap4-iommu";
+                       reg = <0x55082000 0x100>;
+                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,hwmods = "mmu_ipu";
+                       ti,iommu-bus-err-back;
+               };
+
                keypad: keypad@4ae1c000 {
                        compatible = "ti,omap4-keypad";
                        reg = <0x4ae1c000 0x400>;
                        dmas = <&sdma 65>,
                               <&sdma 66>;
                        dma-names = "up_link", "dn_link";
+                       status = "disabled";
                };
 
                dmic: dmic@4012e000 {
                        ti,hwmods = "dmic";
                        dmas = <&sdma 67>;
                        dma-names = "up_link";
+                       status = "disabled";
                };
 
                mcbsp1: mcbsp@40122000 {
                        dmas = <&sdma 33>,
                               <&sdma 34>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp2: mcbsp@40124000 {
                        dmas = <&sdma 17>,
                               <&sdma 18>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                mcbsp3: mcbsp@40126000 {
                        dmas = <&sdma 19>,
                               <&sdma 20>;
                        dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
                timer1: timer@4ae18000 {
                        ti,hwmods = "wd_timer2";
                };
 
+               dmm@4e000000 {
+                       compatible = "ti,omap5-dmm";
+                       reg = <0x4e000000 0x800>;
+                       interrupts = <0 113 0x4>;
+                       ti,hwmods = "dmm";
+               };
+
                emif1: emif@4c000000 {
                        compatible      = "ti,emif-4d5";
                        ti,hwmods       = "emif1";
                                compatible = "snps,dwc3";
                                reg = <0x4a030000 0x10000>;
                                interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
-                               usb-phy = <&usb2_phy>, <&usb3_phy>;
+                               phys = <&usb2_phy>, <&usb3_phy>;
+                               phy-names = "usb2-phy", "usb3-phy";
                                dr_mode = "peripheral";
                                tx-fifo-resize;
                        };
                                compatible = "ti,omap-usb2";
                                reg = <0x4a084000 0x7c>;
                                ctrl-module = <&omap_control_usb2phy>;
+                               #phy-cells = <0>;
                        };
 
                        usb3_phy: usb3phy@4a084400 {
                                      <0x4a084c00 0x40>;
                                reg-names = "phy_rx", "phy_tx", "pll_ctrl";
                                ctrl-module = <&omap_control_usb3phy>;
+                               #phy-cells = <0>;
                        };
                };
 
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges;
+                       clocks = <&l3init_60m_fclk>,
+                                <&xclk60mhsp1_ck>,
+                                <&xclk60mhsp2_ck>;
+                       clock-names = "refclk_60m_int",
+                                     "refclk_60m_ext_p1",
+                                     "refclk_60m_ext_p2";
 
                        usbhsohci: ohci@4a064800 {
-                               compatible = "ti,ohci-omap3", "usb-ohci";
+                               compatible = "ti,ohci-omap3";
                                reg = <0x4a064800 0x400>;
                                interrupt-parent = <&gic>;
                                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        usbhsehci: ehci@4a064c00 {
-                               compatible = "ti,ehci-omap", "usb-ehci";
+                               compatible = "ti,ehci-omap";
                                reg = <0x4a064c00 0x400>;
                                interrupt-parent = <&gic>;
                                interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
index 8582ae41a5834e99ed26e5edc6f55971d2fa1d0c..20145526cd7b23fe649751643b950ef03a6b7b82 100644 (file)
                                #clock-cells = <1>;
                        };
 
-                       reset-controller@88010000 {
+                       rstc: reset-controller@88010000 {
                                compatible = "sirf,prima2-rstc";
                                reg = <0x88010000 0x1000>;
+                               #reset-cells = <1>;
                        };
 
                        rsc-controller@88020000 {
index 68a72f5507b9a88431641b715dd9a974f6b2cf3f..169bad90dac965640039c181cd4ab67cf7c8bec2 100644 (file)
@@ -1,63 +1,6 @@
-/dts-v1/;
-
-/include/ "skeleton.dtsi"
-
-#include <dt-bindings/clock/qcom,gcc-msm8660.h>
+#include "qcom-msm8660.dtsi"
 
 / {
        model = "Qualcomm MSM8660 SURF";
        compatible = "qcom,msm8660-surf", "qcom,msm8660";
-       interrupt-parent = <&intc>;
-
-       intc: interrupt-controller@2080000 {
-               compatible = "qcom,msm-8660-qgic";
-               interrupt-controller;
-               #interrupt-cells = <3>;
-               reg = < 0x02080000 0x1000 >,
-                     < 0x02081000 0x1000 >;
-       };
-
-       timer@2000000 {
-               compatible = "qcom,scss-timer", "qcom,msm-timer";
-               interrupts = <1 0 0x301>,
-                            <1 1 0x301>,
-                            <1 2 0x301>;
-               reg = <0x02000000 0x100>;
-               clock-frequency = <27000000>,
-                                 <32768>;
-               cpu-offset = <0x40000>;
-       };
-
-       msmgpio: gpio@800000 {
-               compatible = "qcom,msm-gpio";
-               reg = <0x00800000 0x4000>;
-               gpio-controller;
-               #gpio-cells = <2>;
-               ngpio = <173>;
-               interrupts = <0 16 0x4>;
-               interrupt-controller;
-               #interrupt-cells = <2>;
-       };
-
-       gcc: clock-controller@900000 {
-               compatible = "qcom,gcc-msm8660";
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-               reg = <0x900000 0x4000>;
-       };
-
-       serial@19c40000 {
-               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-               reg = <0x19c40000 0x1000>,
-                     <0x19c00000 0x1000>;
-               interrupts = <0 195 0x0>;
-               clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-               clock-names = "core", "iface";
-       };
-
-       qcom,ssbi@500000 {
-               compatible = "qcom,ssbi";
-               reg = <0x500000 0x1000>;
-               qcom,controller-type = "pmic-arbiter";
-       };
 };
diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
new file mode 100644 (file)
index 0000000..c52a9e9
--- /dev/null
@@ -0,0 +1,87 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+#include <dt-bindings/clock/qcom,gcc-msm8660.h>
+
+/ {
+       model = "Qualcomm MSM8660";
+       compatible = "qcom,msm8660";
+       interrupt-parent = <&intc>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "qcom,scorpion";
+               enable-method = "qcom,gcc-msm8660";
+
+               cpu@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+               };
+
+               L2: l2-cache {
+                       compatible = "cache";
+                       cache-level = <2>;
+               };
+       };
+
+       intc: interrupt-controller@2080000 {
+               compatible = "qcom,msm-8660-qgic";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               reg = < 0x02080000 0x1000 >,
+                     < 0x02081000 0x1000 >;
+       };
+
+       timer@2000000 {
+               compatible = "qcom,scss-timer", "qcom,msm-timer";
+               interrupts = <1 0 0x301>,
+                            <1 1 0x301>,
+                            <1 2 0x301>;
+               reg = <0x02000000 0x100>;
+               clock-frequency = <27000000>,
+                                 <32768>;
+               cpu-offset = <0x40000>;
+       };
+
+       msmgpio: gpio@800000 {
+               compatible = "qcom,msm-gpio";
+               reg = <0x00800000 0x4000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               ngpio = <173>;
+               interrupts = <0 16 0x4>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gcc: clock-controller@900000 {
+               compatible = "qcom,gcc-msm8660";
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               reg = <0x900000 0x4000>;
+       };
+
+       serial@19c40000 {
+               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+               reg = <0x19c40000 0x1000>,
+                     <0x19c00000 0x1000>;
+               interrupts = <0 195 0x0>;
+               clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
+               clock-names = "core", "iface";
+       };
+
+       qcom,ssbi@500000 {
+               compatible = "qcom,ssbi";
+               reg = <0x500000 0x1000>;
+               qcom,controller-type = "pmic-arbiter";
+       };
+};
index 7c30de4fa3022eb3a2bb7f6ec46c88d6482f6dc2..a58fb88315f69063256fe962e674751307609f82 100644 (file)
@@ -1,70 +1,6 @@
-/dts-v1/;
-
-/include/ "skeleton.dtsi"
-
-#include <dt-bindings/clock/qcom,gcc-msm8960.h>
+#include "qcom-msm8960.dtsi"
 
 / {
        model = "Qualcomm MSM8960 CDP";
        compatible = "qcom,msm8960-cdp", "qcom,msm8960";
-       interrupt-parent = <&intc>;
-
-       intc: interrupt-controller@2000000 {
-               compatible = "qcom,msm-qgic2";
-               interrupt-controller;
-               #interrupt-cells = <3>;
-               reg = < 0x02000000 0x1000 >,
-                     < 0x02002000 0x1000 >;
-       };
-
-       timer@200a000 {
-               compatible = "qcom,kpss-timer", "qcom,msm-timer";
-               interrupts = <1 1 0x301>,
-                            <1 2 0x301>,
-                            <1 3 0x301>;
-               reg = <0x0200a000 0x100>;
-               clock-frequency = <27000000>,
-                                 <32768>;
-               cpu-offset = <0x80000>;
-       };
-
-       msmgpio: gpio@800000 {
-               compatible = "qcom,msm-gpio";
-               gpio-controller;
-               #gpio-cells = <2>;
-               ngpio = <150>;
-               interrupts = <0 16 0x4>;
-               interrupt-controller;
-               #interrupt-cells = <2>;
-               reg = <0x800000 0x4000>;
-       };
-
-       gcc: clock-controller@900000 {
-               compatible = "qcom,gcc-msm8960";
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-               reg = <0x900000 0x4000>;
-       };
-
-       clock-controller@4000000 {
-               compatible = "qcom,mmcc-msm8960";
-               reg = <0x4000000 0x1000>;
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-       };
-
-       serial@16440000 {
-               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-               reg = <0x16440000 0x1000>,
-                     <0x16400000 0x1000>;
-               interrupts = <0 154 0x0>;
-               clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-               clock-names = "core", "iface";
-       };
-
-       qcom,ssbi@500000 {
-               compatible = "qcom,ssbi";
-               reg = <0x500000 0x1000>;
-               qcom,controller-type = "pmic-arbiter";
-       };
 };
diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
new file mode 100644 (file)
index 0000000..997b7b9
--- /dev/null
@@ -0,0 +1,135 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
+
+/ {
+       model = "Qualcomm MSM8960";
+       compatible = "qcom,msm8960";
+       interrupt-parent = <&intc>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <1 14 0x304>;
+               compatible = "qcom,krait";
+               enable-method = "qcom,kpss-acc-v1";
+
+               cpu@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+                       qcom,acc = <&acc0>;
+                       qcom,saw = <&saw0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+                       qcom,acc = <&acc1>;
+                       qcom,saw = <&saw1>;
+               };
+
+               L2: l2-cache {
+                       compatible = "cache";
+                       cache-level = <2>;
+                       interrupts = <0 2 0x4>;
+               };
+       };
+
+       cpu-pmu {
+               compatible = "qcom,krait-pmu";
+               interrupts = <1 10 0x304>;
+               qcom,no-pc-write;
+       };
+
+       intc: interrupt-controller@2000000 {
+               compatible = "qcom,msm-qgic2";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               reg = < 0x02000000 0x1000 >,
+                     < 0x02002000 0x1000 >;
+       };
+
+       timer@200a000 {
+               compatible = "qcom,kpss-timer", "qcom,msm-timer";
+               interrupts = <1 1 0x301>,
+                            <1 2 0x301>,
+                            <1 3 0x301>;
+               reg = <0x0200a000 0x100>;
+               clock-frequency = <27000000>,
+                                 <32768>;
+               cpu-offset = <0x80000>;
+       };
+
+       msmgpio: gpio@800000 {
+               compatible = "qcom,msm-gpio";
+               gpio-controller;
+               #gpio-cells = <2>;
+               ngpio = <150>;
+               interrupts = <0 16 0x4>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               reg = <0x800000 0x4000>;
+       };
+
+       gcc: clock-controller@900000 {
+               compatible = "qcom,gcc-msm8960";
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               reg = <0x900000 0x4000>;
+       };
+
+       clock-controller@4000000 {
+               compatible = "qcom,mmcc-msm8960";
+               reg = <0x4000000 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+       acc0: clock-controller@2088000 {
+               compatible = "qcom,kpss-acc-v1";
+               reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
+       };
+
+       acc1: clock-controller@2098000 {
+               compatible = "qcom,kpss-acc-v1";
+               reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
+       };
+
+       saw0: regulator@2089000 {
+               compatible = "qcom,saw2";
+               reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
+               regulator;
+       };
+
+       saw1: regulator@2099000 {
+               compatible = "qcom,saw2";
+               reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
+               regulator;
+       };
+
+       serial@16440000 {
+               compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+               reg = <0x16440000 0x1000>,
+                     <0x16400000 0x1000>;
+               interrupts = <0 154 0x0>;
+               clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
+               clock-names = "core", "iface";
+       };
+
+       qcom,ssbi@500000 {
+               compatible = "qcom,ssbi";
+               reg = <0x500000 0x1000>;
+               qcom,controller-type = "pmic-arbiter";
+       };
+
+       rng@1a500000 {
+               compatible = "qcom,prng";
+               reg = <0x1a500000 0x200>;
+               clocks = <&gcc PRNG_CLK>;
+               clock-names = "core";
+       };
+};
index 9e5dadb101ebe3f90cc7be611b772d502fd0c369..f68723918b3fe724fc671d1cd8045288221956c6 100644 (file)
@@ -9,6 +9,54 @@
        compatible = "qcom,msm8974";
        interrupt-parent = <&intc>;
 
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <1 9 0xf04>;
+               compatible = "qcom,krait";
+               enable-method = "qcom,kpss-acc-v2";
+
+               cpu@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+                       qcom,acc = <&acc0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+                       qcom,acc = <&acc1>;
+               };
+
+               cpu@2 {
+                       device_type = "cpu";
+                       reg = <2>;
+                       next-level-cache = <&L2>;
+                       qcom,acc = <&acc2>;
+               };
+
+               cpu@3 {
+                       device_type = "cpu";
+                       reg = <3>;
+                       next-level-cache = <&L2>;
+                       qcom,acc = <&acc3>;
+               };
+
+               L2: l2-cache {
+                       compatible = "cache";
+                       cache-level = <2>;
+                       interrupts = <0 2 0x4>;
+                       qcom,saw = <&saw_l2>;
+               };
+       };
+
+       cpu-pmu {
+               compatible = "qcom,krait-pmu";
+               interrupts = <1 7 0xf04>;
+       };
+
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
                        };
                };
 
+               saw_l2: regulator@f9012000 {
+                       compatible = "qcom,saw2";
+                       reg = <0xf9012000 0x1000>;
+                       regulator;
+               };
+
+               acc0: clock-controller@f9088000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0xf9088000 0x1000>, <0xf9008000 0x1000>;
+               };
+
+               acc1: clock-controller@f9098000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0xf9098000 0x1000>, <0xf9008000 0x1000>;
+               };
+
+               acc2: clock-controller@f90a8000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0xf90a8000 0x1000>, <0xf9008000 0x1000>;
+               };
+
+               acc3: clock-controller@f90b8000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
+               };
+
                restart@fc4ab000 {
                        compatible = "qcom,pshold";
                        reg = <0xfc4ab000 0x4>;
                        clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
                        clock-names = "core", "iface";
                };
+
+               rng@f9bff000 {
+                       compatible = "qcom,prng";
+                       reg = <0xf9bff000 0x200>;
+                       clocks = <&gcc GCC_PRNG_AHB_CLK>;
+                       clock-names = "core";
+               };
        };
 };
index da19c70ed82b0019f9e8f449c1c12e47839a6d5a..e664611a47c8710f479644dff5a275f624a08499 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "r7s72100.dtsi"
+#include "r7s72100.dtsi"
 
 / {
        model = "Genmai";
                #size-cells = <1>;
        };
 };
+
+&i2c2 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       eeprom@50 {
+               compatible = "renesas,24c128";
+               reg = <0x50>;
+               pagesize = <64>;
+       };
+};
index 46b82aa7dc4ed67cc6e6c900d50dea2dbddc0587..ee700717a34b4e33f097ca04aae390deb624671b 100644 (file)
@@ -8,12 +8,26 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
        compatible = "renesas,r7s72100";
        interrupt-parent = <&gic>;
        #address-cells = <1>;
        #size-cells = <1>;
 
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
+               spi3 = &spi3;
+               spi4 = &spi4;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0xe8201000 0x1000>,
                        <0xe8202000 0x1000>;
        };
+
+       i2c0: i2c@fcfee000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfee000 0x44>;
+               interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 158 IRQ_TYPE_EDGE_RISING>,
+                            <0 159 IRQ_TYPE_EDGE_RISING>,
+                            <0 160 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 161 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 162 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 163 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 164 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@fcfee400 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfee400 0x44>;
+               interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 166 IRQ_TYPE_EDGE_RISING>,
+                            <0 167 IRQ_TYPE_EDGE_RISING>,
+                            <0 168 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 169 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 170 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 171 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 172 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@fcfee800 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfee800 0x44>;
+               interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 174 IRQ_TYPE_EDGE_RISING>,
+                            <0 175 IRQ_TYPE_EDGE_RISING>,
+                            <0 176 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 177 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 178 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 179 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 180 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@fcfeec00 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfeec00 0x44>;
+               interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 182 IRQ_TYPE_EDGE_RISING>,
+                            <0 183 IRQ_TYPE_EDGE_RISING>,
+                            <0 184 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 185 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 186 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 187 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 188 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       spi0: spi@e800c800 {
+               compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+               reg = <0xe800c800 0x24>;
+               interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 239 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 240 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error", "rx", "tx";
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi1: spi@e800d000 {
+               compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+               reg = <0xe800d000 0x24>;
+               interrupts = <0 241 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 242 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 243 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error", "rx", "tx";
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi2: spi@e800d800 {
+               compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+               reg = <0xe800d800 0x24>;
+               interrupts = <0 244 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 245 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 246 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error", "rx", "tx";
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi3: spi@e800e000 {
+               compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+               reg = <0xe800e000 0x24>;
+               interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 248 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 249 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error", "rx", "tx";
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi4: spi@e800e800 {
+               compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+               reg = <0xe800e800 0x24>;
+               interrupts = <0 250 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 251 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 252 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error", "rx", "tx";
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
 };
index bb62c7a906f47c7b52b8563aedcaf6ae56e46197..06cda19dac6a6dccef649109ca17eb4528327dc7 100644 (file)
@@ -17,6 +17,7 @@
 /dts-v1/;
 #include "r8a7778.dtsi"
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "bockw";
@@ -84,7 +85,7 @@
 
        sdhi0_pins: sd0 {
                renesas,groups = "sdhi0_data4", "sdhi0_ctrl",
-                                 "sdhi0_cd", "sdhi0_wp";
+                                 "sdhi0_cd";
                renesas,function = "sdhi0";
        };
 
        vmmc-supply = <&fixedregulator3v3>;
        bus-width = <4>;
        status = "okay";
+       wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>;
 };
 
 &hspi0 {
index ddb3bd7a8838f63f8a1f369c9778d7a8c2519392..85c5b3b99f5e3b87485f193750e8150815ff9e17 100644 (file)
                status = "disabled";
        };
 
-       i2c0: i2c@ffc70000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,i2c-r8a7778";
-               reg = <0xffc70000 0x1000>;
-               interrupt-parent = <&gic>;
-               interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
-       i2c1: i2c@ffc71000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,i2c-r8a7778";
-               reg = <0xffc71000 0x1000>;
-               interrupt-parent = <&gic>;
-               interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
-       i2c2: i2c@ffc72000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,i2c-r8a7778";
-               reg = <0xffc72000 0x1000>;
-               interrupt-parent = <&gic>;
-               interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
-       i2c3: i2c@ffc73000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,i2c-r8a7778";
-               reg = <0xffc73000 0x1000>;
-               interrupt-parent = <&gic>;
-               interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
        hspi0: spi@fffc7000 {
                compatible = "renesas,hspi";
                reg = <0xfffc7000 0x18>;
index 57569cba152856d634ccb68474b0647012624b52..6e99eb2df076d7f1c7cdfdac46733c968256c0dd 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Device Tree Source for the Lager board
  *
- * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, Inc.
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2.  This program is licensed "as is" without any warranty of any
                regulator-boot-on;
                regulator-always-on;
        };
+
+       vcc_sdhi0: regulator@1 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI0 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio5 24 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi0: regulator@2 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI0 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
+
+       vcc_sdhi2: regulator@3 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI2 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio5 25 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi2: regulator@4 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI2 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio5 30 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
 };
 
 &extal_clk {
 };
 
 &pfc {
-       pinctrl-0 = <&scif0_pins &scif1_pins>;
+       pinctrl-0 = <&du_pins &scif0_pins &scif1_pins>;
        pinctrl-names = "default";
 
+       du_pins: du {
+               renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0";
+               renesas,function = "du";
+       };
+
        scif0_pins: serial0 {
                renesas,groups = "scif0_data";
                renesas,function = "scif0";
        };
 
+       ether_pins: ether {
+               renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+               renesas,function = "eth";
+       };
+
+       phy1_pins: phy1 {
+               renesas,groups = "intc_irq0";
+               renesas,function = "intc";
+       };
+
        scif1_pins: serial1 {
                renesas,groups = "scif1_data";
                renesas,function = "scif1";
        };
 
+       sdhi0_pins: sd0 {
+               renesas,gpios = "sdhi0_data4", "sdhi0_ctrl";
+               renesas,function = "sdhi0";
+       };
+
+       sdhi2_pins: sd2 {
+               renesas,gpios = "sdhi2_data4", "sdhi2_ctrl";
+               renesas,function = "sdhi2";
+       };
+
        mmc1_pins: mmc1 {
                renesas,groups = "mmc1_data8", "mmc1_ctrl";
                renesas,function = "mmc1";
        };
+
+       qspi_pins: spi {
+               renesas,groups = "qspi_ctrl", "qspi_data4";
+               renesas,function = "qspi";
+       };
+};
+
+&ether {
+       pinctrl-0 = <&ether_pins &phy1_pins>;
+       pinctrl-names = "default";
+
+       phy-handle = <&phy1>;
+       renesas,ether-link-active-low;
+       status = "ok";
+
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+               interrupt-parent = <&irqc0>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+       };
 };
 
 &mmcif1 {
        non-removable;
        status = "okay";
 };
+
+&sata1 {
+       status = "okay";
+};
+
+&spi {
+       pinctrl-0 = <&qspi_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       flash: flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spansion,s25fl512s";
+               reg = <0>;
+               spi-max-frequency = <30000000>;
+               m25p,fast-read;
+
+               partition@0 {
+                       label = "loader";
+                       reg = <0x00000000 0x00040000>;
+                       read-only;
+               };
+               partition@40000 {
+                       label = "user";
+                       reg = <0x00040000 0x00400000>;
+                       read-only;
+               };
+               partition@440000 {
+                       label = "flash";
+                       reg = <0x00440000 0x03bc0000>;
+               };
+       };
+};
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi0>;
+       vqmmc-supply = <&vccq_sdhi0>;
+       cd-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&sdhi2 {
+       pinctrl-0 = <&sdhi2_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi2>;
+       vqmmc-supply = <&vccq_sdhi2>;
+       cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
index 71b1251f79c73d24a4607aa33bbcc4b6fbafb0d0..618e5b537eaf9deb5efbe34ee7f917f8ea95990b 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Device Tree Source for the r8a7790 SoC
  *
- * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded Inc.
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2.  This program is licensed "as is" without any warranty of any
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
        gpio0: gpio@e6050000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
                reg = <0 0xe6050000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio1: gpio@e6051000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
                reg = <0 0xe6051000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio2: gpio@e6052000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
                reg = <0 0xe6052000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio3: gpio@e6053000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
                reg = <0 0xe6053000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio4: gpio@e6054000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
                reg = <0 0xe6054000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio5: gpio@e6055000 {
                compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar";
                reg = <0 0xe6055000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        thermal@e61f0000 {
                compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
                reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
-               interrupt-parent = <&gic>;
                interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
        };
 
        timer {
                #interrupt-cells = <2>;
                interrupt-controller;
                reg = <0 0xe61c0000 0 0x200>;
-               interrupt-parent = <&gic>;
                interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
                             <0 1 IRQ_TYPE_LEVEL_HIGH>,
                             <0 2 IRQ_TYPE_LEVEL_HIGH>,
                #size-cells = <0>;
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6508000 0 0x40>;
-               interrupt-parent = <&gic>;
                interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6518000 0 0x40>;
-               interrupt-parent = <&gic>;
                interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6530000 0 0x40>;
-               interrupt-parent = <&gic>;
                interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,i2c-r8a7790";
                reg = <0 0xe6540000 0 0x40>;
-               interrupt-parent = <&gic>;
                interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
                status = "disabled";
        mmcif0: mmcif@ee200000 {
                compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
                reg = <0 0xee200000 0 0x80>;
-               interrupt-parent = <&gic>;
                interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
                reg-io-width = <4>;
        mmcif1: mmc@ee220000 {
                compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
                reg = <0 0xee220000 0 0x80>;
-               interrupt-parent = <&gic>;
                interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
                reg-io-width = <4>;
        sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee100000 0 0x200>;
-               interrupt-parent = <&gic>;
                interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
                cap-sd-highspeed;
        sdhi1: sd@ee120000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee120000 0 0x200>;
-               interrupt-parent = <&gic>;
                interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
                cap-sd-highspeed;
        sdhi2: sd@ee140000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee140000 0 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
                cap-sd-highspeed;
        sdhi3: sd@ee160000 {
                compatible = "renesas,sdhi-r8a7790";
                reg = <0 0xee160000 0 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
                cap-sd-highspeed;
                status = "disabled";
        };
 
+       scifa0: serial@e6c40000 {
+               compatible = "renesas,scifa-r8a7790", "renesas,scifa";
+               reg = <0 0xe6c40000 0 64>;
+               interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa1: serial@e6c50000 {
+               compatible = "renesas,scifa-r8a7790", "renesas,scifa";
+               reg = <0 0xe6c50000 0 64>;
+               interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa2: serial@e6c60000 {
+               compatible = "renesas,scifa-r8a7790", "renesas,scifa";
+               reg = <0 0xe6c60000 0 64>;
+               interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb0: serial@e6c20000 {
+               compatible = "renesas,scifb-r8a7790", "renesas,scifb";
+               reg = <0 0xe6c20000 0 64>;
+               interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb1: serial@e6c30000 {
+               compatible = "renesas,scifb-r8a7790", "renesas,scifb";
+               reg = <0 0xe6c30000 0 64>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb2: serial@e6ce0000 {
+               compatible = "renesas,scifb-r8a7790", "renesas,scifb";
+               reg = <0 0xe6ce0000 0 64>;
+               interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif0: serial@e6e60000 {
+               compatible = "renesas,scif-r8a7790", "renesas,scif";
+               reg = <0 0xe6e60000 0 64>;
+               interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7790_CLK_SCIF0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif1: serial@e6e68000 {
+               compatible = "renesas,scif-r8a7790", "renesas,scif";
+               reg = <0 0xe6e68000 0 64>;
+               interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7790_CLK_SCIF1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif0: serial@e62c0000 {
+               compatible = "renesas,hscif-r8a7790", "renesas,hscif";
+               reg = <0 0xe62c0000 0 96>;
+               interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif1: serial@e62c8000 {
+               compatible = "renesas,hscif-r8a7790", "renesas,hscif";
+               reg = <0 0xe62c8000 0 96>;
+               interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       ether: ethernet@ee700000 {
+               compatible = "renesas,ether-r8a7790";
+               reg = <0 0xee700000 0 0x400>;
+               interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
+               phy-mode = "rmii";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       sata0: sata@ee300000 {
+               compatible = "renesas,sata-r8a7790";
+               reg = <0 0xee300000 0 0x2000>;
+               interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7790_CLK_SATA0>;
+               status = "disabled";
+       };
+
+       sata1: sata@ee500000 {
+               compatible = "renesas,sata-r8a7790";
+               reg = <0 0xee500000 0 0x2000>;
+               interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7790_CLK_SATA1>;
+               status = "disabled";
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                        clock-output-names = "extal";
                };
 
+               /*
+                * 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>;
+                       clock-output-names = "audio_clk_a";
+               };
+               audio_clk_b: audio_clk_b {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "audio_clk_b";
+               };
+               audio_clk_c: audio_clk_c {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "audio_clk_c";
+               };
+
                /* Special CPG clocks */
                cpg_clocks: cpg_clocks@e6150000 {
                        compatible = "renesas,r8a7790-cpg-clocks",
                mstp8_clks: mstp8_clks@e6150990 {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
-                       clocks = <&p_clk>;
+                       clocks = <&zg_clk>, <&zg_clk>, <&zg_clk>, <&zg_clk>, <&p_clk>,
+                                <&zs_clk>, <&zs_clk>;
                        #clock-cells = <1>;
-                       renesas,clock-indices = <R8A7790_CLK_ETHER>;
-                       clock-output-names = "ether";
+                       renesas,clock-indices = <
+                               R8A7790_CLK_VIN3 R8A7790_CLK_VIN2 R8A7790_CLK_VIN1
+                               R8A7790_CLK_VIN0 R8A7790_CLK_ETHER R8A7790_CLK_SATA1
+                               R8A7790_CLK_SATA0
+                       >;
+                       clock-output-names =
+                               "vin3", "vin2", "vin1", "vin0", "ether", "sata1", "sata0";
                };
                mstp9_clks: mstp9_clks@e6150994 {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                                "rcan1", "rcan0", "qspi_mod", "i2c3", "i2c2", "i2c1", "i2c0";
                };
        };
+
+       spi: spi@e6b10000 {
+               compatible = "renesas,qspi-r8a7790", "renesas,qspi";
+               reg = <0 0xe6b10000 0 0x2c>;
+               interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>;
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
 };
diff --git a/arch/arm/boot/dts/r8a7791-koelsch-reference.dts b/arch/arm/boot/dts/r8a7791-koelsch-reference.dts
deleted file mode 100644 (file)
index 588ca17..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Device Tree Source for the Koelsch board
- *
- * Copyright (C) 2013 Renesas Electronics Corporation
- * Copyright (C) 2013 Renesas Solutions Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-/dts-v1/;
-#include "r8a7791.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
-       model = "Koelsch";
-       compatible = "renesas,koelsch-reference", "renesas,r8a7791";
-
-       chosen {
-               bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
-       };
-
-       memory@40000000 {
-               device_type = "memory";
-               reg = <0 0x40000000 0 0x80000000>;
-       };
-
-       lbsc {
-               #address-cells = <1>;
-               #size-cells = <1>;
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-
-               key-a {
-                       gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
-                       linux,code = <30>;
-                       label = "SW30";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-               key-b {
-                       gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
-                       linux,code = <48>;
-                       label = "SW31";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-               key-c {
-                       gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
-                       linux,code = <46>;
-                       label = "SW32";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-               key-d {
-                       gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
-                       linux,code = <32>;
-                       label = "SW33";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-               key-e {
-                       gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
-                       linux,code = <18>;
-                       label = "SW34";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-               key-f {
-                       gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
-                       linux,code = <33>;
-                       label = "SW35";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-               key-g {
-                       gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
-                       linux,code = <34>;
-                       label = "SW36";
-                       gpio-key,wakeup;
-                       debounce-interval = <20>;
-               };
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               led6 {
-                       gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
-               };
-               led7 {
-                       gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
-               };
-               led8 {
-                       gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
-               };
-       };
-};
-
-&pfc {
-       pinctrl-0 = <&scif0_pins &scif1_pins>;
-       pinctrl-names = "default";
-
-       scif0_pins: serial0 {
-               renesas,groups = "scif0_data_d";
-               renesas,function = "scif0";
-       };
-
-       scif1_pins: serial1 {
-               renesas,groups = "scif1_data_d";
-               renesas,function = "scif1";
-       };
-};
index fd556c3483e38cffe0c9d57eba1dce58330b168f..bdd73e6657b27a76ee2d2f7c37abdced267b96ae 100644 (file)
@@ -2,7 +2,8 @@
  * Device Tree Source for the Koelsch board
  *
  * Copyright (C) 2013 Renesas Electronics Corporation
- * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, Inc.
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2.  This program is licensed "as is" without any warranty of any
 
        memory@40000000 {
                device_type = "memory";
-               reg = <0 0x40000000 0 0x80000000>;
+               reg = <0 0x40000000 0 0x40000000>;
+       };
+
+       memory@200000000 {
+               device_type = "memory";
+               reg = <2 0x00000000 0 0x40000000>;
        };
 
        lbsc {
                #size-cells = <1>;
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               key-a {
+                       gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+                       linux,code = <30>;
+                       label = "SW30";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+               key-b {
+                       gpios = <&gpio7 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <48>;
+                       label = "SW31";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+               key-c {
+                       gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <46>;
+                       label = "SW32";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+               key-d {
+                       gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <32>;
+                       label = "SW33";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+               key-e {
+                       gpios = <&gpio7 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <18>;
+                       label = "SW34";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+               key-f {
+                       gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <33>;
+                       label = "SW35";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+               key-g {
+                       gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <34>;
+                       label = "SW36";
+                       gpio-key,wakeup;
+                       debounce-interval = <20>;
+               };
+       };
+
        leds {
                compatible = "gpio-leds";
                led6 {
                        gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
                };
        };
+
+       vcc_sdhi0: regulator@0 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI0 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio7 17 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi0: regulator@1 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI0 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
+
+       vcc_sdhi1: regulator@2 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI1 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio7 18 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi1: regulator@3 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI1 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
+
+       vcc_sdhi2: regulator@4 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI2 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio7 19 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi2: regulator@5 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI2 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
 };
 
 &extal_clk {
        clock-frequency = <20000000>;
 };
 
+&i2c2 {
+       pinctrl-0 = <&i2c2_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       eeprom@50 {
+               compatible = "renesas,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
+
 &pfc {
-       pinctrl-0 = <&scif0_pins &scif1_pins>;
+       pinctrl-0 = <&du_pins &scif0_pins &scif1_pins>;
        pinctrl-names = "default";
 
+       i2c2_pins: i2c {
+               renesas,groups = "i2c2";
+               renesas,function = "i2c2";
+       };
+
+       du_pins: du {
+               renesas,groups = "du_rgb666", "du_sync", "du_clk_out_0";
+               renesas,function = "du";
+       };
+
        scif0_pins: serial0 {
                renesas,groups = "scif0_data_d";
                renesas,function = "scif0";
                renesas,groups = "scif1_data_d";
                renesas,function = "scif1";
        };
+
+       ether_pins: ether {
+               renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+               renesas,function = "eth";
+       };
+
+       phy1_pins: phy1 {
+               renesas,groups = "intc_irq0";
+               renesas,function = "intc";
+       };
+
+       sdhi0_pins: sd0 {
+               renesas,gpios = "sdhi0_data4", "sdhi0_ctrl";
+               renesas,function = "sdhi0";
+       };
+
+       sdhi1_pins: sd1 {
+               renesas,gpios = "sdhi1_data4", "sdhi1_ctrl";
+               renesas,function = "sdhi1";
+       };
+
+       sdhi2_pins: sd2 {
+               renesas,gpios = "sdhi2_data4", "sdhi2_ctrl";
+               renesas,function = "sdhi2";
+       };
+
+       qspi_pins: spi {
+               renesas,groups = "qspi_ctrl", "qspi_data4";
+               renesas,function = "qspi";
+       };
+};
+
+&ether {
+       pinctrl-0 = <&ether_pins &phy1_pins>;
+       pinctrl-names = "default";
+
+       phy-handle = <&phy1>;
+       renesas,ether-link-active-low;
+       status = "ok";
+
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+               interrupt-parent = <&irqc0>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+&sata0 {
+       status = "okay";
+};
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi0>;
+       vqmmc-supply = <&vccq_sdhi0>;
+       cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&sdhi1 {
+       pinctrl-0 = <&sdhi1_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi1>;
+       vqmmc-supply = <&vccq_sdhi1>;
+       cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&sdhi2 {
+       pinctrl-0 = <&sdhi2_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi2>;
+       vqmmc-supply = <&vccq_sdhi2>;
+       cd-gpios = <&gpio6 22 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&spi {
+       pinctrl-0 = <&qspi_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       flash: flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spansion,s25fl512s";
+               reg = <0>;
+               spi-max-frequency = <30000000>;
+               m25p,fast-read;
+
+               partition@0 {
+                       label = "loader";
+                       reg = <0x00000000 0x00080000>;
+                       read-only;
+               };
+               partition@80000 {
+                       label = "bootenv";
+                       reg = <0x00080000 0x00080000>;
+                       read-only;
+               };
+               partition@100000 {
+                       label = "data";
+                       reg = <0x00100000 0x03f00000>;
+               };
+       };
 };
index 3b075dd19b51ce7c28eb2b243c075a5a7e2be56a..46181708e59c5c7d7e558743983a88efa9622e13 100644 (file)
@@ -2,7 +2,8 @@
  * Device Tree Source for the r8a7791 SoC
  *
  * Copyright (C) 2013 Renesas Electronics Corporation
- * Copyright (C) 2013 Renesas Solutions Corp.
+ * Copyright (C) 2013-2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded Inc.
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2.  This program is licensed "as is" without any warranty of any
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
@@ -53,7 +63,6 @@
        gpio0: gpio@e6050000 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6050000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
@@ -65,7 +74,6 @@
        gpio1: gpio@e6051000 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6051000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
@@ -77,7 +85,6 @@
        gpio2: gpio@e6052000 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6052000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
@@ -89,7 +96,6 @@
        gpio3: gpio@e6053000 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6053000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio4: gpio@e6054000 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6054000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio5: gpio@e6055000 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6055000 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio6: gpio@e6055400 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6055400 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        gpio7: gpio@e6055800 {
                compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar";
                reg = <0 0xe6055800 0 0x50>;
-               interrupt-parent = <&gic>;
                interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
                #gpio-cells = <2>;
                gpio-controller;
        thermal@e61f0000 {
                compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal";
                reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
-               interrupt-parent = <&gic>;
                interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp5_clks R8A7791_CLK_THERMAL>;
        };
 
        timer {
                #interrupt-cells = <2>;
                interrupt-controller;
                reg = <0 0xe61c0000 0 0x200>;
-               interrupt-parent = <&gic>;
                interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
                             <0 1 IRQ_TYPE_LEVEL_HIGH>,
                             <0 2 IRQ_TYPE_LEVEL_HIGH>,
                             <0 17 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       i2c0: i2c@e6508000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7791";
+               reg = <0 0xe6508000 0 0x40>;
+               interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@e6518000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7791";
+               reg = <0 0xe6518000 0 0x40>;
+               interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@e6530000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7791";
+               reg = <0 0xe6530000 0 0x40>;
+               interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@e6540000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7791";
+               reg = <0 0xe6540000 0 0x40>;
+               interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
+               status = "disabled";
+       };
+
+       i2c4: i2c@e6520000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7791";
+               reg = <0 0xe6520000 0 0x40>;
+               interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
+               status = "disabled";
+       };
+
+       i2c5: i2c@e6528000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,i2c-r8a7791";
+               reg = <0 0xe6528000 0 0x40>;
+               interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
+               status = "disabled";
+       };
+
        pfc: pfc@e6060000 {
                compatible = "renesas,pfc-r8a7791";
                reg = <0 0xe6060000 0 0x250>;
                #gpio-range-cells = <3>;
        };
 
+       sdhi0: sd@ee100000 {
+               compatible = "renesas,sdhi-r8a7791";
+               reg = <0 0xee100000 0 0x200>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7791_CLK_SDHI0>;
+               status = "disabled";
+       };
+
+       sdhi1: sd@ee140000 {
+               compatible = "renesas,sdhi-r8a7791";
+               reg = <0 0xee140000 0 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7791_CLK_SDHI1>;
+               status = "disabled";
+       };
+
+       sdhi2: sd@ee160000 {
+               compatible = "renesas,sdhi-r8a7791";
+               reg = <0 0xee160000 0 0x100>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7791_CLK_SDHI2>;
+               status = "disabled";
+       };
+
+       scifa0: serial@e6c40000 {
+               compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+               reg = <0 0xe6c40000 0 64>;
+               interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa1: serial@e6c50000 {
+               compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+               reg = <0 0xe6c50000 0 64>;
+               interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa2: serial@e6c60000 {
+               compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+               reg = <0 0xe6c60000 0 64>;
+               interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa3: serial@e6c70000 {
+               compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+               reg = <0 0xe6c70000 0 64>;
+               interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa4: serial@e6c78000 {
+               compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+               reg = <0 0xe6c78000 0 64>;
+               interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa5: serial@e6c80000 {
+               compatible = "renesas,scifa-r8a7791", "renesas,scifa";
+               reg = <0 0xe6c80000 0 64>;
+               interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb0: serial@e6c20000 {
+               compatible = "renesas,scifb-r8a7791", "renesas,scifb";
+               reg = <0 0xe6c20000 0 64>;
+               interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb1: serial@e6c30000 {
+               compatible = "renesas,scifb-r8a7791", "renesas,scifb";
+               reg = <0 0xe6c30000 0 64>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb2: serial@e6ce0000 {
+               compatible = "renesas,scifb-r8a7791", "renesas,scifb";
+               reg = <0 0xe6ce0000 0 64>;
+               interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif0: serial@e6e60000 {
+               compatible = "renesas,scif-r8a7791", "renesas,scif";
+               reg = <0 0xe6e60000 0 64>;
+               interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_SCIF0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif1: serial@e6e68000 {
+               compatible = "renesas,scif-r8a7791", "renesas,scif";
+               reg = <0 0xe6e68000 0 64>;
+               interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_SCIF1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif2: serial@e6e58000 {
+               compatible = "renesas,scif-r8a7791", "renesas,scif";
+               reg = <0 0xe6e58000 0 64>;
+               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_SCIF2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif3: serial@e6ea8000 {
+               compatible = "renesas,scif-r8a7791", "renesas,scif";
+               reg = <0 0xe6ea8000 0 64>;
+               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_SCIF3>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif4: serial@e6ee0000 {
+               compatible = "renesas,scif-r8a7791", "renesas,scif";
+               reg = <0 0xe6ee0000 0 64>;
+               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_SCIF4>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif5: serial@e6ee8000 {
+               compatible = "renesas,scif-r8a7791", "renesas,scif";
+               reg = <0 0xe6ee8000 0 64>;
+               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_SCIF5>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif0: serial@e62c0000 {
+               compatible = "renesas,hscif-r8a7791", "renesas,hscif";
+               reg = <0 0xe62c0000 0 96>;
+               interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif1: serial@e62c8000 {
+               compatible = "renesas,hscif-r8a7791", "renesas,hscif";
+               reg = <0 0xe62c8000 0 96>;
+               interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif2: serial@e62d0000 {
+               compatible = "renesas,hscif-r8a7791", "renesas,hscif";
+               reg = <0 0xe62d0000 0 96>;
+               interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       ether: ethernet@ee700000 {
+               compatible = "renesas,ether-r8a7791";
+               reg = <0 0xee700000 0 0x400>;
+               interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7791_CLK_ETHER>;
+               phy-mode = "rmii";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       sata0: sata@ee300000 {
+               compatible = "renesas,sata-r8a7791";
+               reg = <0 0xee300000 0 0x2000>;
+               interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7791_CLK_SATA0>;
+               status = "disabled";
+       };
+
+       sata1: sata@ee500000 {
+               compatible = "renesas,sata-r8a7791";
+               reg = <0 0xee500000 0 0x2000>;
+               interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp8_clks R8A7791_CLK_SATA1>;
+               status = "disabled";
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                mstp8_clks: mstp8_clks@e6150990 {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
-                       clocks = <&p_clk>;
+                       clocks = <&zg_clk>, <&zg_clk>, <&zg_clk>, <&p_clk>, <&zs_clk>,
+                                <&zs_clk>;
                        #clock-cells = <1>;
-                       renesas,clock-indices = <R8A7791_CLK_ETHER>;
-                       clock-output-names = "ether";
+                       renesas,clock-indices = <
+                               R8A7791_CLK_VIN2 R8A7791_CLK_VIN1 R8A7791_CLK_VIN0
+                               R8A7791_CLK_ETHER R8A7791_CLK_SATA1 R8A7791_CLK_SATA0
+                       >;
+                       clock-output-names =
+                               "vin2", "vin1", "vin0", "ether", "sata1", "sata0";
                };
                mstp9_clks: mstp9_clks@e6150994 {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        #clock-cells = <1>;
                        renesas,clock-indices = <
                                R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD
-                               R8A7791_CLK_I2C4 R8A7791_CLK_I2C4 R8A7791_CLK_I2C3
+                               R8A7791_CLK_I2C5 R8A7791_CLK_I2C4 R8A7791_CLK_I2C3
                                R8A7791_CLK_I2C2 R8A7791_CLK_I2C1 R8A7791_CLK_I2C0
                        >;
                        clock-output-names =
                        clock-output-names = "scifa3", "scifa4", "scifa5";
                };
        };
+
+       spi: spi@e6b10000 {
+               compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+               reg = <0 0xe6b10000 0 0x2c>;
+               interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
+               num-cs = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
 };
index be5d2b09a363d15c66c648ab5079c9d1312226ce..4d4dfbb59f4b53590aaf4fe61af6c013f793a03a 100644 (file)
                        clock-names = "timer", "pclk";
                };
 
+               sram: sram@10080000 {
+                       compatible = "mmio-sram";
+                       reg = <0x10080000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x10080000 0x10000>;
+
+                       smp-sram@0 {
+                               compatible = "rockchip,rk3066-smp-sram";
+                               reg = <0x0 0x50>;
+                       };
+               };
+
                pinctrl@20008000 {
                        compatible = "rockchip,rk3066a-pinctrl";
                        reg = <0x20008000 0x150>;
index 1a26b03b3649dad974499bec8a21d68b88e35d8f..bb36596ea20538ac9ac4d74f868c72fed40b5613 100644 (file)
                        interrupts = <GIC_PPI 13 0xf04>;
                };
 
+               sram: sram@10080000 {
+                       compatible = "mmio-sram";
+                       reg = <0x10080000 0x8000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x10080000 0x8000>;
+
+                       smp-sram@0 {
+                               compatible = "rockchip,rk3066-smp-sram";
+                               reg = <0x0 0x50>;
+                       };
+               };
+
                pinctrl@20008000 {
                        compatible = "rockchip,rk3188-pinctrl";
                        reg = <0x20008000 0xa0>,
index 0fcbcfd67de2ddaa67ae6ef7cc273bd71c1fdcb3..26e5a968d49d1ffa39619d172237f28c4c74f1a7 100644 (file)
                compatible = "simple-bus";
                ranges;
 
+               scu@1013c000 {
+                       compatible = "arm,cortex-a9-scu";
+                       reg = <0x1013c000 0x100>;
+               };
+
+               pmu@20004000 {
+                       compatible = "rockchip,rk3066-pmu";
+                       reg = <0x20004000 0x100>;
+               };
+
                gic: interrupt-controller@1013d000 {
                        compatible = "arm,cortex-a9-gic";
                        interrupt-controller;
index 3d5faf85f51be4c283451b263e22450650019d7c..eabcfdbb403acc7ff40b409617a53c9831414c04 100644 (file)
                        };
 
                        adc0: adc@f8018000 {
-                               compatible = "atmel,at91sam9260-adc";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "atmel,at91sam9x5-adc";
                                reg = <0xf8018000 0x100>;
                                interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
                                pinctrl-names = "default";
                                clocks = <&adc_clk>,
                                         <&adc_op_clk>;
                                clock-names = "adc_clk", "adc_op_clk";
-                               atmel,adc-channel-base = <0x50>;
                                atmel,adc-channels-used = <0xfff>;
-                               atmel,adc-drdy-mask = <0x1000000>;
-                               atmel,adc-num-channels = <12>;
                                atmel,adc-startup-time = <40>;
-                               atmel,adc-status-register = <0x30>;
-                               atmel,adc-trigger-register = <0xc0>;
-                               atmel,adc-use-external;
+                               atmel,adc-use-external-triggers;
                                atmel,adc-vref = <3000>;
                                atmel,adc-res = <10 12>;
                                atmel,adc-res-names = "lowres", "highres";
                                status = "disabled";
 
                                trigger@0 {
+                                       reg = <0>;
                                        trigger-name = "external-rising";
                                        trigger-value = <0x1>;
                                        trigger-external;
                                };
                                trigger@1 {
+                                       reg = <1>;
                                        trigger-name = "external-falling";
                                        trigger-value = <0x2>;
                                        trigger-external;
                                };
                                trigger@2 {
+                                       reg = <2>;
                                        trigger-name = "external-any";
                                        trigger-value = <0x3>;
                                        trigger-external;
                                };
                                trigger@3 {
+                                       reg = <3>;
                                        trigger-name = "continuous";
                                        trigger-value = <0x6>;
                                };
                        };
 
-                       tsadcc: tsadcc@f8018000 {
-                               compatible = "atmel,at91sam9x5-tsadcc";
-                               reg = <0xf8018000 0x4000>;
-                               interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
-                               atmel,tsadcc_clock = <300000>;
-                               atmel,filtering_average = <0x03>;
-                               atmel,pendet_debounce = <0x08>;
-                               atmel,pendet_sensitivity = <0x02>;
-                               atmel,ts_sample_hold_time = <0x0a>;
-                               status = "disabled";
-                       };
-
                        i2c2: i2c@f801c000 {
                                compatible = "atmel,at91sam9x5-i2c";
                                reg = <0xf801c000 0x4000>;
                        interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>;
                        atmel,nand-addr-offset = <21>;
                        atmel,nand-cmd-offset = <22>;
+                       atmel,nand-has-dma;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand0_ale_cle>;
                        atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
index f9bdde542ced2f9e0a76aa6ae73a5a7478215ae6..035ab72b39903c474aeb60c80a44ee0f9207d489 100644 (file)
                        };
 
                        adc0: adc@f8018000 {
-                               status = "disabled";
-                       };
-
-                       tsadcc: tsadcc@f8018000 {
+                               atmel,adc-ts-wires = <4>;
+                               atmel,adc-ts-pressure-threshold = <10000>;
                                status = "okay";
                        };
 
index 537f1a5c07f55538ca161a16f8d0594b6170ca62..56fc214e6d2c3a6fd67f7ce41f11f0ec9a4c8abc 100644 (file)
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
-                                       osc: osc1 {
+                                       osc1: osc1 {
+                                               #clock-cells = <0>;
+                                               compatible = "fixed-clock";
+                                       };
+
+                                       osc2: osc2 {
                                                #clock-cells = <0>;
                                                compatible = "fixed-clock";
                                        };
                                        f2s_periph_ref_clk: f2s_periph_ref_clk {
                                                #clock-cells = <0>;
                                                compatible = "fixed-clock";
-                                               clock-frequency = <10000000>;
+                                       };
+
+                                       f2s_sdram_ref_clk: f2s_sdram_ref_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "fixed-clock";
                                        };
 
                                        main_pll: main_pll {
                                                #size-cells = <0>;
                                                #clock-cells = <0>;
                                                compatible = "altr,socfpga-pll-clock";
-                                               clocks = <&osc>;
+                                               clocks = <&osc1>;
                                                reg = <0x40>;
 
                                                mpuclk: mpuclk {
                                                #size-cells = <0>;
                                                #clock-cells = <0>;
                                                compatible = "altr,socfpga-pll-clock";
-                                               clocks = <&osc>;
+                                               clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>;
                                                reg = <0x80>;
 
                                                emac0_clk: emac0_clk {
                                                #size-cells = <0>;
                                                #clock-cells = <0>;
                                                compatible = "altr,socfpga-pll-clock";
-                                               clocks = <&osc>;
+                                               clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>;
                                                reg = <0xC0>;
 
                                                ddr_dqs_clk: ddr_dqs_clk {
                                                compatible = "altr,socfpga-gate-clk";
                                                clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
                                                clk-gate = <0xa0 8>;
+                                               clk-phase = <0 135>;
                                        };
 
                                        nand_x_clk: nand_x_clk {
 
                gmac0: ethernet@ff700000 {
                        compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+                       altr,sysmgr-syscon = <&sysmgr 0x60 0>;
                        reg = <0xff700000 0x2000>;
                        interrupts = <0 115 4>;
                        interrupt-names = "macirq";
 
                gmac1: ethernet@ff702000 {
                        compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+                       altr,sysmgr-syscon = <&sysmgr 0x60 2>;
                        reg = <0xff702000 0x2000>;
                        interrupts = <0 120 4>;
                        interrupt-names = "macirq";
                        arm,data-latency = <2 1 1>;
                };
 
+               mmc: dwmmc0@ff704000 {
+                       compatible = "altr,socfpga-dw-mshc";
+                       reg = <0xff704000 0x1000>;
+                       interrupts = <0 139 4>;
+                       fifo-depth = <0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&l4_mp_clk>, <&sdmmc_clk>;
+                       clock-names = "biu", "ciu";
+               };
+
                /* Local timer */
                timer@fffec600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0xffd05000 0x1000>;
                };
 
-               sysmgr@ffd08000 {
-                               compatible = "altr,sys-mgr";
-                               reg = <0xffd08000 0x4000>;
-                       };
+               sysmgr: sysmgr@ffd08000 {
+                       compatible = "altr,sys-mgr", "syscon";
+                       reg = <0xffd08000 0x4000>;
+               };
        };
 };
index a85b4043f888b108103ffe3dd3f06856c7e1d90a..6c87b7070ca77d0379e03b214a7a0f6601973bfc 100644 (file)
                        };
                };
 
+               dwmmc0@ff704000 {
+                       num-slots = <1>;
+                       supports-highspeed;
+                       broken-cd;
+
+                       slot@0 {
+                               reg = <0>;
+                               bus-width = <4>;
+                       };
+               };
+
                serial0@ffc02000 {
                        clock-frequency = <100000000>;
                };
index 5beffb2265f4869c0f38ca97385d35b0ebfb5555..a87ee1c07661b466d9d8abc8ca323739f82d6b69 100644 (file)
                */
                ethernet0 = &gmac1;
        };
+
+       aliases {
+               /* this allow the ethaddr uboot environmnet variable contents
+                * to be added to the gmac1 device tree blob.
+                */
+               ethernet0 = &gmac1;
+       };
+};
+
+&gmac1 {
+       status = "okay";
+       phy-mode = "rgmii";
+
+       rxd0-skew-ps = <0>;
+       rxd1-skew-ps = <0>;
+       rxd2-skew-ps = <0>;
+       rxd3-skew-ps = <0>;
+       txen-skew-ps = <0>;
+       txc-skew-ps = <2600>;
+       rxdv-skew-ps = <0>;
+       rxc-skew-ps = <2000>;
 };
index a8716f6dbe2e0adaa365032510a128238be7a764..ca41b0ebf461b12a413d36627a73fff323f5d69a 100644 (file)
                        };
                };
 
+               dwmmc0@ff704000 {
+                       num-slots = <1>;
+                       supports-highspeed;
+                       broken-cd;
+
+                       slot@0 {
+                               reg = <0>;
+                               bus-width = <4>;
+                       };
+               };
+
                ethernet@ff702000 {
                        phy-mode = "rgmii";
                        phy-addr = <0xffffffff>; /* probe for phy addr */
index 2ee52ab8cabbbb3613d03d3d832ccfd16ff21233..ae16d975196d62c1947cbf41187d0e47cb6a5e9a 100644 (file)
                ethernet0 = &gmac1;
        };
 };
+
+&gmac1 {
+       status = "okay";
+       phy-mode = "rgmii";
+
+       rxd0-skew-ps = <0>;
+       rxd1-skew-ps = <0>;
+       rxd2-skew-ps = <0>;
+       rxd3-skew-ps = <0>;
+       txen-skew-ps = <0>;
+       txc-skew-ps = <2600>;
+       rxdv-skew-ps = <0>;
+       rxc-skew-ps = <2000>;
+};
index 50b99a2c12aeb9549d70e09f9ea18c6bca797f1a..b79e2a2bf17522504e5384a929ee2d3226a42654 100644 (file)
                device_type = "memory";
                reg = <0x0 0x40000000>; /* 1GB */
        };
+
+       aliases {
+               /* this allow the ethaddr uboot environmnet variable contents
+                * to be added to the gmac1 device tree blob.
+                */
+               ethernet0 = &gmac1;
+       };
 };
 
 &gmac1 {
        status = "okay";
+       phy-mode = "rgmii";
+
+       rxd0-skew-ps = <0>;
+       rxd1-skew-ps = <0>;
+       rxd2-skew-ps = <0>;
+       rxd3-skew-ps = <0>;
+       txen-skew-ps = <0>;
+       txc-skew-ps = <2600>;
+       rxdv-skew-ps = <0>;
+       rxc-skew-ps = <2000>;
 };
index d1ec0cab2dee0daa986a8ddd75f10222cbcd25bb..87d6f759a9c187dc81c4ddcc718c97e87a7683ab 100644 (file)
                        };
                };
 
+               dwmmc0@ff704000 {
+                       num-slots = <1>;
+                       supports-highspeed;
+                       broken-cd;
+
+                       slot@0 {
+                               reg = <0>;
+                               bus-width = <4>;
+                       };
+               };
+
                ethernet@ff700000 {
                        phy-mode = "gmii";
                        status = "okay";
@@ -75,3 +86,8 @@
                };
        };
 };
+
+&gmac0 {
+       status = "okay";
+       phy-mode = "gmii";
+};
index e0853ea02df2296dc78c997123f3173754df48a8..e41eedca3ce3c562a27fff268f09c43429cbc10f 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <0>;
                        clocks = <&prcc_kclk 3 1>, <&prcc_pclk 3 1>;
-                       clock-names = "ssp0clk", "apb_pclk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */
                               <&dma 8 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        clocks = <&prcc_kclk 3 2>, <&prcc_pclk 3 2>;
-                       clock-names = "ssp1clk", "apb_pclk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */
                               <&dma 9 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        #size-cells = <0>;
                        /* Same clock wired to kernel and pclk */
                        clocks = <&prcc_pclk 2 8>, <&prcc_pclk 2 8>;
-                       clock-names = "spi0clk", "apb_pclk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */
                               <&dma 0 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        #size-cells = <0>;
                        /* Same clock wired to kernel and pclk */
                        clocks = <&prcc_pclk 2 2>, <&prcc_pclk 2 2>;
-                       clock-names = "spi1clk", "apb_pclk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */
                               <&dma 35 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        #size-cells = <0>;
                        /* Same clock wired to kernel and pclk */
                        clocks = <&prcc_pclk 2 1>, <&prcc_pclk 2 1>;
-                       clock-names = "spi2clk", "apb_pclk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */
                               <&dma 33 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        #size-cells = <0>;
                        /* Same clock wired to kernel and pclk */
                        clocks = <&prcc_pclk 1 7>, <&prcc_pclk 1 7>;
-                       clock-names = "spi3clk", "apb_pclk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */
                               <&dma 40 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi
new file mode 100644 (file)
index 0000000..30f8601
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ *
+ * 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
+ */
+
+/ {
+       soc {
+               prcmu@80157000 {
+                       ab8500 {
+                               ab8500-gpio {
+                                       /* Hog a few default settings */
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&gpio2_default_mode>,
+                                                   <&gpio4_default_mode>,
+                                                   <&gpio10_default_mode>,
+                                                   <&gpio11_default_mode>,
+                                                   <&gpio12_default_mode>,
+                                                   <&gpio13_default_mode>,
+                                                   <&gpio16_default_mode>,
+                                                   <&gpio24_default_mode>,
+                                                   <&gpio25_default_mode>,
+                                                   <&gpio36_default_mode>,
+                                                   <&gpio37_default_mode>,
+                                                   <&gpio38_default_mode>,
+                                                   <&gpio39_default_mode>,
+                                                   <&gpio42_default_mode>,
+                                                   <&gpio26_default_mode>,
+                                                   <&gpio35_default_mode>,
+                                                   <&ycbcr_default_mode>,
+                                                   <&pwm_default_mode>,
+                                                   <&adi1_default_mode>,
+                                                   <&usbuicc_default_mode>,
+                                                   <&dmic_default_mode>,
+                                                   <&extcpena_default_mode>,
+                                                   <&modsclsda_default_mode>;
+
+                                       /*
+                                        * Pins 2, 4, 10, 11, 12, 13, 16, 24, 25, 36, 37, 38, 39 and 42
+                                        * are muxed in as GPIO, and configured as INPUT PULL DOWN
+                                        */
+                                       gpio2 {
+                                               gpio2_default_mode: gpio2_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio2_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO2_T9";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio4 {
+                                               gpio4_default_mode: gpio4_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio4_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO4_W2";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio10 {
+                                               gpio10_default_mode: gpio10_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio10_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO10_U17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio11 {
+                                               gpio11_default_mode: gpio11_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio11_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO11_AA18";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio12 {
+                                               gpio12_default_mode: gpio12_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio12_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO12_U16";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio13 {
+                                               gpio13_default_mode: gpio13_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio13_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO13_W17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio16 {
+                                               gpio16_default_mode: gpio16_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio16_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO16_F15";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio24 {
+                                               gpio24_default_mode: gpio24_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio24_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO24_T14";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio25 {
+                                               gpio25_default_mode: gpio25_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio25_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO25_R16";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio36 {
+                                               gpio36_default_mode: gpio36_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio36_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO36_A17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio37 {
+                                               gpio37_default_mode: gpio37_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio37_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO37_E15";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio38 {
+                                               gpio38_default_mode: gpio38_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio38_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO38_C17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio39 {
+                                               gpio39_default_mode: gpio39_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio39_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO39_E16";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio42 {
+                                               gpio42_default_mode: gpio42_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio42_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO42_U2";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /*
+                                        * Pins 26 and 35 muxed in as GPIO, and configured as OUTPUT LOW
+                                        */
+                                       gpio26 {
+                                               gpio26_default_mode: gpio26_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio26_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO26_M16";
+                                                               output-low;
+                                                       };
+                                               };
+                                       };
+                                       gpio35 {
+                                               gpio35_default_mode: gpio35_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio35_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO35_W15";
+                                                               output-low;
+                                                       };
+                                               };
+                                       };
+                                       /*
+                                        * This sets up the YCBCR connector pins, i.e. analog video out.
+                                        * Set as input with no bias.
+                                        */
+                                       ycbcr {
+                                               ycbcr_default_mode: ycbcr_default {
+                                                       default_mux {
+                                                               ste,function = "ycbcr";
+                                                               ste,pins = "ycbcr0123_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO6_Y18",
+                                                                        "GPIO7_AA20",
+                                                                        "GPIO8_W18",
+                                                                        "GPIO9_AA19";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                       };
+                                       /* This sets up the PWM pins 14 and 15 */
+                                       pwm {
+                                               pwm_default_mode: pwm_default {
+                                                       default_mux {
+                                                               ste,function = "pwmout";
+                                                               ste,pins = "pwmout1_d_1", "pwmout2_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO14_F14",
+                                                                        "GPIO15_B17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /* This sets up audio interface 1 */
+                                       adi1 {
+                                               adi1_default_mode: adi1_default {
+                                                       default_mux {
+                                                               ste,function = "adi1";
+                                                               ste,pins = "adi1_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO17_P5",
+                                                                        "GPIO18_R5",
+                                                                        "GPIO19_U5",
+                                                                        "GPIO20_T5";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /* This sets up the USB UICC pins */
+                                       usbuicc {
+                                               usbuicc_default_mode: usbuicc_default {
+                                                       default_mux {
+                                                               ste,function = "usbuicc";
+                                                               ste,pins = "usbuicc_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO21_H19",
+                                                                        "GPIO22_G20",
+                                                                        "GPIO23_G19";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /* This sets up the microphone pins */
+                                       dmic {
+                                               dmic_default_mode: dmic_default {
+                                                       default_mux {
+                                                               ste,function = "dmic";
+                                                               ste,pins = "dmic12_d_1",
+                                                                        "dmic34_d_1",
+                                                                        "dmic56_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO27_J6",
+                                                                        "GPIO28_K6",
+                                                                        "GPIO29_G6",
+                                                                        "GPIO30_H6",
+                                                                        "GPIO31_F5",
+                                                                        "GPIO32_G5";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       extcpena {
+                                               extcpena_default_mode: extcpena_default {
+                                                       default_mux {
+                                                               ste,function = "extcpena";
+                                                               ste,pins = "extcpena_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO34_R17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /* Modem I2C setup (SCL and SDA pins) */
+                                       modsclsda {
+                                               modsclsda_default_mode: modsclsda_default {
+                                                       default_mux {
+                                                               ste,function = "modsclsda";
+                                                               ste,pins = "modsclsda_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO40_T19",
+                                                                       "GPIO41_U19";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /*
+                                        * Clock output pins associated with regulators.
+                                        */
+                                       sysclkreq2 {
+                                               sysclkreq2_default_mode: sysclkreq2_default {
+                                                       default_mux {
+                                                               ste,function = "sysclkreq";
+                                                               ste,pins = "sysclkreq2_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO1_T10";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                               sysclkreq2_sleep_mode: sysclkreq2_sleep {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio1_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO1_T10";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       sysclkreq4 {
+                                               sysclkreq4_default_mode: sysclkreq4_default {
+                                                       default_mux {
+                                                               ste,function = "sysclkreq";
+                                                               ste,pins = "sysclkreq4_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO3_U9";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                               sysclkreq4_sleep_mode: sysclkreq4_sleep {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio3_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO3_U9";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                               };
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-href-ab8505.dtsi b/arch/arm/boot/dts/ste-href-ab8505.dtsi
new file mode 100644 (file)
index 0000000..6006d62
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ *
+ * 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
+ */
+
+/ {
+       soc {
+               prcmu@80157000 {
+                       ab8505 {
+                               ab8505-gpio {
+                                       /* Hog a few default settings */
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&gpio2_default_mode>,
+                                                   <&gpio10_default_mode>,
+                                                   <&gpio11_default_mode>,
+                                                   <&gpio13_default_mode>,
+                                                   <&gpio34_default_mode>,
+                                                   <&gpio50_default_mode>,
+                                                   <&pwm_default_mode>,
+                                                   <&adi2_default_mode>,
+                                                   <&modsclsda_default_mode>,
+                                                   <&resethw_default_mode>,
+                                                   <&service_default_mode>;
+
+                                       /*
+                                        * Pins 2, 10, 11, 13, 34 and 50
+                                        * are muxed in as GPIO, and configured as INPUT PULL DOWN
+                                        */
+                                       gpio2 {
+                                               gpio2_default_mode: gpio2_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio2_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO2_R5";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio10 {
+                                               gpio10_default_mode: gpio10_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio10_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO10_B16";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio11 {
+                                               gpio11_default_mode: gpio11_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio11_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO11_B17";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio13 {
+                                               gpio13_default_mode: gpio13_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio13_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO13_D17";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                       };
+                                       gpio34 {
+                                               gpio34_default_mode: gpio34_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio34_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO34_H14";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       gpio50 {
+                                               gpio50_default_mode: gpio50_default {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio50_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO50_L4";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                       };
+                                       /* This sets up the PWM pin 14 */
+                                       pwm {
+                                               pwm_default_mode: pwm_default {
+                                                       default_mux {
+                                                               ste,function = "pwmout";
+                                                               ste,pins = "pwmout1_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO14_C16";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /* This sets up audio interface 2 */
+                                       adi2 {
+                                               adi2_default_mode: adi2_default {
+                                                       default_mux {
+                                                               ste,function = "adi2";
+                                                               ste,pins = "adi2_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO17_P2",
+                                                                        "GPIO18_N3",
+                                                                        "GPIO19_T1",
+                                                                        "GPIO20_P3";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /* Modem I2C setup (SCL and SDA pins) */
+                                       modsclsda {
+                                               modsclsda_default_mode: modsclsda_default {
+                                                       default_mux {
+                                                               ste,function = "modsclsda";
+                                                               ste,pins = "modsclsda_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO40_J15",
+                                                                       "GPIO41_J14";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       resethw {
+                                               resethw_default_mode: resethw_default {
+                                                       default_mux {
+                                                               ste,function = "resethw";
+                                                               ste,pins = "resethw_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO52_D16";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       service {
+                                               service_default_mode: service_default {
+                                                       default_mux {
+                                                               ste,function = "service";
+                                                               ste,pins = "service_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO53_D15";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       /*
+                                        * Clock output pins associated with regulators.
+                                        */
+                                       sysclkreq2 {
+                                               sysclkreq2_default_mode: sysclkreq2_default {
+                                                       default_mux {
+                                                               ste,function = "sysclkreq";
+                                                               ste,pins = "sysclkreq2_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO1_N4";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                               sysclkreq2_sleep_mode: sysclkreq2_sleep {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio1_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO1_N4";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                                       sysclkreq4 {
+                                               sysclkreq4_default_mode: sysclkreq4_default {
+                                                       default_mux {
+                                                               ste,function = "sysclkreq";
+                                                               ste,pins = "sysclkreq4_d_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO3_P5";
+                                                               input-enable;
+                                                               bias-disable;
+                                                       };
+                                               };
+                                               sysclkreq4_sleep_mode: sysclkreq4_sleep {
+                                                       default_mux {
+                                                               ste,function = "gpio";
+                                                               ste,pins = "gpio3_a_1";
+                                                       };
+                                                       default_cfg {
+                                                               ste,pins = "GPIO3_P5";
+                                                               input-enable;
+                                                               bias-pull-down;
+                                                       };
+                                               };
+                                       };
+                               };
+                       };
+               };
+       };
+};
index 40f0ecdf9303ca2c9db18ef5180bd0afb23564ca..abc762e24fcb759b8c641f69fa0cc54d14f33f4a 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "ste-dbx5x0.dtsi"
+#include "ste-href-ab8500.dtsi"
 #include "ste-href.dtsi"
 
 / {
index 3b6d1181939bc118f6980b583084367c3d395a73..c2341061b943290bbd5c897158a4a8c6bdd441cc 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "ste-dbx5x0.dtsi"
+#include "ste-href-ab8500.dtsi"
 #include "ste-href.dtsi"
 
 / {
index 97d5d21b7db7c2bdb416c064ef389b3425f82b41..a2f632d0be2a2da510d2f7e430e19f157c0f0dfa 100644 (file)
@@ -11,6 +11,7 @@
 
 /dts-v1/;
 #include "ste-dbx5x0.dtsi"
+#include "ste-href-ab8500.dtsi"
 #include "ste-href-family-pinctrl.dtsi"
 
 / {
index a9da4800daf0edf96d5b5a853afce566dc0e411a..6fe688e9e4da5230566ba89a8f7f52fab472bd4a 100644 (file)
                        interrupt-parent = <&vica>;
                        interrupts = <23>;
                        clocks = <&spi_clk>, <&spi_clk>;
-                       clock-names = "apb_pclk", "spi_clk";
+                       clock-names = "SSPCLK", "apb_pclk";
                        dmas = <&dmac 27 &dmac 28>;
                        dma-names = "tx", "rx";
                        num-cs = <3>;
index 174c799df741c0f4efdadad72304bc7a3bfafc22..d047dbc28d61ece8e763833ba6e1c76af9bfc2a0 100644 (file)
                        compatible = "fixed-clock";
                        clock-frequency = <100000000>;
                };
+
+               CLKS_GMAC0_PHY: clockgenA1@7 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+                       clock-output-names = "CLKS_GMAC0_PHY";
+               };
+
+               CLKS_ETH1_PHY: clockgenA0@7 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+                       clock-output-names = "CLKS_ETH1_PHY";
+               };
        };
 };
index e56449d41481fc3badf5fdd83ce3930c77f628f8..f09fb10a3791a7e4fc238f4e47548fc7f86da705 100644 (file)
@@ -7,6 +7,7 @@
  * publishhed by the Free Software Foundation.
  */
 #include "st-pincfg.h"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 / {
 
        aliases {
                        #size-cells     = <1>;
                        compatible      = "st,stih415-sbc-pinctrl";
                        st,syscfg       = <&syscfg_sbc>;
+                       reg             = <0xfe61f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfe610000 0x5000>;
 
                        PIO0: gpio@fe610000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO0";
                        };
                        PIO1: gpio@fe611000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO1";
                        };
                        PIO2: gpio@fe612000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO2";
                        };
                        PIO3: gpio@fe613000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO3";
                        };
                        PIO4: gpio@fe614000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO4";
                        };
                                        };
                                };
                        };
+
+                       rc{
+                               pinctrl_ir: ir0 {
+                                       st,pins {
+                                               ir = <&PIO4 0 ALT2 IN>;
+                                       };
+                               };
+                       };
+
+                       gmac1 {
+                               pinctrl_mii1: mii1 {
+                                               st,pins {
+                                                txd0   = <&PIO0 0 ALT1 OUT  SE_NICLK_IO        0       CLK_A>;
+                                                txd1   = <&PIO0 1 ALT1 OUT  SE_NICLK_IO        0       CLK_A>;
+                                                txd2   = <&PIO0 2 ALT1 OUT  SE_NICLK_IO        0       CLK_A>;
+                                                txd3   = <&PIO0 3 ALT1 OUT  SE_NICLK_IO        0       CLK_A>;
+                                                txer   = <&PIO0 4 ALT1 OUT  SE_NICLK_IO        0       CLK_A>;
+                                                txen   = <&PIO0 5 ALT1 OUT  SE_NICLK_IO        0       CLK_A>;
+                                                txclk  = <&PIO0 6 ALT1 IN   NICLK      0       CLK_A>;
+                                                col    = <&PIO0 7 ALT1 IN   BYPASS     1000>;
+                                                mdio   = <&PIO1 0 ALT1 OUT  BYPASS     0>;
+                                                mdc    = <&PIO1 1 ALT1 OUT  NICLK      0       CLK_A>;
+                                                crs    = <&PIO1 2 ALT1 IN   BYPASS     1000>;
+                                                mdint  = <&PIO1 3 ALT1 IN   BYPASS     0>;
+                                                rxd0   = <&PIO1 4 ALT1 IN   SE_NICLK_IO        0       CLK_A>;
+                                                rxd1   = <&PIO1 5 ALT1 IN   SE_NICLK_IO        0       CLK_A>;
+                                                rxd2   = <&PIO1 6 ALT1 IN   SE_NICLK_IO        0       CLK_A>;
+                                                rxd3   = <&PIO1 7 ALT1 IN   SE_NICLK_IO        0       CLK_A>;
+                                                rxdv   = <&PIO2 0 ALT1 IN   SE_NICLK_IO        0       CLK_A>;
+                                                rx_er  = <&PIO2 1 ALT1 IN   SE_NICLK_IO        0       CLK_A>;
+                                                rxclk  = <&PIO2 2 ALT1 IN   NICLK      0       CLK_A>;
+                                                phyclk = <&PIO2 3 ALT1 IN   NICLK      1000    CLK_A>;
+                                       };
+                               };
+
+                               pinctrl_rgmii1: rgmii1-0 {
+                                       st,pins {
+                                                txd0 =  <&PIO0 0 ALT1 OUT DE_IO        1000    CLK_A>;
+                                                txd1 =  <&PIO0 1 ALT1 OUT DE_IO        1000    CLK_A>;
+                                                txd2 =  <&PIO0 2 ALT1 OUT DE_IO        1000    CLK_A>;
+                                                txd3 =  <&PIO0 3 ALT1 OUT DE_IO        1000    CLK_A>;
+                                                txen =  <&PIO0 5 ALT1 OUT DE_IO        0       CLK_A>;
+                                                txclk = <&PIO0 6 ALT1 IN       NICLK   0       CLK_A>;
+                                                mdio =  <&PIO1 0 ALT1 OUT      BYPASS  0>;
+                                                mdc =   <&PIO1 1 ALT1 OUT      NICLK   0       CLK_A>;
+                                                rxd0 =  <&PIO1 4 ALT1 IN DE_IO 0       CLK_A>;
+                                                rxd1 =  <&PIO1 5 ALT1 IN DE_IO 0       CLK_A>;
+                                                rxd2 =  <&PIO1 6 ALT1 IN DE_IO 0       CLK_A>;
+                                                rxd3 =  <&PIO1 7 ALT1 IN DE_IO 0       CLK_A>;
+
+                                                rxdv =   <&PIO2 0 ALT1 IN DE_IO        500     CLK_A>;
+                                                rxclk =  <&PIO2 2 ALT1 IN      NICLK   0       CLK_A>;
+                                                phyclk = <&PIO2 3 ALT4 OUT     NICLK   0       CLK_B>;
+
+                                                clk125= <&PIO3 7 ALT4 IN       NICLK   0       CLK_A>;
+                                       };
+                               };
+                       };
                };
 
                pin-controller-front {
                        #size-cells     = <1>;
                        compatible      = "st,stih415-front-pinctrl";
                        st,syscfg       = <&syscfg_front>;
+                       reg             = <0xfee0f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfee00000 0x8000>;
 
                        PIO5: gpio@fee00000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO5";
                        };
                        PIO6: gpio@fee01000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO6";
                        };
                        PIO7: gpio@fee02000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO7";
                        };
                        PIO8: gpio@fee03000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO8";
                        };
                        PIO9: gpio@fee04000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO9";
                        };
                        PIO10: gpio@fee05000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x5000 0x100>;
                                st,bank-name    = "PIO10";
                        };
                        PIO11: gpio@fee06000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x6000 0x100>;
                                st,bank-name    = "PIO11";
                        };
                        PIO12: gpio@fee07000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x7000 0x100>;
                                st,bank-name    = "PIO12";
                        };
                        #size-cells     = <1>;
                        compatible      = "st,stih415-rear-pinctrl";
                        st,syscfg       = <&syscfg_rear>;
+                       reg             = <0xfe82f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfe820000 0x8000>;
 
                        PIO13: gpio@fe820000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO13";
                        };
                        PIO14: gpio@fe821000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO14";
                        };
                        PIO15: gpio@fe822000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO15";
                        };
                        PIO16: gpio@fe823000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO16";
                        };
                        PIO17: gpio@fe824000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO17";
                        };
                        PIO18: gpio@fe825000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x5000 0x100>;
                                st,bank-name    = "PIO18";
                        };
                                        };
                                };
                        };
+
+                       gmac0{
+                               pinctrl_mii0: mii0 {
+                                       st,pins {
+                                        mdint =        <&PIO13 6 ALT2  IN      BYPASS          0>;
+                                        txen =         <&PIO13 7 ALT2  OUT     SE_NICLK_IO     0       CLK_A>;
+
+                                        txd0 =         <&PIO14 0 ALT2  OUT     SE_NICLK_IO     0       CLK_A>;
+                                        txd1 =         <&PIO14 1 ALT2  OUT     SE_NICLK_IO     0       CLK_A>;
+                                        txd2 =         <&PIO14 2 ALT2  OUT     SE_NICLK_IO     0       CLK_B>;
+                                        txd3 =         <&PIO14 3 ALT2  OUT     SE_NICLK_IO     0       CLK_B>;
+
+                                        txclk =        <&PIO15 0 ALT2  IN      NICLK           0       CLK_A>;
+                                        txer =         <&PIO15 1 ALT2  OUT     SE_NICLK_IO     0       CLK_A>;
+                                        crs =          <&PIO15 2 ALT2  IN      BYPASS          1000>;
+                                        col =          <&PIO15 3 ALT2  IN      BYPASS          1000>;
+                                        mdio  =        <&PIO15 4 ALT2  OUT     BYPASS  3000>;
+                                        mdc   =        <&PIO15 5 ALT2  OUT     NICLK   0       CLK_B>;
+
+                                        rxd0 =         <&PIO16 0 ALT2  IN      SE_NICLK_IO     0       CLK_A>;
+                                        rxd1 =         <&PIO16 1 ALT2  IN      SE_NICLK_IO     0       CLK_A>;
+                                        rxd2 =         <&PIO16 2 ALT2  IN      SE_NICLK_IO     0       CLK_A>;
+                                        rxd3 =         <&PIO16 3 ALT2  IN      SE_NICLK_IO     0       CLK_A>;
+                                        rxdv =         <&PIO15 6 ALT2  IN      SE_NICLK_IO     0       CLK_A>;
+                                        rx_er =        <&PIO15 7 ALT2  IN      SE_NICLK_IO     0       CLK_A>;
+                                        rxclk =        <&PIO17 0 ALT2  IN      NICLK           0       CLK_A>;
+                                        phyclk =       <&PIO13 5 ALT2  OUT     NICLK   1000    CLK_A>;
+
+                                       };
+                               };
+
+                       pinctrl_gmii0: gmii0 {
+                               st,pins {
+                                        mdint =        <&PIO13 6       ALT2 IN         BYPASS  0>;
+                                        mdio  =        <&PIO15 4       ALT2 OUT        BYPASS  3000>;
+                                        mdc   =        <&PIO15 5       ALT2 OUT        NICLK   0       CLK_B>;
+                                        txen =         <&PIO13 7       ALT2 OUT        SE_NICLK_IO     3000    CLK_A>;
+
+                                        txd0 =         <&PIO14 0       ALT2 OUT        SE_NICLK_IO     3000    CLK_A>;
+                                        txd1 =         <&PIO14 1       ALT2 OUT        SE_NICLK_IO     3000    CLK_A>;
+                                        txd2 =         <&PIO14 2       ALT2 OUT        SE_NICLK_IO     3000    CLK_B>;
+                                        txd3 =         <&PIO14 3       ALT2 OUT        SE_NICLK_IO     3000    CLK_B>;
+                                        txd4 =         <&PIO14 4       ALT2 OUT        SE_NICLK_IO     3000    CLK_B>;
+                                        txd5 =         <&PIO14 5       ALT2 OUT        SE_NICLK_IO     3000    CLK_B>;
+                                        txd6 =         <&PIO14 6       ALT2 OUT        SE_NICLK_IO     3000    CLK_B>;
+                                        txd7 =         <&PIO14 7       ALT2 OUT        SE_NICLK_IO     3000    CLK_B>;
+
+                                        txclk =        <&PIO15 0       ALT2 IN         NICLK   0       CLK_A>;
+                                        txer =         <&PIO15 1       ALT2 OUT        SE_NICLK_IO     3000    CLK_A>;
+                                        crs =          <&PIO15 2       ALT2 IN         BYPASS  1000>;
+                                        col =          <&PIO15 3       ALT2 IN         BYPASS  1000>;
+                                        rxdv =         <&PIO15 6       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rx_er =        <&PIO15 7       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+
+                                        rxd0 =         <&PIO16 0       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd1 =         <&PIO16 1       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd2 =         <&PIO16 2       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd3 =         <&PIO16 3       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd4 =         <&PIO16 4       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd5 =         <&PIO16 5       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd6 =         <&PIO16 6       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+                                        rxd7 =         <&PIO16 7       ALT2 IN         SE_NICLK_IO     1500    CLK_A>;
+
+                                        rxclk =        <&PIO17 0       ALT2 IN NICLK   0       CLK_A>;
+                                        clk125 =       <&PIO17 6       ALT1 IN NICLK   0       CLK_A>;
+                                         phyclk =       <&PIO13 5       ALT4 OUT NICLK   0       CLK_B>;
+
+
+                                       };
+                               };
+                       };
                };
 
                pin-controller-left {
                        #size-cells     = <1>;
                        compatible      = "st,stih415-left-pinctrl";
                        st,syscfg       = <&syscfg_left>;
+                       reg             = <0xfd6bf080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfd6b0000 0x3000>;
 
                        PIO100: gpio@fd6b0000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO100";
                        };
                        PIO101: gpio@fd6b1000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO101";
                        };
                        PIO102: gpio@fd6b2000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO102";
                        };
                        #size-cells     = <1>;
                        compatible      = "st,stih415-right-pinctrl";
                        st,syscfg       = <&syscfg_right>;
+                       reg             = <0xfd33f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfd330000 0x5000>;
 
                        PIO103: gpio@fd330000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO103";
                        };
                        PIO104: gpio@fd331000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO104";
                        };
                        PIO105: gpio@fd332000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO105";
                        };
                        PIO106: gpio@fd333000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO106";
                        };
                        PIO107: gpio@fd334000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO107";
                        };
index d9c7dd1d95a4545a083874f8d0a4193f96063198..d89064c20c8a43ed3bdfd5e934526f72c5da5a54 100644 (file)
@@ -10,6 +10,7 @@
 #include "stih415-clock.dtsi"
 #include "stih415-pinctrl.dtsi"
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset-controller/stih415-resets.h>
 / {
 
        L2: cache-controller {
                ranges;
                compatible      = "simple-bus";
 
+               powerdown: powerdown-controller {
+                       #reset-cells = <1>;
+                       compatible = "st,stih415-powerdown";
+               };
+
+               softreset: softreset-controller {
+                       #reset-cells = <1>;
+                       compatible = "st,stih415-softreset";
+               };
+
                syscfg_sbc: sbc-syscfg@fe600000{
                        compatible      = "st,stih415-sbc-syscfg", "syscon";
                        reg             = <0xfe600000 0xb4>;
 
                        status          = "disabled";
                };
+
+               ethernet0: dwmac@fe810000 {
+                       device_type     = "network";
+                       compatible      = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
+                       status          = "disabled";
+
+                       reg             = <0xfe810000 0x8000>, <0x148 0x4>;
+                       reg-names       = "stmmaceth", "sti-ethconf";
+
+                       interrupts      = <0 147 0>, <0 148 0>, <0 149 0>;
+                       interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+                       resets                  = <&softreset STIH415_ETH0_SOFTRESET>;
+                       reset-names             = "stmmaceth";
+
+                       snps,pbl        = <32>;
+                       snps,mixed-burst;
+                       snps,force_sf_dma_mode;
+
+                       st,syscon       = <&syscfg_rear>;
+
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_mii0>;
+                       clock-names     = "stmmaceth";
+                       clocks          = <&CLKS_GMAC0_PHY>;
+               };
+
+               ethernet1: dwmac@fef08000 {
+                       device_type = "network";
+                       compatible      = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
+                       status          = "disabled";
+                       reg             = <0xfef08000 0x8000>, <0x74 0x4>;
+                       reg-names       = "stmmaceth", "sti-ethconf";
+                       interrupts      = <0 150 0>, <0 151 0>, <0 152 0>;
+                       interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+                       snps,pbl        = <32>;
+                       snps,mixed-burst;
+                       snps,force_sf_dma_mode;
+
+                       st,syscon               = <&syscfg_sbc>;
+
+                       resets                  = <&softreset STIH415_ETH1_SOFTRESET>;
+                       reset-names             = "stmmaceth";
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_mii1>;
+                       clock-names     = "stmmaceth";
+                       clocks          = <&CLKS_ETH1_PHY>;
+               };
+
+               rc: rc@fe518000 {
+                       compatible      = "st,comms-irb";
+                       reg             = <0xfe518000 0x234>;
+                       interrupts      =  <0 203 0>;
+                       clocks          = <&CLK_SYSIN>;
+                       rx-mode         = "infrared";
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_ir>;
+                       resets          = <&softreset STIH415_IRB_SOFTRESET>;
+               };
        };
 };
index 7026bf1158d83e90a98a41d731bf1351d4b89bff..a6942c75cbbbbf4de002588576306cd97c205193 100644 (file)
                        clock-frequency = <100000000>;
                        clock-output-names = "CLK_S_ICN_REG_0";
                };
+
+               CLK_S_GMAC0_PHY: clockgenA1@7 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+                       clock-output-names = "CLK_S_GMAC0_PHY";
+               };
+
+               CLK_S_ETH1_PHY: clockgenA0@7 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+                       clock-output-names = "CLK_S_ETH1_PHY";
+               };
        };
 };
index b29ff4ba542c51300d566f9649a78ed614e0f3b0..aeea304086eb3b57c5682539643f0d6ca4540c0d 100644 (file)
@@ -8,6 +8,7 @@
  * publishhed by the Free Software Foundation.
  */
 #include "st-pincfg.h"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 / {
 
        aliases {
                        #size-cells     = <1>;
                        compatible      = "st,stih416-sbc-pinctrl";
                        st,syscfg       = <&syscfg_sbc>;
+                       reg             = <0xfe61f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfe610000 0x6000>;
 
                        PIO0: gpio@fe610000 {
                                gpio-controller;
                                #gpio-cells = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO0";
                        };
                        PIO1: gpio@fe611000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO1";
                        };
                        PIO2: gpio@fe612000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO2";
                        };
                        PIO3: gpio@fe613000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO3";
                        };
                        PIO4: gpio@fe614000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO4";
                        };
                        PIO40: gpio@fe615000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x5000 0x100>;
                                st,bank-name    = "PIO40";
                                st,retime-pin-mask = <0x7f>;
                        };
 
+                       rc{
+                               pinctrl_ir: ir0 {
+                                       st,pins {
+                                               ir = <&PIO4 0 ALT2 IN>;
+                                       };
+                               };
+                       };
                        sbc_serial1 {
                                pinctrl_sbc_serial1: sbc_serial1 {
                                        st,pins {
                                        };
                                };
                        };
+
+                       gmac1 {
+                               pinctrl_mii1: mii1 {
+                                       st,pins {
+                                               txd0 = <&PIO0 0 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txd1 = <&PIO0 1 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txd2 = <&PIO0 2 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txd3 = <&PIO0 3 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txer = <&PIO0 4 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txen = <&PIO0 5 ALT1 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txclk = <&PIO0 6 ALT1 IN NICLK 0 CLK_A>;
+                                               col =   <&PIO0 7 ALT1 IN BYPASS 1000>;
+
+                                               mdio =  <&PIO1 0 ALT1 OUT BYPASS 1500>;
+                                               mdc =   <&PIO1 1 ALT1 OUT NICLK 0 CLK_A>;
+                                               crs =   <&PIO1 2 ALT1 IN BYPASS 1000>;
+                                               mdint = <&PIO1 3 ALT1 IN BYPASS 0>;
+                                               rxd0 =  <&PIO1 4 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxd1 =  <&PIO1 5 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxd2 =  <&PIO1 6 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxd3 =  <&PIO1 7 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+
+                                               rxdv =  <&PIO2 0 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+                                               rx_er = <&PIO2 1 ALT1 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxclk = <&PIO2 2 ALT1 IN NICLK 0 CLK_A>;
+                                               phyclk = <&PIO2 3 ALT1 OUT NICLK 0 CLK_A>;
+                                       };
+                               };
+                               pinctrl_rgmii1: rgmii1-0 {
+                                       st,pins {
+                                               txd0 =  <&PIO0 0 ALT1 OUT DE_IO 500 CLK_A>;
+                                               txd1 =  <&PIO0 1 ALT1 OUT DE_IO 500 CLK_A>;
+                                               txd2 =  <&PIO0 2 ALT1 OUT DE_IO 500 CLK_A>;
+                                               txd3 =  <&PIO0 3 ALT1 OUT DE_IO 500 CLK_A>;
+                                               txen =  <&PIO0 5 ALT1 OUT DE_IO 0   CLK_A>;
+                                               txclk = <&PIO0 6 ALT1 IN  NICLK 0   CLK_A>;
+
+                                               mdio = <&PIO1 0 ALT1 OUT BYPASS 0>;
+                                               mdc  = <&PIO1 1 ALT1 OUT NICLK  0 CLK_A>;
+                                               rxd0 = <&PIO1 4 ALT1 IN DE_IO 500 CLK_A>;
+                                               rxd1 = <&PIO1 5 ALT1 IN DE_IO 500 CLK_A>;
+                                               rxd2 = <&PIO1 6 ALT1 IN DE_IO 500 CLK_A>;
+                                               rxd3 = <&PIO1 7 ALT1 IN DE_IO 500 CLK_A>;
+
+                                               rxdv   = <&PIO2 0 ALT1 IN  DE_IO 500 CLK_A>;
+                                               rxclk  = <&PIO2 2 ALT1 IN  NICLK 0   CLK_A>;
+                                               phyclk = <&PIO2 3 ALT4 OUT NICLK 0   CLK_B>;
+
+                                               clk125= <&PIO3 7 ALT4 IN NICLK 0 CLK_A>;
+                                       };
+                               };
+                       };
                };
 
                pin-controller-front {
                        #size-cells     = <1>;
                        compatible      = "st,stih416-front-pinctrl";
                        st,syscfg       = <&syscfg_front>;
+                       reg             = <0xfee0f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfee00000 0x10000>;
 
                        PIO5: gpio@fee00000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO5";
                        };
                        PIO6: gpio@fee01000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO6";
                        };
                        PIO7: gpio@fee02000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO7";
                        };
                        PIO8: gpio@fee03000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO8";
                        };
                        PIO9: gpio@fee04000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO9";
                        };
                        PIO10: gpio@fee05000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x5000 0x100>;
                                st,bank-name    = "PIO10";
                        };
                        PIO11: gpio@fee06000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x6000 0x100>;
                                st,bank-name    = "PIO11";
                        };
                        PIO12: gpio@fee07000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x7000 0x100>;
                                st,bank-name    = "PIO12";
                        };
                        PIO30: gpio@fee08000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x8000 0x100>;
                                st,bank-name    = "PIO30";
                        };
                        PIO31: gpio@fee09000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x9000 0x100>;
                                st,bank-name    = "PIO31";
                        };
                                        };
                                };
                        };
+
+                       fsm {
+                               pinctrl_fsm: fsm {
+                                       st,pins {
+                                               spi-fsm-clk  = <&PIO12 2 ALT1 OUT>;
+                                               spi-fsm-cs   = <&PIO12 3 ALT1 OUT>;
+                                               spi-fsm-mosi = <&PIO12 4 ALT1 OUT>;
+                                               spi-fsm-miso = <&PIO12 5 ALT1 IN>;
+                                               spi-fsm-hol  = <&PIO12 6 ALT1 OUT>;
+                                               spi-fsm-wp   = <&PIO12 7 ALT1 OUT>;
+                                       };
+                               };
+                       };
                };
 
                pin-controller-rear {
                        #size-cells     = <1>;
                        compatible      = "st,stih416-rear-pinctrl";
                        st,syscfg       = <&syscfg_rear>;
+                       reg             = <0xfe82f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfe820000 0x6000>;
 
                        PIO13: gpio@fe820000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO13";
                        };
                        PIO14: gpio@fe821000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO14";
                        };
                        PIO15: gpio@fe822000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO15";
                        };
                        PIO16: gpio@fe823000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO16";
                        };
                        PIO17: gpio@fe824000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO17";
                        };
                        PIO18: gpio@fe825000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x5000 0x100>;
                                st,bank-name    = "PIO18";
                                st,retime-pin-mask = <0xf>;
                                        };
                                };
                        };
+
+                       gmac0 {
+                               pinctrl_mii0: mii0 {
+                                       st,pins {
+                                               mdint = <&PIO13 6 ALT2 IN  BYPASS      0>;
+                                               txen =  <&PIO13 7 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txd0 =  <&PIO14 0 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txd1 =  <&PIO14 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+                                               txd2 =  <&PIO14 2 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
+                                               txd3 =  <&PIO14 3 ALT2 OUT SE_NICLK_IO 0 CLK_B>;
+
+                                               txclk = <&PIO15 0 ALT2 IN  NICLK       0 CLK_A>;
+                                               txer =  <&PIO15 1 ALT2 OUT SE_NICLK_IO 0 CLK_A>;
+                                               crs = <&PIO15 2 ALT2 IN  BYPASS 1000>;
+                                               col = <&PIO15 3 ALT2 IN  BYPASS 1000>;
+                                               mdio= <&PIO15 4 ALT2 OUT BYPASS 1500>;
+                                               mdc = <&PIO15 5 ALT2 OUT NICLK  0    CLK_B>;
+
+                                               rxd0 =  <&PIO16 0 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxd1 =  <&PIO16 1 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxd2 =  <&PIO16 2 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxd3 =  <&PIO16 3 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxdv =  <&PIO15 6 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+                                               rx_er = <&PIO15 7 ALT2 IN SE_NICLK_IO 0 CLK_A>;
+                                               rxclk = <&PIO17 0 ALT2 IN NICLK 0 CLK_A>;
+                                               phyclk = <&PIO13 5 ALT2 OUT NICLK 0 CLK_B>;
+                                       };
+                               };
+
+                               pinctrl_gmii0: gmii0 {
+                                       st,pins {
+                                               };
+                               };
+                               pinctrl_rgmii0: rgmii0 {
+                                       st,pins {
+                                                phyclk = <&PIO13  5 ALT4 OUT NICLK 0 CLK_B>;
+                                                txen = <&PIO13 7 ALT2 OUT DE_IO 0 CLK_A>;
+                                                txd0  = <&PIO14 0 ALT2 OUT DE_IO 500 CLK_A>;
+                                                txd1  = <&PIO14 1 ALT2 OUT DE_IO 500 CLK_A>;
+                                                txd2  = <&PIO14 2 ALT2 OUT DE_IO 500 CLK_B>;
+                                                txd3  = <&PIO14 3 ALT2 OUT DE_IO 500 CLK_B>;
+                                                txclk = <&PIO15 0 ALT2 IN NICLK 0 CLK_A>;
+
+                                                mdio = <&PIO15 4 ALT2 OUT BYPASS 0>;
+                                                mdc = <&PIO15 5 ALT2 OUT NICLK 0 CLK_B>;
+
+                                                rxdv = <&PIO15 6 ALT2 IN DE_IO 500 CLK_A>;
+                                                rxd0 =<&PIO16 0 ALT2 IN DE_IO  500 CLK_A>;
+                                                rxd1 =<&PIO16 1 ALT2 IN DE_IO  500 CLK_A>;
+                                                rxd2 =<&PIO16 2 ALT2 IN DE_IO  500 CLK_A>;
+                                                rxd3  =<&PIO16 3 ALT2 IN DE_IO 500 CLK_A>;
+                                                rxclk =<&PIO17 0 ALT2 IN NICLK 0 CLK_A>;
+
+                                                clk125=<&PIO17 6 ALT1 IN NICLK 0 CLK_A>;
+                                       };
+                               };
+                       };
                };
 
                pin-controller-fvdp-fe {
                        #size-cells     = <1>;
                        compatible      = "st,stih416-fvdp-fe-pinctrl";
                        st,syscfg       = <&syscfg_fvdp_fe>;
+                       reg             = <0xfd6bf080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges          = <0 0xfd6b0000 0x3000>;
 
                        PIO100: gpio@fd6b0000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO100";
                        };
                        PIO101: gpio@fd6b1000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO101";
                        };
                        PIO102: gpio@fd6b2000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO102";
                        };
                        #size-cells     = <1>;
                        compatible      = "st,stih416-fvdp-lite-pinctrl";
                        st,syscfg               = <&syscfg_fvdp_lite>;
+                       reg             = <0xfd33f080 0x4>;
+                       reg-names       = "irqmux";
+                       interrupts      = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-names = "irqmux";
                        ranges                  = <0 0xfd330000 0x5000>;
 
                        PIO103: gpio@fd330000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0 0x100>;
                                st,bank-name    = "PIO103";
                        };
                        PIO104: gpio@fd331000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x1000 0x100>;
                                st,bank-name    = "PIO104";
                        };
                        PIO105: gpio@fd332000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x2000 0x100>;
                                st,bank-name    = "PIO105";
                        };
                        PIO106: gpio@fd333000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x3000 0x100>;
                                st,bank-name    = "PIO106";
                        };
                        PIO107: gpio@fd334000 {
                                gpio-controller;
                                #gpio-cells     = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
                                reg             = <0x4000 0x100>;
                                st,bank-name    = "PIO107";
                                st,retime-pin-mask = <0xf>;
index b7ab47b95816de67897c567fcbab4ffb61e90219..78746d20382e3b653a1489decaf94602007b6e21 100644 (file)
@@ -10,6 +10,7 @@
 #include "stih416-clock.dtsi"
 #include "stih416-pinctrl.dtsi"
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset-controller/stih416-resets.h>
 / {
        L2: cache-controller {
                compatible = "arm,pl310-cache";
                ranges;
                compatible      = "simple-bus";
 
+               powerdown: powerdown-controller {
+                       #reset-cells = <1>;
+                       compatible = "st,stih416-powerdown";
+               };
+
+               softreset: softreset-controller {
+                       #reset-cells = <1>;
+                       compatible = "st,stih416-softreset";
+               };
+
                syscfg_sbc:sbc-syscfg@fe600000{
                        compatible      = "st,stih416-sbc-syscfg", "syscon";
                        reg             = <0xfe600000 0x1000>;
 
                        status          = "disabled";
                };
+
+               ethernet0: dwmac@fe810000 {
+                       device_type     = "network";
+                       compatible      = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+                       status          = "disabled";
+                       reg             = <0xfe810000 0x8000>, <0x8bc 0x4>;
+                       reg-names       = "stmmaceth", "sti-ethconf";
+
+                       interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
+                       interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+                       snps,pbl        = <32>;
+                       snps,mixed-burst;
+
+                       st,syscon               = <&syscfg_rear>;
+                       resets                  = <&softreset STIH416_ETH0_SOFTRESET>;
+                       reset-names             = "stmmaceth";
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_mii0>;
+                       clock-names     = "stmmaceth";
+                       clocks          = <&CLK_S_GMAC0_PHY>;
+               };
+
+               ethernet1: dwmac@fef08000 {
+                       device_type = "network";
+                       compatible              = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+                       status          = "disabled";
+                       reg             = <0xfef08000 0x8000>, <0x7f0 0x4>;
+                       reg-names       = "stmmaceth", "sti-ethconf";
+                       interrupts = <0 136 0>, <0 137 0>, <0 138 0>;
+                       interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+
+                       snps,pbl        = <32>;
+                       snps,mixed-burst;
+
+                       st,syscon       = <&syscfg_sbc>;
+
+                       resets          = <&softreset STIH416_ETH1_SOFTRESET>;
+                       reset-names     = "stmmaceth";
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_mii1>;
+                       clock-names     = "stmmaceth";
+                       clocks          = <&CLK_S_ETH1_PHY>;
+               };
+
+               rc: rc@fe518000 {
+                       compatible      = "st,comms-irb";
+                       reg             = <0xfe518000 0x234>;
+                       interrupts      =  <0 203 0>;
+                       rx-mode         = "infrared";
+                       clocks          = <&CLK_SYSIN>;
+                       pinctrl-names   = "default";
+                       pinctrl-0       = <&pinctrl_ir>;
+                       resets          = <&softreset STIH416_IRB_SOFTRESET>;
+               };
+
+               /* FSM */
+               spifsm: spifsm@fe902000 {
+                       compatible         = "st,spi-fsm";
+                       reg                = <0xfe902000 0x1000>;
+                       pinctrl-0          = <&pinctrl_fsm>;
+
+                       st,syscfg          = <&syscfg_rear>;
+                       st,boot-device-reg = <0x958>;
+                       st,boot-device-spi = <0x1a>;
+
+                       status = "disabled";
+               };
        };
 };
index 1e6aa92772f55588d5b8c32b87490f781dc4dfa6..bf65c49095af08fa0e81e3f679461f4d63288c0e 100644 (file)
@@ -20,6 +20,8 @@
 
        aliases {
                ttyAS0 = &serial2;
+               ethernet0 = &ethernet0;
+               ethernet1 = &ethernet1;
        };
 
        soc {
 
                        status = "okay";
                };
+
+               ethernet0: dwmac@fe810000 {
+                       status                  = "okay";
+                       phy-mode                = "mii";
+                       pinctrl-0               = <&pinctrl_mii0>;
+
+                       snps,reset-gpio         = <&PIO106 2>;
+                       snps,reset-active-low;
+                       snps,reset-delays-us    = <0 10000 10000>;
+               };
+
+               ethernet1: dwmac@fef08000 {
+                       status                  = "disabled";
+                       phy-mode                = "mii";
+                       st,tx-retime-src        = "txclk";
+
+                       snps,reset-gpio         = <&PIO4 7>;
+                       snps,reset-active-low;
+                       snps,reset-delays-us    = <0 10000 10000>;
+               };
        };
 };
index 0ef0a69df8ea36909f38e40d6552a8be27fb5d6c..838513f9ddc0f7bd6d526c73e46a68408a47d15b 100644 (file)
@@ -6,6 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * publishhed by the Free Software Foundation.
  */
+#include "stih41x-b2020x.dtsi"
 / {
        memory{
                device_type = "memory";
@@ -19,6 +20,7 @@
 
        aliases {
                ttyAS0 = &sbc_serial1;
+               ethernet1 = &ethernet1;
        };
        soc {
                sbc_serial1: serial@fe531000 {
                i2c@fe541000 {
                        status = "okay";
                };
+
+               ethernet1: dwmac@fef08000 {
+                       status                  = "okay";
+                       phy-mode                = "rgmii-id";
+                       max-speed               = <1000>;
+                       st,tx-retime-src        = "clk_125";
+                       snps,reset-gpio         = <&PIO3 0>;
+                       snps,reset-active-low;
+                       snps,reset-delays-us    = <0 10000 10000>;
+
+                       pinctrl-0       = <&pinctrl_rgmii1>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/stih41x-b2020x.dtsi b/arch/arm/boot/dts/stih41x-b2020x.dtsi
new file mode 100644 (file)
index 0000000..df01c12
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Lee Jones <lee.jones@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+       soc {
+               spifsm: spifsm@fe902000 {
+                       #address-cells = <1>;
+                       #size-cells    = <1>;
+
+                       status = "okay";
+
+                       partition@0 {
+                               label = "SerialFlash1";
+                               reg   = <0x00000000 0x00500000>;
+                       };
+
+                       partition@500000 {
+                               label = "SerialFlash2";
+                               reg   = <0x00500000 0x00b00000>;
+                       };
+               };
+       };
+};
index d4b081d6a16772cbac6835abd4bec6c21753c3c1..fa746aea5e66397e5fc4b727e55a338bdc9df06a 100644 (file)
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 /include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Mele A1000";
                        };
                };
 
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ahci: sata@01c18000 {
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
                pinctrl@01c20800 {
                        emac_power_pin_a1000: emac_power_pin@0 {
                                allwinner,pins = "PH15";
                };
        };
 
-       regulators {
-               compatible = "simple-bus";
+       reg_emac_3v3: emac-3v3 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&emac_power_pin_a1000>;
+               regulator-name = "emac-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               gpio = <&pio 7 15 0>;
+       };
 
-               reg_emac_3v3: emac-3v3 {
-                       compatible = "regulator-fixed";
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&emac_power_pin_a1000>;
-                       regulator-name = "emac-3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       enable-active-high;
-                       gpio = <&pio 7 15 0>;
-               };
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
        };
 };
index b139ee6bcf99f422535899173f481777c7751541..4684cbe6843b4207d9aae236db50e647b3f25c65 100644 (file)
@@ -12,6 +12,7 @@
 
 /dts-v1/;
 /include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Cubietech Cubieboard";
                        };
                };
 
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ahci: sata@01c18000 {
+                       target-supply = <&reg_ahci_5v>;
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
                pinctrl@01c20800 {
                        led_pins_cubieboard: led_pins@0 {
                                allwinner,pins = "PH20", "PH21";
                        linux,default-trigger = "heartbeat";
                };
        };
+
+       reg_ahci_5v: ahci-5v {
+               status = "okay";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
 };
index 3a1595f67823c1999f2ea4c1929ed66fd46fe055..d7c17e46ce23096aafe13f88c7d480ebdea83d32 100644 (file)
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 /include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Miniand Hackberry";
                        };
                };
 
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
                pio: pinctrl@01c20800 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&hackberry_hogs>;
                                allwinner,drive = <0>;
                                allwinner,pull = <0>;
                        };
+
+                       usb2_vbus_pin_hackberry: usb2_vbus_pin@0 {
+                                       allwinner,pins = "PH12";
+                                       allwinner,function = "gpio_out";
+                                       allwinner,drive = <0>;
+                                       allwinner,pull = <0>;
+                       };
                };
 
                uart0: serial@01c28000 {
                };
        };
 
-       regulators {
-               compatible = "simple-bus";
+       reg_emac_3v3: emac-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "emac-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               gpio = <&pio 7 19 0>;
+       };
 
-               reg_emac_3v3: emac-3v3 {
-                       compatible = "regulator-fixed";
-                       regulator-name = "emac-3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       enable-active-high;
-                       gpio = <&pio 7 19 0>;
-               };
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               pinctrl-0 = <&usb2_vbus_pin_hackberry>;
+               gpio = <&pio 7 12 0>;
+               status = "okay";
        };
 };
diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
new file mode 100644 (file)
index 0000000..fe9272e
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014 Open Source Support GmbH
+ *
+ * David Lanzendörfer <david.lanzendoerfer@o2s.ch>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
+
+/ {
+       model = "INet-97F Rev 02";
+       compatible = "primux,inet97fv2", "allwinner,sun4i-a10";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       soc@01c00000 {
+               uart0: serial@01c28000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&uart0_pins_a>;
+                       status = "okay";
+               };
+
+               i2c0: i2c@01c2ac00 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c0_pins_a>;
+                       status = "okay";
+               };
+
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
+};
index 70b3323caf1ad071c6683d759b90955f6bb2b8c1..dd84a9e313b3e9f7ee9f52fce22fdf32d098d1c7 100644 (file)
 
 /dts-v1/;
 /include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "PineRiver Mini X-Plus";
        compatible = "pineriver,mini-xplus", "allwinner,sun4i-a10";
 
        soc@01c00000 {
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
                uart0: serial@01c28000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&uart0_pins_a>;
                        status = "okay";
                };
        };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
 };
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
new file mode 100644 (file)
index 0000000..66cf0c7
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
+
+/ {
+       model = "Olimex A10-OLinuXino-LIME";
+       compatible = "olimex,a10-olinuxino-lime", "allwinner,sun4i-a10";
+
+       soc@01c00000 {
+               emac: ethernet@01c0b000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&emac_pins_a>;
+                       phy = <&phy1>;
+                       status = "okay";
+               };
+
+               mdio@01c0b080 {
+                       status = "okay";
+
+                       phy1: ethernet-phy@1 {
+                               reg = <1>;
+                       };
+               };
+
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ahci: sata@01c18000 {
+                       target-supply = <&reg_ahci_5v>;
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
+               pinctrl@01c20800 {
+                       ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
+                               allwinner,pins = "PC3";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       led_pins_olinuxinolime: led_pins@0 {
+                               allwinner,pins = "PH2";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <1>;
+                               allwinner,pull = <0>;
+                       };
+               };
+
+               uart0: serial@01c28000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&uart0_pins_a>;
+                       status = "okay";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_olinuxinolime>;
+
+               green {
+                       label = "a10-olinuxino-lime:green:usr";
+                       gpios = <&pio 7 2 0>;
+                       default-state = "on";
+               };
+       };
+
+       reg_ahci_5v: ahci-5v {
+               pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
+               gpio = <&pio 2 3 0>;
+               status = "okay";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
new file mode 100644 (file)
index 0000000..255b47e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2014 Zoltan HERPAI
+ * Zoltan HERPAI <wigyori@uid0.hu>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun4i-a10.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
+
+/ {
+       model = "LinkSprite pcDuino";
+       compatible = "linksprite,a10-pcduino", "allwinner,sun4i-a10";
+
+       soc@01c00000 {
+               emac: ethernet@01c0b000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&emac_pins_a>;
+                       phy = <&phy1>;
+                       status = "okay";
+               };
+
+               mdio@01c0b080 {
+                       status = "okay";
+
+                       phy1: ethernet-phy@1 {
+                               reg = <1>;
+                       };
+               };
+
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
+               uart0: serial@01c28000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&uart0_pins_a>;
+                       status = "okay";
+               };
+
+               i2c0: i2c@01c2ac00 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c0_pins_a>;
+                       status = "okay";
+               };
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
+};
index 9321681cc45a393f8759dc54a2c430acf2c3d599..9174724571e24782a2a3ae57d40538e33890912e 100644 (file)
                ethernet0 = &emac;
                serial0 = &uart0;
                serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               serial5 = &uart5;
+               serial6 = &uart6;
+               serial7 = &uart7;
        };
 
        cpus {
                        clock-frequency = <0>;
                };
 
-               osc24M: osc24M@01c20050 {
+               osc24M: clk@01c20050 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-osc-clk";
+                       compatible = "allwinner,sun4i-a10-osc-clk";
                        reg = <0x01c20050 0x4>;
                        clock-frequency = <24000000>;
+                       clock-output-names = "osc24M";
                };
 
-               osc32k: osc32k {
+               osc32k: clk@0 {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
+                       clock-output-names = "osc32k";
                };
 
-               pll1: pll1@01c20000 {
+               pll1: clk@01c20000 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20000 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll1";
                };
 
-               pll4: pll4@01c20018 {
+               pll4: clk@01c20018 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20018 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll4";
                };
 
-               pll5: pll5@01c20020 {
+               pll5: clk@01c20020 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll5-clk";
+                       compatible = "allwinner,sun4i-a10-pll5-clk";
                        reg = <0x01c20020 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll5_ddr", "pll5_other";
                };
 
-               pll6: pll6@01c20028 {
+               pll6: clk@01c20028 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll6-clk";
+                       compatible = "allwinner,sun4i-a10-pll6-clk";
                        reg = <0x01c20028 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll6_sata", "pll6_other", "pll6";
                /* dummy is 200M */
                cpu: cpu@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-cpu-clk";
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+                       clock-output-names = "cpu";
                };
 
                axi: axi@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-axi-clk";
+                       compatible = "allwinner,sun4i-a10-axi-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&cpu>;
+                       clock-output-names = "axi";
                };
 
-               axi_gates: axi_gates@01c2005c {
+               axi_gates: clk@01c2005c {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-axi-gates-clk";
+                       compatible = "allwinner,sun4i-a10-axi-gates-clk";
                        reg = <0x01c2005c 0x4>;
                        clocks = <&axi>;
                        clock-output-names = "axi_dram";
 
                ahb: ahb@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-ahb-clk";
+                       compatible = "allwinner,sun4i-a10-ahb-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&axi>;
+                       clock-output-names = "ahb";
                };
 
-               ahb_gates: ahb_gates@01c20060 {
+               ahb_gates: clk@01c20060 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-ahb-gates-clk";
+                       compatible = "allwinner,sun4i-a10-ahb-gates-clk";
                        reg = <0x01c20060 0x8>;
                        clocks = <&ahb>;
                        clock-output-names = "ahb_usb0", "ahb_ehci0",
 
                apb0: apb0@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb0-clk";
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&ahb>;
+                       clock-output-names = "apb0";
                };
 
-               apb0_gates: apb0_gates@01c20068 {
+               apb0_gates: clk@01c20068 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-apb0-gates-clk";
+                       compatible = "allwinner,sun4i-a10-apb0-gates-clk";
                        reg = <0x01c20068 0x4>;
                        clocks = <&apb0>;
                        clock-output-names = "apb0_codec", "apb0_spdif",
 
                apb1_mux: apb1_mux@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-mux-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+                       clock-output-names = "apb1_mux";
                };
 
                apb1: apb1@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&apb1_mux>;
+                       clock-output-names = "apb1";
                };
 
-               apb1_gates: apb1_gates@01c2006c {
+               apb1_gates: clk@01c2006c {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-apb1-gates-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-gates-clk";
                        reg = <0x01c2006c 0x4>;
                        clocks = <&apb1>;
                        clock-output-names = "apb1_i2c0", "apb1_i2c1",
 
                nand_clk: clk@01c20080 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20080 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "nand";
 
                ms_clk: clk@01c20084 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20084 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ms";
 
                mmc0_clk: clk@01c20088 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc0";
 
                mmc1_clk: clk@01c2008c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc1";
 
                mmc2_clk: clk@01c20090 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc2";
 
                mmc3_clk: clk@01c20094 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20094 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc3";
 
                ts_clk: clk@01c20098 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20098 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ts";
 
                ss_clk: clk@01c2009c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2009c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ss";
 
                spi0_clk: clk@01c200a0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi0";
 
                spi1_clk: clk@01c200a4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi1";
 
                spi2_clk: clk@01c200a8 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a8 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi2";
 
                pata_clk: clk@01c200ac {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200ac 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "pata";
 
                ir0_clk: clk@01c200b0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200b0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ir0";
 
                ir1_clk: clk@01c200b4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200b4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ir1";
                };
 
+               usb_clk: clk@01c200cc {
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-usb-clk";
+                       reg = <0x01c200cc 0x4>;
+                       clocks = <&pll6 1>;
+                       clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+               };
+
                spi3_clk: clk@01c200d4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200d4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi3";
                #size-cells = <1>;
                ranges;
 
+               spi0: spi@01c05000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c05000 0x1000>;
+                       interrupts = <10>;
+                       clocks = <&ahb_gates 20>, <&spi0_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi1: spi@01c06000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c06000 0x1000>;
+                       interrupts = <11>;
+                       clocks = <&ahb_gates 21>, <&spi1_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                emac: ethernet@01c0b000 {
                        compatible = "allwinner,sun4i-a10-emac";
                        reg = <0x01c0b000 0x1000>;
                        #size-cells = <0>;
                };
 
+               usbphy: phy@01c13400 {
+                       #phy-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-usb-phy";
+                       reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;
+                       reg-names = "phy_ctrl", "pmu1", "pmu2";
+                       clocks = <&usb_clk 8>;
+                       clock-names = "usb_phy";
+                       resets = <&usb_clk 1>, <&usb_clk 2>;
+                       reset-names = "usb1_reset", "usb2_reset";
+                       status = "disabled";
+               };
+
+               ehci0: usb@01c14000 {
+                       compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
+                       reg = <0x01c14000 0x100>;
+                       interrupts = <39>;
+                       clocks = <&ahb_gates 1>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci0: usb@01c14400 {
+                       compatible = "allwinner,sun4i-a10-ohci", "generic-ohci";
+                       reg = <0x01c14400 0x100>;
+                       interrupts = <64>;
+                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi2: spi@01c17000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c17000 0x1000>;
+                       interrupts = <12>;
+                       clocks = <&ahb_gates 22>, <&spi2_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               ahci: sata@01c18000 {
+                       compatible = "allwinner,sun4i-a10-ahci";
+                       reg = <0x01c18000 0x1000>;
+                       interrupts = <56>;
+                       clocks = <&pll6 0>, <&ahb_gates 25>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@01c1c000 {
+                       compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
+                       reg = <0x01c1c000 0x100>;
+                       interrupts = <40>;
+                       clocks = <&ahb_gates 3>;
+                       phys = <&usbphy 2>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci1: usb@01c1c400 {
+                       compatible = "allwinner,sun4i-a10-ohci", "generic-ohci";
+                       reg = <0x01c1c400 0x100>;
+                       interrupts = <65>;
+                       clocks = <&usb_clk 7>, <&ahb_gates 4>;
+                       phys = <&usbphy 2>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi3: spi@01c1f000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c1f000 0x1000>;
+                       interrupts = <50>;
+                       clocks = <&ahb_gates 23>, <&spi3_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                intc: interrupt-controller@01c20400 {
                        compatible = "allwinner,sun4i-a10-ic";
                        reg = <0x01c20400 0x400>;
                };
 
                wdt: watchdog@01c20c90 {
-                       compatible = "allwinner,sun4i-wdt";
+                       compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
                };
 
index 3c9f8b3cd3e3cf44e0d0bdd13be5444e437a2fea..23611b71d3aa65736b0419abaafe0a93491e2907 100644 (file)
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 /include/ "sun5i-a10s.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Olimex A10s-Olinuxino Micro";
                        };
                };
 
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
                pinctrl@01c20800 {
                        led_pins_olinuxino: led_pins@0 {
                                allwinner,pins = "PE3";
                                allwinner,drive = <1>;
                                allwinner,pull = <0>;
                        };
+
+                       usb1_vbus_pin_olinuxino_m: usb1_vbus_pin@0 {
+                               allwinner,pins = "PB10";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
                };
 
                uart0: serial@01c28000 {
                        default-state = "on";
                };
        };
+
+       reg_usb1_vbus: usb1-vbus {
+               pinctrl-0 = <&usb1_vbus_pin_olinuxino_m>;
+               gpio = <&pio 1 10 0>;
+               status = "okay";
+       };
 };
index ee17b1c379e319fb852cc47099abe8ca2a61af83..79989ed5658d570b36626d871ba6ee2cd083db6e 100644 (file)
 
        aliases {
                ethernet0 = &emac;
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
        };
 
        cpus {
                        clock-frequency = <0>;
                };
 
-               osc24M: osc24M@01c20050 {
+               osc24M: clk@01c20050 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-osc-clk";
+                       compatible = "allwinner,sun4i-a10-osc-clk";
                        reg = <0x01c20050 0x4>;
                        clock-frequency = <24000000>;
+                       clock-output-names = "osc24M";
                };
 
-               osc32k: osc32k {
+               osc32k: clk@0 {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
+                       clock-output-names = "osc32k";
                };
 
-               pll1: pll1@01c20000 {
+               pll1: clk@01c20000 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20000 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll1";
                };
 
-               pll4: pll4@01c20018 {
+               pll4: clk@01c20018 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20018 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll4";
                };
 
-               pll5: pll5@01c20020 {
+               pll5: clk@01c20020 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll5-clk";
+                       compatible = "allwinner,sun4i-a10-pll5-clk";
                        reg = <0x01c20020 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll5_ddr", "pll5_other";
                };
 
-               pll6: pll6@01c20028 {
+               pll6: clk@01c20028 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll6-clk";
+                       compatible = "allwinner,sun4i-a10-pll6-clk";
                        reg = <0x01c20028 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll6_sata", "pll6_other", "pll6";
                /* dummy is 200M */
                cpu: cpu@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-cpu-clk";
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+                       clock-output-names = "cpu";
                };
 
                axi: axi@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-axi-clk";
+                       compatible = "allwinner,sun4i-a10-axi-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&cpu>;
+                       clock-output-names = "axi";
                };
 
-               axi_gates: axi_gates@01c2005c {
+               axi_gates: clk@01c2005c {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-axi-gates-clk";
+                       compatible = "allwinner,sun4i-a10-axi-gates-clk";
                        reg = <0x01c2005c 0x4>;
                        clocks = <&axi>;
                        clock-output-names = "axi_dram";
 
                ahb: ahb@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-ahb-clk";
+                       compatible = "allwinner,sun4i-a10-ahb-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&axi>;
+                       clock-output-names = "ahb";
                };
 
-               ahb_gates: ahb_gates@01c20060 {
+               ahb_gates: clk@01c20060 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun5i-a10s-ahb-gates-clk";
                        reg = <0x01c20060 0x8>;
 
                apb0: apb0@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb0-clk";
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&ahb>;
+                       clock-output-names = "apb0";
                };
 
-               apb0_gates: apb0_gates@01c20068 {
+               apb0_gates: clk@01c20068 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun5i-a10s-apb0-gates-clk";
                        reg = <0x01c20068 0x4>;
 
                apb1_mux: apb1_mux@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-mux-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+                       clock-output-names = "apb1_mux";
                };
 
                apb1: apb1@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&apb1_mux>;
+                       clock-output-names = "apb1";
                };
 
-               apb1_gates: apb1_gates@01c2006c {
+               apb1_gates: clk@01c2006c {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun5i-a10s-apb1-gates-clk";
                        reg = <0x01c2006c 0x4>;
 
                nand_clk: clk@01c20080 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20080 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "nand";
 
                ms_clk: clk@01c20084 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20084 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ms";
 
                mmc0_clk: clk@01c20088 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc0";
 
                mmc1_clk: clk@01c2008c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc1";
 
                mmc2_clk: clk@01c20090 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc2";
 
                ts_clk: clk@01c20098 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20098 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ts";
 
                ss_clk: clk@01c2009c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2009c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ss";
 
                spi0_clk: clk@01c200a0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi0";
 
                spi1_clk: clk@01c200a4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi1";
 
                spi2_clk: clk@01c200a8 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a8 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi2";
 
                ir0_clk: clk@01c200b0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200b0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ir0";
                };
 
+               usb_clk: clk@01c200cc {
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-usb-clk";
+                       reg = <0x01c200cc 0x4>;
+                       clocks = <&pll6 1>;
+                       clock-output-names = "usb_ohci0", "usb_phy";
+               };
+
                mbus_clk: clk@01c2015c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2015c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mbus";
                #size-cells = <1>;
                ranges;
 
+               spi0: spi@01c05000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c05000 0x1000>;
+                       interrupts = <10>;
+                       clocks = <&ahb_gates 20>, <&spi0_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi1: spi@01c06000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c06000 0x1000>;
+                       interrupts = <11>;
+                       clocks = <&ahb_gates 21>, <&spi1_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                emac: ethernet@01c0b000 {
                        compatible = "allwinner,sun4i-a10-emac";
                        reg = <0x01c0b000 0x1000>;
                        #size-cells = <0>;
                };
 
+               usbphy: phy@01c13400 {
+                       #phy-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-usb-phy";
+                       reg = <0x01c13400 0x10 0x01c14800 0x4>;
+                       reg-names = "phy_ctrl", "pmu1";
+                       clocks = <&usb_clk 8>;
+                       clock-names = "usb_phy";
+                       resets = <&usb_clk 1>;
+                       reset-names = "usb1_reset";
+                       status = "disabled";
+               };
+
+               ehci0: usb@01c14000 {
+                       compatible = "allwinner,sun5i-a10s-ehci", "generic-ehci";
+                       reg = <0x01c14000 0x100>;
+                       interrupts = <39>;
+                       clocks = <&ahb_gates 1>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci0: usb@01c14400 {
+                       compatible = "allwinner,sun5i-a10s-ohci", "generic-ohci";
+                       reg = <0x01c14400 0x100>;
+                       interrupts = <40>;
+                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi2: spi@01c17000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c17000 0x1000>;
+                       interrupts = <12>;
+                       clocks = <&ahb_gates 22>, <&spi2_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                intc: interrupt-controller@01c20400 {
                        compatible = "allwinner,sun4i-a10-ic";
                        reg = <0x01c20400 0x400>;
                };
 
                wdt: watchdog@01c20c90 {
-                       compatible = "allwinner,sun4i-wdt";
+                       compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
                };
 
index fe2ce0acdb06bb055ec7561bd29eb62e1e8e5ffd..11169d5b5b86af143ed554b3617aba22bd4e3d50 100644 (file)
 
 /dts-v1/;
 /include/ "sun5i-a13.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Olimex A13-Olinuxino Micro";
        compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
 
        soc@01c00000 {
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
                pinctrl@01c20800 {
                        led_pins_olinuxinom: led_pins@0 {
                                allwinner,pins = "PG9";
                                allwinner,drive = <1>;
                                allwinner,pull = <0>;
                        };
+
+                       usb1_vbus_pin_olinuxinom: usb1_vbus_pin@0 {
+                               allwinner,pins = "PG11";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
                };
 
                uart1: serial@01c28400 {
                        default-state = "on";
                };
        };
+
+       reg_usb1_vbus: usb1-vbus {
+               pinctrl-0 = <&usb1_vbus_pin_olinuxinom>;
+               gpio = <&pio 6 11 0>;
+               status = "okay";
+       };
 };
index a4ba5ff010cf78b96f9f357c9c4e637a9720171b..7a9187bbeb28fd6574ede79d7e74f4f928d96a9a 100644 (file)
 
 /dts-v1/;
 /include/ "sun5i-a13.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Olimex A13-Olinuxino";
        compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13";
 
        soc@01c00000 {
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
                pinctrl@01c20800 {
                        led_pins_olinuxino: led_pins@0 {
                                allwinner,pins = "PG9";
                                allwinner,drive = <1>;
                                allwinner,pull = <0>;
                        };
+
+                       usb1_vbus_pin_olinuxino: usb1_vbus_pin@0 {
+                               allwinner,pins = "PG11";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
                };
 
                uart1: serial@01c28400 {
                        default-state = "on";
                };
        };
+
+       reg_usb1_vbus: usb1-vbus {
+               pinctrl-0 = <&usb1_vbus_pin_olinuxino>;
+               gpio = <&pio 6 11 0>;
+               status = "okay";
+       };
 };
index 3490ef9ec6034b8d4fb0a100bca11152f1a5133d..f01c315bdc4b0e1a37b34e4456ef95fb92f01352 100644 (file)
 / {
        interrupt-parent = <&intc>;
 
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart3;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        clock-frequency = <0>;
                };
 
-               osc24M: osc24M@01c20050 {
+               osc24M: clk@01c20050 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-osc-clk";
+                       compatible = "allwinner,sun4i-a10-osc-clk";
                        reg = <0x01c20050 0x4>;
                        clock-frequency = <24000000>;
+                       clock-output-names = "osc24M";
                };
 
-               osc32k: osc32k {
+               osc32k: clk@0 {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
+                       clock-output-names = "osc32k";
                };
 
-               pll1: pll1@01c20000 {
+               pll1: clk@01c20000 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20000 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll1";
                };
 
-               pll4: pll4@01c20018 {
+               pll4: clk@01c20018 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20018 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll4";
                };
 
-               pll5: pll5@01c20020 {
+               pll5: clk@01c20020 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll5-clk";
+                       compatible = "allwinner,sun4i-a10-pll5-clk";
                        reg = <0x01c20020 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll5_ddr", "pll5_other";
                };
 
-               pll6: pll6@01c20028 {
+               pll6: clk@01c20028 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll6-clk";
+                       compatible = "allwinner,sun4i-a10-pll6-clk";
                        reg = <0x01c20028 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll6_sata", "pll6_other", "pll6";
                /* dummy is 200M */
                cpu: cpu@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-cpu-clk";
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+                       clock-output-names = "cpu";
                };
 
                axi: axi@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-axi-clk";
+                       compatible = "allwinner,sun4i-a10-axi-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&cpu>;
+                       clock-output-names = "axi";
                };
 
-               axi_gates: axi_gates@01c2005c {
+               axi_gates: clk@01c2005c {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-axi-gates-clk";
+                       compatible = "allwinner,sun4i-a10-axi-gates-clk";
                        reg = <0x01c2005c 0x4>;
                        clocks = <&axi>;
                        clock-output-names = "axi_dram";
 
                ahb: ahb@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-ahb-clk";
+                       compatible = "allwinner,sun4i-a10-ahb-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&axi>;
+                       clock-output-names = "ahb";
                };
 
-               ahb_gates: ahb_gates@01c20060 {
+               ahb_gates: clk@01c20060 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun5i-a13-ahb-gates-clk";
                        reg = <0x01c20060 0x8>;
 
                apb0: apb0@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb0-clk";
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&ahb>;
+                       clock-output-names = "apb0";
                };
 
-               apb0_gates: apb0_gates@01c20068 {
+               apb0_gates: clk@01c20068 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun5i-a13-apb0-gates-clk";
                        reg = <0x01c20068 0x4>;
 
                apb1_mux: apb1_mux@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-mux-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+                       clock-output-names = "apb1_mux";
                };
 
                apb1: apb1@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&apb1_mux>;
+                       clock-output-names = "apb1";
                };
 
-               apb1_gates: apb1_gates@01c2006c {
+               apb1_gates: clk@01c2006c {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun5i-a13-apb1-gates-clk";
                        reg = <0x01c2006c 0x4>;
 
                nand_clk: clk@01c20080 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20080 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "nand";
 
                ms_clk: clk@01c20084 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20084 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ms";
 
                mmc0_clk: clk@01c20088 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc0";
 
                mmc1_clk: clk@01c2008c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc1";
 
                mmc2_clk: clk@01c20090 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc2";
 
                ts_clk: clk@01c20098 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20098 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ts";
 
                ss_clk: clk@01c2009c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2009c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ss";
 
                spi0_clk: clk@01c200a0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi0";
 
                spi1_clk: clk@01c200a4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi1";
 
                spi2_clk: clk@01c200a8 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a8 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi2";
 
                ir0_clk: clk@01c200b0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200b0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ir0";
                };
 
+               usb_clk: clk@01c200cc {
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-usb-clk";
+                       reg = <0x01c200cc 0x4>;
+                       clocks = <&pll6 1>;
+                       clock-output-names = "usb_ohci0", "usb_phy";
+               };
+
                mbus_clk: clk@01c2015c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2015c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mbus";
                #size-cells = <1>;
                ranges;
 
+               spi0: spi@01c05000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c05000 0x1000>;
+                       interrupts = <10>;
+                       clocks = <&ahb_gates 20>, <&spi0_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi1: spi@01c06000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c06000 0x1000>;
+                       interrupts = <11>;
+                       clocks = <&ahb_gates 21>, <&spi1_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               usbphy: phy@01c13400 {
+                       #phy-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-usb-phy";
+                       reg = <0x01c13400 0x10 0x01c14800 0x4>;
+                       reg-names = "phy_ctrl", "pmu1";
+                       clocks = <&usb_clk 8>;
+                       clock-names = "usb_phy";
+                       resets = <&usb_clk 1>;
+                       reset-names = "usb1_reset";
+                       status = "disabled";
+               };
+
+               ehci0: usb@01c14000 {
+                       compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
+                       reg = <0x01c14000 0x100>;
+                       interrupts = <39>;
+                       clocks = <&ahb_gates 1>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci0: usb@01c14400 {
+                       compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
+                       reg = <0x01c14400 0x100>;
+                       interrupts = <40>;
+                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi2: spi@01c17000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c17000 0x1000>;
+                       interrupts = <12>;
+                       clocks = <&ahb_gates 22>, <&spi2_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                intc: interrupt-controller@01c20400 {
                        compatible = "allwinner,sun4i-a10-ic";
                        reg = <0x01c20400 0x400>;
                };
 
                wdt: watchdog@01c20c90 {
-                       compatible = "allwinner,sun4i-wdt";
+                       compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
                };
 
index e5adae30899b5617ecfefe23d4ff3ad6243cd0f6..3898a7bce8317906054c3662c182e48dc9b6b9ff 100644 (file)
                        pinctrl-0 = <&uart0_pins_a>;
                        status = "okay";
                };
+
+               i2c0: i2c@01c2ac00 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c0_pins_a>;
+                       status = "fail";
+               };
+
+               i2c1: i2c@01c2b000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c1_pins_a>;
+                       status = "okay";
+               };
+
+               i2c2: i2c@01c2b400 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c2_pins_a>;
+                       status = "okay";
+               };
        };
 };
index 38d43febda4c0f2721c249fe89ea69a4bc6ca63b..d45efa74827cb542655bf618b9b24d2d4c178c01 100644 (file)
 / {
        interrupt-parent = <&gic>;
 
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               serial5 = &uart5;
+       };
+
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        clock-frequency = <24000000>;
                };
 
-               osc32k: osc32k {
+               osc32k: clk@0 {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
+                       clock-output-names = "osc32k";
                };
 
-               pll1: pll1@01c20000 {
+               pll1: clk@01c20000 {
                        #clock-cells = <0>;
                        compatible = "allwinner,sun6i-a31-pll1-clk";
                        reg = <0x01c20000 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll1";
                };
 
-               /*
-                * This is a dummy clock, to be used as placeholder on
-                * other mux clocks when a specific parent clock is not
-                * yet implemented. It should be dropped when the driver
-                * is complete.
-                */
-               pll6: pll6 {
+               pll6: clk@01c20028 {
                        #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <0>;
+                       compatible = "allwinner,sun6i-a31-pll6-clk";
+                       reg = <0x01c20028 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll6";
                };
 
                cpu: cpu@01c20050 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-cpu-clk";
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
                        reg = <0x01c20050 0x4>;
 
                        /*
                         * Allwinner.
                         */
                        clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+                       clock-output-names = "cpu";
                };
 
                axi: axi@01c20050 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-axi-clk";
+                       compatible = "allwinner,sun4i-a10-axi-clk";
                        reg = <0x01c20050 0x4>;
                        clocks = <&cpu>;
+                       clock-output-names = "axi";
                };
 
                ahb1_mux: ahb1_mux@01c20054 {
                        compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>;
+                       clock-output-names = "ahb1_mux";
                };
 
                ahb1: ahb1@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-ahb-clk";
+                       compatible = "allwinner,sun4i-a10-ahb-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&ahb1_mux>;
+                       clock-output-names = "ahb1";
                };
 
-               ahb1_gates: ahb1_gates@01c20060 {
+               ahb1_gates: clk@01c20060 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun6i-a31-ahb1-gates-clk";
                        reg = <0x01c20060 0x8>;
 
                apb1: apb1@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb0-clk";
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&ahb1>;
+                       clock-output-names = "apb1";
                };
 
-               apb1_gates: apb1_gates@01c20060 {
+               apb1_gates: clk@01c20068 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun6i-a31-apb1-gates-clk";
                        reg = <0x01c20068 0x4>;
 
                apb2_mux: apb2_mux@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-mux-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>;
+                       clock-output-names = "apb2_mux";
                };
 
                apb2: apb2@01c20058 {
                        compatible = "allwinner,sun6i-a31-apb2-div-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&apb2_mux>;
+                       clock-output-names = "apb2";
                };
 
-               apb2_gates: apb2_gates@01c2006c {
+               apb2_gates: clk@01c2006c {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun6i-a31-apb2-gates-clk";
                        reg = <0x01c2006c 0x4>;
                                        "apb2_uart1", "apb2_uart2", "apb2_uart3",
                                        "apb2_uart4", "apb2_uart5";
                };
+
+               spi0_clk: clk@01c200a0 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200a0 0x4>;
+                       clocks = <&osc24M>, <&pll6>;
+                       clock-output-names = "spi0";
+               };
+
+               spi1_clk: clk@01c200a4 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200a4 0x4>;
+                       clocks = <&osc24M>, <&pll6>;
+                       clock-output-names = "spi1";
+               };
+
+               spi2_clk: clk@01c200a8 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200a8 0x4>;
+                       clocks = <&osc24M>, <&pll6>;
+                       clock-output-names = "spi2";
+               };
+
+               spi3_clk: clk@01c200ac {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200ac 0x4>;
+                       clocks = <&osc24M>, <&pll6>;
+                       clock-output-names = "spi3";
+               };
        };
 
        soc@01c00000 {
                                allwinner,drive = <0>;
                                allwinner,pull = <0>;
                        };
+
+                       i2c0_pins_a: i2c0@0 {
+                               allwinner,pins = "PH14", "PH15";
+                               allwinner,function = "i2c0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       i2c1_pins_a: i2c1@0 {
+                               allwinner,pins = "PH16", "PH17";
+                               allwinner,function = "i2c1";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       i2c2_pins_a: i2c2@0 {
+                               allwinner,pins = "PH18", "PH19";
+                               allwinner,function = "i2c2";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
                };
 
                ahb1_rst: reset@01c202c0 {
                };
 
                wdt1: watchdog@01c20ca0 {
-                       compatible = "allwinner,sun6i-wdt";
+                       compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
                };
 
                        status = "disabled";
                };
 
+               i2c0: i2c@01c2ac00 {
+                       compatible = "allwinner,sun6i-a31-i2c";
+                       reg = <0x01c2ac00 0x400>;
+                       interrupts = <0 6 4>;
+                       clocks = <&apb2_gates 0>;
+                       clock-frequency = <100000>;
+                       resets = <&apb2_rst 0>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@01c2b000 {
+                       compatible = "allwinner,sun6i-a31-i2c";
+                       reg = <0x01c2b000 0x400>;
+                       interrupts = <0 7 4>;
+                       clocks = <&apb2_gates 1>;
+                       clock-frequency = <100000>;
+                       resets = <&apb2_rst 1>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@01c2b400 {
+                       compatible = "allwinner,sun6i-a31-i2c";
+                       reg = <0x01c2b400 0x400>;
+                       interrupts = <0 8 4>;
+                       clocks = <&apb2_gates 2>;
+                       clock-frequency = <100000>;
+                       resets = <&apb2_rst 2>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@01c2b800 {
+                       compatible = "allwinner,sun6i-a31-i2c";
+                       reg = <0x01c2b800 0x400>;
+                       interrupts = <0 9 4>;
+                       clocks = <&apb2_gates 3>;
+                       clock-frequency = <100000>;
+                       resets = <&apb2_rst 3>;
+                       status = "disabled";
+               };
+
+               spi0: spi@01c68000 {
+                       compatible = "allwinner,sun6i-a31-spi";
+                       reg = <0x01c68000 0x1000>;
+                       interrupts = <0 65 4>;
+                       clocks = <&ahb1_gates 20>, <&spi0_clk>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ahb1_rst 20>;
+                       status = "disabled";
+               };
+
+               spi1: spi@01c69000 {
+                       compatible = "allwinner,sun6i-a31-spi";
+                       reg = <0x01c69000 0x1000>;
+                       interrupts = <0 66 4>;
+                       clocks = <&ahb1_gates 21>, <&spi1_clk>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ahb1_rst 21>;
+                       status = "disabled";
+               };
+
+               spi2: spi@01c6a000 {
+                       compatible = "allwinner,sun6i-a31-spi";
+                       reg = <0x01c6a000 0x1000>;
+                       interrupts = <0 67 4>;
+                       clocks = <&ahb1_gates 22>, <&spi2_clk>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ahb1_rst 22>;
+                       status = "disabled";
+               };
+
+               spi3: spi@01c6b000 {
+                       compatible = "allwinner,sun6i-a31-spi";
+                       reg = <0x01c6b000 0x1000>;
+                       interrupts = <0 68 4>;
+                       clocks = <&ahb1_gates 23>, <&spi3_clk>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ahb1_rst 23>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@01c81000 {
                        compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
                        reg = <0x01c81000 0x1000>,
index 5c51cb8a98b01bb49b7c189474eef501f6c864b5..68de89ffbdfad7cca723fd53fe7c3d280b09046a 100644 (file)
 
 /dts-v1/;
 /include/ "sun7i-a20.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Cubietech Cubieboard2";
        compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20";
 
        soc@01c00000 {
-               emac: ethernet@01c0b000 {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&emac_pins_a>;
-                       phy = <&phy1>;
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
                        status = "okay";
                };
 
-               mdio@01c0b080 {
+               ehci0: usb@01c14000 {
                        status = "okay";
+               };
 
-                       phy1: ethernet-phy@1 {
-                               reg = <1>;
-                       };
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ahci: sata@01c18000 {
+                       target-supply = <&reg_ahci_5v>;
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
                };
 
                pinctrl@01c20800 {
                        pinctrl-0 = <&i2c1_pins_a>;
                        status = "okay";
                };
+
+               gmac: ethernet@01c50000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gmac_pins_mii_a>;
+                       phy = <&phy1>;
+                       phy-mode = "mii";
+                       status = "okay";
+
+                       phy1: ethernet-phy@1 {
+                               reg = <1>;
+                       };
+               };
        };
 
        leds {
                        gpios = <&pio 7 20 0>;
                };
        };
+
+       reg_ahci_5v: ahci-5v {
+               status = "okay";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
 };
index f9dcb61a5305b08b8ef1c50352401bc2e9ba9487..cb25d3c8da5833bae48d777325be4081b11bedb8 100644 (file)
 
 /dts-v1/;
 /include/ "sun7i-a20.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Cubietech Cubietruck";
        compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
 
        soc@01c00000 {
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               ahci: sata@01c18000 {
+                       target-supply = <&reg_ahci_5v>;
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
+               };
+
                pinctrl@01c20800 {
+                       ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 {
+                               allwinner,pins = "PH12";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
                        led_pins_cubietruck: led_pins@0 {
                                allwinner,pins = "PH7", "PH11", "PH20", "PH21";
                                allwinner,function = "gpio_out";
                        pinctrl-0 = <&i2c2_pins_a>;
                        status = "okay";
                };
+
+               gmac: ethernet@01c50000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gmac_pins_rgmii_a>;
+                       phy = <&phy1>;
+                       phy-mode = "rgmii";
+                       status = "okay";
+
+                       phy1: ethernet-phy@1 {
+                               reg = <1>;
+                       };
+               };
        };
 
        leds {
                        gpios = <&pio 7 7 0>;
                };
        };
+
+       reg_ahci_5v: ahci-5v {
+               pinctrl-0 = <&ahci_pwr_pin_cubietruck>;
+               gpio = <&pio 7 12 0>;
+               status = "okay";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
 };
index ead3013f9aca9db6a3a5e73b0539ba3698139784..eeadf76362fa4238875bc83f6b0853edbba9c5c6 100644 (file)
 
 /dts-v1/;
 /include/ "sun7i-a20.dtsi"
+/include/ "sunxi-common-regulators.dtsi"
 
 / {
        model = "Olimex A20-Olinuxino Micro";
        compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20";
 
+       aliases {
+               spi0 = &spi1;
+               spi1 = &spi2;
+       };
+
        soc@01c00000 {
-               emac: ethernet@01c0b000 {
+               spi1: spi@01c06000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&emac_pins_a>;
-                       phy = <&phy1>;
+                       pinctrl-0 = <&spi1_pins_a>;
                        status = "okay";
                };
 
-               mdio@01c0b080 {
+               usbphy: phy@01c13400 {
+                       usb1_vbus-supply = <&reg_usb1_vbus>;
+                       usb2_vbus-supply = <&reg_usb2_vbus>;
                        status = "okay";
+               };
 
-                       phy1: ethernet-phy@1 {
-                               reg = <1>;
-                       };
+               ehci0: usb@01c14000 {
+                       status = "okay";
+               };
+
+               ohci0: usb@01c14400 {
+                       status = "okay";
+               };
+
+               spi2: spi@01c17000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&spi2_pins_a>;
+                       status = "okay";
+               };
+
+               ahci: sata@01c18000 {
+                       target-supply = <&reg_ahci_5v>;
+                       status = "okay";
+               };
+
+               ehci1: usb@01c1c000 {
+                       status = "okay";
+               };
+
+               ohci1: usb@01c1c400 {
+                       status = "okay";
                };
 
                pinctrl@01c20800 {
                        pinctrl-0 = <&i2c2_pins_a>;
                        status = "okay";
                };
+
+               gmac: ethernet@01c50000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gmac_pins_mii_a>;
+                       phy = <&phy1>;
+                       phy-mode = "mii";
+                       status = "okay";
+
+                       phy1: ethernet-phy@1 {
+                               reg = <1>;
+                       };
+               };
        };
 
        leds {
                        default-state = "on";
                };
        };
+
+       reg_ahci_5v: ahci-5v {
+               status = "okay";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               status = "okay";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               status = "okay";
+       };
 };
index cadcf2f9881d460fd9fbdc6e40d072a8610bf8d6..32efc105df834de3c3143938bf0cfdebbf5d1b55 100644 (file)
        interrupt-parent = <&gic>;
 
        aliases {
-               ethernet0 = &emac;
+               ethernet0 = &gmac;
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               serial5 = &uart5;
+               serial6 = &uart6;
+               serial7 = &uart7;
        };
 
        cpus {
                reg = <0x40000000 0x80000000>;
        };
 
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <1 13 0xf08>,
+                            <1 14 0xf08>,
+                            <1 11 0xf08>,
+                            <1 10 0xf08>;
+       };
+
        clocks {
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
 
-               osc24M: osc24M@01c20050 {
+               osc24M: clk@01c20050 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-osc-clk";
+                       compatible = "allwinner,sun4i-a10-osc-clk";
                        reg = <0x01c20050 0x4>;
                        clock-frequency = <24000000>;
+                       clock-output-names = "osc24M";
                };
 
                osc32k: clk@0 {
                        clock-output-names = "osc32k";
                };
 
-               pll1: pll1@01c20000 {
+               pll1: clk@01c20000 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20000 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll1";
                };
 
-               pll4: pll4@01c20018 {
+               pll4: clk@01c20018 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-pll1-clk";
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
                        reg = <0x01c20018 0x4>;
                        clocks = <&osc24M>;
+                       clock-output-names = "pll4";
                };
 
-               pll5: pll5@01c20020 {
+               pll5: clk@01c20020 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll5-clk";
+                       compatible = "allwinner,sun4i-a10-pll5-clk";
                        reg = <0x01c20020 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll5_ddr", "pll5_other";
                };
 
-               pll6: pll6@01c20028 {
+               pll6: clk@01c20028 {
                        #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-pll6-clk";
+                       compatible = "allwinner,sun4i-a10-pll6-clk";
                        reg = <0x01c20028 0x4>;
                        clocks = <&osc24M>;
                        clock-output-names = "pll6_sata", "pll6_other", "pll6";
 
                cpu: cpu@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-cpu-clk";
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>;
+                       clock-output-names = "cpu";
                };
 
                axi: axi@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-axi-clk";
+                       compatible = "allwinner,sun4i-a10-axi-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&cpu>;
+                       clock-output-names = "axi";
                };
 
                ahb: ahb@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-ahb-clk";
+                       compatible = "allwinner,sun4i-a10-ahb-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&axi>;
+                       clock-output-names = "ahb";
                };
 
-               ahb_gates: ahb_gates@01c20060 {
+               ahb_gates: clk@01c20060 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun7i-a20-ahb-gates-clk";
                        reg = <0x01c20060 0x8>;
 
                apb0: apb0@01c20054 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb0-clk";
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
                        reg = <0x01c20054 0x4>;
                        clocks = <&ahb>;
+                       clock-output-names = "apb0";
                };
 
-               apb0_gates: apb0_gates@01c20068 {
+               apb0_gates: clk@01c20068 {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun7i-a20-apb0-gates-clk";
                        reg = <0x01c20068 0x4>;
 
                apb1_mux: apb1_mux@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-mux-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+                       clock-output-names = "apb1_mux";
                };
 
                apb1: apb1@01c20058 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-apb1-clk";
+                       compatible = "allwinner,sun4i-a10-apb1-clk";
                        reg = <0x01c20058 0x4>;
                        clocks = <&apb1_mux>;
+                       clock-output-names = "apb1";
                };
 
-               apb1_gates: apb1_gates@01c2006c {
+               apb1_gates: clk@01c2006c {
                        #clock-cells = <1>;
                        compatible = "allwinner,sun7i-a20-apb1-gates-clk";
                        reg = <0x01c2006c 0x4>;
 
                nand_clk: clk@01c20080 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20080 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "nand";
 
                ms_clk: clk@01c20084 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20084 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ms";
 
                mmc0_clk: clk@01c20088 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20088 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc0";
 
                mmc1_clk: clk@01c2008c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2008c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc1";
 
                mmc2_clk: clk@01c20090 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20090 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc2";
 
                mmc3_clk: clk@01c20094 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20094 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "mmc3";
 
                ts_clk: clk@01c20098 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c20098 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ts";
 
                ss_clk: clk@01c2009c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2009c 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ss";
 
                spi0_clk: clk@01c200a0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi0";
 
                spi1_clk: clk@01c200a4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi1";
 
                spi2_clk: clk@01c200a8 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200a8 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi2";
 
                pata_clk: clk@01c200ac {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200ac 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "pata";
 
                ir0_clk: clk@01c200b0 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200b0 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ir0";
 
                ir1_clk: clk@01c200b4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200b4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "ir1";
                };
 
+               usb_clk: clk@01c200cc {
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-usb-clk";
+                       reg = <0x01c200cc 0x4>;
+                       clocks = <&pll6 1>;
+                       clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+               };
+
                spi3_clk: clk@01c200d4 {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c200d4 0x4>;
                        clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
                        clock-output-names = "spi3";
 
                mbus_clk: clk@01c2015c {
                        #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-mod0-clk";
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
                        reg = <0x01c2015c 0x4>;
                        clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
                        clock-output-names = "mbus";
                };
 
+               /*
+                * The following two are dummy clocks, placeholders used in the gmac_tx
+                * clock. The gmac driver will choose one parent depending on the PHY
+                * interface mode, using clk_set_rate auto-reparenting.
+                * The actual TX clock rate is not controlled by the gmac_tx clock.
+                */
+               mii_phy_tx_clk: clk@2 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <25000000>;
+                       clock-output-names = "mii_phy_tx";
+               };
+
+               gmac_int_tx_clk: clk@3 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <125000000>;
+                       clock-output-names = "gmac_int_tx";
+               };
+
+               gmac_tx_clk: clk@01c20164 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun7i-a20-gmac-clk";
+                       reg = <0x01c20164 0x4>;
+                       clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
+                       clock-output-names = "gmac_tx";
+               };
+
                /*
                 * Dummy clock used by output clocks
                 */
                        interrupts = <0 0 4>;
                };
 
+               spi0: spi@01c05000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c05000 0x1000>;
+                       interrupts = <0 10 4>;
+                       clocks = <&ahb_gates 20>, <&spi0_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi1: spi@01c06000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c06000 0x1000>;
+                       interrupts = <0 11 4>;
+                       clocks = <&ahb_gates 21>, <&spi1_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                emac: ethernet@01c0b000 {
                        compatible = "allwinner,sun4i-a10-emac";
                        reg = <0x01c0b000 0x1000>;
                        #size-cells = <0>;
                };
 
+               usbphy: phy@01c13400 {
+                       #phy-cells = <1>;
+                       compatible = "allwinner,sun7i-a20-usb-phy";
+                       reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;
+                       reg-names = "phy_ctrl", "pmu1", "pmu2";
+                       clocks = <&usb_clk 8>;
+                       clock-names = "usb_phy";
+                       resets = <&usb_clk 1>, <&usb_clk 2>;
+                       reset-names = "usb1_reset", "usb2_reset";
+                       status = "disabled";
+               };
+
+               ehci0: usb@01c14000 {
+                       compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+                       reg = <0x01c14000 0x100>;
+                       interrupts = <0 39 4>;
+                       clocks = <&ahb_gates 1>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci0: usb@01c14400 {
+                       compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
+                       reg = <0x01c14400 0x100>;
+                       interrupts = <0 64 4>;
+                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi2: spi@01c17000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c17000 0x1000>;
+                       interrupts = <0 12 4>;
+                       clocks = <&ahb_gates 22>, <&spi2_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               ahci: sata@01c18000 {
+                       compatible = "allwinner,sun4i-a10-ahci";
+                       reg = <0x01c18000 0x1000>;
+                       interrupts = <0 56 4>;
+                       clocks = <&pll6 0>, <&ahb_gates 25>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@01c1c000 {
+                       compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
+                       reg = <0x01c1c000 0x100>;
+                       interrupts = <0 40 4>;
+                       clocks = <&ahb_gates 3>;
+                       phys = <&usbphy 2>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci1: usb@01c1c400 {
+                       compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
+                       reg = <0x01c1c400 0x100>;
+                       interrupts = <0 65 4>;
+                       clocks = <&usb_clk 7>, <&ahb_gates 4>;
+                       phys = <&usbphy 2>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi3: spi@01c1f000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c1f000 0x1000>;
+                       interrupts = <0 50 4>;
+                       clocks = <&ahb_gates 23>, <&spi3_clk>;
+                       clock-names = "ahb", "mod";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                pio: pinctrl@01c20800 {
                        compatible = "allwinner,sun7i-a20-pinctrl";
                        reg = <0x01c20800 0x400>;
                                allwinner,pull = <0>;
                        };
 
+                       uart2_pins_a: uart2@0 {
+                               allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+                               allwinner,function = "uart2";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
                        uart6_pins_a: uart6@0 {
                                allwinner,pins = "PI12", "PI13";
                                allwinner,function = "uart6";
                                allwinner,drive = <0>;
                                allwinner,pull = <0>;
                        };
+
+                       gmac_pins_mii_a: gmac_mii@0 {
+                               allwinner,pins = "PA0", "PA1", "PA2",
+                                               "PA3", "PA4", "PA5", "PA6",
+                                               "PA7", "PA8", "PA9", "PA10",
+                                               "PA11", "PA12", "PA13", "PA14",
+                                               "PA15", "PA16";
+                               allwinner,function = "gmac";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       gmac_pins_rgmii_a: gmac_rgmii@0 {
+                               allwinner,pins = "PA0", "PA1", "PA2",
+                                               "PA3", "PA4", "PA5", "PA6",
+                                               "PA7", "PA8", "PA10",
+                                               "PA11", "PA12", "PA13",
+                                               "PA15", "PA16";
+                               allwinner,function = "gmac";
+                               /*
+                                * data lines in RGMII mode use DDR mode
+                                * and need a higher signal drive strength
+                                */
+                               allwinner,drive = <3>;
+                               allwinner,pull = <0>;
+                       };
+
+                       spi1_pins_a: spi1@0 {
+                               allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+                               allwinner,function = "spi1";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       spi2_pins_a: spi2@0 {
+                               allwinner,pins = "PC19", "PC20", "PC21", "PC22";
+                               allwinner,function = "spi2";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
                };
 
                timer@01c20c00 {
                };
 
                wdt: watchdog@01c20c90 {
-                       compatible = "allwinner,sun4i-wdt";
+                       compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
                };
 
                        status = "disabled";
                };
 
+               gmac: ethernet@01c50000 {
+                       compatible = "allwinner,sun7i-a20-gmac";
+                       reg = <0x01c50000 0x10000>;
+                       interrupts = <0 85 4>;
+                       interrupt-names = "macirq";
+                       clocks = <&ahb_gates 49>, <&gmac_tx_clk>;
+                       clock-names = "stmmaceth", "allwinner_gmac_tx";
+                       snps,pbl = <2>;
+                       snps,fixed-burst;
+                       snps,force_sf_dma_mode;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                hstimer@01c60000 {
                        compatible = "allwinner,sun7i-a20-hstimer";
                        reg = <0x01c60000 0x1000>;
diff --git a/arch/arm/boot/dts/sunxi-common-regulators.dtsi b/arch/arm/boot/dts/sunxi-common-regulators.dtsi
new file mode 100644 (file)
index 0000000..18eeac0
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * sunxi boards common regulator (ahci target power supply, usb-vbus) code
+ *
+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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
+ */
+
+/ {
+       soc@01c00000 {
+               pio: pinctrl@01c20800 {
+                       ahci_pwr_pin_a: ahci_pwr_pin@0 {
+                               allwinner,pins = "PB8";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       usb1_vbus_pin_a: usb1_vbus_pin@0 {
+                               allwinner,pins = "PH6";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       usb2_vbus_pin_a: usb2_vbus_pin@0 {
+                               allwinner,pins = "PH3";
+                               allwinner,function = "gpio_out";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+               };
+       };
+
+       reg_ahci_5v: ahci-5v {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&ahci_pwr_pin_a>;
+               regulator-name = "ahci-5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&pio 1 8 0>;
+               status = "disabled";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb1_vbus_pin_a>;
+               regulator-name = "usb1-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&pio 7 6 0>;
+               status = "disabled";
+       };
+
+       reg_usb2_vbus: usb2-vbus {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb2_vbus_pin_a>;
+               regulator-name = "usb2-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&pio 7 3 0>;
+               status = "disabled";
+       };
+};
index 73aecfb57ccb0a6b4210e6babf0b0d063e893e16..a288a12823ed84a1ba42ffae2a1a4e9bd0cd61b6 100644 (file)
@@ -1,3 +1,8 @@
+/*
+ * This dts file supports Dalmore A04.
+ * Other board revisions are not supported
+ */
+
 /dts-v1/;
 
 #include <dt-bindings/input/input.h>
                                nvidia,pins = "drive_sdio1";
                                nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
                                nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-                               nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
                                nvidia,pull-down-strength = <36>;
                                nvidia,pull-up-strength = <20>;
                                nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOW>;
                                nvidia,pins = "drive_sdio3";
                                nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
                                nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-                               nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
                                nvidia,pull-down-strength = <22>;
                                nvidia,pull-up-strength = <36>;
                                nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
                                nvidia,pins = "drive_gma";
                                nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
                                nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-                               nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
                                nvidia,pull-down-strength = <2>;
                                nvidia,pull-up-strength = <1>;
                                nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
                                nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
-                               nvidia,drive-type = <1>;
                        };
                };
        };
index 44ec401ec36682289d8e4afa3b9b87791cd82c73..fdc559ab2db3674b10841e38caff0cf2b8512d60 100644 (file)
                clocks = <&tegra_car TEGRA114_CLK_SDMMC1>;
                resets = <&tegra_car 14>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
        sdhci@78000200 {
                clocks = <&tegra_car TEGRA114_CLK_SDMMC2>;
                resets = <&tegra_car 9>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
        sdhci@78000400 {
                clocks = <&tegra_car TEGRA114_CLK_SDMMC3>;
                resets = <&tegra_car 69>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
        sdhci@78000600 {
                clocks = <&tegra_car TEGRA114_CLK_SDMMC4>;
                resets = <&tegra_car 15>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
        usb@7d000000 {
index c6dcef513e5d0bc34cee9ede445364356cf130ba..c17283c0459807f1906080deca248f4fb638b192 100644 (file)
@@ -8,15 +8,29 @@
        compatible = "nvidia,venice2", "nvidia,tegra124";
 
        aliases {
-               rtc0 = "/i2c@7000d000/as3722@40";
-               rtc1 = "/rtc@7000e000";
+               rtc0 = "/i2c@0,7000d000/pmic@40";
+               rtc1 = "/rtc@0,7000e000";
        };
 
        memory {
-               reg = <0x80000000 0x80000000>;
+               reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
-       pinmux: pinmux@70000868 {
+       host1x@0,50000000 {
+               sor@0,54540000 {
+                       status = "okay";
+
+                       nvidia,dpaux = <&dpaux>;
+                       nvidia,panel = <&panel>;
+               };
+
+               dpaux: dpaux@0,545c0000 {
+                       vdd-supply = <&vdd_3v3_panel>;
+                       status = "okay";
+               };
+       };
+
+       pinmux: pinmux@0,70000868 {
                pinctrl-names = "default";
                pinctrl-0 = <&pinmux_default>;
 
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
                        sdmmc1_clk_pz0 {
-                               nvidia,pins = "sdmmc1_clk_pz0",
-                                             "sdmmc1_cmd_pz1",
-                                             "sdmmc1_dat0_py7",
-                                             "sdmmc1_dat1_py6",
-                                             "sdmmc1_dat2_py5",
-                                             "sdmmc1_dat3_py4";
+                               nvidia,pins = "sdmmc1_clk_pz0";
                                nvidia,function = "sdmmc1";
-                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
                        usb_vbus_en0_pn4 {
-                               nvidia,pins = "usb_vbus_en0_pn4";
+                               nvidia,pins = "usb_vbus_en0_pn4",
+                                             "usb_vbus_en1_pn5";
                                nvidia,function = "usb";
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                               nvidia,lock = <TEGRA_PIN_DISABLE>;
-                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
-                       };
-                       usb_vbus_en1_pn5 {
-                               nvidia,pins = "usb_vbus_en1_pn5";
-                               nvidia,function = "usb";
-                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,lock = <TEGRA_PIN_DISABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                                nvidia,pins = "drive_sdio1";
                                nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
                                nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-                               nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
                                nvidia,pull-down-strength = <32>;
                                nvidia,pull-up-strength = <42>;
                                nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
                                nvidia,pins = "drive_sdio3";
                                nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
                                nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-                               nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
                                nvidia,pull-down-strength = <20>;
                                nvidia,pull-up-strength = <36>;
                                nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
                };
        };
 
-       serial@70006000 {
+       serial@0,70006000 {
                status = "okay";
        };
 
-       pwm: pwm@7000a000 {
+       pwm: pwm@0,7000a000 {
                status = "okay";
        };
 
-       i2c@7000c000 {
+       i2c@0,7000c000 {
                status = "okay";
                clock-frequency = <100000>;
 
                };
        };
 
-       i2c@7000c400 {
+       i2c@0,7000c400 {
                status = "okay";
                clock-frequency = <100000>;
        };
 
-       i2c@7000c500 {
+       i2c@0,7000c500 {
                status = "okay";
                clock-frequency = <100000>;
        };
 
-       i2c@7000c700 {
+       i2c@0,7000c700 {
                status = "okay";
                clock-frequency = <100000>;
        };
 
-       i2c@7000d000 {
+       i2c@0,7000d000 {
                status = "okay";
                clock-frequency = <400000>;
 
-               as3722: as3722@40 {
+               pmic: pmic@40 {
                        compatible = "ams,as3722";
                        reg = <0x40>;
                        interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
 
+                       ams,system-power-controller;
+
                        #interrupt-cells = <2>;
                        interrupt-controller;
 
                        };
 
                        regulators {
-                               vsup-sd2-supply = <&vdd_ac_bat_reg>;
-                               vsup-sd3-supply = <&vdd_ac_bat_reg>;
-                               vsup-sd4-supply = <&vdd_ac_bat_reg>;
-                               vsup-sd5-supply = <&vdd_ac_bat_reg>;
-                               vin-ldo0-supply = <&as3722_sd2>;
-                               vin-ldo1-6-supply = <&vdd_ac_bat_reg>;
-                               vin-ldo2-5-7-supply = <&as3722_sd5>;
-                               vin-ldo3-4-supply = <&vdd_ac_bat_reg>;
-                               vin-ldo9-10-supply = <&vdd_ac_bat_reg>;
-                               vin-ldo11-supply = <&vdd_ac_bat_reg>;
+                               vsup-sd2-supply = <&vdd_5v0_sys>;
+                               vsup-sd3-supply = <&vdd_5v0_sys>;
+                               vsup-sd4-supply = <&vdd_5v0_sys>;
+                               vsup-sd5-supply = <&vdd_5v0_sys>;
+                               vin-ldo0-supply = <&vdd_1v35_lp0>;
+                               vin-ldo1-6-supply = <&vdd_3v3_run>;
+                               vin-ldo2-5-7-supply = <&vddio_1v8>;
+                               vin-ldo3-4-supply = <&vdd_3v3_sys>;
+                               vin-ldo9-10-supply = <&vdd_5v0_sys>;
+                               vin-ldo11-supply = <&vdd_3v3_run>;
 
                                sd0 {
-                                       regulator-name = "vdd-cpu";
+                                       regulator-name = "+VDD_CPU_AP";
                                        regulator-min-microvolt = <700000>;
                                        regulator-max-microvolt = <1400000>;
                                        regulator-min-microamp = <3500000>;
                                };
 
                                sd1 {
-                                       regulator-name = "vdd-core";
+                                       regulator-name = "+VDD_CORE";
                                        regulator-min-microvolt = <700000>;
                                        regulator-max-microvolt = <1350000>;
                                        regulator-min-microamp = <2500000>;
                                        ams,external-control = <1>;
                                };
 
-                               as3722_sd2: sd2 {
-                                       regulator-name = "vddio-ddr";
+                               vdd_1v35_lp0: sd2 {
+                                       regulator-name = "+1.35V_LP0(sd2)";
                                        regulator-min-microvolt = <1350000>;
                                        regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
                                };
 
                                sd3 {
-                                       regulator-name = "vddio-ddr-2phase";
+                                       regulator-name = "+1.35V_LP0(sd3)";
                                        regulator-min-microvolt = <1350000>;
                                        regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
                                };
 
                                sd4 {
-                                       regulator-name = "avdd-pex-sata";
+                                       regulator-name = "+1.05V_RUN";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
-                                       regulator-boot-on;
-                                       regulator-always-on;
                                };
 
-                               as3722_sd5: sd5 {
-                                       regulator-name = "vddio-sys";
+                               vddio_1v8: sd5 {
+                                       regulator-name = "+1.8V_VDDIO";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-boot-on;
                                };
 
                                sd6 {
-                                       regulator-name = "vdd-gpu";
+                                       regulator-name = "+VDD_GPU_AP";
                                        regulator-min-microvolt = <650000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-min-microamp = <3500000>;
                                };
 
                                ldo0 {
-                                       regulator-name = "avdd_pll";
+                                       regulator-name = "+1.05V_RUN_AVDD";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                                        regulator-boot-on;
                                };
 
                                ldo1 {
-                                       regulator-name = "run-cam-1.8";
+                                       regulator-name = "+1.8V_RUN_CAM";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                };
 
                                ldo2 {
-                                       regulator-name = "gen-avdd,vddio-hsic";
+                                       regulator-name = "+1.2V_GEN_AVDD";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-boot-on;
                                };
 
                                ldo3 {
-                                       regulator-name = "vdd-rtc";
+                                       regulator-name = "+1.00V_LP0_VDD_RTC";
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1000000>;
                                        regulator-boot-on;
                                        ams,enable-tracking;
                                };
 
-                               ldo4 {
-                                       regulator-name = "vdd-cam";
+                               vdd_run_cam: ldo4 {
+                                       regulator-name = "+3.3V_RUN_CAM";
                                        regulator-min-microvolt = <2800000>;
                                        regulator-max-microvolt = <2800000>;
-                                       regulator-boot-on;
-                                       regulator-always-on;
                                };
 
                                ldo5 {
-                                       regulator-name = "vdd-cam-front";
+                                       regulator-name = "+1.2V_RUN_CAM_FRONT";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                };
 
-                               ldo6 {
-                                       regulator-name = "vddio-sdmmc3";
+                               vddio_sdmmc3: ldo6 {
+                                       regulator-name = "+VDDIO_SDMMC3";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <3300000>;
-                                       regulator-boot-on;
-                                       regulator-always-on;
                                };
 
                                ldo7 {
-                                       regulator-name = "vdd-cam-rear";
+                                       regulator-name = "+1.05V_RUN_CAM_REAR";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                                };
 
                                ldo9 {
-                                       regulator-name = "vdd-touch";
+                                       regulator-name = "+2.8V_RUN_TOUCH";
                                        regulator-min-microvolt = <2800000>;
                                        regulator-max-microvolt = <2800000>;
                                };
 
                                ldo10 {
-                                       regulator-name = "vdd-cam-af";
+                                       regulator-name = "+2.8V_RUN_CAM_AF";
                                        regulator-min-microvolt = <2800000>;
                                        regulator-max-microvolt = <2800000>;
                                };
 
                                ldo11 {
-                                       regulator-name = "vpp-fuse";
+                                       regulator-name = "+1.8V_RUN_VPP_FUSE";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                };
                };
        };
 
-       spi@7000d400 {
+       spi@0,7000d400 {
                status = "okay";
 
                cros-ec@0 {
                };
        };
 
-       pmc@7000e400 {
+       spi@0,7000da00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+               spi-flash@0 {
+                       compatible = "winbond,w25q32dw";
+                       reg = <0>;
+                       spi-max-frequency = <20000000>;
+               };
+       };
+
+       pmc@0,7000e400 {
                nvidia,invert-interrupt;
                nvidia,suspend-mode = <1>;
                nvidia,cpu-pwr-good-time = <500>;
                nvidia,sys-clock-req-active-high;
        };
 
-       sdhci@700b0400 {
+       sdhci@0,700b0400 {
                cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
                power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
                status = "okay";
                bus-width = <4>;
+               vmmc-supply = <&vddio_sdmmc3>;
        };
 
-       sdhci@700b0600 {
+       sdhci@0,700b0600 {
                status = "okay";
                bus-width = <8>;
        };
 
-       ahub@70300000 {
-               i2s@70301100 {
+       ahub@0,70300000 {
+               i2s@0,70301100 {
                        status = "okay";
                };
        };
 
+       usb@0,7d000000 {
+               status = "okay";
+       };
+
+       usb-phy@0,7d000000 {
+               status = "okay";
+               vbus-supply = <&vdd_usb1_vbus>;
+       };
+
+       usb@0,7d004000 {
+               status = "okay";
+       };
+
+       usb-phy@0,7d004000 {
+               status = "okay";
+               vbus-supply = <&vdd_run_cam>;
+       };
+
+       usb@0,7d008000 {
+               status = "okay";
+       };
+
+       usb-phy@0,7d008000 {
+               status = "okay";
+               vbus-supply = <&vdd_usb3_vbus>;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+
+               enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+               power-supply = <&vdd_led>;
+               pwms = <&pwm 1 1000000>;
+
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+       };
+
        clocks {
                compatible = "simple-bus";
                #address-cells = <1>;
 
                clk32k_in: clock@0 {
                        compatible = "fixed-clock";
-                       reg=<0>;
+                       reg = <0>;
                        #clock-cells = <0>;
                        clock-frequency = <32768>;
                };
                };
        };
 
+       panel: panel {
+               compatible = "lg,lp129qe", "simple-panel";
+
+               backlight = <&backlight>;
+               ddc-i2c-bus = <&dpaux>;
+       };
+
        regulators {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <0>;
 
-               vdd_ac_bat_reg: regulator@0 {
+               vdd_mux: regulator@0 {
                        compatible = "regulator-fixed";
                        reg = <0>;
-                       regulator-name = "vdd_ac_bat";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
+                       regulator-name = "+VDD_MUX";
+                       regulator-min-microvolt = <12000000>;
+                       regulator-max-microvolt = <12000000>;
                        regulator-always-on;
+                       regulator-boot-on;
                };
 
-               vdd_3v3_reg: regulator@1 {
+               vdd_5v0_sys: regulator@1 {
                        compatible = "regulator-fixed";
                        reg = <1>;
-                       regulator-name = "vdd_3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
+                       regulator-name = "+5V_SYS";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
                        regulator-always-on;
                        regulator-boot-on;
-                       enable-active-high;
-                       gpio = <&as3722 1 GPIO_ACTIVE_HIGH>;
+                       vin-supply = <&vdd_mux>;
                };
 
-               vdd_3v3_modem_reg: regulator@2 {
+               vdd_3v3_sys: regulator@2 {
                        compatible = "regulator-fixed";
                        reg = <2>;
-                       regulator-name = "vdd-modem-3v3";
+                       regulator-name = "+3.3V_SYS";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
-                       enable-active-high;
-                       gpio = <&as3722 2 GPIO_ACTIVE_HIGH>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       vin-supply = <&vdd_mux>;
                };
 
-               vdd_hdmi_5v0_reg: regulator@3 {
+               vdd_3v3_run: regulator@3 {
                        compatible = "regulator-fixed";
                        reg = <3>;
-                       regulator-name = "vdd-hdmi-5v0";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
+                       regulator-name = "+3.3V_RUN";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
                        enable-active-high;
-                       gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
+                       vin-supply = <&vdd_3v3_sys>;
                };
 
-               vdd_bl_reg: regulator@4 {
+               vdd_3v3_hdmi: regulator@4 {
                        compatible = "regulator-fixed";
                        reg = <4>;
-                       regulator-name = "vdd-bl";
+                       regulator-name = "+3.3V_AVDD_HDMI_AP_GATED";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
-                       gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_LOW>;
+                       vin-supply = <&vdd_3v3_run>;
                };
 
-               vdd_ts_sw_5v0: regulator@5 {
+               vdd_led: regulator@5 {
                        compatible = "regulator-fixed";
                        reg = <5>;
-                       regulator-name = "vdd_ts_sw";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
+                       regulator-name = "+VDD_LED";
+                       gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
                        enable-active-high;
-                       regulator-boot-on;
-                       gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_LOW>;
+                       vin-supply = <&vdd_mux>;
                };
 
-               usb1_vbus_reg: regulator@6 {
+               vdd_5v0_ts: regulator@6 {
                        compatible = "regulator-fixed";
                        reg = <6>;
-                       regulator-name = "usb1_vbus";
+                       regulator-name = "+5V_VDD_TS_SW";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        regulator-boot-on;
+                       gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
                        enable-active-high;
-                       gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
-                       gpio-open-drain;
+                       vin-supply = <&vdd_5v0_sys>;
                };
 
-               usb3_vbus_reg: regulator@7 {
+               vdd_usb1_vbus: regulator@7 {
                        compatible = "regulator-fixed";
                        reg = <7>;
-                       regulator-name = "usb3_vbus";
+                       regulator-name = "+5V_USB_HS";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
-                       regulator-boot-on;
+                       gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
                        enable-active-high;
-                       gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
                        gpio-open-drain;
+                       vin-supply = <&vdd_5v0_sys>;
                };
 
-               panel_3v3_reg: regulator@8 {
+               vdd_usb3_vbus: regulator@8 {
                        compatible = "regulator-fixed";
                        reg = <8>;
-                       regulator-name = "panel_3v3";
+                       regulator-name = "+5V_USB_SS";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       gpio-open-drain;
+                       vin-supply = <&vdd_5v0_sys>;
+               };
+
+               vdd_3v3_panel: regulator@9 {
+                       compatible = "regulator-fixed";
+                       reg = <9>;
+                       regulator-name = "+3.3V_PANEL";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&pmic 4 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       vin-supply = <&vdd_3v3_run>;
+               };
+
+               vdd_3v3_lp0: regulator@10 {
+                       compatible = "regulator-fixed";
+                       reg = <10>;
+                       regulator-name = "+3.3V_LP0";
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
+                       /*
+                        * TODO: find a way to wire this up with the USB EHCI
+                        * controllers so that it can be enabled on demand.
+                        */
+                       regulator-always-on;
+                       gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
                        enable-active-high;
-                       gpio = <&as3722 4 GPIO_ACTIVE_HIGH>;
+                       vin-supply = <&vdd_3v3_sys>;
                };
        };
 
index ec0698a8354a4795a64318adffe12820efd198c6..cf45a1a394835ecc64309e00f58f5b33a5855260 100644 (file)
@@ -8,22 +8,91 @@
 / {
        compatible = "nvidia,tegra124";
        interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       host1x@0,50000000 {
+               compatible = "nvidia,tegra124-host1x", "simple-bus";
+               reg = <0x0 0x50000000 0x0 0x00034000>;
+               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+                            <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+               clocks = <&tegra_car TEGRA124_CLK_HOST1X>;
+               resets = <&tegra_car 28>;
+               reset-names = "host1x";
+
+               #address-cells = <2>;
+               #size-cells = <2>;
+
+               ranges = <0 0x54000000 0 0x54000000 0 0x01000000>;
+
+               dc@0,54200000 {
+                       compatible = "nvidia,tegra124-dc";
+                       reg = <0x0 0x54200000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_DISP1>,
+                                <&tegra_car TEGRA124_CLK_PLL_P>;
+                       clock-names = "dc", "parent";
+                       resets = <&tegra_car 27>;
+                       reset-names = "dc";
+
+                       nvidia,head = <0>;
+               };
+
+               dc@0,54240000 {
+                       compatible = "nvidia,tegra124-dc";
+                       reg = <0x0 0x54240000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_DISP2>,
+                                <&tegra_car TEGRA124_CLK_PLL_P>;
+                       clock-names = "dc", "parent";
+                       resets = <&tegra_car 26>;
+                       reset-names = "dc";
+
+                       nvidia,head = <1>;
+               };
 
-       gic: interrupt-controller@50041000 {
+               sor@0,54540000 {
+                       compatible = "nvidia,tegra124-sor";
+                       reg = <0x0 0x54540000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_SOR0>,
+                                <&tegra_car TEGRA124_CLK_PLL_D_OUT0>,
+                                <&tegra_car TEGRA124_CLK_PLL_DP>,
+                                <&tegra_car TEGRA124_CLK_CLK_M>;
+                       clock-names = "sor", "parent", "dp", "safe";
+                       resets = <&tegra_car 182>;
+                       reset-names = "sor";
+                       status = "disabled";
+               };
+
+               dpaux@0,545c0000 {
+                       compatible = "nvidia,tegra124-dpaux";
+                       reg = <0x0 0x545c0000 0x0 0x00040000>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA124_CLK_DPAUX>,
+                                <&tegra_car TEGRA124_CLK_PLL_DP>;
+                       clock-names = "dpaux", "parent";
+                       resets = <&tegra_car 181>;
+                       reset-names = "dpaux";
+                       status = "disabled";
+               };
+       };
+
+       gic: interrupt-controller@0,50041000 {
                compatible = "arm,cortex-a15-gic";
                #interrupt-cells = <3>;
                interrupt-controller;
-               reg = <0x50041000 0x1000>,
-                     <0x50042000 0x1000>,
-                     <0x50044000 0x2000>,
-                     <0x50046000 0x2000>;
+               reg = <0x0 0x50041000 0x0 0x1000>,
+                     <0x0 0x50042000 0x0 0x1000>,
+                     <0x0 0x50044000 0x0 0x2000>,
+                     <0x0 0x50046000 0x0 0x2000>;
                interrupts = <GIC_PPI 9
                        (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
        };
 
-       timer@60005000 {
+       timer@0,60005000 {
                compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer";
-               reg = <0x60005000 0x400>;
+               reg = <0x0 0x60005000 0x0 0x400>;
                interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
                clocks = <&tegra_car TEGRA124_CLK_TIMER>;
        };
 
-       tegra_car: clock@60006000 {
+       tegra_car: clock@0,60006000 {
                compatible = "nvidia,tegra124-car";
-               reg = <0x60006000 0x1000>;
+               reg = <0x0 0x60006000 0x0 0x1000>;
                #clock-cells = <1>;
                #reset-cells = <1>;
        };
 
-       gpio: gpio@6000d000 {
+       gpio: gpio@0,6000d000 {
                compatible = "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
-               reg = <0x6000d000 0x1000>;
+               reg = <0x0 0x6000d000 0x0 0x1000>;
                interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
                interrupt-controller;
        };
 
-       apbdma: dma@60020000 {
+       apbdma: dma@0,60020000 {
                compatible = "nvidia,tegra124-apbdma", "nvidia,tegra148-apbdma";
-               reg = <0x60020000 0x1400>;
+               reg = <0x0 0x60020000 0x0 0x1400>;
                interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
                #dma-cells = <1>;
        };
 
-       pinmux: pinmux@70000868 {
+       pinmux: pinmux@0,70000868 {
                compatible = "nvidia,tegra124-pinmux";
-               reg = <0x70000868 0x164>,       /* Pad control registers */
-                     <0x70003000 0x434>;       /* Mux registers */
+               reg = <0x0 0x70000868 0x0 0x164>, /* Pad control registers */
+                     <0x0 0x70003000 0x0 0x434>; /* Mux registers */
        };
 
        /*
         * the APB DMA based serial driver, the comptible is
         * "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart".
         */
-       serial@70006000 {
+       serial@0,70006000 {
                compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
-               reg = <0x70006000 0x40>;
+               reg = <0x0 0x70006000 0x0 0x40>;
                reg-shift = <2>;
                interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_UARTA>;
                status = "disabled";
        };
 
-       serial@70006040 {
+       serial@0,70006040 {
                compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
-               reg = <0x70006040 0x40>;
+               reg = <0x0 0x70006040 0x0 0x40>;
                reg-shift = <2>;
                interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_UARTB>;
                status = "disabled";
        };
 
-       serial@70006200 {
+       serial@0,70006200 {
                compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
-               reg = <0x70006200 0x40>;
+               reg = <0x0 0x70006200 0x0 0x40>;
                reg-shift = <2>;
                interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_UARTC>;
                status = "disabled";
        };
 
-       serial@70006300 {
+       serial@0,70006300 {
                compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
-               reg = <0x70006300 0x40>;
+               reg = <0x0 0x70006300 0x0 0x40>;
                reg-shift = <2>;
                interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_UARTD>;
                status = "disabled";
        };
 
-       serial@70006400 {
+       serial@0,70006400 {
                compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
-               reg = <0x70006400 0x40>;
+               reg = <0x0 0x70006400 0x0 0x40>;
                reg-shift = <2>;
                interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_UARTE>;
                status = "disabled";
        };
 
-       pwm@7000a000 {
+       pwm@0,7000a000 {
                compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
-               reg = <0x7000a000 0x100>;
+               reg = <0x0 0x7000a000 0x0 0x100>;
                #pwm-cells = <2>;
                clocks = <&tegra_car TEGRA124_CLK_PWM>;
                resets = <&tegra_car 17>;
                status = "disabled";
        };
 
-       i2c@7000c000 {
+       i2c@0,7000c000 {
                compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
-               reg = <0x7000c000 0x100>;
+               reg = <0x0 0x7000c000 0x0 0x100>;
                interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       i2c@7000c400 {
+       i2c@0,7000c400 {
                compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
-               reg = <0x7000c400 0x100>;
+               reg = <0x0 0x7000c400 0x0 0x100>;
                interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       i2c@7000c500 {
+       i2c@0,7000c500 {
                compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
-               reg = <0x7000c500 0x100>;
+               reg = <0x0 0x7000c500 0x0 0x100>;
                interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       i2c@7000c700 {
+       i2c@0,7000c700 {
                compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
-               reg = <0x7000c700 0x100>;
+               reg = <0x0 0x7000c700 0x0 0x100>;
                interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       i2c@7000d000 {
+       i2c@0,7000d000 {
                compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
-               reg = <0x7000d000 0x100>;
+               reg = <0x0 0x7000d000 0x0 0x100>;
                interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       i2c@7000d100 {
+       i2c@0,7000d100 {
                compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c";
-               reg = <0x7000d100 0x100>;
+               reg = <0x0 0x7000d100 0x0 0x100>;
                interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       spi@7000d400 {
+       spi@0,7000d400 {
                compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
-               reg = <0x7000d400 0x200>;
+               reg = <0x0 0x7000d400 0x0 0x200>;
                interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       spi@7000d600 {
+       spi@0,7000d600 {
                compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
-               reg = <0x7000d600 0x200>;
+               reg = <0x0 0x7000d600 0x0 0x200>;
                interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       spi@7000d800 {
+       spi@0,7000d800 {
                compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
-               reg = <0x7000d800 0x200>;
+               reg = <0x0 0x7000d800 0x0 0x200>;
                interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       spi@7000da00 {
+       spi@0,7000da00 {
                compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
-               reg = <0x7000da00 0x200>;
+               reg = <0x0 0x7000da00 0x0 0x200>;
                interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       spi@7000dc00 {
+       spi@0,7000dc00 {
                compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
-               reg = <0x7000dc00 0x200>;
+               reg = <0x0 0x7000dc00 0x0 0x200>;
                interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       spi@7000de00 {
+       spi@0,7000de00 {
                compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
-               reg = <0x7000de00 0x200>;
+               reg = <0x0 0x7000de00 0x0 0x200>;
                interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
-       rtc@7000e000 {
+       rtc@0,7000e000 {
                compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
-               reg = <0x7000e000 0x100>;
+               reg = <0x0 0x7000e000 0x0 0x100>;
                interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_RTC>;
        };
 
-       pmc@7000e400 {
+       pmc@0,7000e400 {
                compatible = "nvidia,tegra124-pmc";
-               reg = <0x7000e400 0x400>;
+               reg = <0x0 0x7000e400 0x0 0x400>;
                clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
                clock-names = "pclk", "clk32k_in";
        };
 
-       sdhci@700b0000 {
+       sdhci@0,700b0000 {
                compatible = "nvidia,tegra124-sdhci";
-               reg = <0x700b0000 0x200>;
+               reg = <0x0 0x700b0000 0x0 0x200>;
                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_SDMMC1>;
                resets = <&tegra_car 14>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
-       sdhci@700b0200 {
+       sdhci@0,700b0200 {
                compatible = "nvidia,tegra124-sdhci";
-               reg = <0x700b0200 0x200>;
+               reg = <0x0 0x700b0200 0x0 0x200>;
                interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_SDMMC2>;
                resets = <&tegra_car 9>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
-       sdhci@700b0400 {
+       sdhci@0,700b0400 {
                compatible = "nvidia,tegra124-sdhci";
-               reg = <0x700b0400 0x200>;
+               reg = <0x0 0x700b0400 0x0 0x200>;
                interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_SDMMC3>;
                resets = <&tegra_car 69>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
-       sdhci@700b0600 {
+       sdhci@0,700b0600 {
                compatible = "nvidia,tegra124-sdhci";
-               reg = <0x700b0600 0x200>;
+               reg = <0x0 0x700b0600 0x0 0x200>;
                interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_SDMMC4>;
                resets = <&tegra_car 15>;
                reset-names = "sdhci";
-               status = "disable";
+               status = "disabled";
        };
 
-       ahub@70300000 {
+       ahub@0,70300000 {
                compatible = "nvidia,tegra124-ahub";
-               reg = <0x70300000 0x200>,
-                     <0x70300800 0x800>,
-                     <0x70300200 0x600>;
+               reg = <0x0 0x70300000 0x0 0x200>,
+                     <0x0 0x70300800 0x0 0x800>,
+                     <0x0 0x70300200 0x0 0x600>;
                interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&tegra_car TEGRA124_CLK_D_AUDIO>,
                         <&tegra_car TEGRA124_CLK_APBIF>;
                            "rx6", "tx6", "rx7", "tx7", "rx8", "tx8",
                            "rx9", "tx9";
                ranges;
-               #address-cells = <1>;
-               #size-cells = <1>;
+               #address-cells = <2>;
+               #size-cells = <2>;
 
-               tegra_i2s0: i2s@70301000 {
+               tegra_i2s0: i2s@0,70301000 {
                        compatible = "nvidia,tegra124-i2s";
-                       reg = <0x70301000 0x100>;
+                       reg = <0x0 0x70301000 0x0 0x100>;
                        nvidia,ahub-cif-ids = <4 4>;
                        clocks = <&tegra_car TEGRA124_CLK_I2S0>;
                        resets = <&tegra_car 30>;
                        status = "disabled";
                };
 
-               tegra_i2s1: i2s@70301100 {
+               tegra_i2s1: i2s@0,70301100 {
                        compatible = "nvidia,tegra124-i2s";
-                       reg = <0x70301100 0x100>;
+                       reg = <0x0 0x70301100 0x0 0x100>;
                        nvidia,ahub-cif-ids = <5 5>;
                        clocks = <&tegra_car TEGRA124_CLK_I2S1>;
                        resets = <&tegra_car 11>;
                        status = "disabled";
                };
 
-               tegra_i2s2: i2s@70301200 {
+               tegra_i2s2: i2s@0,70301200 {
                        compatible = "nvidia,tegra124-i2s";
-                       reg = <0x70301200 0x100>;
+                       reg = <0x0 0x70301200 0x0 0x100>;
                        nvidia,ahub-cif-ids = <6 6>;
                        clocks = <&tegra_car TEGRA124_CLK_I2S2>;
                        resets = <&tegra_car 18>;
                        status = "disabled";
                };
 
-               tegra_i2s3: i2s@70301300 {
+               tegra_i2s3: i2s@0,70301300 {
                        compatible = "nvidia,tegra124-i2s";
-                       reg = <0x70301300 0x100>;
+                       reg = <0x0 0x70301300 0x0 0x100>;
                        nvidia,ahub-cif-ids = <7 7>;
                        clocks = <&tegra_car TEGRA124_CLK_I2S3>;
                        resets = <&tegra_car 101>;
                        status = "disabled";
                };
 
-               tegra_i2s4: i2s@70301400 {
+               tegra_i2s4: i2s@0,70301400 {
                        compatible = "nvidia,tegra124-i2s";
-                       reg = <0x70301400 0x100>;
+                       reg = <0x0 0x70301400 0x0 0x100>;
                        nvidia,ahub-cif-ids = <8 8>;
                        clocks = <&tegra_car TEGRA124_CLK_I2S4>;
                        resets = <&tegra_car 102>;
                };
        };
 
+       usb@0,7d000000 {
+               compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d000000 0x0 0x4000>;
+               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USBD>;
+               resets = <&tegra_car 22>;
+               reset-names = "usb";
+               nvidia,phy = <&phy1>;
+               status = "disabled";
+       };
+
+       phy1: usb-phy@0,7d000000 {
+               compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d000000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USBD>,
+                        <&tegra_car TEGRA124_CLK_PLL_U>,
+                        <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               status = "disabled";
+       };
+
+       usb@0,7d004000 {
+               compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d004000 0x0 0x4000>;
+               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB2>;
+               resets = <&tegra_car 58>;
+               reset-names = "usb";
+               nvidia,phy = <&phy2>;
+               status = "disabled";
+       };
+
+       phy2: usb-phy@0,7d004000 {
+               compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d004000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB2>,
+                        <&tegra_car TEGRA124_CLK_PLL_U>,
+                        <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               status = "disabled";
+       };
+
+       usb@0,7d008000 {
+               compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci", "usb-ehci";
+               reg = <0x0 0x7d008000 0x0 0x4000>;
+               interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB3>;
+               resets = <&tegra_car 59>;
+               reset-names = "usb";
+               nvidia,phy = <&phy3>;
+               status = "disabled";
+       };
+
+       phy3: usb-phy@0,7d008000 {
+               compatible = "nvidia,tegra124-usb-phy", "nvidia,tegra30-usb-phy";
+               reg = <0x0 0x7d008000 0x0 0x4000>,
+                     <0x0 0x7d000000 0x0 0x4000>;
+               phy_type = "utmi";
+               clocks = <&tegra_car TEGRA124_CLK_USB3>,
+                        <&tegra_car TEGRA124_CLK_PLL_U>,
+                        <&tegra_car TEGRA124_CLK_USBD>;
+               clock-names = "reg", "pll_u", "utmi-pads";
+               nvidia,hssync-start-delay = <0>;
+               nvidia,idle-wait-delay = <17>;
+               nvidia,elastic-limit = <16>;
+               nvidia,term-range-adj = <6>;
+               nvidia,xcvr-setup = <9>;
+               nvidia,xcvr-lsfslew = <0>;
+               nvidia,xcvr-lsrslew = <3>;
+               nvidia,hssquelch-level = <2>;
+               nvidia,hsdiscon-level = <5>;
+               nvidia,xcvr-hsslew = <12>;
+               status = "disabled";
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
index c7cd8e6802d75687169e69ba8b41cec57d40b1de..9a39a8001f7845fb75572e97a7a8554399af9d81 100644 (file)
        };
 
        host1x@50000000 {
+               dc@54200000 {
+                       rgb {
+                               status = "okay";
+
+                               nvidia,panel = <&panel>;
+                       };
+               };
+
                hdmi@54280000 {
                        status = "okay";
 
                status = "okay";
        };
 
-       i2c@7000c000 {
+       pwm: pwm@7000a000 {
+               status = "okay";
+       };
+
+       lvds_ddc: i2c@7000c000 {
                status = "okay";
                clock-frequency = <400000>;
 
                non-removable;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+
+               enable-gpios = <&gpio TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
+               pwms = <&pwm 0 5000000>;
+
+               brightness-levels = <0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 255>;
+               default-brightness-level = <10>;
+
+               backlight-boot-off;
+       };
+
        clocks {
                compatible = "simple-bus";
                #address-cells = <1>;
                };
        };
 
+       panel: panel {
+               compatible = "samsung,ltn101nt05", "simple-panel";
+
+               ddc-i2c-bus = <&lvds_ddc>;
+               power-supply = <&vdd_pnl_reg>;
+               enable-gpios = <&gpio TEGRA_GPIO(M, 6) GPIO_ACTIVE_HIGH>;
+
+               backlight = <&backlight>;
+       };
+
        regulators {
                compatible = "simple-bus";
                #address-cells = <1>;
                        regulator-max-microvolt = <5000000>;
                        regulator-always-on;
                };
+
+               vdd_pnl_reg: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "+3VS,vdd_pnl";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio TEGRA_GPIO(A, 4) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
        };
 
        sound {
index a11b6e7b47595eb22a17a4c4d293b7614478e156..a1d4bf9895d74c8b0efb7d2fe948a9fcd602b25e 100644 (file)
        };
 
        host1x@50000000 {
+               dc@54200000 {
+                       rgb {
+                               status = "okay";
+
+                               nvidia,panel = <&panel>;
+                       };
+               };
+
                hdmi@54280000 {
                        status = "okay";
 
                status = "okay";
        };
 
+       pwm: pwm@7000a000 {
+               status = "okay";
+       };
+
        i2c@7000c000 {
                status = "okay";
                clock-frequency = <400000>;
                        #size-cells = <0>;
                };
 
-               i2c@1 {
+               lvds_ddc: i2c@1 {
                        reg = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                non-removable;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+
+               enable-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
+               power-supply = <&vdd_bl_reg>;
+               pwms = <&pwm 2 5000000>;
+
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+       };
+
        clocks {
                compatible = "simple-bus";
                #address-cells = <1>;
                };
        };
 
+       panel: panel {
+               compatible = "chunghwa,claa101wa01a", "simple-panel";
+
+               power-supply = <&vdd_pnl_reg>;
+               enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+               backlight = <&backlight>;
+               ddc-i2c-bus = <&lvds_ddc>;
+       };
+
        regulators {
                compatible = "simple-bus";
                #address-cells = <1>;
                        regulator-always-on;
                        regulator-boot-on;
                };
+
+               vdd_pnl_reg: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "vdd_pnl";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+                       gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+
+               vdd_bl_reg: regulator@5 {
+                       compatible = "regulator-fixed";
+                       reg = <5>;
+                       regulator-name = "vdd_bl";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+                       gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
        };
 
        sound {
index 571d12e6ac2d0e6164d5a73ca07c033070ea4b5e..ca8484cccddccc32313649e1abfd644b527f50a3 100644 (file)
        };
 
        host1x@50000000 {
+               dc@54200000 {
+                       rgb {
+                               status = "okay";
+
+                               nvidia,panel = <&panel>;
+                       };
+               };
+
                hdmi@54280000 {
                        status = "okay";
 
                status = "okay";
        };
 
+       pwm: pwm@7000a000 {
+               status = "okay";
+       };
+
        i2c@7000c000 {
                status = "okay";
                clock-frequency = <400000>;
                        #size-cells = <0>;
                };
 
-               i2c@1 {
+               lvds_ddc: i2c@1 {
                        reg = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                non-removable;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+
+               enable-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
+               power-supply = <&vdd_bl_reg>;
+               pwms = <&pwm 2 5000000>;
+
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+       };
+
        clocks {
                compatible = "simple-bus";
                #address-cells = <1>;
                };
        };
 
+       panel: panel {
+               compatible = "chunghwa,claa101wa01a", "simple-panel";
+
+               power-supply = <&vdd_pnl_reg>;
+               enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>;
+
+               backlight = <&backlight>;
+               ddc-i2c-bus = <&lvds_ddc>;
+       };
+
        regulators {
                compatible = "simple-bus";
                #address-cells = <1>;
                        enable-active-high;
                };
 
-               regulator@3 {
+               vdd_pnl_reg: regulator@3 {
                        compatible = "regulator-fixed";
                        reg = <3>;
                        regulator-name = "vdd_pnl";
                        enable-active-high;
                };
 
-               regulator@4 {
+               vdd_bl_reg: regulator@4 {
                        compatible = "regulator-fixed";
                        reg = <4>;
                        regulator-name = "vdd_bl";
index 48d2a7f4d0c05e2808a5cb2150298c41c1aa3367..a7ddf70df50b428012b1d6fdb8dd5b018f1b73a8 100644 (file)
                              GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
                interrupt-names = "intr", "msi";
 
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
                bus-range = <0x00 0xff>;
                #address-cells = <3>;
                #size-cells = <2>;
index 1e156d9d0506085c4ea615ac8c7e06193573edcb..0cf0848a82d88964ddd0ed72fca19aa5c6cb135a 100644 (file)
                        interrupt-parent = <&gpio>;
                        interrupts = <TEGRA_GPIO(L, 0) IRQ_TYPE_LEVEL_HIGH>;
                };
+
+               i2cmux@70 {
+                       compatible = "nxp,pca9546";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x70>;
+               };
        };
 
        i2c@7000c700 {
index 19a84e933f4eae0799fc194b386bfdc51b85b880..dec4fc8239017e3ad78fd94a4440265986494527 100644 (file)
                              GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
                interrupt-names = "intr", "msi";
 
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 0>;
+               interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+
                bus-range = <0x00 0xff>;
                #address-cells = <3>;
                #size-cells = <2>;
                        compatible = "nvidia,tegra30-gr2d";
                        reg = <0x54140000 0x00040000>;
                        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&tegra_car TEGRA30_CLK_GR2D>;
                        resets = <&tegra_car 21>;
                        reset-names = "2d";
-                       clocks = <&tegra_car TEGRA30_CLK_GR2D>;
                };
 
                gr3d@54180000 {
index 92693a89160e3714b3bbaadd9b4d19db35d1e422..b0ac6657a17056b1bb2819b167256135c2423c41 100644 (file)
                        reg = <12>;
                        regulator-compatible = "vmmc";
                };
+
+               vbb_reg: regulator@13 {
+                       reg = <13>;
+                       regulator-compatible = "vbb";
+               };
        };
 };
index 4217096ee6777bd292c208a23ba02ad86a2af8c9..86cfc7d15ca71bb9cc2ccffff0ab1985aeddd8e7 100644 (file)
                compatible = "ti,twl4030-pwrbutton";
                interrupts = <8>;
        };
+
+       twl_keypad: keypad {
+               compatible = "ti,twl4030-keypad";
+               interrupts = <1>;
+               keypad,num-rows = <8>;
+               keypad,num-columns = <8>;
+       };
 };
index c42e4f938dcde153355f58d0ed995eda8db08af1..3fd1b74e1216e1b028751ef64e4f84e7af65bcf3 100644 (file)
 &fec1 {
        phy-mode = "rmii";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec1_1>;
+       pinctrl-0 = <&pinctrl_fec1>;
        status = "okay";
 };
 
+&iomuxc {
+       vf610-cosmic {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <
+                               VF610_PAD_PTC9__ENET_RMII1_MDC          0x30d2
+                               VF610_PAD_PTC10__ENET_RMII1_MDIO        0x30d3
+                               VF610_PAD_PTC11__ENET_RMII1_CRS         0x30d1
+                               VF610_PAD_PTC12__ENET_RMII_RXD1         0x30d1
+                               VF610_PAD_PTC13__ENET_RMII1_RXD0        0x30d1
+                               VF610_PAD_PTC14__ENET_RMII1_RXER        0x30d1
+                               VF610_PAD_PTC15__ENET_RMII1_TXD1        0x30d2
+                               VF610_PAD_PTC16__ENET_RMII1_TXD0        0x30d2
+                               VF610_PAD_PTC17__ENET_RMII1_TXEN        0x30d2
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB4__UART1_TX                0x21a2
+                               VF610_PAD_PTB5__UART1_RX                0x21a1
+                       >;
+               };
+       };
+};
+
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
index c8047ca16501324aaed37981ab133c0207d682f7..7dd1d6ede5258e9b45c384bd2384428b0e8a7818 100644 (file)
                };
        };
 
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3p3v: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_vcc_3v3_mcu: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "vcc_3v3_mcu";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+       };
+
+       sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,widgets =
+                       "Microphone", "Microphone Jack",
+                       "Headphone", "Headphone Jack",
+                       "Speaker", "Speaker Ext",
+                       "Line", "Line In Jack";
+               simple-audio-card,routing =
+                       "MIC_IN", "Microphone Jack",
+                       "Microphone Jack", "Mic Bias",
+                       "LINE_IN", "Line In Jack",
+                       "Headphone Jack", "HP_OUT",
+                       "Speaker Ext", "LINE_OUT";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&sai2>;
+                       master-clkdir-out;
+                       frame-master;
+                       bitclock-master;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&codec>;
+                       frame-master;
+                       bitclock-master;
+               };
+       };
+};
+
+&adc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc0_ad5>;
+       vref-supply = <&reg_vcc_3v3_mcu>;
+       status = "okay";
 };
 
 &dspi0 {
        bus-num = <0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_dspi0_1>;
+       pinctrl-0 = <&pinctrl_dspi0>;
        status = "okay";
 
        sflash: at26df081a@0 {
 &fec0 {
        phy-mode = "rmii";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec0_1>;
+       pinctrl-0 = <&pinctrl_fec0>;
        status = "okay";
 };
 
 &fec1 {
        phy-mode = "rmii";
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_fec1_1>;
+       pinctrl-0 = <&pinctrl_fec1>;
        status = "okay";
 };
 
 &i2c0 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c0_1>;
+       pinctrl-0 = <&pinctrl_i2c0>;
+       status = "okay";
+
+       codec: sgtl5000@0a {
+              #sound-dai-cells = <0>;
+              compatible = "fsl,sgtl5000";
+              reg = <0x0a>;
+              VDDA-supply = <&reg_3p3v>;
+              VDDIO-supply = <&reg_3p3v>;
+              clocks = <&clks VF610_CLK_SAI2>;
+       };
+};
+
+&iomuxc {
+       vf610-twr {
+               pinctrl_adc0_ad5: adc0ad5grp {
+                       fsl,pins = <
+                               VF610_PAD_PTC30__ADC0_SE5               0xa1
+                       >;
+               };
+
+               pinctrl_dspi0: dspi0grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB19__DSPI0_CS0              0x1182
+                               VF610_PAD_PTB20__DSPI0_SIN              0x1181
+                               VF610_PAD_PTB21__DSPI0_SOUT             0x1182
+                               VF610_PAD_PTB22__DSPI0_SCK              0x1182
+                       >;
+               };
+
+               pinctrl_fec0: fec0grp {
+                       fsl,pins = <
+                               VF610_PAD_PTA6__RMII_CLKIN              0x30d1
+                               VF610_PAD_PTC0__ENET_RMII0_MDC          0x30d3
+                               VF610_PAD_PTC1__ENET_RMII0_MDIO         0x30d1
+                               VF610_PAD_PTC2__ENET_RMII0_CRS          0x30d1
+                               VF610_PAD_PTC3__ENET_RMII0_RXD1         0x30d1
+                               VF610_PAD_PTC4__ENET_RMII0_RXD0         0x30d1
+                               VF610_PAD_PTC5__ENET_RMII0_RXER         0x30d1
+                               VF610_PAD_PTC6__ENET_RMII0_TXD1         0x30d2
+                               VF610_PAD_PTC7__ENET_RMII0_TXD0         0x30d2
+                               VF610_PAD_PTC8__ENET_RMII0_TXEN         0x30d2
+                       >;
+               };
+
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <
+                               VF610_PAD_PTC9__ENET_RMII1_MDC          0x30d2
+                               VF610_PAD_PTC10__ENET_RMII1_MDIO        0x30d3
+                               VF610_PAD_PTC11__ENET_RMII1_CRS         0x30d1
+                               VF610_PAD_PTC12__ENET_RMII_RXD1         0x30d1
+                               VF610_PAD_PTC13__ENET_RMII1_RXD0        0x30d1
+                               VF610_PAD_PTC14__ENET_RMII1_RXER        0x30d1
+                               VF610_PAD_PTC15__ENET_RMII1_TXD1        0x30d2
+                               VF610_PAD_PTC16__ENET_RMII1_TXD0        0x30d2
+                               VF610_PAD_PTC17__ENET_RMII1_TXEN        0x30d2
+                       >;
+               };
+
+               pinctrl_i2c0: i2c0grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB14__I2C0_SCL               0x30d3
+                               VF610_PAD_PTB15__I2C0_SDA               0x30d3
+                       >;
+               };
+
+               pinctrl_sai2: sai2grp {
+                       fsl,pins = <
+                               VF610_PAD_PTA16__SAI2_TX_BCLK           0x02ed
+                               VF610_PAD_PTA18__SAI2_TX_DATA           0x02ee
+                               VF610_PAD_PTA19__SAI2_TX_SYNC           0x02ed
+                               VF610_PAD_PTA21__SAI2_RX_BCLK           0x02ed
+                               VF610_PAD_PTA22__SAI2_RX_DATA           0x02ed
+                               VF610_PAD_PTA23__SAI2_RX_SYNC           0x02ed
+                               VF610_PAD_PTB18__EXT_AUDIO_MCLK         0x02ed
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               VF610_PAD_PTB4__UART1_TX                0x21a2
+                               VF610_PAD_PTB5__UART1_RX                0x21a1
+                       >;
+               };
+       };
+};
+
+&sai2 {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sai2>;
        status = "okay";
 };
 
 &uart1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_uart1_1>;
+       pinctrl-0 = <&pinctrl_uart1>;
        status = "okay";
 };
index d31ce1b4a7b08df9dab864e633afe665a2400a59..8048733676693de212e505aeae15ae5ad020c01c 100644 (file)
@@ -10,6 +10,7 @@
 #include "skeleton.dtsi"
 #include "vf610-pinfunc.h"
 #include <dt-bindings/clock/vf610-clock.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        aliases {
                                arm,tag-latency = <2 2 2>;
                        };
 
+                       edma0: dma-controller@40018000 {
+                               #dma-cells = <2>;
+                               compatible = "fsl,vf610-edma";
+                               reg = <0x40018000 0x2000>,
+                                       <0x40024000 0x1000>,
+                                       <0x40025000 0x1000>;
+                               interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
+                                               <0 9 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "edma-tx", "edma-err";
+                               dma-channels = <32>;
+                               clock-names = "dmamux0", "dmamux1";
+                               clocks = <&clks VF610_CLK_DMAMUX0>,
+                                       <&clks VF610_CLK_DMAMUX1>;
+                       };
+
                        uart0: serial@40027000 {
                                compatible = "fsl,vf610-lpuart";
                                reg = <0x40027000 0x1000>;
-                               interrupts = <0 61 0x00>;
+                               interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_UART0>;
                                clock-names = "ipg";
+                               dmas = <&edma0 0 2>,
+                                       <&edma0 0 3>;
+                               dma-names = "rx","tx";
                                status = "disabled";
                        };
 
                        uart1: serial@40028000 {
                                compatible = "fsl,vf610-lpuart";
                                reg = <0x40028000 0x1000>;
-                               interrupts = <0 62 0x04>;
+                               interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_UART1>;
                                clock-names = "ipg";
+                               dmas = <&edma0 0 4>,
+                                       <&edma0 0 5>;
+                               dma-names = "rx","tx";
                                status = "disabled";
                        };
 
                        uart2: serial@40029000 {
                                compatible = "fsl,vf610-lpuart";
                                reg = <0x40029000 0x1000>;
-                               interrupts = <0 63 0x04>;
+                               interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_UART2>;
                                clock-names = "ipg";
+                               dmas = <&edma0 0 6>,
+                                       <&edma0 0 7>;
+                               dma-names = "rx","tx";
                                status = "disabled";
                        };
 
                        uart3: serial@4002a000 {
                                compatible = "fsl,vf610-lpuart";
                                reg = <0x4002a000 0x1000>;
-                               interrupts = <0 64 0x04>;
+                               interrupts = <0 64 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_UART3>;
                                clock-names = "ipg";
+                               dmas = <&edma0 0 8>,
+                                       <&edma0 0 9>;
+                               dma-names = "rx","tx";
                                status = "disabled";
                        };
 
                                #size-cells = <0>;
                                compatible = "fsl,vf610-dspi";
                                reg = <0x4002c000 0x1000>;
-                               interrupts = <0 67 0x04>;
+                               interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_DSPI0>;
                                clock-names = "dspi";
                                spi-num-chipselects = <5>;
                        sai2: sai@40031000 {
                                compatible = "fsl,vf610-sai";
                                reg = <0x40031000 0x1000>;
-                               interrupts = <0 86 0x04>;
+                               interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_SAI2>;
                                clock-names = "sai";
+                               dma-names = "tx", "rx";
+                               dmas = <&edma0 0 21>,
+                                       <&edma0 0 20>;
                                status = "disabled";
                        };
 
                        pit: pit@40037000 {
                                compatible = "fsl,vf610-pit";
                                reg = <0x40037000 0x1000>;
-                               interrupts = <0 39 0x04>;
+                               interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_PIT>;
                                clock-names = "pit";
                        };
 
+                       adc0: adc@4003b000 {
+                               compatible = "fsl,vf610-adc";
+                               reg = <0x4003b000 0x1000>;
+                               interrupts = <0 53 0x04>;
+                               clocks = <&clks VF610_CLK_ADC0>;
+                               clock-names = "adc";
+                               status = "disabled";
+                       };
+
                        wdog@4003e000 {
                                compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
                                reg = <0x4003e000 0x1000>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-qspi";
                                reg = <0x40044000 0x1000>;
-                               interrupts = <0 24 0x04>;
+                               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_QSPI0_EN>,
                                        <&clks VF610_CLK_QSPI0>;
                                clock-names = "qspi_en", "qspi";
                                compatible = "fsl,vf610-iomuxc";
                                reg = <0x40048000 0x1000>;
                                #gpio-range-cells = <3>;
-
-                               /* functions and groups pins */
-
-                               dcu0 {
-                                       pinctrl_dcu0_1: dcu0grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTB8__GPIO_30         0x42
-                                               VF610_PAD_PTE0__DCU0_HSYNC      0x42
-                                               VF610_PAD_PTE1__DCU0_VSYNC      0x42
-                                               VF610_PAD_PTE2__DCU0_PCLK       0x42
-                                               VF610_PAD_PTE4__DCU0_DE         0x42
-                                               VF610_PAD_PTE5__DCU0_R0         0x42
-                                               VF610_PAD_PTE6__DCU0_R1         0x42
-                                               VF610_PAD_PTE7__DCU0_R2         0x42
-                                               VF610_PAD_PTE8__DCU0_R3         0x42
-                                               VF610_PAD_PTE9__DCU0_R4         0x42
-                                               VF610_PAD_PTE10__DCU0_R5        0x42
-                                               VF610_PAD_PTE11__DCU0_R6        0x42
-                                               VF610_PAD_PTE12__DCU0_R7        0x42
-                                               VF610_PAD_PTE13__DCU0_G0        0x42
-                                               VF610_PAD_PTE14__DCU0_G1        0x42
-                                               VF610_PAD_PTE15__DCU0_G2        0x42
-                                               VF610_PAD_PTE16__DCU0_G3        0x42
-                                               VF610_PAD_PTE17__DCU0_G4        0x42
-                                               VF610_PAD_PTE18__DCU0_G5        0x42
-                                               VF610_PAD_PTE19__DCU0_G6        0x42
-                                               VF610_PAD_PTE20__DCU0_G7        0x42
-                                               VF610_PAD_PTE21__DCU0_B0        0x42
-                                               VF610_PAD_PTE22__DCU0_B1        0x42
-                                               VF610_PAD_PTE23__DCU0_B2        0x42
-                                               VF610_PAD_PTE24__DCU0_B3        0x42
-                                               VF610_PAD_PTE25__DCU0_B4        0x42
-                                               VF610_PAD_PTE26__DCU0_B5        0x42
-                                               VF610_PAD_PTE27__DCU0_B6        0x42
-                                               VF610_PAD_PTE28__DCU0_B7        0x42
-                                               >;
-                                       };
-                               };
-
-                               dspi0 {
-                                       pinctrl_dspi0_1: dspi0grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTB19__DSPI0_CS0      0x1182
-                                               VF610_PAD_PTB20__DSPI0_SIN      0x1181
-                                               VF610_PAD_PTB21__DSPI0_SOUT     0x1182
-                                               VF610_PAD_PTB22__DSPI0_SCK      0x1182
-                                               >;
-                                       };
-                               };
-
-                               esdhc1 {
-                                       pinctrl_esdhc1_1: esdhc1grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTA24__ESDHC1_CLK     0x31ef
-                                               VF610_PAD_PTA25__ESDHC1_CMD     0x31ef
-                                               VF610_PAD_PTA26__ESDHC1_DAT0    0x31ef
-                                               VF610_PAD_PTA27__ESDHC1_DAT1    0x31ef
-                                               VF610_PAD_PTA28__ESDHC1_DATA2   0x31ef
-                                               VF610_PAD_PTA29__ESDHC1_DAT3    0x31ef
-                                               VF610_PAD_PTA7__GPIO_134        0x219d
-                                               >;
-                                       };
-                               };
-
-                               fec0 {
-                                       pinctrl_fec0_1: fec0grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTA6__RMII_CLKIN      0x30d1
-                                               VF610_PAD_PTC0__ENET_RMII0_MDC  0x30d3
-                                               VF610_PAD_PTC1__ENET_RMII0_MDIO 0x30d1
-                                               VF610_PAD_PTC2__ENET_RMII0_CRS  0x30d1
-                                               VF610_PAD_PTC3__ENET_RMII0_RXD1 0x30d1
-                                               VF610_PAD_PTC4__ENET_RMII0_RXD0 0x30d1
-                                               VF610_PAD_PTC5__ENET_RMII0_RXER 0x30d1
-                                               VF610_PAD_PTC6__ENET_RMII0_TXD1 0x30d2
-                                               VF610_PAD_PTC7__ENET_RMII0_TXD0 0x30d2
-                                               VF610_PAD_PTC8__ENET_RMII0_TXEN 0x30d2
-                                               >;
-                                       };
-                               };
-
-                               fec1 {
-                                       pinctrl_fec1_1: fec1grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTC9__ENET_RMII1_MDC          0x30d2
-                                               VF610_PAD_PTC10__ENET_RMII1_MDIO        0x30d3
-                                               VF610_PAD_PTC11__ENET_RMII1_CRS         0x30d1
-                                               VF610_PAD_PTC12__ENET_RMII_RXD1         0x30d1
-                                               VF610_PAD_PTC13__ENET_RMII1_RXD0        0x30d1
-                                               VF610_PAD_PTC14__ENET_RMII1_RXER        0x30d1
-                                               VF610_PAD_PTC15__ENET_RMII1_TXD1        0x30d2
-                                               VF610_PAD_PTC16__ENET_RMII1_TXD0        0x30d2
-                                               VF610_PAD_PTC17__ENET_RMII1_TXEN        0x30d2
-                                               >;
-                                       };
-                               };
-
-                               i2c0 {
-                                       pinctrl_i2c0_1: i2c0grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTB14__I2C0_SCL       0x30d3
-                                               VF610_PAD_PTB15__I2C0_SDA       0x30d3
-                                               >;
-                                       };
-                               };
-
-                               pwm0 {
-                                       pinctrl_pwm0_1: pwm0grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTB0__FTM0_CH0        0x1582
-                                               VF610_PAD_PTB1__FTM0_CH1        0x1582
-                                               VF610_PAD_PTB2__FTM0_CH2        0x1582
-                                               VF610_PAD_PTB3__FTM0_CH3        0x1582
-                                               VF610_PAD_PTB6__FTM0_CH6        0x1582
-                                               VF610_PAD_PTB7__FTM0_CH7        0x1582
-                                               >;
-                                       };
-                               };
-
-                               qspi0 {
-                                       pinctrl_qspi0_1: qspi0grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTD0__QSPI0_A_QSCK    0x307b
-                                               VF610_PAD_PTD1__QSPI0_A_CS0     0x307f
-                                               VF610_PAD_PTD2__QSPI0_A_DATA3   0x3073
-                                               VF610_PAD_PTD3__QSPI0_A_DATA2   0x3073
-                                               VF610_PAD_PTD4__QSPI0_A_DATA1   0x3073
-                                               VF610_PAD_PTD5__QSPI0_A_DATA0   0x307b
-                                               VF610_PAD_PTD7__QSPI0_B_QSCK    0x307b
-                                               VF610_PAD_PTD8__QSPI0_B_CS0     0x307f
-                                               VF610_PAD_PTD9__QSPI0_B_DATA3   0x3073
-                                               VF610_PAD_PTD10__QSPI0_B_DATA2  0x3073
-                                               VF610_PAD_PTD11__QSPI0_B_DATA1  0x3073
-                                               VF610_PAD_PTD12__QSPI0_B_DATA0  0x307b
-                                               >;
-                                       };
-                               };
-
-                               sai2 {
-                                       pinctrl_sai2_1: sai2grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTA16__SAI2_TX_BCLK   0x02ed
-                                               VF610_PAD_PTA18__SAI2_TX_DATA   0x02ee
-                                               VF610_PAD_PTA19__SAI2_TX_SYNC   0x02ed
-                                               VF610_PAD_PTA21__SAI2_RX_BCLK   0x02ed
-                                               VF610_PAD_PTA22__SAI2_RX_DATA   0x02ed
-                                               VF610_PAD_PTA23__SAI2_RX_SYNC   0x02ed
-                                               VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x02ed
-                                               >;
-                                       };
-                               };
-
-                               uart1 {
-                                       pinctrl_uart1_1: uart1grp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTB4__UART1_TX        0x21a2
-                                               VF610_PAD_PTB5__UART1_RX        0x21a1
-                                               >;
-                                       };
-                               };
-
-                               usbvbus {
-                                       pinctrl_usbvbus_1: usbvbusgrp_1 {
-                                               fsl,pins = <
-                                               VF610_PAD_PTA24__USB1_VBUS_EN   0x219c
-                                               VF610_PAD_PTA16__USB0_VBUS_EN   0x219c
-                                               >;
-                                       };
-                               };
-
                        };
 
                        gpio1: gpio@40049000 {
                                compatible = "fsl,vf610-gpio";
                                reg = <0x40049000 0x1000 0x400ff000 0x40>;
-                               interrupts = <0 107 0x04>;
+                               interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio2: gpio@4004a000 {
                                compatible = "fsl,vf610-gpio";
                                reg = <0x4004a000 0x1000 0x400ff040 0x40>;
-                               interrupts = <0 108 0x04>;
+                               interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio3: gpio@4004b000 {
                                compatible = "fsl,vf610-gpio";
                                reg = <0x4004b000 0x1000 0x400ff080 0x40>;
-                               interrupts = <0 109 0x04>;
+                               interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio4: gpio@4004c000 {
                                compatible = "fsl,vf610-gpio";
                                reg = <0x4004c000 0x1000 0x400ff0c0 0x40>;
-                               interrupts = <0 110 0x04>;
+                               interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                        gpio5: gpio@4004d000 {
                                compatible = "fsl,vf610-gpio";
                                reg = <0x4004d000 0x1000 0x400ff100 0x40>;
-                               interrupts = <0 111 0x04>;
+                               interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-i2c";
                                reg = <0x40066000 0x1000>;
-                               interrupts =<0 71 0x04>;
+                               interrupts =<0 71 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_I2C0>;
                                clock-names = "ipg";
+                               dmas = <&edma0 0 50>,
+                                       <&edma0 0 51>;
+                               dma-names = "rx","tx";
                                status = "disabled";
                        };
 
                        reg = <0x40080000 0x80000>;
                        ranges;
 
+                       edma1: dma-controller@40098000 {
+                               #dma-cells = <2>;
+                               compatible = "fsl,vf610-edma";
+                               reg = <0x40098000 0x2000>,
+                                       <0x400a1000 0x1000>,
+                                       <0x400a2000 0x1000>;
+                               interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>,
+                                               <0 11 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "edma-tx", "edma-err";
+                               dma-channels = <32>;
+                               clock-names = "dmamux0", "dmamux1";
+                               clocks = <&clks VF610_CLK_DMAMUX2>,
+                                       <&clks VF610_CLK_DMAMUX3>;
+                       };
+
                        uart4: serial@400a9000 {
                                compatible = "fsl,vf610-lpuart";
                                reg = <0x400a9000 0x1000>;
-                               interrupts = <0 65 0x04>;
+                               interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_UART4>;
                                clock-names = "ipg";
                                status = "disabled";
                        uart5: serial@400aa000 {
                                compatible = "fsl,vf610-lpuart";
                                reg = <0x400aa000 0x1000>;
-                               interrupts = <0 66 0x04>;
+                               interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_UART5>;
                                clock-names = "ipg";
                                status = "disabled";
                        };
 
+                       adc1: adc@400bb000 {
+                               compatible = "fsl,vf610-adc";
+                               reg = <0x400bb000 0x1000>;
+                               interrupts = <0 54 0x04>;
+                               clocks = <&clks VF610_CLK_ADC1>;
+                               clock-names = "adc";
+                               status = "disabled";
+                       };
+
                        fec0: ethernet@400d0000 {
                                compatible = "fsl,mvf600-fec";
                                reg = <0x400d0000 0x1000>;
-                               interrupts = <0 78 0x04>;
+                               interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_ENET0>,
                                        <&clks VF610_CLK_ENET0>,
                                        <&clks VF610_CLK_ENET>;
                        fec1: ethernet@400d1000 {
                                compatible = "fsl,mvf600-fec";
                                reg = <0x400d1000 0x1000>;
-                               interrupts = <0 79 0x04>;
+                               interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks VF610_CLK_ENET1>,
                                        <&clks VF610_CLK_ENET1>,
                                        <&clks VF610_CLK_ENET>;
index 789d0bacc11025ac2c333be1bb29748dcdeec3d2..511180769af5c0fb31acd6beb58cb1031a417a1d 100644 (file)
                } ;
 
                slcr: slcr@f8000000 {
-                       compatible = "xlnx,zynq-slcr";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "xlnx,zynq-slcr", "syscon";
                        reg = <0xF8000000 0x1000>;
-
-                       clocks {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               clkc: clkc {
-                                       #clock-cells = <1>;
-                                       compatible = "xlnx,ps7-clkc";
-                                       ps-clk-frequency = <33333333>;
-                                       clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
-                                                       "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
-                                                       "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
-                                                       "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
-                                                       "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
-                                                       "dma", "usb0_aper", "usb1_aper", "gem0_aper",
-                                                       "gem1_aper", "sdio0_aper", "sdio1_aper",
-                                                       "spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
-                                                       "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
-                                                       "gpio_aper", "lqspi_aper", "smc_aper", "swdt",
-                                                       "dbg_trc", "dbg_apb";
-                               };
+                       ranges;
+                       clkc: clkc@100 {
+                               #clock-cells = <1>;
+                               compatible = "xlnx,ps7-clkc";
+                               ps-clk-frequency = <33333333>;
+                               fclk-enable = <0>;
+                               clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
+                                               "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
+                                               "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
+                                               "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+                                               "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
+                                               "dma", "usb0_aper", "usb1_aper", "gem0_aper",
+                                               "gem1_aper", "sdio0_aper", "sdio1_aper",
+                                               "spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
+                                               "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
+                                               "gpio_aper", "lqspi_aper", "smc_aper", "swdt",
+                                               "dbg_trc", "dbg_apb";
+                               reg = <0x100 0x100>;
                        };
                };
 
index 4bdc41622c36686df868e2134d6453fe60684b5b..70b1eff477b3af578a8534fd0bed2e4c125286e1 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_SHARP_SCOOP)     += scoop.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
 obj-$(CONFIG_ARM_TIMER_SP804)  += timer-sp.o
 obj-$(CONFIG_MCPM)             += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
+CFLAGS_REMOVE_mcpm_entry.o     = -pg
 AFLAGS_mcpm_head.o             := -march=armv7-a
 AFLAGS_vlock.o                 := -march=armv7-a
 obj-$(CONFIG_TI_PRIV_EDMA)     += edma.o
index a5c3dc38aa1818d29285d16789df7788bd83aa4c..6ef146edd0cd24849757ab82026c6e33ebf9a199 100644 (file)
@@ -232,8 +232,6 @@ static int scoop_probe(struct platform_device *pdev)
 
        return 0;
 
-       if (devptr->gpio.base != -1)
-               temp = gpiochip_remove(&devptr->gpio);
 err_gpio:
        platform_set_drvdata(pdev, NULL);
 err_ioremap:
index 53c6a26b633d678f6d63f530931157aaefc68f84..fd6bff0c5b967a7503c8912c8ef2a52101e4c7eb 100644 (file)
@@ -271,10 +271,14 @@ static void __init integrator_cp_of_init(struct device_node *np)
        void __iomem *base;
        int irq;
        const char *name = of_get_property(np, "compatible", NULL);
+       struct clk *clk;
 
        base = of_iomap(np, 0);
        if (WARN_ON(!base))
                return;
+       clk = of_clk_get(np, 0);
+       if (WARN_ON(IS_ERR(clk)))
+               return;
 
        /* Ensure timer is disabled */
        writel(0, base + TIMER_CTRL);
@@ -283,13 +287,13 @@ static void __init integrator_cp_of_init(struct device_node *np)
                goto err;
 
        if (!init_count)
-               sp804_clocksource_init(base, name);
+               __sp804_clocksource_and_sched_clock_init(base, name, clk, 0);
        else {
                irq = irq_of_parse_and_map(np, 0);
                if (irq <= 0)
                        goto err;
 
-               sp804_clockevents_init(base, irq, name);
+               __sp804_clockevents_init(base, irq, clk, name);
        }
 
        init_count++;
index cb26c62dc7228a47335f79e50f32029721cc8bf5..bb396c0e5fda6d4067dec7d5bcdffa2652184436 100644 (file)
@@ -48,6 +48,8 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6_SIT is not set
 CONFIG_NETFILTER=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_NETDEVICES=y
 # CONFIG_NET_CADENCE is not set
index 9287a62de830424737e136e412d3239757c2251e..065adddeee3ec4d77bcba307f3dd0972ed85d9e3 100644 (file)
@@ -58,6 +58,8 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_MD=y
index 0b4e9b5210d8dc29435990acd6f0a37b223c62c8..300ded9acbe92a3e5ac05955abe00d5d547092b0 100644 (file)
@@ -16,10 +16,12 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_AT91=y
 CONFIG_SOC_AT91RM9200=y
 CONFIG_SOC_AT91SAM9260=y
+CONFIG_SOC_AT91SAM9261=y
 CONFIG_SOC_AT91SAM9263=y
 CONFIG_SOC_AT91SAM9G45=y
 CONFIG_SOC_AT91SAM9X5=y
 CONFIG_SOC_AT91SAM9N12=y
+CONFIG_SOC_AT91SAM9RL=y
 CONFIG_MACH_AT91RM9200_DT=y
 CONFIG_MACH_AT91SAM9_DT=y
 CONFIG_AT91_TIMER_HZ=128
@@ -119,6 +121,7 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
 # CONFIG_SERIO is not set
 CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_ATMEL=y
index 2cd832918e9ccb7a51d9893c2c6f4e17366b284d..c4c160fc87918463ebdf7360130499a69af376c7 100644 (file)
@@ -3,6 +3,7 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
@@ -30,15 +31,12 @@ CONFIG_MACH_AT91SAM9_DT=y
 CONFIG_AT91_SLOW_CLOCK=y
 # CONFIG_ARM_THUMB is not set
 CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
 CONFIG_AUTO_ZRELADDR=y
-CONFIG_FPE_NWFPE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -57,15 +55,14 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT25=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
@@ -112,8 +109,6 @@ CONFIG_SND_PCM_OSS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_VERBOSE_PROCFS is not set
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_MON=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_STORAGE=y
index 7b6f131cecd6701f553de8f4e479c0c92de952c5..85f846ae9ff21e77d8126bda271660f108c0cc75 100644 (file)
@@ -1,8 +1,8 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EMBEDDED=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
@@ -14,20 +14,23 @@ CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9RL=y
 CONFIG_MACH_AT91SAM9RLEK=y
 # CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,17105363 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
+CONFIG_AUTO_ZRELADDR=y
 CONFIG_NET=y
 CONFIG_UNIX=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=4
@@ -66,6 +69,7 @@ CONFIG_EXT2_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
 CONFIG_CRAMFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
index f43392dc2dcf659c1b1ac4d8a6b524e21f106cd6..0302d293fba0e54d3b236ceb94418b6471922523 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_OPROFILE=y
 CONFIG_JUMP_LABEL=y
 CONFIG_ARCH_MULTI_V6=y
 # CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_BCM=y
 CONFIG_ARCH_BCM2835=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_AEABI=y
index 2519d6de064012be7b17ca38c9e2f6e921780d8c..01004640ee4d0dc206bc239e06fce21f8fd3625f 100644 (file)
@@ -79,6 +79,13 @@ CONFIG_HW_RANDOM=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 # CONFIG_HWMON is not set
+CONFIG_MFD_BCM590XX=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_BCM590XX=y
+
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
index 80cff50beb34ab930709077d03d9a69d72481f5b..e816140d81c5f810370fb3a21007e87fb06faff6 100644 (file)
@@ -44,6 +44,8 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
index 9e8c8316d6b074004686ab7f86cb133c59729767..0facf9da047c2787a4dd7a85a6108964b9a4776f 100644 (file)
@@ -15,7 +15,6 @@ CONFIG_ARCH_CDB89712=y
 CONFIG_ARCH_CLEP7312=y
 CONFIG_ARCH_EDB7211=y
 CONFIG_ARCH_P720T=y
-CONFIG_ARCH_FORTUNET=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
@@ -27,7 +26,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 CONFIG_IRDA=y
 CONFIG_IRTTY_SIR=y
-CONFIG_EP7211_DONGLE=y
 # CONFIG_WIRELESS is not set
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -58,6 +56,7 @@ CONFIG_CS89x0_PLATFORM=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
+CONFIG_SERIAL_CLPS711X=y
 CONFIG_SERIAL_CLPS711X_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig
deleted file mode 100644 (file)
index 1571bea..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CGROUPS=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_DAVINCI=y
-CONFIG_ARCH_DAVINCI_DA830=y
-CONFIG_ARCH_DAVINCI_DA850=y
-CONFIG_MACH_DA8XX_DT=y
-CONFIG_MACH_MITYOMAPL138=y
-CONFIG_MACH_OMAPL138_HAWKBOARD=y
-CONFIG_DAVINCI_RESET_CLOCKS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_LEDS=y
-CONFIG_USE_OF=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
-CONFIG_CPU_FREQ_GOV_ONDEMAND=m
-CONFIG_CPU_IDLE=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_LRO is not set
-CONFIG_NETFILTER=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_FW_LOADER is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_EEPROM_AT24=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_NETDEVICES=y
-CONFIG_TUN=m
-CONFIG_LXT_PHY=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_TI_DAVINCI_EMAC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_NETCONSOLE=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-CONFIG_KEYBOARD_ATKBD=m
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_XTKBD=m
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_DAVINCI=y
-CONFIG_PINCTRL_SINGLE=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_DUMMY=y
-CONFIG_REGULATOR_TPS6507X=y
-CONFIG_FB=y
-CONFIG_FB_DA8XX=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SOC=m
-CONFIG_SND_DAVINCI_SOC=m
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_DMADEVICES=y
-CONFIG_TI_EDMA=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_XFS_FS=m
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_MINIX_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_TIMER_STATS=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=m
-CONFIG_CRC_T10DIF=m
index ab2f7378352c7e1861bac50cf4a21527a7d9564c..2a282c051cfd8bf7c3daf91864dd96a1c27301cc 100644 (file)
@@ -20,9 +20,14 @@ CONFIG_ARCH_DAVINCI_DM644x=y
 CONFIG_ARCH_DAVINCI_DM355=y
 CONFIG_ARCH_DAVINCI_DM646x=y
 CONFIG_ARCH_DAVINCI_DM365=y
+CONFIG_ARCH_DAVINCI_DA830=y
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_MACH_DA8XX_DT=y
 CONFIG_MACH_SFFSDR=y
 CONFIG_MACH_NEUROS_OSD2=y
 CONFIG_MACH_DM355_LEOPARD=y
+CONFIG_MACH_MITYOMAPL138=y
+CONFIG_MACH_OMAPL138_HAWKBOARD=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
 CONFIG_DAVINCI_RESET_CLOCKS=y
@@ -32,8 +37,18 @@ CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
 CONFIG_LEDS=y
+CONFIG_USE_OF=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_IDLE=y
 CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -57,6 +72,7 @@ CONFIG_MTD_CFI_AMDSTD=m
 CONFIG_MTD_PHYSMAP=m
 CONFIG_MTD_NAND=m
 CONFIG_MTD_NAND_DAVINCI=m
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=1
@@ -71,6 +87,7 @@ CONFIG_TUN=m
 CONFIG_LXT_PHY=y
 CONFIG_LSI_ET1011C_PHY=y
 CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
 CONFIG_TI_DAVINCI_EMAC=y
 CONFIG_DM9000=y
 # CONFIG_NETDEV_1000 is not set
@@ -97,15 +114,21 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=3
 # CONFIG_HW_RANDOM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_DAVINCI=y
+CONFIG_PINCTRL_SINGLE=y
 CONFIG_GPIO_PCF857X=y
 CONFIG_WATCHDOG=y
 CONFIG_DAVINCI_WATCHDOG=m
 CONFIG_MFD_DM355EVM_MSP=y
+CONFIG_TPS6507X=y
 CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_TPS6507X=y
 CONFIG_FB=y
+CONFIG_FB_DA8XX=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -198,3 +221,5 @@ CONFIG_DEBUG_ERRORS=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_T10DIF=m
+CONFIG_GPIO_PCA953X=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
index 11010547684851b8af0be967296705a8b7bcfb53..f1595514417560858f3fb517b561aab6b2553a1a 100644 (file)
@@ -48,7 +48,6 @@ CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_M25P80=y
-CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=1
@@ -80,6 +79,8 @@ CONFIG_SPI_ORION=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 CONFIG_DOVE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
index dbe1f1c47bb0defeb03635030fe9ec0f3ba8a42e..4ce7b70ea9011634de2bcb9f1b0ff4f29e046ecd 100644 (file)
@@ -94,7 +94,7 @@ CONFIG_FONT_7x14=y
 CONFIG_LOGO=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_S5P=y
+CONFIG_USB_EHCI_EXYNOS=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_PHY=y
index aa0b704f48aff540d049ad7bb12eb84d2b029217..d238fafb67622a2ee72bfe57fd3de5394430ce91 100644 (file)
@@ -50,6 +50,9 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_EEPROM_AT24=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_CORE is not set
 # CONFIG_NET_VENDOR_ARC is not set
@@ -78,7 +81,10 @@ CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=10
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_I2C_SH_MOBILE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_RIIC=y
+CONFIG_SPI=y
+CONFIG_SPI_RSPI=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 CONFIG_RCAR_THERMAL=y
index 6309ee52ccfcb3d74563f8ea6d5bfe396daf546c..f1aeb7d727125a7d11925b50ac4358cb6f328349 100644 (file)
@@ -154,6 +154,7 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
 CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
index 53e82c2523ebe0bbff2b1ddde62ab9a026799dd9..09e974392fa119f09ef2790e63d58410b5367e4a 100644 (file)
@@ -39,6 +39,8 @@ CONFIG_SOC_IMX53=y
 CONFIG_SOC_IMX6Q=y
 CONFIG_SOC_IMX6SL=y
 CONFIG_SOC_VF610=y
+CONFIG_PCI=y
+CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT_VOLUNTARY=y
@@ -165,6 +167,7 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_REGULATOR_PFUZE100=y
@@ -186,6 +189,7 @@ CONFIG_LCD_L4F00242T03=y
 CONFIG_LCD_PLATFORM=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_GPIO=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
@@ -211,6 +215,7 @@ CONFIG_USB_GADGET=y
 CONFIG_USB_ETH=m
 CONFIG_USB_MASS_STORAGE=m
 CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
@@ -225,6 +230,7 @@ CONFIG_LEDS_TRIGGER_BACKLIGHT=y
 CONFIG_LEDS_TRIGGER_GPIO=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
 CONFIG_RTC_DRV_SNVS=y
@@ -277,6 +283,7 @@ CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_PROVE_LOCKING=y
index 4582e160feab4ebbe01b1b40d5e5dd969d2289d7..ec9a41d506803ef1fe9eb5bd247d92c8065a4bb0 100644 (file)
@@ -111,6 +111,7 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_PLATRAM=y
 CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_DAVINCI=y
 CONFIG_MTD_UBI=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
@@ -131,6 +132,8 @@ CONFIG_SPI_DAVINCI=y
 CONFIG_SPI_SPIDEV=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_DAVINCI_WATCHDOG=y
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -145,6 +148,7 @@ CONFIG_DMADEVICES=y
 CONFIG_TI_EDMA=y
 CONFIG_COMMON_CLK_DEBUG=y
 CONFIG_MEMORY=y
+CONFIG_TI_AEMIF=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_MSDOS_FS=y
@@ -177,3 +181,14 @@ CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
 CONFIG_CRYPTO_USER_API_HASH=y
 CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_DAVINCI=y
+CONFIG_LEDS_CLASS=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
index e248f49d55498491d00434467826a512d2fe9c2a..86faab565a9601f54ef90fdc912b0bc8d03144d0 100644 (file)
@@ -8,7 +8,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
-# CONFIG_BLOCK is not set
 CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A7791=y
 CONFIG_MACH_KOELSCH=y
@@ -35,7 +34,14 @@ CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_RCAR=y
+CONFIG_MTD=y
+CONFIG_MTD_M25P80=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
@@ -53,18 +59,31 @@ CONFIG_SH_ETH=y
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=20
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_RSPI=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_RCAR=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 CONFIG_RCAR_THERMAL=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_DNOTIFY is not set
 CONFIG_TMPFS=y
diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig
deleted file mode 100644 (file)
index e42ce37..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-# CONFIG_ARM_PATCH_PHYS_VIRT is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_NO_HZ=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_EMBEDDED=y
-CONFIG_PERF_EVENTS=y
-CONFIG_SLAB=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE_LEGACY=y
-CONFIG_ARCH_EMEV2=y
-CONFIG_MACH_KZM9D=y
-CONFIG_MEMORY_START=0x40000000
-CONFIG_MEMORY_SIZE=0x10000000
-# CONFIG_SH_TIMER_TMU is not set
-# CONFIG_SWP_EMULATE is not set
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_HOTPLUG_CPU=y
-# CONFIG_LOCAL_TIMERS is not set
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_CROSS_MEMORY_ATTACH is not set
-CONFIG_FORCE_MAX_ZONEORDER=13
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_VFP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_BLK_DEV is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
-# CONFIG_NET_VENDOR_CIRRUS is not set
-# CONFIG_NET_VENDOR_FARADAY is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-CONFIG_SMSC911X=y
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EM=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_EM=y
-# CONFIG_HWMON is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-# CONFIG_FTRACE is not set
index 9934dbc23d64f7892d09e213720cbf0ff6b581c8..12bd1f63c39944d20d7e277840e8f8d2af53b87b 100644 (file)
@@ -60,6 +60,8 @@ CONFIG_IRDA=y
 CONFIG_SH_IRDA=y
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
index 883443f8f4f30ec5af446e5683e08cfad512b3e8..58702440472a7ae16ce3c784079bc279332220c2 100644 (file)
@@ -49,6 +49,13 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_RCAR=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_CORE is not set
 # CONFIG_NET_VENDOR_ARC is not set
@@ -81,6 +88,8 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_I2C=y
 CONFIG_I2C_GPIO=y
 CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_RSPI=y
 CONFIG_GPIO_SH_PFC=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_RCAR=y
@@ -90,8 +99,20 @@ CONFIG_RCAR_THERMAL=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_VIDEO_RCAR_VIN=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_ADV7180=y
 CONFIG_DRM=y
 CONFIG_DRM_RCAR_DU=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_RCAR=y
 # CONFIG_USB_SUPPORT is not set
 CONFIG_MMC=y
 CONFIG_MMC_SDHI=y
index a61e1653fc5e07c728b5cc17048968818ed53117..57ececba2ae6489e90198dd2d0da1592fe5310c8 100644 (file)
@@ -42,6 +42,8 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
index f21bd405cc2a4f3d756bc11cae91f8f332f41732..92994f7f6fd8f562106c19fc6147a468e9d86fc7 100644 (file)
@@ -43,6 +43,8 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
new file mode 100644 (file)
index 0000000..aa3dfb0
--- /dev/null
@@ -0,0 +1,190 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_KIRKWOOD=y
+CONFIG_MACH_T5325=y
+CONFIG_ARCH_MXC=y
+CONFIG_MACH_IMX25_DT=y
+CONFIG_MACH_IMX27_DT=y
+CONFIG_ARCH_U300=y
+CONFIG_PCI_MVEBU=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_KIRKWOOD_CPUIDLE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NET_PKTGEN=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ORION=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_EEPROM_AT24=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_MV643XX_ETH=y
+CONFIG_R8169=y
+CONFIG_MARVELL_PHY=y
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_I2C_NOMADIK=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_QNAP=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_SENSORS_LM63=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_LM85=y
+CONFIG_THERMAL=y
+CONFIG_KIRKWOOD_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_KIRKWOOD_SOC=y
+CONFIG_SND_KIRKWOOD_SOC_T5325=y
+# CONFIG_ABX500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_STAGING=y
+CONFIG_FB_XGI=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_MV_CESA=y
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
index ee6982976d661d0086ff9886851ec9948e4ee909..d4e8a47a2f7c8a016b8eee0adaf36e24bb0c341a 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
 CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -9,8 +10,12 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
+CONFIG_MACH_ARMADA_375=y
+CONFIG_MACH_ARMADA_38X=y
 CONFIG_MACH_ARMADA_XP=y
+CONFIG_MACH_DOVE=y
 CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_5301X=y
 CONFIG_ARCH_BCM_MOBILE=y
 CONFIG_ARCH_BERLIN=y
 CONFIG_MACH_BERLIN_BG2=y
@@ -31,6 +36,10 @@ CONFIG_SOC_OMAP5=y
 CONFIG_SOC_AM33XX=y
 CONFIG_SOC_DRA7XX=y
 CONFIG_SOC_AM43XX=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
 CONFIG_ARCH_ROCKCHIP=y
 CONFIG_ARCH_SOCFPGA=y
 CONFIG_PLAT_SPEAR=y
@@ -55,6 +64,7 @@ CONFIG_ARCH_VEXPRESS_CA9X4=y
 CONFIG_ARCH_VIRT=y
 CONFIG_ARCH_WM8850=y
 CONFIG_ARCH_ZYNQ=y
+CONFIG_NEON=y
 CONFIG_TRUSTED_FOUNDATIONS=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
@@ -94,6 +104,7 @@ CONFIG_RFKILL_GPIO=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_OMAP_OCP2SCP=y
 CONFIG_MTD=y
 CONFIG_MTD_M25P80=y
@@ -111,6 +122,7 @@ CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_MV643XX_ETH=y
 CONFIG_MVNETA=y
 CONFIG_KS8851=y
 CONFIG_R8169=y
@@ -146,6 +158,8 @@ CONFIG_SERIAL_SIRFSOC_CONSOLE=y
 CONFIG_SERIAL_TEGRA=y
 CONFIG_SERIAL_IMX=y
 CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_VT8500=y
 CONFIG_SERIAL_VT8500_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
@@ -159,6 +173,7 @@ CONFIG_SERIAL_ST_ASC=y
 CONFIG_SERIAL_ST_ASC_CONSOLE=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_MUX_PINCTRL=y
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_MV64XXX=y
@@ -187,7 +202,10 @@ CONFIG_POWER_RESET_AS3722=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_SENSORS_LM90=y
 CONFIG_THERMAL=y
+CONFIG_DOVE_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
 CONFIG_MFD_AS3722=y
 CONFIG_MFD_CROS_EC=y
 CONFIG_MFD_CROS_EC_SPI=y
@@ -212,6 +230,8 @@ CONFIG_REGULATOR_VEXPRESS=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_USB_GSPCA=y
 CONFIG_DRM=y
 CONFIG_DRM_TEGRA=y
 CONFIG_DRM_PANEL_SIMPLE=y
@@ -254,6 +274,7 @@ CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_SPEAR=y
 CONFIG_MMC_SDHCI_BCM_KONA=y
 CONFIG_MMC_OMAP=y
@@ -294,6 +315,10 @@ CONFIG_MFD_NVEC=y
 CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_MEMORY=y
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
deleted file mode 100644 (file)
index 0f4511d..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IRQ_DOMAIN_DEBUG=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_ARCH_MVEBU=y
-CONFIG_MACH_ARMADA_370=y
-CONFIG_MACH_ARMADA_XP=y
-# CONFIG_CACHE_L2X0 is not set
-# CONFIG_SWP_EMULATE is not set
-CONFIG_PCI=y
-CONFIG_PCI_MVEBU=y
-CONFIG_SMP=y
-CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
-# CONFIG_COMPACTION is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_VFP=y
-CONFIG_NET=y
-CONFIG_INET=y
-CONFIG_BT=y
-CONFIG_BT_MRVL=y
-CONFIG_BT_MRVL_SDIO=y
-CONFIG_CFG80211=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_SATA_MV=y
-CONFIG_NETDEVICES=y
-CONFIG_MVNETA=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MWIFIEX=y
-CONFIG_MWIFIEX_SDIO=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_SPI=y
-CONFIG_SPI_ORION=y
-CONFIG_I2C_MV64XXX=y
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PXA3xx=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_THERMAL=y
-CONFIG_ARMADA_THERMAL=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_MMC=y
-CONFIG_MMC_MVSDIO=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_CLASS=m
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_S35390A=y
-CONFIG_RTC_DRV_MV=y
-CONFIG_DMADEVICES=y
-CONFIG_MV_XOR=y
-CONFIG_MEMORY=y
-CONFIG_MVEBU_DEVBUS=y
-# CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig
new file mode 100644 (file)
index 0000000..36484a3
--- /dev/null
@@ -0,0 +1,181 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_KIRKWOOD=y
+CONFIG_MACH_T5325=y
+# CONFIG_CPU_FEROCEON_OLD_ID is not set
+CONFIG_PCI_MVEBU=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NET_PKTGEN=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ORION=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_EEPROM_AT24=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_MV643XX_ETH=y
+CONFIG_R8169=y
+CONFIG_MARVELL_PHY=y
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_QNAP=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_SENSORS_LM63=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_LM85=y
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_KIRKWOOD_SOC=y
+CONFIG_SND_KIRKWOOD_SOC_T5325=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_STAGING=y
+CONFIG_FB_XGI=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_MV_CESA=y
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
new file mode 100644 (file)
index 0000000..a34713d
--- /dev/null
@@ -0,0 +1,117 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_ARMADA_370=y
+CONFIG_MACH_ARMADA_375=y
+CONFIG_MACH_ARMADA_38X=y
+CONFIG_MACH_ARMADA_XP=y
+CONFIG_NEON=y
+# CONFIG_CACHE_L2X0 is not set
+# CONFIG_SWP_EMULATE is not set
+CONFIG_PCI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_SMP=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+# CONFIG_COMPACTION is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
+CONFIG_NET=y
+CONFIG_INET=y
+CONFIG_BT=y
+CONFIG_BT_MRVL=y
+CONFIG_BT_MRVL_SDIO=y
+CONFIG_CFG80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_MVNETA=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MWIFIEX=y
+CONFIG_MWIFIEX_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_THERMAL=y
+CONFIG_ARMADA_THERMAL=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_KIRKWOOD_SOC=y
+CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_MMC=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_MEMORY=y
+CONFIG_MVEBU_DEVBUS=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
index 3a0b53d225e7093098d87398e55dba32ecfef98b..364ba38e40f3138317ef10407588b356732ab729 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_ARCH_OMAP3=y
 CONFIG_ARCH_OMAP4=y
 CONFIG_SOC_OMAP5=y
 CONFIG_SOC_AM33XX=y
+CONFIG_SOC_AM43XX=y
 CONFIG_SOC_DRA7XX=y
 CONFIG_ARM_THUMBEE=y
 CONFIG_ARM_ERRATA_411920=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
new file mode 100644 (file)
index 0000000..83b0725
--- /dev/null
@@ -0,0 +1,129 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_SHMOBILE_MULTI=y
+CONFIG_ARCH_EMEV2=y
+CONFIG_ARCH_R8A7790=y
+CONFIG_ARCH_R8A7791=y
+CONFIG_MACH_KOELSCH=y
+CONFIG_MACH_LAGER=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_CPU_BPREDICT_DISABLE=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_PCI=y
+CONFIG_PCI_RCAR_GEN2=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_NR_CPUS=8
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_KEXEC=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_RCAR=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_SH_ETH=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_EM=y
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=20
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_RSPI=y
+CONFIG_GPIO_EM=y
+CONFIG_GPIO_RCAR=y
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_VIDEO_RCAR_VIN=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_VIDEO_ADV7180=y
+CONFIG_DRM=y
+CONFIG_DRM_RCAR_DU=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_RCAR=y
+CONFIG_USB_RCAR_GEN2_PHY=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_ARM_UNWIND is not set
index 4e1ce211d43f101153f676cc2114a791b4a6ea52..e3a05e8801d8f318ccafba40660471f7c25aea88 100644 (file)
@@ -52,6 +52,7 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_STMMAC_ETH=y
+CONFIG_MICREL_PHY=y
 # CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_SERIO_SERPORT is not set
@@ -66,6 +67,9 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT3_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY_USER is not set
 CONFIG_VFAT_FS=y
@@ -82,3 +86,5 @@ CONFIG_DEBUG_INFO=y
 CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DEBUG_USER=y
 CONFIG_XZ_DEC=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
index 3e2259b60236d76af041a1a6eb3ef99cab7975a6..b5df4a511b0acdfea6df30b7dd4b9753d2b00f9a 100644 (file)
@@ -24,6 +24,7 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_EEPROM_SUNXI_SID=y
 CONFIG_NETDEVICES=y
 CONFIG_SUN4I_EMAC=y
 # CONFIG_NET_CADENCE is not set
@@ -48,6 +49,8 @@ CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+CONFIG_SPI_SUN6I=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
index 27d69b558c5de2caf1be2b9ac79388ae997f562a..2926281368ab663aef5c09470a9dbbd0c728c0e8 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
@@ -86,6 +87,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_MTD=y
 CONFIG_MTD_M25P80=y
 CONFIG_PROC_DEVICETREE=y
@@ -125,6 +127,7 @@ CONFIG_SERIAL_TEGRA=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_MUX_PINCTRL=y
 CONFIG_I2C_TEGRA=y
 CONFIG_SPI=y
@@ -141,6 +144,7 @@ CONFIG_POWER_SUPPLY=y
 CONFIG_BATTERY_SBS=y
 CONFIG_CHARGER_TPS65090=y
 CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_AS3722=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_SENSORS_LM90=y
 CONFIG_MFD_AS3722=y
@@ -166,7 +170,8 @@ CONFIG_REGULATOR_TPS65910=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_USB_SUPPORT=y
-CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_USB_GSPCA=y
 CONFIG_DRM=y
 CONFIG_DRM_TEGRA=y
 CONFIG_DRM_PANEL_SIMPLE=y
index bb00ccf00d662e0c66d4aba76e45a09f78c42ae3..ad396af68e47024fee4c517753dd94f60265cd7e 100644 (file)
@@ -11,6 +11,7 @@ menu "Firmware options"
 config TRUSTED_FOUNDATIONS
        bool "Trusted Foundations secure monitor support"
        depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
+       default y
        help
          Some devices (including most Tegra-based consumer devices on the
          market) are booted with the Trusted Foundations secure monitor
@@ -20,7 +21,7 @@ config TRUSTED_FOUNDATIONS
          This option allows the kernel to invoke the secure monitor whenever
          required on devices using Trusted Foundations. See
          arch/arm/include/asm/trusted_foundations.h or the
-         tl,trusted-foundations device tree binding documentation for details
+         tlm,trusted-foundations device tree binding documentation for details
          on how to use it.
 
          Say n if you don't know what this is about.
index ef1e3d8f4af0b7532a68651c7b56515ce5727013..3fb1b5a1dce968d028c8f17057c277e29302caaf 100644 (file)
 
 #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
 
+#define TF_CPU_PM              0xfffffffc
+#define TF_CPU_PM_S3           0xffffffe3
+#define TF_CPU_PM_S2           0xffffffe6
+#define TF_CPU_PM_S2_NO_MC_CLK 0xffffffe5
+#define TF_CPU_PM_S1           0xffffffe4
+#define TF_CPU_PM_S1_NOFLUSH_L2        0xffffffe7
+
+static unsigned long cpu_boot_addr;
+
 static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
 {
        asm volatile(
@@ -41,13 +50,22 @@ static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
 
 static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
 {
-       tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, boot_addr, 0);
+       cpu_boot_addr = boot_addr;
+       tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, cpu_boot_addr, 0);
+
+       return 0;
+}
+
+static int tf_prepare_idle(void)
+{
+       tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2, cpu_boot_addr);
 
        return 0;
 }
 
 static const struct firmware_ops trusted_foundations_ops = {
        .set_cpu_boot_addr = tf_set_cpu_boot_addr,
+       .prepare_idle = tf_prepare_idle,
 };
 
 void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
index 5c228516057552b6eca4f6f5a54f2a3f9733fd09..380ac4f20000c8c33d1744da3898d71e3f4b7c68 100644 (file)
@@ -30,8 +30,8 @@
  * Endian independent macros for shifting bytes within registers.
  */
 #ifndef __ARMEB__
-#define pull            lsr
-#define push            lsl
+#define lspull          lsr
+#define lspush          lsl
 #define get_byte_0      lsl #0
 #define get_byte_1     lsr #8
 #define get_byte_2     lsr #16
@@ -41,8 +41,8 @@
 #define put_byte_2     lsl #16
 #define put_byte_3     lsl #24
 #else
-#define pull            lsl
-#define push            lsr
+#define lspull          lsl
+#define lspush          lsr
 #define get_byte_0     lsr #24
 #define get_byte_1     lsr #16
 #define get_byte_2     lsr #8
index 62d2cb53b06935aed4430bf33c6a127239801ff1..9a92fd7864a841a989942048c8f6beb6ad9890c1 100644 (file)
@@ -60,6 +60,7 @@ static inline int atomic_add_return(int i, atomic_t *v)
        int result;
 
        smp_mb();
+       prefetchw(&v->counter);
 
        __asm__ __volatile__("@ atomic_add_return\n"
 "1:    ldrex   %0, [%3]\n"
@@ -99,6 +100,7 @@ static inline int atomic_sub_return(int i, atomic_t *v)
        int result;
 
        smp_mb();
+       prefetchw(&v->counter);
 
        __asm__ __volatile__("@ atomic_sub_return\n"
 "1:    ldrex   %0, [%3]\n"
@@ -121,6 +123,7 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
        unsigned long res;
 
        smp_mb();
+       prefetchw(&ptr->counter);
 
        do {
                __asm__ __volatile__("@ atomic_cmpxchg\n"
@@ -138,6 +141,33 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
        return oldval;
 }
 
+static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+       int oldval, newval;
+       unsigned long tmp;
+
+       smp_mb();
+       prefetchw(&v->counter);
+
+       __asm__ __volatile__ ("@ atomic_add_unless\n"
+"1:    ldrex   %0, [%4]\n"
+"      teq     %0, %5\n"
+"      beq     2f\n"
+"      add     %1, %0, %6\n"
+"      strex   %2, %1, [%4]\n"
+"      teq     %2, #0\n"
+"      bne     1b\n"
+"2:"
+       : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
+       : "r" (&v->counter), "r" (u), "r" (a)
+       : "cc");
+
+       if (oldval != u)
+               smp_mb();
+
+       return oldval;
+}
+
 #else /* ARM_ARCH_6 */
 
 #ifdef CONFIG_SMP
@@ -186,10 +216,6 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
        return ret;
 }
 
-#endif /* __LINUX_ARM_ARCH__ */
-
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-
 static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 {
        int c, old;
@@ -200,6 +226,10 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
        return c;
 }
 
+#endif /* __LINUX_ARM_ARCH__ */
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 #define atomic_inc(v)          atomic_add(1, v)
 #define atomic_dec(v)          atomic_sub(1, v)
 
@@ -299,6 +329,7 @@ static inline long long atomic64_add_return(long long i, atomic64_t *v)
        unsigned long tmp;
 
        smp_mb();
+       prefetchw(&v->counter);
 
        __asm__ __volatile__("@ atomic64_add_return\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
@@ -340,6 +371,7 @@ static inline long long atomic64_sub_return(long long i, atomic64_t *v)
        unsigned long tmp;
 
        smp_mb();
+       prefetchw(&v->counter);
 
        __asm__ __volatile__("@ atomic64_sub_return\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
@@ -364,6 +396,7 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
        unsigned long res;
 
        smp_mb();
+       prefetchw(&ptr->counter);
 
        do {
                __asm__ __volatile__("@ atomic64_cmpxchg\n"
@@ -388,6 +421,7 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
        unsigned long tmp;
 
        smp_mb();
+       prefetchw(&ptr->counter);
 
        __asm__ __volatile__("@ atomic64_xchg\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
@@ -409,6 +443,7 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v)
        unsigned long tmp;
 
        smp_mb();
+       prefetchw(&v->counter);
 
        __asm__ __volatile__("@ atomic64_dec_if_positive\n"
 "1:    ldrexd  %0, %H0, [%3]\n"
@@ -436,6 +471,7 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
        int ret = 1;
 
        smp_mb();
+       prefetchw(&v->counter);
 
        __asm__ __volatile__("@ atomic64_add_unless\n"
 "1:    ldrexd  %0, %H0, [%4]\n"
index df2fbba7efc80d57074a6053704a9c70119aae03..abb2c3769b014e33ad4a70f87a374b30911de4b3 100644 (file)
@@ -2,6 +2,7 @@
 #define __ASM_ARM_CMPXCHG_H
 
 #include <linux/irqflags.h>
+#include <linux/prefetch.h>
 #include <asm/barrier.h>
 
 #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
@@ -35,6 +36,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
 #endif
 
        smp_mb();
+       prefetchw((const void *)ptr);
 
        switch (size) {
 #if __LINUX_ARM_ARCH__ >= 6
@@ -138,6 +140,8 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 {
        unsigned long oldval, res;
 
+       prefetchw((const void *)ptr);
+
        switch (size) {
 #ifndef CONFIG_CPU_V6  /* min ARCH >= ARMv6K */
        case 1:
@@ -230,6 +234,8 @@ static inline unsigned long long __cmpxchg64(unsigned long long *ptr,
        unsigned long long oldval;
        unsigned long res;
 
+       prefetchw(ptr);
+
        __asm__ __volatile__(
 "1:    ldrexd          %1, %H1, [%3]\n"
 "      teq             %1, %4\n"
index acdde76b39bbae3064034fff78b9dd2b95bbd39c..42f0889f058456be8e1c34705ae0e2aa12364baf 100644 (file)
@@ -71,6 +71,7 @@
 #define ARM_CPU_PART_CORTEX_A5         0xC050
 #define ARM_CPU_PART_CORTEX_A15                0xC0F0
 #define ARM_CPU_PART_CORTEX_A7         0xC070
+#define ARM_CPU_PART_CORTEX_A12                0xC0D0
 
 #define ARM_CPU_XSCALE_ARCH_MASK       0xe000
 #define ARM_CPU_XSCALE_ARCH_V1         0x2000
index 15631300c238bbf16cc2c02e2311e774d7c9d95b..2c9f10df7568d5c77010f0cf8e4e08b1bc820082 100644 (file)
  * A filled up structure can be registered with register_firmware_ops().
  */
 struct firmware_ops {
+       /*
+        * Inform the firmware we intend to enter CPU idle mode
+        */
+       int (*prepare_idle)(void);
        /*
         * Enters CPU idle mode
         */
index c9f03eccc9d86ce76c022d519b4ba66623aa3935..f4882553fbb0125927776c0f3a032625937649c6 100644 (file)
@@ -25,7 +25,7 @@
 
 #define fd_inb(port)           inb((port))
 #define fd_request_irq()       request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
-                                           IRQF_DISABLED,"floppy",NULL)
+                                           0,"floppy",NULL)
 #define fd_free_irq()          free_irq(IRQ_FLOPPYDISK,NULL)
 #define fd_disable_irq()       disable_irq(IRQ_FLOPPYDISK)
 #define fd_enable_irq()                enable_irq(IRQ_FLOPPYDISK)
index e42cf597f6e6b5b7bcad58cdf9e75289d66672d4..53e69dae796f32e495ab262953d4b52cce0cc303 100644 (file)
@@ -3,11 +3,6 @@
 
 #ifdef __KERNEL__
 
-#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP)
-/* ARM doesn't provide unprivileged exclusive memory accessors */
-#include <asm-generic/futex.h>
-#else
-
 #include <linux/futex.h>
 #include <linux/uaccess.h>
 #include <asm/errno.h>
@@ -28,6 +23,7 @@
 
 #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)        \
        smp_mb();                                               \
+       prefetchw(uaddr);                                       \
        __asm__ __volatile__(                                   \
        "1:     ldrex   %1, [%3]\n"                             \
        "       " insn "\n"                                     \
@@ -51,6 +47,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
                return -EFAULT;
 
        smp_mb();
+       /* Prefetching cannot fault */
+       prefetchw(uaddr);
        __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
        "1:     ldrex   %1, [%4]\n"
        "       teq     %1, %2\n"
@@ -164,6 +162,5 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
        return ret;
 }
 
-#endif /* !(CPU_USE_DOMAINS && SMP) */
 #endif /* __KERNEL__ */
 #endif /* _ASM_ARM_FUTEX_H */
diff --git a/arch/arm/include/asm/hardware/cache-feroceon-l2.h b/arch/arm/include/asm/hardware/cache-feroceon-l2.h
new file mode 100644 (file)
index 0000000..12e1588
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/include/asm/hardware/cache-feroceon-l2.h
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * 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.
+ */
+
+extern void __init feroceon_l2_init(int l2_wt_override);
+extern int __init feroceon_of_init(void);
+
index eef55ea9ef0099b9fb080c8539618a77fd622aa6..8e427c7b44257d2d100097e18fa263e2fd1f03f4 100644 (file)
@@ -51,6 +51,7 @@ static inline void decode_ctrl_reg(u32 reg,
 #define ARM_DEBUG_ARCH_V7_ECP14        3
 #define ARM_DEBUG_ARCH_V7_MM   4
 #define ARM_DEBUG_ARCH_V7_1    5
+#define ARM_DEBUG_ARCH_V8      6
 
 /* Breakpoint */
 #define ARM_BREAKPOINT_EXECUTE 0
index 6ff56eca3f1f98ac5215aa0b3274f310ffbf0f7b..6e183fd269fb8b02a001f827ae4bbf3f7252804d 100644 (file)
@@ -9,6 +9,7 @@
  * instruction set this cpu supports.
  */
 #define ELF_HWCAP      (elf_hwcap)
-extern unsigned int elf_hwcap;
+#define ELF_HWCAP2     (elf_hwcap2)
+extern unsigned int elf_hwcap, elf_hwcap2;
 #endif
 #endif
index 863c892b4aaa7403c3bde97b7de3b2cd9a75519c..70f9b9bfb1f9646a1bdfe3ab597c5b9c26e80b7e 100644 (file)
@@ -4,7 +4,6 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
-#include <asm/system.h>
 
 #define JUMP_LABEL_NOP_SIZE 4
 
index f82ec22eeb1174a3ba0b431da119868cd8a1d36d..49fa0dfaad336539b52d35e224b2301f283f9dbd 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <linux/types.h>
 #include <linux/ptrace.h>
-#include <linux/percpu.h>
+#include <linux/notifier.h>
 
 #define __ARCH_WANT_KPROBES_INSN_SLOT
 #define MAX_INSN_SIZE                  2
 #define kretprobe_blacklist_size       0
 
 typedef u32 kprobe_opcode_t;
-
 struct kprobe;
-typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *);
-typedef unsigned long (kprobe_check_cc)(unsigned long);
-typedef void (kprobe_insn_singlestep_t)(struct kprobe *, struct pt_regs *);
-typedef void (kprobe_insn_fn_t)(void);
+#include <asm/probes.h>
 
-/* Architecture specific copy of original instruction. */
-struct arch_specific_insn {
-       kprobe_opcode_t                 *insn;
-       kprobe_insn_handler_t           *insn_handler;
-       kprobe_check_cc                 *insn_check_cc;
-       kprobe_insn_singlestep_t        *insn_singlestep;
-       kprobe_insn_fn_t                *insn_fn;
-};
+#define        arch_specific_insn      arch_probes_insn
 
 struct prev_kprobe {
        struct kprobe *kp;
index 4afb376d9c7c13d07ea81502e17ba53f0554c122..02fa2558f6626a71e6132844986776c46581388f 100644 (file)
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
  * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ *
+ * PFNs are used to describe any physical page; this means
+ * PFN 0 == physical address 0.
  */
-#ifndef __virt_to_phys
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+#if defined(__virt_to_phys)
+#define PHYS_OFFSET    PLAT_PHYS_OFFSET
+#define PHYS_PFN_OFFSET        ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
+
+#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
+
+#elif defined(CONFIG_ARM_PATCH_PHYS_VIRT)
 
 /*
  * Constants used to force the right instruction encodings and shifts
 #define __PV_BITS_31_24        0x81000000
 #define __PV_BITS_7_0  0x81
 
-extern u64 __pv_phys_offset;
+extern unsigned long __pv_phys_pfn_offset;
 extern u64 __pv_offset;
 extern void fixup_pv_table(const void *, unsigned long);
 extern const void *__pv_table_begin, *__pv_table_end;
 
-#define PHYS_OFFSET __pv_phys_offset
+#define PHYS_OFFSET    ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT)
+#define PHYS_PFN_OFFSET        (__pv_phys_pfn_offset)
+
+#define virt_to_pfn(kaddr) \
+       ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
+        PHYS_PFN_OFFSET)
 
 #define __pv_stub(from,to,instr,type)                  \
        __asm__("@ __pv_stub\n"                         \
@@ -243,6 +256,7 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
 #else
 
 #define PHYS_OFFSET    PLAT_PHYS_OFFSET
+#define PHYS_PFN_OFFSET        ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
 
 static inline phys_addr_t __virt_to_phys(unsigned long x)
 {
@@ -254,18 +268,11 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
        return x - PHYS_OFFSET + PAGE_OFFSET;
 }
 
-#endif
-#endif
+#define virt_to_pfn(kaddr) \
+       ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
+        PHYS_PFN_OFFSET)
 
-/*
- * PFNs are used to describe any physical page; this means
- * PFN 0 == physical address 0.
- *
- * This is the PFN of the first RAM page in the kernel
- * direct-mapped view.  We assume this is the first page
- * of RAM in the mem_map as well.
- */
-#define PHYS_PFN_OFFSET        ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
+#endif
 
 /*
  * These are *only* valid on the kernel direct mapped RAM memory.
@@ -343,9 +350,9 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
  */
 #define ARCH_PFN_OFFSET                PHYS_PFN_OFFSET
 
-#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_page(kaddr)    pfn_to_page(virt_to_pfn(kaddr))
 #define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \
-                                       && pfn_valid(__pa(kaddr) >> PAGE_SHIFT) )
+                                       && pfn_valid(virt_to_pfn(kaddr)))
 
 #endif
 
index dfff709fda3ccdddbc0d67f3ff1a04c702c85ad6..219ac88a954243b3e3acaebcebd9871ea49825e4 100644 (file)
 #define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2)      /* 1100 */
 #define L_PTE_MT_DEV_WC                (_AT(pteval_t, 0x09) << 2)      /* 1001 */
 #define L_PTE_MT_DEV_CACHED    (_AT(pteval_t, 0x0b) << 2)      /* 1011 */
+#define L_PTE_MT_VECTORS       (_AT(pteval_t, 0x0f) << 2)      /* 1111 */
 #define L_PTE_MT_MASK          (_AT(pteval_t, 0x0f) << 2)
 
 #ifndef __ASSEMBLY__
index 7d59b524f2af3c48480762a9b41f36fefb04e546..5478e5d6ad89f4f9b4825623a3cd38a5a8bae91e 100644 (file)
@@ -216,13 +216,16 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 #define pte_none(pte)          (!pte_val(pte))
 #define pte_present(pte)       (pte_val(pte) & L_PTE_PRESENT)
+#define pte_valid(pte)         (pte_val(pte) & L_PTE_VALID)
+#define pte_accessible(mm, pte)        (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
 #define pte_write(pte)         (!(pte_val(pte) & L_PTE_RDONLY))
 #define pte_dirty(pte)         (pte_val(pte) & L_PTE_DIRTY)
 #define pte_young(pte)         (pte_val(pte) & L_PTE_YOUNG)
 #define pte_exec(pte)          (!(pte_val(pte) & L_PTE_XN))
 #define pte_special(pte)       (0)
 
-#define pte_present_user(pte)  (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
+#define pte_valid_user(pte)    \
+       (pte_valid(pte) && (pte_val(pte) & L_PTE_USER) && pte_young(pte))
 
 #if __LINUX_ARM_ARCH__ < 6
 static inline void __sync_icache_dcache(pte_t pteval)
@@ -237,7 +240,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 {
        unsigned long ext = 0;
 
-       if (addr < TASK_SIZE && pte_present_user(pteval)) {
+       if (addr < TASK_SIZE && pte_valid_user(pteval)) {
                __sync_icache_dcache(pteval);
                ext |= PTE_EXT_NG;
        }
index f24edad26c70fd34fb9182179ae87618bbb72da8..ae1919be8f988a68d109963f087912128d773dbc 100644 (file)
@@ -71,6 +71,8 @@ struct arm_pmu {
        void            (*disable)(struct perf_event *event);
        int             (*get_event_idx)(struct pmu_hw_events *hw_events,
                                         struct perf_event *event);
+       void            (*clear_event_idx)(struct pmu_hw_events *hw_events,
+                                        struct perf_event *event);
        int             (*set_event_filter)(struct hw_perf_event *evt,
                                            struct perf_event_attr *attr);
        u32             (*read_counter)(struct perf_event *event);
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
new file mode 100644 (file)
index 0000000..806cfe6
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/include/asm/probes.h
+ *
+ * Original contents copied from arch/arm/include/asm/kprobes.h
+ * which contains the following notice...
+ *
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _ASM_PROBES_H
+#define _ASM_PROBES_H
+
+typedef u32 probes_opcode_t;
+
+struct arch_probes_insn;
+typedef void (probes_insn_handler_t)(probes_opcode_t,
+                                    struct arch_probes_insn *,
+                                    struct pt_regs *);
+typedef unsigned long (probes_check_cc)(unsigned long);
+typedef void (probes_insn_singlestep_t)(probes_opcode_t,
+                                       struct arch_probes_insn *,
+                                       struct pt_regs *);
+typedef void (probes_insn_fn_t)(void);
+
+/* Architecture specific copy of original instruction. */
+struct arch_probes_insn {
+       probes_opcode_t                 *insn;
+       probes_insn_handler_t           *insn_handler;
+       probes_check_cc                 *insn_check_cc;
+       probes_insn_singlestep_t        *insn_singlestep;
+       probes_insn_fn_t                *insn_fn;
+};
+
+#endif
index 04c99f36ff7f902208c475066e28cbf67077f606..c877654fe3bf680f51d12bd9f2c7b3154454742b 100644 (file)
@@ -27,9 +27,13 @@ struct pt_regs {
 #define thumb_mode(regs) (0)
 #endif
 
+#ifndef CONFIG_CPU_V7M
 #define isa_mode(regs) \
-       ((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \
-        (((regs)->ARM_cpsr & PSR_T_BIT) >> 5))
+       ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
+        (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
+#else
+#define isa_mode(regs) 1 /* Thumb */
+#endif
 
 #define processor_mode(regs) \
        ((regs)->ARM_cpsr & MODE_MASK)
@@ -80,6 +84,12 @@ static inline long regs_return_value(struct pt_regs *regs)
 
 #define instruction_pointer(regs)      (regs)->ARM_pc
 
+static inline void instruction_pointer_set(struct pt_regs *regs,
+                                          unsigned long val)
+{
+       instruction_pointer(regs) = val;
+}
+
 #ifdef CONFIG_SMP
 extern unsigned long profile_pc(struct pt_regs *regs);
 #else
index 22a3b9b5d4a16fd4ece50bdfc83859f6ea38352f..2ec765c39ab4f25340b6b4f06b0325fc31d8ad75 100644 (file)
@@ -74,6 +74,7 @@ struct secondary_data {
 };
 extern struct secondary_data secondary_data;
 extern volatile int pen_release;
+extern void secondary_startup(void);
 
 extern int __cpu_disable(void);
 
@@ -114,6 +115,15 @@ struct smp_operations {
 #endif
 };
 
+struct of_cpu_method {
+       const char *method;
+       struct smp_operations *ops;
+};
+
+#define CPU_METHOD_OF_DECLARE(name, _method, _ops)                     \
+       static const struct of_cpu_method __cpu_method_of_table_##name  \
+               __used __section(__cpu_method_of_table)                 \
+               = { .method = _method, .ops = _ops }
 /*
  * set platform specific SMP operations
  */
index 63479eecbf769e122169e813f8e948e7e5126a90..9732b8e11e63f6e2cf49038d3f5b9ef6f0cac22f 100644 (file)
@@ -2,7 +2,6 @@
 #define __ASM_SYNC_BITOPS_H__
 
 #include <asm/bitops.h>
-#include <asm/system.h>
 
 /* sync_bitops functions are equivalent to the SMP implementation of the
  * original functions, independently from CONFIG_SMP being defined.
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
deleted file mode 100644 (file)
index 368165e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */
-#include <asm/barrier.h>
-#include <asm/compiler.h>
-#include <asm/cmpxchg.h>
-#include <asm/switch_to.h>
-#include <asm/system_info.h>
-#include <asm/system_misc.h>
index 71a06b293489ddffd1b4177eca38572501c0ce36..f989d7c22dc5ac00c17d3f8ab0b6d3a74565e062 100644 (file)
@@ -153,6 +153,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 #define TIF_SIGPENDING         0
 #define TIF_NEED_RESCHED       1
 #define TIF_NOTIFY_RESUME      2       /* callback before returning to user */
+#define TIF_UPROBE             7
 #define TIF_SYSCALL_TRACE      8
 #define TIF_SYSCALL_AUDIT      9
 #define TIF_SYSCALL_TRACEPOINT 10
@@ -165,6 +166,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
+#define _TIF_UPROBE            (1 << TIF_UPROBE)
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT        (1 << TIF_SYSCALL_TRACEPOINT)
@@ -178,7 +180,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 /*
  * Change these and you break ASM code in entry-common.S
  */
-#define _TIF_WORK_MASK         (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME)
+#define _TIF_WORK_MASK         (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
+                                _TIF_NOTIFY_RESUME | _TIF_UPROBE)
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_THREAD_INFO_H */
index 83f2aa83899c4b14cede7dd798178655884c951f..f6fcc67ef06ef3882ebc7a97f4397c2ff19ed5e5 100644 (file)
 #ifndef _ASMARM_TIMEX_H
 #define _ASMARM_TIMEX_H
 
-#ifdef CONFIG_ARCH_MULTIPLATFORM
-#define CLOCK_TICK_RATE 1000000
-#else
-#include <mach/timex.h>
-#endif
-
 typedef unsigned long cycles_t;
 #define get_cycles()   ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
 
index 3bd36e2c5f2e29ec68048bd32391b323089f675d..b5f7705abcb024bb21c41ce34c6f7e95ddfb9bb8 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/printk.h>
 #include <linux/bug.h>
 #include <linux/of.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
 
 struct trusted_foundations_platform_data {
        unsigned int version_major;
@@ -47,10 +49,13 @@ static inline void register_trusted_foundations(
                                   struct trusted_foundations_platform_data *pd)
 {
        /*
-        * If we try to register TF, this means the system needs it to continue.
-        * Its absence if thus a fatal error.
+        * If the system requires TF and we cannot provide it, continue booting
+        * but disable features that cannot be provided.
         */
-       panic("No support for Trusted Foundations, stopping...\n");
+       pr_err("No support for Trusted Foundations, continuing in degraded mode.\n");
+       pr_err("Secondary processors as well as CPU PM will be disabled.\n");
+       setup_max_cpus = 0;
+       cpu_idle_poll_ctrl(true);
 }
 
 static inline void of_register_trusted_foundations(void)
@@ -59,7 +64,7 @@ static inline void of_register_trusted_foundations(void)
         * If we find the target should enable TF but does not support it,
         * fail as the system won't be able to do much anyway
         */
-       if (of_find_compatible_node(NULL, NULL, "tl,trusted-foundations"))
+       if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations"))
                register_trusted_foundations(NULL);
 }
 #endif /* CONFIG_TRUSTED_FOUNDATIONS */
index 72abdc541f38f6e892a24050d1992fc37098f5e3..12c3a5decc609d882626ec75bb2e82ebcbb74030 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/unified.h>
 #include <asm/compiler.h>
 
-#if __LINUX_ARM_ARCH__ < 6
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 #include <asm-generic/uaccess-unaligned.h>
 #else
 #define __get_user_unaligned __get_user
index acabef1a75df00637def7a94af9f1425d281b7f0..43876245fc5707780115c36d67d1843fce0cf6bf 100644 (file)
@@ -48,6 +48,5 @@
  */
 #define __IGNORE_fadvise64_64
 #define __IGNORE_migrate_pages
-#define __IGNORE_kcmp
 
 #endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/include/asm/uprobes.h b/arch/arm/include/asm/uprobes.h
new file mode 100644 (file)
index 0000000..9472c20
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_UPROBES_H
+#define _ASM_UPROBES_H
+
+#include <asm/probes.h>
+#include <asm/opcodes.h>
+
+typedef u32 uprobe_opcode_t;
+
+#define MAX_UINSN_BYTES                4
+#define UPROBE_XOL_SLOT_BYTES  64
+
+#define UPROBE_SWBP_ARM_INSN   0xe7f001f9
+#define UPROBE_SS_ARM_INSN     0xe7f001fa
+#define UPROBE_SWBP_INSN       __opcode_to_mem_arm(UPROBE_SWBP_ARM_INSN)
+#define UPROBE_SWBP_INSN_SIZE  4
+
+struct arch_uprobe_task {
+       u32 backup;
+       unsigned long   saved_trap_no;
+};
+
+struct arch_uprobe {
+       u8 insn[MAX_UINSN_BYTES];
+       unsigned long ixol[2];
+       uprobe_opcode_t bpinsn;
+       bool simulate;
+       u32 pcreg;
+       void (*prehandler)(struct arch_uprobe *auprobe,
+                          struct arch_uprobe_task *autask,
+                          struct pt_regs *regs);
+       void (*posthandler)(struct arch_uprobe *auprobe,
+                           struct arch_uprobe_task *autask,
+                           struct pt_regs *regs);
+       struct arch_probes_insn asi;
+};
+
+#endif
index f3a9cff6d5d44f421bd6107220d6da6f0cd61e25..8d8d922e5e4458fc7529057559367d8528301389 100644 (file)
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
 */
 
-#include <plat/regs-serial.h>
+#include <linux/serial_s3c.h>
 
 /* The S5PV210/S5PC110 implementations are as belows. */
 
index f98763f0bc179f30edf4a6e1b0b1f0f58bed27c6..3bc80599c02256a8e2f6681a039a98fe67fef82a 100644 (file)
@@ -53,8 +53,7 @@
 
 #define checkuart(rp, rv, lhu, bit, uart) \
                /* Load address of CLK_RST register */ \
-               movw    rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \
-               movt    rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \
+               ldr     rp, =TEGRA_CLK_RST_DEVICES_##lhu ; \
                /* Load value from CLK_RST register */ \
                ldr     rp, [rp, #0] ; \
                /* Test UART's reset bit */ \
@@ -62,8 +61,7 @@
                /* If set, can't use UART; jump to save no UART */ \
                bne     90f ; \
                /* Load address of CLK_OUT_ENB register */ \
-               movw    rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \
-               movt    rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \
+               ldr     rp, =TEGRA_CLK_OUT_ENB_##lhu ; \
                /* Load value from CLK_OUT_ENB register */ \
                ldr     rp, [rp, #0] ; \
                /* Test UART's clock enable bit */ \
@@ -71,8 +69,7 @@
                /* If clear, can't use UART; jump to save no UART */ \
                beq     90f ; \
                /* Passed all tests, load address of UART registers */ \
-               movw    rp, #TEGRA_UART##uart##_BASE & 0xffff ; \
-               movt    rp, #TEGRA_UART##uart##_BASE >> 16 ; \
+               ldr     rp, =TEGRA_UART##uart##_BASE ; \
                /* Jump to save UART address */ \
                b 91f
 
 
 #ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
                /* Check ODMDATA */
-10:            movw    \rp, #TEGRA_PMC_SCRATCH20 & 0xffff
-               movt    \rp, #TEGRA_PMC_SCRATCH20 >> 16
+10:            ldr     \rp, =TEGRA_PMC_SCRATCH20
                ldr     \rp, [\rp, #0]          @ Load PMC_SCRATCH20
-               ubfx    \rv, \rp, #18, #2       @ 19:18 are console type
+               lsr     \rv, \rp, #18           @ 19:18 are console type
+               and     \rv, \rv, #3
                cmp     \rv, #2                 @ 2 and 3 mean DCC, UART
                beq     11f                     @ some boards swap the meaning
                cmp     \rv, #3                 @ so accept either
                bne     90f
-11:            ubfx    \rv, \rp, #15, #3       @ 17:15 are UART ID
+11:            lsr     \rv, \rp, #15           @ 17:15 are UART ID
+               and     \rv, #7 
                cmp     \rv, #0                 @ UART 0?
                beq     20f
                cmp     \rv, #1                 @ UART 1?
index f9aa9740a73f09676d5a963f47e2d8e4f7d83e6c..0b762fafa7586a092399f8864f1cfdeaf3ff05ce 100644 (file)
@@ -42,6 +42,9 @@
                .endm
 
                .macro  waituart,rd,rx
+1001:          ldr     \rd, [\rx, #UART_SR_OFFSET]
+               tst     \rd, #UART_SR_TXEMPTY
+               beq     1001b
                .endm
 
                .macro  busyuart,rd,rx
index 7dcc10d6725352b9b1d35f7c5583187cb3a744c1..20d12f230a2f4d0939ec7e409961016658fb6199 100644 (file)
 #define HWCAP_LPAE     (1 << 20)
 #define HWCAP_EVTSTRM  (1 << 21)
 
+/*
+ * HWCAP2 flags - for elf_hwcap2 (in kernel) and AT_HWCAP2
+ */
+#define HWCAP2_AES     (1 << 0)
+#define HWCAP2_PMULL   (1 << 1)
+#define HWCAP2_SHA1    (1 << 2)
+#define HWCAP2_SHA2    (1 << 3)
+#define HWCAP2_CRC32   (1 << 4)
+
 #endif /* _UAPI__ASMARM_HWCAP_H */
index a30fc9be9e9e6abc8ccbedb17fb61bddba71bcd7..a766bcbaf8adfbca3e4bb5ef4446bc5700454d7d 100644 (file)
@@ -50,11 +50,12 @@ obj-$(CONFIG_DYNAMIC_FTRACE)        += ftrace.o insn.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)    += ftrace.o insn.o
 obj-$(CONFIG_JUMP_LABEL)       += jump_label.o insn.o patch.o
 obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o
-obj-$(CONFIG_KPROBES)          += kprobes.o kprobes-common.o patch.o
+obj-$(CONFIG_UPROBES)          += probes.o probes-arm.o uprobes.o uprobes-arm.o
+obj-$(CONFIG_KPROBES)          += probes.o kprobes.o kprobes-common.o patch.o
 ifdef CONFIG_THUMB2_KERNEL
-obj-$(CONFIG_KPROBES)          += kprobes-thumb.o
+obj-$(CONFIG_KPROBES)          += kprobes-thumb.o probes-thumb.o
 else
-obj-$(CONFIG_KPROBES)          += kprobes-arm.o
+obj-$(CONFIG_KPROBES)          += kprobes-arm.o probes-arm.o
 endif
 obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
 test-kprobes-objs              := kprobes-test.o
index 85e664b6a5f19be5e92d5f2fc5047dd2567ce09f..f7b450f97e6884bf5d28de653e7d291f809ab1d1 100644 (file)
@@ -158,6 +158,6 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
 #endif
 
 #ifdef CONFIG_ARM_PATCH_PHYS_VIRT
-EXPORT_SYMBOL(__pv_phys_offset);
+EXPORT_SYMBOL(__pv_phys_pfn_offset);
 EXPORT_SYMBOL(__pv_offset);
 #endif
index d0d46786892cac86f5f8575f063d3637032292fd..16d43cd4561908518894f6141cdcc2a6f0a2af4b 100644 (file)
@@ -605,41 +605,10 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
  */
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-       u16 cmd, old_cmd;
-       int idx;
-       struct resource *r;
-
-       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-       old_cmd = cmd;
-       for (idx = 0; idx < 6; idx++) {
-               /* Only set up the requested stuff */
-               if (!(mask & (1 << idx)))
-                       continue;
-
-               r = dev->resource + idx;
-               if (!r->start && r->end) {
-                       printk(KERN_ERR "PCI: Device %s not available because"
-                              " of resource collisions\n", pci_name(dev));
-                       return -EINVAL;
-               }
-               if (r->flags & IORESOURCE_IO)
-                       cmd |= PCI_COMMAND_IO;
-               if (r->flags & IORESOURCE_MEM)
-                       cmd |= PCI_COMMAND_MEMORY;
-       }
+       if (pci_has_flag(PCI_PROBE_ONLY))
+               return 0;
 
-       /*
-        * Bridges (eg, cardbus bridges) need to be fully enabled
-        */
-       if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
-               cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-
-       if (cmd != old_cmd) {
-               printk("PCI: enabling device %s (%04x -> %04x)\n",
-                      pci_name(dev), old_cmd, cmd);
-               pci_write_config_word(dev, PCI_COMMAND, cmd);
-       }
-       return 0;
+       return pci_enable_resources(dev, mask);
 }
 
 int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
index f751714d52c1f7dd5d4e87542bfadb012fcf1ca0..c7419a585ddc6e7fca602be71b3119582efc34ba 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/smp.h>
 
 #include <asm/cputype.h>
 #include <asm/setup.h>
@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void)
        }
 }
 
+#ifdef CONFIG_SMP
+extern struct of_cpu_method __cpu_method_of_table_begin[];
+extern struct of_cpu_method __cpu_method_of_table_end[];
+
+static int __init set_smp_ops_by_method(struct device_node *node)
+{
+       const char *method;
+       struct of_cpu_method *m = __cpu_method_of_table_begin;
+
+       if (of_property_read_string(node, "enable-method", &method))
+               return 0;
+
+       for (; m < __cpu_method_of_table_end; m++)
+               if (!strcmp(m->method, method)) {
+                       smp_set_ops(m->ops);
+                       return 1;
+               }
+
+       return 0;
+}
+#else
+static inline int set_smp_ops_by_method(struct device_node *node)
+{
+       return 1;
+}
+#endif
+
+
 /*
  * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
  * and builds the cpu logical map array containing MPIDR values related to
@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
         * read as 0.
         */
        struct device_node *cpu, *cpus;
+       int found_method = 0;
        u32 i, j, cpuidx = 1;
        u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
 
@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
                }
 
                tmp_map[i] = hwid;
+
+               if (!found_method)
+                       found_method = set_smp_ops_by_method(cpu);
        }
 
+       /*
+        * Fallback to an enable-method in the cpus node if nothing found in
+        * a cpu node.
+        */
+       if (!found_method)
+               set_smp_ops_by_method(cpus);
+
        if (!bootcpu_valid) {
                pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
                return;
index f5f381d915560818dcf0d2200731a90b0c7ae404..f8c08839edf3053c3ee9ac884fab3f61e8ba84b3 100644 (file)
@@ -584,9 +584,10 @@ __fixup_pv_table:
        subs    r3, r0, r3      @ PHYS_OFFSET - PAGE_OFFSET
        add     r4, r4, r3      @ adjust table start address
        add     r5, r5, r3      @ adjust table end address
-       add     r6, r6, r3      @ adjust __pv_phys_offset address
+       add     r6, r6, r3      @ adjust __pv_phys_pfn_offset address
        add     r7, r7, r3      @ adjust __pv_offset address
-       str     r8, [r6, #LOW_OFFSET]   @ save computed PHYS_OFFSET to __pv_phys_offset
+       mov     r0, r8, lsr #12 @ convert to PFN
+       str     r0, [r6, #LOW_OFFSET]   @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
        strcc   ip, [r7, #HIGH_OFFSET]  @ save to __pv_offset high bits
        mov     r6, r3, lsr #24 @ constant for add/sub instructions
        teq     r3, r6, lsl #24 @ must be 16MiB aligned
@@ -600,7 +601,7 @@ ENDPROC(__fixup_pv_table)
 1:     .long   .
        .long   __pv_table_begin
        .long   __pv_table_end
-2:     .long   __pv_phys_offset
+2:     .long   __pv_phys_pfn_offset
        .long   __pv_offset
 
        .text
@@ -688,11 +689,11 @@ ENTRY(fixup_pv_table)
 ENDPROC(fixup_pv_table)
 
        .data
-       .globl  __pv_phys_offset
-       .type   __pv_phys_offset, %object
-__pv_phys_offset:
-       .quad   0
-       .size   __pv_phys_offset, . -__pv_phys_offset
+       .globl  __pv_phys_pfn_offset
+       .type   __pv_phys_pfn_offset, %object
+__pv_phys_pfn_offset:
+       .word   0
+       .size   __pv_phys_pfn_offset, . -__pv_phys_pfn_offset
 
        .globl  __pv_offset
        .type   __pv_offset, %object
index 3d446605cbf84b89890bdf5bb2398a64a8401120..4d963fb66e3f0bce4590e5885415916be9aba866 100644 (file)
@@ -167,7 +167,7 @@ static int debug_arch_supported(void)
 /* Can we determine the watchpoint access type from the fsr? */
 static int debug_exception_updates_fsr(void)
 {
-       return 0;
+       return get_debug_arch() >= ARM_DEBUG_ARCH_V8;
 }
 
 /* Determine number of WRP registers available. */
@@ -257,6 +257,7 @@ static int enable_monitor_mode(void)
                break;
        case ARM_DEBUG_ARCH_V7_ECP14:
        case ARM_DEBUG_ARCH_V7_1:
+       case ARM_DEBUG_ARCH_V8:
                ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN));
                isb();
                break;
@@ -1072,6 +1073,8 @@ static int __init arch_hw_breakpoint_init(void)
        core_num_brps = get_num_brps();
        core_num_wrps = get_num_wrps();
 
+       cpu_notifier_register_begin();
+
        /*
         * We need to tread carefully here because DBGSWENABLE may be
         * driven low on this core and there isn't an architected way to
@@ -1088,6 +1091,7 @@ static int __init arch_hw_breakpoint_init(void)
        if (!cpumask_empty(&debug_err_mask)) {
                core_num_brps = 0;
                core_num_wrps = 0;
+               cpu_notifier_register_done();
                return 0;
        }
 
@@ -1107,7 +1111,10 @@ static int __init arch_hw_breakpoint_init(void)
                        TRAP_HWBKPT, "breakpoint debug exception");
 
        /* Register hotplug and PM notifiers. */
-       register_cpu_notifier(&dbg_reset_nb);
+       __register_cpu_notifier(&dbg_reset_nb);
+
+       cpu_notifier_register_done();
+
        pm_init();
        return 0;
 }
index 8a30c89da70ec104d4c1499f3a88a1dc4721e6e0..ac300c60d656982b5ae3ebf06fcbdbfc822e1017 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
-#include <linux/module.h>
+#include <linux/ptrace.h>
 
 #include "kprobes.h"
-
-#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
-
-#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
+#include "probes-arm.h"
 
 #if  __LINUX_ARM_ARCH__ >= 6
 #define BLX(reg)       "blx    "reg"           \n\t"
                        "mov    pc, "reg"       \n\t"
 #endif
 
-/*
- * To avoid the complications of mimicing single-stepping on a
- * processor without a Next-PC or a single-step mode, and to
- * avoid having to deal with the side-effects of boosting, we
- * simulate or emulate (almost) all ARM instructions.
- *
- * "Simulation" is where the instruction's behavior is duplicated in
- * C code.  "Emulation" is where the original instruction is rewritten
- * and executed, often by altering its registers.
- *
- * By having all behavior of the kprobe'd instruction completed before
- * returning from the kprobe_handler(), all locks (scheduler and
- * interrupt) can safely be released.  There is no need for secondary
- * breakpoints, no race with MP or preemptable kernels, nor having to
- * clean up resources counts at a later time impacting overall system
- * performance.  By rewriting the instruction, only the minimum registers
- * need to be loaded and saved back optimizing performance.
- *
- * Calling the insnslot_*_rwflags version of a function doesn't hurt
- * anything even when the CPSR flags aren't updated by the
- * instruction.  It's just a little slower in return for saving
- * a little space by not having a duplicate function that doesn't
- * update the flags.  (The same optimization can be said for
- * instructions that do or don't perform register writeback)
- * Also, instructions can either read the flags, only write the
- * flags, or read and write the flags.  To save combinations
- * rather than for sheer performance, flag functions just assume
- * read and write of flags.
- */
-
-static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
-{
-       kprobe_opcode_t insn = p->opcode;
-       long iaddr = (long)p->addr;
-       int disp  = branch_displacement(insn);
-
-       if (insn & (1 << 24))
-               regs->ARM_lr = iaddr + 4;
-
-       regs->ARM_pc = iaddr + 8 + disp;
-}
-
-static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
-{
-       kprobe_opcode_t insn = p->opcode;
-       long iaddr = (long)p->addr;
-       int disp = branch_displacement(insn);
-
-       regs->ARM_lr = iaddr + 4;
-       regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
-       regs->ARM_cpsr |= PSR_T_BIT;
-}
-
-static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
-{
-       kprobe_opcode_t insn = p->opcode;
-       int rm = insn & 0xf;
-       long rmv = regs->uregs[rm];
-
-       if (insn & (1 << 5))
-               regs->ARM_lr = (long)p->addr + 4;
-
-       regs->ARM_pc = rmv & ~0x1;
-       regs->ARM_cpsr &= ~PSR_T_BIT;
-       if (rmv & 0x1)
-               regs->ARM_cpsr |= PSR_T_BIT;
-}
-
-static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
-{
-       kprobe_opcode_t insn = p->opcode;
-       int rd = (insn >> 12) & 0xf;
-       unsigned long mask = 0xf8ff03df; /* Mask out execution state */
-       regs->uregs[rd] = regs->ARM_cpsr & mask;
-}
-
-static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
-{
-       regs->uregs[12] = regs->uregs[13];
-}
-
 static void __kprobes
-emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
+emulate_ldrdstrd(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = (unsigned long)p->addr + 8;
+       unsigned long pc = regs->ARM_pc + 4;
        int rt = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -175,7 +91,7 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
                BLX("%[fn]")
                : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
                : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
-                 [fn] "r" (p->ainsn.insn_fn)
+                 [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -186,10 +102,10 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_ldr(struct kprobe *p, struct pt_regs *regs)
+emulate_ldr(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = (unsigned long)p->addr + 8;
+       unsigned long pc = regs->ARM_pc + 4;
        int rt = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -202,7 +118,7 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                BLX("%[fn]")
                : "=r" (rtv), "=r" (rnv)
-               : "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+               : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -216,11 +132,11 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_str(struct kprobe *p, struct pt_regs *regs)
+emulate_str(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long rtpc = (unsigned long)p->addr + str_pc_offset;
-       unsigned long rnpc = (unsigned long)p->addr + 8;
+       unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
+       unsigned long rnpc = regs->ARM_pc + 4;
        int rt = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -234,7 +150,7 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                BLX("%[fn]")
                : "=r" (rnv)
-               : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+               : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -243,10 +159,10 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
+emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = (unsigned long)p->addr + 8;
+       unsigned long pc = regs->ARM_pc + 4;
        int rd = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -266,7 +182,7 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
                "mrs    %[cpsr], cpsr           \n\t"
                : "=r" (rdv), [cpsr] "=r" (cpsr)
                : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
-                 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+                 "1" (cpsr), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -278,9 +194,9 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
+emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rd = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -296,7 +212,7 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
                "mrs    %[cpsr], cpsr           \n\t"
                : "=r" (rdv), [cpsr] "=r" (cpsr)
                : "0" (rdv), "r" (rnv), "r" (rmv),
-                 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+                 "1" (cpsr), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -305,9 +221,10 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
+emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
+       struct arch_probes_insn *asi,
+       struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rd = (insn >> 16) & 0xf;
        int rn = (insn >> 12) & 0xf;
        int rm = insn & 0xf;
@@ -325,7 +242,7 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
                "mrs    %[cpsr], cpsr           \n\t"
                : "=r" (rdv), [cpsr] "=r" (cpsr)
                : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
-                 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+                 "1" (cpsr), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -334,9 +251,9 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
+emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rd = (insn >> 12) & 0xf;
        int rm = insn & 0xf;
 
@@ -346,7 +263,7 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                BLX("%[fn]")
                : "=r" (rdv)
-               : "0" (rdv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+               : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -354,9 +271,10 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
+emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
+       struct arch_probes_insn *asi,
+       struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rdlo = (insn >> 12) & 0xf;
        int rdhi = (insn >> 16) & 0xf;
        int rn = insn & 0xf;
@@ -374,7 +292,7 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
                "mrs    %[cpsr], cpsr           \n\t"
                : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
                : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
-                 "2" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+                 "2" (cpsr), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -383,623 +301,43 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
        regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
 }
 
-/*
- * For the instruction masking and comparisons in all the "space_*"
- * functions below, Do _not_ rearrange the order of tests unless
- * you're very, very sure of what you are doing.  For the sake of
- * efficiency, the masks for some tests sometimes assume other test
- * have been done prior to them so the number of patterns to test
- * for an instruction set can be as broad as possible to reduce the
- * number of tests needed.
- */
-
-static const union decode_item arm_1111_table[] = {
-       /* Unconditional instructions                                   */
-
-       /* memory hint          1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
-       /* PLDI (immediate)     1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
-       /* PLDW (immediate)     1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
-       /* PLD (immediate)      1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_SIMULATE (0xfe300000, 0xf4100000, kprobe_simulate_nop),
-
-       /* memory hint          1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
-       /* PLDI (register)      1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
-       /* PLDW (register)      1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
-       /* PLD (register)       1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
-       DECODE_SIMULATE (0xfe300010, 0xf6100000, kprobe_simulate_nop),
-
-       /* BLX (immediate)      1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
-       DECODE_SIMULATE (0xfe000000, 0xfa000000, simulate_blx1),
-
-       /* CPS                  1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
-       /* SETEND               1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
-       /* SRS                  1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
-       /* RFE                  1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
-
-       /* Coprocessor instructions... */
-       /* MCRR2                1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */
-       /* MRRC2                1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
-       /* LDC2                 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
-       /* STC2                 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
-       /* CDP2                 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
-       /* MCR2                 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
-       /* MRC2                 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
-
-       /* Other unallocated instructions...                            */
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
-       /* Miscellaneous instructions                                   */
-
-       /* MRS cpsr             cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
-       DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs,
-                                                REGS(0, NOPC, 0, 0, 0)),
-
-       /* BX                   cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
-       DECODE_SIMULATE (0x0ff000f0, 0x01200010, simulate_blx2bx),
-
-       /* BLX (register)       cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
-       DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx,
-                                                REGS(0, 0, 0, 0, NOPC)),
-
-       /* CLZ                  cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
-       DECODE_EMULATEX (0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, NOPC)),
-
-       /* QADD                 cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
-       /* QSUB                 cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
-       /* QDADD                cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
-       /* QDSUB                cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
-       DECODE_EMULATEX (0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
-
-       /* BXJ                  cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
-       /* MSR                  cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
-       /* MRS spsr             cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
-       /* BKPT                 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
-       /* SMC                  cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
-       /* And unallocated instructions...                              */
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
-       /* Halfword multiply and multiply-accumulate                    */
-
-       /* SMLALxy              cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
-       DECODE_EMULATEX (0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
-                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
-
-       /* SMULWy               cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
-       DECODE_OR       (0x0ff000b0, 0x012000a0),
-       /* SMULxy               cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
-       DECODE_EMULATEX (0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, 0, NOPC, 0, NOPC)),
-
-       /* SMLAxy               cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
-       DECODE_OR       (0x0ff00090, 0x01000080),
-       /* SMLAWy               cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
-       DECODE_EMULATEX (0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
-
-       DECODE_END
+const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
+       [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none},
+       [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
+       [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
+       [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
+       [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
+       [PROBES_MRS] = {.handler = simulate_mrs},
+       [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
+       [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
+       [PROBES_SATURATING_ARITHMETIC] = {
+               .handler = emulate_rd12rn16rm0_rwflags_nopc},
+       [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
+       [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
+       [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+       [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
+       [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
+       [PROBES_LOAD] = {.handler = emulate_ldr},
+       [PROBES_STORE_EXTRA] = {.handler = emulate_str},
+       [PROBES_STORE] = {.handler = emulate_str},
+       [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
+       [PROBES_DATA_PROCESSING_REG] = {
+               .handler = emulate_rd12rn16rm0rs8_rwflags},
+       [PROBES_DATA_PROCESSING_IMM] = {
+               .handler = emulate_rd12rn16rm0rs8_rwflags},
+       [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
+       [PROBES_SEV] = {.handler = probes_emulate_none},
+       [PROBES_WFE] = {.handler = probes_simulate_nop},
+       [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+       [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
+       [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+       [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+       [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
+       [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
+       [PROBES_MUL_ADD_LONG] = {
+               .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
+       [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
+       [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
+       [PROBES_BRANCH] = {.handler = simulate_bbl},
+       [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
 };
-
-static const union decode_item arm_cccc_0000_____1001_table[] = {
-       /* Multiply and multiply-accumulate                             */
-
-       /* MUL                  cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
-       /* MULS                 cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
-       DECODE_EMULATEX (0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, 0, NOPC, 0, NOPC)),
-
-       /* MLA                  cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
-       /* MLAS                 cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
-       DECODE_OR       (0x0fe000f0, 0x00200090),
-       /* MLS                  cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
-       DECODE_EMULATEX (0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
-
-       /* UMAAL                cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
-       DECODE_OR       (0x0ff000f0, 0x00400090),
-       /* UMULL                cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
-       /* UMULLS               cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
-       /* UMLAL                cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
-       /* UMLALS               cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
-       /* SMULL                cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
-       /* SMULLS               cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
-       /* SMLAL                cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
-       /* SMLALS               cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
-       DECODE_EMULATEX (0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
-                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_0001_____1001_table[] = {
-       /* Synchronization primitives                                   */
-
-#if __LINUX_ARM_ARCH__ < 6
-       /* Deprecated on ARMv6 and may be UNDEFINED on v7               */
-       /* SMP/SWPB             cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
-       DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
-#endif
-       /* LDREX/STREX{,D,B,H}  cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
-       /* And unallocated instructions...                              */
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_000x_____1xx1_table[] = {
-       /* Extra load/store instructions                                */
-
-       /* STRHT                cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
-       /* ???                  cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
-       /* LDRHT                cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
-       /* LDRSBT               cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
-       /* LDRSHT               cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_REJECT   (0x0f200090, 0x00200090),
-
-       /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
-       DECODE_REJECT   (0x0e10e0d0, 0x0000e0d0),
-
-       /* LDRD (register)      cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
-       /* STRD (register)      cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_EMULATEX (0x0e5000d0, 0x000000d0, emulate_ldrdstrd,
-                                                REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
-
-       /* LDRD (immediate)     cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
-       /* STRD (immediate)     cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_EMULATEX (0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
-                                                REGS(NOPCWB, NOPCX, 0, 0, 0)),
-
-       /* STRH (register)      cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
-       DECODE_EMULATEX (0x0e5000f0, 0x000000b0, emulate_str,
-                                                REGS(NOPCWB, NOPC, 0, 0, NOPC)),
-
-       /* LDRH (register)      cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
-       /* LDRSB (register)     cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
-       /* LDRSH (register)     cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_EMULATEX (0x0e500090, 0x00100090, emulate_ldr,
-                                                REGS(NOPCWB, NOPC, 0, 0, NOPC)),
-
-       /* STRH (immediate)     cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
-       DECODE_EMULATEX (0x0e5000f0, 0x004000b0, emulate_str,
-                                                REGS(NOPCWB, NOPC, 0, 0, 0)),
-
-       /* LDRH (immediate)     cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
-       /* LDRSB (immediate)    cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
-       /* LDRSH (immediate)    cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_EMULATEX (0x0e500090, 0x00500090, emulate_ldr,
-                                                REGS(NOPCWB, NOPC, 0, 0, 0)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_000x_table[] = {
-       /* Data-processing (register)                                   */
-
-       /* <op>S PC, ...        cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
-       DECODE_REJECT   (0x0e10f000, 0x0010f000),
-
-       /* MOV IP, SP           1110 0001 1010 0000 1100 0000 0000 1101 */
-       DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, simulate_mov_ipsp),
-
-       /* TST (register)       cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
-       /* TEQ (register)       cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
-       /* CMP (register)       cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
-       /* CMN (register)       cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
-       DECODE_EMULATEX (0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(ANY, 0, 0, 0, ANY)),
-
-       /* MOV (register)       cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
-       /* MVN (register)       cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
-       DECODE_EMULATEX (0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(0, ANY, 0, 0, ANY)),
-
-       /* AND (register)       cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
-       /* EOR (register)       cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
-       /* SUB (register)       cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
-       /* RSB (register)       cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
-       /* ADD (register)       cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
-       /* ADC (register)       cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
-       /* SBC (register)       cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
-       /* RSC (register)       cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
-       /* ORR (register)       cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
-       /* BIC (register)       cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
-       DECODE_EMULATEX (0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(ANY, ANY, 0, 0, ANY)),
-
-       /* TST (reg-shift reg)  cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
-       /* TEQ (reg-shift reg)  cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
-       /* CMP (reg-shift reg)  cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
-       /* CMN (reg-shift reg)  cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
-       DECODE_EMULATEX (0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(ANY, 0, NOPC, 0, ANY)),
-
-       /* MOV (reg-shift reg)  cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
-       /* MVN (reg-shift reg)  cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
-       DECODE_EMULATEX (0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(0, ANY, NOPC, 0, ANY)),
-
-       /* AND (reg-shift reg)  cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
-       /* EOR (reg-shift reg)  cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
-       /* SUB (reg-shift reg)  cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
-       /* RSB (reg-shift reg)  cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
-       /* ADD (reg-shift reg)  cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
-       /* ADC (reg-shift reg)  cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
-       /* SBC (reg-shift reg)  cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
-       /* RSC (reg-shift reg)  cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
-       /* ORR (reg-shift reg)  cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
-       /* BIC (reg-shift reg)  cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
-       DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(ANY, ANY, NOPC, 0, ANY)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_001x_table[] = {
-       /* Data-processing (immediate)                                  */
-
-       /* MOVW                 cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
-       /* MOVT                 cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, 0)),
-
-       /* YIELD                cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
-       DECODE_OR       (0x0fff00ff, 0x03200001),
-       /* SEV                  cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
-       DECODE_EMULATE  (0x0fff00ff, 0x03200004, kprobe_emulate_none),
-       /* NOP                  cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
-       /* WFE                  cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
-       /* WFI                  cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
-       DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop),
-       /* DBG                  cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
-       /* unallocated hints    cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
-       /* MSR (immediate)      cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0x0fb00000, 0x03200000),
-
-       /* <op>S PC, ...        cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
-       DECODE_REJECT   (0x0e10f000, 0x0210f000),
-
-       /* TST (immediate)      cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
-       /* TEQ (immediate)      cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
-       /* CMP (immediate)      cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
-       /* CMN (immediate)      cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(ANY, 0, 0, 0, 0)),
-
-       /* MOV (immediate)      cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
-       /* MVN (immediate)      cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(0, ANY, 0, 0, 0)),
-
-       /* AND (immediate)      cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
-       /* EOR (immediate)      cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
-       /* SUB (immediate)      cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
-       /* RSB (immediate)      cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
-       /* ADD (immediate)      cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
-       /* ADC (immediate)      cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
-       /* SBC (immediate)      cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
-       /* RSC (immediate)      cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
-       /* ORR (immediate)      cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
-       /* BIC (immediate)      cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags,
-                                                REGS(ANY, ANY, 0, 0, 0)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_0110_____xxx1_table[] = {
-       /* Media instructions                                           */
-
-       /* SEL                  cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
-       DECODE_EMULATEX (0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
-
-       /* SSAT                 cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
-       /* USAT                 cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
-       DECODE_OR(0x0fa00030, 0x06a00010),
-       /* SSAT16               cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
-       /* USAT16               cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
-       DECODE_EMULATEX (0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(0, NOPC, 0, 0, NOPC)),
-
-       /* REV                  cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
-       /* REV16                cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
-       /* RBIT                 cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
-       /* REVSH                cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
-       DECODE_EMULATEX (0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, NOPC)),
-
-       /* ???                  cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
-       DECODE_REJECT   (0x0fb00010, 0x06000010),
-       /* ???                  cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
-       DECODE_REJECT   (0x0f8000f0, 0x060000b0),
-       /* ???                  cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
-       DECODE_REJECT   (0x0f8000f0, 0x060000d0),
-       /* SADD16               cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
-       /* SADDSUBX             cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
-       /* SSUBADDX             cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
-       /* SSUB16               cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
-       /* SADD8                cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
-       /* SSUB8                cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
-       /* QADD16               cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
-       /* QADDSUBX             cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
-       /* QSUBADDX             cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
-       /* QSUB16               cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
-       /* QADD8                cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
-       /* QSUB8                cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
-       /* SHADD16              cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
-       /* SHADDSUBX            cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
-       /* SHSUBADDX            cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
-       /* SHSUB16              cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
-       /* SHADD8               cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
-       /* SHSUB8               cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
-       /* UADD16               cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
-       /* UADDSUBX             cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
-       /* USUBADDX             cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
-       /* USUB16               cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
-       /* UADD8                cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
-       /* USUB8                cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
-       /* UQADD16              cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
-       /* UQADDSUBX            cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
-       /* UQSUBADDX            cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
-       /* UQSUB16              cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
-       /* UQADD8               cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
-       /* UQSUB8               cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
-       /* UHADD16              cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
-       /* UHADDSUBX            cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
-       /* UHSUBADDX            cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
-       /* UHSUB16              cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
-       /* UHADD8               cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
-       /* UHSUB8               cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_EMULATEX (0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
-
-       /* PKHBT                cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
-       /* PKHTB                cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
-       DECODE_EMULATEX (0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
-
-       /* ???                  cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
-       /* ???                  cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
-       DECODE_REJECT   (0x0fb000f0, 0x06900070),
-
-       /* SXTB16               cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
-       /* SXTB                 cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
-       /* SXTH                 cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
-       /* UXTB16               cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
-       /* UXTB                 cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
-       /* UXTH                 cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
-       DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, NOPC)),
-
-       /* SXTAB16              cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
-       /* SXTAB                cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
-       /* SXTAH                cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
-       /* UXTAB16              cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
-       /* UXTAB                cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
-       /* UXTAH                cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
-       DECODE_EMULATEX (0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc,
-                                                REGS(NOPCX, NOPC, 0, 0, NOPC)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_0111_____xxx1_table[] = {
-       /* Media instructions                                           */
-
-       /* UNDEFINED            cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
-       DECODE_REJECT   (0x0ff000f0, 0x07f000f0),
-
-       /* SMLALD               cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
-       /* SMLSLD               cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
-       DECODE_EMULATEX (0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
-                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
-
-       /* SMUAD                cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
-       /* SMUSD                cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
-       DECODE_OR       (0x0ff0f090, 0x0700f010),
-       /* SMMUL                cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
-       DECODE_OR       (0x0ff0f0d0, 0x0750f010),
-       /* USAD8                cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
-       DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, 0, NOPC, 0, NOPC)),
-
-       /* SMLAD                cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
-       /* SMLSD                cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
-       DECODE_OR       (0x0ff00090, 0x07000010),
-       /* SMMLA                cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
-       DECODE_OR       (0x0ff000d0, 0x07500010),
-       /* USADA8               cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
-       DECODE_EMULATEX (0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
-
-       /* SMMLS                cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
-       DECODE_EMULATEX (0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc,
-                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
-
-       /* SBFX                 cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
-       /* UBFX                 cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
-       DECODE_EMULATEX (0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, NOPC)),
-
-       /* BFC                  cccc 0111 110x xxxx xxxx xxxx x001 1111 */
-       DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, 0)),
-
-       /* BFI                  cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
-       DECODE_EMULATEX (0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc,
-                                                REGS(0, NOPC, 0, 0, NOPCX)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_01xx_table[] = {
-       /* Load/store word and unsigned byte                            */
-
-       /* LDRB/STRB pc,[...]   cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0x0c40f000, 0x0440f000),
-
-       /* STRT                 cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRT                 cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
-       /* STRBT                cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRBT                cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0x0d200000, 0x04200000),
-
-       /* STR (immediate)      cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
-       /* STRB (immediate)     cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0e100000, 0x04000000, emulate_str,
-                                                REGS(NOPCWB, ANY, 0, 0, 0)),
-
-       /* LDR (immediate)      cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRB (immediate)     cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0e100000, 0x04100000, emulate_ldr,
-                                                REGS(NOPCWB, ANY, 0, 0, 0)),
-
-       /* STR (register)       cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
-       /* STRB (register)      cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0e100000, 0x06000000, emulate_str,
-                                                REGS(NOPCWB, ANY, 0, 0, NOPC)),
-
-       /* LDR (register)       cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRB (register)      cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0x0e100000, 0x06100000, emulate_ldr,
-                                                REGS(NOPCWB, ANY, 0, 0, NOPC)),
-
-       DECODE_END
-};
-
-static const union decode_item arm_cccc_100x_table[] = {
-       /* Block data transfer instructions                             */
-
-       /* LDM                  cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
-       /* STM                  cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_CUSTOM   (0x0e400000, 0x08000000, kprobe_decode_ldmstm),
-
-       /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
-       /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
-       /* LDM (exception ret)  cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
-       DECODE_END
-};
-
-const union decode_item kprobe_decode_arm_table[] = {
-       /*
-        * Unconditional instructions
-        *                      1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xf0000000, 0xf0000000, arm_1111_table),
-
-       /*
-        * Miscellaneous instructions
-        *                      cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
-        */
-       DECODE_TABLE    (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
-
-       /*
-        * Halfword multiply and multiply-accumulate
-        *                      cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
-        */
-       DECODE_TABLE    (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
-
-       /*
-        * Multiply and multiply-accumulate
-        *                      cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
-        */
-       DECODE_TABLE    (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
-
-       /*
-        * Synchronization primitives
-        *                      cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
-        */
-       DECODE_TABLE    (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
-
-       /*
-        * Extra load/store instructions
-        *                      cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
-        */
-       DECODE_TABLE    (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
-
-       /*
-        * Data-processing (register)
-        *                      cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
-        * Data-processing (register-shifted register)
-        *                      cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
-        */
-       DECODE_TABLE    (0x0e000000, 0x00000000, arm_cccc_000x_table),
-
-       /*
-        * Data-processing (immediate)
-        *                      cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0x0e000000, 0x02000000, arm_cccc_001x_table),
-
-       /*
-        * Media instructions
-        *                      cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
-        */
-       DECODE_TABLE    (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
-       DECODE_TABLE    (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
-
-       /*
-        * Load/store word and unsigned byte
-        *                      cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0x0c000000, 0x04000000, arm_cccc_01xx_table),
-
-       /*
-        * Block data transfer instructions
-        *                      cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0x0e000000, 0x08000000, arm_cccc_100x_table),
-
-       /* B                    cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
-       /* BL                   cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
-       DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl),
-
-       /*
-        * Supervisor Call, and coprocessor instructions
-        */
-
-       /* MCRR                 cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
-       /* MRRC                 cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
-       /* LDC                  cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
-       /* STC                  cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
-       /* CDP                  cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
-       /* MCR                  cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
-       /* MRC                  cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
-       /* SVC                  cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0x0c000000, 0x0c000000),
-
-       DECODE_END
-};
-#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
-EXPORT_SYMBOL_GPL(kprobe_decode_arm_table);
-#endif
-
-static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
-       regs->ARM_pc += 4;
-       p->ainsn.insn_handler(p, regs);
-}
-
-/* Return:
- *   INSN_REJECTED     If instruction is one not allowed to kprobe,
- *   INSN_GOOD         If instruction is supported and uses instruction slot,
- *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
- *
- * For instructions we don't want to kprobe (INSN_REJECTED return result):
- *   These are generally ones that modify the processor state making
- *   them "hard" to simulate such as switches processor modes or
- *   make accesses in alternate modes.  Any of these could be simulated
- *   if the work was put into it, but low return considering they
- *   should also be very rare.
- */
-enum kprobe_insn __kprobes
-arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-       asi->insn_singlestep = arm_singlestep;
-       asi->insn_check_cc = kprobe_condition_checks[insn>>28];
-       return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false);
-}
index 18a76282970e6dfaa414b6f9ff266553258bd27d..c311ed94ff1cbfbfca554345e2603c687021bd0e 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
-#include <asm/system_info.h>
 
 #include "kprobes.h"
 
 
-#ifndef find_str_pc_offset
-
-/*
- * For STR and STM instructions, an ARM core may choose to use either
- * a +8 or a +12 displacement from the current instruction's address.
- * Whichever value is chosen for a given core, it must be the same for
- * both instructions and may not change.  This function measures it.
- */
-
-int str_pc_offset;
-
-void __init find_str_pc_offset(void)
-{
-       int addr, scratch, ret;
-
-       __asm__ (
-               "sub    %[ret], pc, #4          \n\t"
-               "str    pc, %[addr]             \n\t"
-               "ldr    %[scr], %[addr]         \n\t"
-               "sub    %[ret], %[scr], %[ret]  \n\t"
-               : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
-
-       str_pc_offset = ret;
-}
-
-#endif /* !find_str_pc_offset */
-
-
-#ifndef test_load_write_pc_interworking
-
-bool load_write_pc_interworks;
-
-void __init test_load_write_pc_interworking(void)
-{
-       int arch = cpu_architecture();
-       BUG_ON(arch == CPU_ARCH_UNKNOWN);
-       load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
-}
-
-#endif /* !test_load_write_pc_interworking */
-
-
-#ifndef test_alu_write_pc_interworking
-
-bool alu_write_pc_interworks;
-
-void __init test_alu_write_pc_interworking(void)
-{
-       int arch = cpu_architecture();
-       BUG_ON(arch == CPU_ARCH_UNKNOWN);
-       alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
-}
-
-#endif /* !test_alu_write_pc_interworking */
-
-
-void __init arm_kprobe_decode_init(void)
-{
-       find_str_pc_offset();
-       test_load_write_pc_interworking();
-       test_alu_write_pc_interworking();
-}
-
-
-static unsigned long __kprobes __check_eq(unsigned long cpsr)
-{
-       return cpsr & PSR_Z_BIT;
-}
-
-static unsigned long __kprobes __check_ne(unsigned long cpsr)
-{
-       return (~cpsr) & PSR_Z_BIT;
-}
-
-static unsigned long __kprobes __check_cs(unsigned long cpsr)
-{
-       return cpsr & PSR_C_BIT;
-}
-
-static unsigned long __kprobes __check_cc(unsigned long cpsr)
-{
-       return (~cpsr) & PSR_C_BIT;
-}
-
-static unsigned long __kprobes __check_mi(unsigned long cpsr)
-{
-       return cpsr & PSR_N_BIT;
-}
-
-static unsigned long __kprobes __check_pl(unsigned long cpsr)
-{
-       return (~cpsr) & PSR_N_BIT;
-}
-
-static unsigned long __kprobes __check_vs(unsigned long cpsr)
-{
-       return cpsr & PSR_V_BIT;
-}
-
-static unsigned long __kprobes __check_vc(unsigned long cpsr)
-{
-       return (~cpsr) & PSR_V_BIT;
-}
-
-static unsigned long __kprobes __check_hi(unsigned long cpsr)
-{
-       cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
-       return cpsr & PSR_C_BIT;
-}
-
-static unsigned long __kprobes __check_ls(unsigned long cpsr)
-{
-       cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
-       return (~cpsr) & PSR_C_BIT;
-}
-
-static unsigned long __kprobes __check_ge(unsigned long cpsr)
-{
-       cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
-       return (~cpsr) & PSR_N_BIT;
-}
-
-static unsigned long __kprobes __check_lt(unsigned long cpsr)
-{
-       cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
-       return cpsr & PSR_N_BIT;
-}
-
-static unsigned long __kprobes __check_gt(unsigned long cpsr)
-{
-       unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
-       temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
-       return (~temp) & PSR_N_BIT;
-}
-
-static unsigned long __kprobes __check_le(unsigned long cpsr)
-{
-       unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
-       temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
-       return temp & PSR_N_BIT;
-}
-
-static unsigned long __kprobes __check_al(unsigned long cpsr)
-{
-       return true;
-}
-
-kprobe_check_cc * const kprobe_condition_checks[16] = {
-       &__check_eq, &__check_ne, &__check_cs, &__check_cc,
-       &__check_mi, &__check_pl, &__check_vs, &__check_vc,
-       &__check_hi, &__check_ls, &__check_ge, &__check_lt,
-       &__check_gt, &__check_le, &__check_al, &__check_al
-};
-
-
-void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs)
-{
-}
-
-void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs)
-{
-       p->ainsn.insn_fn();
-}
-
-static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
+               struct arch_probes_insn *asi,
+               struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rn = (insn >> 16) & 0xf;
        int lbit = insn & (1 << 20);
        int wbit = insn & (1 << 21);
@@ -223,24 +59,31 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
        }
 }
 
-static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes simulate_stm1_pc(probes_opcode_t insn,
+       struct arch_probes_insn *asi,
+       struct pt_regs *regs)
 {
-       regs->ARM_pc = (long)p->addr + str_pc_offset;
-       simulate_ldm1stm1(p, regs);
-       regs->ARM_pc = (long)p->addr + 4;
+       unsigned long addr = regs->ARM_pc - 4;
+
+       regs->ARM_pc = (long)addr + str_pc_offset;
+       simulate_ldm1stm1(insn, asi, regs);
+       regs->ARM_pc = (long)addr + 4;
 }
 
-static void __kprobes simulate_ldm1_pc(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes simulate_ldm1_pc(probes_opcode_t insn,
+       struct arch_probes_insn *asi,
+       struct pt_regs *regs)
 {
-       simulate_ldm1stm1(p, regs);
+       simulate_ldm1stm1(insn, asi, regs);
        load_write_pc(regs->ARM_pc, regs);
 }
 
 static void __kprobes
-emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs)
+emulate_generic_r0_12_noflags(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        register void *rregs asm("r1") = regs;
-       register void *rfn asm("lr") = p->ainsn.insn_fn;
+       register void *rfn asm("lr") = asi->insn_fn;
 
        __asm__ __volatile__ (
                "stmdb  sp!, {%[regs], r11}     \n\t"
@@ -264,22 +107,27 @@ emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-emulate_generic_r2_14_noflags(struct kprobe *p, struct pt_regs *regs)
+emulate_generic_r2_14_noflags(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+2));
+       emulate_generic_r0_12_noflags(insn, asi,
+               (struct pt_regs *)(regs->uregs+2));
 }
 
 static void __kprobes
-emulate_ldm_r3_15(struct kprobe *p, struct pt_regs *regs)
+emulate_ldm_r3_15(probes_opcode_t insn,
+       struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+3));
+       emulate_generic_r0_12_noflags(insn, asi,
+               (struct pt_regs *)(regs->uregs+3));
        load_write_pc(regs->ARM_pc, regs);
 }
 
-enum kprobe_insn __kprobes
-kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+enum probes_insn __kprobes
+kprobe_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *h)
 {
-       kprobe_insn_handler_t *handler = 0;
+       probes_insn_handler_t *handler = 0;
        unsigned reglist = insn & 0xffff;
        int is_ldm = insn & 0x100000;
        int rn = (insn >> 16) & 0xf;
@@ -319,260 +167,3 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        return INSN_GOOD_NO_SLOT;
 }
 
-
-/*
- * Prepare an instruction slot to receive an instruction for emulating.
- * This is done by placing a subroutine return after the location where the
- * instruction will be placed. We also modify ARM instructions to be
- * unconditional as the condition code will already be checked before any
- * emulation handler is called.
- */
-static kprobe_opcode_t __kprobes
-prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
-                                                               bool thumb)
-{
-#ifdef CONFIG_THUMB2_KERNEL
-       if (thumb) {
-               u16 *thumb_insn = (u16 *)asi->insn;
-               thumb_insn[1] = 0x4770; /* Thumb bx lr */
-               thumb_insn[2] = 0x4770; /* Thumb bx lr */
-               return insn;
-       }
-       asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
-#else
-       asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
-#endif
-       /* Make an ARM instruction unconditional */
-       if (insn < 0xe0000000)
-               insn = (insn | 0xe0000000) & ~0x10000000;
-       return insn;
-}
-
-/*
- * Write a (probably modified) instruction into the slot previously prepared by
- * prepare_emulated_insn
- */
-static void  __kprobes
-set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
-                                                               bool thumb)
-{
-#ifdef CONFIG_THUMB2_KERNEL
-       if (thumb) {
-               u16 *ip = (u16 *)asi->insn;
-               if (is_wide_instruction(insn))
-                       *ip++ = insn >> 16;
-               *ip++ = insn;
-               return;
-       }
-#endif
-       asi->insn[0] = insn;
-}
-
-/*
- * When we modify the register numbers encoded in an instruction to be emulated,
- * the new values come from this define. For ARM and 32-bit Thumb instructions
- * this gives...
- *
- *     bit position      16  12   8   4   0
- *     ---------------+---+---+---+---+---+
- *     register         r2  r0  r1  --  r3
- */
-#define INSN_NEW_BITS          0x00020103
-
-/* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
-#define INSN_SAMEAS16_BITS     0x22222222
-
-/*
- * Validate and modify each of the registers encoded in an instruction.
- *
- * Each nibble in regs contains a value from enum decode_reg_type. For each
- * non-zero value, the corresponding nibble in pinsn is validated and modified
- * according to the type.
- */
-static bool __kprobes decode_regs(kprobe_opcode_t* pinsn, u32 regs)
-{
-       kprobe_opcode_t insn = *pinsn;
-       kprobe_opcode_t mask = 0xf; /* Start at least significant nibble */
-
-       for (; regs != 0; regs >>= 4, mask <<= 4) {
-
-               kprobe_opcode_t new_bits = INSN_NEW_BITS;
-
-               switch (regs & 0xf) {
-
-               case REG_TYPE_NONE:
-                       /* Nibble not a register, skip to next */
-                       continue;
-
-               case REG_TYPE_ANY:
-                       /* Any register is allowed */
-                       break;
-
-               case REG_TYPE_SAMEAS16:
-                       /* Replace register with same as at bit position 16 */
-                       new_bits = INSN_SAMEAS16_BITS;
-                       break;
-
-               case REG_TYPE_SP:
-                       /* Only allow SP (R13) */
-                       if ((insn ^ 0xdddddddd) & mask)
-                               goto reject;
-                       break;
-
-               case REG_TYPE_PC:
-                       /* Only allow PC (R15) */
-                       if ((insn ^ 0xffffffff) & mask)
-                               goto reject;
-                       break;
-
-               case REG_TYPE_NOSP:
-                       /* Reject SP (R13) */
-                       if (((insn ^ 0xdddddddd) & mask) == 0)
-                               goto reject;
-                       break;
-
-               case REG_TYPE_NOSPPC:
-               case REG_TYPE_NOSPPCX:
-                       /* Reject SP and PC (R13 and R15) */
-                       if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
-                               goto reject;
-                       break;
-
-               case REG_TYPE_NOPCWB:
-                       if (!is_writeback(insn))
-                               break; /* No writeback, so any register is OK */
-                       /* fall through... */
-               case REG_TYPE_NOPC:
-               case REG_TYPE_NOPCX:
-                       /* Reject PC (R15) */
-                       if (((insn ^ 0xffffffff) & mask) == 0)
-                               goto reject;
-                       break;
-               }
-
-               /* Replace value of nibble with new register number... */
-               insn &= ~mask;
-               insn |= new_bits & mask;
-       }
-
-       *pinsn = insn;
-       return true;
-
-reject:
-       return false;
-}
-
-static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
-       [DECODE_TYPE_TABLE]     = sizeof(struct decode_table),
-       [DECODE_TYPE_CUSTOM]    = sizeof(struct decode_custom),
-       [DECODE_TYPE_SIMULATE]  = sizeof(struct decode_simulate),
-       [DECODE_TYPE_EMULATE]   = sizeof(struct decode_emulate),
-       [DECODE_TYPE_OR]        = sizeof(struct decode_or),
-       [DECODE_TYPE_REJECT]    = sizeof(struct decode_reject)
-};
-
-/*
- * kprobe_decode_insn operates on data tables in order to decode an ARM
- * architecture instruction onto which a kprobe has been placed.
- *
- * These instruction decoding tables are a concatenation of entries each
- * of which consist of one of the following structs:
- *
- *     decode_table
- *     decode_custom
- *     decode_simulate
- *     decode_emulate
- *     decode_or
- *     decode_reject
- *
- * Each of these starts with a struct decode_header which has the following
- * fields:
- *
- *     type_regs
- *     mask
- *     value
- *
- * The least significant DECODE_TYPE_BITS of type_regs contains a value
- * from enum decode_type, this indicates which of the decode_* structs
- * the entry contains. The value DECODE_TYPE_END indicates the end of the
- * table.
- *
- * When the table is parsed, each entry is checked in turn to see if it
- * matches the instruction to be decoded using the test:
- *
- *     (insn & mask) == value
- *
- * If no match is found before the end of the table is reached then decoding
- * fails with INSN_REJECTED.
- *
- * When a match is found, decode_regs() is called to validate and modify each
- * of the registers encoded in the instruction; the data it uses to do this
- * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
- * to fail with INSN_REJECTED.
- *
- * Once the instruction has passed the above tests, further processing
- * depends on the type of the table entry's decode struct.
- *
- */
-int __kprobes
-kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
-                               const union decode_item *table, bool thumb)
-{
-       const struct decode_header *h = (struct decode_header *)table;
-       const struct decode_header *next;
-       bool matched = false;
-
-       insn = prepare_emulated_insn(insn, asi, thumb);
-
-       for (;; h = next) {
-               enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
-               u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
-
-               if (type == DECODE_TYPE_END)
-                       return INSN_REJECTED;
-
-               next = (struct decode_header *)
-                               ((uintptr_t)h + decode_struct_sizes[type]);
-
-               if (!matched && (insn & h->mask.bits) != h->value.bits)
-                       continue;
-
-               if (!decode_regs(&insn, regs))
-                       return INSN_REJECTED;
-
-               switch (type) {
-
-               case DECODE_TYPE_TABLE: {
-                       struct decode_table *d = (struct decode_table *)h;
-                       next = (struct decode_header *)d->table.table;
-                       break;
-               }
-
-               case DECODE_TYPE_CUSTOM: {
-                       struct decode_custom *d = (struct decode_custom *)h;
-                       return (*d->decoder.decoder)(insn, asi);
-               }
-
-               case DECODE_TYPE_SIMULATE: {
-                       struct decode_simulate *d = (struct decode_simulate *)h;
-                       asi->insn_handler = d->handler.handler;
-                       return INSN_GOOD_NO_SLOT;
-               }
-
-               case DECODE_TYPE_EMULATE: {
-                       struct decode_emulate *d = (struct decode_emulate *)h;
-                       asi->insn_handler = d->handler.handler;
-                       set_emulated_insn(insn, asi, thumb);
-                       return INSN_GOOD;
-               }
-
-               case DECODE_TYPE_OR:
-                       matched = true;
-                       break;
-
-               case DECODE_TYPE_REJECT:
-               default:
-                       return INSN_REJECTED;
-               }
-               }
-       }
index 83931290506704ad226e8a8cb2a15b52a33d4494..87839de77e5f6a0237745cdbc9dd4e57a36fac33 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <asm/system_info.h>
 
 #include "kprobes-test.h"
 
index 0cd63d080c7bf2d93f35db5a69e3debc5147351e..c2fd06b4c3894bd5e5a901e70abd5411d00691ae 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/kprobes.h>
-
+#include <linux/errno.h>
+#include <linux/stddef.h>
+#include <linux/bug.h>
 #include <asm/opcodes.h>
 
 #include "kprobes.h"
+#include "probes-arm.h"
+#include "probes-thumb.h"
 #include "kprobes-test.h"
 
 
@@ -1608,7 +1612,7 @@ static int __init run_all_tests(void)
                goto out;
 
        pr_info("ARM instruction simulation\n");
-       ret = run_test_cases(kprobe_arm_test_cases, kprobe_decode_arm_table);
+       ret = run_test_cases(kprobe_arm_test_cases, probes_decode_arm_table);
        if (ret)
                goto out;
 
@@ -1631,13 +1635,13 @@ static int __init run_all_tests(void)
 
        pr_info("16-bit Thumb instruction simulation\n");
        ret = run_test_cases(kprobe_thumb16_test_cases,
-                               kprobe_decode_thumb16_table);
+                               probes_decode_thumb16_table);
        if (ret)
                goto out;
 
        pr_info("32-bit Thumb instruction simulation\n");
        ret = run_test_cases(kprobe_thumb32_test_cases,
-                               kprobe_decode_thumb32_table);
+                               probes_decode_thumb32_table);
        if (ret)
                goto out;
 #endif
index 6123daf397a7bbb7ffe161075165ddf57f175d10..6619188619ae1409ef4c75c4909d7c58675c3f08 100644 (file)
@@ -8,41 +8,25 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/ptrace.h>
 #include <linux/kprobes.h>
-#include <linux/module.h>
 
 #include "kprobes.h"
+#include "probes-thumb.h"
 
+/* These emulation encodings are functionally equivalent... */
+#define t32_emulate_rd8rn16rm0ra12_noflags \
+               t32_emulate_rdlo12rdhi8rn16rm0_noflags
 
-/*
- * True if current instruction is in an IT block.
- */
-#define in_it_block(cpsr)      ((cpsr & 0x06000c00) != 0x00000000)
-
-/*
- * Return the condition code to check for the currently executing instruction.
- * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if
- * in_it_block returns true.
- */
-#define current_cond(cpsr)     ((cpsr >> 12) & 0xf)
-
-/*
- * Return the PC value for a probe in thumb code.
- * This is the address of the probed instruction plus 4.
- * We subtract one because the address will have bit zero set to indicate
- * a pointer to thumb code.
- */
-static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p)
-{
-       return (unsigned long)p->addr - 1 + 4;
-}
+/* t32 thumb actions */
 
 static void __kprobes
-t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
+t32_simulate_table_branch(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
 
@@ -59,19 +43,19 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs)
+t32_simulate_mrs(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rd = (insn >> 8) & 0xf;
        unsigned long mask = 0xf8ff03df; /* Mask out execution state */
        regs->uregs[rd] = regs->ARM_cpsr & mask;
 }
 
 static void __kprobes
-t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
+t32_simulate_cond_branch(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc;
 
        long offset = insn & 0x7ff;             /* imm11 */
        offset += (insn & 0x003f0000) >> 5;     /* imm6 */
@@ -82,20 +66,21 @@ t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
        regs->ARM_pc = pc + (offset * 2);
 }
 
-static enum kprobe_insn __kprobes
-t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t32_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
        int cc = (insn >> 22) & 0xf;
-       asi->insn_check_cc = kprobe_condition_checks[cc];
+       asi->insn_check_cc = probes_condition_checks[cc];
        asi->insn_handler = t32_simulate_cond_branch;
        return INSN_GOOD_NO_SLOT;
 }
 
 static void __kprobes
-t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
+t32_simulate_branch(probes_opcode_t insn,
+                   struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc;
 
        long offset = insn & 0x7ff;             /* imm11 */
        offset += (insn & 0x03ff0000) >> 5;     /* imm10 */
@@ -108,7 +93,7 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
 
        if (insn & (1 << 14)) {
                /* BL or BLX */
-               regs->ARM_lr = (unsigned long)p->addr + 4;
+               regs->ARM_lr = regs->ARM_pc | 1;
                if (!(insn & (1 << 12))) {
                        /* BLX so switch to ARM mode */
                        regs->ARM_cpsr &= ~PSR_T_BIT;
@@ -120,10 +105,10 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
+t32_simulate_ldr_literal(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long addr = thumb_probe_pc(p) & ~3;
+       unsigned long addr = regs->ARM_pc & ~3;
        int rt = (insn >> 12) & 0xf;
        unsigned long rtv;
 
@@ -157,10 +142,11 @@ t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
        regs->uregs[rt] = rtv;
 }
 
-static enum kprobe_insn __kprobes
-t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t32_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
-       enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi);
+       enum probes_insn ret = kprobe_decode_ldmstm(insn, asi, d);
 
        /* Fixup modified instruction to have halfwords in correct order...*/
        insn = asi->insn[0];
@@ -171,10 +157,10 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 }
 
 static void __kprobes
-t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
+t32_emulate_ldrdstrd(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p) & ~3;
+       unsigned long pc = regs->ARM_pc & ~3;
        int rt1 = (insn >> 12) & 0xf;
        int rt2 = (insn >> 8) & 0xf;
        int rn = (insn >> 16) & 0xf;
@@ -187,7 +173,7 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                "blx    %[fn]"
                : "=r" (rt1v), "=r" (rt2v), "=r" (rnv)
-               : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (p->ainsn.insn_fn)
+               : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -198,9 +184,9 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
+t32_emulate_ldrstr(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rt = (insn >> 12) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -212,7 +198,7 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                "blx    %[fn]"
                : "=r" (rtv), "=r" (rnv)
-               : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
+               : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -224,9 +210,9 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+t32_emulate_rd8rn16rm0_rwflags(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rd = (insn >> 8) & 0xf;
        int rn = (insn >> 16) & 0xf;
        int rm = insn & 0xf;
@@ -242,7 +228,7 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
                "mrs    %[cpsr], cpsr           \n\t"
                : "=r" (rdv), [cpsr] "=r" (cpsr)
                : "0" (rdv), "r" (rnv), "r" (rmv),
-                 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+                 "1" (cpsr), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -251,10 +237,10 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
+t32_emulate_rd8pc16_noflags(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc;
        int rd = (insn >> 8) & 0xf;
 
        register unsigned long rdv asm("r1") = regs->uregs[rd];
@@ -263,7 +249,7 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                "blx    %[fn]"
                : "=r" (rdv)
-               : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn)
+               : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -271,9 +257,9 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
+t32_emulate_rd8rn16_noflags(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rd = (insn >> 8) & 0xf;
        int rn = (insn >> 16) & 0xf;
 
@@ -283,7 +269,7 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
        __asm__ __volatile__ (
                "blx    %[fn]"
                : "=r" (rdv)
-               : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn)
+               : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -291,9 +277,10 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
+t32_emulate_rdlo12rdhi8rn16rm0_noflags(probes_opcode_t insn,
+               struct arch_probes_insn *asi,
+               struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rdlo = (insn >> 12) & 0xf;
        int rdhi = (insn >> 8) & 0xf;
        int rn = (insn >> 16) & 0xf;
@@ -308,674 +295,43 @@ t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
                "blx    %[fn]"
                : "=r" (rdlov), "=r" (rdhiv)
                : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
-                 [fn] "r" (p->ainsn.insn_fn)
+                 [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
        regs->uregs[rdlo] = rdlov;
        regs->uregs[rdhi] = rdhiv;
 }
-
-/* These emulation encodings are functionally equivalent... */
-#define t32_emulate_rd8rn16rm0ra12_noflags \
-               t32_emulate_rdlo12rdhi8rn16rm0_noflags
-
-static const union decode_item t32_table_1110_100x_x0xx[] = {
-       /* Load/store multiple instructions */
-
-       /* Rn is PC             1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfe4f0000, 0xe80f0000),
-
-       /* SRS                  1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
-       /* RFE                  1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xffc00000, 0xe8000000),
-       /* SRS                  1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
-       /* RFE                  1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xffc00000, 0xe9800000),
-
-       /* STM Rn, {...pc}      1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfe508000, 0xe8008000),
-       /* LDM Rn, {...lr,pc}   1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfe50c000, 0xe810c000),
-       /* LDM/STM Rn, {...sp}  1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfe402000, 0xe8002000),
-
-       /* STMIA                1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
-       /* LDMIA                1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
-       /* STMDB                1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
-       /* LDMDB                1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_CUSTOM   (0xfe400000, 0xe8000000, t32_decode_ldmstm),
-
-       DECODE_END
-};
-
-static const union decode_item t32_table_1110_100x_x1xx[] = {
-       /* Load/store dual, load/store exclusive, table branch */
-
-       /* STRD (immediate)     1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRD (immediate)     1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_OR       (0xff600000, 0xe8600000),
-       /* STRD (immediate)     1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRD (immediate)     1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xff400000, 0xe9400000, t32_emulate_ldrdstrd,
-                                                REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
-
-       /* TBB                  1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
-       /* TBH                  1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
-       DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, t32_simulate_table_branch,
-                                                REGS(NOSP, 0, 0, 0, NOSPPC)),
-
-       /* STREX                1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
-       /* LDREX                1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
-       /* STREXB               1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
-       /* STREXH               1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
-       /* STREXD               1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
-       /* LDREXB               1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
-       /* LDREXH               1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
-       /* LDREXD               1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
-       /* And unallocated instructions...                              */
-       DECODE_END
-};
-
-static const union decode_item t32_table_1110_101x[] = {
-       /* Data-processing (shifted register)                           */
-
-       /* TST                  1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
-       /* TEQ                  1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
-       DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, 0, 0, NOSPPC)),
-
-       /* CMN                  1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
-       DECODE_OR       (0xfff00f00, 0xeb100f00),
-       /* CMP                  1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
-       DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOPC, 0, 0, 0, NOSPPC)),
-
-       /* MOV                  1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
-       /* MVN                  1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(0, 0, NOSPPC, 0, NOSPPC)),
-
-       /* ???                  1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
-       /* ???                  1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xffa00000, 0xeaa00000),
-       /* ???                  1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xffe00000, 0xeb200000),
-       /* ???                  1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xffe00000, 0xeb800000),
-       /* ???                  1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xffe00000, 0xebe00000),
-
-       /* ADD/SUB SP, SP, Rm, LSL #0..3                                */
-       /*                      1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
-       DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(SP, 0, SP, 0, NOSPPC)),
-
-       /* ADD/SUB SP, SP, Rm, shift                                    */
-       /*                      1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
-       DECODE_REJECT   (0xff4f0f00, 0xeb0d0d00),
-
-       /* ADD/SUB Rd, SP, Rm, shift                                    */
-       /*                      1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(SP, 0, NOPC, 0, NOSPPC)),
-
-       /* AND                  1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
-       /* BIC                  1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
-       /* ORR                  1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
-       /* ORN                  1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
-       /* EOR                  1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
-       /* PKH                  1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
-       /* ADD                  1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
-       /* ADC                  1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
-       /* SBC                  1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
-       /* SUB                  1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
-       /* RSB                  1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
-
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_0x0x___0[] = {
-       /* Data-processing (modified immediate)                         */
-
-       /* TST                  1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
-       /* TEQ                  1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
-       DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, 0, 0, 0)),
-
-       /* CMN                  1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
-       DECODE_OR       (0xfbf08f00, 0xf1100f00),
-       /* CMP                  1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
-       DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOPC, 0, 0, 0, 0)),
-
-       /* MOV                  1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
-       /* MVN                  1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(0, 0, NOSPPC, 0, 0)),
-
-       /* ???                  1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfbe08000, 0xf0a00000),
-       /* ???                  1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
-       /* ???                  1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfbc08000, 0xf0c00000),
-       /* ???                  1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfbe08000, 0xf1200000),
-       /* ???                  1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfbe08000, 0xf1800000),
-       /* ???                  1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfbe08000, 0xf1e00000),
-
-       /* ADD Rd, SP, #imm     1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
-       /* SUB Rd, SP, #imm     1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(SP, 0, NOPC, 0, 0)),
-
-       /* AND                  1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
-       /* BIC                  1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
-       /* ORR                  1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
-       /* ORN                  1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
-       /* EOR                  1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
-       /* ADD                  1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
-       /* ADC                  1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
-       /* SBC                  1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
-       /* SUB                  1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
-       /* RSB                  1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, 0)),
-
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_0x1x___0[] = {
-       /* Data-processing (plain binary immediate)                     */
-
-       /* ADDW Rd, PC, #imm    1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
-       DECODE_OR       (0xfbff8000, 0xf20f0000),
-       /* SUBW Rd, PC, #imm    1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags,
-                                                REGS(PC, 0, NOSPPC, 0, 0)),
-
-       /* ADDW SP, SP, #imm    1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
-       DECODE_OR       (0xfbff8f00, 0xf20d0d00),
-       /* SUBW SP, SP, #imm    1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
-       DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags,
-                                                REGS(SP, 0, SP, 0, 0)),
-
-       /* ADDW                 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_OR       (0xfbf08000, 0xf2000000),
-       /* SUBW                 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags,
-                                                REGS(NOPCX, 0, NOSPPC, 0, 0)),
-
-       /* MOVW                 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
-       /* MOVT                 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags,
-                                                REGS(0, 0, NOSPPC, 0, 0)),
-
-       /* SSAT16               1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
-       /* SSAT                 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
-       /* USAT16               1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
-       /* USAT                 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, 0)),
-
-       /* SFBX                 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
-       /* UFBX                 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, 0)),
-
-       /* BFC                  1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags,
-                                                REGS(0, 0, NOSPPC, 0, 0)),
-
-       /* BFI                  1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags,
-                                                REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
-
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_0xxx___1[] = {
-       /* Branches and miscellaneous control                           */
-
-       /* YIELD                1111 0011 1010 xxxx 10x0 x000 0000 0001 */
-       DECODE_OR       (0xfff0d7ff, 0xf3a08001),
-       /* SEV                  1111 0011 1010 xxxx 10x0 x000 0000 0100 */
-       DECODE_EMULATE  (0xfff0d7ff, 0xf3a08004, kprobe_emulate_none),
-       /* NOP                  1111 0011 1010 xxxx 10x0 x000 0000 0000 */
-       /* WFE                  1111 0011 1010 xxxx 10x0 x000 0000 0010 */
-       /* WFI                  1111 0011 1010 xxxx 10x0 x000 0000 0011 */
-       DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, kprobe_simulate_nop),
-
-       /* MRS Rd, CPSR         1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
-       DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, t32_simulate_mrs,
-                                                REGS(0, 0, NOSPPC, 0, 0)),
-
-       /*
-        * Unsupported instructions
-        *                      1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
-        *
-        * MSR                  1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
-        * DBG hint             1111 0011 1010 xxxx 10x0 x000 1111 xxxx
-        * Unallocated hints    1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
-        * CPS                  1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
-        * CLREX/DSB/DMB/ISB    1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
-        * BXJ                  1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
-        * SUBS PC,LR,#<imm8>   1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
-        * MRS Rd, SPSR         1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
-        * SMC                  1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
-        * UNDEFINED            1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
-        * ???                  1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
-        */
-       DECODE_REJECT   (0xfb80d000, 0xf3808000),
-
-       /* Bcc                  1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
-       DECODE_CUSTOM   (0xf800d000, 0xf0008000, t32_decode_cond_branch),
-
-       /* BLX                  1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
-       DECODE_OR       (0xf800d001, 0xf000c000),
-       /* B                    1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
-       /* BL                   1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
-       DECODE_SIMULATE (0xf8009000, 0xf0009000, t32_simulate_branch),
-
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
-       /* Memory hints                                                 */
-
-       /* PLD (literal)        1111 1000 x001 1111 1111 xxxx xxxx xxxx */
-       /* PLI (literal)        1111 1001 x001 1111 1111 xxxx xxxx xxxx */
-       DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, kprobe_simulate_nop),
-
-       /* PLD{W} (immediate)   1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
-       DECODE_OR       (0xffd0f000, 0xf890f000),
-       /* PLD{W} (immediate)   1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
-       DECODE_OR       (0xffd0ff00, 0xf810fc00),
-       /* PLI (immediate)      1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
-       DECODE_OR       (0xfff0f000, 0xf990f000),
-       /* PLI (immediate)      1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
-       DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, kprobe_simulate_nop,
-                                                REGS(NOPCX, 0, 0, 0, 0)),
-
-       /* PLD{W} (register)    1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
-       DECODE_OR       (0xffd0ffc0, 0xf810f000),
-       /* PLI (register)       1111 1001 0001 xxxx 1111 0000 00xx xxxx */
-       DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, kprobe_simulate_nop,
-                                                REGS(NOPCX, 0, 0, 0, NOSPPC)),
-
-       /* Other unallocated instructions...                            */
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_100x[] = {
-       /* Store/Load single data item                                  */
-
-       /* ???                  1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfe600000, 0xf8600000),
-
-       /* ???                  1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xfff00000, 0xf9500000),
-
-       /* ???                  1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
-       DECODE_REJECT   (0xfe800d00, 0xf8000800),
-
-       /* STRBT                1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
-       /* STRHT                1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
-       /* STRT                 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
-       /* LDRBT                1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
-       /* LDRSBT               1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
-       /* LDRHT                1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
-       /* LDRSHT               1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
-       /* LDRT                 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
-       DECODE_REJECT   (0xfe800f00, 0xf8000e00),
-
-       /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
-       DECODE_REJECT   (0xff1f0000, 0xf80f0000),
-
-       /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
-       DECODE_REJECT   (0xff10f000, 0xf800f000),
-
-       /* LDR (literal)        1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
-       DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, t32_simulate_ldr_literal,
-                                                REGS(PC, ANY, 0, 0, 0)),
-
-       /* STR (immediate)      1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
-       /* LDR (immediate)      1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
-       DECODE_OR       (0xffe00800, 0xf8400800),
-       /* STR (immediate)      1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
-       /* LDR (immediate)      1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xffe00000, 0xf8c00000, t32_emulate_ldrstr,
-                                                REGS(NOPCX, ANY, 0, 0, 0)),
-
-       /* STR (register)       1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
-       /* LDR (register)       1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
-       DECODE_EMULATEX (0xffe00fc0, 0xf8400000, t32_emulate_ldrstr,
-                                                REGS(NOPCX, ANY, 0, 0, NOSPPC)),
-
-       /* LDRB (literal)       1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
-       /* LDRSB (literal)      1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
-       /* LDRH (literal)       1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
-       /* LDRSH (literal)      1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
-       DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal,
-                                                REGS(PC, NOSPPCX, 0, 0, 0)),
-
-       /* STRB (immediate)     1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
-       /* STRH (immediate)     1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
-       /* LDRB (immediate)     1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
-       /* LDRSB (immediate)    1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
-       /* LDRH (immediate)     1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
-       /* LDRSH (immediate)    1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
-       DECODE_OR       (0xfec00800, 0xf8000800),
-       /* STRB (immediate)     1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
-       /* STRH (immediate)     1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRB (immediate)     1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRSB (immediate)    1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRH (immediate)     1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
-       /* LDRSH (immediate)    1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
-       DECODE_EMULATEX (0xfec00000, 0xf8800000, t32_emulate_ldrstr,
-                                                REGS(NOPCX, NOSPPCX, 0, 0, 0)),
-
-       /* STRB (register)      1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
-       /* STRH (register)      1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
-       /* LDRB (register)      1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
-       /* LDRSB (register)     1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
-       /* LDRH (register)      1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
-       /* LDRSH (register)     1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
-       DECODE_EMULATEX (0xfe800fc0, 0xf8000000, t32_emulate_ldrstr,
-                                                REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
-
-       /* Other unallocated instructions...                            */
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_1010___1111[] = {
-       /* Data-processing (register)                                   */
-
-       /* ???                  1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
-       DECODE_REJECT   (0xffe0f080, 0xfa60f080),
-
-       /* SXTH                 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
-       /* UXTH                 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
-       /* SXTB16               1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
-       /* UXTB16               1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
-       /* SXTB                 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
-       /* UXTB                 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
-       DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(0, 0, NOSPPC, 0, NOSPPC)),
-
-
-       /* ???                  1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
-       DECODE_REJECT   (0xff80f0b0, 0xfa80f030),
-       /* ???                  1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
-       DECODE_REJECT   (0xffb0f080, 0xfab0f000),
-
-       /* SADD16               1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
-       /* SASX                 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
-       /* SSAX                 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
-       /* SSUB16               1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
-       /* SADD8                1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
-       /* SSUB8                1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
-
-       /* QADD16               1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
-       /* QASX                 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
-       /* QSAX                 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
-       /* QSUB16               1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
-       /* QADD8                1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
-       /* QSUB8                1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
-
-       /* SHADD16              1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
-       /* SHASX                1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
-       /* SHSAX                1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
-       /* SHSUB16              1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
-       /* SHADD8               1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
-       /* SHSUB8               1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
-
-       /* UADD16               1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
-       /* UASX                 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
-       /* USAX                 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
-       /* USUB16               1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
-       /* UADD8                1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
-       /* USUB8                1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
-
-       /* UQADD16              1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
-       /* UQASX                1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
-       /* UQSAX                1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
-       /* UQSUB16              1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
-       /* UQADD8               1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
-       /* UQSUB8               1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
-
-       /* UHADD16              1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
-       /* UHASX                1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
-       /* UHSAX                1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
-       /* UHSUB16              1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
-       /* UHADD8               1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
-       /* UHSUB8               1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
-       DECODE_OR       (0xff80f080, 0xfa80f000),
-
-       /* SXTAH                1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
-       /* UXTAH                1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
-       /* SXTAB16              1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
-       /* UXTAB16              1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
-       /* SXTAB                1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
-       /* UXTAB                1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
-       DECODE_OR       (0xff80f080, 0xfa00f080),
-
-       /* QADD                 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
-       /* QDADD                1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
-       /* QSUB                 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
-       /* QDSUB                1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
-       DECODE_OR       (0xfff0f0c0, 0xfa80f080),
-
-       /* SEL                  1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
-       DECODE_OR       (0xfff0f0f0, 0xfaa0f080),
-
-       /* LSL                  1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
-       /* LSR                  1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
-       /* ASR                  1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
-       /* ROR                  1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
-       DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
-
-       /* CLZ                  1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
-       DECODE_OR       (0xfff0f0f0, 0xfab0f080),
-
-       /* REV                  1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
-       /* REV16                1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
-       /* RBIT                 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
-       /* REVSH                1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
-       DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, t32_emulate_rd8rn16_noflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
-
-       /* Other unallocated instructions...                            */
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_1011_0[] = {
-       /* Multiply, multiply accumulate, and absolute difference       */
-
-       /* ???                  1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
-       DECODE_REJECT   (0xfff0f0f0, 0xfb00f010),
-       /* ???                  1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
-       DECODE_REJECT   (0xfff0f0f0, 0xfb70f010),
-
-       /* SMULxy               1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
-       DECODE_OR       (0xfff0f0c0, 0xfb10f000),
-       /* MUL                  1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
-       /* SMUAD{X}             1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
-       /* SMULWy               1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
-       /* SMUSD{X}             1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
-       /* SMMUL{R}             1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
-       /* USAD8                1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
-       DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags,
-                                                REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
-
-       /* ???                  1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
-       DECODE_REJECT   (0xfff000f0, 0xfb700010),
-
-       /* SMLAxy               1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
-       DECODE_OR       (0xfff000c0, 0xfb100000),
-       /* MLA                  1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
-       /* MLS                  1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
-       /* SMLAD{X}             1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
-       /* SMLAWy               1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
-       /* SMLSD{X}             1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
-       /* SMMLA{R}             1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
-       /* SMMLS{R}             1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
-       /* USADA8               1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
-       DECODE_EMULATEX (0xff8000c0, 0xfb000000, t32_emulate_rd8rn16rm0ra12_noflags,
-                                                REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
-
-       /* Other unallocated instructions...                            */
-       DECODE_END
-};
-
-static const union decode_item t32_table_1111_1011_1[] = {
-       /* Long multiply, long multiply accumulate, and divide          */
-
-       /* UMAAL                1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
-       DECODE_OR       (0xfff000f0, 0xfbe00060),
-       /* SMLALxy              1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
-       DECODE_OR       (0xfff000c0, 0xfbc00080),
-       /* SMLALD{X}            1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
-       /* SMLSLD{X}            1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
-       DECODE_OR       (0xffe000e0, 0xfbc000c0),
-       /* SMULL                1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
-       /* UMULL                1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
-       /* SMLAL                1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
-       /* UMLAL                1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
-       DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags,
-                                                REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
-
-       /* SDIV                 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
-       /* UDIV                 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
-       /* Other unallocated instructions...                            */
-       DECODE_END
-};
-
-const union decode_item kprobe_decode_thumb32_table[] = {
-
-       /*
-        * Load/store multiple instructions
-        *                      1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
-
-       /*
-        * Load/store dual, load/store exclusive, table branch
-        *                      1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
-
-       /*
-        * Data-processing (shifted register)
-        *                      1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfe000000, 0xea000000, t32_table_1110_101x),
-
-       /*
-        * Coprocessor instructions
-        *                      1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_REJECT   (0xfc000000, 0xec000000),
-
-       /*
-        * Data-processing (modified immediate)
-        *                      1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
-
-       /*
-        * Data-processing (plain binary immediate)
-        *                      1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
-
-       /*
-        * Branches and miscellaneous control
-        *                      1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
-
-       /*
-        * Advanced SIMD element or structure load/store instructions
-        *                      1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_REJECT   (0xff100000, 0xf9000000),
-
-       /*
-        * Memory hints
-        *                      1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
-
-       /*
-        * Store single data item
-        *                      1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
-        * Load single data items
-        *                      1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xfe000000, 0xf8000000, t32_table_1111_100x),
-
-       /*
-        * Data-processing (register)
-        *                      1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
-
-       /*
-        * Multiply, multiply accumulate, and absolute difference
-        *                      1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xff800000, 0xfb000000, t32_table_1111_1011_0),
-
-       /*
-        * Long multiply, long multiply accumulate, and divide
-        *                      1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xff800000, 0xfb800000, t32_table_1111_1011_1),
-
-       /*
-        * Coprocessor instructions
-        *                      1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
-        */
-       DECODE_END
-};
-#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
-EXPORT_SYMBOL_GPL(kprobe_decode_thumb32_table);
-#endif
+/* t16 thumb actions */
 
 static void __kprobes
-t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_bxblx(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc + 2;
        int rm = (insn >> 3) & 0xf;
        unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm];
 
        if (insn & (1 << 7)) /* BLX ? */
-               regs->ARM_lr = (unsigned long)p->addr + 2;
+               regs->ARM_lr = regs->ARM_pc | 1;
 
        bx_write_pc(rmv, regs);
 }
 
 static void __kprobes
-t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_ldr_literal(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long* base = (unsigned long *)(thumb_probe_pc(p) & ~3);
+       unsigned long *base = (unsigned long *)((regs->ARM_pc + 2) & ~3);
        long index = insn & 0xff;
        int rt = (insn >> 8) & 0x7;
        regs->uregs[rt] = base[index];
 }
 
 static void __kprobes
-t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_ldrstr_sp_relative(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        unsigned long* base = (unsigned long *)regs->ARM_sp;
        long index = insn & 0xff;
        int rt = (insn >> 8) & 0x7;
@@ -986,20 +342,20 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_reladr(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        unsigned long base = (insn & 0x800) ? regs->ARM_sp
-                                           : (thumb_probe_pc(p) & ~3);
+                                           : ((regs->ARM_pc + 2) & ~3);
        long offset = insn & 0xff;
        int rt = (insn >> 8) & 0x7;
        regs->uregs[rt] = base + offset * 4;
 }
 
 static void __kprobes
-t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_add_sp_imm(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        long imm = insn & 0x7f;
        if (insn & 0x80) /* SUB */
                regs->ARM_sp -= imm * 4;
@@ -1008,21 +364,22 @@ t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_cbz(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
        int rn = insn & 0x7;
-       kprobe_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn;
+       probes_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn;
        if (nonzero & 0x800) {
                long i = insn & 0x200;
                long imm5 = insn & 0xf8;
-               unsigned long pc = thumb_probe_pc(p);
+               unsigned long pc = regs->ARM_pc + 2;
                regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2);
        }
 }
 
 static void __kprobes
-t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_it(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        /*
         * The 8 IT state bits are split into two parts in CPSR:
@@ -1030,7 +387,6 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
         *      ITSTATE<7:2> are in CPSR<15:10>
         * The new IT state is in the lower byte of insn.
         */
-       kprobe_opcode_t insn = p->opcode;
        unsigned long cpsr = regs->ARM_cpsr;
        cpsr &= ~PSR_IT_MASK;
        cpsr |= (insn & 0xfc) << 8;
@@ -1039,50 +395,54 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t16_singlestep_it(struct kprobe *p, struct pt_regs *regs)
+t16_singlestep_it(probes_opcode_t insn,
+                 struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        regs->ARM_pc += 2;
-       t16_simulate_it(p, regs);
+       t16_simulate_it(insn, asi, regs);
 }
 
-static enum kprobe_insn __kprobes
-t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t16_decode_it(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
        asi->insn_singlestep = t16_singlestep_it;
        return INSN_GOOD_NO_SLOT;
 }
 
 static void __kprobes
-t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_cond_branch(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc + 2;
        long offset = insn & 0x7f;
        offset -= insn & 0x80; /* Apply sign bit */
        regs->ARM_pc = pc + (offset * 2);
 }
 
-static enum kprobe_insn __kprobes
-t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t16_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
        int cc = (insn >> 8) & 0xf;
-       asi->insn_check_cc = kprobe_condition_checks[cc];
+       asi->insn_check_cc = probes_condition_checks[cc];
        asi->insn_handler = t16_simulate_cond_branch;
        return INSN_GOOD_NO_SLOT;
 }
 
 static void __kprobes
-t16_simulate_branch(struct kprobe *p, struct pt_regs *regs)
+t16_simulate_branch(probes_opcode_t insn,
+                  struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc + 2;
        long offset = insn & 0x3ff;
        offset -= insn & 0x400; /* Apply sign bit */
        regs->ARM_pc = pc + (offset * 2);
 }
 
 static unsigned long __kprobes
-t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_loregs(probes_opcode_t insn,
+                  struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        unsigned long oldcpsr = regs->ARM_cpsr;
        unsigned long newcpsr;
@@ -1095,7 +455,7 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
                "mrs    %[newcpsr], cpsr        \n\t"
                : [newcpsr] "=r" (newcpsr)
                : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
-                 [fn] "r" (p->ainsn.insn_fn)
+                 [fn] "r" (asi->insn_fn)
                : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
                  "lr", "memory", "cc"
                );
@@ -1104,24 +464,26 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
-t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_loregs_rwflags(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       regs->ARM_cpsr = t16_emulate_loregs(p, regs);
+       regs->ARM_cpsr = t16_emulate_loregs(insn, asi, regs);
 }
 
 static void __kprobes
-t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_loregs_noitrwflags(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       unsigned long cpsr = t16_emulate_loregs(p, regs);
+       unsigned long cpsr = t16_emulate_loregs(insn, asi, regs);
        if (!in_it_block(cpsr))
                regs->ARM_cpsr = cpsr;
 }
 
 static void __kprobes
-t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_hiregs(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
-       kprobe_opcode_t insn = p->opcode;
-       unsigned long pc = thumb_probe_pc(p);
+       unsigned long pc = regs->ARM_pc + 2;
        int rdn = (insn & 0x7) | ((insn & 0x80) >> 4);
        int rm = (insn >> 3) & 0xf;
 
@@ -1137,7 +499,7 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
                "blx    %[fn]                   \n\t"
                "mrs    %[cpsr], cpsr           \n\t"
                : "=r" (rdnv), [cpsr] "=r" (cpsr)
-               : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
+               : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (asi->insn_fn)
                : "lr", "memory", "cc"
        );
 
@@ -1148,8 +510,9 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
        regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
 }
 
-static enum kprobe_insn __kprobes
-t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t16_decode_hiregs(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
        insn &= ~0x00ff;
        insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
@@ -1159,7 +522,8 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 }
 
 static void __kprobes
-t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_push(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        __asm__ __volatile__ (
                "ldr    r9, [%[regs], #13*4]    \n\t"
@@ -1168,14 +532,15 @@ t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
                "blx    %[fn]                   \n\t"
                "str    r9, [%[regs], #13*4]    \n\t"
                :
-               : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn)
+               : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
                : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
                  "lr", "memory", "cc"
                );
 }
 
-static enum kprobe_insn __kprobes
-t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t16_decode_push(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
        /*
         * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}"
@@ -1189,7 +554,8 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 }
 
 static void __kprobes
-t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_pop_nopc(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        __asm__ __volatile__ (
                "ldr    r9, [%[regs], #13*4]    \n\t"
@@ -1198,14 +564,15 @@ t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
                "stmia  %[regs], {r0-r7}        \n\t"
                "str    r9, [%[regs], #13*4]    \n\t"
                :
-               : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn)
+               : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
                : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
                  "lr", "memory", "cc"
                );
 }
 
 static void __kprobes
-t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
+t16_emulate_pop_pc(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        register unsigned long pc asm("r8");
 
@@ -1216,7 +583,7 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
                "stmia  %[regs], {r0-r7}        \n\t"
                "str    r9, [%[regs], #13*4]    \n\t"
                : "=r" (pc)
-               : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn)
+               : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
                : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
                  "lr", "memory", "cc"
                );
@@ -1224,8 +591,9 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
        bx_write_pc(pc, regs);
 }
 
-static enum kprobe_insn __kprobes
-t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+static enum probes_insn __kprobes
+t16_decode_pop(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *d)
 {
        /*
         * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}"
@@ -1239,231 +607,56 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        return INSN_GOOD;
 }
 
-static const union decode_item t16_table_1011[] = {
-       /* Miscellaneous 16-bit instructions                */
-
-       /* ADD (SP plus immediate)      1011 0000 0xxx xxxx */
-       /* SUB (SP minus immediate)     1011 0000 1xxx xxxx */
-       DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm),
-
-       /* CBZ                          1011 00x1 xxxx xxxx */
-       /* CBNZ                         1011 10x1 xxxx xxxx */
-       DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz),
-
-       /* SXTH                         1011 0010 00xx xxxx */
-       /* SXTB                         1011 0010 01xx xxxx */
-       /* UXTH                         1011 0010 10xx xxxx */
-       /* UXTB                         1011 0010 11xx xxxx */
-       /* REV                          1011 1010 00xx xxxx */
-       /* REV16                        1011 1010 01xx xxxx */
-       /* ???                          1011 1010 10xx xxxx */
-       /* REVSH                        1011 1010 11xx xxxx */
-       DECODE_REJECT   (0xffc0, 0xba80),
-       DECODE_EMULATE  (0xf500, 0xb000, t16_emulate_loregs_rwflags),
-
-       /* PUSH                         1011 010x xxxx xxxx */
-       DECODE_CUSTOM   (0xfe00, 0xb400, t16_decode_push),
-       /* POP                          1011 110x xxxx xxxx */
-       DECODE_CUSTOM   (0xfe00, 0xbc00, t16_decode_pop),
-
-       /*
-        * If-Then, and hints
-        *                              1011 1111 xxxx xxxx
-        */
-
-       /* YIELD                        1011 1111 0001 0000 */
-       DECODE_OR       (0xffff, 0xbf10),
-       /* SEV                          1011 1111 0100 0000 */
-       DECODE_EMULATE  (0xffff, 0xbf40, kprobe_emulate_none),
-       /* NOP                          1011 1111 0000 0000 */
-       /* WFE                          1011 1111 0010 0000 */
-       /* WFI                          1011 1111 0011 0000 */
-       DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop),
-       /* Unassigned hints             1011 1111 xxxx 0000 */
-       DECODE_REJECT   (0xff0f, 0xbf00),
-       /* IT                           1011 1111 xxxx xxxx */
-       DECODE_CUSTOM   (0xff00, 0xbf00, t16_decode_it),
-
-       /* SETEND                       1011 0110 010x xxxx */
-       /* CPS                          1011 0110 011x xxxx */
-       /* BKPT                         1011 1110 xxxx xxxx */
-       /* And unallocated instructions...                  */
-       DECODE_END
+const union decode_action kprobes_t16_actions[NUM_PROBES_T16_ACTIONS] = {
+       [PROBES_T16_ADD_SP] = {.handler = t16_simulate_add_sp_imm},
+       [PROBES_T16_CBZ] = {.handler = t16_simulate_cbz},
+       [PROBES_T16_SIGN_EXTEND] = {.handler = t16_emulate_loregs_rwflags},
+       [PROBES_T16_PUSH] = {.decoder = t16_decode_push},
+       [PROBES_T16_POP] = {.decoder = t16_decode_pop},
+       [PROBES_T16_SEV] = {.handler = probes_emulate_none},
+       [PROBES_T16_WFE] = {.handler = probes_simulate_nop},
+       [PROBES_T16_IT] = {.decoder = t16_decode_it},
+       [PROBES_T16_CMP] = {.handler = t16_emulate_loregs_rwflags},
+       [PROBES_T16_ADDSUB] = {.handler = t16_emulate_loregs_noitrwflags},
+       [PROBES_T16_LOGICAL] = {.handler = t16_emulate_loregs_noitrwflags},
+       [PROBES_T16_LDR_LIT] = {.handler = t16_simulate_ldr_literal},
+       [PROBES_T16_BLX] = {.handler = t16_simulate_bxblx},
+       [PROBES_T16_HIREGOPS] = {.decoder = t16_decode_hiregs},
+       [PROBES_T16_LDRHSTRH] = {.handler = t16_emulate_loregs_rwflags},
+       [PROBES_T16_LDRSTR] = {.handler = t16_simulate_ldrstr_sp_relative},
+       [PROBES_T16_ADR] = {.handler = t16_simulate_reladr},
+       [PROBES_T16_LDMSTM] = {.handler = t16_emulate_loregs_rwflags},
+       [PROBES_T16_BRANCH_COND] = {.decoder = t16_decode_cond_branch},
+       [PROBES_T16_BRANCH] = {.handler = t16_simulate_branch},
 };
 
-const union decode_item kprobe_decode_thumb16_table[] = {
-
-       /*
-        * Shift (immediate), add, subtract, move, and compare
-        *                              00xx xxxx xxxx xxxx
-        */
-
-       /* CMP (immediate)              0010 1xxx xxxx xxxx */
-       DECODE_EMULATE  (0xf800, 0x2800, t16_emulate_loregs_rwflags),
-
-       /* ADD (register)               0001 100x xxxx xxxx */
-       /* SUB (register)               0001 101x xxxx xxxx */
-       /* LSL (immediate)              0000 0xxx xxxx xxxx */
-       /* LSR (immediate)              0000 1xxx xxxx xxxx */
-       /* ASR (immediate)              0001 0xxx xxxx xxxx */
-       /* ADD (immediate, Thumb)       0001 110x xxxx xxxx */
-       /* SUB (immediate, Thumb)       0001 111x xxxx xxxx */
-       /* MOV (immediate)              0010 0xxx xxxx xxxx */
-       /* ADD (immediate, Thumb)       0011 0xxx xxxx xxxx */
-       /* SUB (immediate, Thumb)       0011 1xxx xxxx xxxx */
-       DECODE_EMULATE  (0xc000, 0x0000, t16_emulate_loregs_noitrwflags),
-
-       /*
-        * 16-bit Thumb data-processing instructions
-        *                              0100 00xx xxxx xxxx
-        */
-
-       /* TST (register)               0100 0010 00xx xxxx */
-       DECODE_EMULATE  (0xffc0, 0x4200, t16_emulate_loregs_rwflags),
-       /* CMP (register)               0100 0010 10xx xxxx */
-       /* CMN (register)               0100 0010 11xx xxxx */
-       DECODE_EMULATE  (0xff80, 0x4280, t16_emulate_loregs_rwflags),
-       /* AND (register)               0100 0000 00xx xxxx */
-       /* EOR (register)               0100 0000 01xx xxxx */
-       /* LSL (register)               0100 0000 10xx xxxx */
-       /* LSR (register)               0100 0000 11xx xxxx */
-       /* ASR (register)               0100 0001 00xx xxxx */
-       /* ADC (register)               0100 0001 01xx xxxx */
-       /* SBC (register)               0100 0001 10xx xxxx */
-       /* ROR (register)               0100 0001 11xx xxxx */
-       /* RSB (immediate)              0100 0010 01xx xxxx */
-       /* ORR (register)               0100 0011 00xx xxxx */
-       /* MUL                          0100 0011 00xx xxxx */
-       /* BIC (register)               0100 0011 10xx xxxx */
-       /* MVN (register)               0100 0011 10xx xxxx */
-       DECODE_EMULATE  (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags),
-
-       /*
-        * Special data instructions and branch and exchange
-        *                              0100 01xx xxxx xxxx
-        */
-
-       /* BLX pc                       0100 0111 1111 1xxx */
-       DECODE_REJECT   (0xfff8, 0x47f8),
-
-       /* BX (register)                0100 0111 0xxx xxxx */
-       /* BLX (register)               0100 0111 1xxx xxxx */
-       DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx),
-
-       /* ADD pc, pc                   0100 0100 1111 1111 */
-       DECODE_REJECT   (0xffff, 0x44ff),
-
-       /* ADD (register)               0100 0100 xxxx xxxx */
-       /* CMP (register)               0100 0101 xxxx xxxx */
-       /* MOV (register)               0100 0110 xxxx xxxx */
-       DECODE_CUSTOM   (0xfc00, 0x4400, t16_decode_hiregs),
-
-       /*
-        * Load from Literal Pool
-        * LDR (literal)                0100 1xxx xxxx xxxx
-        */
-       DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal),
-
-       /*
-        * 16-bit Thumb Load/store instructions
-        *                              0101 xxxx xxxx xxxx
-        *                              011x xxxx xxxx xxxx
-        *                              100x xxxx xxxx xxxx
-        */
-
-       /* STR (register)               0101 000x xxxx xxxx */
-       /* STRH (register)              0101 001x xxxx xxxx */
-       /* STRB (register)              0101 010x xxxx xxxx */
-       /* LDRSB (register)             0101 011x xxxx xxxx */
-       /* LDR (register)               0101 100x xxxx xxxx */
-       /* LDRH (register)              0101 101x xxxx xxxx */
-       /* LDRB (register)              0101 110x xxxx xxxx */
-       /* LDRSH (register)             0101 111x xxxx xxxx */
-       /* STR (immediate, Thumb)       0110 0xxx xxxx xxxx */
-       /* LDR (immediate, Thumb)       0110 1xxx xxxx xxxx */
-       /* STRB (immediate, Thumb)      0111 0xxx xxxx xxxx */
-       /* LDRB (immediate, Thumb)      0111 1xxx xxxx xxxx */
-       DECODE_EMULATE  (0xc000, 0x4000, t16_emulate_loregs_rwflags),
-       /* STRH (immediate, Thumb)      1000 0xxx xxxx xxxx */
-       /* LDRH (immediate, Thumb)      1000 1xxx xxxx xxxx */
-       DECODE_EMULATE  (0xf000, 0x8000, t16_emulate_loregs_rwflags),
-       /* STR (immediate, Thumb)       1001 0xxx xxxx xxxx */
-       /* LDR (immediate, Thumb)       1001 1xxx xxxx xxxx */
-       DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative),
-
-       /*
-        * Generate PC-/SP-relative address
-        * ADR (literal)                1010 0xxx xxxx xxxx
-        * ADD (SP plus immediate)      1010 1xxx xxxx xxxx
-        */
-       DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr),
-
-       /*
-        * Miscellaneous 16-bit instructions
-        *                              1011 xxxx xxxx xxxx
-        */
-       DECODE_TABLE    (0xf000, 0xb000, t16_table_1011),
-
-       /* STM                          1100 0xxx xxxx xxxx */
-       /* LDM                          1100 1xxx xxxx xxxx */
-       DECODE_EMULATE  (0xf000, 0xc000, t16_emulate_loregs_rwflags),
-
-       /*
-        * Conditional branch, and Supervisor Call
-        */
-
-       /* Permanently UNDEFINED        1101 1110 xxxx xxxx */
-       /* SVC                          1101 1111 xxxx xxxx */
-       DECODE_REJECT   (0xfe00, 0xde00),
-
-       /* Conditional branch           1101 xxxx xxxx xxxx */
-       DECODE_CUSTOM   (0xf000, 0xd000, t16_decode_cond_branch),
-
-       /*
-        * Unconditional branch
-        * B                            1110 0xxx xxxx xxxx
-        */
-       DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch),
-
-       DECODE_END
+const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
+       [PROBES_T32_LDMSTM] = {.decoder = t32_decode_ldmstm},
+       [PROBES_T32_LDRDSTRD] = {.handler = t32_emulate_ldrdstrd},
+       [PROBES_T32_TABLE_BRANCH] = {.handler = t32_simulate_table_branch},
+       [PROBES_T32_TST] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_MOV] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_ADDSUB] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_LOGICAL] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_CMP] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_ADDWSUBW_PC] = {.handler = t32_emulate_rd8pc16_noflags,},
+       [PROBES_T32_ADDWSUBW] = {.handler = t32_emulate_rd8rn16_noflags},
+       [PROBES_T32_MOVW] = {.handler = t32_emulate_rd8rn16_noflags},
+       [PROBES_T32_SAT] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_BITFIELD] = {.handler = t32_emulate_rd8rn16_noflags},
+       [PROBES_T32_SEV] = {.handler = probes_emulate_none},
+       [PROBES_T32_WFE] = {.handler = probes_simulate_nop},
+       [PROBES_T32_MRS] = {.handler = t32_simulate_mrs},
+       [PROBES_T32_BRANCH_COND] = {.decoder = t32_decode_cond_branch},
+       [PROBES_T32_BRANCH] = {.handler = t32_simulate_branch},
+       [PROBES_T32_PLDI] = {.handler = probes_simulate_nop},
+       [PROBES_T32_LDR_LIT] = {.handler = t32_simulate_ldr_literal},
+       [PROBES_T32_LDRSTR] = {.handler = t32_emulate_ldrstr},
+       [PROBES_T32_SIGN_EXTEND] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_MEDIA] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_REVERSE] = {.handler = t32_emulate_rd8rn16_noflags},
+       [PROBES_T32_MUL_ADD] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
+       [PROBES_T32_MUL_ADD2] = {.handler = t32_emulate_rd8rn16rm0ra12_noflags},
+       [PROBES_T32_MUL_ADD_LONG] = {
+               .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
 };
-#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
-EXPORT_SYMBOL_GPL(kprobe_decode_thumb16_table);
-#endif
-
-static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
-{
-       if (unlikely(in_it_block(cpsr)))
-               return kprobe_condition_checks[current_cond(cpsr)](cpsr);
-       return true;
-}
-
-static void __kprobes thumb16_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
-       regs->ARM_pc += 2;
-       p->ainsn.insn_handler(p, regs);
-       regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
-}
-
-static void __kprobes thumb32_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
-       regs->ARM_pc += 4;
-       p->ainsn.insn_handler(p, regs);
-       regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
-}
-
-enum kprobe_insn __kprobes
-thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-       asi->insn_singlestep = thumb16_singlestep;
-       asi->insn_check_cc = thumb_check_cc;
-       return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true);
-}
-
-enum kprobe_insn __kprobes
-thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
-{
-       asi->insn_singlestep = thumb32_singlestep;
-       asi->insn_check_cc = thumb_check_cc;
-       return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true);
-}
index a7b621ece23d3c729d681e8004952c320215e9fc..8795f9f819d5820285bd5e737456ddb7a3f802bb 100644 (file)
 #include <linux/stringify.h>
 #include <asm/traps.h>
 #include <asm/cacheflush.h>
+#include <linux/percpu.h>
+#include <linux/bug.h>
 
 #include "kprobes.h"
+#include "probes-arm.h"
+#include "probes-thumb.h"
 #include "patch.h"
 
 #define MIN_STACK_SIZE(addr)                           \
@@ -54,6 +58,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        unsigned long addr = (unsigned long)p->addr;
        bool thumb;
        kprobe_decode_insn_t *decode_insn;
+       const union decode_action *actions;
        int is;
 
        if (in_exception_text(addr))
@@ -66,21 +71,25 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        if (is_wide_instruction(insn)) {
                insn <<= 16;
                insn |= ((u16 *)addr)[1];
-               decode_insn = thumb32_kprobe_decode_insn;
-       } else
-               decode_insn = thumb16_kprobe_decode_insn;
+               decode_insn = thumb32_probes_decode_insn;
+               actions = kprobes_t32_actions;
+       } else {
+               decode_insn = thumb16_probes_decode_insn;
+               actions = kprobes_t16_actions;
+       }
 #else /* !CONFIG_THUMB2_KERNEL */
        thumb = false;
        if (addr & 0x3)
                return -EINVAL;
        insn = *p->addr;
-       decode_insn = arm_kprobe_decode_insn;
+       decode_insn = arm_probes_decode_insn;
+       actions = kprobes_arm_actions;
 #endif
 
        p->opcode = insn;
        p->ainsn.insn = tmp_insn;
 
-       switch ((*decode_insn)(insn, &p->ainsn)) {
+       switch ((*decode_insn)(insn, &p->ainsn, true, actions)) {
        case INSN_REJECTED:     /* not supported */
                return -EINVAL;
 
@@ -92,7 +101,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
                        p->ainsn.insn[is] = tmp_insn[is];
                flush_insns(p->ainsn.insn,
                                sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE);
-               p->ainsn.insn_fn = (kprobe_insn_fn_t *)
+               p->ainsn.insn_fn = (probes_insn_fn_t *)
                                        ((uintptr_t)p->ainsn.insn | thumb);
                break;
 
@@ -197,7 +206,7 @@ singlestep_skip(struct kprobe *p, struct pt_regs *regs)
 static inline void __kprobes
 singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
-       p->ainsn.insn_singlestep(p, regs);
+       p->ainsn.insn_singlestep(p->opcode, &p->ainsn, regs);
 }
 
 /*
@@ -607,7 +616,7 @@ static struct undef_hook kprobes_arm_break_hook = {
 
 int __init arch_init_kprobes()
 {
-       arm_kprobe_decode_init();
+       arm_probes_decode_init();
 #ifdef CONFIG_THUMB2_KERNEL
        register_undef_hook(&kprobes_thumb16_break_hook);
        register_undef_hook(&kprobes_thumb32_break_hook);
index 38945f78f9f1cea97a9607d9a1572b9e5184ad81..9a2712ecefc32d4fca8f389f622409a55099f056 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef _ARM_KERNEL_KPROBES_H
 #define _ARM_KERNEL_KPROBES_H
 
+#include "probes.h"
+
 /*
  * These undefined instructions must be unique and
  * reserved solely for kprobes' use.
 #define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION  0xde18
 #define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION  0xf7f0a018
 
+enum probes_insn __kprobes
+kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
+               const struct decode_header *h);
 
-enum kprobe_insn {
-       INSN_REJECTED,
-       INSN_GOOD,
-       INSN_GOOD_NO_SLOT
-};
-
-typedef enum kprobe_insn (kprobe_decode_insn_t)(kprobe_opcode_t,
-                                               struct arch_specific_insn *);
+typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t,
+                                               struct arch_probes_insn *,
+                                               bool,
+                                               const union decode_action *);
 
 #ifdef CONFIG_THUMB2_KERNEL
 
-enum kprobe_insn thumb16_kprobe_decode_insn(kprobe_opcode_t,
-                                               struct arch_specific_insn *);
-enum kprobe_insn thumb32_kprobe_decode_insn(kprobe_opcode_t,
-                                               struct arch_specific_insn *);
+extern const union decode_action kprobes_t32_actions[];
+extern const union decode_action kprobes_t16_actions[];
 
 #else /* !CONFIG_THUMB2_KERNEL */
 
-enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t,
-                                       struct arch_specific_insn *);
-#endif
-
-void __init arm_kprobe_decode_init(void);
-
-extern kprobe_check_cc * const kprobe_condition_checks[16];
-
-
-#if __LINUX_ARM_ARCH__ >= 7
-
-/* str_pc_offset is architecturally defined from ARMv7 onwards */
-#define str_pc_offset 8
-#define find_str_pc_offset()
-
-#else /* __LINUX_ARM_ARCH__ < 7 */
-
-/* We need a run-time check to determine str_pc_offset */
-extern int str_pc_offset;
-void __init find_str_pc_offset(void);
+extern const union decode_action kprobes_arm_actions[];
 
 #endif
 
-
-/*
- * Update ITSTATE after normal execution of an IT block instruction.
- *
- * The 8 IT state bits are split into two parts in CPSR:
- *     ITSTATE<1:0> are in CPSR<26:25>
- *     ITSTATE<7:2> are in CPSR<15:10>
- */
-static inline unsigned long it_advance(unsigned long cpsr)
-       {
-       if ((cpsr & 0x06000400) == 0) {
-               /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
-               cpsr &= ~PSR_IT_MASK;
-       } else {
-               /* We need to shift left ITSTATE<4:0> */
-               const unsigned long mask = 0x06001c00;  /* Mask ITSTATE<4:0> */
-               unsigned long it = cpsr & mask;
-               it <<= 1;
-               it |= it >> (27 - 10);  /* Carry ITSTATE<2> to correct place */
-               it &= mask;
-               cpsr &= ~mask;
-               cpsr |= it;
-       }
-       return cpsr;
-}
-
-static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
-{
-       long cpsr = regs->ARM_cpsr;
-       if (pcv & 0x1) {
-               cpsr |= PSR_T_BIT;
-               pcv &= ~0x1;
-       } else {
-               cpsr &= ~PSR_T_BIT;
-               pcv &= ~0x2;    /* Avoid UNPREDICTABLE address allignment */
-       }
-       regs->ARM_cpsr = cpsr;
-       regs->ARM_pc = pcv;
-}
-
-
-#if __LINUX_ARM_ARCH__ >= 6
-
-/* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */
-#define load_write_pc_interworks true
-#define test_load_write_pc_interworking()
-
-#else /* __LINUX_ARM_ARCH__ < 6 */
-
-/* We need run-time testing to determine if load_write_pc() should interwork. */
-extern bool load_write_pc_interworks;
-void __init test_load_write_pc_interworking(void);
-
-#endif
-
-static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
-{
-       if (load_write_pc_interworks)
-               bx_write_pc(pcv, regs);
-       else
-               regs->ARM_pc = pcv;
-}
-
-
-#if __LINUX_ARM_ARCH__ >= 7
-
-#define alu_write_pc_interworks true
-#define test_alu_write_pc_interworking()
-
-#elif __LINUX_ARM_ARCH__ <= 5
-
-/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
-#define alu_write_pc_interworks false
-#define test_alu_write_pc_interworking()
-
-#else /* __LINUX_ARM_ARCH__ == 6 */
-
-/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
-extern bool alu_write_pc_interworks;
-void __init test_alu_write_pc_interworking(void);
-
-#endif /* __LINUX_ARM_ARCH__ == 6 */
-
-static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
-{
-       if (alu_write_pc_interworks)
-               bx_write_pc(pcv, regs);
-       else
-               regs->ARM_pc = pcv;
-}
-
-
-void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs);
-void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs);
-
-enum kprobe_insn __kprobes
-kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
-
-/*
- * Test if load/store instructions writeback the address register.
- * if P (bit 24) == 0 or W (bit 21) == 1
- */
-#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
-
-/*
- * The following definitions and macros are used to build instruction
- * decoding tables for use by kprobe_decode_insn.
- *
- * These tables are a concatenation of entries each of which consist of one of
- * the decode_* structs. All of the fields in every type of decode structure
- * are of the union type decode_item, therefore the entire decode table can be
- * viewed as an array of these and declared like:
- *
- *     static const union decode_item table_name[] = {};
- *
- * In order to construct each entry in the table, macros are used to
- * initialise a number of sequential decode_item values in a layout which
- * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct
- * decode_simulate by initialising four decode_item objects like this...
- *
- *     {.bits = _type},
- *     {.bits = _mask},
- *     {.bits = _value},
- *     {.handler = _handler},
- *
- * Initialising a specified member of the union means that the compiler
- * will produce a warning if the argument is of an incorrect type.
- *
- * Below is a list of each of the macros used to initialise entries and a
- * description of the action performed when that entry is matched to an
- * instruction. A match is found when (instruction & mask) == value.
- *
- * DECODE_TABLE(mask, value, table)
- *     Instruction decoding jumps to parsing the new sub-table 'table'.
- *
- * DECODE_CUSTOM(mask, value, decoder)
- *     The custom function 'decoder' is called to the complete decoding
- *     of an instruction.
- *
- * DECODE_SIMULATE(mask, value, handler)
- *     Set the probes instruction handler to 'handler', this will be used
- *     to simulate the instruction when the probe is hit. Decoding returns
- *     with INSN_GOOD_NO_SLOT.
- *
- * DECODE_EMULATE(mask, value, handler)
- *     Set the probes instruction handler to 'handler', this will be used
- *     to emulate the instruction when the probe is hit. The modified
- *     instruction (see below) is placed in the probes instruction slot so it
- *     may be called by the emulation code. Decoding returns with INSN_GOOD.
- *
- * DECODE_REJECT(mask, value)
- *     Instruction decoding fails with INSN_REJECTED
- *
- * DECODE_OR(mask, value)
- *     This allows the mask/value test of multiple table entries to be
- *     logically ORed. Once an 'or' entry is matched the decoding action to
- *     be performed is that of the next entry which isn't an 'or'. E.g.
- *
- *             DECODE_OR       (mask1, value1)
- *             DECODE_OR       (mask2, value2)
- *             DECODE_SIMULATE (mask3, value3, simulation_handler)
- *
- *     This means that if any of the three mask/value pairs match the
- *     instruction being decoded, then 'simulation_handler' will be used
- *     for it.
- *
- * Both the SIMULATE and EMULATE macros have a second form which take an
- * additional 'regs' argument.
- *
- *     DECODE_SIMULATEX(mask, value, handler, regs)
- *     DECODE_EMULATEX (mask, value, handler, regs)
- *
- * These are used to specify what kind of CPU register is encoded in each of the
- * least significant 5 nibbles of the instruction being decoded. The regs value
- * is specified using the REGS macro, this takes any of the REG_TYPE_* values
- * from enum decode_reg_type as arguments; only the '*' part of the name is
- * given. E.g.
- *
- *     REGS(0, ANY, NOPC, 0, ANY)
- *
- * This indicates an instruction is encoded like:
- *
- *     bits 19..16     ignore
- *     bits 15..12     any register allowed here
- *     bits 11.. 8     any register except PC allowed here
- *     bits  7.. 4     ignore
- *     bits  3.. 0     any register allowed here
- *
- * This register specification is checked after a decode table entry is found to
- * match an instruction (through the mask/value test). Any invalid register then
- * found in the instruction will cause decoding to fail with INSN_REJECTED. In
- * the above example this would happen if bits 11..8 of the instruction were
- * 1111, indicating R15 or PC.
- *
- * As well as checking for legal combinations of registers, this data is also
- * used to modify the registers encoded in the instructions so that an
- * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.)
- *
- * Here is a real example which matches ARM instructions of the form
- * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
- *
- *     DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
- *                                              REGS(ANY, ANY, NOPC, 0, ANY)),
- *                                                   ^    ^    ^        ^
- *                                                   Rn   Rd   Rs       Rm
- *
- * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because
- * Rs == R15
- *
- * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
- * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
- * the kprobes instruction slot. This can then be called later by the handler
- * function emulate_rd12rn16rm0rs8_rwflags in order to simulate the instruction.
- */
-
-enum decode_type {
-       DECODE_TYPE_END,
-       DECODE_TYPE_TABLE,
-       DECODE_TYPE_CUSTOM,
-       DECODE_TYPE_SIMULATE,
-       DECODE_TYPE_EMULATE,
-       DECODE_TYPE_OR,
-       DECODE_TYPE_REJECT,
-       NUM_DECODE_TYPES /* Must be last enum */
-};
-
-#define DECODE_TYPE_BITS       4
-#define DECODE_TYPE_MASK       ((1 << DECODE_TYPE_BITS) - 1)
-
-enum decode_reg_type {
-       REG_TYPE_NONE = 0, /* Not a register, ignore */
-       REG_TYPE_ANY,      /* Any register allowed */
-       REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */
-       REG_TYPE_SP,       /* Register must be SP */
-       REG_TYPE_PC,       /* Register must be PC */
-       REG_TYPE_NOSP,     /* Register must not be SP */
-       REG_TYPE_NOSPPC,   /* Register must not be SP or PC */
-       REG_TYPE_NOPC,     /* Register must not be PC */
-       REG_TYPE_NOPCWB,   /* No PC if load/store write-back flag also set */
-
-       /* The following types are used when the encoding for PC indicates
-        * another instruction form. This distiction only matters for test
-        * case coverage checks.
-        */
-       REG_TYPE_NOPCX,    /* Register must not be PC */
-       REG_TYPE_NOSPPCX,  /* Register must not be SP or PC */
-
-       /* Alias to allow '0' arg to be used in REGS macro. */
-       REG_TYPE_0 = REG_TYPE_NONE
-};
-
-#define REGS(r16, r12, r8, r4, r0)     \
-       ((REG_TYPE_##r16) << 16) +      \
-       ((REG_TYPE_##r12) << 12) +      \
-       ((REG_TYPE_##r8) << 8) +        \
-       ((REG_TYPE_##r4) << 4) +        \
-       (REG_TYPE_##r0)
-
-union decode_item {
-       u32                     bits;
-       const union decode_item *table;
-       kprobe_insn_handler_t   *handler;
-       kprobe_decode_insn_t    *decoder;
-};
-
-
-#define DECODE_END                     \
-       {.bits = DECODE_TYPE_END}
-
-
-struct decode_header {
-       union decode_item       type_regs;
-       union decode_item       mask;
-       union decode_item       value;
-};
-
-#define DECODE_HEADER(_type, _mask, _value, _regs)             \
-       {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)},      \
-       {.bits = (_mask)},                                      \
-       {.bits = (_value)}
-
-
-struct decode_table {
-       struct decode_header    header;
-       union decode_item       table;
-};
-
-#define DECODE_TABLE(_mask, _value, _table)                    \
-       DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0),     \
-       {.table = (_table)}
-
-
-struct decode_custom {
-       struct decode_header    header;
-       union decode_item       decoder;
-};
-
-#define DECODE_CUSTOM(_mask, _value, _decoder)                 \
-       DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0),    \
-       {.decoder = (_decoder)}
-
-
-struct decode_simulate {
-       struct decode_header    header;
-       union decode_item       handler;
-};
-
-#define DECODE_SIMULATEX(_mask, _value, _handler, _regs)               \
-       DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs),      \
-       {.handler = (_handler)}
-
-#define DECODE_SIMULATE(_mask, _value, _handler)       \
-       DECODE_SIMULATEX(_mask, _value, _handler, 0)
-
-
-struct decode_emulate {
-       struct decode_header    header;
-       union decode_item       handler;
-};
-
-#define DECODE_EMULATEX(_mask, _value, _handler, _regs)                        \
-       DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs),       \
-       {.handler = (_handler)}
-
-#define DECODE_EMULATE(_mask, _value, _handler)                \
-       DECODE_EMULATEX(_mask, _value, _handler, 0)
-
-
-struct decode_or {
-       struct decode_header    header;
-};
-
-#define DECODE_OR(_mask, _value)                               \
-       DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
-
-
-struct decode_reject {
-       struct decode_header    header;
-};
-
-#define DECODE_REJECT(_mask, _value)                           \
-       DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
-
-
-#ifdef CONFIG_THUMB2_KERNEL
-extern const union decode_item kprobe_decode_thumb16_table[];
-extern const union decode_item kprobe_decode_thumb32_table[];
-#else
-extern const union decode_item kprobe_decode_arm_table[];
-#endif
-
-
-int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
-                       const union decode_item *table, bool thumb16);
-
-
 #endif /* _ARM_KERNEL_KPROBES_H */
index 789d846a9184531a1c9c05cc97a54966101a13e2..a6bc431cde701037ca6146d6931a56aa96838cb1 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
 
 #include <asm/irq_regs.h>
 #include <asm/pmu.h>
@@ -205,6 +207,8 @@ armpmu_del(struct perf_event *event, int flags)
        armpmu_stop(event, PERF_EF_UPDATE);
        hw_events->events[idx] = NULL;
        clear_bit(idx, hw_events->used_mask);
+       if (armpmu->clear_event_idx)
+               armpmu->clear_event_idx(hw_events, event);
 
        perf_event_update_userpage(event);
 }
@@ -295,14 +299,27 @@ validate_group(struct perf_event *event)
 
 static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
 {
-       struct arm_pmu *armpmu = (struct arm_pmu *) dev;
-       struct platform_device *plat_device = armpmu->plat_device;
-       struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev);
+       struct arm_pmu *armpmu;
+       struct platform_device *plat_device;
+       struct arm_pmu_platdata *plat;
+       int ret;
+       u64 start_clock, finish_clock;
 
+       if (irq_is_percpu(irq))
+               dev = *(void **)dev;
+       armpmu = dev;
+       plat_device = armpmu->plat_device;
+       plat = dev_get_platdata(&plat_device->dev);
+
+       start_clock = sched_clock();
        if (plat && plat->handle_irq)
-               return plat->handle_irq(irq, dev, armpmu->handle_irq);
+               ret = plat->handle_irq(irq, dev, armpmu->handle_irq);
        else
-               return armpmu->handle_irq(irq, dev);
+               ret = armpmu->handle_irq(irq, dev);
+       finish_clock = sched_clock();
+
+       perf_sample_event_took(finish_clock - start_clock);
+       return ret;
 }
 
 static void
index 20d553c9f5e2928a0c4321878a30520dde87656d..51798d7854aca9b9109abba97c1cc22a6efc5a33 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
 
 #include <asm/cputype.h>
 #include <asm/irq_regs.h>
@@ -33,6 +35,7 @@
 /* Set at runtime when we know what CPU type we are. */
 static struct arm_pmu *cpu_pmu;
 
+static DEFINE_PER_CPU(struct arm_pmu *, percpu_pmu);
 static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
 static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
 static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
@@ -71,6 +74,26 @@ static struct pmu_hw_events *cpu_pmu_get_cpu_events(void)
        return this_cpu_ptr(&cpu_hw_events);
 }
 
+static void cpu_pmu_enable_percpu_irq(void *data)
+{
+       struct arm_pmu *cpu_pmu = data;
+       struct platform_device *pmu_device = cpu_pmu->plat_device;
+       int irq = platform_get_irq(pmu_device, 0);
+
+       enable_percpu_irq(irq, IRQ_TYPE_NONE);
+       cpumask_set_cpu(smp_processor_id(), &cpu_pmu->active_irqs);
+}
+
+static void cpu_pmu_disable_percpu_irq(void *data)
+{
+       struct arm_pmu *cpu_pmu = data;
+       struct platform_device *pmu_device = cpu_pmu->plat_device;
+       int irq = platform_get_irq(pmu_device, 0);
+
+       cpumask_clear_cpu(smp_processor_id(), &cpu_pmu->active_irqs);
+       disable_percpu_irq(irq);
+}
+
 static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu)
 {
        int i, irq, irqs;
@@ -78,12 +101,18 @@ static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu)
 
        irqs = min(pmu_device->num_resources, num_possible_cpus());
 
-       for (i = 0; i < irqs; ++i) {
-               if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
-                       continue;
-               irq = platform_get_irq(pmu_device, i);
-               if (irq >= 0)
-                       free_irq(irq, cpu_pmu);
+       irq = platform_get_irq(pmu_device, 0);
+       if (irq >= 0 && irq_is_percpu(irq)) {
+               on_each_cpu(cpu_pmu_disable_percpu_irq, cpu_pmu, 1);
+               free_percpu_irq(irq, &percpu_pmu);
+       } else {
+               for (i = 0; i < irqs; ++i) {
+                       if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
+                               continue;
+                       irq = platform_get_irq(pmu_device, i);
+                       if (irq >= 0)
+                               free_irq(irq, cpu_pmu);
+               }
        }
 }
 
@@ -101,33 +130,44 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
                return -ENODEV;
        }
 
-       for (i = 0; i < irqs; ++i) {
-               err = 0;
-               irq = platform_get_irq(pmu_device, i);
-               if (irq < 0)
-                       continue;
-
-               /*
-                * If we have a single PMU interrupt that we can't shift,
-                * assume that we're running on a uniprocessor machine and
-                * continue. Otherwise, continue without this interrupt.
-                */
-               if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
-                       pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
-                                   irq, i);
-                       continue;
-               }
-
-               err = request_irq(irq, handler,
-                                 IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu",
-                                 cpu_pmu);
+       irq = platform_get_irq(pmu_device, 0);
+       if (irq >= 0 && irq_is_percpu(irq)) {
+               err = request_percpu_irq(irq, handler, "arm-pmu", &percpu_pmu);
                if (err) {
                        pr_err("unable to request IRQ%d for ARM PMU counters\n",
                                irq);
                        return err;
                }
-
-               cpumask_set_cpu(i, &cpu_pmu->active_irqs);
+               on_each_cpu(cpu_pmu_enable_percpu_irq, cpu_pmu, 1);
+       } else {
+               for (i = 0; i < irqs; ++i) {
+                       err = 0;
+                       irq = platform_get_irq(pmu_device, i);
+                       if (irq < 0)
+                               continue;
+
+                       /*
+                        * If we have a single PMU interrupt that we can't shift,
+                        * assume that we're running on a uniprocessor machine and
+                        * continue. Otherwise, continue without this interrupt.
+                        */
+                       if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
+                               pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
+                                           irq, i);
+                               continue;
+                       }
+
+                       err = request_irq(irq, handler,
+                                         IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu",
+                                         cpu_pmu);
+                       if (err) {
+                               pr_err("unable to request IRQ%d for ARM PMU counters\n",
+                                       irq);
+                               return err;
+                       }
+
+                       cpumask_set_cpu(i, &cpu_pmu->active_irqs);
+               }
        }
 
        return 0;
@@ -141,6 +181,7 @@ static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
                events->events = per_cpu(hw_events, cpu);
                events->used_mask = per_cpu(used_mask, cpu);
                raw_spin_lock_init(&events->pmu_lock);
+               per_cpu(percpu_pmu, cpu) = cpu_pmu;
        }
 
        cpu_pmu->get_hw_events  = cpu_pmu_get_cpu_events;
@@ -181,6 +222,7 @@ static struct notifier_block cpu_pmu_hotplug_notifier = {
  */
 static struct of_device_id cpu_pmu_of_device_ids[] = {
        {.compatible = "arm,cortex-a15-pmu",    .data = armv7_a15_pmu_init},
+       {.compatible = "arm,cortex-a12-pmu",    .data = armv7_a12_pmu_init},
        {.compatible = "arm,cortex-a9-pmu",     .data = armv7_a9_pmu_init},
        {.compatible = "arm,cortex-a8-pmu",     .data = armv7_a8_pmu_init},
        {.compatible = "arm,cortex-a7-pmu",     .data = armv7_a7_pmu_init},
@@ -188,6 +230,7 @@ static struct of_device_id cpu_pmu_of_device_ids[] = {
        {.compatible = "arm,arm11mpcore-pmu",   .data = armv6mpcore_pmu_init},
        {.compatible = "arm,arm1176-pmu",       .data = armv6pmu_init},
        {.compatible = "arm,arm1136-pmu",       .data = armv6pmu_init},
+       {.compatible = "qcom,krait-pmu",        .data = krait_pmu_init},
        {},
 };
 
@@ -225,15 +268,6 @@ static int probe_current_pmu(struct arm_pmu *pmu)
                case ARM_CPU_PART_CORTEX_A9:
                        ret = armv7_a9_pmu_init(pmu);
                        break;
-               case ARM_CPU_PART_CORTEX_A5:
-                       ret = armv7_a5_pmu_init(pmu);
-                       break;
-               case ARM_CPU_PART_CORTEX_A15:
-                       ret = armv7_a15_pmu_init(pmu);
-                       break;
-               case ARM_CPU_PART_CORTEX_A7:
-                       ret = armv7_a7_pmu_init(pmu);
-                       break;
                }
        /* Intel CPUs [xscale]. */
        } else if (implementor == ARM_CPU_IMP_INTEL) {
@@ -270,6 +304,9 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       cpu_pmu = pmu;
+       cpu_pmu->plat_device = pdev;
+
        if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
                init_fn = of_id->data;
                ret = init_fn(pmu);
@@ -282,8 +319,6 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
                goto out_free;
        }
 
-       cpu_pmu = pmu;
-       cpu_pmu->plat_device = pdev;
        cpu_pmu_init(cpu_pmu);
        ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW);
 
index 039cffb053a7ec017a552013fc6eff5c17ca1d50..f4ef3981ed0293a6ebcc887cf3428e8c848294ca 100644 (file)
 
 #ifdef CONFIG_CPU_V7
 
+#include <asm/cp15.h>
+#include <asm/vfp.h>
+#include "../vfp/vfpinstr.h"
+
 /*
  * Common ARMv7 event types
  *
@@ -109,6 +113,33 @@ enum armv7_a15_perf_types {
        ARMV7_A15_PERFCTR_PC_WRITE_SPEC                 = 0x76,
 };
 
+/* ARMv7 Cortex-A12 specific event types */
+enum armv7_a12_perf_types {
+       ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ         = 0x40,
+       ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE        = 0x41,
+
+       ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ          = 0x50,
+       ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE         = 0x51,
+
+       ARMV7_A12_PERFCTR_PC_WRITE_SPEC                 = 0x76,
+
+       ARMV7_A12_PERFCTR_PF_TLB_REFILL                 = 0xe7,
+};
+
+/* ARMv7 Krait specific event types */
+enum krait_perf_types {
+       KRAIT_PMRESR0_GROUP0                            = 0xcc,
+       KRAIT_PMRESR1_GROUP0                            = 0xd0,
+       KRAIT_PMRESR2_GROUP0                            = 0xd4,
+       KRAIT_VPMRESR0_GROUP0                           = 0xd8,
+
+       KRAIT_PERFCTR_L1_ICACHE_ACCESS                  = 0x10011,
+       KRAIT_PERFCTR_L1_ICACHE_MISS                    = 0x10010,
+
+       KRAIT_PERFCTR_L1_ITLB_ACCESS                    = 0x12222,
+       KRAIT_PERFCTR_L1_DTLB_ACCESS                    = 0x12210,
+};
+
 /*
  * Cortex-A8 HW events mapping
  *
@@ -731,6 +762,262 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
 };
 
+/*
+ * Cortex-A12 HW events mapping
+ */
+static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]              = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+       [PERF_COUNT_HW_CACHE_MISSES]            = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]              = ARMV7_PERFCTR_BUS_CYCLES,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                       [PERF_COUNT_HW_CACHE_OP_MAX]
+                                       [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               /*
+                * Not all performance counters differentiate between read
+                * and write accesses/misses so we're not always strictly
+                * correct, but it's the best we can do. Writes and reads get
+                * combined in these cases.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_ICACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L2_CACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L2_CACHE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(NODE)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+/*
+ * Krait HW events mapping
+ */
+static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                         [PERF_COUNT_HW_CACHE_OP_MAX]
+                                         [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               /*
+                * The performance counters don't differentiate between read
+                * and write accesses/misses so this isn't strictly correct,
+                * but it's the best we can do. Writes and reads get
+                * combined.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_DCACHE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = KRAIT_PERFCTR_L1_ICACHE_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = KRAIT_PERFCTR_L1_DTLB_ACCESS,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = KRAIT_PERFCTR_L1_DTLB_ACCESS,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = KRAIT_PERFCTR_L1_ITLB_ACCESS,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = KRAIT_PERFCTR_L1_ITLB_ACCESS,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(NODE)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
 /*
  * Perf Events' indices
  */
@@ -1212,6 +1499,24 @@ static int armv7_a7_map_event(struct perf_event *event)
                                &armv7_a7_perf_cache_map, 0xFF);
 }
 
+static int armv7_a12_map_event(struct perf_event *event)
+{
+       return armpmu_map_event(event, &armv7_a12_perf_map,
+                               &armv7_a12_perf_cache_map, 0xFF);
+}
+
+static int krait_map_event(struct perf_event *event)
+{
+       return armpmu_map_event(event, &krait_perf_map,
+                               &krait_perf_cache_map, 0xFFFFF);
+}
+
+static int krait_map_event_no_branch(struct perf_event *event)
+{
+       return armpmu_map_event(event, &krait_perf_map_no_branch,
+                               &krait_perf_cache_map, 0xFFFFF);
+}
+
 static void armv7pmu_init(struct arm_pmu *cpu_pmu)
 {
        cpu_pmu->handle_irq     = armv7pmu_handle_irq;
@@ -1283,6 +1588,408 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
        cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
        return 0;
 }
+
+static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
+{
+       armv7pmu_init(cpu_pmu);
+       cpu_pmu->name           = "ARMv7 Cortex-A12";
+       cpu_pmu->map_event      = armv7_a12_map_event;
+       cpu_pmu->num_events     = armv7_read_num_pmnc_events();
+       cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+       return 0;
+}
+
+/*
+ * Krait Performance Monitor Region Event Selection Register (PMRESRn)
+ *
+ *            31   30     24     16     8      0
+ *            +--------------------------------+
+ *  PMRESR0   | EN |  CC  |  CC  |  CC  |  CC  |   N = 1, R = 0
+ *            +--------------------------------+
+ *  PMRESR1   | EN |  CC  |  CC  |  CC  |  CC  |   N = 1, R = 1
+ *            +--------------------------------+
+ *  PMRESR2   | EN |  CC  |  CC  |  CC  |  CC  |   N = 1, R = 2
+ *            +--------------------------------+
+ *  VPMRESR0  | EN |  CC  |  CC  |  CC  |  CC  |   N = 2, R = ?
+ *            +--------------------------------+
+ *              EN | G=3  | G=2  | G=1  | G=0
+ *
+ *  Event Encoding:
+ *
+ *      hwc->config_base = 0xNRCCG
+ *
+ *      N  = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
+ *      R  = region register
+ *      CC = class of events the group G is choosing from
+ *      G  = group or particular event
+ *
+ *  Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
+ *
+ *  A region (R) corresponds to a piece of the CPU (execution unit, instruction
+ *  unit, etc.) while the event code (CC) corresponds to a particular class of
+ *  events (interrupts for example). An event code is broken down into
+ *  groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
+ *  example).
+ */
+
+#define KRAIT_EVENT            (1 << 16)
+#define VENUM_EVENT            (2 << 16)
+#define KRAIT_EVENT_MASK       (KRAIT_EVENT | VENUM_EVENT)
+#define PMRESRn_EN             BIT(31)
+
+static u32 krait_read_pmresrn(int n)
+{
+       u32 val;
+
+       switch (n) {
+       case 0:
+               asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
+               break;
+       case 1:
+               asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
+               break;
+       case 2:
+               asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
+               break;
+       default:
+               BUG(); /* Should be validated in krait_pmu_get_event_idx() */
+       }
+
+       return val;
+}
+
+static void krait_write_pmresrn(int n, u32 val)
+{
+       switch (n) {
+       case 0:
+               asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
+               break;
+       case 1:
+               asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
+               break;
+       case 2:
+               asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
+               break;
+       default:
+               BUG(); /* Should be validated in krait_pmu_get_event_idx() */
+       }
+}
+
+static u32 krait_read_vpmresr0(void)
+{
+       u32 val;
+       asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
+       return val;
+}
+
+static void krait_write_vpmresr0(u32 val)
+{
+       asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
+}
+
+static void krait_pre_vpmresr0(u32 *venum_orig_val, u32 *fp_orig_val)
+{
+       u32 venum_new_val;
+       u32 fp_new_val;
+
+       BUG_ON(preemptible());
+       /* CPACR Enable CP10 and CP11 access */
+       *venum_orig_val = get_copro_access();
+       venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
+       set_copro_access(venum_new_val);
+
+       /* Enable FPEXC */
+       *fp_orig_val = fmrx(FPEXC);
+       fp_new_val = *fp_orig_val | FPEXC_EN;
+       fmxr(FPEXC, fp_new_val);
+}
+
+static void krait_post_vpmresr0(u32 venum_orig_val, u32 fp_orig_val)
+{
+       BUG_ON(preemptible());
+       /* Restore FPEXC */
+       fmxr(FPEXC, fp_orig_val);
+       isb();
+       /* Restore CPACR */
+       set_copro_access(venum_orig_val);
+}
+
+static u32 krait_get_pmresrn_event(unsigned int region)
+{
+       static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
+                                            KRAIT_PMRESR1_GROUP0,
+                                            KRAIT_PMRESR2_GROUP0 };
+       return pmresrn_table[region];
+}
+
+static void krait_evt_setup(int idx, u32 config_base)
+{
+       u32 val;
+       u32 mask;
+       u32 vval, fval;
+       unsigned int region;
+       unsigned int group;
+       unsigned int code;
+       unsigned int group_shift;
+       bool venum_event;
+
+       venum_event = !!(config_base & VENUM_EVENT);
+       region = (config_base >> 12) & 0xf;
+       code   = (config_base >> 4) & 0xff;
+       group  = (config_base >> 0)  & 0xf;
+
+       group_shift = group * 8;
+       mask = 0xff << group_shift;
+
+       /* Configure evtsel for the region and group */
+       if (venum_event)
+               val = KRAIT_VPMRESR0_GROUP0;
+       else
+               val = krait_get_pmresrn_event(region);
+       val += group;
+       /* Mix in mode-exclusion bits */
+       val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
+       armv7_pmnc_write_evtsel(idx, val);
+
+       asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
+
+       if (venum_event) {
+               krait_pre_vpmresr0(&vval, &fval);
+               val = krait_read_vpmresr0();
+               val &= ~mask;
+               val |= code << group_shift;
+               val |= PMRESRn_EN;
+               krait_write_vpmresr0(val);
+               krait_post_vpmresr0(vval, fval);
+       } else {
+               val = krait_read_pmresrn(region);
+               val &= ~mask;
+               val |= code << group_shift;
+               val |= PMRESRn_EN;
+               krait_write_pmresrn(region, val);
+       }
+}
+
+static u32 krait_clear_pmresrn_group(u32 val, int group)
+{
+       u32 mask;
+       int group_shift;
+
+       group_shift = group * 8;
+       mask = 0xff << group_shift;
+       val &= ~mask;
+
+       /* Don't clear enable bit if entire region isn't disabled */
+       if (val & ~PMRESRn_EN)
+               return val |= PMRESRn_EN;
+
+       return 0;
+}
+
+static void krait_clearpmu(u32 config_base)
+{
+       u32 val;
+       u32 vval, fval;
+       unsigned int region;
+       unsigned int group;
+       bool venum_event;
+
+       venum_event = !!(config_base & VENUM_EVENT);
+       region = (config_base >> 12) & 0xf;
+       group  = (config_base >> 0)  & 0xf;
+
+       if (venum_event) {
+               krait_pre_vpmresr0(&vval, &fval);
+               val = krait_read_vpmresr0();
+               val = krait_clear_pmresrn_group(val, group);
+               krait_write_vpmresr0(val);
+               krait_post_vpmresr0(vval, fval);
+       } else {
+               val = krait_read_pmresrn(region);
+               val = krait_clear_pmresrn_group(val, group);
+               krait_write_pmresrn(region, val);
+       }
+}
+
+static void krait_pmu_disable_event(struct perf_event *event)
+{
+       unsigned long flags;
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+       struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+
+       /* Disable counter and interrupt */
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+       /* Disable counter */
+       armv7_pmnc_disable_counter(idx);
+
+       /*
+        * Clear pmresr code (if destined for PMNx counters)
+        */
+       if (hwc->config_base & KRAIT_EVENT_MASK)
+               krait_clearpmu(hwc->config_base);
+
+       /* Disable interrupt for this counter */
+       armv7_pmnc_disable_intens(idx);
+
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void krait_pmu_enable_event(struct perf_event *event)
+{
+       unsigned long flags;
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+       struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+
+       /*
+        * Enable counter and interrupt, and set the counter to count
+        * the event that we're interested in.
+        */
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
+
+       /* Disable counter */
+       armv7_pmnc_disable_counter(idx);
+
+       /*
+        * Set event (if destined for PMNx counters)
+        * We set the event for the cycle counter because we
+        * have the ability to perform event filtering.
+        */
+       if (hwc->config_base & KRAIT_EVENT_MASK)
+               krait_evt_setup(idx, hwc->config_base);
+       else
+               armv7_pmnc_write_evtsel(idx, hwc->config_base);
+
+       /* Enable interrupt for this counter */
+       armv7_pmnc_enable_intens(idx);
+
+       /* Enable counter */
+       armv7_pmnc_enable_counter(idx);
+
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
+}
+
+static void krait_pmu_reset(void *info)
+{
+       u32 vval, fval;
+
+       armv7pmu_reset(info);
+
+       /* Clear all pmresrs */
+       krait_write_pmresrn(0, 0);
+       krait_write_pmresrn(1, 0);
+       krait_write_pmresrn(2, 0);
+
+       krait_pre_vpmresr0(&vval, &fval);
+       krait_write_vpmresr0(0);
+       krait_post_vpmresr0(vval, fval);
+}
+
+static int krait_event_to_bit(struct perf_event *event, unsigned int region,
+                             unsigned int group)
+{
+       int bit;
+       struct hw_perf_event *hwc = &event->hw;
+       struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+
+       if (hwc->config_base & VENUM_EVENT)
+               bit = KRAIT_VPMRESR0_GROUP0;
+       else
+               bit = krait_get_pmresrn_event(region);
+       bit -= krait_get_pmresrn_event(0);
+       bit += group;
+       /*
+        * Lower bits are reserved for use by the counters (see
+        * armv7pmu_get_event_idx() for more info)
+        */
+       bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
+
+       return bit;
+}
+
+/*
+ * We check for column exclusion constraints here.
+ * Two events cant use the same group within a pmresr register.
+ */
+static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+                                  struct perf_event *event)
+{
+       int idx;
+       int bit;
+       unsigned int prefix;
+       unsigned int region;
+       unsigned int code;
+       unsigned int group;
+       bool krait_event;
+       struct hw_perf_event *hwc = &event->hw;
+
+       region = (hwc->config_base >> 12) & 0xf;
+       code   = (hwc->config_base >> 4) & 0xff;
+       group  = (hwc->config_base >> 0) & 0xf;
+       krait_event = !!(hwc->config_base & KRAIT_EVENT_MASK);
+
+       if (krait_event) {
+               /* Ignore invalid events */
+               if (group > 3 || region > 2)
+                       return -EINVAL;
+               prefix = hwc->config_base & KRAIT_EVENT_MASK;
+               if (prefix != KRAIT_EVENT && prefix != VENUM_EVENT)
+                       return -EINVAL;
+               if (prefix == VENUM_EVENT && (code & 0xe0))
+                       return -EINVAL;
+
+               bit = krait_event_to_bit(event, region, group);
+               if (test_and_set_bit(bit, cpuc->used_mask))
+                       return -EAGAIN;
+       }
+
+       idx = armv7pmu_get_event_idx(cpuc, event);
+       if (idx < 0 && krait_event)
+               clear_bit(bit, cpuc->used_mask);
+
+       return idx;
+}
+
+static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
+                                     struct perf_event *event)
+{
+       int bit;
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned int region;
+       unsigned int group;
+       bool krait_event;
+
+       region = (hwc->config_base >> 12) & 0xf;
+       group  = (hwc->config_base >> 0) & 0xf;
+       krait_event = !!(hwc->config_base & KRAIT_EVENT_MASK);
+
+       if (krait_event) {
+               bit = krait_event_to_bit(event, region, group);
+               clear_bit(bit, cpuc->used_mask);
+       }
+}
+
+static int krait_pmu_init(struct arm_pmu *cpu_pmu)
+{
+       armv7pmu_init(cpu_pmu);
+       cpu_pmu->name           = "ARMv7 Krait";
+       /* Some early versions of Krait don't support PC write events */
+       if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
+                                 "qcom,no-pc-write"))
+               cpu_pmu->map_event = krait_map_event_no_branch;
+       else
+               cpu_pmu->map_event = krait_map_event;
+       cpu_pmu->num_events     = armv7_read_num_pmnc_events();
+       cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+       cpu_pmu->reset          = krait_pmu_reset;
+       cpu_pmu->enable         = krait_pmu_enable_event;
+       cpu_pmu->disable        = krait_pmu_disable_event;
+       cpu_pmu->get_event_idx  = krait_pmu_get_event_idx;
+       cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
+       return 0;
+}
 #else
 static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
 {
@@ -1308,4 +2015,14 @@ static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
 {
        return -ENODEV;
 }
+
+static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
+{
+       return -ENODEV;
+}
+
+static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
+{
+       return -ENODEV;
+}
 #endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/kernel/probes-arm.c
new file mode 100644 (file)
index 0000000..51a13a0
--- /dev/null
@@ -0,0 +1,734 @@
+/*
+ * arch/arm/kernel/probes-arm.c
+ *
+ * Some code moved here from arch/arm/kernel/kprobes-arm.c
+ *
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/ptrace.h>
+
+#include "probes.h"
+#include "probes-arm.h"
+
+#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
+
+#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
+
+/*
+ * To avoid the complications of mimicing single-stepping on a
+ * processor without a Next-PC or a single-step mode, and to
+ * avoid having to deal with the side-effects of boosting, we
+ * simulate or emulate (almost) all ARM instructions.
+ *
+ * "Simulation" is where the instruction's behavior is duplicated in
+ * C code.  "Emulation" is where the original instruction is rewritten
+ * and executed, often by altering its registers.
+ *
+ * By having all behavior of the kprobe'd instruction completed before
+ * returning from the kprobe_handler(), all locks (scheduler and
+ * interrupt) can safely be released.  There is no need for secondary
+ * breakpoints, no race with MP or preemptable kernels, nor having to
+ * clean up resources counts at a later time impacting overall system
+ * performance.  By rewriting the instruction, only the minimum registers
+ * need to be loaded and saved back optimizing performance.
+ *
+ * Calling the insnslot_*_rwflags version of a function doesn't hurt
+ * anything even when the CPSR flags aren't updated by the
+ * instruction.  It's just a little slower in return for saving
+ * a little space by not having a duplicate function that doesn't
+ * update the flags.  (The same optimization can be said for
+ * instructions that do or don't perform register writeback)
+ * Also, instructions can either read the flags, only write the
+ * flags, or read and write the flags.  To save combinations
+ * rather than for sheer performance, flag functions just assume
+ * read and write of flags.
+ */
+
+void __kprobes simulate_bbl(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+       long iaddr = (long) regs->ARM_pc - 4;
+       int disp  = branch_displacement(insn);
+
+       if (insn & (1 << 24))
+               regs->ARM_lr = iaddr + 4;
+
+       regs->ARM_pc = iaddr + 8 + disp;
+}
+
+void __kprobes simulate_blx1(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+       long iaddr = (long) regs->ARM_pc - 4;
+       int disp = branch_displacement(insn);
+
+       regs->ARM_lr = iaddr + 4;
+       regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
+       regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+void __kprobes simulate_blx2bx(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+       int rm = insn & 0xf;
+       long rmv = regs->uregs[rm];
+
+       if (insn & (1 << 5))
+               regs->ARM_lr = (long) regs->ARM_pc;
+
+       regs->ARM_pc = rmv & ~0x1;
+       regs->ARM_cpsr &= ~PSR_T_BIT;
+       if (rmv & 0x1)
+               regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+void __kprobes simulate_mrs(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+       int rd = (insn >> 12) & 0xf;
+       unsigned long mask = 0xf8ff03df; /* Mask out execution state */
+       regs->uregs[rd] = regs->ARM_cpsr & mask;
+}
+
+void __kprobes simulate_mov_ipsp(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+       regs->uregs[12] = regs->uregs[13];
+}
+
+/*
+ * For the instruction masking and comparisons in all the "space_*"
+ * functions below, Do _not_ rearrange the order of tests unless
+ * you're very, very sure of what you are doing.  For the sake of
+ * efficiency, the masks for some tests sometimes assume other test
+ * have been done prior to them so the number of patterns to test
+ * for an instruction set can be as broad as possible to reduce the
+ * number of tests needed.
+ */
+
+static const union decode_item arm_1111_table[] = {
+       /* Unconditional instructions                                   */
+
+       /* memory hint          1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
+       /* PLDI (immediate)     1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
+       /* PLDW (immediate)     1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
+       /* PLD (immediate)      1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_SIMULATE (0xfe300000, 0xf4100000, PROBES_PRELOAD_IMM),
+
+       /* memory hint          1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
+       /* PLDI (register)      1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
+       /* PLDW (register)      1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
+       /* PLD (register)       1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
+       DECODE_SIMULATE (0xfe300010, 0xf6100000, PROBES_PRELOAD_REG),
+
+       /* BLX (immediate)      1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
+       DECODE_SIMULATE (0xfe000000, 0xfa000000, PROBES_BRANCH_IMM),
+
+       /* CPS                  1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
+       /* SETEND               1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
+       /* SRS                  1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+       /* RFE                  1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+
+       /* Coprocessor instructions... */
+       /* MCRR2                1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */
+       /* MRRC2                1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
+       /* LDC2                 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+       /* STC2                 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+       /* CDP2                 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+       /* MCR2                 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+       /* MRC2                 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+
+       /* Other unallocated instructions...                            */
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
+       /* Miscellaneous instructions                                   */
+
+       /* MRS cpsr             cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
+       DECODE_SIMULATEX(0x0ff000f0, 0x01000000, PROBES_MRS,
+                                                REGS(0, NOPC, 0, 0, 0)),
+
+       /* BX                   cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
+       DECODE_SIMULATE (0x0ff000f0, 0x01200010, PROBES_BRANCH_REG),
+
+       /* BLX (register)       cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
+       DECODE_SIMULATEX(0x0ff000f0, 0x01200030, PROBES_BRANCH_REG,
+                                                REGS(0, 0, 0, 0, NOPC)),
+
+       /* CLZ                  cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
+       DECODE_EMULATEX (0x0ff000f0, 0x01600010, PROBES_CLZ,
+                                                REGS(0, NOPC, 0, 0, NOPC)),
+
+       /* QADD                 cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
+       /* QSUB                 cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
+       /* QDADD                cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
+       /* QDSUB                cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
+       DECODE_EMULATEX (0x0f9000f0, 0x01000050, PROBES_SATURATING_ARITHMETIC,
+                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+       /* BXJ                  cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
+       /* MSR                  cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
+       /* MRS spsr             cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
+       /* BKPT                 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+       /* SMC                  cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
+       /* And unallocated instructions...                              */
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
+       /* Halfword multiply and multiply-accumulate                    */
+
+       /* SMLALxy              cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
+       DECODE_EMULATEX (0x0ff00090, 0x01400080, PROBES_MUL1,
+                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+       /* SMULWy               cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
+       DECODE_OR       (0x0ff000b0, 0x012000a0),
+       /* SMULxy               cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
+       DECODE_EMULATEX (0x0ff00090, 0x01600080, PROBES_MUL2,
+                                                REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+       /* SMLAxy               cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
+       DECODE_OR       (0x0ff00090, 0x01000080),
+       /* SMLAWy               cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
+       DECODE_EMULATEX (0x0ff000b0, 0x01200080, PROBES_MUL2,
+                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_0000_____1001_table[] = {
+       /* Multiply and multiply-accumulate                             */
+
+       /* MUL                  cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
+       /* MULS                 cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
+       DECODE_EMULATEX (0x0fe000f0, 0x00000090, PROBES_MUL2,
+                                                REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+       /* MLA                  cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
+       /* MLAS                 cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
+       DECODE_OR       (0x0fe000f0, 0x00200090),
+       /* MLS                  cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
+       DECODE_EMULATEX (0x0ff000f0, 0x00600090, PROBES_MUL2,
+                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+       /* UMAAL                cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
+       DECODE_OR       (0x0ff000f0, 0x00400090),
+       /* UMULL                cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
+       /* UMULLS               cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
+       /* UMLAL                cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
+       /* UMLALS               cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
+       /* SMULL                cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
+       /* SMULLS               cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
+       /* SMLAL                cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
+       /* SMLALS               cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
+       DECODE_EMULATEX (0x0f8000f0, 0x00800090, PROBES_MUL1,
+                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_0001_____1001_table[] = {
+       /* Synchronization primitives                                   */
+
+#if __LINUX_ARM_ARCH__ < 6
+       /* Deprecated on ARMv6 and may be UNDEFINED on v7               */
+       /* SMP/SWPB             cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
+       DECODE_EMULATEX (0x0fb000f0, 0x01000090, PROBES_SWP,
+                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
+#endif
+       /* LDREX/STREX{,D,B,H}  cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
+       /* And unallocated instructions...                              */
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_000x_____1xx1_table[] = {
+       /* Extra load/store instructions                                */
+
+       /* STRHT                cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
+       /* ???                  cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
+       /* LDRHT                cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
+       /* LDRSBT               cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
+       /* LDRSHT               cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_REJECT   (0x0f200090, 0x00200090),
+
+       /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
+       DECODE_REJECT   (0x0e10e0d0, 0x0000e0d0),
+
+       /* LDRD (register)      cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
+       /* STRD (register)      cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_EMULATEX (0x0e5000d0, 0x000000d0, PROBES_LDRSTRD,
+                                                REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
+
+       /* LDRD (immediate)     cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
+       /* STRD (immediate)     cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_EMULATEX (0x0e5000d0, 0x004000d0, PROBES_LDRSTRD,
+                                                REGS(NOPCWB, NOPCX, 0, 0, 0)),
+
+       /* STRH (register)      cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
+       DECODE_EMULATEX (0x0e5000f0, 0x000000b0, PROBES_STORE_EXTRA,
+                                                REGS(NOPCWB, NOPC, 0, 0, NOPC)),
+
+       /* LDRH (register)      cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
+       /* LDRSB (register)     cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
+       /* LDRSH (register)     cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_EMULATEX (0x0e500090, 0x00100090, PROBES_LOAD_EXTRA,
+                                                REGS(NOPCWB, NOPC, 0, 0, NOPC)),
+
+       /* STRH (immediate)     cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
+       DECODE_EMULATEX (0x0e5000f0, 0x004000b0, PROBES_STORE_EXTRA,
+                                                REGS(NOPCWB, NOPC, 0, 0, 0)),
+
+       /* LDRH (immediate)     cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
+       /* LDRSB (immediate)    cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
+       /* LDRSH (immediate)    cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_EMULATEX (0x0e500090, 0x00500090, PROBES_LOAD_EXTRA,
+                                                REGS(NOPCWB, NOPC, 0, 0, 0)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_000x_table[] = {
+       /* Data-processing (register)                                   */
+
+       /* <op>S PC, ...        cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
+       DECODE_REJECT   (0x0e10f000, 0x0010f000),
+
+       /* MOV IP, SP           1110 0001 1010 0000 1100 0000 0000 1101 */
+       DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, PROBES_MOV_IP_SP),
+
+       /* TST (register)       cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
+       /* TEQ (register)       cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
+       /* CMP (register)       cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
+       /* CMN (register)       cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
+       DECODE_EMULATEX (0x0f900010, 0x01100000, PROBES_DATA_PROCESSING_REG,
+                                                REGS(ANY, 0, 0, 0, ANY)),
+
+       /* MOV (register)       cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
+       /* MVN (register)       cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
+       DECODE_EMULATEX (0x0fa00010, 0x01a00000, PROBES_DATA_PROCESSING_REG,
+                                                REGS(0, ANY, 0, 0, ANY)),
+
+       /* AND (register)       cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
+       /* EOR (register)       cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
+       /* SUB (register)       cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
+       /* RSB (register)       cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
+       /* ADD (register)       cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
+       /* ADC (register)       cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
+       /* SBC (register)       cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
+       /* RSC (register)       cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
+       /* ORR (register)       cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
+       /* BIC (register)       cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
+       DECODE_EMULATEX (0x0e000010, 0x00000000, PROBES_DATA_PROCESSING_REG,
+                                                REGS(ANY, ANY, 0, 0, ANY)),
+
+       /* TST (reg-shift reg)  cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
+       /* TEQ (reg-shift reg)  cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
+       /* CMP (reg-shift reg)  cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
+       /* CMN (reg-shift reg)  cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
+       DECODE_EMULATEX (0x0f900090, 0x01100010, PROBES_DATA_PROCESSING_REG,
+                                                REGS(ANY, 0, NOPC, 0, ANY)),
+
+       /* MOV (reg-shift reg)  cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
+       /* MVN (reg-shift reg)  cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
+       DECODE_EMULATEX (0x0fa00090, 0x01a00010, PROBES_DATA_PROCESSING_REG,
+                                                REGS(0, ANY, NOPC, 0, ANY)),
+
+       /* AND (reg-shift reg)  cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
+       /* EOR (reg-shift reg)  cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
+       /* SUB (reg-shift reg)  cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
+       /* RSB (reg-shift reg)  cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
+       /* ADD (reg-shift reg)  cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
+       /* ADC (reg-shift reg)  cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
+       /* SBC (reg-shift reg)  cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
+       /* RSC (reg-shift reg)  cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
+       /* ORR (reg-shift reg)  cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
+       /* BIC (reg-shift reg)  cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
+       DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
+                                                REGS(ANY, ANY, NOPC, 0, ANY)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_001x_table[] = {
+       /* Data-processing (immediate)                                  */
+
+       /* MOVW                 cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
+       /* MOVT                 cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM,
+                                                REGS(0, NOPC, 0, 0, 0)),
+
+       /* YIELD                cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
+       DECODE_OR       (0x0fff00ff, 0x03200001),
+       /* SEV                  cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
+       DECODE_EMULATE  (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE),
+       /* NOP                  cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
+       /* WFE                  cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
+       /* WFI                  cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
+       DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP),
+       /* DBG                  cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
+       /* unallocated hints    cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
+       /* MSR (immediate)      cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0x0fb00000, 0x03200000),
+
+       /* <op>S PC, ...        cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
+       DECODE_REJECT   (0x0e10f000, 0x0210f000),
+
+       /* TST (immediate)      cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
+       /* TEQ (immediate)      cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
+       /* CMP (immediate)      cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
+       /* CMN (immediate)      cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0f900000, 0x03100000, PROBES_DATA_PROCESSING_IMM,
+                                                REGS(ANY, 0, 0, 0, 0)),
+
+       /* MOV (immediate)      cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
+       /* MVN (immediate)      cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0fa00000, 0x03a00000, PROBES_DATA_PROCESSING_IMM,
+                                                REGS(0, ANY, 0, 0, 0)),
+
+       /* AND (immediate)      cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
+       /* EOR (immediate)      cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
+       /* SUB (immediate)      cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
+       /* RSB (immediate)      cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
+       /* ADD (immediate)      cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
+       /* ADC (immediate)      cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
+       /* SBC (immediate)      cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
+       /* RSC (immediate)      cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
+       /* ORR (immediate)      cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
+       /* BIC (immediate)      cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0e000000, 0x02000000, PROBES_DATA_PROCESSING_IMM,
+                                                REGS(ANY, ANY, 0, 0, 0)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_0110_____xxx1_table[] = {
+       /* Media instructions                                           */
+
+       /* SEL                  cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
+       DECODE_EMULATEX (0x0ff000f0, 0x068000b0, PROBES_SATURATE,
+                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+       /* SSAT                 cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
+       /* USAT                 cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
+       DECODE_OR(0x0fa00030, 0x06a00010),
+       /* SSAT16               cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
+       /* USAT16               cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
+       DECODE_EMULATEX (0x0fb000f0, 0x06a00030, PROBES_SATURATE,
+                                                REGS(0, NOPC, 0, 0, NOPC)),
+
+       /* REV                  cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
+       /* REV16                cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
+       /* RBIT                 cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
+       /* REVSH                cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
+       DECODE_EMULATEX (0x0fb00070, 0x06b00030, PROBES_REV,
+                                                REGS(0, NOPC, 0, 0, NOPC)),
+
+       /* ???                  cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
+       DECODE_REJECT   (0x0fb00010, 0x06000010),
+       /* ???                  cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
+       DECODE_REJECT   (0x0f8000f0, 0x060000b0),
+       /* ???                  cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
+       DECODE_REJECT   (0x0f8000f0, 0x060000d0),
+       /* SADD16               cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
+       /* SADDSUBX             cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
+       /* SSUBADDX             cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
+       /* SSUB16               cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
+       /* SADD8                cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
+       /* SSUB8                cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
+       /* QADD16               cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
+       /* QADDSUBX             cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
+       /* QSUBADDX             cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
+       /* QSUB16               cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
+       /* QADD8                cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
+       /* QSUB8                cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
+       /* SHADD16              cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
+       /* SHADDSUBX            cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
+       /* SHSUBADDX            cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
+       /* SHSUB16              cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
+       /* SHADD8               cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
+       /* SHSUB8               cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
+       /* UADD16               cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
+       /* UADDSUBX             cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
+       /* USUBADDX             cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
+       /* USUB16               cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
+       /* UADD8                cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
+       /* USUB8                cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
+       /* UQADD16              cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
+       /* UQADDSUBX            cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
+       /* UQSUBADDX            cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
+       /* UQSUB16              cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
+       /* UQADD8               cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
+       /* UQSUB8               cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
+       /* UHADD16              cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
+       /* UHADDSUBX            cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
+       /* UHSUBADDX            cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
+       /* UHSUB16              cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
+       /* UHADD8               cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
+       /* UHSUB8               cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_EMULATEX (0x0f800010, 0x06000010, PROBES_MMI,
+                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+       /* PKHBT                cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
+       /* PKHTB                cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
+       DECODE_EMULATEX (0x0ff00030, 0x06800010, PROBES_PACK,
+                                                REGS(NOPC, NOPC, 0, 0, NOPC)),
+
+       /* ???                  cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
+       /* ???                  cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
+       DECODE_REJECT   (0x0fb000f0, 0x06900070),
+
+       /* SXTB16               cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
+       /* SXTB                 cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
+       /* SXTH                 cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
+       /* UXTB16               cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
+       /* UXTB                 cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
+       /* UXTH                 cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
+       DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, PROBES_EXTEND,
+                                                REGS(0, NOPC, 0, 0, NOPC)),
+
+       /* SXTAB16              cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
+       /* SXTAB                cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
+       /* SXTAH                cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
+       /* UXTAB16              cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
+       /* UXTAB                cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
+       /* UXTAH                cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
+       DECODE_EMULATEX (0x0f8000f0, 0x06800070, PROBES_EXTEND_ADD,
+                                                REGS(NOPCX, NOPC, 0, 0, NOPC)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_0111_____xxx1_table[] = {
+       /* Media instructions                                           */
+
+       /* UNDEFINED            cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
+       DECODE_REJECT   (0x0ff000f0, 0x07f000f0),
+
+       /* SMLALD               cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
+       /* SMLSLD               cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
+       DECODE_EMULATEX (0x0ff00090, 0x07400010, PROBES_MUL_ADD_LONG,
+                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+       /* SMUAD                cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
+       /* SMUSD                cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
+       DECODE_OR       (0x0ff0f090, 0x0700f010),
+       /* SMMUL                cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
+       DECODE_OR       (0x0ff0f0d0, 0x0750f010),
+       /* USAD8                cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
+       DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, PROBES_MUL_ADD,
+                                                REGS(NOPC, 0, NOPC, 0, NOPC)),
+
+       /* SMLAD                cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
+       /* SMLSD                cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
+       DECODE_OR       (0x0ff00090, 0x07000010),
+       /* SMMLA                cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
+       DECODE_OR       (0x0ff000d0, 0x07500010),
+       /* USADA8               cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
+       DECODE_EMULATEX (0x0ff000f0, 0x07800010, PROBES_MUL_ADD,
+                                                REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
+
+       /* SMMLS                cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
+       DECODE_EMULATEX (0x0ff000d0, 0x075000d0, PROBES_MUL_ADD,
+                                                REGS(NOPC, NOPC, NOPC, 0, NOPC)),
+
+       /* SBFX                 cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
+       /* UBFX                 cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
+       DECODE_EMULATEX (0x0fa00070, 0x07a00050, PROBES_BITFIELD,
+                                                REGS(0, NOPC, 0, 0, NOPC)),
+
+       /* BFC                  cccc 0111 110x xxxx xxxx xxxx x001 1111 */
+       DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, PROBES_BITFIELD,
+                                                REGS(0, NOPC, 0, 0, 0)),
+
+       /* BFI                  cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
+       DECODE_EMULATEX (0x0fe00070, 0x07c00010, PROBES_BITFIELD,
+                                                REGS(0, NOPC, 0, 0, NOPCX)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_01xx_table[] = {
+       /* Load/store word and unsigned byte                            */
+
+       /* LDRB/STRB pc,[...]   cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0x0c40f000, 0x0440f000),
+
+       /* STRT                 cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRT                 cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
+       /* STRBT                cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRBT                cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0x0d200000, 0x04200000),
+
+       /* STR (immediate)      cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
+       /* STRB (immediate)     cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0e100000, 0x04000000, PROBES_STORE,
+                                                REGS(NOPCWB, ANY, 0, 0, 0)),
+
+       /* LDR (immediate)      cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRB (immediate)     cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0e100000, 0x04100000, PROBES_LOAD,
+                                                REGS(NOPCWB, ANY, 0, 0, 0)),
+
+       /* STR (register)       cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
+       /* STRB (register)      cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0e100000, 0x06000000, PROBES_STORE,
+                                                REGS(NOPCWB, ANY, 0, 0, NOPC)),
+
+       /* LDR (register)       cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRB (register)      cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0x0e100000, 0x06100000, PROBES_LOAD,
+                                                REGS(NOPCWB, ANY, 0, 0, NOPC)),
+
+       DECODE_END
+};
+
+static const union decode_item arm_cccc_100x_table[] = {
+       /* Block data transfer instructions                             */
+
+       /* LDM                  cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+       /* STM                  cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_CUSTOM   (0x0e400000, 0x08000000, PROBES_LDMSTM),
+
+       /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+       /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
+       /* LDM (exception ret)  cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
+       DECODE_END
+};
+
+const union decode_item probes_decode_arm_table[] = {
+       /*
+        * Unconditional instructions
+        *                      1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xf0000000, 0xf0000000, arm_1111_table),
+
+       /*
+        * Miscellaneous instructions
+        *                      cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
+        */
+       DECODE_TABLE    (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
+
+       /*
+        * Halfword multiply and multiply-accumulate
+        *                      cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
+        */
+       DECODE_TABLE    (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
+
+       /*
+        * Multiply and multiply-accumulate
+        *                      cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
+        */
+       DECODE_TABLE    (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
+
+       /*
+        * Synchronization primitives
+        *                      cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
+        */
+       DECODE_TABLE    (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
+
+       /*
+        * Extra load/store instructions
+        *                      cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
+        */
+       DECODE_TABLE    (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
+
+       /*
+        * Data-processing (register)
+        *                      cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
+        * Data-processing (register-shifted register)
+        *                      cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
+        */
+       DECODE_TABLE    (0x0e000000, 0x00000000, arm_cccc_000x_table),
+
+       /*
+        * Data-processing (immediate)
+        *                      cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0x0e000000, 0x02000000, arm_cccc_001x_table),
+
+       /*
+        * Media instructions
+        *                      cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
+        */
+       DECODE_TABLE    (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
+       DECODE_TABLE    (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
+
+       /*
+        * Load/store word and unsigned byte
+        *                      cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0x0c000000, 0x04000000, arm_cccc_01xx_table),
+
+       /*
+        * Block data transfer instructions
+        *                      cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0x0e000000, 0x08000000, arm_cccc_100x_table),
+
+       /* B                    cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
+       /* BL                   cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
+       DECODE_SIMULATE (0x0e000000, 0x0a000000, PROBES_BRANCH),
+
+       /*
+        * Supervisor Call, and coprocessor instructions
+        */
+
+       /* MCRR                 cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
+       /* MRRC                 cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
+       /* LDC                  cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+       /* STC                  cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+       /* CDP                  cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+       /* MCR                  cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+       /* MRC                  cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+       /* SVC                  cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0x0c000000, 0x0c000000),
+
+       DECODE_END
+};
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(probes_decode_arm_table);
+#endif
+
+static void __kprobes arm_singlestep(probes_opcode_t insn,
+               struct arch_probes_insn *asi, struct pt_regs *regs)
+{
+       regs->ARM_pc += 4;
+       asi->insn_handler(insn, asi, regs);
+}
+
+/* Return:
+ *   INSN_REJECTED     If instruction is one not allowed to kprobe,
+ *   INSN_GOOD         If instruction is supported and uses instruction slot,
+ *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
+ *
+ * For instructions we don't want to kprobe (INSN_REJECTED return result):
+ *   These are generally ones that modify the processor state making
+ *   them "hard" to simulate such as switches processor modes or
+ *   make accesses in alternate modes.  Any of these could be simulated
+ *   if the work was put into it, but low return considering they
+ *   should also be very rare.
+ */
+enum probes_insn __kprobes
+arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+                      bool emulate, const union decode_action *actions)
+{
+       asi->insn_singlestep = arm_singlestep;
+       asi->insn_check_cc = probes_condition_checks[insn>>28];
+       return probes_decode_insn(insn, asi, probes_decode_arm_table, false,
+                                 emulate, actions);
+}
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/kernel/probes-arm.h
new file mode 100644 (file)
index 0000000..ace6572
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/kernel/probes-arm.h
+ *
+ * Copyright 2013 Linaro Ltd.
+ * Written by: David A. Long
+ *
+ * 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
+ */
+
+#ifndef _ARM_KERNEL_PROBES_ARM_H
+#define  _ARM_KERNEL_PROBES_ARM_H
+
+enum probes_arm_action {
+       PROBES_EMULATE_NONE,
+       PROBES_SIMULATE_NOP,
+       PROBES_PRELOAD_IMM,
+       PROBES_PRELOAD_REG,
+       PROBES_BRANCH_IMM,
+       PROBES_BRANCH_REG,
+       PROBES_MRS,
+       PROBES_CLZ,
+       PROBES_SATURATING_ARITHMETIC,
+       PROBES_MUL1,
+       PROBES_MUL2,
+       PROBES_SWP,
+       PROBES_LDRSTRD,
+       PROBES_LOAD,
+       PROBES_STORE,
+       PROBES_LOAD_EXTRA,
+       PROBES_STORE_EXTRA,
+       PROBES_MOV_IP_SP,
+       PROBES_DATA_PROCESSING_REG,
+       PROBES_DATA_PROCESSING_IMM,
+       PROBES_MOV_HALFWORD,
+       PROBES_SEV,
+       PROBES_WFE,
+       PROBES_SATURATE,
+       PROBES_REV,
+       PROBES_MMI,
+       PROBES_PACK,
+       PROBES_EXTEND,
+       PROBES_EXTEND_ADD,
+       PROBES_MUL_ADD_LONG,
+       PROBES_MUL_ADD,
+       PROBES_BITFIELD,
+       PROBES_BRANCH,
+       PROBES_LDMSTM,
+       NUM_PROBES_ARM_ACTIONS
+};
+
+void __kprobes simulate_bbl(probes_opcode_t opcode,
+       struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_blx1(probes_opcode_t opcode,
+       struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_blx2bx(probes_opcode_t opcode,
+       struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_mrs(probes_opcode_t opcode,
+       struct arch_probes_insn *asi, struct pt_regs *regs);
+void __kprobes simulate_mov_ipsp(probes_opcode_t opcode,
+       struct arch_probes_insn *asi, struct pt_regs *regs);
+
+extern const union decode_item probes_decode_arm_table[];
+
+enum probes_insn arm_probes_decode_insn(probes_opcode_t,
+               struct arch_probes_insn *, bool emulate,
+               const union decode_action *actions);
+
+#endif
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/kernel/probes-thumb.c
new file mode 100644 (file)
index 0000000..4131351
--- /dev/null
@@ -0,0 +1,882 @@
+/*
+ * arch/arm/kernel/probes-thumb.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "probes.h"
+#include "probes-thumb.h"
+
+
+static const union decode_item t32_table_1110_100x_x0xx[] = {
+       /* Load/store multiple instructions */
+
+       /* Rn is PC             1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfe4f0000, 0xe80f0000),
+
+       /* SRS                  1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
+       /* RFE                  1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xffc00000, 0xe8000000),
+       /* SRS                  1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
+       /* RFE                  1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xffc00000, 0xe9800000),
+
+       /* STM Rn, {...pc}      1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfe508000, 0xe8008000),
+       /* LDM Rn, {...lr,pc}   1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfe50c000, 0xe810c000),
+       /* LDM/STM Rn, {...sp}  1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfe402000, 0xe8002000),
+
+       /* STMIA                1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
+       /* LDMIA                1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
+       /* STMDB                1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
+       /* LDMDB                1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_CUSTOM   (0xfe400000, 0xe8000000, PROBES_T32_LDMSTM),
+
+       DECODE_END
+};
+
+static const union decode_item t32_table_1110_100x_x1xx[] = {
+       /* Load/store dual, load/store exclusive, table branch */
+
+       /* STRD (immediate)     1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRD (immediate)     1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_OR       (0xff600000, 0xe8600000),
+       /* STRD (immediate)     1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRD (immediate)     1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xff400000, 0xe9400000, PROBES_T32_LDRDSTRD,
+                                                REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
+
+       /* TBB                  1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
+       /* TBH                  1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
+       DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, PROBES_T32_TABLE_BRANCH,
+                                                REGS(NOSP, 0, 0, 0, NOSPPC)),
+
+       /* STREX                1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
+       /* LDREX                1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
+       /* STREXB               1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
+       /* STREXH               1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
+       /* STREXD               1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
+       /* LDREXB               1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
+       /* LDREXH               1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
+       /* LDREXD               1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
+       /* And unallocated instructions...                              */
+       DECODE_END
+};
+
+static const union decode_item t32_table_1110_101x[] = {
+       /* Data-processing (shifted register)                           */
+
+       /* TST                  1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
+       /* TEQ                  1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
+       DECODE_EMULATEX (0xff700f00, 0xea100f00, PROBES_T32_TST,
+                                                REGS(NOSPPC, 0, 0, 0, NOSPPC)),
+
+       /* CMN                  1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
+       DECODE_OR       (0xfff00f00, 0xeb100f00),
+       /* CMP                  1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
+       DECODE_EMULATEX (0xfff00f00, 0xebb00f00, PROBES_T32_TST,
+                                                REGS(NOPC, 0, 0, 0, NOSPPC)),
+
+       /* MOV                  1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
+       /* MVN                  1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xffcf0000, 0xea4f0000, PROBES_T32_MOV,
+                                                REGS(0, 0, NOSPPC, 0, NOSPPC)),
+
+       /* ???                  1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
+       /* ???                  1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xffa00000, 0xeaa00000),
+       /* ???                  1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xffe00000, 0xeb200000),
+       /* ???                  1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xffe00000, 0xeb800000),
+       /* ???                  1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xffe00000, 0xebe00000),
+
+       /* ADD/SUB SP, SP, Rm, LSL #0..3                                */
+       /*                      1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
+       DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, PROBES_T32_ADDSUB,
+                                                REGS(SP, 0, SP, 0, NOSPPC)),
+
+       /* ADD/SUB SP, SP, Rm, shift                                    */
+       /*                      1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
+       DECODE_REJECT   (0xff4f0f00, 0xeb0d0d00),
+
+       /* ADD/SUB Rd, SP, Rm, shift                                    */
+       /*                      1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, PROBES_T32_ADDSUB,
+                                                REGS(SP, 0, NOPC, 0, NOSPPC)),
+
+       /* AND                  1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
+       /* BIC                  1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
+       /* ORR                  1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
+       /* ORN                  1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
+       /* EOR                  1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
+       /* PKH                  1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
+       /* ADD                  1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
+       /* ADC                  1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
+       /* SBC                  1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
+       /* SUB                  1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
+       /* RSB                  1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfe000000, 0xea000000, PROBES_T32_LOGICAL,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
+
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_0x0x___0[] = {
+       /* Data-processing (modified immediate)                         */
+
+       /* TST                  1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
+       /* TEQ                  1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
+       DECODE_EMULATEX (0xfb708f00, 0xf0100f00, PROBES_T32_TST,
+                                                REGS(NOSPPC, 0, 0, 0, 0)),
+
+       /* CMN                  1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
+       DECODE_OR       (0xfbf08f00, 0xf1100f00),
+       /* CMP                  1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
+       DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, PROBES_T32_CMP,
+                                                REGS(NOPC, 0, 0, 0, 0)),
+
+       /* MOV                  1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
+       /* MVN                  1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, PROBES_T32_MOV,
+                                                REGS(0, 0, NOSPPC, 0, 0)),
+
+       /* ???                  1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfbe08000, 0xf0a00000),
+       /* ???                  1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
+       /* ???                  1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfbc08000, 0xf0c00000),
+       /* ???                  1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfbe08000, 0xf1200000),
+       /* ???                  1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfbe08000, 0xf1800000),
+       /* ???                  1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfbe08000, 0xf1e00000),
+
+       /* ADD Rd, SP, #imm     1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
+       /* SUB Rd, SP, #imm     1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, PROBES_T32_ADDSUB,
+                                                REGS(SP, 0, NOPC, 0, 0)),
+
+       /* AND                  1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
+       /* BIC                  1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
+       /* ORR                  1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
+       /* ORN                  1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
+       /* EOR                  1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
+       /* ADD                  1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
+       /* ADC                  1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
+       /* SBC                  1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
+       /* SUB                  1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
+       /* RSB                  1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfa008000, 0xf0000000, PROBES_T32_LOGICAL,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, 0)),
+
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_0x1x___0[] = {
+       /* Data-processing (plain binary immediate)                     */
+
+       /* ADDW Rd, PC, #imm    1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
+       DECODE_OR       (0xfbff8000, 0xf20f0000),
+       /* SUBW Rd, PC, #imm    1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfbff8000, 0xf2af0000, PROBES_T32_ADDWSUBW_PC,
+                                                REGS(PC, 0, NOSPPC, 0, 0)),
+
+       /* ADDW SP, SP, #imm    1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
+       DECODE_OR       (0xfbff8f00, 0xf20d0d00),
+       /* SUBW SP, SP, #imm    1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
+       DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, PROBES_T32_ADDWSUBW,
+                                                REGS(SP, 0, SP, 0, 0)),
+
+       /* ADDW                 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_OR       (0xfbf08000, 0xf2000000),
+       /* SUBW                 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfbf08000, 0xf2a00000, PROBES_T32_ADDWSUBW,
+                                                REGS(NOPCX, 0, NOSPPC, 0, 0)),
+
+       /* MOVW                 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
+       /* MOVT                 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfb708000, 0xf2400000, PROBES_T32_MOVW,
+                                                REGS(0, 0, NOSPPC, 0, 0)),
+
+       /* SSAT16               1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
+       /* SSAT                 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
+       /* USAT16               1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
+       /* USAT                 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfb508000, 0xf3000000, PROBES_T32_SAT,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, 0)),
+
+       /* SFBX                 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
+       /* UFBX                 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfb708000, 0xf3400000, PROBES_T32_BITFIELD,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, 0)),
+
+       /* BFC                  1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfbff8000, 0xf36f0000, PROBES_T32_BITFIELD,
+                                                REGS(0, 0, NOSPPC, 0, 0)),
+
+       /* BFI                  1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfbf08000, 0xf3600000, PROBES_T32_BITFIELD,
+                                                REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
+
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_0xxx___1[] = {
+       /* Branches and miscellaneous control                           */
+
+       /* YIELD                1111 0011 1010 xxxx 10x0 x000 0000 0001 */
+       DECODE_OR       (0xfff0d7ff, 0xf3a08001),
+       /* SEV                  1111 0011 1010 xxxx 10x0 x000 0000 0100 */
+       DECODE_EMULATE  (0xfff0d7ff, 0xf3a08004, PROBES_T32_SEV),
+       /* NOP                  1111 0011 1010 xxxx 10x0 x000 0000 0000 */
+       /* WFE                  1111 0011 1010 xxxx 10x0 x000 0000 0010 */
+       /* WFI                  1111 0011 1010 xxxx 10x0 x000 0000 0011 */
+       DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, PROBES_T32_WFE),
+
+       /* MRS Rd, CPSR         1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
+       DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, PROBES_T32_MRS,
+                                                REGS(0, 0, NOSPPC, 0, 0)),
+
+       /*
+        * Unsupported instructions
+        *                      1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
+        *
+        * MSR                  1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
+        * DBG hint             1111 0011 1010 xxxx 10x0 x000 1111 xxxx
+        * Unallocated hints    1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
+        * CPS                  1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
+        * CLREX/DSB/DMB/ISB    1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
+        * BXJ                  1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
+        * SUBS PC,LR,#<imm8>   1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
+        * MRS Rd, SPSR         1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
+        * SMC                  1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
+        * UNDEFINED            1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
+        * ???                  1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
+        */
+       DECODE_REJECT   (0xfb80d000, 0xf3808000),
+
+       /* Bcc                  1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
+       DECODE_CUSTOM   (0xf800d000, 0xf0008000, PROBES_T32_BRANCH_COND),
+
+       /* BLX                  1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
+       DECODE_OR       (0xf800d001, 0xf000c000),
+       /* B                    1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
+       /* BL                   1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
+       DECODE_SIMULATE (0xf8009000, 0xf0009000, PROBES_T32_BRANCH),
+
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
+       /* Memory hints                                                 */
+
+       /* PLD (literal)        1111 1000 x001 1111 1111 xxxx xxxx xxxx */
+       /* PLI (literal)        1111 1001 x001 1111 1111 xxxx xxxx xxxx */
+       DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, PROBES_T32_PLDI),
+
+       /* PLD{W} (immediate)   1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
+       DECODE_OR       (0xffd0f000, 0xf890f000),
+       /* PLD{W} (immediate)   1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
+       DECODE_OR       (0xffd0ff00, 0xf810fc00),
+       /* PLI (immediate)      1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
+       DECODE_OR       (0xfff0f000, 0xf990f000),
+       /* PLI (immediate)      1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
+       DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, PROBES_T32_PLDI,
+                                                REGS(NOPCX, 0, 0, 0, 0)),
+
+       /* PLD{W} (register)    1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
+       DECODE_OR       (0xffd0ffc0, 0xf810f000),
+       /* PLI (register)       1111 1001 0001 xxxx 1111 0000 00xx xxxx */
+       DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, PROBES_T32_PLDI,
+                                                REGS(NOPCX, 0, 0, 0, NOSPPC)),
+
+       /* Other unallocated instructions...                            */
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_100x[] = {
+       /* Store/Load single data item                                  */
+
+       /* ???                  1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfe600000, 0xf8600000),
+
+       /* ???                  1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xfff00000, 0xf9500000),
+
+       /* ???                  1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
+       DECODE_REJECT   (0xfe800d00, 0xf8000800),
+
+       /* STRBT                1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
+       /* STRHT                1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
+       /* STRT                 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
+       /* LDRBT                1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
+       /* LDRSBT               1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
+       /* LDRHT                1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
+       /* LDRSHT               1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
+       /* LDRT                 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
+       DECODE_REJECT   (0xfe800f00, 0xf8000e00),
+
+       /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
+       DECODE_REJECT   (0xff1f0000, 0xf80f0000),
+
+       /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
+       DECODE_REJECT   (0xff10f000, 0xf800f000),
+
+       /* LDR (literal)        1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
+       DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, PROBES_T32_LDR_LIT,
+                                                REGS(PC, ANY, 0, 0, 0)),
+
+       /* STR (immediate)      1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
+       /* LDR (immediate)      1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
+       DECODE_OR       (0xffe00800, 0xf8400800),
+       /* STR (immediate)      1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
+       /* LDR (immediate)      1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xffe00000, 0xf8c00000, PROBES_T32_LDRSTR,
+                                                REGS(NOPCX, ANY, 0, 0, 0)),
+
+       /* STR (register)       1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
+       /* LDR (register)       1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
+       DECODE_EMULATEX (0xffe00fc0, 0xf8400000, PROBES_T32_LDRSTR,
+                                                REGS(NOPCX, ANY, 0, 0, NOSPPC)),
+
+       /* LDRB (literal)       1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
+       /* LDRSB (literal)      1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
+       /* LDRH (literal)       1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
+       /* LDRSH (literal)      1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
+       DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, PROBES_T32_LDR_LIT,
+                                                REGS(PC, NOSPPCX, 0, 0, 0)),
+
+       /* STRB (immediate)     1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
+       /* STRH (immediate)     1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
+       /* LDRB (immediate)     1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
+       /* LDRSB (immediate)    1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
+       /* LDRH (immediate)     1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
+       /* LDRSH (immediate)    1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
+       DECODE_OR       (0xfec00800, 0xf8000800),
+       /* STRB (immediate)     1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
+       /* STRH (immediate)     1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRB (immediate)     1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRSB (immediate)    1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRH (immediate)     1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
+       /* LDRSH (immediate)    1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
+       DECODE_EMULATEX (0xfec00000, 0xf8800000, PROBES_T32_LDRSTR,
+                                                REGS(NOPCX, NOSPPCX, 0, 0, 0)),
+
+       /* STRB (register)      1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
+       /* STRH (register)      1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
+       /* LDRB (register)      1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
+       /* LDRSB (register)     1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
+       /* LDRH (register)      1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
+       /* LDRSH (register)     1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
+       DECODE_EMULATEX (0xfe800fc0, 0xf8000000, PROBES_T32_LDRSTR,
+                                                REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
+
+       /* Other unallocated instructions...                            */
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_1010___1111[] = {
+       /* Data-processing (register)                                   */
+
+       /* ???                  1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
+       DECODE_REJECT   (0xffe0f080, 0xfa60f080),
+
+       /* SXTH                 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
+       /* UXTH                 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
+       /* SXTB16               1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
+       /* UXTB16               1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
+       /* SXTB                 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
+       /* UXTB                 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
+       DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, PROBES_T32_SIGN_EXTEND,
+                                                REGS(0, 0, NOSPPC, 0, NOSPPC)),
+
+
+       /* ???                  1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
+       DECODE_REJECT   (0xff80f0b0, 0xfa80f030),
+       /* ???                  1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
+       DECODE_REJECT   (0xffb0f080, 0xfab0f000),
+
+       /* SADD16               1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
+       /* SASX                 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
+       /* SSAX                 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
+       /* SSUB16               1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
+       /* SADD8                1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
+       /* SSUB8                1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
+
+       /* QADD16               1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
+       /* QASX                 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
+       /* QSAX                 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
+       /* QSUB16               1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
+       /* QADD8                1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
+       /* QSUB8                1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
+
+       /* SHADD16              1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
+       /* SHASX                1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
+       /* SHSAX                1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
+       /* SHSUB16              1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
+       /* SHADD8               1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
+       /* SHSUB8               1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
+
+       /* UADD16               1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
+       /* UASX                 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
+       /* USAX                 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
+       /* USUB16               1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
+       /* UADD8                1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
+       /* USUB8                1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
+
+       /* UQADD16              1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
+       /* UQASX                1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
+       /* UQSAX                1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
+       /* UQSUB16              1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
+       /* UQADD8               1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
+       /* UQSUB8               1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
+
+       /* UHADD16              1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
+       /* UHASX                1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
+       /* UHSAX                1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
+       /* UHSUB16              1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
+       /* UHADD8               1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
+       /* UHSUB8               1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
+       DECODE_OR       (0xff80f080, 0xfa80f000),
+
+       /* SXTAH                1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
+       /* UXTAH                1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
+       /* SXTAB16              1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
+       /* UXTAB16              1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
+       /* SXTAB                1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
+       /* UXTAB                1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
+       DECODE_OR       (0xff80f080, 0xfa00f080),
+
+       /* QADD                 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
+       /* QDADD                1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
+       /* QSUB                 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
+       /* QDSUB                1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
+       DECODE_OR       (0xfff0f0c0, 0xfa80f080),
+
+       /* SEL                  1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
+       DECODE_OR       (0xfff0f0f0, 0xfaa0f080),
+
+       /* LSL                  1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
+       /* LSR                  1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
+       /* ASR                  1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
+       /* ROR                  1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
+       DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, PROBES_T32_MEDIA,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
+
+       /* CLZ                  1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
+       DECODE_OR       (0xfff0f0f0, 0xfab0f080),
+
+       /* REV                  1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
+       /* REV16                1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
+       /* RBIT                 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
+       /* REVSH                1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
+       DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, PROBES_T32_REVERSE,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
+
+       /* Other unallocated instructions...                            */
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_1011_0[] = {
+       /* Multiply, multiply accumulate, and absolute difference       */
+
+       /* ???                  1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
+       DECODE_REJECT   (0xfff0f0f0, 0xfb00f010),
+       /* ???                  1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
+       DECODE_REJECT   (0xfff0f0f0, 0xfb70f010),
+
+       /* SMULxy               1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
+       DECODE_OR       (0xfff0f0c0, 0xfb10f000),
+       /* MUL                  1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
+       /* SMUAD{X}             1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
+       /* SMULWy               1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
+       /* SMUSD{X}             1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
+       /* SMMUL{R}             1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
+       /* USAD8                1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
+       DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, PROBES_T32_MUL_ADD,
+                                                REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
+
+       /* ???                  1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
+       DECODE_REJECT   (0xfff000f0, 0xfb700010),
+
+       /* SMLAxy               1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
+       DECODE_OR       (0xfff000c0, 0xfb100000),
+       /* MLA                  1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
+       /* MLS                  1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
+       /* SMLAD{X}             1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
+       /* SMLAWy               1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
+       /* SMLSD{X}             1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
+       /* SMMLA{R}             1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
+       /* SMMLS{R}             1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
+       /* USADA8               1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
+       DECODE_EMULATEX (0xff8000c0, 0xfb000000,  PROBES_T32_MUL_ADD2,
+                                                REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
+
+       /* Other unallocated instructions...                            */
+       DECODE_END
+};
+
+static const union decode_item t32_table_1111_1011_1[] = {
+       /* Long multiply, long multiply accumulate, and divide          */
+
+       /* UMAAL                1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
+       DECODE_OR       (0xfff000f0, 0xfbe00060),
+       /* SMLALxy              1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
+       DECODE_OR       (0xfff000c0, 0xfbc00080),
+       /* SMLALD{X}            1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
+       /* SMLSLD{X}            1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
+       DECODE_OR       (0xffe000e0, 0xfbc000c0),
+       /* SMULL                1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
+       /* UMULL                1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
+       /* SMLAL                1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
+       /* UMLAL                1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
+       DECODE_EMULATEX (0xff9000f0, 0xfb800000, PROBES_T32_MUL_ADD_LONG,
+                                                REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
+
+       /* SDIV                 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
+       /* UDIV                 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
+       /* Other unallocated instructions...                            */
+       DECODE_END
+};
+
+const union decode_item probes_decode_thumb32_table[] = {
+
+       /*
+        * Load/store multiple instructions
+        *                      1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
+
+       /*
+        * Load/store dual, load/store exclusive, table branch
+        *                      1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
+
+       /*
+        * Data-processing (shifted register)
+        *                      1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfe000000, 0xea000000, t32_table_1110_101x),
+
+       /*
+        * Coprocessor instructions
+        *                      1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_REJECT   (0xfc000000, 0xec000000),
+
+       /*
+        * Data-processing (modified immediate)
+        *                      1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
+
+       /*
+        * Data-processing (plain binary immediate)
+        *                      1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
+
+       /*
+        * Branches and miscellaneous control
+        *                      1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
+
+       /*
+        * Advanced SIMD element or structure load/store instructions
+        *                      1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_REJECT   (0xff100000, 0xf9000000),
+
+       /*
+        * Memory hints
+        *                      1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
+
+       /*
+        * Store single data item
+        *                      1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
+        * Load single data items
+        *                      1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xfe000000, 0xf8000000, t32_table_1111_100x),
+
+       /*
+        * Data-processing (register)
+        *                      1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
+
+       /*
+        * Multiply, multiply accumulate, and absolute difference
+        *                      1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xff800000, 0xfb000000, t32_table_1111_1011_0),
+
+       /*
+        * Long multiply, long multiply accumulate, and divide
+        *                      1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xff800000, 0xfb800000, t32_table_1111_1011_1),
+
+       /*
+        * Coprocessor instructions
+        *                      1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
+        */
+       DECODE_END
+};
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(probes_decode_thumb32_table);
+#endif
+
+static const union decode_item t16_table_1011[] = {
+       /* Miscellaneous 16-bit instructions                */
+
+       /* ADD (SP plus immediate)      1011 0000 0xxx xxxx */
+       /* SUB (SP minus immediate)     1011 0000 1xxx xxxx */
+       DECODE_SIMULATE (0xff00, 0xb000, PROBES_T16_ADD_SP),
+
+       /* CBZ                          1011 00x1 xxxx xxxx */
+       /* CBNZ                         1011 10x1 xxxx xxxx */
+       DECODE_SIMULATE (0xf500, 0xb100, PROBES_T16_CBZ),
+
+       /* SXTH                         1011 0010 00xx xxxx */
+       /* SXTB                         1011 0010 01xx xxxx */
+       /* UXTH                         1011 0010 10xx xxxx */
+       /* UXTB                         1011 0010 11xx xxxx */
+       /* REV                          1011 1010 00xx xxxx */
+       /* REV16                        1011 1010 01xx xxxx */
+       /* ???                          1011 1010 10xx xxxx */
+       /* REVSH                        1011 1010 11xx xxxx */
+       DECODE_REJECT   (0xffc0, 0xba80),
+       DECODE_EMULATE  (0xf500, 0xb000, PROBES_T16_SIGN_EXTEND),
+
+       /* PUSH                         1011 010x xxxx xxxx */
+       DECODE_CUSTOM   (0xfe00, 0xb400, PROBES_T16_PUSH),
+       /* POP                          1011 110x xxxx xxxx */
+       DECODE_CUSTOM   (0xfe00, 0xbc00, PROBES_T16_POP),
+
+       /*
+        * If-Then, and hints
+        *                              1011 1111 xxxx xxxx
+        */
+
+       /* YIELD                        1011 1111 0001 0000 */
+       DECODE_OR       (0xffff, 0xbf10),
+       /* SEV                          1011 1111 0100 0000 */
+       DECODE_EMULATE  (0xffff, 0xbf40, PROBES_T16_SEV),
+       /* NOP                          1011 1111 0000 0000 */
+       /* WFE                          1011 1111 0010 0000 */
+       /* WFI                          1011 1111 0011 0000 */
+       DECODE_SIMULATE (0xffcf, 0xbf00, PROBES_T16_WFE),
+       /* Unassigned hints             1011 1111 xxxx 0000 */
+       DECODE_REJECT   (0xff0f, 0xbf00),
+       /* IT                           1011 1111 xxxx xxxx */
+       DECODE_CUSTOM   (0xff00, 0xbf00, PROBES_T16_IT),
+
+       /* SETEND                       1011 0110 010x xxxx */
+       /* CPS                          1011 0110 011x xxxx */
+       /* BKPT                         1011 1110 xxxx xxxx */
+       /* And unallocated instructions...                  */
+       DECODE_END
+};
+
+const union decode_item probes_decode_thumb16_table[] = {
+
+       /*
+        * Shift (immediate), add, subtract, move, and compare
+        *                              00xx xxxx xxxx xxxx
+        */
+
+       /* CMP (immediate)              0010 1xxx xxxx xxxx */
+       DECODE_EMULATE  (0xf800, 0x2800, PROBES_T16_CMP),
+
+       /* ADD (register)               0001 100x xxxx xxxx */
+       /* SUB (register)               0001 101x xxxx xxxx */
+       /* LSL (immediate)              0000 0xxx xxxx xxxx */
+       /* LSR (immediate)              0000 1xxx xxxx xxxx */
+       /* ASR (immediate)              0001 0xxx xxxx xxxx */
+       /* ADD (immediate, Thumb)       0001 110x xxxx xxxx */
+       /* SUB (immediate, Thumb)       0001 111x xxxx xxxx */
+       /* MOV (immediate)              0010 0xxx xxxx xxxx */
+       /* ADD (immediate, Thumb)       0011 0xxx xxxx xxxx */
+       /* SUB (immediate, Thumb)       0011 1xxx xxxx xxxx */
+       DECODE_EMULATE  (0xc000, 0x0000, PROBES_T16_ADDSUB),
+
+       /*
+        * 16-bit Thumb data-processing instructions
+        *                              0100 00xx xxxx xxxx
+        */
+
+       /* TST (register)               0100 0010 00xx xxxx */
+       DECODE_EMULATE  (0xffc0, 0x4200, PROBES_T16_CMP),
+       /* CMP (register)               0100 0010 10xx xxxx */
+       /* CMN (register)               0100 0010 11xx xxxx */
+       DECODE_EMULATE  (0xff80, 0x4280, PROBES_T16_CMP),
+       /* AND (register)               0100 0000 00xx xxxx */
+       /* EOR (register)               0100 0000 01xx xxxx */
+       /* LSL (register)               0100 0000 10xx xxxx */
+       /* LSR (register)               0100 0000 11xx xxxx */
+       /* ASR (register)               0100 0001 00xx xxxx */
+       /* ADC (register)               0100 0001 01xx xxxx */
+       /* SBC (register)               0100 0001 10xx xxxx */
+       /* ROR (register)               0100 0001 11xx xxxx */
+       /* RSB (immediate)              0100 0010 01xx xxxx */
+       /* ORR (register)               0100 0011 00xx xxxx */
+       /* MUL                          0100 0011 00xx xxxx */
+       /* BIC (register)               0100 0011 10xx xxxx */
+       /* MVN (register)               0100 0011 10xx xxxx */
+       DECODE_EMULATE  (0xfc00, 0x4000, PROBES_T16_LOGICAL),
+
+       /*
+        * Special data instructions and branch and exchange
+        *                              0100 01xx xxxx xxxx
+        */
+
+       /* BLX pc                       0100 0111 1111 1xxx */
+       DECODE_REJECT   (0xfff8, 0x47f8),
+
+       /* BX (register)                0100 0111 0xxx xxxx */
+       /* BLX (register)               0100 0111 1xxx xxxx */
+       DECODE_SIMULATE (0xff00, 0x4700, PROBES_T16_BLX),
+
+       /* ADD pc, pc                   0100 0100 1111 1111 */
+       DECODE_REJECT   (0xffff, 0x44ff),
+
+       /* ADD (register)               0100 0100 xxxx xxxx */
+       /* CMP (register)               0100 0101 xxxx xxxx */
+       /* MOV (register)               0100 0110 xxxx xxxx */
+       DECODE_CUSTOM   (0xfc00, 0x4400, PROBES_T16_HIREGOPS),
+
+       /*
+        * Load from Literal Pool
+        * LDR (literal)                0100 1xxx xxxx xxxx
+        */
+       DECODE_SIMULATE (0xf800, 0x4800, PROBES_T16_LDR_LIT),
+
+       /*
+        * 16-bit Thumb Load/store instructions
+        *                              0101 xxxx xxxx xxxx
+        *                              011x xxxx xxxx xxxx
+        *                              100x xxxx xxxx xxxx
+        */
+
+       /* STR (register)               0101 000x xxxx xxxx */
+       /* STRH (register)              0101 001x xxxx xxxx */
+       /* STRB (register)              0101 010x xxxx xxxx */
+       /* LDRSB (register)             0101 011x xxxx xxxx */
+       /* LDR (register)               0101 100x xxxx xxxx */
+       /* LDRH (register)              0101 101x xxxx xxxx */
+       /* LDRB (register)              0101 110x xxxx xxxx */
+       /* LDRSH (register)             0101 111x xxxx xxxx */
+       /* STR (immediate, Thumb)       0110 0xxx xxxx xxxx */
+       /* LDR (immediate, Thumb)       0110 1xxx xxxx xxxx */
+       /* STRB (immediate, Thumb)      0111 0xxx xxxx xxxx */
+       /* LDRB (immediate, Thumb)      0111 1xxx xxxx xxxx */
+       DECODE_EMULATE  (0xc000, 0x4000, PROBES_T16_LDRHSTRH),
+       /* STRH (immediate, Thumb)      1000 0xxx xxxx xxxx */
+       /* LDRH (immediate, Thumb)      1000 1xxx xxxx xxxx */
+       DECODE_EMULATE  (0xf000, 0x8000, PROBES_T16_LDRHSTRH),
+       /* STR (immediate, Thumb)       1001 0xxx xxxx xxxx */
+       /* LDR (immediate, Thumb)       1001 1xxx xxxx xxxx */
+       DECODE_SIMULATE (0xf000, 0x9000, PROBES_T16_LDRSTR),
+
+       /*
+        * Generate PC-/SP-relative address
+        * ADR (literal)                1010 0xxx xxxx xxxx
+        * ADD (SP plus immediate)      1010 1xxx xxxx xxxx
+        */
+       DECODE_SIMULATE (0xf000, 0xa000, PROBES_T16_ADR),
+
+       /*
+        * Miscellaneous 16-bit instructions
+        *                              1011 xxxx xxxx xxxx
+        */
+       DECODE_TABLE    (0xf000, 0xb000, t16_table_1011),
+
+       /* STM                          1100 0xxx xxxx xxxx */
+       /* LDM                          1100 1xxx xxxx xxxx */
+       DECODE_EMULATE  (0xf000, 0xc000, PROBES_T16_LDMSTM),
+
+       /*
+        * Conditional branch, and Supervisor Call
+        */
+
+       /* Permanently UNDEFINED        1101 1110 xxxx xxxx */
+       /* SVC                          1101 1111 xxxx xxxx */
+       DECODE_REJECT   (0xfe00, 0xde00),
+
+       /* Conditional branch           1101 xxxx xxxx xxxx */
+       DECODE_CUSTOM   (0xf000, 0xd000, PROBES_T16_BRANCH_COND),
+
+       /*
+        * Unconditional branch
+        * B                            1110 0xxx xxxx xxxx
+        */
+       DECODE_SIMULATE (0xf800, 0xe000, PROBES_T16_BRANCH),
+
+       DECODE_END
+};
+#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
+EXPORT_SYMBOL_GPL(probes_decode_thumb16_table);
+#endif
+
+static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
+{
+       if (unlikely(in_it_block(cpsr)))
+               return probes_condition_checks[current_cond(cpsr)](cpsr);
+       return true;
+}
+
+static void __kprobes thumb16_singlestep(probes_opcode_t opcode,
+               struct arch_probes_insn *asi,
+               struct pt_regs *regs)
+{
+       regs->ARM_pc += 2;
+       asi->insn_handler(opcode, asi, regs);
+       regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
+}
+
+static void __kprobes thumb32_singlestep(probes_opcode_t opcode,
+               struct arch_probes_insn *asi,
+               struct pt_regs *regs)
+{
+       regs->ARM_pc += 4;
+       asi->insn_handler(opcode, asi, regs);
+       regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
+}
+
+enum probes_insn __kprobes
+thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+                          bool emulate, const union decode_action *actions)
+{
+       asi->insn_singlestep = thumb16_singlestep;
+       asi->insn_check_cc = thumb_check_cc;
+       return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true,
+                                 emulate, actions);
+}
+
+enum probes_insn __kprobes
+thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+                          bool emulate, const union decode_action *actions)
+{
+       asi->insn_singlestep = thumb32_singlestep;
+       asi->insn_check_cc = thumb_check_cc;
+       return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true,
+                                 emulate, actions);
+}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/kernel/probes-thumb.h
new file mode 100644 (file)
index 0000000..7c6f6eb
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/kernel/probes-thumb.h
+ *
+ * Copyright 2013 Linaro Ltd.
+ * Written by: David A. Long
+ *
+ * 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
+ */
+
+#ifndef _ARM_KERNEL_PROBES_THUMB_H
+#define  _ARM_KERNEL_PROBES_THUMB_H
+
+/*
+ * True if current instruction is in an IT block.
+ */
+#define in_it_block(cpsr)      ((cpsr & 0x06000c00) != 0x00000000)
+
+/*
+ * Return the condition code to check for the currently executing instruction.
+ * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if
+ * in_it_block returns true.
+ */
+#define current_cond(cpsr)     ((cpsr >> 12) & 0xf)
+
+enum probes_t32_action {
+       PROBES_T32_EMULATE_NONE,
+       PROBES_T32_SIMULATE_NOP,
+       PROBES_T32_LDMSTM,
+       PROBES_T32_LDRDSTRD,
+       PROBES_T32_TABLE_BRANCH,
+       PROBES_T32_TST,
+       PROBES_T32_CMP,
+       PROBES_T32_MOV,
+       PROBES_T32_ADDSUB,
+       PROBES_T32_LOGICAL,
+       PROBES_T32_ADDWSUBW_PC,
+       PROBES_T32_ADDWSUBW,
+       PROBES_T32_MOVW,
+       PROBES_T32_SAT,
+       PROBES_T32_BITFIELD,
+       PROBES_T32_SEV,
+       PROBES_T32_WFE,
+       PROBES_T32_MRS,
+       PROBES_T32_BRANCH_COND,
+       PROBES_T32_BRANCH,
+       PROBES_T32_PLDI,
+       PROBES_T32_LDR_LIT,
+       PROBES_T32_LDRSTR,
+       PROBES_T32_SIGN_EXTEND,
+       PROBES_T32_MEDIA,
+       PROBES_T32_REVERSE,
+       PROBES_T32_MUL_ADD,
+       PROBES_T32_MUL_ADD2,
+       PROBES_T32_MUL_ADD_LONG,
+       NUM_PROBES_T32_ACTIONS
+};
+
+enum probes_t16_action {
+       PROBES_T16_ADD_SP,
+       PROBES_T16_CBZ,
+       PROBES_T16_SIGN_EXTEND,
+       PROBES_T16_PUSH,
+       PROBES_T16_POP,
+       PROBES_T16_SEV,
+       PROBES_T16_WFE,
+       PROBES_T16_IT,
+       PROBES_T16_CMP,
+       PROBES_T16_ADDSUB,
+       PROBES_T16_LOGICAL,
+       PROBES_T16_BLX,
+       PROBES_T16_HIREGOPS,
+       PROBES_T16_LDR_LIT,
+       PROBES_T16_LDRHSTRH,
+       PROBES_T16_LDRSTR,
+       PROBES_T16_ADR,
+       PROBES_T16_LDMSTM,
+       PROBES_T16_BRANCH_COND,
+       PROBES_T16_BRANCH,
+       NUM_PROBES_T16_ACTIONS
+};
+
+extern const union decode_item probes_decode_thumb32_table[];
+extern const union decode_item probes_decode_thumb16_table[];
+
+enum probes_insn __kprobes
+thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+               bool emulate, const union decode_action *actions);
+enum probes_insn __kprobes
+thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+               bool emulate, const union decode_action *actions);
+
+#endif
diff --git a/arch/arm/kernel/probes.c b/arch/arm/kernel/probes.c
new file mode 100644 (file)
index 0000000..b41873f
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * arch/arm/kernel/probes.c
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
+ * Copyright (C) 2006, 2007 Motorola 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/kernel.h>
+#include <linux/types.h>
+#include <asm/system_info.h>
+#include <asm/ptrace.h>
+#include <linux/bug.h>
+
+#include "probes.h"
+
+
+#ifndef find_str_pc_offset
+
+/*
+ * For STR and STM instructions, an ARM core may choose to use either
+ * a +8 or a +12 displacement from the current instruction's address.
+ * Whichever value is chosen for a given core, it must be the same for
+ * both instructions and may not change.  This function measures it.
+ */
+
+int str_pc_offset;
+
+void __init find_str_pc_offset(void)
+{
+       int addr, scratch, ret;
+
+       __asm__ (
+               "sub    %[ret], pc, #4          \n\t"
+               "str    pc, %[addr]             \n\t"
+               "ldr    %[scr], %[addr]         \n\t"
+               "sub    %[ret], %[scr], %[ret]  \n\t"
+               : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
+
+       str_pc_offset = ret;
+}
+
+#endif /* !find_str_pc_offset */
+
+
+#ifndef test_load_write_pc_interworking
+
+bool load_write_pc_interworks;
+
+void __init test_load_write_pc_interworking(void)
+{
+       int arch = cpu_architecture();
+       BUG_ON(arch == CPU_ARCH_UNKNOWN);
+       load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
+}
+
+#endif /* !test_load_write_pc_interworking */
+
+
+#ifndef test_alu_write_pc_interworking
+
+bool alu_write_pc_interworks;
+
+void __init test_alu_write_pc_interworking(void)
+{
+       int arch = cpu_architecture();
+       BUG_ON(arch == CPU_ARCH_UNKNOWN);
+       alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
+}
+
+#endif /* !test_alu_write_pc_interworking */
+
+
+void __init arm_probes_decode_init(void)
+{
+       find_str_pc_offset();
+       test_load_write_pc_interworking();
+       test_alu_write_pc_interworking();
+}
+
+
+static unsigned long __kprobes __check_eq(unsigned long cpsr)
+{
+       return cpsr & PSR_Z_BIT;
+}
+
+static unsigned long __kprobes __check_ne(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_Z_BIT;
+}
+
+static unsigned long __kprobes __check_cs(unsigned long cpsr)
+{
+       return cpsr & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_cc(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_mi(unsigned long cpsr)
+{
+       return cpsr & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_pl(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_vs(unsigned long cpsr)
+{
+       return cpsr & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_vc(unsigned long cpsr)
+{
+       return (~cpsr) & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_hi(unsigned long cpsr)
+{
+       cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+       return cpsr & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ls(unsigned long cpsr)
+{
+       cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+       return (~cpsr) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ge(unsigned long cpsr)
+{
+       cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       return (~cpsr) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_lt(unsigned long cpsr)
+{
+       cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       return cpsr & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_gt(unsigned long cpsr)
+{
+       unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
+       return (~temp) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_le(unsigned long cpsr)
+{
+       unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+       temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
+       return temp & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_al(unsigned long cpsr)
+{
+       return true;
+}
+
+probes_check_cc * const probes_condition_checks[16] = {
+       &__check_eq, &__check_ne, &__check_cs, &__check_cc,
+       &__check_mi, &__check_pl, &__check_vs, &__check_vc,
+       &__check_hi, &__check_ls, &__check_ge, &__check_lt,
+       &__check_gt, &__check_le, &__check_al, &__check_al
+};
+
+
+void __kprobes probes_simulate_nop(probes_opcode_t opcode,
+       struct arch_probes_insn *asi,
+       struct pt_regs *regs)
+{
+}
+
+void __kprobes probes_emulate_none(probes_opcode_t opcode,
+       struct arch_probes_insn *asi,
+       struct pt_regs *regs)
+{
+       asi->insn_fn();
+}
+
+/*
+ * Prepare an instruction slot to receive an instruction for emulating.
+ * This is done by placing a subroutine return after the location where the
+ * instruction will be placed. We also modify ARM instructions to be
+ * unconditional as the condition code will already be checked before any
+ * emulation handler is called.
+ */
+static probes_opcode_t __kprobes
+prepare_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+                     bool thumb)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+       if (thumb) {
+               u16 *thumb_insn = (u16 *)asi->insn;
+               thumb_insn[1] = 0x4770; /* Thumb bx lr */
+               thumb_insn[2] = 0x4770; /* Thumb bx lr */
+               return insn;
+       }
+       asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
+#else
+       asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
+#endif
+       /* Make an ARM instruction unconditional */
+       if (insn < 0xe0000000)
+               insn = (insn | 0xe0000000) & ~0x10000000;
+       return insn;
+}
+
+/*
+ * Write a (probably modified) instruction into the slot previously prepared by
+ * prepare_emulated_insn
+ */
+static void  __kprobes
+set_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+                 bool thumb)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+       if (thumb) {
+               u16 *ip = (u16 *)asi->insn;
+               if (is_wide_instruction(insn))
+                       *ip++ = insn >> 16;
+               *ip++ = insn;
+               return;
+       }
+#endif
+       asi->insn[0] = insn;
+}
+
+/*
+ * When we modify the register numbers encoded in an instruction to be emulated,
+ * the new values come from this define. For ARM and 32-bit Thumb instructions
+ * this gives...
+ *
+ *     bit position      16  12   8   4   0
+ *     ---------------+---+---+---+---+---+
+ *     register         r2  r0  r1  --  r3
+ */
+#define INSN_NEW_BITS          0x00020103
+
+/* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
+#define INSN_SAMEAS16_BITS     0x22222222
+
+/*
+ * Validate and modify each of the registers encoded in an instruction.
+ *
+ * Each nibble in regs contains a value from enum decode_reg_type. For each
+ * non-zero value, the corresponding nibble in pinsn is validated and modified
+ * according to the type.
+ */
+static bool __kprobes decode_regs(probes_opcode_t *pinsn, u32 regs, bool modify)
+{
+       probes_opcode_t insn = *pinsn;
+       probes_opcode_t mask = 0xf; /* Start at least significant nibble */
+
+       for (; regs != 0; regs >>= 4, mask <<= 4) {
+
+               probes_opcode_t new_bits = INSN_NEW_BITS;
+
+               switch (regs & 0xf) {
+
+               case REG_TYPE_NONE:
+                       /* Nibble not a register, skip to next */
+                       continue;
+
+               case REG_TYPE_ANY:
+                       /* Any register is allowed */
+                       break;
+
+               case REG_TYPE_SAMEAS16:
+                       /* Replace register with same as at bit position 16 */
+                       new_bits = INSN_SAMEAS16_BITS;
+                       break;
+
+               case REG_TYPE_SP:
+                       /* Only allow SP (R13) */
+                       if ((insn ^ 0xdddddddd) & mask)
+                               goto reject;
+                       break;
+
+               case REG_TYPE_PC:
+                       /* Only allow PC (R15) */
+                       if ((insn ^ 0xffffffff) & mask)
+                               goto reject;
+                       break;
+
+               case REG_TYPE_NOSP:
+                       /* Reject SP (R13) */
+                       if (((insn ^ 0xdddddddd) & mask) == 0)
+                               goto reject;
+                       break;
+
+               case REG_TYPE_NOSPPC:
+               case REG_TYPE_NOSPPCX:
+                       /* Reject SP and PC (R13 and R15) */
+                       if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
+                               goto reject;
+                       break;
+
+               case REG_TYPE_NOPCWB:
+                       if (!is_writeback(insn))
+                               break; /* No writeback, so any register is OK */
+                       /* fall through... */
+               case REG_TYPE_NOPC:
+               case REG_TYPE_NOPCX:
+                       /* Reject PC (R15) */
+                       if (((insn ^ 0xffffffff) & mask) == 0)
+                               goto reject;
+                       break;
+               }
+
+               /* Replace value of nibble with new register number... */
+               insn &= ~mask;
+               insn |= new_bits & mask;
+       }
+
+       if (modify)
+               *pinsn = insn;
+
+       return true;
+
+reject:
+       return false;
+}
+
+static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
+       [DECODE_TYPE_TABLE]     = sizeof(struct decode_table),
+       [DECODE_TYPE_CUSTOM]    = sizeof(struct decode_custom),
+       [DECODE_TYPE_SIMULATE]  = sizeof(struct decode_simulate),
+       [DECODE_TYPE_EMULATE]   = sizeof(struct decode_emulate),
+       [DECODE_TYPE_OR]        = sizeof(struct decode_or),
+       [DECODE_TYPE_REJECT]    = sizeof(struct decode_reject)
+};
+
+/*
+ * probes_decode_insn operates on data tables in order to decode an ARM
+ * architecture instruction onto which a kprobe has been placed.
+ *
+ * These instruction decoding tables are a concatenation of entries each
+ * of which consist of one of the following structs:
+ *
+ *     decode_table
+ *     decode_custom
+ *     decode_simulate
+ *     decode_emulate
+ *     decode_or
+ *     decode_reject
+ *
+ * Each of these starts with a struct decode_header which has the following
+ * fields:
+ *
+ *     type_regs
+ *     mask
+ *     value
+ *
+ * The least significant DECODE_TYPE_BITS of type_regs contains a value
+ * from enum decode_type, this indicates which of the decode_* structs
+ * the entry contains. The value DECODE_TYPE_END indicates the end of the
+ * table.
+ *
+ * When the table is parsed, each entry is checked in turn to see if it
+ * matches the instruction to be decoded using the test:
+ *
+ *     (insn & mask) == value
+ *
+ * If no match is found before the end of the table is reached then decoding
+ * fails with INSN_REJECTED.
+ *
+ * When a match is found, decode_regs() is called to validate and modify each
+ * of the registers encoded in the instruction; the data it uses to do this
+ * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
+ * to fail with INSN_REJECTED.
+ *
+ * Once the instruction has passed the above tests, further processing
+ * depends on the type of the table entry's decode struct.
+ *
+ */
+int __kprobes
+probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+                  const union decode_item *table, bool thumb,
+                  bool emulate, const union decode_action *actions)
+{
+       const struct decode_header *h = (struct decode_header *)table;
+       const struct decode_header *next;
+       bool matched = false;
+
+       if (emulate)
+               insn = prepare_emulated_insn(insn, asi, thumb);
+
+       for (;; h = next) {
+               enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
+               u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
+
+               if (type == DECODE_TYPE_END)
+                       return INSN_REJECTED;
+
+               next = (struct decode_header *)
+                               ((uintptr_t)h + decode_struct_sizes[type]);
+
+               if (!matched && (insn & h->mask.bits) != h->value.bits)
+                       continue;
+
+               if (!decode_regs(&insn, regs, emulate))
+                       return INSN_REJECTED;
+
+               switch (type) {
+
+               case DECODE_TYPE_TABLE: {
+                       struct decode_table *d = (struct decode_table *)h;
+                       next = (struct decode_header *)d->table.table;
+                       break;
+               }
+
+               case DECODE_TYPE_CUSTOM: {
+                       struct decode_custom *d = (struct decode_custom *)h;
+                       return actions[d->decoder.action].decoder(insn, asi, h);
+               }
+
+               case DECODE_TYPE_SIMULATE: {
+                       struct decode_simulate *d = (struct decode_simulate *)h;
+                       asi->insn_handler = actions[d->handler.action].handler;
+                       return INSN_GOOD_NO_SLOT;
+               }
+
+               case DECODE_TYPE_EMULATE: {
+                       struct decode_emulate *d = (struct decode_emulate *)h;
+
+                       if (!emulate)
+                               return actions[d->handler.action].decoder(insn,
+                                       asi, h);
+
+                       asi->insn_handler = actions[d->handler.action].handler;
+                       set_emulated_insn(insn, asi, thumb);
+                       return INSN_GOOD;
+               }
+
+               case DECODE_TYPE_OR:
+                       matched = true;
+                       break;
+
+               case DECODE_TYPE_REJECT:
+               default:
+                       return INSN_REJECTED;
+               }
+       }
+}
diff --git a/arch/arm/kernel/probes.h b/arch/arm/kernel/probes.h
new file mode 100644 (file)
index 0000000..dba9f24
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * arch/arm/kernel/probes.h
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * Some contents moved here from arch/arm/include/asm/kprobes.h which is
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _ARM_KERNEL_PROBES_H
+#define  _ARM_KERNEL_PROBES_H
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <asm/probes.h>
+
+void __init arm_probes_decode_init(void);
+
+extern probes_check_cc * const probes_condition_checks[16];
+
+#if __LINUX_ARM_ARCH__ >= 7
+
+/* str_pc_offset is architecturally defined from ARMv7 onwards */
+#define str_pc_offset 8
+#define find_str_pc_offset()
+
+#else /* __LINUX_ARM_ARCH__ < 7 */
+
+/* We need a run-time check to determine str_pc_offset */
+extern int str_pc_offset;
+void __init find_str_pc_offset(void);
+
+#endif
+
+
+/*
+ * Update ITSTATE after normal execution of an IT block instruction.
+ *
+ * The 8 IT state bits are split into two parts in CPSR:
+ *     ITSTATE<1:0> are in CPSR<26:25>
+ *     ITSTATE<7:2> are in CPSR<15:10>
+ */
+static inline unsigned long it_advance(unsigned long cpsr)
+       {
+       if ((cpsr & 0x06000400) == 0) {
+               /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
+               cpsr &= ~PSR_IT_MASK;
+       } else {
+               /* We need to shift left ITSTATE<4:0> */
+               const unsigned long mask = 0x06001c00;  /* Mask ITSTATE<4:0> */
+               unsigned long it = cpsr & mask;
+               it <<= 1;
+               it |= it >> (27 - 10);  /* Carry ITSTATE<2> to correct place */
+               it &= mask;
+               cpsr &= ~mask;
+               cpsr |= it;
+       }
+       return cpsr;
+}
+
+static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
+{
+       long cpsr = regs->ARM_cpsr;
+       if (pcv & 0x1) {
+               cpsr |= PSR_T_BIT;
+               pcv &= ~0x1;
+       } else {
+               cpsr &= ~PSR_T_BIT;
+               pcv &= ~0x2;    /* Avoid UNPREDICTABLE address allignment */
+       }
+       regs->ARM_cpsr = cpsr;
+       regs->ARM_pc = pcv;
+}
+
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+/* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */
+#define load_write_pc_interworks true
+#define test_load_write_pc_interworking()
+
+#else /* __LINUX_ARM_ARCH__ < 6 */
+
+/* We need run-time testing to determine if load_write_pc() should interwork. */
+extern bool load_write_pc_interworks;
+void __init test_load_write_pc_interworking(void);
+
+#endif
+
+static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
+{
+       if (load_write_pc_interworks)
+               bx_write_pc(pcv, regs);
+       else
+               regs->ARM_pc = pcv;
+}
+
+
+#if __LINUX_ARM_ARCH__ >= 7
+
+#define alu_write_pc_interworks true
+#define test_alu_write_pc_interworking()
+
+#elif __LINUX_ARM_ARCH__ <= 5
+
+/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
+#define alu_write_pc_interworks false
+#define test_alu_write_pc_interworking()
+
+#else /* __LINUX_ARM_ARCH__ == 6 */
+
+/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
+extern bool alu_write_pc_interworks;
+void __init test_alu_write_pc_interworking(void);
+
+#endif /* __LINUX_ARM_ARCH__ == 6 */
+
+static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
+{
+       if (alu_write_pc_interworks)
+               bx_write_pc(pcv, regs);
+       else
+               regs->ARM_pc = pcv;
+}
+
+
+/*
+ * Test if load/store instructions writeback the address register.
+ * if P (bit 24) == 0 or W (bit 21) == 1
+ */
+#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
+
+/*
+ * The following definitions and macros are used to build instruction
+ * decoding tables for use by probes_decode_insn.
+ *
+ * These tables are a concatenation of entries each of which consist of one of
+ * the decode_* structs. All of the fields in every type of decode structure
+ * are of the union type decode_item, therefore the entire decode table can be
+ * viewed as an array of these and declared like:
+ *
+ *     static const union decode_item table_name[] = {};
+ *
+ * In order to construct each entry in the table, macros are used to
+ * initialise a number of sequential decode_item values in a layout which
+ * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct
+ * decode_simulate by initialising four decode_item objects like this...
+ *
+ *     {.bits = _type},
+ *     {.bits = _mask},
+ *     {.bits = _value},
+ *     {.action = _handler},
+ *
+ * Initialising a specified member of the union means that the compiler
+ * will produce a warning if the argument is of an incorrect type.
+ *
+ * Below is a list of each of the macros used to initialise entries and a
+ * description of the action performed when that entry is matched to an
+ * instruction. A match is found when (instruction & mask) == value.
+ *
+ * DECODE_TABLE(mask, value, table)
+ *     Instruction decoding jumps to parsing the new sub-table 'table'.
+ *
+ * DECODE_CUSTOM(mask, value, decoder)
+ *     The value of 'decoder' is used as an index into the array of
+ *     action functions, and the retrieved decoder function is invoked
+ *     to complete decoding of the instruction.
+ *
+ * DECODE_SIMULATE(mask, value, handler)
+ *     The probes instruction handler is set to the value found by
+ *     indexing into the action array using the value of 'handler'. This
+ *     will be used to simulate the instruction when the probe is hit.
+ *     Decoding returns with INSN_GOOD_NO_SLOT.
+ *
+ * DECODE_EMULATE(mask, value, handler)
+ *     The probes instruction handler is set to the value found by
+ *     indexing into the action array using the value of 'handler'. This
+ *     will be used to emulate the instruction when the probe is hit. The
+ *     modified instruction (see below) is placed in the probes instruction
+ *     slot so it may be called by the emulation code. Decoding returns
+ *     with INSN_GOOD.
+ *
+ * DECODE_REJECT(mask, value)
+ *     Instruction decoding fails with INSN_REJECTED
+ *
+ * DECODE_OR(mask, value)
+ *     This allows the mask/value test of multiple table entries to be
+ *     logically ORed. Once an 'or' entry is matched the decoding action to
+ *     be performed is that of the next entry which isn't an 'or'. E.g.
+ *
+ *             DECODE_OR       (mask1, value1)
+ *             DECODE_OR       (mask2, value2)
+ *             DECODE_SIMULATE (mask3, value3, simulation_handler)
+ *
+ *     This means that if any of the three mask/value pairs match the
+ *     instruction being decoded, then 'simulation_handler' will be used
+ *     for it.
+ *
+ * Both the SIMULATE and EMULATE macros have a second form which take an
+ * additional 'regs' argument.
+ *
+ *     DECODE_SIMULATEX(mask, value, handler, regs)
+ *     DECODE_EMULATEX (mask, value, handler, regs)
+ *
+ * These are used to specify what kind of CPU register is encoded in each of the
+ * least significant 5 nibbles of the instruction being decoded. The regs value
+ * is specified using the REGS macro, this takes any of the REG_TYPE_* values
+ * from enum decode_reg_type as arguments; only the '*' part of the name is
+ * given. E.g.
+ *
+ *     REGS(0, ANY, NOPC, 0, ANY)
+ *
+ * This indicates an instruction is encoded like:
+ *
+ *     bits 19..16     ignore
+ *     bits 15..12     any register allowed here
+ *     bits 11.. 8     any register except PC allowed here
+ *     bits  7.. 4     ignore
+ *     bits  3.. 0     any register allowed here
+ *
+ * This register specification is checked after a decode table entry is found to
+ * match an instruction (through the mask/value test). Any invalid register then
+ * found in the instruction will cause decoding to fail with INSN_REJECTED. In
+ * the above example this would happen if bits 11..8 of the instruction were
+ * 1111, indicating R15 or PC.
+ *
+ * As well as checking for legal combinations of registers, this data is also
+ * used to modify the registers encoded in the instructions so that an
+ * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.)
+ *
+ * Here is a real example which matches ARM instructions of the form
+ * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
+ *
+ *     DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
+ *                                              REGS(ANY, ANY, NOPC, 0, ANY)),
+ *                                                   ^    ^    ^        ^
+ *                                                   Rn   Rd   Rs       Rm
+ *
+ * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because
+ * Rs == R15
+ *
+ * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
+ * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
+ * the kprobes instruction slot. This can then be called later by the handler
+ * function emulate_rd12rn16rm0rs8_rwflags (a pointer to which is retrieved from
+ * the indicated slot in the action array), in order to simulate the instruction.
+ */
+
+enum decode_type {
+       DECODE_TYPE_END,
+       DECODE_TYPE_TABLE,
+       DECODE_TYPE_CUSTOM,
+       DECODE_TYPE_SIMULATE,
+       DECODE_TYPE_EMULATE,
+       DECODE_TYPE_OR,
+       DECODE_TYPE_REJECT,
+       NUM_DECODE_TYPES /* Must be last enum */
+};
+
+#define DECODE_TYPE_BITS       4
+#define DECODE_TYPE_MASK       ((1 << DECODE_TYPE_BITS) - 1)
+
+enum decode_reg_type {
+       REG_TYPE_NONE = 0, /* Not a register, ignore */
+       REG_TYPE_ANY,      /* Any register allowed */
+       REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */
+       REG_TYPE_SP,       /* Register must be SP */
+       REG_TYPE_PC,       /* Register must be PC */
+       REG_TYPE_NOSP,     /* Register must not be SP */
+       REG_TYPE_NOSPPC,   /* Register must not be SP or PC */
+       REG_TYPE_NOPC,     /* Register must not be PC */
+       REG_TYPE_NOPCWB,   /* No PC if load/store write-back flag also set */
+
+       /* The following types are used when the encoding for PC indicates
+        * another instruction form. This distiction only matters for test
+        * case coverage checks.
+        */
+       REG_TYPE_NOPCX,    /* Register must not be PC */
+       REG_TYPE_NOSPPCX,  /* Register must not be SP or PC */
+
+       /* Alias to allow '0' arg to be used in REGS macro. */
+       REG_TYPE_0 = REG_TYPE_NONE
+};
+
+#define REGS(r16, r12, r8, r4, r0)     \
+       (((REG_TYPE_##r16) << 16) +     \
+       ((REG_TYPE_##r12) << 12) +      \
+       ((REG_TYPE_##r8) << 8) +        \
+       ((REG_TYPE_##r4) << 4) +        \
+       (REG_TYPE_##r0))
+
+union decode_item {
+       u32                     bits;
+       const union decode_item *table;
+       int                     action;
+};
+
+struct decode_header;
+typedef enum probes_insn (probes_custom_decode_t)(probes_opcode_t,
+                                                 struct arch_probes_insn *,
+                                                 const struct decode_header *);
+
+union decode_action {
+       probes_insn_handler_t   *handler;
+       probes_custom_decode_t  *decoder;
+};
+
+#define DECODE_END                     \
+       {.bits = DECODE_TYPE_END}
+
+
+struct decode_header {
+       union decode_item       type_regs;
+       union decode_item       mask;
+       union decode_item       value;
+};
+
+#define DECODE_HEADER(_type, _mask, _value, _regs)             \
+       {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)},      \
+       {.bits = (_mask)},                                      \
+       {.bits = (_value)}
+
+
+struct decode_table {
+       struct decode_header    header;
+       union decode_item       table;
+};
+
+#define DECODE_TABLE(_mask, _value, _table)                    \
+       DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0),     \
+       {.table = (_table)}
+
+
+struct decode_custom {
+       struct decode_header    header;
+       union decode_item       decoder;
+};
+
+#define DECODE_CUSTOM(_mask, _value, _decoder)                 \
+       DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0),    \
+       {.action = (_decoder)}
+
+
+struct decode_simulate {
+       struct decode_header    header;
+       union decode_item       handler;
+};
+
+#define DECODE_SIMULATEX(_mask, _value, _handler, _regs)               \
+       DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs),      \
+       {.action = (_handler)}
+
+#define DECODE_SIMULATE(_mask, _value, _handler)       \
+       DECODE_SIMULATEX(_mask, _value, _handler, 0)
+
+
+struct decode_emulate {
+       struct decode_header    header;
+       union decode_item       handler;
+};
+
+#define DECODE_EMULATEX(_mask, _value, _handler, _regs)                        \
+       DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs),       \
+       {.action = (_handler)}
+
+#define DECODE_EMULATE(_mask, _value, _handler)                \
+       DECODE_EMULATEX(_mask, _value, _handler, 0)
+
+
+struct decode_or {
+       struct decode_header    header;
+};
+
+#define DECODE_OR(_mask, _value)                               \
+       DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
+
+enum probes_insn {
+       INSN_REJECTED,
+       INSN_GOOD,
+       INSN_GOOD_NO_SLOT
+};
+
+struct decode_reject {
+       struct decode_header    header;
+};
+
+#define DECODE_REJECT(_mask, _value)                           \
+       DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
+
+probes_insn_handler_t probes_simulate_nop;
+probes_insn_handler_t probes_emulate_none;
+
+int __kprobes
+probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
+               const union decode_item *table, bool thumb, bool emulate,
+               const union decode_action *actions);
+
+#endif
index adabeababeb03d5fc34efe76fa5c12d4eab90a5d..806d287e3e5383972bf08b9d389fbf8e5e8573d3 100644 (file)
@@ -47,14 +47,14 @@ unsigned long __stack_chk_guard __read_mostly;
 EXPORT_SYMBOL(__stack_chk_guard);
 #endif
 
-static const char *processor_modes[] = {
+static const char *processor_modes[] __maybe_unused = {
   "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
   "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
   "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
   "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
 };
 
-static const char *isa_modes[] = {
+static const char *isa_modes[] __maybe_unused = {
   "ARM" , "Thumb" , "Jazelle", "ThumbEE"
 };
 
@@ -270,12 +270,17 @@ void __show_regs(struct pt_regs *regs)
        buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
        buf[4] = '\0';
 
+#ifndef CONFIG_CPU_V7M
        printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
                buf, interrupts_enabled(regs) ? "n" : "ff",
                fast_interrupts_enabled(regs) ? "n" : "ff",
                processor_modes[processor_mode(regs)],
                isa_modes[isa_mode(regs)],
                get_fs() == get_ds() ? "kernel" : "user");
+#else
+       printk("xPSR: %08lx\n", regs->ARM_cpsr);
+#endif
+
 #ifdef CONFIG_CPU_CP15
        {
                unsigned int ctrl;
index 1e8b030dbefd8b2b19da27d9ca8ecabfaf610bba..50e198c1e9c8a16f1b4e06563682e6046f564951 100644 (file)
@@ -100,6 +100,9 @@ EXPORT_SYMBOL(system_serial_high);
 unsigned int elf_hwcap __read_mostly;
 EXPORT_SYMBOL(elf_hwcap);
 
+unsigned int elf_hwcap2 __read_mostly;
+EXPORT_SYMBOL(elf_hwcap2);
+
 
 #ifdef MULTI_CPU
 struct processor processor __read_mostly;
@@ -1005,6 +1008,15 @@ static const char *hwcap_str[] = {
        NULL
 };
 
+static const char *hwcap2_str[] = {
+       "aes",
+       "pmull",
+       "sha1",
+       "sha2",
+       "crc32",
+       NULL
+};
+
 static int c_show(struct seq_file *m, void *v)
 {
        int i, j;
@@ -1028,6 +1040,10 @@ static int c_show(struct seq_file *m, void *v)
                        if (elf_hwcap & (1 << j))
                                seq_printf(m, "%s ", hwcap_str[j]);
 
+               for (j = 0; hwcap2_str[j]; j++)
+                       if (elf_hwcap2 & (1 << j))
+                               seq_printf(m, "%s ", hwcap2_str[j]);
+
                seq_printf(m, "\nCPU implementer\t: 0x%02x\n", cpuid >> 24);
                seq_printf(m, "CPU architecture: %s\n",
                           proc_arch[cpu_architecture()]);
index 04d63880037f9c293741230f95e9520c19ee3dee..bd1983437205190f349b892361e1e488e87f3f79 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/personality.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
+#include <linux/uprobes.h>
 
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
@@ -590,6 +591,9 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
                                        return restart;
                                }
                                syscall = 0;
+                       } else if (thread_flags & _TIF_UPROBE) {
+                               clear_thread_flag(TIF_UPROBE);
+                               uprobe_notify_resume(regs);
                        } else {
                                clear_thread_flag(TIF_NOTIFY_RESUME);
                                tracehook_notify_resume(regs);
index 3e94811690ce1c510beb49e2bf15edea9e0a4fa7..702bd329d9d0cd4f8b0912ca3a9694f942f1a568 100644 (file)
@@ -203,6 +203,9 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
        int ret;
 
        switch (cmd) {
+       case F_GETLKP:
+       case F_SETLKP:
+       case F_SETLKPW:
        case F_GETLK64:
        case F_SETLK64:
        case F_SETLKW64:
index 00df012c46784ac8c510466f1a4124158c3f86a3..3c217694ebecb126b23f226688bcc6874b0c8c7b 100644 (file)
@@ -68,6 +68,12 @@ EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
 struct unwind_ctrl_block {
        unsigned long vrs[16];          /* virtual register set */
        const unsigned long *insn;      /* pointer to the current instructions word */
+       unsigned long sp_high;          /* highest value of sp allowed */
+       /*
+        * 1 : check for stack overflow for each register pop.
+        * 0 : save overhead if there is plenty of stack remaining.
+        */
+       int check_each_pop;
        int entries;                    /* number of entries left to interpret */
        int byte;                       /* current byte number in the instructions word */
 };
@@ -235,12 +241,85 @@ static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
        return ret;
 }
 
+/* Before poping a register check whether it is feasible or not */
+static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
+                               unsigned long **vsp, unsigned int reg)
+{
+       if (unlikely(ctrl->check_each_pop))
+               if (*vsp >= (unsigned long *)ctrl->sp_high)
+                       return -URC_FAILURE;
+
+       ctrl->vrs[reg] = *(*vsp)++;
+       return URC_OK;
+}
+
+/* Helper functions to execute the instructions */
+static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl,
+                                               unsigned long mask)
+{
+       unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+       int load_sp, reg = 4;
+
+       load_sp = mask & (1 << (13 - 4));
+       while (mask) {
+               if (mask & 1)
+                       if (unwind_pop_register(ctrl, &vsp, reg))
+                               return -URC_FAILURE;
+               mask >>= 1;
+               reg++;
+       }
+       if (!load_sp)
+               ctrl->vrs[SP] = (unsigned long)vsp;
+
+       return URC_OK;
+}
+
+static int unwind_exec_pop_r4_to_rN(struct unwind_ctrl_block *ctrl,
+                                       unsigned long insn)
+{
+       unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+       int reg;
+
+       /* pop R4-R[4+bbb] */
+       for (reg = 4; reg <= 4 + (insn & 7); reg++)
+               if (unwind_pop_register(ctrl, &vsp, reg))
+                               return -URC_FAILURE;
+
+       if (insn & 0x80)
+               if (unwind_pop_register(ctrl, &vsp, 14))
+                               return -URC_FAILURE;
+
+       ctrl->vrs[SP] = (unsigned long)vsp;
+
+       return URC_OK;
+}
+
+static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl,
+                                               unsigned long mask)
+{
+       unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+       int reg = 0;
+
+       /* pop R0-R3 according to mask */
+       while (mask) {
+               if (mask & 1)
+                       if (unwind_pop_register(ctrl, &vsp, reg))
+                               return -URC_FAILURE;
+               mask >>= 1;
+               reg++;
+       }
+       ctrl->vrs[SP] = (unsigned long)vsp;
+
+       return URC_OK;
+}
+
 /*
  * Execute the current unwind instruction.
  */
 static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
 {
        unsigned long insn = unwind_get_byte(ctrl);
+       int ret = URC_OK;
 
        pr_debug("%s: insn = %08lx\n", __func__, insn);
 
@@ -250,8 +329,6 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
                ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
        else if ((insn & 0xf0) == 0x80) {
                unsigned long mask;
-               unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
-               int load_sp, reg = 4;
 
                insn = (insn << 8) | unwind_get_byte(ctrl);
                mask = insn & 0x0fff;
@@ -261,29 +338,16 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
                        return -URC_FAILURE;
                }
 
-               /* pop R4-R15 according to mask */
-               load_sp = mask & (1 << (13 - 4));
-               while (mask) {
-                       if (mask & 1)
-                               ctrl->vrs[reg] = *vsp++;
-                       mask >>= 1;
-                       reg++;
-               }
-               if (!load_sp)
-                       ctrl->vrs[SP] = (unsigned long)vsp;
+               ret = unwind_exec_pop_subset_r4_to_r13(ctrl, mask);
+               if (ret)
+                       goto error;
        } else if ((insn & 0xf0) == 0x90 &&
                   (insn & 0x0d) != 0x0d)
                ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
        else if ((insn & 0xf0) == 0xa0) {
-               unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
-               int reg;
-
-               /* pop R4-R[4+bbb] */
-               for (reg = 4; reg <= 4 + (insn & 7); reg++)
-                       ctrl->vrs[reg] = *vsp++;
-               if (insn & 0x80)
-                       ctrl->vrs[14] = *vsp++;
-               ctrl->vrs[SP] = (unsigned long)vsp;
+               ret = unwind_exec_pop_r4_to_rN(ctrl, insn);
+               if (ret)
+                       goto error;
        } else if (insn == 0xb0) {
                if (ctrl->vrs[PC] == 0)
                        ctrl->vrs[PC] = ctrl->vrs[LR];
@@ -291,8 +355,6 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
                ctrl->entries = 0;
        } else if (insn == 0xb1) {
                unsigned long mask = unwind_get_byte(ctrl);
-               unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
-               int reg = 0;
 
                if (mask == 0 || mask & 0xf0) {
                        pr_warning("unwind: Spare encoding %04lx\n",
@@ -300,14 +362,9 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
                        return -URC_FAILURE;
                }
 
-               /* pop R0-R3 according to mask */
-               while (mask) {
-                       if (mask & 1)
-                               ctrl->vrs[reg] = *vsp++;
-                       mask >>= 1;
-                       reg++;
-               }
-               ctrl->vrs[SP] = (unsigned long)vsp;
+               ret = unwind_exec_pop_subset_r0_to_r3(ctrl, mask);
+               if (ret)
+                       goto error;
        } else if (insn == 0xb2) {
                unsigned long uleb128 = unwind_get_byte(ctrl);
 
@@ -320,7 +377,8 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
        pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
                 ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
 
-       return URC_OK;
+error:
+       return ret;
 }
 
 /*
@@ -329,13 +387,13 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
  */
 int unwind_frame(struct stackframe *frame)
 {
-       unsigned long high, low;
+       unsigned long low;
        const struct unwind_idx *idx;
        struct unwind_ctrl_block ctrl;
 
-       /* only go to a higher address on the stack */
+       /* store the highest address on the stack to avoid crossing it*/
        low = frame->sp;
-       high = ALIGN(low, THREAD_SIZE);
+       ctrl.sp_high = ALIGN(low, THREAD_SIZE);
 
        pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
                 frame->pc, frame->lr, frame->sp);
@@ -382,11 +440,16 @@ int unwind_frame(struct stackframe *frame)
                return -URC_FAILURE;
        }
 
+       ctrl.check_each_pop = 0;
+
        while (ctrl.entries > 0) {
-               int urc = unwind_exec_insn(&ctrl);
+               int urc;
+               if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs))
+                       ctrl.check_each_pop = 1;
+               urc = unwind_exec_insn(&ctrl);
                if (urc < 0)
                        return urc;
-               if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+               if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high)
                        return -URC_FAILURE;
        }
 
diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/kernel/uprobes-arm.c
new file mode 100644 (file)
index 0000000..d3b655f
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/stddef.h>
+#include <linux/wait.h>
+#include <linux/uprobes.h>
+#include <linux/module.h>
+
+#include "probes.h"
+#include "probes-arm.h"
+#include "uprobes.h"
+
+static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
+{
+       probes_opcode_t insn = __mem_to_opcode_arm(*pinsn);
+       probes_opcode_t temp;
+       probes_opcode_t mask;
+       int freereg;
+       u32 free = 0xffff;
+       u32 regs;
+
+       for (regs = oregs; regs; regs >>= 4, insn >>= 4) {
+               if ((regs & 0xf) == REG_TYPE_NONE)
+                       continue;
+
+               free &= ~(1 << (insn & 0xf));
+       }
+
+       /* No PC, no problem */
+       if (free & (1 << 15))
+               return 15;
+
+       if (!free)
+               return -1;
+
+       /*
+        * fls instead of ffs ensures that for "ldrd r0, r1, [pc]" we would
+        * pick LR instead of R1.
+        */
+       freereg = free = fls(free) - 1;
+
+       temp = __mem_to_opcode_arm(*pinsn);
+       insn = temp;
+       regs = oregs;
+       mask = 0xf;
+
+       for (; regs; regs >>= 4, mask <<= 4, free <<= 4, temp >>= 4) {
+               if ((regs & 0xf) == REG_TYPE_NONE)
+                       continue;
+
+               if ((temp & 0xf) != 15)
+                       continue;
+
+               insn &= ~mask;
+               insn |= free & mask;
+       }
+
+       *pinsn = __opcode_to_mem_arm(insn);
+       return freereg;
+}
+
+static void uprobe_set_pc(struct arch_uprobe *auprobe,
+                         struct arch_uprobe_task *autask,
+                         struct pt_regs *regs)
+{
+       u32 pcreg = auprobe->pcreg;
+
+       autask->backup = regs->uregs[pcreg];
+       regs->uregs[pcreg] = regs->ARM_pc + 8;
+}
+
+static void uprobe_unset_pc(struct arch_uprobe *auprobe,
+                           struct arch_uprobe_task *autask,
+                           struct pt_regs *regs)
+{
+       /* PC will be taken care of by common code */
+       regs->uregs[auprobe->pcreg] = autask->backup;
+}
+
+static void uprobe_aluwrite_pc(struct arch_uprobe *auprobe,
+                              struct arch_uprobe_task *autask,
+                              struct pt_regs *regs)
+{
+       u32 pcreg = auprobe->pcreg;
+
+       alu_write_pc(regs->uregs[pcreg], regs);
+       regs->uregs[pcreg] = autask->backup;
+}
+
+static void uprobe_write_pc(struct arch_uprobe *auprobe,
+                           struct arch_uprobe_task *autask,
+                           struct pt_regs *regs)
+{
+       u32 pcreg = auprobe->pcreg;
+
+       load_write_pc(regs->uregs[pcreg], regs);
+       regs->uregs[pcreg] = autask->backup;
+}
+
+enum probes_insn
+decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi,
+            const struct decode_header *d)
+{
+       struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
+                                                  asi);
+       struct decode_emulate *decode = (struct decode_emulate *) d;
+       u32 regs = decode->header.type_regs.bits >> DECODE_TYPE_BITS;
+       int reg;
+
+       reg = uprobes_substitute_pc(&auprobe->ixol[0], regs);
+       if (reg == 15)
+               return INSN_GOOD;
+
+       if (reg == -1)
+               return INSN_REJECTED;
+
+       auprobe->pcreg = reg;
+       auprobe->prehandler = uprobe_set_pc;
+       auprobe->posthandler = uprobe_unset_pc;
+
+       return INSN_GOOD;
+}
+
+enum probes_insn
+decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi,
+            const struct decode_header *d, bool alu)
+{
+       struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
+                                                  asi);
+       enum probes_insn ret = decode_pc_ro(insn, asi, d);
+
+       if (((insn >> 12) & 0xf) == 15)
+               auprobe->posthandler = alu ? uprobe_aluwrite_pc
+                                          : uprobe_write_pc;
+
+       return ret;
+}
+
+enum probes_insn
+decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
+                             struct arch_probes_insn *asi,
+                             const struct decode_header *d)
+{
+       return decode_wb_pc(insn, asi, d, true);
+}
+
+enum probes_insn
+decode_ldr(probes_opcode_t insn, struct arch_probes_insn *asi,
+          const struct decode_header *d)
+{
+       return decode_wb_pc(insn, asi, d, false);
+}
+
+enum probes_insn
+uprobe_decode_ldmstm(probes_opcode_t insn,
+                    struct arch_probes_insn *asi,
+                    const struct decode_header *d)
+{
+       struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
+                                                  asi);
+       unsigned reglist = insn & 0xffff;
+       int rn = (insn >> 16) & 0xf;
+       int lbit = insn & (1 << 20);
+       unsigned used = reglist | (1 << rn);
+
+       if (rn == 15)
+               return INSN_REJECTED;
+
+       if (!(used & (1 << 15)))
+               return INSN_GOOD;
+
+       if (used & (1 << 14))
+               return INSN_REJECTED;
+
+       /* Use LR instead of PC */
+       insn ^= 0xc000;
+
+       auprobe->pcreg = 14;
+       auprobe->ixol[0] = __opcode_to_mem_arm(insn);
+
+       auprobe->prehandler = uprobe_set_pc;
+       if (lbit)
+               auprobe->posthandler = uprobe_write_pc;
+       else
+               auprobe->posthandler = uprobe_unset_pc;
+
+       return INSN_GOOD;
+}
+
+const union decode_action uprobes_probes_actions[] = {
+       [PROBES_EMULATE_NONE] = {.handler = probes_simulate_nop},
+       [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
+       [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
+       [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
+       [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
+       [PROBES_MRS] = {.handler = simulate_mrs},
+       [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
+       [PROBES_CLZ] = {.handler = probes_simulate_nop},
+       [PROBES_SATURATING_ARITHMETIC] = {.handler = probes_simulate_nop},
+       [PROBES_MUL1] = {.handler = probes_simulate_nop},
+       [PROBES_MUL2] = {.handler = probes_simulate_nop},
+       [PROBES_SWP] = {.handler = probes_simulate_nop},
+       [PROBES_LDRSTRD] = {.decoder = decode_pc_ro},
+       [PROBES_LOAD_EXTRA] = {.decoder = decode_pc_ro},
+       [PROBES_LOAD] = {.decoder = decode_ldr},
+       [PROBES_STORE_EXTRA] = {.decoder = decode_pc_ro},
+       [PROBES_STORE] = {.decoder = decode_pc_ro},
+       [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
+       [PROBES_DATA_PROCESSING_REG] = {
+               .decoder = decode_rd12rn16rm0rs8_rwflags},
+       [PROBES_DATA_PROCESSING_IMM] = {
+               .decoder = decode_rd12rn16rm0rs8_rwflags},
+       [PROBES_MOV_HALFWORD] = {.handler = probes_simulate_nop},
+       [PROBES_SEV] = {.handler = probes_simulate_nop},
+       [PROBES_WFE] = {.handler = probes_simulate_nop},
+       [PROBES_SATURATE] = {.handler = probes_simulate_nop},
+       [PROBES_REV] = {.handler = probes_simulate_nop},
+       [PROBES_MMI] = {.handler = probes_simulate_nop},
+       [PROBES_PACK] = {.handler = probes_simulate_nop},
+       [PROBES_EXTEND] = {.handler = probes_simulate_nop},
+       [PROBES_EXTEND_ADD] = {.handler = probes_simulate_nop},
+       [PROBES_MUL_ADD_LONG] = {.handler = probes_simulate_nop},
+       [PROBES_MUL_ADD] = {.handler = probes_simulate_nop},
+       [PROBES_BITFIELD] = {.handler = probes_simulate_nop},
+       [PROBES_BRANCH] = {.handler = simulate_bbl},
+       [PROBES_LDMSTM] = {.decoder = uprobe_decode_ldmstm}
+};
diff --git a/arch/arm/kernel/uprobes.c b/arch/arm/kernel/uprobes.c
new file mode 100644 (file)
index 0000000..f9bacee
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can 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/stddef.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/sched.h>
+#include <linux/uprobes.h>
+#include <linux/notifier.h>
+
+#include <asm/opcodes.h>
+#include <asm/traps.h>
+
+#include "probes.h"
+#include "probes-arm.h"
+#include "uprobes.h"
+
+#define UPROBE_TRAP_NR UINT_MAX
+
+bool is_swbp_insn(uprobe_opcode_t *insn)
+{
+       return (__mem_to_opcode_arm(*insn) & 0x0fffffff) ==
+               (UPROBE_SWBP_ARM_INSN & 0x0fffffff);
+}
+
+int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
+            unsigned long vaddr)
+{
+       return uprobe_write_opcode(mm, vaddr,
+                  __opcode_to_mem_arm(auprobe->bpinsn));
+}
+
+bool arch_uprobe_ignore(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+       if (!auprobe->asi.insn_check_cc(regs->ARM_cpsr)) {
+               regs->ARM_pc += 4;
+               return true;
+       }
+
+       return false;
+}
+
+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+       probes_opcode_t opcode;
+
+       if (!auprobe->simulate)
+               return false;
+
+       opcode = __mem_to_opcode_arm(*(unsigned int *) auprobe->insn);
+
+       auprobe->asi.insn_singlestep(opcode, &auprobe->asi, regs);
+
+       return true;
+}
+
+unsigned long
+arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,
+                                 struct pt_regs *regs)
+{
+       unsigned long orig_ret_vaddr;
+
+       orig_ret_vaddr = regs->ARM_lr;
+       /* Replace the return addr with trampoline addr */
+       regs->ARM_lr = trampoline_vaddr;
+       return orig_ret_vaddr;
+}
+
+int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
+                            unsigned long addr)
+{
+       unsigned int insn;
+       unsigned int bpinsn;
+       enum probes_insn ret;
+
+       /* Thumb not yet support */
+       if (addr & 0x3)
+               return -EINVAL;
+
+       insn = __mem_to_opcode_arm(*(unsigned int *)auprobe->insn);
+       auprobe->ixol[0] = __opcode_to_mem_arm(insn);
+       auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN);
+
+       ret = arm_probes_decode_insn(insn, &auprobe->asi, false,
+                                    uprobes_probes_actions);
+       switch (ret) {
+       case INSN_REJECTED:
+               return -EINVAL;
+
+       case INSN_GOOD_NO_SLOT:
+               auprobe->simulate = true;
+               break;
+
+       case INSN_GOOD:
+       default:
+               break;
+       }
+
+       bpinsn = UPROBE_SWBP_ARM_INSN & 0x0fffffff;
+       if (insn >= 0xe0000000)
+               bpinsn |= 0xe0000000;  /* Unconditional instruction */
+       else
+               bpinsn |= insn & 0xf0000000;  /* Copy condition from insn */
+
+       auprobe->bpinsn = bpinsn;
+
+       return 0;
+}
+
+int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+       struct uprobe_task *utask = current->utask;
+
+       if (auprobe->prehandler)
+               auprobe->prehandler(auprobe, &utask->autask, regs);
+
+       utask->autask.saved_trap_no = current->thread.trap_no;
+       current->thread.trap_no = UPROBE_TRAP_NR;
+       regs->ARM_pc = utask->xol_vaddr;
+
+       return 0;
+}
+
+int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+       struct uprobe_task *utask = current->utask;
+
+       WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NR);
+
+       current->thread.trap_no = utask->autask.saved_trap_no;
+       regs->ARM_pc = utask->vaddr + 4;
+
+       if (auprobe->posthandler)
+               auprobe->posthandler(auprobe, &utask->autask, regs);
+
+       return 0;
+}
+
+bool arch_uprobe_xol_was_trapped(struct task_struct *t)
+{
+       if (t->thread.trap_no != UPROBE_TRAP_NR)
+               return true;
+
+       return false;
+}
+
+void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+       struct uprobe_task *utask = current->utask;
+
+       current->thread.trap_no = utask->autask.saved_trap_no;
+       instruction_pointer_set(regs, utask->vaddr);
+}
+
+int arch_uprobe_exception_notify(struct notifier_block *self,
+                                unsigned long val, void *data)
+{
+       return NOTIFY_DONE;
+}
+
+static int uprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       instr &= 0x0fffffff;
+       if (instr == (UPROBE_SWBP_ARM_INSN & 0x0fffffff))
+               uprobe_pre_sstep_notifier(regs);
+       else if (instr == (UPROBE_SS_ARM_INSN & 0x0fffffff))
+               uprobe_post_sstep_notifier(regs);
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
+{
+       return instruction_pointer(regs);
+}
+
+static struct undef_hook uprobes_arm_break_hook = {
+       .instr_mask     = 0x0fffffff,
+       .instr_val      = (UPROBE_SWBP_ARM_INSN & 0x0fffffff),
+       .cpsr_mask      = MODE_MASK,
+       .cpsr_val       = USR_MODE,
+       .fn             = uprobe_trap_handler,
+};
+
+static struct undef_hook uprobes_arm_ss_hook = {
+       .instr_mask     = 0x0fffffff,
+       .instr_val      = (UPROBE_SS_ARM_INSN & 0x0fffffff),
+       .cpsr_mask      = MODE_MASK,
+       .cpsr_val       = USR_MODE,
+       .fn             = uprobe_trap_handler,
+};
+
+static int arch_uprobes_init(void)
+{
+       register_undef_hook(&uprobes_arm_break_hook);
+       register_undef_hook(&uprobes_arm_ss_hook);
+
+       return 0;
+}
+device_initcall(arch_uprobes_init);
diff --git a/arch/arm/kernel/uprobes.h b/arch/arm/kernel/uprobes.h
new file mode 100644 (file)
index 0000000..1d0c12d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
+ *
+ * This program is free software; you can 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 __ARM_KERNEL_UPROBES_H
+#define __ARM_KERNEL_UPROBES_H
+
+enum probes_insn uprobe_decode_ldmstm(probes_opcode_t insn,
+                                     struct arch_probes_insn *asi,
+                                     const struct decode_header *d);
+
+enum probes_insn decode_ldr(probes_opcode_t insn,
+                           struct arch_probes_insn *asi,
+                           const struct decode_header *d);
+
+enum probes_insn
+decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
+                             struct arch_probes_insn *asi,
+                             const struct decode_header *d);
+
+enum probes_insn
+decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi,
+            const struct decode_header *d, bool alu);
+
+enum probes_insn
+decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi,
+            const struct decode_header *d);
+
+extern const union decode_action uprobes_probes_actions[];
+
+#endif
index bd18bb8b2770ced6a65e5b3ad50dd79963d49c3b..f0e50a0f3a65b1c0476ec18db3ff914594c1061f 100644 (file)
@@ -1051,21 +1051,26 @@ int kvm_arch_init(void *opaque)
                }
        }
 
+       cpu_notifier_register_begin();
+
        err = init_hyp_mode();
        if (err)
                goto out_err;
 
-       err = register_cpu_notifier(&hyp_init_cpu_nb);
+       err = __register_cpu_notifier(&hyp_init_cpu_nb);
        if (err) {
                kvm_err("Cannot register HYP init CPU notifier (%d)\n", err);
                goto out_err;
        }
 
+       cpu_notifier_register_done();
+
        hyp_cpu_pm_init();
 
        kvm_coproc_table_init();
        return 0;
 out_err:
+       cpu_notifier_register_done();
        return err;
 }
 
index 52886b89706caf466b1cc6c6586db70a7d9d962e..9f12ed1eea860fccf4b6c301277827cb376c2c41 100644 (file)
@@ -37,6 +37,11 @@ UNWIND(      .fnstart        )
        add     r1, r1, r0, lsl #2      @ Get word offset
        mov     r3, r2, lsl r3          @ create mask
        smp_dmb
+#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+       .arch_extension mp
+       ALT_SMP(W(pldw) [r1])
+       ALT_UP(W(nop))
+#endif
 1:     ldrex   r2, [r1]
        ands    r0, r2, r3              @ save old value of bit
        \instr  r2, r2, r3              @ toggle bit
index 805e3f8fb00786f00f62820c57b02852ad043aaa..3bc8eb811a732cda131927a5c009bf7d34e2b987 100644 (file)
 
 12:    PLD(    pld     [r1, #124]              )
 13:            ldr4w   r1, r4, r5, r6, r7, abort=19f
-               mov     r3, lr, pull #\pull
+               mov     r3, lr, lspull #\pull
                subs    r2, r2, #32
                ldr4w   r1, r8, r9, ip, lr, abort=19f
-               orr     r3, r3, r4, push #\push
-               mov     r4, r4, pull #\pull
-               orr     r4, r4, r5, push #\push
-               mov     r5, r5, pull #\pull
-               orr     r5, r5, r6, push #\push
-               mov     r6, r6, pull #\pull
-               orr     r6, r6, r7, push #\push
-               mov     r7, r7, pull #\pull
-               orr     r7, r7, r8, push #\push
-               mov     r8, r8, pull #\pull
-               orr     r8, r8, r9, push #\push
-               mov     r9, r9, pull #\pull
-               orr     r9, r9, ip, push #\push
-               mov     ip, ip, pull #\pull
-               orr     ip, ip, lr, push #\push
+               orr     r3, r3, r4, lspush #\push
+               mov     r4, r4, lspull #\pull
+               orr     r4, r4, r5, lspush #\push
+               mov     r5, r5, lspull #\pull
+               orr     r5, r5, r6, lspush #\push
+               mov     r6, r6, lspull #\pull
+               orr     r6, r6, r7, lspush #\push
+               mov     r7, r7, lspull #\pull
+               orr     r7, r7, r8, lspush #\push
+               mov     r8, r8, lspull #\pull
+               orr     r8, r8, r9, lspush #\push
+               mov     r9, r9, lspull #\pull
+               orr     r9, r9, ip, lspush #\push
+               mov     ip, ip, lspull #\pull
+               orr     ip, ip, lr, lspush #\push
                str8w   r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
                bge     12b
        PLD(    cmn     r2, #96                 )
 14:            ands    ip, r2, #28
                beq     16f
 
-15:            mov     r3, lr, pull #\pull
+15:            mov     r3, lr, lspull #\pull
                ldr1w   r1, lr, abort=21f
                subs    ip, ip, #4
-               orr     r3, r3, lr, push #\push
+               orr     r3, r3, lr, lspush #\push
                str1w   r0, r3, abort=21f
                bgt     15b
        CALGN(  cmp     r2, #0                  )
index d620a5f22a09d4a683b884d9d6836171ded4d5f1..d6e742d240075a05c35902d21f86979b054fb928 100644 (file)
@@ -141,7 +141,7 @@ FN_ENTRY
                tst     len, #2
                mov     r5, r4, get_byte_0
                beq     .Lexit
-               adcs    sum, sum, r4, push #16
+               adcs    sum, sum, r4, lspush #16
                strb    r5, [dst], #1
                mov     r5, r4, get_byte_1
                strb    r5, [dst], #1
@@ -171,23 +171,23 @@ FN_ENTRY
                cmp     ip, #2
                beq     .Lsrc2_aligned
                bhi     .Lsrc3_aligned
-               mov     r4, r5, pull #8         @ C = 0
+               mov     r4, r5, lspull #8               @ C = 0
                bics    ip, len, #15
                beq     2f
 1:             load4l  r5, r6, r7, r8
-               orr     r4, r4, r5, push #24
-               mov     r5, r5, pull #8
-               orr     r5, r5, r6, push #24
-               mov     r6, r6, pull #8
-               orr     r6, r6, r7, push #24
-               mov     r7, r7, pull #8
-               orr     r7, r7, r8, push #24
+               orr     r4, r4, r5, lspush #24
+               mov     r5, r5, lspull #8
+               orr     r5, r5, r6, lspush #24
+               mov     r6, r6, lspull #8
+               orr     r6, r6, r7, lspush #24
+               mov     r7, r7, lspull #8
+               orr     r7, r7, r8, lspush #24
                stmia   dst!, {r4, r5, r6, r7}
                adcs    sum, sum, r4
                adcs    sum, sum, r5
                adcs    sum, sum, r6
                adcs    sum, sum, r7
-               mov     r4, r8, pull #8
+               mov     r4, r8, lspull #8
                sub     ip, ip, #16
                teq     ip, #0
                bne     1b
@@ -196,50 +196,50 @@ FN_ENTRY
                tst     ip, #8
                beq     3f
                load2l  r5, r6
-               orr     r4, r4, r5, push #24
-               mov     r5, r5, pull #8
-               orr     r5, r5, r6, push #24
+               orr     r4, r4, r5, lspush #24
+               mov     r5, r5, lspull #8
+               orr     r5, r5, r6, lspush #24
                stmia   dst!, {r4, r5}
                adcs    sum, sum, r4
                adcs    sum, sum, r5
-               mov     r4, r6, pull #8
+               mov     r4, r6, lspull #8
                tst     ip, #4
                beq     4f
 3:             load1l  r5
-               orr     r4, r4, r5, push #24
+               orr     r4, r4, r5, lspush #24
                str     r4, [dst], #4
                adcs    sum, sum, r4
-               mov     r4, r5, pull #8
+               mov     r4, r5, lspull #8
 4:             ands    len, len, #3
                beq     .Ldone
                mov     r5, r4, get_byte_0
                tst     len, #2
                beq     .Lexit
-               adcs    sum, sum, r4, push #16
+               adcs    sum, sum, r4, lspush #16
                strb    r5, [dst], #1
                mov     r5, r4, get_byte_1
                strb    r5, [dst], #1
                mov     r5, r4, get_byte_2
                b       .Lexit
 
-.Lsrc2_aligned:        mov     r4, r5, pull #16
+.Lsrc2_aligned:        mov     r4, r5, lspull #16
                adds    sum, sum, #0
                bics    ip, len, #15
                beq     2f
 1:             load4l  r5, r6, r7, r8
-               orr     r4, r4, r5, push #16
-               mov     r5, r5, pull #16
-               orr     r5, r5, r6, push #16
-               mov     r6, r6, pull #16
-               orr     r6, r6, r7, push #16
-               mov     r7, r7, pull #16
-               orr     r7, r7, r8, push #16
+               orr     r4, r4, r5, lspush #16
+               mov     r5, r5, lspull #16
+               orr     r5, r5, r6, lspush #16
+               mov     r6, r6, lspull #16
+               orr     r6, r6, r7, lspush #16
+               mov     r7, r7, lspull #16
+               orr     r7, r7, r8, lspush #16
                stmia   dst!, {r4, r5, r6, r7}
                adcs    sum, sum, r4
                adcs    sum, sum, r5
                adcs    sum, sum, r6
                adcs    sum, sum, r7
-               mov     r4, r8, pull #16
+               mov     r4, r8, lspull #16
                sub     ip, ip, #16
                teq     ip, #0
                bne     1b
@@ -248,20 +248,20 @@ FN_ENTRY
                tst     ip, #8
                beq     3f
                load2l  r5, r6
-               orr     r4, r4, r5, push #16
-               mov     r5, r5, pull #16
-               orr     r5, r5, r6, push #16
+               orr     r4, r4, r5, lspush #16
+               mov     r5, r5, lspull #16
+               orr     r5, r5, r6, lspush #16
                stmia   dst!, {r4, r5}
                adcs    sum, sum, r4
                adcs    sum, sum, r5
-               mov     r4, r6, pull #16
+               mov     r4, r6, lspull #16
                tst     ip, #4
                beq     4f
 3:             load1l  r5
-               orr     r4, r4, r5, push #16
+               orr     r4, r4, r5, lspush #16
                str     r4, [dst], #4
                adcs    sum, sum, r4
-               mov     r4, r5, pull #16
+               mov     r4, r5, lspull #16
 4:             ands    len, len, #3
                beq     .Ldone
                mov     r5, r4, get_byte_0
@@ -276,24 +276,24 @@ FN_ENTRY
                load1b  r5
                b       .Lexit
 
-.Lsrc3_aligned:        mov     r4, r5, pull #24
+.Lsrc3_aligned:        mov     r4, r5, lspull #24
                adds    sum, sum, #0
                bics    ip, len, #15
                beq     2f
 1:             load4l  r5, r6, r7, r8
-               orr     r4, r4, r5, push #8
-               mov     r5, r5, pull #24
-               orr     r5, r5, r6, push #8
-               mov     r6, r6, pull #24
-               orr     r6, r6, r7, push #8
-               mov     r7, r7, pull #24
-               orr     r7, r7, r8, push #8
+               orr     r4, r4, r5, lspush #8
+               mov     r5, r5, lspull #24
+               orr     r5, r5, r6, lspush #8
+               mov     r6, r6, lspull #24
+               orr     r6, r6, r7, lspush #8
+               mov     r7, r7, lspull #24
+               orr     r7, r7, r8, lspush #8
                stmia   dst!, {r4, r5, r6, r7}
                adcs    sum, sum, r4
                adcs    sum, sum, r5
                adcs    sum, sum, r6
                adcs    sum, sum, r7
-               mov     r4, r8, pull #24
+               mov     r4, r8, lspull #24
                sub     ip, ip, #16
                teq     ip, #0
                bne     1b
@@ -302,20 +302,20 @@ FN_ENTRY
                tst     ip, #8
                beq     3f
                load2l  r5, r6
-               orr     r4, r4, r5, push #8
-               mov     r5, r5, pull #24
-               orr     r5, r5, r6, push #8
+               orr     r4, r4, r5, lspush #8
+               mov     r5, r5, lspull #24
+               orr     r5, r5, r6, lspush #8
                stmia   dst!, {r4, r5}
                adcs    sum, sum, r4
                adcs    sum, sum, r5
-               mov     r4, r6, pull #24
+               mov     r4, r6, lspull #24
                tst     ip, #4
                beq     4f
 3:             load1l  r5
-               orr     r4, r4, r5, push #8
+               orr     r4, r4, r5, lspush #8
                str     r4, [dst], #4
                adcs    sum, sum, r4
-               mov     r4, r5, pull #24
+               mov     r4, r5, lspull #24
 4:             ands    len, len, #3
                beq     .Ldone
                mov     r5, r4, get_byte_0
@@ -326,7 +326,7 @@ FN_ENTRY
                load1l  r4
                mov     r5, r4, get_byte_0
                strb    r5, [dst], #1
-               adcs    sum, sum, r4, push #24
+               adcs    sum, sum, r4, lspush #24
                mov     r5, r4, get_byte_1
                b       .Lexit
 FN_EXIT
index 5fb97e7f9f4bd9a8cbc2e40ee6ebaea3d273e732..7a7430950c7974621eccc31e65e08294a1492d1e 100644 (file)
@@ -47,25 +47,25 @@ ENTRY(__raw_readsl)
                strb    ip, [r1], #1
 
 4:             subs    r2, r2, #1
-               mov     ip, r3, pull #24
+               mov     ip, r3, lspull #24
                ldrne   r3, [r0]
-               orrne   ip, ip, r3, push #8
+               orrne   ip, ip, r3, lspush #8
                strne   ip, [r1], #4
                bne     4b
                b       8f
 
 5:             subs    r2, r2, #1
-               mov     ip, r3, pull #16
+               mov     ip, r3, lspull #16
                ldrne   r3, [r0]
-               orrne   ip, ip, r3, push #16
+               orrne   ip, ip, r3, lspush #16
                strne   ip, [r1], #4
                bne     5b
                b       7f
 
 6:             subs    r2, r2, #1
-               mov     ip, r3, pull #8
+               mov     ip, r3, lspull #8
                ldrne   r3, [r0]
-               orrne   ip, ip, r3, push #24
+               orrne   ip, ip, r3, lspush #24
                strne   ip, [r1], #4
                bne     6b
 
index 8d3b7813725cde5b877a896f4ad4780fff663781..d0d104a0dd116890db92e91e75bd6ef32a2d00e9 100644 (file)
@@ -41,26 +41,26 @@ ENTRY(__raw_writesl)
                blt     5f
                bgt     6f
 
-4:             mov     ip, r3, pull #16
+4:             mov     ip, r3, lspull #16
                ldr     r3, [r1], #4
                subs    r2, r2, #1
-               orr     ip, ip, r3, push #16
+               orr     ip, ip, r3, lspush #16
                str     ip, [r0]
                bne     4b
                mov     pc, lr
 
-5:             mov     ip, r3, pull #8
+5:             mov     ip, r3, lspull #8
                ldr     r3, [r1], #4
                subs    r2, r2, #1
-               orr     ip, ip, r3, push #24
+               orr     ip, ip, r3, lspush #24
                str     ip, [r0]
                bne     5b
                mov     pc, lr
 
-6:             mov     ip, r3, pull #24
+6:             mov     ip, r3, lspull #24
                ldr     r3, [r1], #4
                subs    r2, r2, #1
-               orr     ip, ip, r3, push #8
+               orr     ip, ip, r3, lspush #8
                str     ip, [r0]
                bne     6b
                mov     pc, lr
index 938fc14f962d35693cc96c9d3f8899ae1b5bd193..d1fc0c0c342cff0a13e6d07ae8b6af76f609ffdc 100644 (file)
@@ -147,24 +147,24 @@ ENTRY(memmove)
 
 12:    PLD(    pld     [r1, #-128]             )
 13:            ldmdb   r1!, {r7, r8, r9, ip}
-               mov     lr, r3, push #\push
+               mov     lr, r3, lspush #\push
                subs    r2, r2, #32
                ldmdb   r1!, {r3, r4, r5, r6}
-               orr     lr, lr, ip, pull #\pull
-               mov     ip, ip, push #\push
-               orr     ip, ip, r9, pull #\pull
-               mov     r9, r9, push #\push
-               orr     r9, r9, r8, pull #\pull
-               mov     r8, r8, push #\push
-               orr     r8, r8, r7, pull #\pull
-               mov     r7, r7, push #\push
-               orr     r7, r7, r6, pull #\pull
-               mov     r6, r6, push #\push
-               orr     r6, r6, r5, pull #\pull
-               mov     r5, r5, push #\push
-               orr     r5, r5, r4, pull #\pull
-               mov     r4, r4, push #\push
-               orr     r4, r4, r3, pull #\pull
+               orr     lr, lr, ip, lspull #\pull
+               mov     ip, ip, lspush #\push
+               orr     ip, ip, r9, lspull #\pull
+               mov     r9, r9, lspush #\push
+               orr     r9, r9, r8, lspull #\pull
+               mov     r8, r8, lspush #\push
+               orr     r8, r8, r7, lspull #\pull
+               mov     r7, r7, lspush #\push
+               orr     r7, r7, r6, lspull #\pull
+               mov     r6, r6, lspush #\push
+               orr     r6, r6, r5, lspull #\pull
+               mov     r5, r5, lspush #\push
+               orr     r5, r5, r4, lspull #\pull
+               mov     r4, r4, lspush #\push
+               orr     r4, r4, r3, lspull #\pull
                stmdb   r0!, {r4 - r9, ip, lr}
                bge     12b
        PLD(    cmn     r2, #96                 )
@@ -175,10 +175,10 @@ ENTRY(memmove)
 14:            ands    ip, r2, #28
                beq     16f
 
-15:            mov     lr, r3, push #\push
+15:            mov     lr, r3, lspush #\push
                ldr     r3, [r1, #-4]!
                subs    ip, ip, #4
-               orr     lr, lr, r3, pull #\pull
+               orr     lr, lr, r3, lspull #\pull
                str     lr, [r0, #-4]!
                bgt     15b
        CALGN(  cmp     r2, #0                  )
index 5c908b1cb8ed5db3eeabfb89f7f659f99d2d6f76..e50520904b76416cc97274465efa445170fe3fe1 100644 (file)
@@ -117,9 +117,9 @@ USER(       TUSER(  strgtb) r3, [r0], #1)                   @ May fault
 .Lc2u_1fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lc2u_1nowords
-               mov     r3, r7, pull #8
+               mov     r3, r7, lspull #8
                ldr     r7, [r1], #4
-               orr     r3, r3, r7, push #24
+               orr     r3, r3, r7, lspush #24
 USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
@@ -131,30 +131,30 @@ USER(     TUSER(  str)    r3, [r0], #4)                   @ May fault
                subs    ip, ip, #16
                blt     .Lc2u_1rem8lp
 
-.Lc2u_1cpy8lp: mov     r3, r7, pull #8
+.Lc2u_1cpy8lp: mov     r3, r7, lspull #8
                ldmia   r1!, {r4 - r7}
                subs    ip, ip, #16
-               orr     r3, r3, r4, push #24
-               mov     r4, r4, pull #8
-               orr     r4, r4, r5, push #24
-               mov     r5, r5, pull #8
-               orr     r5, r5, r6, push #24
-               mov     r6, r6, pull #8
-               orr     r6, r6, r7, push #24
+               orr     r3, r3, r4, lspush #24
+               mov     r4, r4, lspull #8
+               orr     r4, r4, r5, lspush #24
+               mov     r5, r5, lspull #8
+               orr     r5, r5, r6, lspush #24
+               mov     r6, r6, lspull #8
+               orr     r6, r6, r7, lspush #24
                stmia   r0!, {r3 - r6}                  @ Shouldnt fault
                bpl     .Lc2u_1cpy8lp
 
 .Lc2u_1rem8lp: tst     ip, #8
-               movne   r3, r7, pull #8
+               movne   r3, r7, lspull #8
                ldmneia r1!, {r4, r7}
-               orrne   r3, r3, r4, push #24
-               movne   r4, r4, pull #8
-               orrne   r4, r4, r7, push #24
+               orrne   r3, r3, r4, lspush #24
+               movne   r4, r4, lspull #8
+               orrne   r4, r4, r7, lspush #24
                stmneia r0!, {r3 - r4}                  @ Shouldnt fault
                tst     ip, #4
-               movne   r3, r7, pull #8
+               movne   r3, r7, lspull #8
                ldrne   r7, [r1], #4
-               orrne   r3, r3, r7, push #24
+               orrne   r3, r3, r7, lspush #24
        TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_1fupi
@@ -172,9 +172,9 @@ USER(       TUSER(  strgtb) r3, [r0], #1)                   @ May fault
 .Lc2u_2fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lc2u_2nowords
-               mov     r3, r7, pull #16
+               mov     r3, r7, lspull #16
                ldr     r7, [r1], #4
-               orr     r3, r3, r7, push #16
+               orr     r3, r3, r7, lspush #16
 USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
@@ -186,30 +186,30 @@ USER(     TUSER(  str)    r3, [r0], #4)                   @ May fault
                subs    ip, ip, #16
                blt     .Lc2u_2rem8lp
 
-.Lc2u_2cpy8lp: mov     r3, r7, pull #16
+.Lc2u_2cpy8lp: mov     r3, r7, lspull #16
                ldmia   r1!, {r4 - r7}
                subs    ip, ip, #16
-               orr     r3, r3, r4, push #16
-               mov     r4, r4, pull #16
-               orr     r4, r4, r5, push #16
-               mov     r5, r5, pull #16
-               orr     r5, r5, r6, push #16
-               mov     r6, r6, pull #16
-               orr     r6, r6, r7, push #16
+               orr     r3, r3, r4, lspush #16
+               mov     r4, r4, lspull #16
+               orr     r4, r4, r5, lspush #16
+               mov     r5, r5, lspull #16
+               orr     r5, r5, r6, lspush #16
+               mov     r6, r6, lspull #16
+               orr     r6, r6, r7, lspush #16
                stmia   r0!, {r3 - r6}                  @ Shouldnt fault
                bpl     .Lc2u_2cpy8lp
 
 .Lc2u_2rem8lp: tst     ip, #8
-               movne   r3, r7, pull #16
+               movne   r3, r7, lspull #16
                ldmneia r1!, {r4, r7}
-               orrne   r3, r3, r4, push #16
-               movne   r4, r4, pull #16
-               orrne   r4, r4, r7, push #16
+               orrne   r3, r3, r4, lspush #16
+               movne   r4, r4, lspull #16
+               orrne   r4, r4, r7, lspush #16
                stmneia r0!, {r3 - r4}                  @ Shouldnt fault
                tst     ip, #4
-               movne   r3, r7, pull #16
+               movne   r3, r7, lspull #16
                ldrne   r7, [r1], #4
-               orrne   r3, r3, r7, push #16
+               orrne   r3, r3, r7, lspush #16
        TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_2fupi
@@ -227,9 +227,9 @@ USER(       TUSER(  strgtb) r3, [r0], #1)                   @ May fault
 .Lc2u_3fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lc2u_3nowords
-               mov     r3, r7, pull #24
+               mov     r3, r7, lspull #24
                ldr     r7, [r1], #4
-               orr     r3, r3, r7, push #8
+               orr     r3, r3, r7, lspush #8
 USER(  TUSER(  str)    r3, [r0], #4)                   @ May fault
                mov     ip, r0, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
@@ -241,30 +241,30 @@ USER(     TUSER(  str)    r3, [r0], #4)                   @ May fault
                subs    ip, ip, #16
                blt     .Lc2u_3rem8lp
 
-.Lc2u_3cpy8lp: mov     r3, r7, pull #24
+.Lc2u_3cpy8lp: mov     r3, r7, lspull #24
                ldmia   r1!, {r4 - r7}
                subs    ip, ip, #16
-               orr     r3, r3, r4, push #8
-               mov     r4, r4, pull #24
-               orr     r4, r4, r5, push #8
-               mov     r5, r5, pull #24
-               orr     r5, r5, r6, push #8
-               mov     r6, r6, pull #24
-               orr     r6, r6, r7, push #8
+               orr     r3, r3, r4, lspush #8
+               mov     r4, r4, lspull #24
+               orr     r4, r4, r5, lspush #8
+               mov     r5, r5, lspull #24
+               orr     r5, r5, r6, lspush #8
+               mov     r6, r6, lspull #24
+               orr     r6, r6, r7, lspush #8
                stmia   r0!, {r3 - r6}                  @ Shouldnt fault
                bpl     .Lc2u_3cpy8lp
 
 .Lc2u_3rem8lp: tst     ip, #8
-               movne   r3, r7, pull #24
+               movne   r3, r7, lspull #24
                ldmneia r1!, {r4, r7}
-               orrne   r3, r3, r4, push #8
-               movne   r4, r4, pull #24
-               orrne   r4, r4, r7, push #8
+               orrne   r3, r3, r4, lspush #8
+               movne   r4, r4, lspull #24
+               orrne   r4, r4, r7, lspush #8
                stmneia r0!, {r3 - r4}                  @ Shouldnt fault
                tst     ip, #4
-               movne   r3, r7, pull #24
+               movne   r3, r7, lspull #24
                ldrne   r7, [r1], #4
-               orrne   r3, r3, r7, push #8
+               orrne   r3, r3, r7, lspush #8
        TUSER(  strne) r3, [r0], #4                     @ Shouldnt fault
                ands    ip, ip, #3
                beq     .Lc2u_3fupi
@@ -382,9 +382,9 @@ USER(       TUSER(  ldr)    r7, [r1], #4)                   @ May fault
 .Lcfu_1fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lcfu_1nowords
-               mov     r3, r7, pull #8
+               mov     r3, r7, lspull #8
 USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
-               orr     r3, r3, r7, push #24
+               orr     r3, r3, r7, lspush #24
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
@@ -396,30 +396,30 @@ USER(     TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                subs    ip, ip, #16
                blt     .Lcfu_1rem8lp
 
-.Lcfu_1cpy8lp: mov     r3, r7, pull #8
+.Lcfu_1cpy8lp: mov     r3, r7, lspull #8
                ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
                subs    ip, ip, #16
-               orr     r3, r3, r4, push #24
-               mov     r4, r4, pull #8
-               orr     r4, r4, r5, push #24
-               mov     r5, r5, pull #8
-               orr     r5, r5, r6, push #24
-               mov     r6, r6, pull #8
-               orr     r6, r6, r7, push #24
+               orr     r3, r3, r4, lspush #24
+               mov     r4, r4, lspull #8
+               orr     r4, r4, r5, lspush #24
+               mov     r5, r5, lspull #8
+               orr     r5, r5, r6, lspush #24
+               mov     r6, r6, lspull #8
+               orr     r6, r6, r7, lspush #24
                stmia   r0!, {r3 - r6}
                bpl     .Lcfu_1cpy8lp
 
 .Lcfu_1rem8lp: tst     ip, #8
-               movne   r3, r7, pull #8
+               movne   r3, r7, lspull #8
                ldmneia r1!, {r4, r7}                   @ Shouldnt fault
-               orrne   r3, r3, r4, push #24
-               movne   r4, r4, pull #8
-               orrne   r4, r4, r7, push #24
+               orrne   r3, r3, r4, lspush #24
+               movne   r4, r4, lspull #8
+               orrne   r4, r4, r7, lspush #24
                stmneia r0!, {r3 - r4}
                tst     ip, #4
-               movne   r3, r7, pull #8
+               movne   r3, r7, lspull #8
 USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
-               orrne   r3, r3, r7, push #24
+               orrne   r3, r3, r7, lspush #24
                strne   r3, [r0], #4
                ands    ip, ip, #3
                beq     .Lcfu_1fupi
@@ -437,9 +437,9 @@ USER(       TUSER(  ldrne) r7, [r1], #4)                    @ May fault
 .Lcfu_2fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lcfu_2nowords
-               mov     r3, r7, pull #16
+               mov     r3, r7, lspull #16
 USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
-               orr     r3, r3, r7, push #16
+               orr     r3, r3, r7, lspush #16
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
@@ -452,30 +452,30 @@ USER(     TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                blt     .Lcfu_2rem8lp
 
 
-.Lcfu_2cpy8lp: mov     r3, r7, pull #16
+.Lcfu_2cpy8lp: mov     r3, r7, lspull #16
                ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
                subs    ip, ip, #16
-               orr     r3, r3, r4, push #16
-               mov     r4, r4, pull #16
-               orr     r4, r4, r5, push #16
-               mov     r5, r5, pull #16
-               orr     r5, r5, r6, push #16
-               mov     r6, r6, pull #16
-               orr     r6, r6, r7, push #16
+               orr     r3, r3, r4, lspush #16
+               mov     r4, r4, lspull #16
+               orr     r4, r4, r5, lspush #16
+               mov     r5, r5, lspull #16
+               orr     r5, r5, r6, lspush #16
+               mov     r6, r6, lspull #16
+               orr     r6, r6, r7, lspush #16
                stmia   r0!, {r3 - r6}
                bpl     .Lcfu_2cpy8lp
 
 .Lcfu_2rem8lp: tst     ip, #8
-               movne   r3, r7, pull #16
+               movne   r3, r7, lspull #16
                ldmneia r1!, {r4, r7}                   @ Shouldnt fault
-               orrne   r3, r3, r4, push #16
-               movne   r4, r4, pull #16
-               orrne   r4, r4, r7, push #16
+               orrne   r3, r3, r4, lspush #16
+               movne   r4, r4, lspull #16
+               orrne   r4, r4, r7, lspush #16
                stmneia r0!, {r3 - r4}
                tst     ip, #4
-               movne   r3, r7, pull #16
+               movne   r3, r7, lspull #16
 USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
-               orrne   r3, r3, r7, push #16
+               orrne   r3, r3, r7, lspush #16
                strne   r3, [r0], #4
                ands    ip, ip, #3
                beq     .Lcfu_2fupi
@@ -493,9 +493,9 @@ USER(       TUSER(  ldrgtb) r3, [r1], #0)                   @ May fault
 .Lcfu_3fupi:   subs    r2, r2, #4
                addmi   ip, r2, #4
                bmi     .Lcfu_3nowords
-               mov     r3, r7, pull #24
+               mov     r3, r7, lspull #24
 USER(  TUSER(  ldr)    r7, [r1], #4)                   @ May fault
-               orr     r3, r3, r7, push #8
+               orr     r3, r3, r7, lspush #8
                str     r3, [r0], #4
                mov     ip, r1, lsl #32 - PAGE_SHIFT
                rsb     ip, ip, #0
@@ -507,30 +507,30 @@ USER(     TUSER(  ldr)    r7, [r1], #4)                   @ May fault
                subs    ip, ip, #16
                blt     .Lcfu_3rem8lp
 
-.Lcfu_3cpy8lp: mov     r3, r7, pull #24
+.Lcfu_3cpy8lp: mov     r3, r7, lspull #24
                ldmia   r1!, {r4 - r7}                  @ Shouldnt fault
-               orr     r3, r3, r4, push #8
-               mov     r4, r4, pull #24
-               orr     r4, r4, r5, push #8
-               mov     r5, r5, pull #24
-               orr     r5, r5, r6, push #8
-               mov     r6, r6, pull #24
-               orr     r6, r6, r7, push #8
+               orr     r3, r3, r4, lspush #8
+               mov     r4, r4, lspull #24
+               orr     r4, r4, r5, lspush #8
+               mov     r5, r5, lspull #24
+               orr     r5, r5, r6, lspush #8
+               mov     r6, r6, lspull #24
+               orr     r6, r6, r7, lspush #8
                stmia   r0!, {r3 - r6}
                subs    ip, ip, #16
                bpl     .Lcfu_3cpy8lp
 
 .Lcfu_3rem8lp: tst     ip, #8
-               movne   r3, r7, pull #24
+               movne   r3, r7, lspull #24
                ldmneia r1!, {r4, r7}                   @ Shouldnt fault
-               orrne   r3, r3, r4, push #8
-               movne   r4, r4, pull #24
-               orrne   r4, r4, r7, push #8
+               orrne   r3, r3, r4, lspush #8
+               movne   r4, r4, lspull #24
+               orrne   r4, r4, r7, lspush #8
                stmneia r0!, {r3 - r4}
                tst     ip, #4
-               movne   r3, r7, pull #24
+               movne   r3, r7, lspull #24
 USER(  TUSER(  ldrne) r7, [r1], #4)                    @ May fault
-               orrne   r3, r3, r7, push #8
+               orrne   r3, r3, r7, lspush #8
                strne   r3, [r0], #4
                ands    ip, ip, #3
                beq     .Lcfu_3fupi
index 4f0e800e7e711707caaf9c3331f9f90c4eae8cab..b2d2cf4dc0523fcc4175db241b61e66017e72ea0 100644 (file)
@@ -57,6 +57,7 @@ config SOC_SAMA5
        select GENERIC_CLOCKEVENTS
        select MULTI_IRQ_HANDLER
        select SPARSE_IRQ
+       select USE_OF
 
 menu "Atmel AT91 System-on-Chip"
 
@@ -64,11 +65,22 @@ choice
 
        prompt "Core type"
 
+config ARCH_AT91X40
+       bool "ARM7 AT91X40"
+       depends on !MMU
+       select CPU_ARM7TDMI
+       select ARCH_USES_GETTIMEOFFSET
+       select MULTI_IRQ_HANDLER
+       select SPARSE_IRQ
+
+       help
+         Select this if you are using one of Atmel's AT91X40 SoC.
+
 config SOC_SAM_V4_V5
-       bool "ARM7/ARM9"
+       bool "ARM9 AT91SAM9/AT91RM9200"
        help
-         Select this if you are using one of Atmel's AT91SAM9, AT91RM9200
-         or AT91X40 SoC.
+         Select this if you are using one of Atmel's AT91SAM9 or
+         AT91RM9200 SoC.
 
 config SOC_SAM_V7
        bool "Cortex A5"
@@ -119,7 +131,6 @@ config SOC_AT91SAM9261
        select HAVE_AT91_DBGU0
        select HAVE_FB_ATMEL
        select SOC_AT91SAM9
-       select AT91_USE_OLD_CLK
        select HAVE_AT91_USB_CLK
        help
          Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
@@ -137,7 +148,6 @@ config SOC_AT91SAM9RL
        select HAVE_AT91_DBGU0
        select HAVE_FB_ATMEL
        select SOC_AT91SAM9
-       select AT91_USE_OLD_CLK
        select HAVE_AT91_UTMI
 
 config SOC_AT91SAM9G45
@@ -179,9 +189,12 @@ config SOC_AT91SAM9N12
          Select this if you are using Atmel's AT91SAM9N12 SoC.
 
 # ----------------------------------------------------------
+endif # SOC_SAM_V4_V5
 
+
+if SOC_SAM_V4_V5 || ARCH_AT91X40
 source arch/arm/mach-at91/Kconfig.non_dt
-endif # SOC_SAM_V4_V5
+endif
 
 comment "Generic Board Type"
 
index 1f73e9b527dac56f57ca37ec7af80f47b05c37fe..44ace320d2e107ee27a755d82f339996dae81c17 100644 (file)
@@ -5,6 +5,7 @@ config HAVE_AT91_DATAFLASH_CARD
 
 choice
        prompt "Atmel AT91 Processor Devices for non DT boards"
+       depends on !ARCH_AT91X40
 
 config ARCH_AT91_NONE
        bool "None"
@@ -39,13 +40,6 @@ config ARCH_AT91SAM9G45
        select SOC_AT91SAM9G45
        select AT91_USE_OLD_CLK
 
-config ARCH_AT91X40
-       bool "AT91x40"
-       depends on !MMU
-       select ARCH_USES_GETTIMEOFFSET
-       select MULTI_IRQ_HANDLER
-       select SPARSE_IRQ
-
 endchoice
 
 config ARCH_AT91SAM9G20
index e47f5fd232f5f91e9a42b83beb8a21faddc6ac65..787bb50a4dff442361b587a190283a659a059de6 100644 (file)
@@ -21,6 +21,7 @@
 #include <mach/at91rm9200.h>
 #include <mach/at91_st.h>
 #include <mach/cpu.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "soc.h"
index 3ebc9792560cebed75a53883e42e774742c5660c..f3f19f21352aa94275755f882226027d58a39287 100644 (file)
@@ -21,6 +21,7 @@
 #include <mach/at91rm9200.h>
 #include <mach/at91rm9200_mc.h>
 #include <mach/at91_ramc.h>
+#include <mach/hardware.h>
 
 #include "board.h"
 #include "generic.h"
@@ -922,6 +923,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -960,6 +962,7 @@ static struct resource uart0_resources[] = {
 static struct atmel_uart_data uart0_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -987,9 +990,10 @@ static inline void configure_usart0_pins(unsigned pins)
        if (pins & ATMEL_UART_RTS) {
                /*
                 * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
-                *  We need to drive the pin manually.  Default is off (RTS is active low).
+                * We need to drive the pin manually. The serial driver will driver
+                * this to high when initializing.
                 */
-               at91_set_gpio_output(AT91_PIN_PA21, 1);
+               uart0_data.rts_gpio = AT91_PIN_PA21;
        }
 }
 
@@ -1009,6 +1013,7 @@ static struct resource uart1_resources[] = {
 static struct atmel_uart_data uart1_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1060,6 +1065,7 @@ static struct resource uart2_resources[] = {
 static struct atmel_uart_data uart2_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1103,6 +1109,7 @@ static struct resource uart3_resources[] = {
 static struct atmel_uart_data uart3_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart3_dmamask = DMA_BIT_MASK(32);
index bc7b363a3083bfdab31591786fe38991c199e2dc..7fd13aef982725ea0e869d5b76ddd4fe2530eb67 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mach/time.h>
 
 #include <mach/at91_st.h>
+#include <mach/hardware.h>
 
 static unsigned long last_crtr;
 static u32 irqmask;
index 6c821e5621590b5e920d330a2d895b196b7530b9..c3d22be73b7cc99bc638192dce47f25ed0919821 100644 (file)
@@ -21,6 +21,7 @@
 #include <mach/cpu.h>
 #include <mach/at91_dbgu.h>
 #include <mach/at91sam9260.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
index eda8d1679d404ef3a75ad999fabd333c23296b58..8b1b0a8700259961d04617ee064eb036679f8acd 100644 (file)
@@ -25,6 +25,7 @@
 #include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_adc.h>
+#include <mach/hardware.h>
 
 #include "board.h"
 #include "generic.h"
@@ -819,6 +820,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -857,6 +859,7 @@ static struct resource uart0_resources[] = {
 static struct atmel_uart_data uart0_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -908,6 +911,7 @@ static struct resource uart1_resources[] = {
 static struct atmel_uart_data uart1_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -951,6 +955,7 @@ static struct resource uart2_resources[] = {
 static struct atmel_uart_data uart2_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -994,6 +999,7 @@ static struct resource uart3_resources[] = {
 static struct atmel_uart_data uart3_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1037,6 +1043,7 @@ static struct resource uart4_resources[] = {
 static struct atmel_uart_data uart4_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1075,6 +1082,7 @@ static struct resource uart5_resources[] = {
 static struct atmel_uart_data uart5_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart5_dmamask = DMA_BIT_MASK(32);
@@ -1255,12 +1263,8 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
        at91_set_A_periph(AT91_PIN_PC10, 0);    /* CFRNW */
        at91_set_A_periph(AT91_PIN_PC15, 1);    /* NWAIT */
 
-       if (data->flags & AT91_CF_TRUE_IDE)
-#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
+       if (IS_ENABLED(CONFIG_PATA_AT91) && (data->flags & AT91_CF_TRUE_IDE))
                pdev->name = "pata_at91";
-#else
-#warning "board requires AT91_CF_TRUE_IDE: enable pata_at91"
-#endif
        else
                pdev->name = "at91_cf";
 
index 6276b4c1acfed2943354809b8b5f6ddd37bba9f9..fb164a5d04a906b09cb44872f7be7edf1784737a 100644 (file)
 #include <asm/system_misc.h>
 #include <mach/cpu.h>
 #include <mach/at91sam9261.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
 #include "soc.h"
 #include "generic.h"
-#include "clock.h"
 #include "sam9_smc.h"
 #include "pm.h"
 
+#if defined(CONFIG_OLD_CLK_AT91)
+#include "clock.h"
+
 /* --------------------------------------------------------------------
  *  Clocks
  * -------------------------------------------------------------------- */
@@ -189,6 +192,23 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_ID("pioA", &pioA_clk),
        CLKDEV_CON_ID("pioB", &pioB_clk),
        CLKDEV_CON_ID("pioC", &pioC_clk),
+       /* more lookup table for DT entries */
+       CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+       CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
+       CLKDEV_CON_DEV_ID("usart", "ffffb400.serial", &usart1_clk),
+       CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
+       CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
+       CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk),
+       CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &hck0),
+       CLKDEV_CON_DEV_ID("hclk", "600000.fb", &hck1),
+       CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk),
+       CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk),
+       CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
@@ -247,7 +267,9 @@ static void __init at91sam9261_register_clocks(void)
        clk_register(&hck0);
        clk_register(&hck1);
 }
-
+#else
+#define at91sam9261_register_clocks NULL
+#endif
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
index b2a34740146aaab4d3af99b741979c670be6402e..80e35895d28fb74f06d852d5712cb4c283b56a47 100644 (file)
@@ -25,6 +25,7 @@
 #include <mach/at91sam9261_matrix.h>
 #include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/hardware.h>
 
 #include "board.h"
 #include "generic.h"
@@ -880,6 +881,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -918,6 +920,7 @@ static struct resource uart0_resources[] = {
 static struct atmel_uart_data uart0_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -961,6 +964,7 @@ static struct resource uart1_resources[] = {
 static struct atmel_uart_data uart1_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1004,6 +1008,7 @@ static struct resource uart2_resources[] = {
 static struct atmel_uart_data uart2_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart2_dmamask = DMA_BIT_MASK(32);
index 37b90f4b990c3ce4e5360c526ca979810277121c..f30290572293273e94b9523ce0072f43cf607fc6 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
 #include <mach/at91sam9263.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
@@ -223,6 +224,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioCDE_clk),
        CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk),
        CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffb8000.pwm", &pwm_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
index 4aeadddbc18108918b883150bef49b3a770eeb42..43d53d6156dd7fd60384da67afb3784cf08c88f4 100644 (file)
@@ -24,6 +24,7 @@
 #include <mach/at91sam9263_matrix.h>
 #include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/hardware.h>
 
 #include "board.h"
 #include "generic.h"
@@ -1324,6 +1325,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1362,6 +1364,7 @@ static struct resource uart0_resources[] = {
 static struct atmel_uart_data uart0_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1405,6 +1408,7 @@ static struct resource uart1_resources[] = {
 static struct atmel_uart_data uart1_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1448,6 +1452,7 @@ static struct resource uart2_resources[] = {
 static struct atmel_uart_data uart2_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart2_dmamask = DMA_BIT_MASK(32);
index 0f04ffe9c5a87c2afb4f90b02d75b86b70fd722b..0a9e2fc8f7968996fcd5d994e4e797eaac76ea3d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
+#include <mach/hardware.h>
 
 #define AT91_PIT_MR            0x00                    /* Mode Register */
 #define                AT91_PIT_PITIEN         (1 << 25)               /* Timer Interrupt Enable */
index 2f455ce35268513d5abaafc954a54be76ef48a26..5e6f498db0a8d1bbda3bd2bad51f8dd4ce1b4576 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/system_misc.h>
 #include <mach/at91sam9g45.h>
 #include <mach/cpu.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "soc.h"
@@ -284,6 +285,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_ID("pioE", &pioDE_clk),
        /* Fake adc clock */
        CLKDEV_CON_ID("adc_clk", &tsc_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffb8000.pwm", &pwm_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
index cb36fa872d305d6f22b9133d48d3bdaaa678789d..77b04c2edd783485d89f229a5c9c075bc68ab468 100644 (file)
@@ -32,6 +32,7 @@
 #include <mach/at91sam9_smc.h>
 #include <linux/platform_data/dma-atmel.h>
 #include <mach/atmel-mci.h>
+#include <mach/hardware.h>
 
 #include <media/atmel-isi.h>
 
@@ -1587,6 +1588,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1625,6 +1627,7 @@ static struct resource uart0_resources[] = {
 static struct atmel_uart_data uart0_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1668,6 +1671,7 @@ static struct resource uart1_resources[] = {
 static struct atmel_uart_data uart1_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1711,6 +1715,7 @@ static struct resource uart2_resources[] = {
 static struct atmel_uart_data uart2_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1754,6 +1759,7 @@ static struct resource uart3_resources[] = {
 static struct atmel_uart_data uart3_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart3_dmamask = DMA_BIT_MASK(32);
index 4ef088c62eabdf6661a801f495e795912f250cd5..f2ea7b0a02da8f95073fe01d36d048c712a88712 100644 (file)
@@ -182,6 +182,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        /* additional fake clock for macb_hclk */
        CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk),
        CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk),
+       CLKDEV_CON_DEV_ID(NULL, "f8034000.pwm", &pwm_clk),
 };
 
 /*
index 3651517abedfb1214386cabd93d7ab82844d16aa..57f12d86c0e6166c38019b7b7f6acac75078451b 100644 (file)
 #include <mach/cpu.h>
 #include <mach/at91_dbgu.h>
 #include <mach/at91sam9rl.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
 #include "soc.h"
 #include "generic.h"
-#include "clock.h"
 #include "sam9_smc.h"
 #include "pm.h"
 
 /* --------------------------------------------------------------------
  *  Clocks
  * -------------------------------------------------------------------- */
+#if defined(CONFIG_OLD_CLK_AT91)
+#include "clock.h"
 
 /*
  * The peripheral clocks.
@@ -196,6 +198,24 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_ID("pioB", &pioB_clk),
        CLKDEV_CON_ID("pioC", &pioC_clk),
        CLKDEV_CON_ID("pioD", &pioD_clk),
+       /* more lookup table for DT entries */
+       CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+       CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
+       CLKDEV_CON_DEV_ID("usart", "ffffb400.serial", &usart1_clk),
+       CLKDEV_CON_DEV_ID("usart", "ffffb800.serial", &usart2_clk),
+       CLKDEV_CON_DEV_ID("usart", "ffffbc00.serial", &usart3_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
+       CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
+       CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk),
+       CLKDEV_CON_DEV_ID("mci_clk", "fffa4000.mmc", &mmc_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffa8000.i2c", &twi0_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi1_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffc8000.pwm", &pwm_clk),
+       CLKDEV_CON_DEV_ID(NULL, "ffffc800.pwm", &pwm_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
+       CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
@@ -238,6 +258,7 @@ static void __init at91sam9rl_register_clocks(void)
        clk_register(&pck0);
        clk_register(&pck1);
 }
+#endif
 
 /* --------------------------------------------------------------------
  *  GPIO
@@ -350,6 +371,8 @@ AT91_SOC_START(at91sam9rl)
        .default_irq_priority = at91sam9rl_default_irq_priority,
        .extern_irq = (1 << AT91SAM9RL_ID_IRQ0),
        .ioremap_registers = at91sam9rl_ioremap_registers,
+#if defined(CONFIG_OLD_CLK_AT91)
        .register_clocks = at91sam9rl_register_clocks,
+#endif
        .init = at91sam9rl_initialize,
 AT91_SOC_END
index a698bdab2cce682fee2983e0942d5bc2126139e4..428fc412aaf1e223da13a0d675aea08681391210 100644 (file)
@@ -21,6 +21,7 @@
 #include <mach/at91sam9rl_matrix.h>
 #include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/hardware.h>
 #include <linux/platform_data/dma-atmel.h>
 
 #include "board.h"
@@ -956,6 +957,7 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -994,6 +996,7 @@ static struct resource uart0_resources[] = {
 static struct atmel_uart_data uart0_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1045,6 +1048,7 @@ static struct resource uart1_resources[] = {
 static struct atmel_uart_data uart1_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1088,6 +1092,7 @@ static struct resource uart2_resources[] = {
 static struct atmel_uart_data uart2_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1131,6 +1136,7 @@ static struct resource uart3_resources[] = {
 static struct atmel_uart_data uart3_data = {
        .use_dma_tx     = 1,
        .use_dma_rx     = 1,
+       .rts_gpio       = -EINVAL,
 };
 
 static u64 uart3_dmamask = DMA_BIT_MASK(32);
index 3e8ec26e39dcc7404120fab8cbbfb0e168d9fa44..9ad781d5ee7cc9d5cd76650d395dffac9c98e0ca 100644 (file)
@@ -253,6 +253,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
        CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk),
        CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk),
+       CLKDEV_CON_DEV_ID(NULL, "f8034000.pwm", &pwm_clk),
 };
 
 /*
index bad94b84a46f7b72c9fe5bc182c1c0fbd19861b1..7523f1cdfe1d8a56a29087a4fceaa5cab9fabbd3 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/mach/arch.h>
 #include <mach/at91x40.h>
 #include <mach/at91_st.h>
-#include <mach/timex.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "generic.h"
index c0e637adf65d2555adddaa1897730fc4021d04d7..07d0bf2ac2dac18d2ad7b2c83e201134fc778bb8 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/time.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
+#include <mach/at91x40.h>
 #include <asm/mach/time.h>
 
 #include "at91_tc.h"
index 3dab868b02fad864fbc2ee537c7b846d563889b4..575b0be66ca8958028c656e3289b26368fb401a4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/clk-provider.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include "generic.h"
 
 
+static void __init sam9_dt_timer_init(void)
+{
+#if defined(CONFIG_COMMON_CLK)
+       of_clk_init(NULL);
+#endif
+       at91sam926x_pit_init();
+}
+
 static const struct of_device_id irq_of_match[] __initconst = {
 
        { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
@@ -43,7 +52,7 @@ static const char *at91_dt_board_compat[] __initdata = {
 
 DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
        /* Maintainer: Atmel */
-       .init_time      = at91sam926x_pit_init,
+       .init_time      = sam9_dt_timer_init,
        .map_io         = at91_map_io,
        .handle_irq     = at91_aic_handle_irq,
        .init_early     = at91_dt_initialize,
index c1d61d247790b72fc009547d61bd49a6cc3797a5..416bae8435eeaaeb526eb79bf363cfc5fccb764b 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/at91sam9_smc.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "board.h"
index 65c0d6b5ecba751bc19435083fd7c44162032ff9..5f25fa54eb93e9887bea2bced02521941c53a63c 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/at91sam9_smc.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "board.h"
index 869cbecf00b7eee51c78b4621019ac40ea2edacf..e4a5ac17cdbcb79c020635431ba1ebdf7057c062 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/at91sam9_smc.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "board.h"
index 90680217064eea8e1248f909e201596887a2c2f5..38dca2bb027f602b8a568f62c6528d04f34bcb3f 100644 (file)
@@ -55,4 +55,6 @@
 #define        AT91_PS_CR      (AT91_PS + 0)   /* PS Control register */
 #define        AT91_PS_CR_CPU  (1 << 0)        /* CPU clock disable bit */
 
+#define AT91X40_MASTER_CLOCK   40000000
+
 #endif /* AT91X40_H */
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
deleted file mode 100644 (file)
index 5e917a6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/timex.h
- *
- *  Copyright (C) 2003 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-#include <mach/hardware.h>
-
-#ifdef CONFIG_ARCH_AT91X40
-
-#define AT91X40_MASTER_CLOCK   40000000
-#define CLOCK_TICK_RATE                (AT91X40_MASTER_CLOCK)
-
-#else
-
-#define CLOCK_TICK_RATE                12345678
-
-#endif
-
-#endif /* __ASM_ARCH_TIMEX_H */
index 590b52dea9f7a2c1da84440dd3c556ea06efcd8f..8bda1cefdf96ad500f84641cbcb8fa300c3b13df 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/cpu.h>
+#include <mach/hardware.h>
 
 #include "at91_aic.h"
 #include "generic.h"
index b26156bf15db487b11080c4942730ad27bb1521a..826315af6d11c4bde262fbf44e92aefba20f2e90 100644 (file)
@@ -36,6 +36,7 @@ void sam9_smc_write_mode(int id, int cs,
 {
        sam9_smc_cs_write_mode(AT91_SMC_CS(id, cs), config);
 }
+EXPORT_SYMBOL_GPL(sam9_smc_write_mode);
 
 static void sam9_smc_cs_configure(void __iomem *base,
                                        struct sam9_smc_config *config)
@@ -69,6 +70,7 @@ void sam9_smc_configure(int id, int cs,
 {
        sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config);
 }
+EXPORT_SYMBOL_GPL(sam9_smc_configure);
 
 static void sam9_smc_cs_read_mode(void __iomem *base,
                                        struct sam9_smc_config *config)
@@ -84,6 +86,7 @@ void sam9_smc_read_mode(int id, int cs,
 {
        sam9_smc_cs_read_mode(AT91_SMC_CS(id, cs), config);
 }
+EXPORT_SYMBOL_GPL(sam9_smc_read_mode);
 
 static void sam9_smc_cs_read(void __iomem *base,
                                        struct sam9_smc_config *config)
index f7ca97b7291e2f9b48a2968f47bc92e788ff79cf..f7a07a58ebb6aa10da5f9aae0dac80bd745d1e15 100644 (file)
@@ -351,7 +351,7 @@ void __init at91_ioremap_matrix(u32 base_addr)
                panic("Impossible to ioremap at91_matrix_base\n");
 }
 
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40)
 static struct of_device_id rstc_ids[] = {
        { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
        { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
index b1aa6a9b3bd13a7f02ff4e8c4a80a03698e22c27..49c914cd9c7a9c83159475a33c4a4a9961b7f4a9 100644 (file)
@@ -16,12 +16,7 @@ config ARCH_BCM_MOBILE
        select ARM_ERRATA_754322
        select ARM_ERRATA_764369 if SMP
        select ARM_GIC
-       select CPU_V7
-       select CLKSRC_OF
-       select GENERIC_CLOCKEVENTS
-       select GENERIC_TIME
        select GPIO_BCM_KONA
-       select SPARSE_IRQ
        select TICK_ONESHOT
        select CACHE_L2X0
        select HAVE_ARM_ARCH_TIMER
@@ -32,6 +27,48 @@ config ARCH_BCM_MOBILE
          BCM11130, BCM11140, BCM11351, BCM28145 and
          BCM28155 variants.
 
+config ARCH_BCM2835
+       bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
+       select ARCH_REQUIRE_GPIOLIB
+       select ARM_AMBA
+       select ARM_ERRATA_411920
+       select ARM_TIMER_SP804
+       select CLKDEV_LOOKUP
+       select CLKSRC_OF
+       select CPU_V6
+       select GENERIC_CLOCKEVENTS
+       select PINCTRL
+       select PINCTRL_BCM2835
+       help
+         This enables support for the Broadcom BCM2835 SoC. This SoC is
+         used in the Raspberry Pi and Roku 2 devices.
+
+config ARCH_BCM_5301X
+       bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
+       depends on MMU
+       select ARM_GIC
+       select CACHE_L2X0
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       select HAVE_SMP
+       select COMMON_CLK
+       select GENERIC_CLOCKEVENTS
+       select ARM_GLOBAL_TIMER
+       select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+       select MIGHT_HAVE_PCI
+       help
+         Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
+
+         This is a network SoC line mostly used in home routers and
+         wifi access points, it's internal name is Northstar.
+         This inclused the following SoC: BCM53010, BCM53011, BCM53012,
+         BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
+         BCM4708 and BCM4709.
+
+         Do not confuse this with the BCM4760 which is a totally
+         different SoC or with the older BCM47XX and BCM53XX based
+         network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
+
 endmenu
 
 endif
index c2ccd5a0f77212ee4ba9389448bacba8ddc4faa6..a326b28c44064656b69f67f20ce721a9e5192169 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2013 Broadcom Corporation
+# Copyright (C) 2012-2014 Broadcom Corporation
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-obj-$(CONFIG_ARCH_BCM_MOBILE)  := board_bcm281xx.o bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
+obj-$(CONFIG_ARCH_BCM_MOBILE)  := board_bcm281xx.o board_bcm21664.o \
+                               bcm_kona_smc.o bcm_kona_smc_asm.o kona.o
+obj-$(CONFIG_ARCH_BCM2835)     += board_bcm2835.o
+
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_bcm_kona_smc_asm.o      :=-Wa,-march=armv7-a$(plus_sec)
+obj-$(CONFIG_ARCH_BCM_5301X)   += bcm_5301x.o
diff --git a/arch/arm/mach-bcm/bcm_5301x.c b/arch/arm/mach-bcm/bcm_5301x.c
new file mode 100644 (file)
index 0000000..edff697
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ *
+ * Copyright 2013 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <asm/mach/arch.h>
+#include <asm/siginfo.h>
+#include <asm/signal.h>
+
+
+static bool first_fault = true;
+
+static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
+                                struct pt_regs *regs)
+{
+       if (fsr == 0x1c06 && first_fault) {
+               first_fault = false;
+
+               /*
+                * These faults with code 0x1c06 happens for no good reason,
+                * possibly left over from the CFE boot loader.
+                */
+               pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
+               addr, fsr);
+
+               /* Returning non-zero causes fault display and panic */
+               return 0;
+       }
+
+       /* Others should cause a fault */
+       return 1;
+}
+
+static void __init bcm5301x_init_early(void)
+{
+       /* Install our hook */
+       hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
+                       "imprecise external abort");
+}
+
+static void __init bcm5301x_dt_init(void)
+{
+       l2x0_of_init(0, ~0UL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char __initconst *bcm5301x_dt_compat[] = {
+       "brcm,bcm4708",
+       NULL,
+};
+
+DT_MACHINE_START(BCM5301X, "BCM5301X")
+       .init_early     = bcm5301x_init_early,
+       .init_machine   = bcm5301x_dt_init,
+       .dt_compat      = bcm5301x_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c
new file mode 100644 (file)
index 0000000..acc1573
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clocksource.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+
+#include "bcm_kona_smc.h"
+#include "kona.h"
+
+#define RSTMGR_DT_STRING               "brcm,bcm21664-resetmgr"
+
+#define RSTMGR_REG_WR_ACCESS_OFFSET    0
+#define RSTMGR_REG_CHIP_SOFT_RST_OFFSET        4
+
+#define RSTMGR_WR_PASSWORD             0xa5a5
+#define RSTMGR_WR_PASSWORD_SHIFT       8
+#define RSTMGR_WR_ACCESS_ENABLE                1
+
+static void bcm21664_restart(enum reboot_mode mode, const char *cmd)
+{
+       void __iomem *base;
+       struct device_node *resetmgr;
+
+       resetmgr = of_find_compatible_node(NULL, NULL, RSTMGR_DT_STRING);
+       if (!resetmgr) {
+               pr_emerg("Couldn't find " RSTMGR_DT_STRING "\n");
+               return;
+       }
+       base = of_iomap(resetmgr, 0);
+       if (!base) {
+               pr_emerg("Couldn't map " RSTMGR_DT_STRING "\n");
+               return;
+       }
+
+       /*
+        * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
+        * register. To write to that register we must first write the password
+        * and the enable bit in the write access enable register.
+        */
+       writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) |
+               RSTMGR_WR_ACCESS_ENABLE,
+               base + RSTMGR_REG_WR_ACCESS_OFFSET);
+       writel(0, base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET);
+
+       /* Wait for reset */
+       while (1);
+}
+
+static void __init bcm21664_init(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table, NULL,
+               &platform_bus);
+       kona_l2_cache_init();
+}
+
+static const char * const bcm21664_dt_compat[] = {
+       "brcm,bcm21664",
+       NULL,
+};
+
+DT_MACHINE_START(BCM21664_DT, "BCM21664 Broadcom Application Processor")
+       .init_machine = bcm21664_init,
+       .restart = bcm21664_restart,
+       .dt_compat = bcm21664_dt_compat,
+MACHINE_END
index cb3dc364405c4eec94465adbb503b7763fe4887f..6be54c10f8cb9b8c077e86ff1f9476f7917ce511 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013 Broadcom Corporation
+ * Copyright (C) 2012-2014 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * GNU General Public License for more details.
  */
 
-#include <linux/of_platform.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
 #include <linux/clocksource.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/hardware/cache-l2x0.h>
 
-#include "bcm_kona_smc.h"
 #include "kona.h"
 
-static int __init kona_l2_cache_init(void)
+#define SECWDOG_OFFSET                 0x00000000
+#define SECWDOG_RESERVED_MASK          0xe2000000
+#define SECWDOG_WD_LOAD_FLAG_MASK      0x10000000
+#define SECWDOG_EN_MASK                        0x08000000
+#define SECWDOG_SRSTEN_MASK            0x04000000
+#define SECWDOG_CLKS_SHIFT             20
+#define SECWDOG_COUNT_SHIFT            0
+
+static void bcm281xx_restart(enum reboot_mode mode, const char *cmd)
 {
-       if (!IS_ENABLED(CONFIG_CACHE_L2X0))
-               return 0;
+       uint32_t val;
+       void __iomem *base;
+       struct device_node *np_wdog;
 
-       if (bcm_kona_smc_init() < 0) {
-               pr_info("Kona secure API not available. Skipping L2 init\n");
-               return 0;
+       np_wdog = of_find_compatible_node(NULL, NULL, "brcm,kona-wdt");
+       if (!np_wdog) {
+               pr_emerg("Couldn't find brcm,kona-wdt\n");
+               return;
+       }
+       base = of_iomap(np_wdog, 0);
+       if (!base) {
+               pr_emerg("Couldn't map brcm,kona-wdt\n");
+               return;
        }
 
-       bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
-
-       /*
-        * The aux_val and aux_mask have no effect since L2 cache is already
-        * enabled.  Pass 0s for aux_val and 1s for aux_mask for default value.
-        */
-       return l2x0_of_init(0, ~0);
-}
-
-static void bcm_board_setup_restart(void)
-{
-       struct device_node *np;
+       /* Enable watchdog with short timeout (244us). */
+       val = readl(base + SECWDOG_OFFSET);
+       val &= SECWDOG_RESERVED_MASK | SECWDOG_WD_LOAD_FLAG_MASK;
+       val |= SECWDOG_EN_MASK | SECWDOG_SRSTEN_MASK |
+               (0x15 << SECWDOG_CLKS_SHIFT) |
+               (0x8 << SECWDOG_COUNT_SHIFT);
+       writel(val, base + SECWDOG_OFFSET);
 
-       np = of_find_compatible_node(NULL, NULL, "brcm,bcm11351");
-       if (np) {
-               if (of_device_is_available(np))
-                       bcm_kona_setup_restart();
-               of_node_put(np);
-       }
-       /* Restart setup for other boards goes here */
+       /* Wait for reset */
+       while (1);
 }
 
-static void __init board_init(void)
+static void __init bcm281xx_init(void)
 {
        of_platform_populate(NULL, of_default_bus_match_table, NULL,
                &platform_bus);
-
-       bcm_board_setup_restart();
        kona_l2_cache_init();
 }
 
-static const char * const bcm11351_dt_compat[] = { "brcm,bcm11351", NULL, };
+static const char * const bcm281xx_dt_compat[] = {
+       "brcm,bcm11351",        /* Have to use the first number upstreamed */
+       NULL,
+};
 
-DT_MACHINE_START(BCM11351_DT, "BCM281xx Broadcom Application Processor")
-       .init_machine = board_init,
-       .restart = bcm_kona_restart,
-       .dt_compat = bcm11351_dt_compat,
+DT_MACHINE_START(BCM281XX_DT, "BCM281xx Broadcom Application Processor")
+       .init_machine = bcm281xx_init,
+       .restart = bcm281xx_restart,
+       .dt_compat = bcm281xx_dt_compat,
 MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
new file mode 100644 (file)
index 0000000..70f2f39
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 Broadcom
+ *
+ * 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/delay.h>
+#include <linux/init.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk/bcm2835.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#define PM_RSTC                                0x1c
+#define PM_RSTS                                0x20
+#define PM_WDOG                                0x24
+
+#define PM_PASSWORD                    0x5a000000
+#define PM_RSTC_WRCFG_MASK             0x00000030
+#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
+#define PM_RSTS_HADWRH_SET             0x00000040
+
+#define BCM2835_PERIPH_PHYS    0x20000000
+#define BCM2835_PERIPH_VIRT    0xf0000000
+#define BCM2835_PERIPH_SIZE    SZ_16M
+
+static void __iomem *wdt_regs;
+
+/*
+ * The machine restart method can be called from an atomic context so we won't
+ * be able to ioremap the regs then.
+ */
+static void bcm2835_setup_restart(void)
+{
+       struct device_node *np = of_find_compatible_node(NULL, NULL,
+                                               "brcm,bcm2835-pm-wdt");
+       if (WARN(!np, "unable to setup watchdog restart"))
+               return;
+
+       wdt_regs = of_iomap(np, 0);
+       WARN(!wdt_regs, "failed to remap watchdog regs");
+}
+
+static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
+{
+       u32 val;
+
+       if (!wdt_regs)
+               return;
+
+       /* use a timeout of 10 ticks (~150us) */
+       writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
+       val = readl_relaxed(wdt_regs + PM_RSTC);
+       val &= ~PM_RSTC_WRCFG_MASK;
+       val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
+       writel_relaxed(val, wdt_regs + PM_RSTC);
+
+       /* No sleeping, possibly atomic. */
+       mdelay(1);
+}
+
+/*
+ * We can't really power off, but if we do the normal reset scheme, and
+ * indicate to bootcode.bin not to reboot, then most of the chip will be
+ * powered off.
+ */
+static void bcm2835_power_off(void)
+{
+       u32 val;
+
+       /*
+        * We set the watchdog hard reset bit here to distinguish this reset
+        * from the normal (full) reset. bootcode.bin will not reboot after a
+        * hard reset.
+        */
+       val = readl_relaxed(wdt_regs + PM_RSTS);
+       val &= ~PM_RSTC_WRCFG_MASK;
+       val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
+       writel_relaxed(val, wdt_regs + PM_RSTS);
+
+       /* Continue with normal reset mechanism */
+       bcm2835_restart(REBOOT_HARD, "");
+}
+
+static struct map_desc io_map __initdata = {
+       .virtual = BCM2835_PERIPH_VIRT,
+       .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
+       .length = BCM2835_PERIPH_SIZE,
+       .type = MT_DEVICE
+};
+
+static void __init bcm2835_map_io(void)
+{
+       iotable_init(&io_map, 1);
+}
+
+static void __init bcm2835_init(void)
+{
+       int ret;
+
+       bcm2835_setup_restart();
+       if (wdt_regs)
+               pm_power_off = bcm2835_power_off;
+
+       bcm2835_init_clocks();
+
+       ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
+                                  NULL);
+       if (ret) {
+               pr_err("of_platform_populate failed: %d\n", ret);
+               BUG();
+       }
+}
+
+static const char * const bcm2835_compat[] = {
+       "brcm,bcm2835",
+       NULL
+};
+
+DT_MACHINE_START(BCM2835, "BCM2835")
+       .map_io = bcm2835_map_io,
+       .init_irq = irqchip_init,
+       .init_machine = bcm2835_init,
+       .restart = bcm2835_restart,
+       .dt_compat = bcm2835_compat
+MACHINE_END
index 6939d9017f63369c3c34cba1921869ea7a873583..768bc2837bf5985a8c3b2810afc9d0507ab98fd2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Broadcom Corporation
+ * Copyright (C) 2012-2014 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * GNU General Public License for more details.
  */
 
-#include <linux/of_address.h>
-#include <asm/io.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
 
+#include "bcm_kona_smc.h"
 #include "kona.h"
 
-static void __iomem *watchdog_base;
-
-void bcm_kona_setup_restart(void)
+void __init kona_l2_cache_init(void)
 {
-       struct device_node *np_wdog;
+       int ret;
 
-       /*
-        * The assumption is that whoever calls bcm_kona_setup_restart()
-        * also needs a Kona Watchdog Timer entry in Device Tree, i.e. we
-        * report an error if the DT entry is missing.
-        */
-       np_wdog = of_find_compatible_node(NULL, NULL, "brcm,kona-wdt");
-       if (!np_wdog) {
-               pr_err("brcm,kona-wdt not found in DT, reboot disabled\n");
+       if (!IS_ENABLED(CONFIG_CACHE_L2X0))
                return;
-       }
-       watchdog_base = of_iomap(np_wdog, 0);
-       WARN(!watchdog_base, "failed to map watchdog base");
-       of_node_put(np_wdog);
-}
-
-#define SECWDOG_OFFSET                 0x00000000
-#define SECWDOG_RESERVED_MASK          0xE2000000
-#define SECWDOG_WD_LOAD_FLAG_MASK      0x10000000
-#define SECWDOG_EN_MASK                        0x08000000
-#define SECWDOG_SRSTEN_MASK            0x04000000
-#define SECWDOG_CLKS_SHIFT             20
-#define SECWDOG_LOCK_SHIFT             0
 
-void bcm_kona_restart(enum reboot_mode mode, const char *cmd)
-{
-       uint32_t val;
-
-       if (!watchdog_base)
-               panic("Watchdog not mapped. Reboot failed.\n");
+       ret = bcm_kona_smc_init();
+       if (ret) {
+               pr_info("Secure API not available (%d). Skipping L2 init.\n",
+                       ret);
+               return;
+       }
 
-       /* Enable watchdog2 with very short timeout. */
-       val = readl(watchdog_base + SECWDOG_OFFSET);
-       val &= SECWDOG_RESERVED_MASK | SECWDOG_WD_LOAD_FLAG_MASK;
-       val |= SECWDOG_EN_MASK | SECWDOG_SRSTEN_MASK |
-               (0x8 << SECWDOG_CLKS_SHIFT) |
-               (0x8 << SECWDOG_LOCK_SHIFT);
-       writel(val, watchdog_base + SECWDOG_OFFSET);
+       bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0);
 
-       while (1)
-               ;
+       /*
+        * The aux_val and aux_mask have no effect since L2 cache is already
+        * enabled.  Pass 0s for aux_val and 1s for aux_mask for default value.
+        */
+       ret = l2x0_of_init(0, ~0);
+       if (ret)
+               pr_err("Couldn't enable L2 cache: %d\n", ret);
 }
index 291eca3e06ff1f0d6e27cd10e2f1d4a29c96cb21..3a7a017c29cd0414c8afd11a97509c18f66dade9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Broadcom Corporation
+ * Copyright (C) 2012-2014 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -11,7 +11,4 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/reboot.h>
-
-void bcm_kona_setup_restart(void);
-void bcm_kona_restart(enum reboot_mode mode, const char *cmd);
+void __init kona_l2_cache_init(void);
diff --git a/arch/arm/mach-bcm2835/Kconfig b/arch/arm/mach-bcm2835/Kconfig
deleted file mode 100644 (file)
index d1f9612..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-config ARCH_BCM2835
-       bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
-       select ARCH_REQUIRE_GPIOLIB
-       select ARM_AMBA
-       select ARM_ERRATA_411920
-       select ARM_TIMER_SP804
-       select CLKDEV_LOOKUP
-       select CLKSRC_OF
-       select CPU_V6
-       select GENERIC_CLOCKEVENTS
-       select PINCTRL
-       select PINCTRL_BCM2835
-       help
-         This enables support for the Broadcom BCM2835 SoC. This SoC is
-         used in the Raspberry Pi and Roku 2 devices.
diff --git a/arch/arm/mach-bcm2835/Makefile b/arch/arm/mach-bcm2835/Makefile
deleted file mode 100644 (file)
index 4c3892f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-obj-y += bcm2835.o
diff --git a/arch/arm/mach-bcm2835/bcm2835.c b/arch/arm/mach-bcm2835/bcm2835.c
deleted file mode 100644 (file)
index 70f2f39..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2010 Broadcom
- *
- * 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/delay.h>
-#include <linux/init.h>
-#include <linux/irqchip.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/clk/bcm2835.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#define PM_RSTC                                0x1c
-#define PM_RSTS                                0x20
-#define PM_WDOG                                0x24
-
-#define PM_PASSWORD                    0x5a000000
-#define PM_RSTC_WRCFG_MASK             0x00000030
-#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
-#define PM_RSTS_HADWRH_SET             0x00000040
-
-#define BCM2835_PERIPH_PHYS    0x20000000
-#define BCM2835_PERIPH_VIRT    0xf0000000
-#define BCM2835_PERIPH_SIZE    SZ_16M
-
-static void __iomem *wdt_regs;
-
-/*
- * The machine restart method can be called from an atomic context so we won't
- * be able to ioremap the regs then.
- */
-static void bcm2835_setup_restart(void)
-{
-       struct device_node *np = of_find_compatible_node(NULL, NULL,
-                                               "brcm,bcm2835-pm-wdt");
-       if (WARN(!np, "unable to setup watchdog restart"))
-               return;
-
-       wdt_regs = of_iomap(np, 0);
-       WARN(!wdt_regs, "failed to remap watchdog regs");
-}
-
-static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
-{
-       u32 val;
-
-       if (!wdt_regs)
-               return;
-
-       /* use a timeout of 10 ticks (~150us) */
-       writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
-       val = readl_relaxed(wdt_regs + PM_RSTC);
-       val &= ~PM_RSTC_WRCFG_MASK;
-       val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
-       writel_relaxed(val, wdt_regs + PM_RSTC);
-
-       /* No sleeping, possibly atomic. */
-       mdelay(1);
-}
-
-/*
- * We can't really power off, but if we do the normal reset scheme, and
- * indicate to bootcode.bin not to reboot, then most of the chip will be
- * powered off.
- */
-static void bcm2835_power_off(void)
-{
-       u32 val;
-
-       /*
-        * We set the watchdog hard reset bit here to distinguish this reset
-        * from the normal (full) reset. bootcode.bin will not reboot after a
-        * hard reset.
-        */
-       val = readl_relaxed(wdt_regs + PM_RSTS);
-       val &= ~PM_RSTC_WRCFG_MASK;
-       val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
-       writel_relaxed(val, wdt_regs + PM_RSTS);
-
-       /* Continue with normal reset mechanism */
-       bcm2835_restart(REBOOT_HARD, "");
-}
-
-static struct map_desc io_map __initdata = {
-       .virtual = BCM2835_PERIPH_VIRT,
-       .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
-       .length = BCM2835_PERIPH_SIZE,
-       .type = MT_DEVICE
-};
-
-static void __init bcm2835_map_io(void)
-{
-       iotable_init(&io_map, 1);
-}
-
-static void __init bcm2835_init(void)
-{
-       int ret;
-
-       bcm2835_setup_restart();
-       if (wdt_regs)
-               pm_power_off = bcm2835_power_off;
-
-       bcm2835_init_clocks();
-
-       ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
-                                  NULL);
-       if (ret) {
-               pr_err("of_platform_populate failed: %d\n", ret);
-               BUG();
-       }
-}
-
-static const char * const bcm2835_compat[] = {
-       "brcm,bcm2835",
-       NULL
-};
-
-DT_MACHINE_START(BCM2835, "BCM2835")
-       .map_io = bcm2835_map_io,
-       .init_irq = irqchip_init,
-       .init_machine = bcm2835_init,
-       .restart = bcm2835_restart,
-       .dt_compat = bcm2835_compat
-MACHINE_END
index 7a02d222c37860b554bc9f5a4b609ae457ee0eac..b0cb0722acd254fb411c7616504c9399d396c4b1 100644 (file)
@@ -1,9 +1,7 @@
 config ARCH_BERLIN
        bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
        select ARM_GIC
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select COMMON_CLK
        select DW_APB_ICTL
        select DW_APB_TIMER_OF
 
@@ -16,12 +14,10 @@ config MACH_BERLIN_BG2
        select CACHE_L2X0
        select CPU_PJ4B
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
 
 config MACH_BERLIN_BG2CD
        bool "Marvell Armada 1500-mini (BG2CD)"
        select CACHE_L2X0
-       select CPU_V7
        select HAVE_ARM_TWD if SMP
 
 endmenu
index bea6295c8c590b3e0da4309e91bf854000907c4f..f711498c180c0e7f1f97037e76c852c5a93dfb8e 100644 (file)
@@ -33,20 +33,6 @@ config ARCH_P720T
          Say Y here if you intend to run this kernel on the ARM Prospector
          720T.
 
-config EP72XX_ROM_BOOT
-       bool "EP721x/EP731x ROM boot"
-       help
-         If you say Y here, your CLPS711x-based kernel will use the bootstrap
-         mode memory map instead of the normal memory map.
-
-         Processors derived from the Cirrus CLPS711X core support two boot
-         modes.  Normal mode boots from the external memory device at CS0.
-         Bootstrap mode rearranges parts of the memory map, placing an
-         internal 128 byte bootstrap ROM at CS0.  This option performs the
-         address map changes required to support booting in this mode.
-
-         You almost surely want to say N here.
-
 endmenu
 
 endif
index f8d71a89644ab222f08a33f7d81e5fb4964ff4b8..d62ca16d53942e9a69db041261d79e4be3217e6f 100644 (file)
@@ -73,7 +73,7 @@
 #define AUTCPU12_SMC_NCE       (AUTCPU12_MMGPIO_BASE + 0) /* Bit 0 */
 #define AUTCPU12_SMC_RDY       CLPS711X_GPIO(1, 2)
 #define AUTCPU12_SMC_ALE       CLPS711X_GPIO(1, 3)
-#define AUTCPU12_SMC_CLE       CLPS711X_GPIO(1, 3)
+#define AUTCPU12_SMC_CLE       CLPS711X_GPIO(1, 4)
 
 /* LCD contrast digital potentiometer */
 #define AUTCPU12_DPOT_CS       CLPS711X_GPIO(4, 0)
@@ -265,14 +265,12 @@ static void __init autcpu12_init_late(void)
 MACHINE_START(AUTCPU12, "autronix autcpu12")
        /* Maintainer: Thomas Gleixner */
        .atag_offset    = 0x20000,
-       .nr_irqs        = CLPS711X_NR_IRQS,
        .map_io         = clps711x_map_io,
        .init_early     = clps711x_init_early,
        .init_irq       = clps711x_init_irq,
        .init_time      = clps711x_timer_init,
        .init_machine   = autcpu12_init,
        .init_late      = autcpu12_init_late,
-       .handle_irq     = clps711x_handle_irq,
        .restart        = clps711x_restart,
 MACHINE_END
 
index a9e38c6bcfb4169339b103a9a4df00e55e70f8af..e261a47f2aff276ac60cc8d6dd3daa627fbb2d45 100644 (file)
@@ -139,12 +139,10 @@ static void __init cdb89712_init(void)
 MACHINE_START(CDB89712, "Cirrus-CDB89712")
        /* Maintainer: Ray Lehtiniemi */
        .atag_offset    = 0x100,
-       .nr_irqs        = CLPS711X_NR_IRQS,
        .map_io         = clps711x_map_io,
        .init_early     = clps711x_init_early,
        .init_irq       = clps711x_init_irq,
        .init_time      = clps711x_timer_init,
        .init_machine   = cdb89712_init,
-       .handle_irq     = clps711x_handle_irq,
        .restart        = clps711x_restart,
 MACHINE_END
index b4764246d0f85deb15c4c127ed48a7faaff7aa63..221b9de32dd69e511b0d4281a7e0e6e1352df04e 100644 (file)
@@ -36,12 +36,10 @@ fixup_clep7312(struct tag *tags, char **cmdline, struct meminfo *mi)
 MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
        /* Maintainer: Nobody */
        .atag_offset    = 0x0100,
-       .nr_irqs        = CLPS711X_NR_IRQS,
        .fixup          = fixup_clep7312,
        .map_io         = clps711x_map_io,
        .init_early     = clps711x_init_early,
        .init_irq       = clps711x_init_irq,
        .init_time      = clps711x_timer_init,
-       .handle_irq     = clps711x_handle_irq,
        .restart        = clps711x_restart,
 MACHINE_END
index fe6184ead89668d0f10b9e22b07d0ee05c867137..077609841f14a8051977a173be594244376fed55 100644 (file)
@@ -177,7 +177,6 @@ static void __init edb7211_init_late(void)
 MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
        /* Maintainer: Jon McClintock */
        .atag_offset    = VIDEORAM_SIZE + 0x100,
-       .nr_irqs        = CLPS711X_NR_IRQS,
        .fixup          = fixup_edb7211,
        .reserve        = edb7211_reserve,
        .map_io         = clps711x_map_io,
@@ -186,6 +185,5 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
        .init_time      = clps711x_timer_init,
        .init_machine   = edb7211_init,
        .init_late      = edb7211_init_late,
-       .handle_irq     = clps711x_handle_irq,
        .restart        = clps711x_restart,
 MACHINE_END
index dd81b06f68fed749e38c16f743ec65fb0ef78164..67b733744ed7dbb0fdb4a526b3897f51e7b34203 100644 (file)
@@ -363,7 +363,6 @@ static void __init p720t_init_late(void)
 MACHINE_START(P720T, "ARM-Prospector720T")
        /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
        .atag_offset    = 0x100,
-       .nr_irqs        = CLPS711X_NR_IRQS,
        .fixup          = fixup_p720t,
        .map_io         = clps711x_map_io,
        .init_early     = clps711x_init_early,
@@ -371,6 +370,5 @@ MACHINE_START(P720T, "ARM-Prospector720T")
        .init_time      = clps711x_timer_init,
        .init_machine   = p720t_init,
        .init_late      = p720t_init_late,
-       .handle_irq     = clps711x_handle_irq,
        .restart        = clps711x_restart,
 MACHINE_END
index a1935911e4f19ffd1a62080241470a6651cc2c10..aee81fa46ccfc4454e5ed9d1082a853965100c97 100644 (file)
 #include <linux/clk-provider.h>
 #include <linux/sched_clock.h>
 
-#include <asm/exception.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
 
 #include <mach/hardware.h>
 
+#include "common.h"
+
 static struct clk *clk_pll, *clk_bus, *clk_uart, *clk_timerl, *clk_timerh,
                  *clk_tint, *clk_spi;
 
@@ -59,204 +59,9 @@ void __init clps711x_map_io(void)
        iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc));
 }
 
-static void int1_mask(struct irq_data *d)
-{
-       u32 intmr1;
-
-       intmr1 = clps_readl(INTMR1);
-       intmr1 &= ~(1 << d->irq);
-       clps_writel(intmr1, INTMR1);
-}
-
-static void int1_eoi(struct irq_data *d)
-{
-       switch (d->irq) {
-       case IRQ_CSINT:  clps_writel(0, COEOI);  break;
-       case IRQ_TC1OI:  clps_writel(0, TC1EOI); break;
-       case IRQ_TC2OI:  clps_writel(0, TC2EOI); break;
-       case IRQ_RTCMI:  clps_writel(0, RTCEOI); break;
-       case IRQ_TINT:   clps_writel(0, TEOI);   break;
-       case IRQ_UMSINT: clps_writel(0, UMSEOI); break;
-       }
-}
-
-static void int1_unmask(struct irq_data *d)
-{
-       u32 intmr1;
-
-       intmr1 = clps_readl(INTMR1);
-       intmr1 |= 1 << d->irq;
-       clps_writel(intmr1, INTMR1);
-}
-
-static struct irq_chip int1_chip = {
-       .name           = "Interrupt Vector 1",
-       .irq_eoi        = int1_eoi,
-       .irq_mask       = int1_mask,
-       .irq_unmask     = int1_unmask,
-};
-
-static void int2_mask(struct irq_data *d)
-{
-       u32 intmr2;
-
-       intmr2 = clps_readl(INTMR2);
-       intmr2 &= ~(1 << (d->irq - 16));
-       clps_writel(intmr2, INTMR2);
-}
-
-static void int2_eoi(struct irq_data *d)
-{
-       switch (d->irq) {
-       case IRQ_KBDINT: clps_writel(0, KBDEOI); break;
-       }
-}
-
-static void int2_unmask(struct irq_data *d)
-{
-       u32 intmr2;
-
-       intmr2 = clps_readl(INTMR2);
-       intmr2 |= 1 << (d->irq - 16);
-       clps_writel(intmr2, INTMR2);
-}
-
-static struct irq_chip int2_chip = {
-       .name           = "Interrupt Vector 2",
-       .irq_eoi        = int2_eoi,
-       .irq_mask       = int2_mask,
-       .irq_unmask     = int2_unmask,
-};
-
-static void int3_mask(struct irq_data *d)
-{
-       u32 intmr3;
-
-       intmr3 = clps_readl(INTMR3);
-       intmr3 &= ~(1 << (d->irq - 32));
-       clps_writel(intmr3, INTMR3);
-}
-
-static void int3_unmask(struct irq_data *d)
-{
-       u32 intmr3;
-
-       intmr3 = clps_readl(INTMR3);
-       intmr3 |= 1 << (d->irq - 32);
-       clps_writel(intmr3, INTMR3);
-}
-
-static struct irq_chip int3_chip = {
-       .name           = "Interrupt Vector 3",
-       .irq_mask       = int3_mask,
-       .irq_unmask     = int3_unmask,
-};
-
-static struct {
-       int                     nr;
-       struct irq_chip         *chip;
-       irq_flow_handler_t      handle;
-} clps711x_irqdescs[] __initdata = {
-       { IRQ_CSINT,    &int1_chip,     handle_fasteoi_irq,     },
-       { IRQ_EINT1,    &int1_chip,     handle_level_irq,       },
-       { IRQ_EINT2,    &int1_chip,     handle_level_irq,       },
-       { IRQ_EINT3,    &int1_chip,     handle_level_irq,       },
-       { IRQ_TC1OI,    &int1_chip,     handle_fasteoi_irq,     },
-       { IRQ_TC2OI,    &int1_chip,     handle_fasteoi_irq,     },
-       { IRQ_RTCMI,    &int1_chip,     handle_fasteoi_irq,     },
-       { IRQ_TINT,     &int1_chip,     handle_fasteoi_irq,     },
-       { IRQ_UTXINT1,  &int1_chip,     handle_level_irq,       },
-       { IRQ_URXINT1,  &int1_chip,     handle_level_irq,       },
-       { IRQ_UMSINT,   &int1_chip,     handle_fasteoi_irq,     },
-       { IRQ_SSEOTI,   &int1_chip,     handle_level_irq,       },
-       { IRQ_KBDINT,   &int2_chip,     handle_fasteoi_irq,     },
-       { IRQ_SS2RX,    &int2_chip,     handle_level_irq,       },
-       { IRQ_SS2TX,    &int2_chip,     handle_level_irq,       },
-       { IRQ_UTXINT2,  &int2_chip,     handle_level_irq,       },
-       { IRQ_URXINT2,  &int2_chip,     handle_level_irq,       },
-};
-
 void __init clps711x_init_irq(void)
 {
-       unsigned int i;
-
-       /* Disable interrupts */
-       clps_writel(0, INTMR1);
-       clps_writel(0, INTMR2);
-       clps_writel(0, INTMR3);
-
-       /* Clear down any pending interrupts */
-       clps_writel(0, BLEOI);
-       clps_writel(0, MCEOI);
-       clps_writel(0, COEOI);
-       clps_writel(0, TC1EOI);
-       clps_writel(0, TC2EOI);
-       clps_writel(0, RTCEOI);
-       clps_writel(0, TEOI);
-       clps_writel(0, UMSEOI);
-       clps_writel(0, KBDEOI);
-       clps_writel(0, SRXEOF);
-       clps_writel(0xffffffff, DAISR);
-
-       for (i = 0; i < ARRAY_SIZE(clps711x_irqdescs); i++) {
-               irq_set_chip_and_handler(clps711x_irqdescs[i].nr,
-                                        clps711x_irqdescs[i].chip,
-                                        clps711x_irqdescs[i].handle);
-               set_irq_flags(clps711x_irqdescs[i].nr,
-                             IRQF_VALID | IRQF_PROBE);
-       }
-
-       if (IS_ENABLED(CONFIG_FIQ)) {
-               init_FIQ(0);
-               irq_set_chip_and_handler(IRQ_DAIINT, &int3_chip,
-                                        handle_bad_irq);
-               set_irq_flags(IRQ_DAIINT,
-                             IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
-       }
-}
-
-static inline u32 fls16(u32 x)
-{
-       u32 r = 15;
-
-       if (!(x & 0xff00)) {
-               x <<= 8;
-               r -= 8;
-       }
-       if (!(x & 0xf000)) {
-               x <<= 4;
-               r -= 4;
-       }
-       if (!(x & 0xc000)) {
-               x <<= 2;
-               r -= 2;
-       }
-       if (!(x & 0x8000))
-               r--;
-
-       return r;
-}
-
-asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs)
-{
-       do {
-               u32 irqstat;
-               void __iomem *base = CLPS711X_VIRT_BASE;
-
-               irqstat = readw_relaxed(base + INTSR1) &
-                         readw_relaxed(base + INTMR1);
-               if (irqstat)
-                       handle_IRQ(fls16(irqstat), regs);
-
-               irqstat = readw_relaxed(base + INTSR2) &
-                         readw_relaxed(base + INTMR2);
-               if (irqstat) {
-                       handle_IRQ(fls16(irqstat) + 16, regs);
-                       continue;
-               }
-
-               break;
-       } while (1);
+       clps711x_intc_init(CLPS711X_PHYS_BASE, SZ_16K);
 }
 
 static u64 notrace clps711x_sched_clock_read(void)
index 9a6767bfdc471c98a9f61d63288004ef5936cc43..7489139d5d632f312e5ef13c41b357e761d70706 100644 (file)
@@ -6,13 +6,14 @@
 
 #include <linux/reboot.h>
 
-#define CLPS711X_NR_IRQS       (33)
 #define CLPS711X_NR_GPIO       (4 * 8 + 3)
 #define CLPS711X_GPIO(prt, bit)        ((prt) * 8 + (bit))
 
 extern void clps711x_map_io(void);
 extern void clps711x_init_irq(void);
 extern void clps711x_timer_init(void);
-extern void clps711x_handle_irq(struct pt_regs *regs);
 extern void clps711x_restart(enum reboot_mode mode, const char *cmd);
 extern void clps711x_init_early(void);
+
+/* drivers/irqchip/irq-clps711x.c */
+void clps711x_intc_init(phys_addr_t, resource_size_t);
index 0286f4bf994544da39253d05aae17594f091fb49..eb052a11aa9d6e60acbf7c615fcee708fa746e3c 100644 (file)
@@ -40,8 +40,6 @@
 #define MEMCFG1                (0x0180)
 #define MEMCFG2                (0x01c0)
 #define DRFPR          (0x0200)
-#define INTSR1         (0x0240)
-#define INTMR1         (0x0280)
 #define LCDCON         (0x02c0)
 #define TC1D           (0x0300)
 #define TC2D           (0x0340)
 #define PALLSW         (0x0540)
 #define PALMSW         (0x0580)
 #define STFCLR         (0x05c0)
-#define BLEOI          (0x0600)
-#define MCEOI          (0x0640)
-#define TEOI           (0x0680)
-#define TC1EOI         (0x06c0)
-#define TC2EOI         (0x0700)
-#define RTCEOI         (0x0740)
-#define UMSEOI         (0x0780)
-#define COEOI          (0x07c0)
 #define HALT           (0x0800)
 #define STDBY          (0x0840)
 
 #define FBADDR         (0x1000)
 #define SYSCON2                (0x1100)
 #define SYSFLG2                (0x1140)
-#define INTSR2         (0x1240)
-#define INTMR2         (0x1280)
 #define UARTDR2                (0x1480)
 #define UBRLCR2                (0x14c0)
 #define SS2DR          (0x1500)
-#define SRXEOF         (0x1600)
 #define SS2POP         (0x16c0)
-#define KBDEOI         (0x1700)
 
 #define DAIR           (0x2000)
 #define DAIDR0         (0x2040)
@@ -84,8 +70,6 @@
 #define DAIDR2         (0x20c0)
 #define DAISR          (0x2100)
 #define SYSCON3                (0x2200)
-#define INTSR3         (0x2240)
-#define INTMR3         (0x2280)
 #define LEDFLSH                (0x22c0)
 #define SDCONF         (0x2300)
 #define SDRFPR         (0x2340)
index c5a8ea6839ef4b870cacd1766f00207f8e8fba51..5d6afda1c0e8251ccfca3a905b5886185c25da88 100644 (file)
 #define clps_writel(val,off)   writel(val, CLPS711X_VIRT_BASE + (off))
 #endif
 
-/*
- * The physical addresses that the external chip select signals map to is
- * dependent on the setting of the nMEDCHG signal on EP7211 and EP7212
- * processors.  CONFIG_EP72XX_BOOT_ROM is only available if these
- * processors are in use.
- */
-#ifndef CONFIG_EP72XX_ROM_BOOT
 #define CS0_PHYS_BASE          (0x00000000)
 #define CS1_PHYS_BASE          (0x10000000)
 #define CS2_PHYS_BASE          (0x20000000)
 #define CS5_PHYS_BASE          (0x50000000)
 #define CS6_PHYS_BASE          (0x60000000)
 #define CS7_PHYS_BASE          (0x70000000)
-#else
-#define CS0_PHYS_BASE          (0x70000000)
-#define CS1_PHYS_BASE          (0x60000000)
-#define CS2_PHYS_BASE          (0x50000000)
-#define CS3_PHYS_BASE          (0x40000000)
-#define CS4_PHYS_BASE          (0x30000000)
-#define CS5_PHYS_BASE          (0x20000000)
-#define CS6_PHYS_BASE          (0x10000000)
-#define CS7_PHYS_BASE          (0x00000000)
-#endif
 
 #define CLPS711X_SRAM_BASE     CS6_PHYS_BASE
 #define CLPS711X_SRAM_SIZE     (48 * 1024)
diff --git a/arch/arm/mach-clps711x/include/mach/timex.h b/arch/arm/mach-clps711x/include/mach/timex.h
deleted file mode 100644 (file)
index de6fd19..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Bogus value */
-#define CLOCK_TICK_RATE 512000
index dbf0df8bb0acf916624a2eeef6eb12ab86d9f6a1..dce8decd5d46a387afa7f5da6bb9fdfc727733e1 100644 (file)
@@ -1,9 +1,6 @@
 config ARCH_CNS3XXX
        bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
        select ARM_GIC
-       select CPU_V6K
-       select GENERIC_CLOCKEVENTS
-       select MIGHT_HAVE_CACHE_L2X0
        select MIGHT_HAVE_PCI
        select PCI_DOMAINS if PCI
        help
index ce096d678aa410d68ab1915e500b7c8bdf7a2242..d863d8729edc54c9744cfd4137748727b57673f6 100644 (file)
@@ -246,7 +246,6 @@ static void __init cns3420_map_io(void)
 
 MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
        .atag_offset    = 0x100,
-       .nr_irqs        = NR_IRQS_CNS3XXX,
        .map_io         = cns3420_map_io,
        .init_irq       = cns3xxx_init_irq,
        .init_time      = cns3xxx_timer_init,
index e38b279f402c46977ed90323018044e431ede887..2ae28a69e3e55f69de95a0b498ac6acf7c58de70 100644 (file)
@@ -47,6 +47,38 @@ static struct map_desc cns3xxx_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(CNS3XXX_PM_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
+#ifdef CONFIG_PCI
+       }, {
+               .virtual        = CNS3XXX_PCIE0_HOST_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PCIE0_HOST_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_PCIE0_CFG0_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PCIE0_CFG0_BASE),
+               .length         = SZ_64K, /* really 4 KiB at offset 32 KiB */
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_PCIE0_CFG1_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PCIE0_CFG1_BASE),
+               .length         = SZ_16M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_PCIE1_HOST_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PCIE1_HOST_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_PCIE1_CFG0_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PCIE1_CFG0_BASE),
+               .length         = SZ_64K, /* really 4 KiB at offset 32 KiB */
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_PCIE1_CFG1_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PCIE1_CFG1_BASE),
+               .length         = SZ_16M,
+               .type           = MT_DEVICE,
+#endif
        },
 };
 
@@ -155,7 +187,7 @@ static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction cns3xxx_timer_irq = {
        .name           = "timer",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = cns3xxx_timer_interrupt,
 };
 
@@ -368,7 +400,6 @@ static const char *cns3xxx_dt_compat[] __initdata = {
 
 DT_MACHINE_START(CNS3XXX_DT, "Cavium Networks CNS3xxx")
        .dt_compat      = cns3xxx_dt_compat,
-       .nr_irqs        = NR_IRQS_CNS3XXX,
        .map_io         = cns3xxx_map_io,
        .init_irq       = cns3xxx_init_irq,
        .init_time      = cns3xxx_timer_init,
index c7b204bff3866141d2d8ead8416cfbaef8f57d9b..413134c54452b5d7fa2a91c0b1f68978eb79c811 100644 (file)
 #include "cns3xxx.h"
 #include "core.h"
 
-enum cns3xxx_access_type {
-       CNS3XXX_HOST_TYPE = 0,
-       CNS3XXX_CFG0_TYPE,
-       CNS3XXX_CFG1_TYPE,
-       CNS3XXX_NUM_ACCESS_TYPES,
-};
-
 struct cns3xxx_pcie {
-       struct map_desc cfg_bases[CNS3XXX_NUM_ACCESS_TYPES];
+       void __iomem *host_regs; /* PCI config registers for host bridge */
+       void __iomem *cfg0_regs; /* PCI Type 0 config registers */
+       void __iomem *cfg1_regs; /* PCI Type 1 config registers */
        unsigned int irqs[2];
        struct resource res_io;
        struct resource res_mem;
@@ -66,7 +61,6 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
        int busno = bus->number;
        int slot = PCI_SLOT(devfn);
        int offset;
-       enum cns3xxx_access_type type;
        void __iomem *base;
 
        /* If there is no link, just show the CNS PCI bridge. */
@@ -78,17 +72,21 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
         * we still want to access it. For this to work, we must place
         * the first device on the same bus as the CNS PCI bridge.
         */
-       if (busno == 0) {
-               if (slot > 1)
-                       return NULL;
-               type = slot;
-       } else {
-               type = CNS3XXX_CFG1_TYPE;
-       }
+       if (busno == 0) { /* directly connected PCIe bus */
+               switch (slot) {
+               case 0: /* host bridge device, function 0 only */
+                       base = cnspci->host_regs;
+                       break;
+               case 1: /* directly connected device */
+                       base = cnspci->cfg0_regs;
+                       break;
+               default:
+                       return NULL; /* no such device */
+               }
+       } else /* remote PCI bus */
+               base = cnspci->cfg1_regs;
 
-       base = (void __iomem *)cnspci->cfg_bases[type].virtual;
        offset = ((busno & 0xf) << 20) | (devfn << 12) | (where & 0xffc);
-
        return base + offset;
 }
 
@@ -180,36 +178,19 @@ static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 
 static struct cns3xxx_pcie cns3xxx_pcie[] = {
        [0] = {
-               .cfg_bases = {
-                       [CNS3XXX_HOST_TYPE] = {
-                               .virtual = CNS3XXX_PCIE0_HOST_BASE_VIRT,
-                               .pfn = __phys_to_pfn(CNS3XXX_PCIE0_HOST_BASE),
-                               .length = SZ_16M,
-                               .type = MT_DEVICE,
-                       },
-                       [CNS3XXX_CFG0_TYPE] = {
-                               .virtual = CNS3XXX_PCIE0_CFG0_BASE_VIRT,
-                               .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG0_BASE),
-                               .length = SZ_16M,
-                               .type = MT_DEVICE,
-                       },
-                       [CNS3XXX_CFG1_TYPE] = {
-                               .virtual = CNS3XXX_PCIE0_CFG1_BASE_VIRT,
-                               .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG1_BASE),
-                               .length = SZ_16M,
-                               .type = MT_DEVICE,
-                       },
-               },
+               .host_regs = (void __iomem *)CNS3XXX_PCIE0_HOST_BASE_VIRT,
+               .cfg0_regs = (void __iomem *)CNS3XXX_PCIE0_CFG0_BASE_VIRT,
+               .cfg1_regs = (void __iomem *)CNS3XXX_PCIE0_CFG1_BASE_VIRT,
                .res_io = {
                        .name = "PCIe0 I/O space",
                        .start = CNS3XXX_PCIE0_IO_BASE,
-                       .end = CNS3XXX_PCIE0_IO_BASE + SZ_16M - 1,
+                       .end = CNS3XXX_PCIE0_CFG0_BASE - 1, /* 16 MiB */
                        .flags = IORESOURCE_IO,
                },
                .res_mem = {
                        .name = "PCIe0 non-prefetchable",
                        .start = CNS3XXX_PCIE0_MEM_BASE,
-                       .end = CNS3XXX_PCIE0_MEM_BASE + SZ_16M - 1,
+                       .end = CNS3XXX_PCIE0_HOST_BASE - 1, /* 176 MiB */
                        .flags = IORESOURCE_MEM,
                },
                .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, },
@@ -222,36 +203,19 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = {
                },
        },
        [1] = {
-               .cfg_bases = {
-                       [CNS3XXX_HOST_TYPE] = {
-                               .virtual = CNS3XXX_PCIE1_HOST_BASE_VIRT,
-                               .pfn = __phys_to_pfn(CNS3XXX_PCIE1_HOST_BASE),
-                               .length = SZ_16M,
-                               .type = MT_DEVICE,
-                       },
-                       [CNS3XXX_CFG0_TYPE] = {
-                               .virtual = CNS3XXX_PCIE1_CFG0_BASE_VIRT,
-                               .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG0_BASE),
-                               .length = SZ_16M,
-                               .type = MT_DEVICE,
-                       },
-                       [CNS3XXX_CFG1_TYPE] = {
-                               .virtual = CNS3XXX_PCIE1_CFG1_BASE_VIRT,
-                               .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG1_BASE),
-                               .length = SZ_16M,
-                               .type = MT_DEVICE,
-                       },
-               },
+               .host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT,
+               .cfg0_regs = (void __iomem *)CNS3XXX_PCIE1_CFG0_BASE_VIRT,
+               .cfg1_regs = (void __iomem *)CNS3XXX_PCIE1_CFG1_BASE_VIRT,
                .res_io = {
                        .name = "PCIe1 I/O space",
                        .start = CNS3XXX_PCIE1_IO_BASE,
-                       .end = CNS3XXX_PCIE1_IO_BASE + SZ_16M - 1,
+                       .end = CNS3XXX_PCIE1_CFG0_BASE - 1, /* 16 MiB */
                        .flags = IORESOURCE_IO,
                },
                .res_mem = {
                        .name = "PCIe1 non-prefetchable",
                        .start = CNS3XXX_PCIE1_MEM_BASE,
-                       .end = CNS3XXX_PCIE1_MEM_BASE + SZ_16M - 1,
+                       .end = CNS3XXX_PCIE1_HOST_BASE - 1, /* 176 MiB */
                        .flags = IORESOURCE_MEM,
                },
                .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, },
@@ -307,18 +271,15 @@ static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
                .ops = &cns3xxx_pcie_ops,
                .sysdata = &sd,
        };
-       u32 io_base = cnspci->res_io.start >> 16;
-       u32 mem_base = cnspci->res_mem.start >> 16;
-       u32 host_base = cnspci->cfg_bases[CNS3XXX_HOST_TYPE].pfn;
-       u32 cfg0_base = cnspci->cfg_bases[CNS3XXX_CFG0_TYPE].pfn;
+       u16 mem_base  = cnspci->res_mem.start >> 16;
+       u16 mem_limit = cnspci->res_mem.end   >> 16;
+       u16 io_base   = cnspci->res_io.start  >> 16;
+       u16 io_limit  = cnspci->res_io.end    >> 16;
        u32 devfn = 0;
        u8 tmp8;
        u16 pos;
        u16 dc;
 
-       host_base = (__pfn_to_phys(host_base) - 1) >> 16;
-       cfg0_base = (__pfn_to_phys(cfg0_base) - 1) >> 16;
-
        pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0);
        pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1);
        pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1);
@@ -328,9 +289,9 @@ static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
        pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8);
 
        pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base);
-       pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, host_base);
+       pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, mem_limit);
        pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
-       pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, cfg0_base);
+       pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, io_limit);
 
        if (!cnspci->linked)
                return;
@@ -368,8 +329,6 @@ static int __init cns3xxx_pcie_init(void)
                        "imprecise external abort");
 
        for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
-               iotable_init(cns3xxx_pcie[i].cfg_bases,
-                            ARRAY_SIZE(cns3xxx_pcie[i].cfg_bases));
                cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE(i));
                cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i));
                cns3xxx_pcie_check_link(&cns3xxx_pcie[i]);
index a075b3e0c5c7a5229aa87163e732d9c6b49a7a50..db18ef866593882ccda3216f90be35827a4a8f23 100644 (file)
@@ -51,11 +51,6 @@ config ARCH_DAVINCI_DM365
        select AINTC
        select ARCH_DAVINCI_DMx
 
-config ARCH_DAVINCI_TNETV107X
-       bool "TNETV107X based system"
-       select CPU_V6
-       select CP_INTC
-
 comment "DaVinci Board Type"
 
 config MACH_DA8XX_DT
@@ -214,18 +209,6 @@ config DA850_WL12XX
          Say Y if you want to use a wl1271 expansion card connected to the
          AM18x EVM.
 
-config GPIO_PCA953X
-       default MACH_DAVINCI_DA850_EVM
-
-config KEYBOARD_GPIO_POLLED
-       default MACH_DAVINCI_DA850_EVM
-
-config MACH_TNETV107X
-       bool "TI TNETV107X Reference Platform"
-       default ARCH_DAVINCI_TNETV107X
-       depends on ARCH_DAVINCI_TNETV107X
-       help
-         Say Y here to select the TI TNETV107X Evaluation Module.
 
 config MACH_MITYOMAPL138
        bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
index 63997a1128e68ce008e977c42b9d4e849101203a..2204239ed243335545613f4a63f23f5e18daba60 100644 (file)
@@ -16,7 +16,6 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x)       += dm646x.o devices.o
 obj-$(CONFIG_ARCH_DAVINCI_DM365)       += dm365.o devices.o
 obj-$(CONFIG_ARCH_DAVINCI_DA830)        += da830.o devices-da8xx.o
 obj-$(CONFIG_ARCH_DAVINCI_DA850)        += da850.o devices-da8xx.o
-obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)    += tnetv107x.o devices-tnetv107x.o
 
 obj-$(CONFIG_AINTC)                    += irq.o
 obj-$(CONFIG_CP_INTC)                  += cp_intc.o
@@ -32,7 +31,6 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
 obj-$(CONFIG_MACH_DAVINCI_DM365_EVM)   += board-dm365-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA830_EVM)   += board-da830-evm.o
 obj-$(CONFIG_MACH_DAVINCI_DA850_EVM)   += board-da850-evm.o
-obj-$(CONFIG_MACH_TNETV107X)           += board-tnetv107x-evm.o
 obj-$(CONFIG_MACH_MITYOMAPL138)                += board-mityomapl138.o
 obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD)  += board-omapl138-hawk.o
 
index 04a6c4e67b146dee4aeaab855b55a63f554e3674..4b81601754a2ab8de29ab5ebf3dc2a8fc2f235ad 100644 (file)
@@ -1,13 +1,7 @@
-ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
-ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
-$(error Cannot enable DaVinci and DA8XX platforms concurrently)
-else
-   zreladdr-y  += 0xc0008000
-params_phys-y  := 0xc0000100
-initrd_phys-y  := 0xc0800000
-endif
-else
-   zreladdr-y  += 0x80008000
-params_phys-y  := 0x80000100
-initrd_phys-y  := 0x80800000
-endif
+zreladdr-$(CONFIG_ARCH_DAVINCI_DA8XX)          += 0xc0008000
+params_phys-$(CONFIG_ARCH_DAVINCI_DA8XX)       := 0xc0000100
+initrd_phys-$(CONFIG_ARCH_DAVINCI_DA8XX)       := 0xc0800000
+
+zreladdr-$(CONFIG_ARCH_DAVINCI_DMx)            += 0x80008000
+params_phys-$(CONFIG_ARCH_DAVINCI_DMx)         := 0x80000100
+initrd_phys-$(CONFIG_ARCH_DAVINCI_DMx)         := 0x80800000
index f091a9010c2fb3b36ece218f87a228057edac487..ff8b7e76b6e961f9493e8b070db8d249359d58fa 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/time.h>
 
 #include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/mtd-davinci.h>
 
 /* Timing value configuration */
 
                                WSTROBE(WSTROBE_MAX) | \
                                WSETUP(WSETUP_MAX))
 
+static inline unsigned int davinci_aemif_readl(void __iomem *base, int offset)
+{
+       return readl_relaxed(base + offset);
+}
+
+static inline void davinci_aemif_writel(void __iomem *base,
+                                       int offset, unsigned long value)
+{
+       writel_relaxed(value, base + offset);
+}
+
 /*
  * aemif_calc_rate - calculate timing data.
  * @wanted: The cycle time needed in nanoseconds.
@@ -76,6 +88,7 @@ static int aemif_calc_rate(int wanted, unsigned long clk, int max)
  * @t: timing values to be progammed
  * @base: The virtual base address of the AEMIF interface
  * @cs: chip-select to program the timing values for
+ * @clkrate: the AEMIF clkrate
  *
  * This function programs the given timing values (in real clock) into the
  * AEMIF registers taking the AEMIF clock into account.
@@ -86,24 +99,17 @@ static int aemif_calc_rate(int wanted, unsigned long clk, int max)
  *
  * Returns 0 on success, else negative errno.
  */
-int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
-                                       void __iomem *base, unsigned cs)
+static int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+                                       void __iomem *base, unsigned cs,
+                                       unsigned long clkrate)
 {
        unsigned set, val;
        int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
        unsigned offset = A1CR_OFFSET + cs * 4;
-       struct clk *aemif_clk;
-       unsigned long clkrate;
 
        if (!t)
                return 0;       /* Nothing to do */
 
-       aemif_clk = clk_get(NULL, "aemif");
-       if (IS_ERR(aemif_clk))
-               return PTR_ERR(aemif_clk);
-
-       clkrate = clk_get_rate(aemif_clk);
-
        clkrate /= 1000;        /* turn clock into kHz for ease of use */
 
        ta      = aemif_calc_rate(t->ta, clkrate, TA_MAX);
@@ -130,4 +136,83 @@ int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
 
        return 0;
 }
-EXPORT_SYMBOL(davinci_aemif_setup_timing);
+
+/**
+ * davinci_aemif_setup - setup AEMIF interface by davinci_nand_pdata
+ * @pdev - link to platform device to setup settings for
+ *
+ * This function does not use any locking while programming the AEMIF
+ * because it is expected that there is only one user of a given
+ * chip-select.
+ *
+ * Returns 0 on success, else negative errno.
+ */
+int davinci_aemif_setup(struct platform_device *pdev)
+{
+       struct davinci_nand_pdata *pdata = dev_get_platdata(&pdev->dev);
+       uint32_t val;
+       unsigned long clkrate;
+       struct resource *res;
+       void __iomem *base;
+       struct clk *clk;
+       int ret = 0;
+
+       clk = clk_get(&pdev->dev, "aemif");
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
+               dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(clk);
+       if (ret < 0) {
+               dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
+                       ret);
+               goto err_put;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!res) {
+               dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       base = ioremap(res->start, resource_size(res));
+       if (!base) {
+               dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res);
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       /*
+        * Setup Async configuration register in case we did not boot
+        * from NAND and so bootloader did not bother to set it up.
+        */
+       val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4);
+       /*
+        * Extended Wait is not valid and Select Strobe mode is not
+        * used
+        */
+       val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
+       if (pdata->options & NAND_BUSWIDTH_16)
+               val |= 0x1;
+
+       davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val);
+
+       clkrate = clk_get_rate(clk);
+
+       if (pdata->timing)
+               ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id,
+                                                clkrate);
+
+       if (ret < 0)
+               dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
+
+       iounmap(base);
+err:
+       clk_disable_unprepare(clk);
+err_put:
+       clk_put(clk);
+       return ret;
+}
index d1f45af7a530e9abc33d794fcc6cf52010cfc52b..5623131c4f0b6108a289872d445174f1ce2473d9 100644 (file)
@@ -419,6 +419,9 @@ static inline void da830_evm_init_nand(int mux_mode)
        if (ret)
                pr_warning("da830_evm_init: NAND device not registered.\n");
 
+       if (davinci_aemif_setup(&da830_evm_nand_device))
+               pr_warn("%s: Cannot configure AEMIF.\n", __func__);
+
        gpio_direction_output(mux_mode, 1);
 }
 #else
index e0af0eccde8fbe0d9f54abaeb339ee974db4c2d2..234c5bb091f5119f6c044620cc204bdbb63655e7 100644 (file)
@@ -358,6 +358,9 @@ static inline void da850_evm_setup_nor_nand(void)
 
                platform_add_devices(da850_evm_devices,
                                        ARRAY_SIZE(da850_evm_devices));
+
+               if (davinci_aemif_setup(&da850_evm_nandflash_device))
+                       pr_warn("%s: Cannot configure AEMIF.\n", __func__);
        }
 }
 
index 987605b78556f9e8fa16b1e9b1b278ad0abe4d1c..e583e58b5e1ee7e2f30d782ef133ce76d2935dbf 100644 (file)
@@ -778,6 +778,11 @@ static __init void davinci_evm_init(void)
                /* only one device will be jumpered and detected */
                if (HAS_NAND) {
                        platform_device_register(&davinci_evm_nandflash_device);
+
+                       if (davinci_aemif_setup(&davinci_evm_nandflash_device))
+                               pr_warn("%s: Cannot configure AEMIF.\n",
+                                       __func__);
+
                        evm_leds[7].default_trigger = "nand-disk";
                        if (HAS_NOR)
                                pr_warning("WARNING: both NAND and NOR flash "
@@ -799,11 +804,12 @@ static __init void davinci_evm_init(void)
        /* irlml6401 switches over 1A, in under 8 msec */
        davinci_setup_usb(1000, 8);
 
-       soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID;
-       /* Register the fixup for PHY on DaVinci */
-       phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
-                                       davinci_phy_fixup);
-
+       if (IS_BUILTIN(CONFIG_PHYLIB)) {
+               soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID;
+               /* Register the fixup for PHY on DaVinci */
+               phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
+                                               davinci_phy_fixup);
+       }
 }
 
 MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
index 13d0801fd6b170e155dfe3d4cf8c069522c4baf7..ae129bc4927381f44759eb2b745d97e0a1ea9e34 100644 (file)
@@ -805,6 +805,9 @@ static __init void evm_init(void)
 
        platform_device_register(&davinci_nand_device);
 
+       if (davinci_aemif_setup(&davinci_nand_device))
+               pr_warn("%s: Cannot configure AEMIF.\n", __func__);
+
        dm646x_init_edma(dm646x_edma_rsv);
 
        if (HAS_ATA)
index 7aa105b1fd0f7553170134c9a8dae654c931784d..96fc00a167f5cc61e5cc877cca97fe5367ae25b4 100644 (file)
@@ -27,6 +27,7 @@
 #include <mach/cp_intc.h>
 #include <mach/da8xx.h>
 #include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
 #include <mach/mux.h>
 #include <linux/platform_data/spi-davinci.h>
 
@@ -432,6 +433,9 @@ static void __init mityomapl138_setup_nand(void)
 {
        platform_add_devices(mityomapl138_devices,
                                 ARRAY_SIZE(mityomapl138_devices));
+
+       if (davinci_aemif_setup(&mityomapl138_nandflash_device))
+               pr_warn("%s: Cannot configure AEMIF.\n", __func__);
 }
 
 static const short mityomap_mii_pins[] = {
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
deleted file mode 100644 (file)
index 78ea395..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Texas Instruments TNETV107X EVM Board Support
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/ratelimit.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/input.h>
-#include <linux/input/matrix_keypad.h>
-#include <linux/spi/spi.h>
-#include <linux/platform_data/edma.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <mach/irqs.h>
-#include <mach/mux.h>
-#include <mach/cp_intc.h>
-#include <mach/tnetv107x.h>
-
-#define EVM_MMC_WP_GPIO                21
-#define EVM_MMC_CD_GPIO                24
-#define EVM_SPI_CS_GPIO                54
-
-static int initialize_gpio(int gpio, char *desc)
-{
-       int ret;
-
-       ret = gpio_request(gpio, desc);
-       if (ret < 0) {
-               pr_err_ratelimited("cannot open %s gpio\n", desc);
-               return -ENOSYS;
-       }
-       gpio_direction_input(gpio);
-       return gpio;
-}
-
-static int mmc_get_cd(int index)
-{
-       static int gpio;
-
-       if (!gpio)
-               gpio = initialize_gpio(EVM_MMC_CD_GPIO, "mmc card detect");
-
-       if (gpio < 0)
-               return gpio;
-
-       return gpio_get_value(gpio) ? 0 : 1;
-}
-
-static int mmc_get_ro(int index)
-{
-       static int gpio;
-
-       if (!gpio)
-               gpio = initialize_gpio(EVM_MMC_WP_GPIO, "mmc write protect");
-
-       if (gpio < 0)
-               return gpio;
-
-       return gpio_get_value(gpio) ? 1 : 0;
-}
-
-static struct davinci_mmc_config mmc_config = {
-       .get_cd         = mmc_get_cd,
-       .get_ro         = mmc_get_ro,
-       .wires          = 4,
-       .max_freq       = 50000000,
-       .caps           = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
-};
-
-static const short sdio1_pins[] __initconst = {
-       TNETV107X_SDIO1_CLK_1,          TNETV107X_SDIO1_CMD_1,
-       TNETV107X_SDIO1_DATA0_1,        TNETV107X_SDIO1_DATA1_1,
-       TNETV107X_SDIO1_DATA2_1,        TNETV107X_SDIO1_DATA3_1,
-       TNETV107X_GPIO21,               TNETV107X_GPIO24,
-       -1
-};
-
-static const short uart1_pins[] __initconst = {
-       TNETV107X_UART1_RD,             TNETV107X_UART1_TD,
-       -1
-};
-
-static const short ssp_pins[] __initconst = {
-       TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2,
-       TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2,
-       TNETV107X_SSP1_3, -1
-};
-
-static struct mtd_partition nand_partitions[] = {
-       /* bootloader (U-Boot, etc) in first 12 sectors */
-       {
-               .name           = "bootloader",
-               .offset         = 0,
-               .size           = (12*SZ_128K),
-               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
-       },
-       /* bootloader params in the next sector */
-       {
-               .name           = "params",
-               .offset         = MTDPART_OFS_NXTBLK,
-               .size           = SZ_128K,
-               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
-       },
-       /* kernel */
-       {
-               .name           = "kernel",
-               .offset         = MTDPART_OFS_NXTBLK,
-               .size           = SZ_4M,
-               .mask_flags     = 0,
-       },
-       /* file system */
-       {
-               .name           = "filesystem",
-               .offset         = MTDPART_OFS_NXTBLK,
-               .size           = MTDPART_SIZ_FULL,
-               .mask_flags     = 0,
-       }
-};
-
-static struct davinci_nand_pdata nand_config = {
-       .mask_cle       = 0x4000,
-       .mask_ale       = 0x2000,
-       .parts          = nand_partitions,
-       .nr_parts       = ARRAY_SIZE(nand_partitions),
-       .ecc_mode       = NAND_ECC_HW,
-       .bbt_options    = NAND_BBT_USE_FLASH,
-       .ecc_bits       = 1,
-};
-
-static struct davinci_uart_config serial_config __initconst = {
-       .enabled_uarts  = BIT(1),
-};
-
-static const uint32_t keymap[] = {
-       KEY(0, 0, KEY_NUMERIC_1),
-       KEY(0, 1, KEY_NUMERIC_2),
-       KEY(0, 2, KEY_NUMERIC_3),
-       KEY(0, 3, KEY_FN_F1),
-       KEY(0, 4, KEY_MENU),
-
-       KEY(1, 0, KEY_NUMERIC_4),
-       KEY(1, 1, KEY_NUMERIC_5),
-       KEY(1, 2, KEY_NUMERIC_6),
-       KEY(1, 3, KEY_UP),
-       KEY(1, 4, KEY_FN_F2),
-
-       KEY(2, 0, KEY_NUMERIC_7),
-       KEY(2, 1, KEY_NUMERIC_8),
-       KEY(2, 2, KEY_NUMERIC_9),
-       KEY(2, 3, KEY_LEFT),
-       KEY(2, 4, KEY_ENTER),
-
-       KEY(3, 0, KEY_NUMERIC_STAR),
-       KEY(3, 1, KEY_NUMERIC_0),
-       KEY(3, 2, KEY_NUMERIC_POUND),
-       KEY(3, 3, KEY_DOWN),
-       KEY(3, 4, KEY_RIGHT),
-
-       KEY(4, 0, KEY_FN_F3),
-       KEY(4, 1, KEY_FN_F4),
-       KEY(4, 2, KEY_MUTE),
-       KEY(4, 3, KEY_HOME),
-       KEY(4, 4, KEY_BACK),
-
-       KEY(5, 0, KEY_VOLUMEDOWN),
-       KEY(5, 1, KEY_VOLUMEUP),
-       KEY(5, 2, KEY_F1),
-       KEY(5, 3, KEY_F2),
-       KEY(5, 4, KEY_F3),
-};
-
-static const struct matrix_keymap_data keymap_data = {
-       .keymap         = keymap,
-       .keymap_size    = ARRAY_SIZE(keymap),
-};
-
-static struct matrix_keypad_platform_data keypad_config = {
-       .keymap_data    = &keymap_data,
-       .num_row_gpios  = 6,
-       .num_col_gpios  = 5,
-       .debounce_ms    = 0, /* minimum */
-       .active_low     = 0, /* pull up realization */
-       .no_autorepeat  = 0,
-};
-
-static void spi_select_device(int cs)
-{
-       static int gpio;
-
-       if (!gpio) {
-               int ret;
-               ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel");
-               if (ret < 0) {
-                       pr_err("cannot open spi chipsel gpio\n");
-                       gpio = -ENOSYS;
-                       return;
-               } else {
-                       gpio = EVM_SPI_CS_GPIO;
-                       gpio_direction_output(gpio, 0);
-               }
-       }
-
-       if (gpio < 0)
-               return;
-
-       return gpio_set_value(gpio, cs ? 1 : 0);
-}
-
-static struct ti_ssp_spi_data spi_master_data = {
-       .num_cs = 2,
-       .select = spi_select_device,
-       .iosel  = SSP_PIN_SEL(0, SSP_CLOCK)     | SSP_PIN_SEL(1, SSP_DATA) |
-                 SSP_PIN_SEL(2, SSP_CHIPSEL)   | SSP_PIN_SEL(3, SSP_IN)   |
-                 SSP_INPUT_SEL(3),
-};
-
-static struct ti_ssp_data ssp_config = {
-       .out_clock      = 250 * 1000,
-       .dev_data       = {
-               [1] = {
-                       .dev_name = "ti-ssp-spi",
-                       .pdata = &spi_master_data,
-                       .pdata_size = sizeof(spi_master_data),
-               },
-       },
-};
-
-static struct tnetv107x_device_info evm_device_info __initconst = {
-       .serial_config          = &serial_config,
-       .mmc_config[1]          = &mmc_config,  /* controller 1 */
-       .nand_config[0]         = &nand_config, /* chip select 0 */
-       .keypad_config          = &keypad_config,
-       .ssp_config             = &ssp_config,
-};
-
-static struct spi_board_info spi_info[] __initconst = {
-};
-
-static __init void tnetv107x_evm_board_init(void)
-{
-       davinci_cfg_reg_list(sdio1_pins);
-       davinci_cfg_reg_list(uart1_pins);
-       davinci_cfg_reg_list(ssp_pins);
-
-       tnetv107x_devices_init(&evm_device_info);
-
-       spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
-}
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-static int __init tnetv107x_evm_console_init(void)
-{
-       return add_preferred_console("ttyS", 0, "115200");
-}
-console_initcall(tnetv107x_evm_console_init);
-#endif
-
-MACHINE_START(TNETV107X, "TNETV107X EVM")
-       .atag_offset    = 0x100,
-       .map_io         = tnetv107x_init,
-       .init_irq       = cp_intc_init,
-       .init_time      = davinci_timer_init,
-       .init_machine   = tnetv107x_evm_board_init,
-       .init_late      = davinci_init_late,
-       .dma_zone_size  = SZ_128M,
-       .restart        = tnetv107x_restart,
-MACHINE_END
index 2eebc433880223b0ed2c5fe18c56aa11807cd699..4ffc37accce074fa639c1b6821f50c8c45455b47 100644 (file)
@@ -79,6 +79,8 @@ int davinci_gpio_register(struct resource *res, int size, void *pdata);
 #define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
 #define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
 
+int davinci_init_wdt(void);
+
 /* DM355 function declarations */
 void dm355_init(void);
 void dm355_init_spi0(unsigned chipselect_mask,
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
deleted file mode 100644 (file)
index 01d8686..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Texas Instruments TNETV107X SoC devices
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/platform_data/edma.h>
-
-#include <mach/common.h>
-#include <mach/irqs.h>
-#include <mach/tnetv107x.h>
-
-#include "clock.h"
-
-/* Base addresses for on-chip devices */
-#define TNETV107X_TPCC_BASE                    0x01c00000
-#define TNETV107X_TPTC0_BASE                   0x01c10000
-#define TNETV107X_TPTC1_BASE                   0x01c10400
-#define TNETV107X_WDOG_BASE                    0x08086700
-#define TNETV107X_TSC_BASE                     0x08088500
-#define TNETV107X_SDIO0_BASE                   0x08088700
-#define TNETV107X_SDIO1_BASE                   0x08088800
-#define TNETV107X_KEYPAD_BASE                  0x08088a00
-#define TNETV107X_SSP_BASE                     0x08088c00
-#define TNETV107X_ASYNC_EMIF_CNTRL_BASE                0x08200000
-#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE     0x30000000
-#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE     0x40000000
-#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE     0x44000000
-#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE     0x48000000
-
-/* TNETV107X specific EDMA3 information */
-#define EDMA_TNETV107X_NUM_DMACH       64
-#define EDMA_TNETV107X_NUM_TCC         64
-#define EDMA_TNETV107X_NUM_PARAMENTRY  128
-#define EDMA_TNETV107X_NUM_EVQUE       2
-#define EDMA_TNETV107X_NUM_TC          2
-#define EDMA_TNETV107X_CHMAP_EXIST     0
-#define EDMA_TNETV107X_NUM_REGIONS     4
-#define TNETV107X_DMACH2EVENT_MAP0     0x3C0CE000u
-#define TNETV107X_DMACH2EVENT_MAP1     0x000FFFFFu
-
-#define TNETV107X_DMACH_SDIO0_RX               26
-#define TNETV107X_DMACH_SDIO0_TX               27
-#define TNETV107X_DMACH_SDIO1_RX               28
-#define TNETV107X_DMACH_SDIO1_TX               29
-
-static s8 edma_tc_mapping[][2] = {
-       /* event queue no       TC no   */
-       {        0,              0      },
-       {        1,              1      },
-       {       -1,             -1      }
-};
-
-static s8 edma_priority_mapping[][2] = {
-       /* event queue no       Prio    */
-       {        0,              3      },
-       {        1,              7      },
-       {       -1,             -1      }
-};
-
-static struct edma_soc_info edma_cc0_info = {
-       .n_channel              = EDMA_TNETV107X_NUM_DMACH,
-       .n_region               = EDMA_TNETV107X_NUM_REGIONS,
-       .n_slot                 = EDMA_TNETV107X_NUM_PARAMENTRY,
-       .n_tc                   = EDMA_TNETV107X_NUM_TC,
-       .n_cc                   = 1,
-       .queue_tc_mapping       = edma_tc_mapping,
-       .queue_priority_mapping = edma_priority_mapping,
-       .default_queue          = EVENTQ_1,
-};
-
-static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
-       &edma_cc0_info,
-};
-
-static struct resource edma_resources[] = {
-       {
-               .name   = "edma_cc0",
-               .start  = TNETV107X_TPCC_BASE,
-               .end    = TNETV107X_TPCC_BASE + SZ_32K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "edma_tc0",
-               .start  = TNETV107X_TPTC0_BASE,
-               .end    = TNETV107X_TPTC0_BASE + SZ_1K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "edma_tc1",
-               .start  = TNETV107X_TPTC1_BASE,
-               .end    = TNETV107X_TPTC1_BASE + SZ_1K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .name   = "edma0",
-               .start  = IRQ_TNETV107X_TPCC,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .name   = "edma0_err",
-               .start  = IRQ_TNETV107X_TPCC_ERR,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device edma_device = {
-       .name           = "edma",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(edma_resources),
-       .resource       = edma_resources,
-       .dev.platform_data = tnetv107x_edma_info,
-};
-
-static struct plat_serial8250_port serial0_platform_data[] = {
-       {
-               .mapbase        = TNETV107X_UART0_BASE,
-               .irq            = IRQ_TNETV107X_UART0,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
-                                       UPF_FIXED_TYPE | UPF_IOREMAP,
-               .type           = PORT_AR7,
-               .iotype         = UPIO_MEM32,
-               .regshift       = 2,
-       },
-       {
-               .flags  = 0,
-       }
-};
-static struct plat_serial8250_port serial1_platform_data[] = {
-       {
-               .mapbase        = TNETV107X_UART1_BASE,
-               .irq            = IRQ_TNETV107X_UART1,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
-                                       UPF_FIXED_TYPE | UPF_IOREMAP,
-               .type           = PORT_AR7,
-               .iotype         = UPIO_MEM32,
-               .regshift       = 2,
-       },
-       {
-               .flags  = 0,
-       }
-};
-static struct plat_serial8250_port serial2_platform_data[] = {
-       {
-               .mapbase        = TNETV107X_UART2_BASE,
-               .irq            = IRQ_TNETV107X_UART2,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
-                                       UPF_FIXED_TYPE | UPF_IOREMAP,
-               .type           = PORT_AR7,
-               .iotype         = UPIO_MEM32,
-               .regshift       = 2,
-       },
-       {
-               .flags  = 0,
-       }
-};
-
-
-struct platform_device tnetv107x_serial_device[] = {
-       {
-               .name                   = "serial8250",
-               .id                     = PLAT8250_DEV_PLATFORM,
-               .dev.platform_data      = serial0_platform_data,
-       },
-       {
-               .name                   = "serial8250",
-               .id                     = PLAT8250_DEV_PLATFORM1,
-               .dev.platform_data      = serial1_platform_data,
-       },
-       {
-               .name                   = "serial8250",
-               .id                     = PLAT8250_DEV_PLATFORM2,
-               .dev.platform_data      = serial2_platform_data,
-       },
-       {
-       }
-};
-
-static struct resource mmc0_resources[] = {
-       { /* Memory mapped registers */
-               .start  = TNETV107X_SDIO0_BASE,
-               .end    = TNETV107X_SDIO0_BASE + 0x0ff,
-               .flags  = IORESOURCE_MEM
-       },
-       { /* MMC interrupt */
-               .start  = IRQ_TNETV107X_MMC0,
-               .flags  = IORESOURCE_IRQ
-       },
-       { /* SDIO interrupt */
-               .start  = IRQ_TNETV107X_SDIO0,
-               .flags  = IORESOURCE_IRQ
-       },
-       { /* DMA RX */
-               .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX),
-               .flags  = IORESOURCE_DMA
-       },
-       { /* DMA TX */
-               .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX),
-               .flags  = IORESOURCE_DMA
-       },
-};
-
-static struct resource mmc1_resources[] = {
-       { /* Memory mapped registers */
-               .start  = TNETV107X_SDIO1_BASE,
-               .end    = TNETV107X_SDIO1_BASE + 0x0ff,
-               .flags  = IORESOURCE_MEM
-       },
-       { /* MMC interrupt */
-               .start  = IRQ_TNETV107X_MMC1,
-               .flags  = IORESOURCE_IRQ
-       },
-       { /* SDIO interrupt */
-               .start  = IRQ_TNETV107X_SDIO1,
-               .flags  = IORESOURCE_IRQ
-       },
-       { /* DMA RX */
-               .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX),
-               .flags  = IORESOURCE_DMA
-       },
-       { /* DMA TX */
-               .start  = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX),
-               .flags  = IORESOURCE_DMA
-       },
-};
-
-static u64 mmc0_dma_mask = DMA_BIT_MASK(32);
-static u64 mmc1_dma_mask = DMA_BIT_MASK(32);
-
-static struct platform_device mmc_devices[2] = {
-       {
-               .name           = "dm6441-mmc",
-               .id             = 0,
-               .dev            = {
-                       .dma_mask               = &mmc0_dma_mask,
-                       .coherent_dma_mask      = DMA_BIT_MASK(32),
-               },
-               .num_resources  = ARRAY_SIZE(mmc0_resources),
-               .resource       = mmc0_resources
-       },
-       {
-               .name           = "dm6441-mmc",
-               .id             = 1,
-               .dev            = {
-                       .dma_mask               = &mmc1_dma_mask,
-                       .coherent_dma_mask      = DMA_BIT_MASK(32),
-               },
-               .num_resources  = ARRAY_SIZE(mmc1_resources),
-               .resource       = mmc1_resources
-       },
-};
-
-static const u32 emif_windows[] = {
-       TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE,
-       TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE,
-};
-
-static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M };
-
-static struct resource wdt_resources[] = {
-       {
-               .start  = TNETV107X_WDOG_BASE,
-               .end    = TNETV107X_WDOG_BASE + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-struct platform_device tnetv107x_wdt_device = {
-       .name           = "tnetv107x_wdt",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(wdt_resources),
-       .resource       = wdt_resources,
-};
-
-static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)
-{
-       struct resource res[2];
-       struct platform_device *pdev;
-       u32     range;
-       int     ret;
-
-       /* Figure out the resource range from the ale/cle masks */
-       range = max(data->mask_cle, data->mask_ale);
-       range = PAGE_ALIGN(range + 4) - 1;
-
-       if (range >= emif_window_sizes[chipsel])
-               return -EINVAL;
-
-       pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
-       if (!pdev)
-               return -ENOMEM;
-
-       pdev->name              = "davinci_nand";
-       pdev->id                = chipsel;
-       pdev->dev.platform_data = data;
-
-       memset(res, 0, sizeof(res));
-
-       res[0].start    = emif_windows[chipsel];
-       res[0].end      = res[0].start + range;
-       res[0].flags    = IORESOURCE_MEM;
-
-       res[1].start    = TNETV107X_ASYNC_EMIF_CNTRL_BASE;
-       res[1].end      = res[1].start + SZ_4K - 1;
-       res[1].flags    = IORESOURCE_MEM;
-
-       ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
-       if (ret < 0) {
-               kfree(pdev);
-               return ret;
-       }
-
-       return platform_device_register(pdev);
-}
-
-static struct resource keypad_resources[] = {
-       {
-               .start  = TNETV107X_KEYPAD_BASE,
-               .end    = TNETV107X_KEYPAD_BASE + 0xff,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = IRQ_TNETV107X_KEYPAD,
-               .flags  = IORESOURCE_IRQ,
-               .name   = "press",
-       },
-       {
-               .start  = IRQ_TNETV107X_KEYPAD_FREE,
-               .flags  = IORESOURCE_IRQ,
-               .name   = "release",
-       },
-};
-
-static struct platform_device keypad_device = {
-       .name           = "tnetv107x-keypad",
-       .num_resources  = ARRAY_SIZE(keypad_resources),
-       .resource       = keypad_resources,
-};
-
-static struct resource tsc_resources[] = {
-       {
-               .start  = TNETV107X_TSC_BASE,
-               .end    = TNETV107X_TSC_BASE + 0xff,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = IRQ_TNETV107X_TSC,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device tsc_device = {
-       .name           = "tnetv107x-ts",
-       .num_resources  = ARRAY_SIZE(tsc_resources),
-       .resource       = tsc_resources,
-};
-
-static struct resource ssp_resources[] = {
-       {
-               .start  = TNETV107X_SSP_BASE,
-               .end    = TNETV107X_SSP_BASE + 0x1ff,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = IRQ_TNETV107X_SSP,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device ssp_device = {
-       .name           = "ti-ssp",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(ssp_resources),
-       .resource       = ssp_resources,
-};
-
-void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
-{
-       int i, error;
-       struct clk *tsc_clk;
-
-       /*
-        * The reset defaults for tnetv107x tsc clock divider is set too high.
-        * This forces the clock down to a range that allows the ADC to
-        * complete sample conversion in time.
-        */
-       tsc_clk = clk_get(NULL, "sys_tsc_clk");
-       if (!IS_ERR(tsc_clk)) {
-               error = clk_set_rate(tsc_clk, 5000000);
-               WARN_ON(error < 0);
-               clk_put(tsc_clk);
-       }
-
-       platform_device_register(&edma_device);
-       platform_device_register(&tnetv107x_wdt_device);
-       platform_device_register(&tsc_device);
-
-       if (info->serial_config)
-               davinci_serial_init(tnetv107x_serial_device);
-
-       for (i = 0; i < 2; i++)
-               if (info->mmc_config[i]) {
-                       mmc_devices[i].dev.platform_data = info->mmc_config[i];
-                       platform_device_register(&mmc_devices[i]);
-               }
-
-       for (i = 0; i < 4; i++)
-               if (info->nand_config[i])
-                       nand_init(i, info->nand_config[i]);
-
-       if (info->keypad_config) {
-               keypad_device.dev.platform_data = info->keypad_config;
-               platform_device_register(&keypad_device);
-       }
-
-       if (info->ssp_config) {
-               ssp_device.dev.platform_data = info->ssp_config;
-               platform_device_register(&ssp_device);
-       }
-}
index 5cf9a027dcc6ae23063182c2461f1ddb66339e7b..6257aa4525688e7232c40f2cf87c0847c4ba9baf 100644 (file)
@@ -313,9 +313,9 @@ void davinci_restart(enum reboot_mode mode, const char *cmd)
        davinci_watchdog_reset(&davinci_wdt_device);
 }
 
-static void davinci_init_wdt(void)
+int davinci_init_wdt(void)
 {
-       platform_device_register(&davinci_wdt_device);
+       return platform_device_register(&davinci_wdt_device);
 }
 
 static struct platform_device davinci_gpio_device = {
@@ -348,16 +348,3 @@ struct davinci_timer_instance davinci_timer_instance[2] = {
        },
 };
 
-/*-------------------------------------------------------------------------*/
-
-static int __init davinci_init_devices(void)
-{
-       /* please keep these calls, and their implementations above,
-        * in alphabetical order so they're easier to sort through.
-        */
-       davinci_init_wdt();
-
-       return 0;
-}
-arch_initcall(davinci_init_devices);
-
index 4668c0e197670123aea18a95a61a4cc78e796884..07381d8cea6297d25f173460aa3ce849da2c4852 100644 (file)
@@ -1076,12 +1076,18 @@ int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
 
 static int __init dm355_init_devices(void)
 {
+       int ret = 0;
+
        if (!cpu_is_davinci_dm355())
                return 0;
 
        davinci_cfg_reg(DM355_INT_EDMA_CC);
        platform_device_register(&dm355_edma_device);
 
-       return 0;
+       ret = davinci_init_wdt();
+       if (ret)
+               pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+       return ret;
 }
 postcore_initcall(dm355_init_devices);
index b44b49e2801af7b33842ed2e996cdf13fa600b63..08a61b9383337b67b801a4a706814285a936b9aa 100644 (file)
@@ -1436,6 +1436,8 @@ int __init dm365_init_video(struct vpfe_config *vpfe_cfg,
 
 static int __init dm365_init_devices(void)
 {
+       int ret = 0;
+
        if (!cpu_is_davinci_dm365())
                return 0;
 
@@ -1445,6 +1447,10 @@ static int __init dm365_init_devices(void)
        platform_device_register(&dm365_mdio_device);
        platform_device_register(&dm365_emac_device);
 
-       return 0;
+       ret = davinci_init_wdt();
+       if (ret)
+               pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+       return ret;
 }
 postcore_initcall(dm365_init_devices);
index 5c3e0be95ef3d283b653d5842001386527ab2979..5debffba4b24b82e70d9f4eaba8c80c1833afed6 100644 (file)
@@ -964,6 +964,8 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
 
 static int __init dm644x_init_devices(void)
 {
+       int ret = 0;
+
        if (!cpu_is_davinci_dm644x())
                return 0;
 
@@ -972,6 +974,10 @@ static int __init dm644x_init_devices(void)
        platform_device_register(&dm644x_mdio_device);
        platform_device_register(&dm644x_emac_device);
 
-       return 0;
+       ret = davinci_init_wdt();
+       if (ret)
+               pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+       return ret;
 }
 postcore_initcall(dm644x_init_devices);
index 81768dd47096ec0f5a476c5c90d9fcd70690521a..332d00d24dc205b1ef5a74659eee2aa6af8d96eb 100644 (file)
@@ -955,12 +955,18 @@ void __init dm646x_init(void)
 
 static int __init dm646x_init_devices(void)
 {
+       int ret = 0;
+
        if (!cpu_is_davinci_dm646x())
                return 0;
 
        platform_device_register(&dm646x_mdio_device);
        platform_device_register(&dm646x_emac_device);
 
-       return 0;
+       ret = davinci_init_wdt();
+       if (ret)
+               pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
+
+       return ret;
 }
 postcore_initcall(dm646x_init_devices);
index 957fb87e832e5da741f0ac2067347bacd6008dd6..1fc84e21664d252f38c61f6eb9bdf9dc0f837eda 100644 (file)
@@ -33,7 +33,6 @@ struct davinci_id {
 #define        DAVINCI_CPU_ID_DM365            0x03650000
 #define        DAVINCI_CPU_ID_DA830            0x08300000
 #define        DAVINCI_CPU_ID_DA850            0x08500000
-#define        DAVINCI_CPU_ID_TNETV107X        0x0b8a0000
 
 #define IS_DAVINCI_CPU(type, id)                                       \
 static inline int is_davinci_ ##type(void)                             \
@@ -47,7 +46,6 @@ IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
 IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365)
 IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830)
 IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850)
-IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X)
 
 #ifdef CONFIG_ARCH_DAVINCI_DM644x
 #define cpu_is_davinci_dm644x() is_davinci_dm644x()
@@ -85,10 +83,4 @@ IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X)
 #define cpu_is_davinci_da850() 0
 #endif
 
-#ifdef CONFIG_ARCH_DAVINCI_TNETV107X
-#define cpu_is_davinci_tnetv107x() is_davinci_tnetv107x()
-#else
-#define cpu_is_davinci_tnetv107x() 0
-#endif
-
 #endif
index ec76c7775c2e8bec0e0bd1bc05eb89d04114ceff..354af71798dcd4e09206ae6e82bfa862b4ccb0a1 100644 (file)
 
 #define DA850_N_CP_INTC_IRQ            101
 
-
-/* TNETV107X specific interrupts */
-#define IRQ_TNETV107X_TDM1_TXDMA               0
-#define IRQ_TNETV107X_EXT_INT_0                        1
-#define IRQ_TNETV107X_EXT_INT_1                        2
-#define IRQ_TNETV107X_GPIO_INT12               3
-#define IRQ_TNETV107X_GPIO_INT13               4
-#define IRQ_TNETV107X_TIMER_0_TINT12           5
-#define IRQ_TNETV107X_TIMER_1_TINT12           6
-#define IRQ_TNETV107X_UART0                    7
-#define IRQ_TNETV107X_TDM1_RXDMA               8
-#define IRQ_TNETV107X_MCDMA_INT0               9
-#define IRQ_TNETV107X_MCDMA_INT1               10
-#define IRQ_TNETV107X_TPCC                     11
-#define IRQ_TNETV107X_TPCC_INT0                        12
-#define IRQ_TNETV107X_TPCC_INT1                        13
-#define IRQ_TNETV107X_TPCC_INT2                        14
-#define IRQ_TNETV107X_TPCC_INT3                        15
-#define IRQ_TNETV107X_TPTC0                    16
-#define IRQ_TNETV107X_TPTC1                    17
-#define IRQ_TNETV107X_TIMER_0_TINT34           18
-#define IRQ_TNETV107X_ETHSS                    19
-#define IRQ_TNETV107X_TIMER_1_TINT34           20
-#define IRQ_TNETV107X_DSP2ARM_INT0             21
-#define IRQ_TNETV107X_DSP2ARM_INT1             22
-#define IRQ_TNETV107X_ARM_NPMUIRQ              23
-#define IRQ_TNETV107X_USB1                     24
-#define IRQ_TNETV107X_VLYNQ                    25
-#define IRQ_TNETV107X_UART0_DMATX              26
-#define IRQ_TNETV107X_UART0_DMARX              27
-#define IRQ_TNETV107X_TDM1_TXMCSP              28
-#define IRQ_TNETV107X_SSP                      29
-#define IRQ_TNETV107X_MCDMA_INT2               30
-#define IRQ_TNETV107X_MCDMA_INT3               31
-#define IRQ_TNETV107X_TDM_CODECIF_EOT          32
-#define IRQ_TNETV107X_IMCOP_SQR_ARM            33
-#define IRQ_TNETV107X_USB0                     34
-#define IRQ_TNETV107X_USB_CDMA                 35
-#define IRQ_TNETV107X_LCD                      36
-#define IRQ_TNETV107X_KEYPAD                   37
-#define IRQ_TNETV107X_KEYPAD_FREE              38
-#define IRQ_TNETV107X_RNG                      39
-#define IRQ_TNETV107X_PKA                      40
-#define IRQ_TNETV107X_TDM0_TXDMA               41
-#define IRQ_TNETV107X_TDM0_RXDMA               42
-#define IRQ_TNETV107X_TDM0_TXMCSP              43
-#define IRQ_TNETV107X_TDM0_RXMCSP              44
-#define IRQ_TNETV107X_TDM1_RXMCSP              45
-#define IRQ_TNETV107X_SDIO1                    46
-#define IRQ_TNETV107X_SDIO0                    47
-#define IRQ_TNETV107X_TSC                      48
-#define IRQ_TNETV107X_TS                       49
-#define IRQ_TNETV107X_UART1                    50
-#define IRQ_TNETV107X_MBX_LITE                 51
-#define IRQ_TNETV107X_GPIO_INT00               52
-#define IRQ_TNETV107X_GPIO_INT01               53
-#define IRQ_TNETV107X_GPIO_INT02               54
-#define IRQ_TNETV107X_GPIO_INT03               55
-#define IRQ_TNETV107X_UART2                    56
-#define IRQ_TNETV107X_UART2_DMATX              57
-#define IRQ_TNETV107X_UART2_DMARX              58
-#define IRQ_TNETV107X_IMCOP_IMX                        59
-#define IRQ_TNETV107X_IMCOP_VLCD               60
-#define IRQ_TNETV107X_AES                      61
-#define IRQ_TNETV107X_DES                      62
-#define IRQ_TNETV107X_SHAMD5                   63
-#define IRQ_TNETV107X_TPCC_ERR                 68
-#define IRQ_TNETV107X_TPCC_PROT                        69
-#define IRQ_TNETV107X_TPTC0_ERR                        70
-#define IRQ_TNETV107X_TPTC1_ERR                        71
-#define IRQ_TNETV107X_UART0_ERR                        72
-#define IRQ_TNETV107X_UART1_ERR                        73
-#define IRQ_TNETV107X_AEMIF_ERR                        74
-#define IRQ_TNETV107X_DDR_ERR                  75
-#define IRQ_TNETV107X_WDTARM_INT0              76
-#define IRQ_TNETV107X_MCDMA_ERR                        77
-#define IRQ_TNETV107X_GPIO_ERR                 78
-#define IRQ_TNETV107X_MPU_ADDR                 79
-#define IRQ_TNETV107X_MPU_PROT                 80
-#define IRQ_TNETV107X_IOPU_ADDR                        81
-#define IRQ_TNETV107X_IOPU_PROT                        82
-#define IRQ_TNETV107X_KEYPAD_ADDR_ERR          83
-#define IRQ_TNETV107X_WDT0_ADDR_ERR            84
-#define IRQ_TNETV107X_WDT1_ADDR_ERR            85
-#define IRQ_TNETV107X_CLKCTL_ADDR_ERR          86
-#define IRQ_TNETV107X_PLL_UNLOCK               87
-#define IRQ_TNETV107X_WDTDSP_INT0              88
-#define IRQ_TNETV107X_SEC_CTRL_VIOLATION       89
-#define IRQ_TNETV107X_KEY_MNG_VIOLATION                90
-#define IRQ_TNETV107X_PBIST_CPU                        91
-#define IRQ_TNETV107X_WDTARM                   92
-#define IRQ_TNETV107X_PSC                      93
-#define IRQ_TNETV107X_MMC0                     94
-#define IRQ_TNETV107X_MMC1                     95
-
-#define TNETV107X_N_CP_INTC_IRQ                        96
-
 /* da850 currently has the most gpio pins (144) */
 #define DAVINCI_N_GPIO                 144
 /* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */
index 9e95b8a1edb62964cc473c1947bc61ebc6ca0402..631655e68ae046601aabcad315d622e9d83c8331 100644 (file)
@@ -972,275 +972,6 @@ enum davinci_da850_index {
        DA850_VPIF_CLKO3,
 };
 
-enum davinci_tnetv107x_index {
-       TNETV107X_ASR_A00,
-       TNETV107X_GPIO32,
-       TNETV107X_ASR_A01,
-       TNETV107X_GPIO33,
-       TNETV107X_ASR_A02,
-       TNETV107X_GPIO34,
-       TNETV107X_ASR_A03,
-       TNETV107X_GPIO35,
-       TNETV107X_ASR_A04,
-       TNETV107X_GPIO36,
-       TNETV107X_ASR_A05,
-       TNETV107X_GPIO37,
-       TNETV107X_ASR_A06,
-       TNETV107X_GPIO38,
-       TNETV107X_ASR_A07,
-       TNETV107X_GPIO39,
-       TNETV107X_ASR_A08,
-       TNETV107X_GPIO40,
-       TNETV107X_ASR_A09,
-       TNETV107X_GPIO41,
-       TNETV107X_ASR_A10,
-       TNETV107X_GPIO42,
-       TNETV107X_ASR_A11,
-       TNETV107X_BOOT_STRP_0,
-       TNETV107X_ASR_A12,
-       TNETV107X_BOOT_STRP_1,
-       TNETV107X_ASR_A13,
-       TNETV107X_GPIO43,
-       TNETV107X_ASR_A14,
-       TNETV107X_GPIO44,
-       TNETV107X_ASR_A15,
-       TNETV107X_GPIO45,
-       TNETV107X_ASR_A16,
-       TNETV107X_GPIO46,
-       TNETV107X_ASR_A17,
-       TNETV107X_GPIO47,
-       TNETV107X_ASR_A18,
-       TNETV107X_GPIO48,
-       TNETV107X_SDIO1_DATA3_0,
-       TNETV107X_ASR_A19,
-       TNETV107X_GPIO49,
-       TNETV107X_SDIO1_DATA2_0,
-       TNETV107X_ASR_A20,
-       TNETV107X_GPIO50,
-       TNETV107X_SDIO1_DATA1_0,
-       TNETV107X_ASR_A21,
-       TNETV107X_GPIO51,
-       TNETV107X_SDIO1_DATA0_0,
-       TNETV107X_ASR_A22,
-       TNETV107X_GPIO52,
-       TNETV107X_SDIO1_CMD_0,
-       TNETV107X_ASR_A23,
-       TNETV107X_GPIO53,
-       TNETV107X_SDIO1_CLK_0,
-       TNETV107X_ASR_BA_1,
-       TNETV107X_GPIO54,
-       TNETV107X_SYS_PLL_CLK,
-       TNETV107X_ASR_CS0,
-       TNETV107X_ASR_CS1,
-       TNETV107X_ASR_CS2,
-       TNETV107X_TDM_PLL_CLK,
-       TNETV107X_ASR_CS3,
-       TNETV107X_ETH_PHY_CLK,
-       TNETV107X_ASR_D00,
-       TNETV107X_GPIO55,
-       TNETV107X_ASR_D01,
-       TNETV107X_GPIO56,
-       TNETV107X_ASR_D02,
-       TNETV107X_GPIO57,
-       TNETV107X_ASR_D03,
-       TNETV107X_GPIO58,
-       TNETV107X_ASR_D04,
-       TNETV107X_GPIO59_0,
-       TNETV107X_ASR_D05,
-       TNETV107X_GPIO60_0,
-       TNETV107X_ASR_D06,
-       TNETV107X_GPIO61_0,
-       TNETV107X_ASR_D07,
-       TNETV107X_GPIO62_0,
-       TNETV107X_ASR_D08,
-       TNETV107X_GPIO63_0,
-       TNETV107X_ASR_D09,
-       TNETV107X_GPIO64_0,
-       TNETV107X_ASR_D10,
-       TNETV107X_SDIO1_DATA3_1,
-       TNETV107X_ASR_D11,
-       TNETV107X_SDIO1_DATA2_1,
-       TNETV107X_ASR_D12,
-       TNETV107X_SDIO1_DATA1_1,
-       TNETV107X_ASR_D13,
-       TNETV107X_SDIO1_DATA0_1,
-       TNETV107X_ASR_D14,
-       TNETV107X_SDIO1_CMD_1,
-       TNETV107X_ASR_D15,
-       TNETV107X_SDIO1_CLK_1,
-       TNETV107X_ASR_OE,
-       TNETV107X_BOOT_STRP_2,
-       TNETV107X_ASR_RNW,
-       TNETV107X_GPIO29_0,
-       TNETV107X_ASR_WAIT,
-       TNETV107X_GPIO30_0,
-       TNETV107X_ASR_WE,
-       TNETV107X_BOOT_STRP_3,
-       TNETV107X_ASR_WE_DQM0,
-       TNETV107X_GPIO31,
-       TNETV107X_LCD_PD17_0,
-       TNETV107X_ASR_WE_DQM1,
-       TNETV107X_ASR_BA0_0,
-       TNETV107X_VLYNQ_CLK,
-       TNETV107X_GPIO14,
-       TNETV107X_LCD_PD19_0,
-       TNETV107X_VLYNQ_RXD0,
-       TNETV107X_GPIO15,
-       TNETV107X_LCD_PD20_0,
-       TNETV107X_VLYNQ_RXD1,
-       TNETV107X_GPIO16,
-       TNETV107X_LCD_PD21_0,
-       TNETV107X_VLYNQ_TXD0,
-       TNETV107X_GPIO17,
-       TNETV107X_LCD_PD22_0,
-       TNETV107X_VLYNQ_TXD1,
-       TNETV107X_GPIO18,
-       TNETV107X_LCD_PD23_0,
-       TNETV107X_SDIO0_CLK,
-       TNETV107X_GPIO19,
-       TNETV107X_SDIO0_CMD,
-       TNETV107X_GPIO20,
-       TNETV107X_SDIO0_DATA0,
-       TNETV107X_GPIO21,
-       TNETV107X_SDIO0_DATA1,
-       TNETV107X_GPIO22,
-       TNETV107X_SDIO0_DATA2,
-       TNETV107X_GPIO23,
-       TNETV107X_SDIO0_DATA3,
-       TNETV107X_GPIO24,
-       TNETV107X_EMU0,
-       TNETV107X_EMU1,
-       TNETV107X_RTCK,
-       TNETV107X_TRST_N,
-       TNETV107X_TCK,
-       TNETV107X_TDI,
-       TNETV107X_TDO,
-       TNETV107X_TMS,
-       TNETV107X_TDM1_CLK,
-       TNETV107X_TDM1_RX,
-       TNETV107X_TDM1_TX,
-       TNETV107X_TDM1_FS,
-       TNETV107X_KEYPAD_R0,
-       TNETV107X_KEYPAD_R1,
-       TNETV107X_KEYPAD_R2,
-       TNETV107X_KEYPAD_R3,
-       TNETV107X_KEYPAD_R4,
-       TNETV107X_KEYPAD_R5,
-       TNETV107X_KEYPAD_R6,
-       TNETV107X_GPIO12,
-       TNETV107X_KEYPAD_R7,
-       TNETV107X_GPIO10,
-       TNETV107X_KEYPAD_C0,
-       TNETV107X_KEYPAD_C1,
-       TNETV107X_KEYPAD_C2,
-       TNETV107X_KEYPAD_C3,
-       TNETV107X_KEYPAD_C4,
-       TNETV107X_KEYPAD_C5,
-       TNETV107X_KEYPAD_C6,
-       TNETV107X_GPIO13,
-       TNETV107X_TEST_CLK_IN,
-       TNETV107X_KEYPAD_C7,
-       TNETV107X_GPIO11,
-       TNETV107X_SSP0_0,
-       TNETV107X_SCC_DCLK,
-       TNETV107X_LCD_PD20_1,
-       TNETV107X_SSP0_1,
-       TNETV107X_SCC_CS_N,
-       TNETV107X_LCD_PD21_1,
-       TNETV107X_SSP0_2,
-       TNETV107X_SCC_D,
-       TNETV107X_LCD_PD22_1,
-       TNETV107X_SSP0_3,
-       TNETV107X_SCC_RESETN,
-       TNETV107X_LCD_PD23_1,
-       TNETV107X_SSP1_0,
-       TNETV107X_GPIO25,
-       TNETV107X_UART2_CTS,
-       TNETV107X_SSP1_1,
-       TNETV107X_GPIO26,
-       TNETV107X_UART2_RD,
-       TNETV107X_SSP1_2,
-       TNETV107X_GPIO27,
-       TNETV107X_UART2_RTS,
-       TNETV107X_SSP1_3,
-       TNETV107X_GPIO28,
-       TNETV107X_UART2_TD,
-       TNETV107X_UART0_CTS,
-       TNETV107X_UART0_RD,
-       TNETV107X_UART0_RTS,
-       TNETV107X_UART0_TD,
-       TNETV107X_UART1_RD,
-       TNETV107X_UART1_TD,
-       TNETV107X_LCD_AC_NCS,
-       TNETV107X_LCD_HSYNC_RNW,
-       TNETV107X_LCD_VSYNC_A0,
-       TNETV107X_LCD_MCLK,
-       TNETV107X_LCD_PD16_0,
-       TNETV107X_LCD_PCLK_E,
-       TNETV107X_LCD_PD00,
-       TNETV107X_LCD_PD01,
-       TNETV107X_LCD_PD02,
-       TNETV107X_LCD_PD03,
-       TNETV107X_LCD_PD04,
-       TNETV107X_LCD_PD05,
-       TNETV107X_LCD_PD06,
-       TNETV107X_LCD_PD07,
-       TNETV107X_LCD_PD08,
-       TNETV107X_GPIO59_1,
-       TNETV107X_LCD_PD09,
-       TNETV107X_GPIO60_1,
-       TNETV107X_LCD_PD10,
-       TNETV107X_ASR_BA0_1,
-       TNETV107X_GPIO61_1,
-       TNETV107X_LCD_PD11,
-       TNETV107X_GPIO62_1,
-       TNETV107X_LCD_PD12,
-       TNETV107X_GPIO63_1,
-       TNETV107X_LCD_PD13,
-       TNETV107X_GPIO64_1,
-       TNETV107X_LCD_PD14,
-       TNETV107X_GPIO29_1,
-       TNETV107X_LCD_PD15,
-       TNETV107X_GPIO30_1,
-       TNETV107X_EINT0,
-       TNETV107X_GPIO08,
-       TNETV107X_EINT1,
-       TNETV107X_GPIO09,
-       TNETV107X_GPIO00,
-       TNETV107X_LCD_PD20_2,
-       TNETV107X_TDM_CLK_IN_2,
-       TNETV107X_GPIO01,
-       TNETV107X_LCD_PD21_2,
-       TNETV107X_24M_CLK_OUT_1,
-       TNETV107X_GPIO02,
-       TNETV107X_LCD_PD22_2,
-       TNETV107X_GPIO03,
-       TNETV107X_LCD_PD23_2,
-       TNETV107X_GPIO04,
-       TNETV107X_LCD_PD16_1,
-       TNETV107X_USB0_RXERR,
-       TNETV107X_GPIO05,
-       TNETV107X_LCD_PD17_1,
-       TNETV107X_TDM_CLK_IN_1,
-       TNETV107X_GPIO06,
-       TNETV107X_LCD_PD18,
-       TNETV107X_24M_CLK_OUT_2,
-       TNETV107X_GPIO07,
-       TNETV107X_LCD_PD19_1,
-       TNETV107X_USB1_RXERR,
-       TNETV107X_ETH_PLL_CLK,
-       TNETV107X_MDIO,
-       TNETV107X_MDC,
-       TNETV107X_AIC_MUTE_STAT_N,
-       TNETV107X_TDM0_CLK,
-       TNETV107X_AIC_HNS_EN_N,
-       TNETV107X_TDM0_FS,
-       TNETV107X_AIC_HDS_EN_STAT_N,
-       TNETV107X_TDM0_TX,
-       TNETV107X_AIC_HNF_EN_STAT_N,
-       TNETV107X_TDM0_RX,
-};
-
 #define PINMUX(x)              (4 * (x))
 
 #ifdef CONFIG_DAVINCI_MUX
index 0a22710493fd27f5cc2f8178741fdb0fcc1de666..99d47cfa301ff7d33de838c8bf8de597a0a21832 100644 (file)
 #define DA8XX_LPSC1_CR_P3_SS           26
 #define DA8XX_LPSC1_L3_CBA_RAM         31
 
-/* TNETV107X LPSC Assignments */
-#define TNETV107X_LPSC_ARM                     0
-#define TNETV107X_LPSC_GEM                     1
-#define TNETV107X_LPSC_DDR2_PHY                        2
-#define TNETV107X_LPSC_TPCC                    3
-#define TNETV107X_LPSC_TPTC0                   4
-#define TNETV107X_LPSC_TPTC1                   5
-#define TNETV107X_LPSC_RAM                     6
-#define TNETV107X_LPSC_MBX_LITE                        7
-#define TNETV107X_LPSC_LCD                     8
-#define TNETV107X_LPSC_ETHSS                   9
-#define TNETV107X_LPSC_AEMIF                   10
-#define TNETV107X_LPSC_CHIP_CFG                        11
-#define TNETV107X_LPSC_TSC                     12
-#define TNETV107X_LPSC_ROM                     13
-#define TNETV107X_LPSC_UART2                   14
-#define TNETV107X_LPSC_PKTSEC                  15
-#define TNETV107X_LPSC_SECCTL                  16
-#define TNETV107X_LPSC_KEYMGR                  17
-#define TNETV107X_LPSC_KEYPAD                  18
-#define TNETV107X_LPSC_GPIO                    19
-#define TNETV107X_LPSC_MDIO                    20
-#define TNETV107X_LPSC_SDIO0                   21
-#define TNETV107X_LPSC_UART0                   22
-#define TNETV107X_LPSC_UART1                   23
-#define TNETV107X_LPSC_TIMER0                  24
-#define TNETV107X_LPSC_TIMER1                  25
-#define TNETV107X_LPSC_WDT_ARM                 26
-#define TNETV107X_LPSC_WDT_DSP                 27
-#define TNETV107X_LPSC_SSP                     28
-#define TNETV107X_LPSC_TDM0                    29
-#define TNETV107X_LPSC_VLYNQ                   30
-#define TNETV107X_LPSC_MCDMA                   31
-#define TNETV107X_LPSC_USB0                    32
-#define TNETV107X_LPSC_TDM1                    33
-#define TNETV107X_LPSC_DEBUGSS                 34
-#define TNETV107X_LPSC_ETHSS_RGMII             35
-#define TNETV107X_LPSC_SYSTEM                  36
-#define TNETV107X_LPSC_IMCOP                   37
-#define TNETV107X_LPSC_SPARE                   38
-#define TNETV107X_LPSC_SDIO1                   39
-#define TNETV107X_LPSC_USB1                    40
-#define TNETV107X_LPSC_USBSS                   41
-#define TNETV107X_LPSC_DDR2_EMIF1_VRST         42
-#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST     43
-#define TNETV107X_LPSC_MAX                     44
-
 /* PSC register offsets */
 #define EPCPR          0x070
 #define PTCMD          0x120
index ce402cd21fa0a6f809963d71ca3cac3c6f650131..d4b4aa87964f06315bc27c73c5bda93d7a3dcb18 100644 (file)
 #define DA8XX_UART1_BASE       (IO_PHYS + 0x10c000)
 #define DA8XX_UART2_BASE       (IO_PHYS + 0x10d000)
 
-#define TNETV107X_UART0_BASE   0x08108100
-#define TNETV107X_UART1_BASE   0x08088400
-#define TNETV107X_UART2_BASE   0x08108300
-
-#define TNETV107X_UART0_VIRT   IOMEM(0xfee08100)
-#define TNETV107X_UART1_VIRT   IOMEM(0xfed88400)
-#define TNETV107X_UART2_VIRT   IOMEM(0xfee08300)
-
 /* DaVinci UART register offsets */
 #define UART_DAVINCI_PWREMU            0x0c
 #define UART_DM646X_SCR                        0x10
diff --git a/arch/arm/mach-davinci/include/mach/timex.h b/arch/arm/mach-davinci/include/mach/timex.h
deleted file mode 100644 (file)
index 9b88529..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * DaVinci timer defines
- *
- * Author: Kevin Hilman, MontaVista Software, Inc. <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_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/*
- * Alert: Not all timers of the DaVinci family run at a frequency of 27MHz,
- * but we should be fine as long as CLOCK_TICK_RATE or LATCH (see include/
- * linux/jiffies.h) are not used directly in code. Currently none of the
- * code relevant to DaVinci platform depends on these values directly.
- */
-#define CLOCK_TICK_RATE 27000000
-
-#endif /* __ASM_ARCH_TIMEX_H__ */
diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h
deleted file mode 100644 (file)
index 494fcf5..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Texas Instruments TNETV107X SoC Specific Defines
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#ifndef __ASM_ARCH_DAVINCI_TNETV107X_H
-#define __ASM_ARCH_DAVINCI_TNETV107X_H
-
-#include <asm/sizes.h>
-
-#define TNETV107X_DDR_BASE     0x80000000
-
-/*
- * Fixed mapping for early init starts here. If low-level debug is enabled,
- * this area also gets mapped via io_pg_offset and io_phys by the boot code.
- * To fit in with the io_pg_offset calculation, the io base address selected
- * here _must_ be a multiple of 2^20.
- */
-#define TNETV107X_IO_BASE      0x08000000
-#define TNETV107X_IO_VIRT      (IO_VIRT + SZ_1M)
-
-#define TNETV107X_N_GPIO       65
-
-#ifndef __ASSEMBLY__
-
-#include <linux/serial_8250.h>
-#include <linux/input/matrix_keypad.h>
-#include <linux/mfd/ti_ssp.h>
-#include <linux/reboot.h>
-
-#include <linux/platform_data/mmc-davinci.h>
-#include <linux/platform_data/mtd-davinci.h>
-#include <mach/serial.h>
-
-struct tnetv107x_device_info {
-       struct davinci_mmc_config       *mmc_config[2];  /* 2 controllers */
-       struct davinci_nand_pdata       *nand_config[4]; /* 4 chipsels */
-       struct matrix_keypad_platform_data *keypad_config;
-       struct ti_ssp_data              *ssp_config;
-};
-
-extern struct platform_device tnetv107x_wdt_device;
-extern struct platform_device tnetv107x_serial_device[];
-
-extern void tnetv107x_init(void);
-extern void tnetv107x_devices_init(struct tnetv107x_device_info *);
-extern void tnetv107x_irq_init(void);
-void tnetv107x_restart(enum reboot_mode mode, const char *cmd);
-
-#endif
-
-#endif /* __ASM_ARCH_DAVINCI_TNETV107X_H */
index f49c2916aa3aad2b0b4adb0092a9cf25b703d155..8fb97b93b6bb3d85ab0055c444b44f5fb9612a6e 100644 (file)
@@ -68,9 +68,6 @@ static inline void set_uart_info(u32 phys)
 #define DEBUG_LL_DA8XX(machine, port)                          \
        _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE)
 
-#define DEBUG_LL_TNETV107X(machine, port)                      \
-       _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE)
-
 static inline void __arch_decomp_setup(unsigned long arch_id)
 {
        /*
@@ -94,9 +91,6 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
                DEBUG_LL_DA8XX(davinci_da850_evm,       2);
                DEBUG_LL_DA8XX(mityomapl138,            1);
                DEBUG_LL_DA8XX(omapl138_hawkboard,      2);
-
-               /* TNETV107x boards */
-               DEBUG_LL_TNETV107X(tnetv107x,           1);
        } while (0);
 }
 
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
deleted file mode 100644 (file)
index f4d7fbb..0000000
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- * Texas Instruments TNETV107X SoC Support
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 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/gpio.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/reboot.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/common.h>
-#include <mach/time.h>
-#include <mach/cputype.h>
-#include <mach/psc.h>
-#include <mach/cp_intc.h>
-#include <mach/irqs.h>
-#include <mach/hardware.h>
-#include <mach/tnetv107x.h>
-#include <mach/gpio-davinci.h>
-
-#include "clock.h"
-#include "mux.h"
-
-/* Base addresses for on-chip devices */
-#define TNETV107X_INTC_BASE                    0x03000000
-#define TNETV107X_TIMER0_BASE                  0x08086500
-#define TNETV107X_TIMER1_BASE                  0x08086600
-#define TNETV107X_CHIP_CFG_BASE                        0x08087000
-#define TNETV107X_GPIO_BASE                    0x08088000
-#define TNETV107X_CLOCK_CONTROL_BASE           0x0808a000
-#define TNETV107X_PSC_BASE                     0x0808b000
-
-/* Reference clock frequencies */
-#define OSC_FREQ_ONCHIP                (24000 * 1000)
-#define OSC_FREQ_OFFCHIP_SYS   (25000 * 1000)
-#define OSC_FREQ_OFFCHIP_ETH   (25000 * 1000)
-#define OSC_FREQ_OFFCHIP_TDM   (19200 * 1000)
-
-#define N_PLLS 3
-
-/* Clock Control Registers */
-struct clk_ctrl_regs {
-       u32     pll_bypass;
-       u32     _reserved0;
-       u32     gem_lrst;
-       u32     _reserved1;
-       u32     pll_unlock_stat;
-       u32     sys_unlock;
-       u32     eth_unlock;
-       u32     tdm_unlock;
-};
-
-/* SSPLL Registers */
-struct sspll_regs {
-       u32     modes;
-       u32     post_div;
-       u32     pre_div;
-       u32     mult_factor;
-       u32     divider_range;
-       u32     bw_divider;
-       u32     spr_amount;
-       u32     spr_rate_div;
-       u32     diag;
-};
-
-/* Watchdog Timer Registers */
-struct wdt_regs {
-       u32     kick_lock;
-       u32     kick;
-       u32     change_lock;
-       u32     change ;
-       u32     disable_lock;
-       u32     disable;
-       u32     prescale_lock;
-       u32     prescale;
-};
-
-static struct clk_ctrl_regs __iomem *clk_ctrl_regs;
-
-static struct sspll_regs __iomem *sspll_regs[N_PLLS];
-static int sspll_regs_base[N_PLLS] = { 0x40, 0x80, 0xc0 };
-
-/* PLL bypass bit shifts in clk_ctrl_regs->pll_bypass register */
-static u32 bypass_mask[N_PLLS] = { BIT(0), BIT(2), BIT(1) };
-
-/* offchip (external) reference clock frequencies */
-static u32 pll_ext_freq[] = {
-       OSC_FREQ_OFFCHIP_SYS,
-       OSC_FREQ_OFFCHIP_TDM,
-       OSC_FREQ_OFFCHIP_ETH
-};
-
-/* PSC control registers */
-static u32 psc_regs[] = { TNETV107X_PSC_BASE };
-
-/* Host map for interrupt controller */
-static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 };
-
-static unsigned long clk_sspll_recalc(struct clk *clk);
-
-/* Level 1 - the PLLs */
-#define define_pll_clk(cname, pll, divmask, base)      \
-       static struct pll_data pll_##cname##_data = {   \
-               .num            = pll,                  \
-               .div_ratio_mask = divmask,              \
-               .phys_base      = base +                \
-                       TNETV107X_CLOCK_CONTROL_BASE,   \
-       };                                              \
-       static struct clk pll_##cname##_clk = {         \
-               .name           = "pll_" #cname "_clk", \
-               .pll_data       = &pll_##cname##_data,  \
-               .flags          = CLK_PLL,              \
-               .recalc         = clk_sspll_recalc,     \
-       }
-
-define_pll_clk(sys, 0, 0x1ff, 0x600);
-define_pll_clk(tdm, 1, 0x0ff, 0x200);
-define_pll_clk(eth, 2, 0x0ff, 0x400);
-
-/* Level 2 - divided outputs from the PLLs */
-#define define_pll_div_clk(pll, cname, div)                    \
-       static struct clk pll##_##cname##_clk = {               \
-               .name           = #pll "_" #cname "_clk",       \
-               .parent         = &pll_##pll##_clk,             \
-               .flags          = CLK_PLL,                      \
-               .div_reg        = PLLDIV##div,                  \
-               .set_rate       = davinci_set_sysclk_rate,      \
-       }
-
-define_pll_div_clk(sys, arm1176,       1);
-define_pll_div_clk(sys, dsp,           2);
-define_pll_div_clk(sys, ddr,           3);
-define_pll_div_clk(sys, full,          4);
-define_pll_div_clk(sys, lcd,           5);
-define_pll_div_clk(sys, vlynq_ref,     6);
-define_pll_div_clk(sys, tsc,           7);
-define_pll_div_clk(sys, half,          8);
-
-define_pll_div_clk(eth, 5mhz,          1);
-define_pll_div_clk(eth, 50mhz,         2);
-define_pll_div_clk(eth, 125mhz,                3);
-define_pll_div_clk(eth, 250mhz,                4);
-define_pll_div_clk(eth, 25mhz,         5);
-
-define_pll_div_clk(tdm, 0,             1);
-define_pll_div_clk(tdm, extra,         2);
-define_pll_div_clk(tdm, 1,             3);
-
-
-/* Level 3 - LPSC gated clocks */
-#define __lpsc_clk(cname, _parent, mod, flg)           \
-       static struct clk clk_##cname = {               \
-               .name           = #cname,               \
-               .parent         = &_parent,             \
-               .lpsc           = TNETV107X_LPSC_##mod,\
-               .flags          = flg,                  \
-       }
-
-#define lpsc_clk_enabled(cname, parent, mod)           \
-       __lpsc_clk(cname, parent, mod, ALWAYS_ENABLED)
-
-#define lpsc_clk(cname, parent, mod)                   \
-       __lpsc_clk(cname, parent, mod, 0)
-
-lpsc_clk_enabled(arm,          sys_arm1176_clk, ARM);
-lpsc_clk_enabled(gem,          sys_dsp_clk,    GEM);
-lpsc_clk_enabled(ddr2_phy,     sys_ddr_clk,    DDR2_PHY);
-lpsc_clk_enabled(tpcc,         sys_full_clk,   TPCC);
-lpsc_clk_enabled(tptc0,                sys_full_clk,   TPTC0);
-lpsc_clk_enabled(tptc1,                sys_full_clk,   TPTC1);
-lpsc_clk_enabled(ram,          sys_full_clk,   RAM);
-lpsc_clk_enabled(aemif,                sys_full_clk,   AEMIF);
-lpsc_clk_enabled(chipcfg,      sys_half_clk,   CHIP_CFG);
-lpsc_clk_enabled(rom,          sys_half_clk,   ROM);
-lpsc_clk_enabled(secctl,       sys_half_clk,   SECCTL);
-lpsc_clk_enabled(keymgr,       sys_half_clk,   KEYMGR);
-lpsc_clk_enabled(gpio,         sys_half_clk,   GPIO);
-lpsc_clk_enabled(debugss,      sys_half_clk,   DEBUGSS);
-lpsc_clk_enabled(system,       sys_half_clk,   SYSTEM);
-lpsc_clk_enabled(ddr2_vrst,    sys_ddr_clk,    DDR2_EMIF1_VRST);
-lpsc_clk_enabled(ddr2_vctl_rst,        sys_ddr_clk,    DDR2_EMIF2_VCTL_RST);
-lpsc_clk_enabled(wdt_arm,      sys_half_clk,   WDT_ARM);
-lpsc_clk_enabled(timer1,       sys_half_clk,   TIMER1);
-
-lpsc_clk(mbx_lite,     sys_arm1176_clk,        MBX_LITE);
-lpsc_clk(ethss,                eth_125mhz_clk,         ETHSS);
-lpsc_clk(tsc,          sys_tsc_clk,            TSC);
-lpsc_clk(uart0,                sys_half_clk,           UART0);
-lpsc_clk(uart1,                sys_half_clk,           UART1);
-lpsc_clk(uart2,                sys_half_clk,           UART2);
-lpsc_clk(pktsec,       sys_half_clk,           PKTSEC);
-lpsc_clk(keypad,       sys_half_clk,           KEYPAD);
-lpsc_clk(mdio,         sys_half_clk,           MDIO);
-lpsc_clk(sdio0,                sys_half_clk,           SDIO0);
-lpsc_clk(sdio1,                sys_half_clk,           SDIO1);
-lpsc_clk(timer0,       sys_half_clk,           TIMER0);
-lpsc_clk(wdt_dsp,      sys_half_clk,           WDT_DSP);
-lpsc_clk(ssp,          sys_half_clk,           SSP);
-lpsc_clk(tdm0,         tdm_0_clk,              TDM0);
-lpsc_clk(tdm1,         tdm_1_clk,              TDM1);
-lpsc_clk(vlynq,                sys_vlynq_ref_clk,      VLYNQ);
-lpsc_clk(mcdma,                sys_half_clk,           MCDMA);
-lpsc_clk(usbss,                sys_half_clk,           USBSS);
-lpsc_clk(usb0,         clk_usbss,              USB0);
-lpsc_clk(usb1,         clk_usbss,              USB1);
-lpsc_clk(ethss_rgmii,  eth_250mhz_clk,         ETHSS_RGMII);
-lpsc_clk(imcop,                sys_dsp_clk,            IMCOP);
-lpsc_clk(spare,                sys_half_clk,           SPARE);
-
-/* LCD needs a full power down to clear controller state */
-__lpsc_clk(lcd, sys_lcd_clk, LCD, PSC_SWRSTDISABLE);
-
-
-/* Level 4 - leaf clocks for LPSC modules shared across drivers */
-static struct clk clk_rng = { .name = "rng", .parent = &clk_pktsec };
-static struct clk clk_pka = { .name = "pka", .parent = &clk_pktsec };
-
-static struct clk_lookup clks[] = {
-       CLK(NULL,               "pll_sys_clk",          &pll_sys_clk),
-       CLK(NULL,               "pll_eth_clk",          &pll_eth_clk),
-       CLK(NULL,               "pll_tdm_clk",          &pll_tdm_clk),
-       CLK(NULL,               "sys_arm1176_clk",      &sys_arm1176_clk),
-       CLK(NULL,               "sys_dsp_clk",          &sys_dsp_clk),
-       CLK(NULL,               "sys_ddr_clk",          &sys_ddr_clk),
-       CLK(NULL,               "sys_full_clk",         &sys_full_clk),
-       CLK(NULL,               "sys_lcd_clk",          &sys_lcd_clk),
-       CLK(NULL,               "sys_vlynq_ref_clk",    &sys_vlynq_ref_clk),
-       CLK(NULL,               "sys_tsc_clk",          &sys_tsc_clk),
-       CLK(NULL,               "sys_half_clk",         &sys_half_clk),
-       CLK(NULL,               "eth_5mhz_clk",         &eth_5mhz_clk),
-       CLK(NULL,               "eth_50mhz_clk",        &eth_50mhz_clk),
-       CLK(NULL,               "eth_125mhz_clk",       &eth_125mhz_clk),
-       CLK(NULL,               "eth_250mhz_clk",       &eth_250mhz_clk),
-       CLK(NULL,               "eth_25mhz_clk",        &eth_25mhz_clk),
-       CLK(NULL,               "tdm_0_clk",            &tdm_0_clk),
-       CLK(NULL,               "tdm_extra_clk",        &tdm_extra_clk),
-       CLK(NULL,               "tdm_1_clk",            &tdm_1_clk),
-       CLK(NULL,               "clk_arm",              &clk_arm),
-       CLK(NULL,               "clk_gem",              &clk_gem),
-       CLK(NULL,               "clk_ddr2_phy",         &clk_ddr2_phy),
-       CLK(NULL,               "clk_tpcc",             &clk_tpcc),
-       CLK(NULL,               "clk_tptc0",            &clk_tptc0),
-       CLK(NULL,               "clk_tptc1",            &clk_tptc1),
-       CLK(NULL,               "clk_ram",              &clk_ram),
-       CLK(NULL,               "clk_mbx_lite",         &clk_mbx_lite),
-       CLK("tnetv107x-fb.0",   NULL,                   &clk_lcd),
-       CLK(NULL,               "clk_ethss",            &clk_ethss),
-       CLK(NULL,               "aemif",                &clk_aemif),
-       CLK(NULL,               "clk_chipcfg",          &clk_chipcfg),
-       CLK("tnetv107x-ts.0",   NULL,                   &clk_tsc),
-       CLK(NULL,               "clk_rom",              &clk_rom),
-       CLK("serial8250.2",     NULL,                   &clk_uart2),
-       CLK(NULL,               "clk_pktsec",           &clk_pktsec),
-       CLK("tnetv107x-rng.0",  NULL,                   &clk_rng),
-       CLK("tnetv107x-pka.0",  NULL,                   &clk_pka),
-       CLK(NULL,               "clk_secctl",           &clk_secctl),
-       CLK(NULL,               "clk_keymgr",           &clk_keymgr),
-       CLK("tnetv107x-keypad.0", NULL,                 &clk_keypad),
-       CLK(NULL,               "clk_gpio",             &clk_gpio),
-       CLK(NULL,               "clk_mdio",             &clk_mdio),
-       CLK("dm6441-mmc.0",     NULL,                   &clk_sdio0),
-       CLK("serial8250.0",     NULL,                   &clk_uart0),
-       CLK("serial8250.1",     NULL,                   &clk_uart1),
-       CLK(NULL,               "timer0",               &clk_timer0),
-       CLK(NULL,               "timer1",               &clk_timer1),
-       CLK("tnetv107x_wdt.0",  NULL,                   &clk_wdt_arm),
-       CLK(NULL,               "clk_wdt_dsp",          &clk_wdt_dsp),
-       CLK("ti-ssp",           NULL,                   &clk_ssp),
-       CLK(NULL,               "clk_tdm0",             &clk_tdm0),
-       CLK(NULL,               "clk_vlynq",            &clk_vlynq),
-       CLK(NULL,               "clk_mcdma",            &clk_mcdma),
-       CLK(NULL,               "clk_usbss",            &clk_usbss),
-       CLK(NULL,               "clk_usb0",             &clk_usb0),
-       CLK(NULL,               "clk_usb1",             &clk_usb1),
-       CLK(NULL,               "clk_tdm1",             &clk_tdm1),
-       CLK(NULL,               "clk_debugss",          &clk_debugss),
-       CLK(NULL,               "clk_ethss_rgmii",      &clk_ethss_rgmii),
-       CLK(NULL,               "clk_system",           &clk_system),
-       CLK(NULL,               "clk_imcop",            &clk_imcop),
-       CLK(NULL,               "clk_spare",            &clk_spare),
-       CLK("dm6441-mmc.1",     NULL,                   &clk_sdio1),
-       CLK(NULL,               "clk_ddr2_vrst",        &clk_ddr2_vrst),
-       CLK(NULL,               "clk_ddr2_vctl_rst",    &clk_ddr2_vctl_rst),
-       CLK(NULL,               NULL,                   NULL),
-};
-
-static const struct mux_config pins[] = {
-#ifdef CONFIG_DAVINCI_MUX
-       MUX_CFG(TNETV107X, ASR_A00,             0, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO32,              0, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A01,             0, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO33,              0, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A02,             0, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO34,              0, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A03,             0, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO35,              0, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A04,             0, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO36,              0, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A05,             0, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO37,              0, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A06,             1, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO38,              1, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A07,             1, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO39,              1, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A08,             1, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO40,              1, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A09,             1, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO41,              1, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A10,             1, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO42,              1, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A11,             1, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, BOOT_STRP_0,         1, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A12,             2, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, BOOT_STRP_1,         2, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A13,             2, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO43,              2, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A14,             2, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO44,              2, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A15,             2, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO45,              2, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A16,             2, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO46,              2, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A17,             2, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO47,              2, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_A18,             3, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO48,              3, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA3_0,       3, 0, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_A19,             3, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO49,              3, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA2_0,       3, 5, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_A20,             3, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO50,              3, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA1_0,       3, 10, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_A21,             3, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO51,              3, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA0_0,       3, 15, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_A22,             3, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO52,              3, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO1_CMD_0,         3, 20, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_A23,             3, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO53,              3, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO1_CLK_0,         3, 25, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_BA_1,            4, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO54,              4, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SYS_PLL_CLK,         4, 0, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_CS0,             4, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, ASR_CS1,             4, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, ASR_CS2,             4, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM_PLL_CLK,         4, 15, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_CS3,             4, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, ETH_PHY_CLK,         4, 20, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, ASR_D00,             4, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO55,              4, 25, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D01,             5, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO56,              5, 0, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D02,             5, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO57,              5, 5, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D03,             5, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO58,              5, 10, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D04,             5, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO59_0,            5, 15, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D05,             5, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO60_0,            5, 20, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D06,             5, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO61_0,            5, 25, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D07,             6, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO62_0,            6, 0, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D08,             6, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO63_0,            6, 5, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D09,             6, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO64_0,            6, 10, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D10,             6, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA3_1,       6, 15, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D11,             6, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA2_1,       6, 20, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D12,             6, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA1_1,       6, 25, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D13,             7, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SDIO1_DATA0_1,       7, 0, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D14,             7, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SDIO1_CMD_1,         7, 5, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_D15,             7, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SDIO1_CLK_1,         7, 10, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_OE,              7, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, BOOT_STRP_2,         7, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_RNW,             7, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO29_0,            7, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_WAIT,            7, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO30_0,            7, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_WE,              8, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, BOOT_STRP_3,         8, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, ASR_WE_DQM0,         8, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO31,              8, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD17_0,          8, 5, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, ASR_WE_DQM1,         8, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, ASR_BA0_0,           8, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, VLYNQ_CLK,           9, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO14,              9, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD19_0,          9, 0, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, VLYNQ_RXD0,          9, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO15,              9, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD20_0,          9, 5, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, VLYNQ_RXD1,          9, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO16,              9, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD21_0,          9, 10, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, VLYNQ_TXD0,          9, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO17,              9, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD22_0,          9, 15, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, VLYNQ_TXD1,          9, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO18,              9, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD23_0,          9, 20, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, SDIO0_CLK,           10, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO19,              10, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO0_CMD,           10, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO20,              10, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO0_DATA0,         10, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO21,              10, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO0_DATA1,         10, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO22,              10, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO0_DATA2,         10, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO23,              10, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SDIO0_DATA3,         10, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO24,              10, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, EMU0,                11, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, EMU1,                11, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, RTCK,                12, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TRST_N,              12, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TCK,                 12, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDI,                 12, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDO,                 12, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TMS,                 12, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM1_CLK,            13, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM1_RX,             13, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM1_TX,             13, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM1_FS,             13, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R0,           14, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R1,           14, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R2,           14, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R3,           14, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R4,           14, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R5,           14, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_R6,           15, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO12,              15, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, KEYPAD_R7,           15, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO10,              15, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, KEYPAD_C0,           15, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_C1,           15, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_C2,           15, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_C3,           15, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_C4,           16, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_C5,           16, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, KEYPAD_C6,           16, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO13,              16, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, TEST_CLK_IN,         16, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, KEYPAD_C7,           16, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO11,              16, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, SSP0_0,              17, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SCC_DCLK,            17, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD20_1,          17, 0, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP0_1,              17, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SCC_CS_N,            17, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD21_1,          17, 5, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP0_2,              17, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SCC_D,               17, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD22_1,          17, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP0_3,              17, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, SCC_RESETN,          17, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, LCD_PD23_1,          17, 15, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP1_0,              18, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO25,              18, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, UART2_CTS,           18, 0, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP1_1,              18, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO26,              18, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, UART2_RD,            18, 5, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP1_2,              18, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO27,              18, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, UART2_RTS,           18, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, SSP1_3,              18, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO28,              18, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, UART2_TD,            18, 15, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, UART0_CTS,           19, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, UART0_RD,            19, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, UART0_RTS,           19, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, UART0_TD,            19, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, UART1_RD,            19, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, UART1_TD,            19, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_AC_NCS,          20, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_HSYNC_RNW,       20, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_VSYNC_A0,        20, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_MCLK,            20, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD16_0,          20, 15, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PCLK_E,          20, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD00,            20, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD01,            21, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD02,            21, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD03,            21, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD04,            21, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD05,            21, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD06,            21, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD07,            22, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD08,            22, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO59_1,            22, 5, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD09,            22, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO60_1,            22, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD10,            22, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, ASR_BA0_1,           22, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, GPIO61_1,            22, 15, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD11,            22, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO62_1,            22, 20, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD12,            22, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO63_1,            22, 25, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD13,            23, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO64_1,            23, 0, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD14,            23, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO29_1,            23, 5, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, LCD_PD15,            23, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO30_1,            23, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, EINT0,               24, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO08,              24, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, EINT1,               24, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, GPIO09,              24, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, GPIO00,              24, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD20_2,          24, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, TDM_CLK_IN_2,        24, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, GPIO01,              24, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD21_2,          24, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, 24M_CLK_OUT_1,       24, 15, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, GPIO02,              24, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD22_2,          24, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, GPIO03,              24, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD23_2,          24, 25, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, GPIO04,              25, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD16_1,          25, 0, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, USB0_RXERR,          25, 0, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, GPIO05,              25, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD17_1,          25, 5, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, TDM_CLK_IN_1,        25, 5, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, GPIO06,              25, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD18,            25, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, 24M_CLK_OUT_2,       25, 10, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, GPIO07,              25, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, LCD_PD19_1,          25, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, USB1_RXERR,          25, 15, 0x1f, 0x0c, false)
-       MUX_CFG(TNETV107X, ETH_PLL_CLK,         25, 15, 0x1f, 0x1c, false)
-       MUX_CFG(TNETV107X, MDIO,                26, 0, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, MDC,                 26, 5, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, AIC_MUTE_STAT_N,     26, 10, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM0_CLK,            26, 10, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, AIC_HNS_EN_N,        26, 15, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM0_FS,             26, 15, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, AIC_HDS_EN_STAT_N,   26, 20, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM0_TX,             26, 20, 0x1f, 0x04, false)
-       MUX_CFG(TNETV107X, AIC_HNF_EN_STAT_N,   26, 25, 0x1f, 0x00, false)
-       MUX_CFG(TNETV107X, TDM0_RX,             26, 25, 0x1f, 0x04, false)
-#endif
-};
-
-/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
-static u8 irq_prios[TNETV107X_N_CP_INTC_IRQ] = {
-       /* fill in default priority 7 */
-       [0 ... (TNETV107X_N_CP_INTC_IRQ - 1)]   = 7,
-       /* now override as needed, e.g. [xxx] = 5 */
-};
-
-/* Contents of JTAG ID register used to identify exact cpu type */
-static struct davinci_id ids[] = {
-       {
-               .variant        = 0x0,
-               .part_no        = 0xb8a1,
-               .manufacturer   = 0x017,
-               .cpu_id         = DAVINCI_CPU_ID_TNETV107X,
-               .name           = "tnetv107x rev 1.0",
-       },
-       {
-               .variant        = 0x1,
-               .part_no        = 0xb8a1,
-               .manufacturer   = 0x017,
-               .cpu_id         = DAVINCI_CPU_ID_TNETV107X,
-               .name           = "tnetv107x rev 1.1/1.2",
-       },
-};
-
-static struct davinci_timer_instance timer_instance[2] = {
-       {
-               .base           = TNETV107X_TIMER0_BASE,
-               .bottom_irq     = IRQ_TNETV107X_TIMER_0_TINT12,
-               .top_irq        = IRQ_TNETV107X_TIMER_0_TINT34,
-       },
-       {
-               .base           = TNETV107X_TIMER1_BASE,
-               .bottom_irq     = IRQ_TNETV107X_TIMER_1_TINT12,
-               .top_irq        = IRQ_TNETV107X_TIMER_1_TINT34,
-       },
-};
-
-static struct davinci_timer_info timer_info = {
-       .timers         = timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_TOP,
-};
-
-/*
- * TNETV107X platforms do not use the static mappings from Davinci
- * IO_PHYS/IO_VIRT. This SOC's interesting MMRs are at different addresses,
- * and changing IO_PHYS would break away from existing Davinci SOCs.
- *
- * The primary impact of the current model is that IO_ADDRESS() is not to be
- * used to map registers on TNETV107X.
- *
- * 1.  The first chunk is for INTC:  This needs to be mapped in via iotable
- *     because ioremap() does not seem to be operational at the time when
- *     irqs are initialized.  Without this, consistent dma init bombs.
- *
- * 2.  The second chunk maps in register areas that need to be populated into
- *     davinci_soc_info.  Note that alignment restrictions come into play if
- *     low-level debug is enabled (see note in <mach/tnetv107x.h>).
- */
-static struct map_desc io_desc[] = {
-       {       /* INTC */
-               .virtual        = IO_VIRT,
-               .pfn            = __phys_to_pfn(TNETV107X_INTC_BASE),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE
-       },
-       {       /* Most of the rest */
-               .virtual        = TNETV107X_IO_VIRT,
-               .pfn            = __phys_to_pfn(TNETV107X_IO_BASE),
-               .length         = IO_SIZE - SZ_1M,
-               .type           = MT_DEVICE
-       },
-};
-
-static unsigned long clk_sspll_recalc(struct clk *clk)
-{
-       int             pll;
-       unsigned long   mult = 0, prediv = 1, postdiv = 1;
-       unsigned long   ref = OSC_FREQ_ONCHIP, ret;
-       u32             tmp;
-
-       if (WARN_ON(!clk->pll_data))
-               return clk->rate;
-
-       if (!clk_ctrl_regs) {
-               void __iomem *tmp;
-
-               tmp = ioremap(TNETV107X_CLOCK_CONTROL_BASE, SZ_4K);
-
-               if (WARN(!tmp, "failed ioremap for clock control regs\n"))
-                       return clk->parent ? clk->parent->rate : 0;
-
-               for (pll = 0; pll < N_PLLS; pll++)
-                       sspll_regs[pll] = tmp + sspll_regs_base[pll];
-
-               clk_ctrl_regs = tmp;
-       }
-
-       pll = clk->pll_data->num;
-
-       tmp = __raw_readl(&clk_ctrl_regs->pll_bypass);
-       if (!(tmp & bypass_mask[pll])) {
-               mult    = __raw_readl(&sspll_regs[pll]->mult_factor);
-               prediv  = __raw_readl(&sspll_regs[pll]->pre_div) + 1;
-               postdiv = __raw_readl(&sspll_regs[pll]->post_div) + 1;
-       }
-
-       tmp = __raw_readl(clk->pll_data->base + PLLCTL);
-       if (tmp & PLLCTL_CLKMODE)
-               ref = pll_ext_freq[pll];
-
-       clk->pll_data->input_rate = ref;
-
-       tmp = __raw_readl(clk->pll_data->base + PLLCTL);
-       if (!(tmp & PLLCTL_PLLEN))
-               return ref;
-
-       ret = ref;
-       if (mult)
-               ret += ((unsigned long long)ref * mult) / 256;
-
-       ret /= (prediv * postdiv);
-
-       return ret;
-}
-
-static void tnetv107x_watchdog_reset(struct platform_device *pdev)
-{
-       struct wdt_regs __iomem *regs;
-
-       regs = ioremap(pdev->resource[0].start, SZ_4K);
-
-       /* disable watchdog */
-       __raw_writel(0x7777, &regs->disable_lock);
-       __raw_writel(0xcccc, &regs->disable_lock);
-       __raw_writel(0xdddd, &regs->disable_lock);
-       __raw_writel(0, &regs->disable);
-
-       /* program prescale */
-       __raw_writel(0x5a5a, &regs->prescale_lock);
-       __raw_writel(0xa5a5, &regs->prescale_lock);
-       __raw_writel(0, &regs->prescale);
-
-       /* program countdown */
-       __raw_writel(0x6666, &regs->change_lock);
-       __raw_writel(0xbbbb, &regs->change_lock);
-       __raw_writel(1, &regs->change);
-
-       /* enable watchdog */
-       __raw_writel(0x7777, &regs->disable_lock);
-       __raw_writel(0xcccc, &regs->disable_lock);
-       __raw_writel(0xdddd, &regs->disable_lock);
-       __raw_writel(1, &regs->disable);
-
-       /* kick */
-       __raw_writel(0x5555, &regs->kick_lock);
-       __raw_writel(0xaaaa, &regs->kick_lock);
-       __raw_writel(1, &regs->kick);
-}
-
-void tnetv107x_restart(enum reboot_mode mode, const char *cmd)
-{
-       tnetv107x_watchdog_reset(&tnetv107x_wdt_device);
-}
-
-static struct davinci_soc_info tnetv107x_soc_info = {
-       .io_desc                = io_desc,
-       .io_desc_num            = ARRAY_SIZE(io_desc),
-       .ids                    = ids,
-       .ids_num                = ARRAY_SIZE(ids),
-       .jtag_id_reg            = TNETV107X_CHIP_CFG_BASE + 0x018,
-       .cpu_clks               = clks,
-       .psc_bases              = psc_regs,
-       .psc_bases_num          = ARRAY_SIZE(psc_regs),
-       .pinmux_base            = TNETV107X_CHIP_CFG_BASE + 0x150,
-       .pinmux_pins            = pins,
-       .pinmux_pins_num        = ARRAY_SIZE(pins),
-       .intc_type              = DAVINCI_INTC_TYPE_CP_INTC,
-       .intc_base              = TNETV107X_INTC_BASE,
-       .intc_irq_prios         = irq_prios,
-       .intc_irq_num           = TNETV107X_N_CP_INTC_IRQ,
-       .intc_host_map          = intc_host_map,
-       .gpio_base              = TNETV107X_GPIO_BASE,
-       .gpio_type              = GPIO_TYPE_TNETV107X,
-       .gpio_num               = TNETV107X_N_GPIO,
-       .timer_info             = &timer_info,
-       .serial_dev             = tnetv107x_serial_device,
-};
-
-void __init tnetv107x_init(void)
-{
-       davinci_common_init(&tnetv107x_soc_info);
-}
index 0bc7cdf8cf469d760ac384a4aa5ae46fa7605270..d8c439c89ea93b76849965f08cbeb5149a25bbb8 100644 (file)
@@ -20,18 +20,6 @@ config MACH_CM_A510
          Say 'Y' here if you want your kernel to support the
          CompuLab CM-A510 Board.
 
-config MACH_DOVE_DT
-       bool "Marvell Dove Flattened Device Tree"
-       select DOVE_CLK
-       select ORION_IRQCHIP
-       select ORION_TIMER
-       select REGULATOR
-       select REGULATOR_FIXED_VOLTAGE
-       select USE_OF
-       help
-         Say 'Y' here if you want your kernel to support the
-         Marvell Dove using flattened device tree.
-
 endmenu
 
 endif
index cbc5c06187883988e012a282d67e359d17b624c2..b608a21919fbf5c513046a7ed5ba1668099b1b7c 100644 (file)
@@ -2,5 +2,4 @@ obj-y                           += common.o
 obj-$(CONFIG_DOVE_LEGACY)      += irq.o mpp.o
 obj-$(CONFIG_PCI)              += pcie.o
 obj-$(CONFIG_MACH_DOVE_DB)     += dove-db-setup.o
-obj-$(CONFIG_MACH_DOVE_DT)     += board-dt.o
 obj-$(CONFIG_MACH_CM_A510)     += cm-a510.o
diff --git a/arch/arm/mach-dove/board-dt.c b/arch/arm/mach-dove/board-dt.c
deleted file mode 100644 (file)
index 49fa9ab..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * arch/arm/mach-dove/board-dt.c
- *
- * Marvell Dove 88AP510 System On Chip FDT Board
- *
- * 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/init.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <asm/hardware/cache-tauros2.h>
-#include <asm/mach/arch.h>
-#include <mach/dove.h>
-#include <mach/pm.h>
-#include <plat/common.h>
-#include "common.h"
-
-static void __init dove_dt_init(void)
-{
-       pr_info("Dove 88AP510 SoC\n");
-
-#ifdef CONFIG_CACHE_TAUROS2
-       tauros2_init(0);
-#endif
-       BUG_ON(mvebu_mbus_dt_init());
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const dove_dt_board_compat[] = {
-       "marvell,dove",
-       NULL
-};
-
-DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)")
-       .map_io         = dove_map_io,
-       .init_machine   = dove_dt_init,
-       .restart        = dove_restart,
-       .dt_compat      = dove_dt_board_compat,
-MACHINE_END
index 5362df3df89f9b816f9db721e4188d3820d63e50..f4a5b34489b70285f6ad45445fc32a9031b64ee0 100644 (file)
@@ -21,6 +21,7 @@
 #define  CPU_CTRL_PCIE1_LINK   0x00000008
 
 #define RSTOUTn_MASK           (BRIDGE_VIRT_BASE + 0x0108)
+#define RSTOUTn_MASK_PHYS      (BRIDGE_PHYS_BASE + 0x0108)
 #define  SOFT_RESET_OUT_EN     0x00000004
 
 #define SYSTEM_SOFT_RESET      (BRIDGE_VIRT_BASE + 0x010c)
diff --git a/arch/arm/mach-dove/include/mach/timex.h b/arch/arm/mach-dove/include/mach/timex.h
deleted file mode 100644 (file)
index 251d538..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * arch/arm/mach-dove/include/mach/timex.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#define CLOCK_TICK_RATE                (100 * HZ)
index 68ac934d45651511fe653853dd9c3e3abb5c775a..8254e716b095b8516f657881b24bcd095d511d9c 100644 (file)
@@ -206,7 +206,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction ebsa110_timer_irq = {
        .name           = "EBSA110 Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = ebsa110_timer_interrupt,
 };
 
diff --git a/arch/arm/mach-ebsa110/include/mach/timex.h b/arch/arm/mach-ebsa110/include/mach/timex.h
deleted file mode 100644 (file)
index 4fb43b2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  arch/arm/mach-ebsa110/include/mach/timex.h
- *
- *  Copyright (C) 1997, 1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  EBSA110 architecture timex specifications
- */
-
-/*
- * On the EBSA, the clock ticks at weird rates.
- * This is therefore not used to calculate the
- * divisor.
- */
-#define CLOCK_TICK_RATE                47894000
-
diff --git a/arch/arm/mach-efm32/include/mach/entry-macro.S b/arch/arm/mach-efm32/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 322159d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
- * Empty file waiting for deletion once <mach/entry-macro.S> isn't needed any
- * more. Patch "ARM: v7-M: drop using mach/entry-macro.S" sitting in next.
- */
diff --git a/arch/arm/mach-efm32/include/mach/timex.h b/arch/arm/mach-efm32/include/mach/timex.h
deleted file mode 100644 (file)
index 7a8b26d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/*
- * Empty file waiting for deletion once <mach/timex.h> isn't needed any more.
- */
index 157ba88433c949c1db4595400cfbea3cc29a5c47..0e571f1749d6f20c7f599d72b7f72f58e641f04e 100644 (file)
@@ -117,7 +117,7 @@ void __init ep93xx_map_io(void)
 #define EP93XX_TIMER4_CLOCK            983040
 
 #define TIMER1_RELOAD                  ((EP93XX_TIMER123_CLOCK / HZ) - 1)
-#define TIMER4_TICKS_PER_JIFFY         DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
+#define TIMER4_TICKS_PER_JIFFY         DIV_ROUND_CLOSEST(EP93XX_TIMER4_CLOCK, HZ)
 
 static unsigned int last_jiffy_time;
 
@@ -242,6 +242,7 @@ unsigned int ep93xx_chip_revision(void)
        v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
        return v;
 }
+EXPORT_SYMBOL_GPL(ep93xx_chip_revision);
 
 /*************************************************************************
  * EP93xx GPIO
diff --git a/arch/arm/mach-ep93xx/include/mach/timex.h b/arch/arm/mach-ep93xx/include/mach/timex.h
deleted file mode 100644 (file)
index 6b3503b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/include/mach/timex.h
- */
-
-#define CLOCK_TICK_RATE                983040
index 8d197dcdd2c06a9fc6af1ed84d4d966c6847a46c..fc8bf18e222ddbd855e407547936e85dcc751499 100644 (file)
@@ -24,7 +24,7 @@ config ARCH_EXYNOS4
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
        select PINCTRL
-       select PM_GENERIC_DOMAINS if PM
+       select PM_GENERIC_DOMAINS if PM_RUNTIME
        select S5P_DEV_MFC
        help
          Samsung EXYNOS4 SoCs based systems
@@ -46,10 +46,8 @@ config CPU_EXYNOS4210
        default y
        depends on ARCH_EXYNOS4
        select ARCH_HAS_BANDGAP
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND if PM_SLEEP
        select PINCTRL_EXYNOS
-       select S5P_PM if PM
-       select S5P_SLEEP if PM
        select SAMSUNG_DMADEV
        help
          Enable EXYNOS4210 CPU support
@@ -60,8 +58,6 @@ config SOC_EXYNOS4212
        depends on ARCH_EXYNOS4
        select ARCH_HAS_BANDGAP
        select PINCTRL_EXYNOS
-       select S5P_PM if PM
-       select S5P_SLEEP if PM
        select SAMSUNG_DMADEV
        help
          Enable EXYNOS4212 SoC support
@@ -82,9 +78,7 @@ config SOC_EXYNOS5250
        depends on ARCH_EXYNOS5
        select ARCH_HAS_BANDGAP
        select PINCTRL_EXYNOS
-       select PM_GENERIC_DOMAINS if PM
-       select S5P_PM if PM
-       select S5P_SLEEP if PM
+       select PM_GENERIC_DOMAINS if PM_RUNTIME
        select S5P_DEV_MFC
        select SAMSUNG_DMADEV
        help
@@ -94,9 +88,7 @@ config SOC_EXYNOS5420
        bool "SAMSUNG EXYNOS5420"
        default y
        depends on ARCH_EXYNOS5
-       select PM_GENERIC_DOMAINS if PM
-       select S5P_PM if PM
-       select S5P_SLEEP if PM
+       select PM_GENERIC_DOMAINS if PM_RUNTIME
        help
          Enable EXYNOS5420 SoC support
 
index 8930b66b4abdba97b2d09aac81f28cf0df5fb21b..a656dbe3b78c877e94ac88e34fab3eb1814ef3e3 100644 (file)
@@ -12,9 +12,9 @@ obj-                          :=
 
 # Core
 
-obj-$(CONFIG_ARCH_EXYNOS)      += common.o
+obj-$(CONFIG_ARCH_EXYNOS)      += exynos.o
 
-obj-$(CONFIG_S5P_PM)           += pm.o
+obj-$(CONFIG_PM_SLEEP)         += pm.o sleep.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
 obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
 
@@ -29,8 +29,3 @@ obj-$(CONFIG_ARCH_EXYNOS)     += firmware.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_exynos-smc.o            :=-Wa,-march=armv7-a$(plus_sec)
-
-# machine support
-
-obj-$(CONFIG_ARCH_EXYNOS4)     += mach-exynos4-dt.o
-obj-$(CONFIG_ARCH_EXYNOS5)     += mach-exynos5-dt.o
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
deleted file mode 100644 (file)
index f18be40..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Common Codes for EXYNOS
- *
- * This program is free software; you can 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/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
-#include <linux/io.h>
-#include <linux/device.h>
-#include <linux/gpio.h>
-#include <clocksource/samsung_pwm.h>
-#include <linux/sched.h>
-#include <linux/serial_core.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/pm_domain.h>
-#include <linux/export.h>
-#include <linux/irqdomain.h>
-#include <linux/of_address.h>
-#include <linux/irqchip/arm-gic.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/platform_device.h>
-
-#include <asm/proc-fns.h>
-#include <asm/exception.h>
-#include <asm/hardware/cache-l2x0.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/cacheflush.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/regs-serial.h>
-
-#include "common.h"
-#include "regs-pmu.h"
-
-#define L2_AUX_VAL 0x7C470001
-#define L2_AUX_MASK 0xC200ffff
-
-static const char name_exynos4210[] = "EXYNOS4210";
-static const char name_exynos4212[] = "EXYNOS4212";
-static const char name_exynos4412[] = "EXYNOS4412";
-static const char name_exynos5250[] = "EXYNOS5250";
-static const char name_exynos5420[] = "EXYNOS5420";
-static const char name_exynos5440[] = "EXYNOS5440";
-
-static void exynos4_map_io(void);
-static void exynos5_map_io(void);
-static int exynos_init(void);
-
-static struct cpu_table cpu_ids[] __initdata = {
-       {
-               .idcode         = EXYNOS4210_CPU_ID,
-               .idmask         = EXYNOS4_CPU_MASK,
-               .map_io         = exynos4_map_io,
-               .init           = exynos_init,
-               .name           = name_exynos4210,
-       }, {
-               .idcode         = EXYNOS4212_CPU_ID,
-               .idmask         = EXYNOS4_CPU_MASK,
-               .map_io         = exynos4_map_io,
-               .init           = exynos_init,
-               .name           = name_exynos4212,
-       }, {
-               .idcode         = EXYNOS4412_CPU_ID,
-               .idmask         = EXYNOS4_CPU_MASK,
-               .map_io         = exynos4_map_io,
-               .init           = exynos_init,
-               .name           = name_exynos4412,
-       }, {
-               .idcode         = EXYNOS5250_SOC_ID,
-               .idmask         = EXYNOS5_SOC_MASK,
-               .map_io         = exynos5_map_io,
-               .init           = exynos_init,
-               .name           = name_exynos5250,
-       }, {
-               .idcode         = EXYNOS5420_SOC_ID,
-               .idmask         = EXYNOS5_SOC_MASK,
-               .map_io         = exynos5_map_io,
-               .init           = exynos_init,
-               .name           = name_exynos5420,
-       }, {
-               .idcode         = EXYNOS5440_SOC_ID,
-               .idmask         = EXYNOS5_SOC_MASK,
-               .init           = exynos_init,
-               .name           = name_exynos5440,
-       },
-};
-
-/* Initial IO mappings */
-
-static struct map_desc exynos4_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S3C_VA_SYS,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSCON),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_TIMER,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_TIMER),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_WATCHDOG,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_WATCHDOG),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_SROMC,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SROMC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_SYSTIMER,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_PMU,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_PMU),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_COMBINER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GIC_CPU,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GIC_DIST,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_CMU,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_CMU),
-               .length         = SZ_128K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_COREPERI_BASE,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_COREPERI),
-               .length         = SZ_8K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_L2CC,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_L2CC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_DMC0,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC0),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_DMC1,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC1),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_HSPHY),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4_iodesc0[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4_iodesc1[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4210_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
-               .pfn            = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4x12_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
-               .pfn            = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos5250_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
-               .pfn            = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos5_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S3C_VA_SYS,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSCON),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_TIMER,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_TIMER),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_WATCHDOG,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_SROMC,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_SROMC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_CMU,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_CMU),
-               .length         = 144 * SZ_1K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_PMU,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_PMU),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       },
-};
-
-void exynos4_restart(enum reboot_mode mode, const char *cmd)
-{
-       __raw_writel(0x1, S5P_SWRESET);
-}
-
-void exynos5_restart(enum reboot_mode mode, const char *cmd)
-{
-       struct device_node *np;
-       u32 val;
-       void __iomem *addr;
-
-       val = 0x1;
-       addr = EXYNOS_SWRESET;
-
-       if (of_machine_is_compatible("samsung,exynos5440")) {
-               u32 status;
-               np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
-
-               addr = of_iomap(np, 0) + 0xbc;
-               status = __raw_readl(addr);
-
-               addr = of_iomap(np, 0) + 0xcc;
-               val = __raw_readl(addr);
-
-               val = (val & 0xffff0000) | (status & 0xffff);
-       }
-
-       __raw_writel(val, addr);
-}
-
-static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
-};
-
-void __init exynos_cpuidle_init(void)
-{
-       platform_device_register(&exynos_cpuidle);
-}
-
-void __init exynos_cpufreq_init(void)
-{
-       platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
-}
-
-void __init exynos_init_late(void)
-{
-       if (of_machine_is_compatible("samsung,exynos5440"))
-               /* to be supported later */
-               return;
-
-       pm_genpd_poweroff_unused();
-}
-
-static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
-                                       int depth, void *data)
-{
-       struct map_desc iodesc;
-       __be32 *reg;
-       unsigned long len;
-
-       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
-               !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
-               return 0;
-
-       reg = of_get_flat_dt_prop(node, "reg", &len);
-       if (reg == NULL || len != (sizeof(unsigned long) * 2))
-               return 0;
-
-       iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
-       iodesc.length = be32_to_cpu(reg[1]) - 1;
-       iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
-       iodesc.type = MT_DEVICE;
-       iotable_init(&iodesc, 1);
-       return 1;
-}
-
-/*
- * exynos_map_io
- *
- * register the standard cpu IO areas
- */
-
-void __init exynos_init_io(void)
-{
-       debug_ll_io_init();
-
-       of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
-
-       /* detect cpu id and rev. */
-       s5p_init_cpu(S5P_VA_CHIPID);
-
-       s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
-}
-
-static void __init exynos4_map_io(void)
-{
-       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-
-       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
-               iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0));
-       else
-               iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
-
-       if (soc_is_exynos4210())
-               iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
-       if (soc_is_exynos4212() || soc_is_exynos4412())
-               iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
-}
-
-static void __init exynos5_map_io(void)
-{
-       iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
-
-       if (soc_is_exynos5250())
-               iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
-}
-
-struct bus_type exynos_subsys = {
-       .name           = "exynos-core",
-       .dev_name       = "exynos-core",
-};
-
-static struct device exynos4_dev = {
-       .bus    = &exynos_subsys,
-};
-
-static int __init exynos_core_init(void)
-{
-       return subsys_system_register(&exynos_subsys, NULL);
-}
-core_initcall(exynos_core_init);
-
-static int __init exynos4_l2x0_cache_init(void)
-{
-       int ret;
-
-       ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
-       if (ret)
-               return ret;
-
-       l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
-       clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
-       return 0;
-}
-early_initcall(exynos4_l2x0_cache_init);
-
-static int __init exynos_init(void)
-{
-       printk(KERN_INFO "EXYNOS: Initializing architecture\n");
-
-       return device_register(&exynos4_dev);
-}
index f76967b1c551054da36b391e7413e47057641aae..9ef3f83efaffa642c9bbe26d68aa71750072c28e 100644 (file)
@@ -19,14 +19,27 @@ void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1);
 
 struct map_desc;
 void exynos_init_io(void);
-void exynos4_restart(enum reboot_mode mode, const char *cmd);
-void exynos5_restart(enum reboot_mode mode, const char *cmd);
+void exynos_restart(enum reboot_mode mode, const char *cmd);
 void exynos_cpuidle_init(void);
 void exynos_cpufreq_init(void);
 void exynos_init_late(void);
 
 void exynos_firmware_init(void);
 
+#ifdef CONFIG_PINCTRL_EXYNOS
+extern u32 exynos_get_eint_wake_mask(void);
+#else
+static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+extern void __init exynos_pm_init(void);
+#else
+static inline void exynos_pm_init(void) {}
+#endif
+
+extern void exynos_cpu_resume(void);
+
 extern struct smp_operations exynos_smp_ops;
 
 extern void exynos_cpu_die(unsigned int cpu);
index f57cb91f02aa939b8896ed07eae6f3e2326f38da..c57cae0e8779213aec55424c43530e1404af4db0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/cpu_pm.h>
 #include <linux/io.h>
 #include <linux/export.h>
+#include <linux/module.h>
 #include <linux/time.h>
 #include <linux/platform_device.h>
 
@@ -26,7 +27,6 @@
 #include <plat/cpu.h>
 #include <plat/pm.h>
 
-#include <mach/pm-core.h>
 #include <mach/map.h>
 
 #include "common.h"
@@ -127,7 +127,7 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
        /* Set value of power down register for aftr mode */
        exynos_sys_powerdown_conf(SYS_AFTR);
 
-       __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
+       __raw_writel(virt_to_phys(exynos_cpu_resume), REG_DIRECTGO_ADDR);
        __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
 
        save_cpu_arch_register();
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
new file mode 100644 (file)
index 0000000..b32a907
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * SAMSUNG EXYNOS Flattened Device Tree enabled machine
+ *
+ * Copyright (c) 2010-2014 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/serial_s3c.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/memory.h>
+
+#include <plat/cpu.h>
+
+#include "common.h"
+#include "mfc.h"
+#include "regs-pmu.h"
+
+#define L2_AUX_VAL 0x7C470001
+#define L2_AUX_MASK 0xC200ffff
+
+static struct map_desc exynos4_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_SYS,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSCON),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_TIMER,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_TIMER),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_WATCHDOG,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_WATCHDOG),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SROMC,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SROMC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SYSTIMER,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_PMU,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_PMU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_COMBINER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GIC_CPU,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GIC_DIST,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_CMU,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_CMU),
+               .length         = SZ_128K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_COREPERI_BASE,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_COREPERI),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_L2CC,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_L2CC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_DMC0,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC0),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_DMC1,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC1),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_HSPHY),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4_iodesc0[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4_iodesc1[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4210_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
+               .pfn            = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4x12_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
+               .pfn            = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos5250_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
+               .pfn            = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos5_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_SYS,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSCON),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_TIMER,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_TIMER),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_WATCHDOG,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SROMC,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SROMC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_CMU,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_CMU),
+               .length         = 144 * SZ_1K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_PMU,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_PMU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       },
+};
+
+void exynos_restart(enum reboot_mode mode, const char *cmd)
+{
+       struct device_node *np;
+       u32 val = 0x1;
+       void __iomem *addr = EXYNOS_SWRESET;
+
+       if (of_machine_is_compatible("samsung,exynos5440")) {
+               u32 status;
+               np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
+
+               addr = of_iomap(np, 0) + 0xbc;
+               status = __raw_readl(addr);
+
+               addr = of_iomap(np, 0) + 0xcc;
+               val = __raw_readl(addr);
+
+               val = (val & 0xffff0000) | (status & 0xffff);
+       }
+
+       __raw_writel(val, addr);
+}
+
+static struct platform_device exynos_cpuidle = {
+       .name           = "exynos_cpuidle",
+       .id             = -1,
+};
+
+void __init exynos_cpuidle_init(void)
+{
+       platform_device_register(&exynos_cpuidle);
+}
+
+void __init exynos_cpufreq_init(void)
+{
+       platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
+}
+
+void __init exynos_init_late(void)
+{
+       if (of_machine_is_compatible("samsung,exynos5440"))
+               /* to be supported later */
+               return;
+
+       pm_genpd_poweroff_unused();
+       exynos_pm_init();
+}
+
+static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
+                                       int depth, void *data)
+{
+       struct map_desc iodesc;
+       __be32 *reg;
+       unsigned long len;
+
+       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
+               !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
+               return 0;
+
+       reg = of_get_flat_dt_prop(node, "reg", &len);
+       if (reg == NULL || len != (sizeof(unsigned long) * 2))
+               return 0;
+
+       iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
+       iodesc.length = be32_to_cpu(reg[1]) - 1;
+       iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
+       iodesc.type = MT_DEVICE;
+       iotable_init(&iodesc, 1);
+       return 1;
+}
+
+/*
+ * exynos_map_io
+ *
+ * register the standard cpu IO areas
+ */
+static void __init exynos_map_io(void)
+{
+       if (soc_is_exynos4())
+               iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+
+       if (soc_is_exynos5())
+               iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
+
+       if (soc_is_exynos4210()) {
+               if (samsung_rev() == EXYNOS4210_REV_0)
+                       iotable_init(exynos4_iodesc0,
+                                               ARRAY_SIZE(exynos4_iodesc0));
+               else
+                       iotable_init(exynos4_iodesc1,
+                                               ARRAY_SIZE(exynos4_iodesc1));
+               iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
+       }
+       if (soc_is_exynos4212() || soc_is_exynos4412())
+               iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
+       if (soc_is_exynos5250())
+               iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
+}
+
+void __init exynos_init_io(void)
+{
+       debug_ll_io_init();
+
+       of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
+
+       /* detect cpu id and rev. */
+       s5p_init_cpu(S5P_VA_CHIPID);
+
+       exynos_map_io();
+}
+
+struct bus_type exynos_subsys = {
+       .name           = "exynos-core",
+       .dev_name       = "exynos-core",
+};
+
+static int __init exynos_core_init(void)
+{
+       return subsys_system_register(&exynos_subsys, NULL);
+}
+core_initcall(exynos_core_init);
+
+static int __init exynos4_l2x0_cache_init(void)
+{
+       int ret;
+
+       ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+       if (ret)
+               return ret;
+
+       if (IS_ENABLED(CONFIG_S5P_SLEEP)) {
+               l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+               clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+       }
+       return 0;
+}
+early_initcall(exynos4_l2x0_cache_init);
+
+static void __init exynos_dt_machine_init(void)
+{
+       struct device_node *i2c_np;
+       const char *i2c_compat = "samsung,s3c2440-i2c";
+       unsigned int tmp;
+       int id;
+
+       /*
+        * Exynos5's legacy i2c controller and new high speed i2c
+        * controller have muxed interrupt sources. By default the
+        * interrupts for 4-channel HS-I2C controller are enabled.
+        * If node for first four channels of legacy i2c controller
+        * are available then re-configure the interrupts via the
+        * system register.
+        */
+       if (soc_is_exynos5()) {
+               for_each_compatible_node(i2c_np, NULL, i2c_compat) {
+                       if (of_device_is_available(i2c_np)) {
+                               id = of_alias_get_id(i2c_np, "i2c");
+                               if (id < 4) {
+                                       tmp = readl(EXYNOS5_SYS_I2C_CFG);
+                                       writel(tmp & ~(0x1 << id),
+                                                       EXYNOS5_SYS_I2C_CFG);
+                               }
+                       }
+               }
+       }
+
+       exynos_cpuidle_init();
+       exynos_cpufreq_init();
+
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static char const *exynos_dt_compat[] __initconst = {
+       "samsung,exynos4",
+       "samsung,exynos4210",
+       "samsung,exynos4212",
+       "samsung,exynos4412",
+       "samsung,exynos5",
+       "samsung,exynos5250",
+       "samsung,exynos5420",
+       "samsung,exynos5440",
+       NULL
+};
+
+static void __init exynos_reserve(void)
+{
+#ifdef CONFIG_S5P_DEV_MFC
+       int i;
+       char *mfc_mem[] = {
+               "samsung,mfc-v5",
+               "samsung,mfc-v6",
+               "samsung,mfc-v7",
+       };
+
+       for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
+               if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i]))
+                       break;
+#endif
+}
+
+DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
+       /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .smp            = smp_ops(exynos_smp_ops),
+       .map_io         = exynos_init_io,
+       .init_early     = exynos_firmware_init,
+       .init_machine   = exynos_dt_machine_init,
+       .init_late      = exynos_init_late,
+       .dt_compat      = exynos_dt_compat,
+       .restart        = exynos_restart,
+       .reserve        = exynos_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/include/mach/hardware.h b/arch/arm/mach-exynos/include/mach/hardware.h
deleted file mode 100644 (file)
index 5109eb2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/hardware.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Hardware support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H __FILE__
-
-/* currently nothing here, placeholder */
-
-#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h
deleted file mode 100644 (file)
index dc0697c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_PM_CORE_H
-#define __ASM_ARCH_PM_CORE_H __FILE__
-
-#include <linux/of.h>
-#include <mach/map.h>
-
-#define S5P_EINT_WAKEUP_MASK                   (S5P_VA_PMU + 0x0604)
-#define S5P_WAKEUP_MASK                                (S5P_VA_PMU + 0x0608)
-
-#ifdef CONFIG_PINCTRL_EXYNOS
-extern u32 exynos_get_eint_wake_mask(void);
-#else
-static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
-#endif
-
-static inline void s3c_pm_debug_init_uart(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_arch_prepare_irqs(void)
-{
-       __raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
-       __raw_writel(s3c_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
-}
-
-static inline void s3c_pm_arch_stop_clocks(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_arch_show_resume_irqs(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
-                                          struct pm_uart_save *save)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_restored_gpios(void)
-{
-       /* nothing here yet */
-}
-
-static inline void samsung_pm_saved_gpios(void)
-{
-       /* nothing here yet */
-}
-
-/* Compatibility definitions to make plat-samsung/pm.c compile */
-#define IRQ_EINT_BIT(x)                1
-#define s3c_irqwake_intallow   0
-#define s3c_irqwake_eintallow  0
-
-#endif /* __ASM_ARCH_PM_CORE_H */
diff --git a/arch/arm/mach-exynos/include/mach/timex.h b/arch/arm/mach-exynos/include/mach/timex.h
deleted file mode 100644 (file)
index 6d13875..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/timex.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (c) 2003-2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Based on arch/arm/mach-s5p6442/include/mach/timex.h
- *
- * EXYNOS4 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H __FILE__
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-exynos/include/mach/uncompress.h b/arch/arm/mach-exynos/include/mach/uncompress.h
deleted file mode 100644 (file)
index 5d7ce36..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H __FILE__
-
-#include <asm/mach-types.h>
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static unsigned int __raw_readl(unsigned int ptr)
-{
-       return *((volatile unsigned int *)ptr);
-}
-
-static void arch_detect_cpu(void)
-{
-       u32 chip_id = __raw_readl(EXYNOS_PA_CHIPID);
-
-       /*
-        * product_id is bits 31:12
-        * bits 23:20 describe the exynosX family
-        * bits 27:24 describe the exynosX family in exynos5420
-        */
-       chip_id >>= 20;
-
-       if ((chip_id & 0x0f) == 0x5 || (chip_id & 0xf0) == 0x50)
-               uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
-       else
-               uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
-
-       /*
-        * For preventing FIFO overrun or infinite loop of UART console,
-        * fifo_max should be the minimum fifo size of all of the UART channels
-        */
-       fifo_mask = S5PV210_UFSTAT_TXMASK;
-       fifo_max = 15 << S5PV210_UFSTAT_TXSHIFT;
-}
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
deleted file mode 100644 (file)
index d3e54b7..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Samsung's EXYNOS4 flattened device tree enabled machine
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- * Copyright (c) 2010-2011 Linaro Ltd.
- *             www.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.
-*/
-
-#include <linux/of_platform.h>
-#include <linux/of_fdt.h>
-
-#include <asm/mach/arch.h>
-#include <plat/mfc.h>
-
-#include "common.h"
-
-static void __init exynos4_dt_machine_init(void)
-{
-       exynos_cpuidle_init();
-       exynos_cpufreq_init();
-
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static char const *exynos4_dt_compat[] __initdata = {
-       "samsung,exynos4210",
-       "samsung,exynos4212",
-       "samsung,exynos4412",
-       NULL
-};
-
-static void __init exynos4_reserve(void)
-{
-#ifdef CONFIG_S5P_DEV_MFC
-       struct s5p_mfc_dt_meminfo mfc_mem;
-
-       /* Reserve memory for MFC only if it's available */
-       mfc_mem.compatible = "samsung,mfc-v5";
-       if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem))
-               s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff,
-                               mfc_mem.lsize);
-#endif
-}
-DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
-       /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
-       .smp            = smp_ops(exynos_smp_ops),
-       .map_io         = exynos_init_io,
-       .init_early     = exynos_firmware_init,
-       .init_machine   = exynos4_dt_machine_init,
-       .init_late      = exynos_init_late,
-       .dt_compat      = exynos4_dt_compat,
-       .restart        = exynos4_restart,
-       .reserve        = exynos4_reserve,
-MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
deleted file mode 100644 (file)
index 37ea261..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SAMSUNG EXYNOS5250 Flattened Device Tree enabled machine
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/of_platform.h>
-#include <linux/of_fdt.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <plat/mfc.h>
-
-#include "common.h"
-#include "regs-pmu.h"
-
-static void __init exynos5_dt_machine_init(void)
-{
-       struct device_node *i2c_np;
-       const char *i2c_compat = "samsung,s3c2440-i2c";
-       unsigned int tmp;
-
-       /*
-        * Exynos5's legacy i2c controller and new high speed i2c
-        * controller have muxed interrupt sources. By default the
-        * interrupts for 4-channel HS-I2C controller are enabled.
-        * If node for first four channels of legacy i2c controller
-        * are available then re-configure the interrupts via the
-        * system register.
-        */
-       for_each_compatible_node(i2c_np, NULL, i2c_compat) {
-               if (of_device_is_available(i2c_np)) {
-                       if (of_alias_get_id(i2c_np, "i2c") < 4) {
-                               tmp = readl(EXYNOS5_SYS_I2C_CFG);
-                               writel(tmp & ~(0x1 << of_alias_get_id(i2c_np, "i2c")),
-                                               EXYNOS5_SYS_I2C_CFG);
-                       }
-               }
-       }
-
-       exynos_cpuidle_init();
-       exynos_cpufreq_init();
-
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static char const *exynos5_dt_compat[] __initdata = {
-       "samsung,exynos5250",
-       "samsung,exynos5420",
-       "samsung,exynos5440",
-       NULL
-};
-
-static void __init exynos5_reserve(void)
-{
-#ifdef CONFIG_S5P_DEV_MFC
-       struct s5p_mfc_dt_meminfo mfc_mem;
-
-       /* Reserve memory for MFC only if it's available */
-       mfc_mem.compatible = "samsung,mfc-v6";
-       if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem))
-               s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff,
-                               mfc_mem.lsize);
-#endif
-}
-
-DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
-       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-       .smp            = smp_ops(exynos_smp_ops),
-       .map_io         = exynos_init_io,
-       .init_machine   = exynos5_dt_machine_init,
-       .init_late      = exynos_init_late,
-       .dt_compat      = exynos5_dt_compat,
-       .restart        = exynos5_restart,
-       .reserve        = exynos5_reserve,
-MACHINE_END
diff --git a/arch/arm/mach-exynos/mfc.h b/arch/arm/mach-exynos/mfc.h
new file mode 100644 (file)
index 0000000..dec93cd
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MACH_EXYNOS_MFC_H
+#define __MACH_EXYNOS_MFC_H __FILE__
+
+int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname,
+                               int depth, void *data);
+
+#endif /* __MACH_EXYNOS_MFC_H */
index 8ea02f63fed9565993e15fb6d645888191926436..03e5e9f9470536c01180963261dabf0c0c0eca08 100644 (file)
@@ -26,8 +26,6 @@
 #include <asm/smp_scu.h>
 #include <asm/firmware.h>
 
-#include <mach/hardware.h>
-
 #include <plat/cpu.h>
 
 #include "common.h"
index e00025bbbe89c914accb61ec42f519415823f8a3..15af0ceb0a66a063d0c2ed948ca4a28a1109c777 100644 (file)
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
 #include <linux/io.h>
+#include <linux/irqchip/arm-gic.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/smp_scu.h>
+#include <asm/suspend.h>
 
 #include <plat/cpu.h>
-#include <plat/pm.h>
+#include <plat/pm-common.h>
 #include <plat/pll.h>
 #include <plat/regs-srom.h>
 
 #include <mach/map.h>
-#include <mach/pm-core.h>
 
 #include "common.h"
 #include "regs-pmu.h"
 
-#define EXYNOS4_EPLL_LOCK                      (S5P_VA_CMU + 0x0C010)
-#define EXYNOS4_VPLL_LOCK                      (S5P_VA_CMU + 0x0C020)
-
-#define EXYNOS4_EPLL_CON0                      (S5P_VA_CMU + 0x0C110)
-#define EXYNOS4_EPLL_CON1                      (S5P_VA_CMU + 0x0C114)
-#define EXYNOS4_VPLL_CON0                      (S5P_VA_CMU + 0x0C120)
-#define EXYNOS4_VPLL_CON1                      (S5P_VA_CMU + 0x0C124)
-
-#define EXYNOS4_CLKSRC_MASK_TOP                        (S5P_VA_CMU + 0x0C310)
-#define EXYNOS4_CLKSRC_MASK_CAM                        (S5P_VA_CMU + 0x0C320)
-#define EXYNOS4_CLKSRC_MASK_TV                 (S5P_VA_CMU + 0x0C324)
-#define EXYNOS4_CLKSRC_MASK_LCD0               (S5P_VA_CMU + 0x0C334)
-#define EXYNOS4_CLKSRC_MASK_MAUDIO             (S5P_VA_CMU + 0x0C33C)
-#define EXYNOS4_CLKSRC_MASK_FSYS               (S5P_VA_CMU + 0x0C340)
-#define EXYNOS4_CLKSRC_MASK_PERIL0             (S5P_VA_CMU + 0x0C350)
-#define EXYNOS4_CLKSRC_MASK_PERIL1             (S5P_VA_CMU + 0x0C354)
-
-#define EXYNOS4_CLKSRC_MASK_DMC                        (S5P_VA_CMU + 0x10300)
-
-#define EXYNOS4_EPLLCON0_LOCKED_SHIFT          (29)
-#define EXYNOS4_VPLLCON0_LOCKED_SHIFT          (29)
-
-#define EXYNOS4210_CLKSRC_MASK_LCD1            (S5P_VA_CMU + 0x0C338)
-
-static const struct sleep_save exynos4_set_clksrc[] = {
-       { .reg = EXYNOS4_CLKSRC_MASK_TOP                , .val = 0x00000001, },
-       { .reg = EXYNOS4_CLKSRC_MASK_CAM                , .val = 0x11111111, },
-       { .reg = EXYNOS4_CLKSRC_MASK_TV                 , .val = 0x00000111, },
-       { .reg = EXYNOS4_CLKSRC_MASK_LCD0               , .val = 0x00001111, },
-       { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO             , .val = 0x00000001, },
-       { .reg = EXYNOS4_CLKSRC_MASK_FSYS               , .val = 0x01011111, },
-       { .reg = EXYNOS4_CLKSRC_MASK_PERIL0             , .val = 0x01111111, },
-       { .reg = EXYNOS4_CLKSRC_MASK_PERIL1             , .val = 0x01110111, },
-       { .reg = EXYNOS4_CLKSRC_MASK_DMC                , .val = 0x00010000, },
-};
-
-static const struct sleep_save exynos4210_set_clksrc[] = {
-       { .reg = EXYNOS4210_CLKSRC_MASK_LCD1            , .val = 0x00001111, },
-};
-
-static struct sleep_save exynos4_epll_save[] = {
-       SAVE_ITEM(EXYNOS4_EPLL_CON0),
-       SAVE_ITEM(EXYNOS4_EPLL_CON1),
-};
-
-static struct sleep_save exynos4_vpll_save[] = {
-       SAVE_ITEM(EXYNOS4_VPLL_CON0),
-       SAVE_ITEM(EXYNOS4_VPLL_CON1),
+/**
+ * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
+ * @hwirq: Hardware IRQ signal of the GIC
+ * @mask: Mask in PMU wake-up mask register
+ */
+struct exynos_wkup_irq {
+       unsigned int hwirq;
+       u32 mask;
 };
 
 static struct sleep_save exynos5_sys_save[] = {
@@ -98,6 +59,46 @@ static struct sleep_save exynos_core_save[] = {
        SAVE_ITEM(S5P_SROM_BC3),
 };
 
+/*
+ * GIC wake-up support
+ */
+
+static u32 exynos_irqwake_intmask = 0xffffffff;
+
+static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
+       { 76, BIT(1) }, /* RTC alarm */
+       { 77, BIT(2) }, /* RTC tick */
+       { /* sentinel */ },
+};
+
+static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
+       { 75, BIT(1) }, /* RTC alarm */
+       { 76, BIT(2) }, /* RTC tick */
+       { /* sentinel */ },
+};
+
+static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
+{
+       const struct exynos_wkup_irq *wkup_irq;
+
+       if (soc_is_exynos5250())
+               wkup_irq = exynos5250_wkup_irq;
+       else
+               wkup_irq = exynos4_wkup_irq;
+
+       while (wkup_irq->mask) {
+               if (wkup_irq->hwirq == data->hwirq) {
+                       if (!state)
+                               exynos_irqwake_intmask |= wkup_irq->mask;
+                       else
+                               exynos_irqwake_intmask &= ~wkup_irq->mask;
+                       return 0;
+               }
+               ++wkup_irq;
+       }
+
+       return -ENOENT;
+}
 
 /* For Cortex-A9 Diagnostic and Power control register */
 static unsigned int save_arm_register[2];
@@ -122,12 +123,13 @@ static void exynos_pm_prepare(void)
 {
        unsigned int tmp;
 
+       /* Set wake-up mask registers */
+       __raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
+       __raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
+
        s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-       if (!soc_is_exynos5250()) {
-               s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
-               s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
-       } else {
+       if (soc_is_exynos5250()) {
                s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
                /* Disable USE_RETENTION of JPEG_MEM_OPTION */
                tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION);
@@ -142,127 +144,8 @@ static void exynos_pm_prepare(void)
 
        /* ensure at least INFORM0 has the resume address */
 
-       __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
-
-       /* Before enter central sequence mode, clock src register have to set */
-
-       if (!soc_is_exynos5250())
-               s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
-
-       if (soc_is_exynos4210())
-               s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
-
-}
-
-static int exynos_pm_add(struct device *dev, struct subsys_interface *sif)
-{
-       pm_cpu_prep = exynos_pm_prepare;
-       pm_cpu_sleep = exynos_cpu_suspend;
-
-       return 0;
-}
-
-static unsigned long pll_base_rate;
-
-static void exynos4_restore_pll(void)
-{
-       unsigned long pll_con, locktime, lockcnt;
-       unsigned long pll_in_rate;
-       unsigned int p_div, epll_wait = 0, vpll_wait = 0;
-
-       if (pll_base_rate == 0)
-               return;
-
-       pll_in_rate = pll_base_rate;
-
-       /* EPLL */
-       pll_con = exynos4_epll_save[0].val;
-
-       if (pll_con & (1 << 31)) {
-               pll_con &= (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT);
-               p_div = (pll_con >> PLL46XX_PDIV_SHIFT);
-
-               pll_in_rate /= 1000000;
-
-               locktime = (3000 / pll_in_rate) * p_div;
-               lockcnt = locktime * 10000 / (10000 / pll_in_rate);
-
-               __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK);
-
-               s3c_pm_do_restore_core(exynos4_epll_save,
-                                       ARRAY_SIZE(exynos4_epll_save));
-               epll_wait = 1;
-       }
-
-       pll_in_rate = pll_base_rate;
-
-       /* VPLL */
-       pll_con = exynos4_vpll_save[0].val;
-
-       if (pll_con & (1 << 31)) {
-               pll_in_rate /= 1000000;
-               /* 750us */
-               locktime = 750;
-               lockcnt = locktime * 10000 / (10000 / pll_in_rate);
-
-               __raw_writel(lockcnt, EXYNOS4_VPLL_LOCK);
-
-               s3c_pm_do_restore_core(exynos4_vpll_save,
-                                       ARRAY_SIZE(exynos4_vpll_save));
-               vpll_wait = 1;
-       }
-
-       /* Wait PLL locking */
-
-       do {
-               if (epll_wait) {
-                       pll_con = __raw_readl(EXYNOS4_EPLL_CON0);
-                       if (pll_con & (1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT))
-                               epll_wait = 0;
-               }
-
-               if (vpll_wait) {
-                       pll_con = __raw_readl(EXYNOS4_VPLL_CON0);
-                       if (pll_con & (1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT))
-                               vpll_wait = 0;
-               }
-       } while (epll_wait || vpll_wait);
-}
-
-static struct subsys_interface exynos_pm_interface = {
-       .name           = "exynos_pm",
-       .subsys         = &exynos_subsys,
-       .add_dev        = exynos_pm_add,
-};
-
-static __init int exynos_pm_drvinit(void)
-{
-       struct clk *pll_base;
-       unsigned int tmp;
-
-       if (soc_is_exynos5440())
-               return 0;
-
-       s3c_pm_init();
-
-       /* All wakeup disable */
-
-       tmp = __raw_readl(S5P_WAKEUP_MASK);
-       tmp |= ((0xFF << 8) | (0x1F << 1));
-       __raw_writel(tmp, S5P_WAKEUP_MASK);
-
-       if (!soc_is_exynos5250()) {
-               pll_base = clk_get(NULL, "xtal");
-
-               if (!IS_ERR(pll_base)) {
-                       pll_base_rate = clk_get_rate(pll_base);
-                       clk_put(pll_base);
-               }
-       }
-
-       return subsys_interface_register(&exynos_pm_interface);
+       __raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
 }
-arch_initcall(exynos_pm_drvinit);
 
 static int exynos_pm_suspend(void)
 {
@@ -343,13 +226,8 @@ static void exynos_pm_resume(void)
 
        s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-       if (!soc_is_exynos5250()) {
-               exynos4_restore_pll();
-
-#ifdef CONFIG_SMP
+       if (IS_ENABLED(CONFIG_SMP) && !soc_is_exynos5250())
                scu_enable(S5P_VA_SCU);
-#endif
-       }
 
 early_wakeup:
 
@@ -364,12 +242,80 @@ static struct syscore_ops exynos_pm_syscore_ops = {
        .resume         = exynos_pm_resume,
 };
 
-static __init int exynos_pm_syscore_init(void)
+/*
+ * Suspend Ops
+ */
+
+static int exynos_suspend_enter(suspend_state_t state)
 {
-       if (soc_is_exynos5440())
-               return 0;
+       int ret;
+
+       s3c_pm_debug_init();
+
+       S3C_PMDBG("%s: suspending the system...\n", __func__);
+
+       S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
+                       exynos_irqwake_intmask, exynos_get_eint_wake_mask());
+
+       if (exynos_irqwake_intmask == -1U
+           && exynos_get_eint_wake_mask() == -1U) {
+               pr_err("%s: No wake-up sources!\n", __func__);
+               pr_err("%s: Aborting sleep\n", __func__);
+               return -EINVAL;
+       }
+
+       s3c_pm_save_uarts();
+       exynos_pm_prepare();
+       flush_cache_all();
+       s3c_pm_check_store();
+
+       ret = cpu_suspend(0, exynos_cpu_suspend);
+       if (ret)
+               return ret;
+
+       s3c_pm_restore_uarts();
+
+       S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
+                       __raw_readl(S5P_WAKEUP_STAT));
+
+       s3c_pm_check_restore();
+
+       S3C_PMDBG("%s: resuming the system...\n", __func__);
 
-       register_syscore_ops(&exynos_pm_syscore_ops);
        return 0;
 }
-arch_initcall(exynos_pm_syscore_init);
+
+static int exynos_suspend_prepare(void)
+{
+       s3c_pm_check_prepare();
+
+       return 0;
+}
+
+static void exynos_suspend_finish(void)
+{
+       s3c_pm_check_cleanup();
+}
+
+static const struct platform_suspend_ops exynos_suspend_ops = {
+       .enter          = exynos_suspend_enter,
+       .prepare        = exynos_suspend_prepare,
+       .finish         = exynos_suspend_finish,
+       .valid          = suspend_valid_only_mem,
+};
+
+void __init exynos_pm_init(void)
+{
+       u32 tmp;
+
+       /* Platform-specific GIC callback */
+       gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
+
+       /* All wakeup disable */
+       tmp = __raw_readl(S5P_WAKEUP_MASK);
+       tmp |= ((0xFF << 8) | (0x1F << 1));
+       __raw_writel(tmp, S5P_WAKEUP_MASK);
+
+       register_syscore_ops(&exynos_pm_syscore_ops);
+       suspend_set_ops(&exynos_suspend_ops);
+}
index 8fd24882f0b1eb5a1963fdb985c577729170e081..fe6570ebbdde961de10602f3e77ad5a7bc09fa8c 100644 (file)
@@ -22,8 +22,6 @@
 #include <linux/of_platform.h>
 #include <linux/sched.h>
 
-#include <plat/devs.h>
-
 #include "regs-pmu.h"
 
 /*
index 7c029ce27711d7b8fa2737098e1662befe322ebe..4f6a2560d0220e0244eb35d55f1ebc55e66cc734 100644 (file)
 #define S5P_USE_STANDBY_WFI0                   (1 << 16)
 #define S5P_USE_STANDBY_WFE0                   (1 << 24)
 
-#define S5P_SWRESET                            S5P_PMUREG(0x0400)
 #define EXYNOS_SWRESET                         S5P_PMUREG(0x0400)
 #define EXYNOS5440_SWRESET                     S5P_PMUREG(0x00C4)
 
 #define S5P_WAKEUP_STAT                                S5P_PMUREG(0x0600)
+#define S5P_EINT_WAKEUP_MASK                   S5P_PMUREG(0x0604)
+#define S5P_WAKEUP_MASK                                S5P_PMUREG(0x0608)
 
 #define S5P_INFORM0                            S5P_PMUREG(0x0800)
 #define S5P_INFORM1                            S5P_PMUREG(0x0804)
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
new file mode 100644 (file)
index 0000000..a2613e9
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Exynos low-level resume code
+ *
+ * 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>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#define CPU_MASK       0xff0ffff0
+#define CPU_CORTEX_A9  0x410fc090
+
+       /*
+        * The following code is located into the .data section. This is to
+        * allow l2x0_regs_phys to be accessed with a relative load while we
+        * can't rely on any MMU translation. We could have put l2x0_regs_phys
+        * in the .text section as well, but some setups might insist on it to
+        * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
+        */
+       .data
+       .align
+
+       /*
+        * sleep magic, to allow the bootloader to check for an valid
+        * image to resume to. Must be the first word before the
+        * exynos_cpu_resume entry.
+        */
+
+       .word   0x2bedf00d
+
+       /*
+        * exynos_cpu_resume
+        *
+        * resume code entry for bootloader to call
+        */
+
+ENTRY(exynos_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+       mrc     p15, 0, r0, c0, c0, 0
+       ldr     r1, =CPU_MASK
+       and     r0, r0, r1
+       ldr     r1, =CPU_CORTEX_A9
+       cmp     r0, r1
+       bne     skip_l2_resume
+       adr     r0, l2x0_regs_phys
+       ldr     r0, [r0]
+       cmp     r0, #0
+       beq     skip_l2_resume
+       ldr     r1, [r0, #L2X0_R_PHY_BASE]
+       ldr     r2, [r1, #L2X0_CTRL]
+       tst     r2, #0x1
+       bne     skip_l2_resume
+       ldr     r2, [r0, #L2X0_R_AUX_CTRL]
+       str     r2, [r1, #L2X0_AUX_CTRL]
+       ldr     r2, [r0, #L2X0_R_TAG_LATENCY]
+       str     r2, [r1, #L2X0_TAG_LATENCY_CTRL]
+       ldr     r2, [r0, #L2X0_R_DATA_LATENCY]
+       str     r2, [r1, #L2X0_DATA_LATENCY_CTRL]
+       ldr     r2, [r0, #L2X0_R_PREFETCH_CTRL]
+       str     r2, [r1, #L2X0_PREFETCH_CTRL]
+       ldr     r2, [r0, #L2X0_R_PWR_CTRL]
+       str     r2, [r1, #L2X0_POWER_CTRL]
+       mov     r2, #1
+       str     r2, [r1, #L2X0_CTRL]
+skip_l2_resume:
+#endif
+       b       cpu_resume
+ENDPROC(exynos_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+       .globl l2x0_regs_phys
+l2x0_regs_phys:
+       .long   0
+#endif
index fba55fb9f47dfe58829f74174c718d69e5ea70d1..07152d00fc505bc2aceac2cc9ebffae485175c8d 100644 (file)
@@ -52,6 +52,7 @@ config ARCH_EBSA285_HOST
        select FOOTBRIDGE_HOST
        select ISA
        select ISA_DMA
+       select ARCH_MAY_HAVE_PC_FDC
        select PCI
        help
          Say Y here if you intend to run this kernel on the EBSA285 card
@@ -94,6 +95,5 @@ config FOOTBRIDGE_ADDIN
 # EBSA285 board in either host or addin mode
 config ARCH_EBSA285
        bool
-       select ARCH_MAY_HAVE_PC_FDC
 
 endif
index 0b64dd430d6150317288302c94f3b11fa0f1762e..c3faa3bc84dd3ea49321d06ae997132dabd12c7b 100644 (file)
@@ -4,11 +4,12 @@
 
 # Object file lists.
 
-obj-y                  := common.o dc21285.o dma.o isa-irq.o
+obj-y                  := common.o dma.o isa-irq.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
 
+pci-y                  += dc21285.o
 pci-$(CONFIG_ARCH_CATS) += cats-pci.o
 pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
 pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
index 9669cc0b63182c780cb55314db4aa194869dc49c..da04150948566383890b9704eb871ee0dc7108bb 100644 (file)
@@ -78,9 +78,11 @@ __initcall(cats_hw_init);
 static void __init
 fixup_cats(struct tag *tags, char **cmdline, struct meminfo *mi)
 {
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
        screen_info.orig_video_lines  = 25;
        screen_info.orig_video_points = 16;
        screen_info.orig_y = 24;
+#endif
 }
 
 MACHINE_START(CATS, "Chalice-CATS")
index 3971104d32d4794591199f2ac7df54829032e07d..bf7aa7d298e7da11324087ef60b06928c00479c2 100644 (file)
@@ -105,7 +105,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
 static struct irqaction footbridge_timer_irq = {
        .name           = "dc21285_timer1",
        .handler        = timer1_interrupt,
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .dev_id         = &ckevt_dc21285,
 };
 
@@ -125,7 +125,7 @@ void __init footbridge_timer_init(void)
        clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
 }
 
-static u32 notrace footbridge_read_sched_clock(void)
+static u64 notrace footbridge_read_sched_clock(void)
 {
        return ~*CSR_TIMER3_VALUE;
 }
@@ -138,5 +138,5 @@ void __init footbridge_sched_clock(void)
        *CSR_TIMER3_CLR = 0;
        *CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
 
-       setup_sched_clock(footbridge_read_sched_clock, 24, rate);
+       sched_clock_register(footbridge_read_sched_clock, 24, rate);
 }
index 7c2fdae9a38b63454523277a005dcf6c5c1c65ab..96a3d73ef4bf43eeab172bd5c3df4457b7023931 100644 (file)
@@ -334,15 +334,15 @@ void __init dc21285_preinit(void)
        /*
         * We don't care if these fail.
         */
-       dc21285_request_irq(IRQ_PCI_SERR, dc21285_serr_irq, IRQF_DISABLED,
+       dc21285_request_irq(IRQ_PCI_SERR, dc21285_serr_irq, 0,
                            "PCI system error", &serr_timer);
-       dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, IRQF_DISABLED,
+       dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, 0,
                            "PCI parity error", &perr_timer);
-       dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, IRQF_DISABLED,
+       dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, 0,
                            "PCI abort", NULL);
-       dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, IRQF_DISABLED,
+       dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, 0,
                            "Discard timer", NULL);
-       dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, IRQF_DISABLED,
+       dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, 0,
                            "PCI data parity", NULL);
 
        if (cfn_mode) {
diff --git a/arch/arm/mach-footbridge/include/mach/timex.h b/arch/arm/mach-footbridge/include/mach/timex.h
deleted file mode 100644 (file)
index d0fea9d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *  arch/arm/mach-footbridge/include/mach/timex.h
- *
- *  Copyright (C) 1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  EBSA285 architecture timex specifications
- */
-
-/*
- * We assume a constant here; this satisfies the maths in linux/timex.h
- * and linux/time.h.  CLOCK_TICK_RATE is actually system dependent, but
- * this must be a constant.
- */
-#define CLOCK_TICK_RATE                (50000000/16)
index d9301dd563547b4a838275ff57e349b14b224e13..b73f52e196b90e91b75ac6ae8ab628f72381a070 100644 (file)
@@ -27,7 +27,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
 static struct irqaction pit_timer_irq = {
        .name           = "pit",
        .handler        = pit_timer_interrupt,
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .dev_id         = &i8253_clockevent,
 };
 
index 87dff4f5059edc740c501118682ca8f95fb67e7f..ddf8ec9d203bd8fe6bc660db66ba5a1009a6b249 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #include <linux/init.h>
-#include <asm/system.h>
+#include <asm/system_misc.h>
 #include <asm/proc-fns.h>
 
 static void gemini_idle(void)
diff --git a/arch/arm/mach-gemini/include/mach/timex.h b/arch/arm/mach-gemini/include/mach/timex.h
deleted file mode 100644 (file)
index dc5690b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Gemini timex specifications
- *
- * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- *
- * 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.
- */
-
-/* When AHB bus frequency is 150MHz */
-#define CLOCK_TICK_RATE        38000000
index 0aded64a9ebcd68a4213620ace8b5b2f81b53121..830b76e70250bdae8b35db60d21f12662bbf5dbd 100644 (file)
@@ -5,7 +5,6 @@ config ARCH_HIGHBANK
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_HAS_OPP
        select ARCH_SUPPORTS_BIG_ENDIAN
-       select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_AMBA
        select ARM_ERRATA_764369 if SMP
        select ARM_ERRATA_775420
@@ -14,14 +13,8 @@ config ARCH_HIGHBANK
        select ARM_PSCI
        select ARM_TIMER_SP804
        select CACHE_L2X0
-       select COMMON_CLK
-       select CPU_V7
-       select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
        select MAILBOX
        select PL320_MBOX
-       select SPARSE_IRQ
-       select USE_OF
        select ZONE_DMA if ARM_LPAE
index 1abae5f6a4181013a83e286d8ec9b1518179ce39..feee4dbb0760bfb4c4fa604ac1392bad4ae88a72 100644 (file)
@@ -3,13 +3,9 @@ config ARCH_HI3xxx
        select ARM_AMBA
        select ARM_GIC
        select ARM_TIMER_SP804
-       select ARCH_WANT_OPTIONAL_GPIOLIB
        select CACHE_L2X0
-       select CLKSRC_OF
-       select GENERIC_CLOCKEVENTS
-       select HAVE_ARM_SCU
+       select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
        select PINCTRL
        select PINCTRL_SINGLE
        help
index 6870058d0a48c2b09f03b7199b6989ff472229d2..2ae1b59267c23373af3c5dacd0876eec3c7d8f99 100644 (file)
@@ -3,5 +3,4 @@
 #
 
 obj-y  += hisilicon.o
-obj-$(CONFIG_SMP)              += platsmp.o
-obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
+obj-$(CONFIG_SMP)              += platsmp.o hotplug.o
index b909854eee7f7dff96479d520123a99cbc389c5a..abd441b0c60425a9b196a10bbcb181d4ebbaa09e 100644 (file)
@@ -178,6 +178,7 @@ static inline void cpu_enter_lowpower(void)
          : "cc");
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 void hi3xxx_cpu_die(unsigned int cpu)
 {
        cpu_enter_lowpower();
@@ -198,3 +199,4 @@ int hi3xxx_cpu_kill(unsigned int cpu)
        hi3xxx_set_cpu(cpu, false);
        return 1;
 }
+#endif
index 33567aa5880f423f936aefd5e59dda722c9c3371..5740296dc4299090c2875b3e22dd81419d069a50 100644 (file)
@@ -1,19 +1,15 @@
 config ARCH_MXC
        bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
+       select ARCH_HAS_CPUFREQ
+       select ARCH_HAS_OPP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
-       select ARM_PATCH_PHYS_VIRT
        select CLKSRC_MMIO
-       select COMMON_CLK
-       select GENERIC_ALLOCATOR
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7
-       select MULTI_IRQ_HANDLER
        select PINCTRL
+       select PM_OPP if PM
        select SOC_BUS
-       select SPARSE_IRQ
-       select USE_OF
+       select SRAM
        help
          Support for Freescale MXC/iMX-based family of processors
 
@@ -121,18 +117,16 @@ config SOC_IMX31
 config SOC_IMX35
        bool
        select ARCH_MXC_IOMUX_V3
-       select CPU_V6K
        select HAVE_EPIT
        select MXC_AVIC
+       select PINCTRL_IMX35
        select SMP_ON_UP if SMP
-       select PINCTRL
 
 config SOC_IMX5
        bool
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARCH_MXC_IOMUX_V3
-       select CPU_V7
        select MXC_TZIC
 
 config SOC_IMX51
@@ -777,65 +771,50 @@ config    SOC_IMX50
 config SOC_IMX53
        bool "i.MX53 support"
        select HAVE_IMX_SRC
-       select IMX_HAVE_PLATFORM_IMX2_WDT
        select PINCTRL_IMX53
        select SOC_IMX5
 
        help
          This enables support for Freescale i.MX53 processor.
 
-config SOC_IMX6Q
-       bool "i.MX6 Quad/DualLite support"
-       select ARCH_HAS_CPUFREQ
-       select ARCH_HAS_OPP
+config SOC_IMX6
+       bool
        select ARM_ERRATA_754322
-       select ARM_ERRATA_764369 if SMP
        select ARM_ERRATA_775420
        select ARM_GIC
-       select CPU_V7
-       select HAVE_ARM_SCU if SMP
-       select HAVE_ARM_TWD if SMP
        select HAVE_IMX_ANATOP
        select HAVE_IMX_GPC
        select HAVE_IMX_MMDC
        select HAVE_IMX_SRC
-       select HAVE_SMP
        select MFD_SYSCON
-       select MIGHT_HAVE_PCI
-       select PCI_DOMAINS if PCI
-       select PINCTRL_IMX6Q
        select PL310_ERRATA_588369 if CACHE_PL310
        select PL310_ERRATA_727915 if CACHE_PL310
        select PL310_ERRATA_769419 if CACHE_PL310
-       select PM_OPP if PM
+
+config SOC_IMX6Q
+       bool "i.MX6 Quad/DualLite support"
+       select ARM_ERRATA_764369 if SMP
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       select MIGHT_HAVE_PCI
+       select PCI_DOMAINS if PCI
+       select PINCTRL_IMX6Q
+       select SOC_IMX6
 
        help
          This enables support for Freescale i.MX6 Quad processor.
 
 config SOC_IMX6SL
        bool "i.MX6 SoloLite support"
-       select ARM_ERRATA_754322
-       select ARM_ERRATA_775420
-       select ARM_GIC
-       select CPU_V7
-       select HAVE_IMX_ANATOP
-       select HAVE_IMX_GPC
-       select HAVE_IMX_MMDC
-       select HAVE_IMX_SRC
-       select MFD_SYSCON
        select PINCTRL_IMX6SL
-       select PL310_ERRATA_588369 if CACHE_PL310
-       select PL310_ERRATA_727915 if CACHE_PL310
-       select PL310_ERRATA_769419 if CACHE_PL310
+       select SOC_IMX6
 
        help
          This enables support for Freescale i.MX6 SoloLite processor.
 
 config SOC_VF610
        bool "Vybrid Family VF610 support"
-       select CPU_V7
        select ARM_GIC
-       select CLKSRC_OF
        select PINCTRL_VF610
        select VF_PIT_TIMER
        select PL310_ERRATA_588369 if CACHE_PL310
index ec419649320ffe8fd6cae929d4664ae8071c9fff..f4ed83032dd0fce3f9e4faada7216a0c95d2226b 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
 ifeq ($(CONFIG_CPU_IDLE),y)
 obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
 obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
+obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
 endif
 
 ifdef CONFIG_SND_IMX_SOC
@@ -101,9 +102,11 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
 
-obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
-# i.MX6SL reuses i.MX6Q code
-obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
+ifeq ($(CONFIG_SUSPEND),y)
+AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
+endif
+obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
 
 # i.MX5 based machines
 obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o
index d7ed66091a2ab60f0ef372ebf7ee57af8a4e4e6e..bdc2e4630a082b4a8c376884616ea1b1dafedf94 100644 (file)
@@ -149,7 +149,6 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
        clk_register_clkdev(clk[per1], "per", "imx-gpt.1");
        clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
        clk_register_clkdev(clk[per1], "per", "imx-gpt.2");
-       clk_register_clkdev(clk[pwm_ipg_gate], "pwm", "mxc_pwm.0");
        clk_register_clkdev(clk[per2], "per", "imx21-cspi.0");
        clk_register_clkdev(clk[cspi1_ipg_gate], "ipg", "imx21-cspi.0");
        clk_register_clkdev(clk[per2], "per", "imx21-cspi.1");
index 69858c78f40d07ff5a4ef7a2ae724b09813a19f5..dc36e6c2f1da5b83e57e41612a7caca3afce8879 100644 (file)
@@ -265,14 +265,6 @@ int __init mx25_clocks_init(void)
        clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
        clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1");
        clk_register_clkdev(clk[cspi3_ipg], NULL, "imx35-cspi.2");
-       clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.0");
-       clk_register_clkdev(clk[per10], "per", "mxc_pwm.0");
-       clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.1");
-       clk_register_clkdev(clk[per10], "per", "mxc_pwm.1");
-       clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.2");
-       clk_register_clkdev(clk[per10], "per", "mxc_pwm.2");
-       clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.3");
-       clk_register_clkdev(clk[per10], "per", "mxc_pwm.3");
        clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad");
        clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc");
        clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx21-i2c.0");
index c6b40f3867863c7de1a52e5a1ab72acdc23f758f..d2da8908b26859370f797b746515f501bee89ad1 100644 (file)
@@ -231,7 +231,6 @@ int __init mx27_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.4");
        clk_register_clkdev(clk[gpt6_ipg_gate], "ipg", "imx-gpt.5");
        clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.5");
-       clk_register_clkdev(clk[pwm_ipg_gate], NULL, "mxc_pwm.0");
        clk_register_clkdev(clk[per2_gate], "per", "imx21-mmc.0");
        clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "imx21-mmc.0");
        clk_register_clkdev(clk[per2_gate], "per", "imx21-mmc.1");
index 19fca1fdc6feb76f0e86805ec7d5c980b716c515..568ef0a4de84b8892c0ee5b84fd339a5fecbf67a 100644 (file)
@@ -266,8 +266,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
        clk_register_clkdev(clk[IMX5_CLK_ECSPI2_PER_GATE], "per", "imx51-ecspi.1");
        clk_register_clkdev(clk[IMX5_CLK_ECSPI2_IPG_GATE], "ipg", "imx51-ecspi.1");
        clk_register_clkdev(clk[IMX5_CLK_CSPI_IPG_GATE], NULL, "imx35-cspi.2");
-       clk_register_clkdev(clk[IMX5_CLK_PWM1_IPG_GATE], "pwm", "mxc_pwm.0");
-       clk_register_clkdev(clk[IMX5_CLK_PWM2_IPG_GATE], "pwm", "mxc_pwm.1");
        clk_register_clkdev(clk[IMX5_CLK_I2C1_GATE], NULL, "imx21-i2c.0");
        clk_register_clkdev(clk[IMX5_CLK_I2C2_GATE], NULL, "imx21-i2c.1");
        clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.0");
index 4d677f4425399c03c07827c7fca39719ca00620c..b0e7f9d2c245ff093f1f08e11672e740f5170db0 100644 (file)
@@ -437,12 +437,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 
        clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
        clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
-       clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
-       clk_register_clkdev(clk[ahb], "ahb", NULL);
-       clk_register_clkdev(clk[cko1], "cko1", NULL);
-       clk_register_clkdev(clk[arm], NULL, "cpu0");
-       clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
-       clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
+       clk_register_clkdev(clk[enet_ref], "enet_ref", NULL);
 
        if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
            cpu_is_imx6dl()) {
index 4c86f303520573d544528c983cade541135e71a2..f7073c0782fb0f1ce45b384357241f97948fedc3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Freescale Semiconductor, Inc.
+ * Copyright 2013-2014 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #include "clk.h"
 #include "common.h"
 
-static const char const *step_sels[]           = { "osc", "pll2_pfd2", };
-static const char const *pll1_sw_sels[]                = { "pll1_sys", "step", };
-static const char const *ocram_alt_sels[]      = { "pll2_pfd2", "pll3_pfd1", };
-static const char const *ocram_sels[]          = { "periph", "ocram_alt_sels", };
-static const char const *pre_periph_sels[]     = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
-static const char const *periph_clk2_sels[]    = { "pll3_usb_otg", "osc", "osc", "dummy", };
-static const char const *periph2_clk2_sels[]   = { "pll3_usb_otg", "pll2_bus", };
-static const char const *periph_sels[]         = { "pre_periph_sel", "periph_clk2_podf", };
-static const char const *periph2_sels[]                = { "pre_periph2_sel", "periph2_clk2_podf", };
-static const char const *csi_lcdif_sels[]      = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
-static const char const *usdhc_sels[]          = { "pll2_pfd2", "pll2_pfd0", };
-static const char const *ssi_sels[]            = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
-static const char const *perclk_sels[]         = { "ipg", "osc", };
-static const char const *epdc_pxp_sels[]       = { "mmdc", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd1", };
-static const char const *gpu2d_ovg_sels[]      = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
-static const char const *gpu2d_sels[]          = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
-static const char const *lcdif_pix_sels[]      = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
-static const char const *epdc_pix_sels[]       = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
-static const char const *audio_sels[]          = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
-static const char const *ecspi_sels[]          = { "pll3_60m", "osc", };
-static const char const *uart_sels[]           = { "pll3_80m", "osc", };
+#define CCSR                   0xc
+#define BM_CCSR_PLL1_SW_CLK_SEL        (1 << 2)
+#define CACRR                  0x10
+#define CDHIPR                 0x48
+#define BM_CDHIPR_ARM_PODF_BUSY        (1 << 16)
+#define ARM_WAIT_DIV_396M      2
+#define ARM_WAIT_DIV_792M      4
+#define ARM_WAIT_DIV_996M      6
+
+#define PLL_ARM                        0x0
+#define BM_PLL_ARM_DIV_SELECT  (0x7f << 0)
+#define BM_PLL_ARM_POWERDOWN   (1 << 12)
+#define BM_PLL_ARM_ENABLE      (1 << 13)
+#define BM_PLL_ARM_LOCK                (1 << 31)
+#define PLL_ARM_DIV_792M       66
+
+static const char *step_sels[]         = { "osc", "pll2_pfd2", };
+static const char *pll1_sw_sels[]      = { "pll1_sys", "step", };
+static const char *ocram_alt_sels[]    = { "pll2_pfd2", "pll3_pfd1", };
+static const char *ocram_sels[]                = { "periph", "ocram_alt_sels", };
+static const char *pre_periph_sels[]   = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
+static const char *periph_clk2_sels[]  = { "pll3_usb_otg", "osc", "osc", "dummy", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
+static const char *periph_sels[]       = { "pre_periph_sel", "periph_clk2_podf", };
+static const char *periph2_sels[]      = { "pre_periph2_sel", "periph2_clk2_podf", };
+static const char *csi_lcdif_sels[]    = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
+static const char *usdhc_sels[]                = { "pll2_pfd2", "pll2_pfd0", };
+static const char *ssi_sels[]          = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
+static const char *perclk_sels[]       = { "ipg", "osc", };
+static const char *epdc_pxp_sels[]     = { "mmdc", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd1", };
+static const char *gpu2d_ovg_sels[]    = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
+static const char *gpu2d_sels[]                = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
+static const char *lcdif_pix_sels[]    = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
+static const char *epdc_pix_sels[]     = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
+static const char *audio_sels[]                = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
+static const char *ecspi_sels[]                = { "pll3_60m", "osc", };
+static const char *uart_sels[]         = { "pll3_80m", "osc", };
 
 static struct clk_div_table clk_enet_ref_table[] = {
        { .val = 0, .div = 20, },
@@ -65,6 +81,89 @@ static struct clk_div_table video_div_table[] = {
 
 static struct clk *clks[IMX6SL_CLK_END];
 static struct clk_onecell_data clk_data;
+static void __iomem *ccm_base;
+static void __iomem *anatop_base;
+
+static const u32 clks_init_on[] __initconst = {
+       IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT,
+};
+
+/*
+ * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken
+ *           during WAIT mode entry process could cause cache memory
+ *           corruption.
+ *
+ * Software workaround:
+ *     To prevent this issue from occurring, software should ensure that the
+ * ARM to IPG clock ratio is less than 12:5 (that is < 2.4x), before
+ * entering WAIT mode.
+ *
+ * This function will set the ARM clk to max value within the 12:5 limit.
+ * As IPG clock is fixed at 66MHz(so ARM freq must not exceed 158.4MHz),
+ * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since
+ * the clk APIs can NOT be called in idle thread(may cause kernel schedule
+ * as there is sleep function in PLL wait function), so here we just slow
+ * down ARM to below freq according to previous freq:
+ *
+ * run mode      wait mode
+ * 396MHz   ->   132MHz;
+ * 792MHz   ->   158.4MHz;
+ * 996MHz   ->   142.3MHz;
+ */
+static int imx6sl_get_arm_divider_for_wait(void)
+{
+       if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) {
+               return ARM_WAIT_DIV_396M;
+       } else {
+               if ((readl_relaxed(anatop_base + PLL_ARM) &
+                       BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M)
+                       return ARM_WAIT_DIV_792M;
+               else
+                       return ARM_WAIT_DIV_996M;
+       }
+}
+
+static void imx6sl_enable_pll_arm(bool enable)
+{
+       static u32 saved_pll_arm;
+       u32 val;
+
+       if (enable) {
+               saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
+               val |= BM_PLL_ARM_ENABLE;
+               val &= ~BM_PLL_ARM_POWERDOWN;
+               writel_relaxed(val, anatop_base + PLL_ARM);
+               while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
+                       ;
+       } else {
+                writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
+       }
+}
+
+void imx6sl_set_wait_clk(bool enter)
+{
+       static unsigned long saved_arm_div;
+       int arm_div_for_wait = imx6sl_get_arm_divider_for_wait();
+
+       /*
+        * According to hardware design, arm podf change need
+        * PLL1 clock enabled.
+        */
+       if (arm_div_for_wait == ARM_WAIT_DIV_396M)
+               imx6sl_enable_pll_arm(true);
+
+       if (enter) {
+               saved_arm_div = readl_relaxed(ccm_base + CACRR);
+               writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
+       } else {
+               writel_relaxed(saved_arm_div, ccm_base + CACRR);
+       }
+       while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
+               ;
+
+       if (arm_div_for_wait == ARM_WAIT_DIV_396M)
+               imx6sl_enable_pll_arm(false);
+}
 
 static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 {
@@ -72,6 +171,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        void __iomem *base;
        int irq;
        int i;
+       int ret;
 
        clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
        clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
@@ -80,6 +180,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
        base = of_iomap(np, 0);
        WARN_ON(!base);
+       anatop_base = base;
 
        /*                                             type               name            parent  base         div_mask */
        clks[IMX6SL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,     "pll1_sys",      "osc", base,        0x7f);
@@ -127,6 +228,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        np = ccm_node;
        base = of_iomap(np, 0);
        WARN_ON(!base);
+       ccm_base = base;
 
        /* Reuse imx6q pm code */
        imx6q_pm_set_ccm_base(base);
@@ -258,6 +360,19 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0");
        clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0");
 
+       /* Ensure the AHB clk is at 132MHz. */
+       ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
+       if (ret)
+               pr_warn("%s: failed to set AHB clock rate %d!\n",
+                       __func__, ret);
+
+       /*
+        * Make sure those always on clocks are enabled to maintain the correct
+        * usecount and enabling/disabling of parent PLLs.
+        */
+       for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+               clk_prepare_enable(clks[clks_init_on[i]]);
+
        if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
                clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
                clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
index ecd66d8e20b62b84419f0c0bcc4a54d0c5ef8a02..22dc3ee21fd494fe671a3048fc4925c4d9d95c80 100644 (file)
@@ -63,25 +63,25 @@ static void __iomem *anatop_base;
 static void __iomem *ccm_base;
 
 /* sources for multiplexer clocks, this is used multiple times */
-static const char const *fast_sels[]   = { "firc", "fxosc", };
-static const char const *slow_sels[]   = { "sirc_32k", "sxosc", };
-static const char const *pll1_sels[]   = { "pll1_main", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
-static const char const *pll2_sels[]   = { "pll2_main", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
-static const char const *sys_sels[]    = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_main", "pll1_pfd_sel", "pll3_main", };
-static const char const *ddr_sels[]    = { "pll2_pfd2", "sys_sel", };
-static const char const *rmii_sels[]   = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
-static const char const *enet_ts_sels[]        = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
-static const char const *esai_sels[]   = { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
-static const char const *sai_sels[]    = { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
-static const char const *nfc_sels[]    = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
-static const char const *qspi_sels[]   = { "pll3_main", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
-static const char const *esdhc_sels[]  = { "pll3_main", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
-static const char const *dcu_sels[]    = { "pll1_pfd2", "pll3_main", };
-static const char const *gpu_sels[]    = { "pll2_pfd2", "pll3_pfd2", };
-static const char const *vadc_sels[]   = { "pll6_main_div", "pll3_main_div", "pll3_main", };
+static const char *fast_sels[] = { "firc", "fxosc", };
+static const char *slow_sels[] = { "sirc_32k", "sxosc", };
+static const char *pll1_sels[] = { "pll1_main", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
+static const char *pll2_sels[] = { "pll2_main", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
+static const char *sys_sels[]  = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_main", "pll1_pfd_sel", "pll3_main", };
+static const char *ddr_sels[]  = { "pll2_pfd2", "sys_sel", };
+static const char *rmii_sels[] = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
+static const char *enet_ts_sels[]      = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
+static const char *esai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
+static const char *sai_sels[]  = { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
+static const char *nfc_sels[]  = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
+static const char *qspi_sels[] = { "pll3_main", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
+static const char *esdhc_sels[]        = { "pll3_main", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
+static const char *dcu_sels[]  = { "pll1_pfd2", "pll3_main", };
+static const char *gpu_sels[]  = { "pll2_pfd2", "pll3_pfd2", };
+static const char *vadc_sels[] = { "pll6_main_div", "pll3_main_div", "pll3_main", };
 /* FTM counter clock source, not module clock */
-static const char const *ftm_ext_sels[]        = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
-static const char const *ftm_fix_sels[]        = { "sxosc", "ipg_bus", };
+static const char *ftm_ext_sels[]      = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
+static const char *ftm_fix_sels[]      = { "sxosc", "ipg_bus", };
 
 static struct clk_div_table pll4_main_div_table[] = {
        { .val = 0, .div = 1 },
index baf439dc22d8268d65bd269f508c968aae822046..b5241ea7670642fd2902f1896ad8c666daea3f4f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -116,7 +116,6 @@ void imx_enable_cpu(int cpu, bool enable);
 void imx_set_cpu_jump(int cpu, void *jump_addr);
 u32 imx_get_cpu_arg(int cpu);
 void imx_set_cpu_arg(int cpu, u32 arg);
-void v7_cpu_resume(void);
 #ifdef CONFIG_SMP
 void v7_secondary_startup(void);
 void imx_scu_map_io(void);
@@ -139,13 +138,25 @@ void imx_anatop_init(void);
 void imx_anatop_pre_suspend(void);
 void imx_anatop_post_resume(void);
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
-void imx6q_set_chicken_bit(void);
+void imx6q_set_int_mem_clk_lpm(void);
+void imx6sl_set_wait_clk(bool enter);
 
 void imx_cpu_die(unsigned int cpu);
 int imx_cpu_kill(unsigned int cpu);
 
+#ifdef CONFIG_SUSPEND
+void v7_cpu_resume(void);
+void imx6_suspend(void __iomem *ocram_vbase);
+#else
+static inline void v7_cpu_resume(void) {}
+static inline void imx6_suspend(void __iomem *ocram_vbase) {}
+#endif
+
 void imx6q_pm_init(void);
+void imx6dl_pm_init(void);
+void imx6sl_pm_init(void);
 void imx6q_pm_set_ccm_base(void __iomem *base);
+
 #ifdef CONFIG_PM
 void imx5_pm_init(void);
 #else
index 23ddfb693b2d01f606612dbe8b7eaf146aad8da1..6bcae047904905696c3cb0fbe238f74b1e54100f 100644 (file)
@@ -68,8 +68,8 @@ int __init imx6q_cpuidle_init(void)
        /* Need to enable SCU standby for entering WAIT modes */
        imx_scu_standby_enable();
 
-       /* Set chicken bit to get a reliable WAIT mode support */
-       imx6q_set_chicken_bit();
+       /* Set INT_MEM_CLK_LPM bit to get a reliable WAIT mode support */
+       imx6q_set_int_mem_clk_lpm();
 
        return cpuidle_register(&imx6q_cpuidle_driver, NULL);
 }
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
new file mode 100644 (file)
index 0000000..d4b6b81
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <asm/cpuidle.h>
+#include <asm/proc-fns.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int imx6sl_enter_wait(struct cpuidle_device *dev,
+                           struct cpuidle_driver *drv, int index)
+{
+       imx6q_set_lpm(WAIT_UNCLOCKED);
+       /*
+        * Software workaround for ERR005311, see function
+        * description for details.
+        */
+       imx6sl_set_wait_clk(true);
+       cpu_do_idle();
+       imx6sl_set_wait_clk(false);
+       imx6q_set_lpm(WAIT_CLOCKED);
+
+       return index;
+}
+
+static struct cpuidle_driver imx6sl_cpuidle_driver = {
+       .name = "imx6sl_cpuidle",
+       .owner = THIS_MODULE,
+       .states = {
+               /* WFI */
+               ARM_CPUIDLE_WFI_STATE,
+               /* WAIT */
+               {
+                       .exit_latency = 50,
+                       .target_residency = 75,
+                       .flags = CPUIDLE_FLAG_TIME_VALID |
+                               CPUIDLE_FLAG_TIMER_STOP,
+                       .enter = imx6sl_enter_wait,
+                       .name = "WAIT",
+                       .desc = "Clock off",
+               },
+       },
+       .state_count = 2,
+       .safe_state_index = 0,
+};
+
+int __init imx6sl_cpuidle_init(void)
+{
+       return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
+}
index 786f98ecc14578630bdb9351b388135fb51aebad..24e33670417c1dd48f21aa2acf4f8bdfbc16c95a 100644 (file)
@@ -13,6 +13,7 @@
 #ifdef CONFIG_CPU_IDLE
 extern int imx5_cpuidle_init(void);
 extern int imx6q_cpuidle_init(void);
+extern int imx6sl_cpuidle_init(void);
 #else
 static inline int imx5_cpuidle_init(void)
 {
@@ -22,4 +23,8 @@ static inline int imx6q_cpuidle_init(void)
 {
        return 0;
 }
+static inline int imx6sl_cpuidle_init(void)
+{
+       return 0;
+}
 #endif
index 769563fdeaa00a7a096bcbc2ad96bcb219ea6337..61a114cddc3966110cdecd368c76f4be4f48a3e2 100644 (file)
@@ -83,7 +83,3 @@ extern const struct imx_spi_imx_data imx25_cspi_data[];
 #define imx25_add_spi_imx0(pdata)      imx25_add_spi_imx(0, pdata)
 #define imx25_add_spi_imx1(pdata)      imx25_add_spi_imx(1, pdata)
 #define imx25_add_spi_imx2(pdata)      imx25_add_spi_imx(2, pdata)
-
-extern struct imx_mxc_pwm_data imx25_mxc_pwm_data[];
-#define imx25_add_mxc_pwm(id)  \
-       imx_add_mxc_pwm(&imx25_mxc_pwm_data[id])
index deee5baee88cf636627acb1c923b029e9d58b032..26389f35a2b28f162ecba27d7e5d7a66d9b6687d 100644 (file)
@@ -57,10 +57,6 @@ extern const struct imx_imx2_wdt_data imx51_imx2_wdt_data[];
 #define imx51_add_imx2_wdt(id) \
        imx_add_imx2_wdt(&imx51_imx2_wdt_data[id])
 
-extern const struct imx_mxc_pwm_data imx51_mxc_pwm_data[];
-#define imx51_add_mxc_pwm(id)  \
-       imx_add_mxc_pwm(&imx51_mxc_pwm_data[id])
-
 extern const struct imx_imx_keypad_data imx51_imx_keypad_data;
 #define imx51_add_imx_keypad(pdata)    \
        imx_add_imx_keypad(&imx51_imx_keypad_data, pdata)
index 68c74fb0373c63a1f47b97630cf90f70b2e59ee1..2d260a5a307c752a264d8a9a4be75d98cb31b2ea 100644 (file)
@@ -67,9 +67,6 @@ config IMX_HAVE_PLATFORM_MXC_MMC
 config IMX_HAVE_PLATFORM_MXC_NAND
        bool
 
-config IMX_HAVE_PLATFORM_MXC_PWM
-       bool
-
 config IMX_HAVE_PLATFORM_MXC_RNGA
        bool
        select ARCH_HAS_RNGA
index 67416fb1dc69251719e028fa6c6a00b0a9d40df1..1cbc14cd80d1614e32c571ed87adda726cf14c18 100644 (file)
@@ -23,7 +23,6 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_CAMERA) += platform-mx2-camera.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI) += platform-mxc-ehci.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_MMC) += platform-mxc-mmc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
-obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_PWM) += platform-mxc_pwm.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RNGA) += platform-mxc_rnga.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
index c13b76b9f6b38b995422279d05f4f4eaa5eb31ec..61352a80bb59325e062915fbaef737322a8f1aed 100644 (file)
@@ -290,15 +290,6 @@ struct imx_pata_imx_data {
 struct platform_device *__init imx_add_pata_imx(
                const struct imx_pata_imx_data *data);
 
-struct imx_mxc_pwm_data {
-       int id;
-       resource_size_t iobase;
-       resource_size_t iosize;
-       resource_size_t irq;
-};
-struct platform_device *__init imx_add_mxc_pwm(
-               const struct imx_mxc_pwm_data *data);
-
 /* mxc_rtc */
 struct imx_mxc_rtc_data {
        const char *devid;
diff --git a/arch/arm/mach-imx/devices/platform-mxc_pwm.c b/arch/arm/mach-imx/devices/platform-mxc_pwm.c
deleted file mode 100644 (file)
index dcd2897..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Pengutronix
- * Uwe Kleine-Koenig <u.kleine-koenig@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 "../hardware.h"
-#include "devices-common.h"
-
-#define imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size)          \
-       {                                                               \
-               .id = _id,                                              \
-               .iobase = soc ## _PWM ## _hwid ## _BASE_ADDR,           \
-               .iosize = _size,                                        \
-               .irq = soc ## _INT_PWM ## _hwid,                        \
-       }
-#define imx_mxc_pwm_data_entry(soc, _id, _hwid, _size)                 \
-       [_id] = imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size)
-
-#ifdef CONFIG_SOC_IMX21
-const struct imx_mxc_pwm_data imx21_mxc_pwm_data __initconst =
-       imx_mxc_pwm_data_entry_single(MX21, 0, , SZ_4K);
-#endif /* ifdef CONFIG_SOC_IMX21 */
-
-#ifdef CONFIG_SOC_IMX25
-const struct imx_mxc_pwm_data imx25_mxc_pwm_data[] __initconst = {
-#define imx25_mxc_pwm_data_entry(_id, _hwid)                           \
-       imx_mxc_pwm_data_entry(MX25, _id, _hwid, SZ_16K)
-       imx25_mxc_pwm_data_entry(0, 1),
-       imx25_mxc_pwm_data_entry(1, 2),
-       imx25_mxc_pwm_data_entry(2, 3),
-       imx25_mxc_pwm_data_entry(3, 4),
-};
-#endif /* ifdef CONFIG_SOC_IMX25 */
-
-#ifdef CONFIG_SOC_IMX27
-const struct imx_mxc_pwm_data imx27_mxc_pwm_data __initconst =
-       imx_mxc_pwm_data_entry_single(MX27, 0, , SZ_4K);
-#endif /* ifdef CONFIG_SOC_IMX27 */
-
-#ifdef CONFIG_SOC_IMX51
-const struct imx_mxc_pwm_data imx51_mxc_pwm_data[] __initconst = {
-#define imx51_mxc_pwm_data_entry(_id, _hwid)                           \
-       imx_mxc_pwm_data_entry(MX51, _id, _hwid, SZ_16K)
-       imx51_mxc_pwm_data_entry(0, 1),
-       imx51_mxc_pwm_data_entry(1, 2),
-};
-#endif /* ifdef CONFIG_SOC_IMX51 */
-
-struct platform_device *__init imx_add_mxc_pwm(
-               const struct imx_mxc_pwm_data *data)
-{
-       struct resource res[] = {
-               {
-                       .start = data->iobase,
-                       .end = data->iobase + data->iosize - 1,
-                       .flags = IORESOURCE_MEM,
-               }, {
-                       .start = data->irq,
-                       .end = data->irq,
-                       .flags = IORESOURCE_IRQ,
-               },
-       };
-
-       return imx_add_platform_device("mxc_pwm", data->id,
-                       res, ARRAY_SIZE(res), NULL, 0);
-}
index a3b0b04b45c90f9bc4808ece62482521f85fcf24..abf43bb47eca16d05253cb757fc823e1cdfc5645 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2007, 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  *
  * This program is free software; you can redistribute it and/or
@@ -20,7 +20,9 @@
 #ifndef __ASM_ARCH_MXC_HARDWARE_H__
 #define __ASM_ARCH_MXC_HARDWARE_H__
 
+#ifndef __ASSEMBLY__
 #include <asm/io.h>
+#endif
 #include <asm/sizes.h>
 
 #define addr_in_module(addr, mod) \
index 627f16f0e9d1d393d48527e50f25c5e22c81987d..de5047c8a6c87ab2fc957ed09e51897780e287fc 100644 (file)
 
 #include <linux/linkage.h>
 #include <linux/init.h>
-#include <asm/asm-offsets.h>
-#include <asm/hardware/cache-l2x0.h>
 
-       .section ".text.head", "ax"
-
-#ifdef CONFIG_SMP
 diag_reg_offset:
        .word   g_diag_reg - .
 
@@ -34,38 +29,3 @@ ENTRY(v7_secondary_startup)
        set_diag_reg
        b       secondary_startup
 ENDPROC(v7_secondary_startup)
-#endif
-
-#ifdef CONFIG_ARM_CPU_SUSPEND
-/*
- * The following code must assume it is running from physical address
- * where absolute virtual addresses to the data section have to be
- * turned into relative ones.
- */
-
-#ifdef CONFIG_CACHE_L2X0
-       .macro  pl310_resume
-       adr     r0, l2x0_saved_regs_offset
-       ldr     r2, [r0]
-       add     r2, r2, r0
-       ldr     r0, [r2, #L2X0_R_PHY_BASE]      @ get physical base of l2x0
-       ldr     r1, [r2, #L2X0_R_AUX_CTRL]      @ get aux_ctrl value
-       str     r1, [r0, #L2X0_AUX_CTRL]        @ restore aux_ctrl
-       mov     r1, #0x1
-       str     r1, [r0, #L2X0_CTRL]            @ re-enable L2
-       .endm
-
-l2x0_saved_regs_offset:
-       .word   l2x0_saved_regs - .
-
-#else
-       .macro  pl310_resume
-       .endm
-#endif
-
-ENTRY(v7_cpu_resume)
-       bl      v7_invalidate_l1
-       pl310_resume
-       b       cpu_resume
-ENDPROC(v7_cpu_resume)
-#endif
index 76e5db4fce35a96eb7b5f7abeaf6c60e70fddcf3..e60456d85c9d867218eca5e244034ef348592376 100644 (file)
@@ -182,16 +182,83 @@ static void __init imx6q_enet_phy_init(void)
 
 static void __init imx6q_1588_init(void)
 {
+       struct device_node *np;
+       struct clk *ptp_clk;
+       struct clk *enet_ref;
        struct regmap *gpr;
+       u32 clksel;
 
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-fec");
+       if (!np) {
+               pr_warn("%s: failed to find fec node\n", __func__);
+               return;
+       }
+
+       ptp_clk = of_clk_get(np, 2);
+       if (IS_ERR(ptp_clk)) {
+               pr_warn("%s: failed to get ptp clock\n", __func__);
+               goto put_node;
+       }
+
+       enet_ref = clk_get_sys(NULL, "enet_ref");
+       if (IS_ERR(enet_ref)) {
+               pr_warn("%s: failed to get enet clock\n", __func__);
+               goto put_ptp_clk;
+       }
+
+       /*
+        * If enet_ref from ANATOP/CCM is the PTP clock source, we need to
+        * set bit IOMUXC_GPR1[21].  Or the PTP clock must be from pad
+        * (external OSC), and we need to clear the bit.
+        */
+       clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
+                                      IMX6Q_GPR1_ENET_CLK_SEL_PAD;
        gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
        if (!IS_ERR(gpr))
                regmap_update_bits(gpr, IOMUXC_GPR1,
                                IMX6Q_GPR1_ENET_CLK_SEL_MASK,
-                               IMX6Q_GPR1_ENET_CLK_SEL_ANATOP);
+                               clksel);
        else
                pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
 
+       clk_put(enet_ref);
+put_ptp_clk:
+       clk_put(ptp_clk);
+put_node:
+       of_node_put(np);
+}
+
+static void __init imx6q_axi_init(void)
+{
+       struct regmap *gpr;
+       unsigned int mask;
+
+       gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+       if (!IS_ERR(gpr)) {
+               /*
+                * Enable the cacheable attribute of VPU and IPU
+                * AXI transactions.
+                */
+               mask = IMX6Q_GPR4_VPU_WR_CACHE_SEL |
+                       IMX6Q_GPR4_VPU_RD_CACHE_SEL |
+                       IMX6Q_GPR4_VPU_P_WR_CACHE_VAL |
+                       IMX6Q_GPR4_VPU_P_RD_CACHE_VAL_MASK |
+                       IMX6Q_GPR4_IPU_WR_CACHE_CTL |
+                       IMX6Q_GPR4_IPU_RD_CACHE_CTL;
+               regmap_update_bits(gpr, IOMUXC_GPR4, mask, mask);
+
+               /* Increase IPU read QoS priority */
+               regmap_update_bits(gpr, IOMUXC_GPR6,
+                               IMX6Q_GPR6_IPU1_ID00_RD_QOS_MASK |
+                               IMX6Q_GPR6_IPU1_ID01_RD_QOS_MASK,
+                               (0xf << 16) | (0x7 << 20));
+               regmap_update_bits(gpr, IOMUXC_GPR7,
+                               IMX6Q_GPR7_IPU2_ID00_RD_QOS_MASK |
+                               IMX6Q_GPR7_IPU2_ID01_RD_QOS_MASK,
+                               (0xf << 16) | (0x7 << 20));
+       } else {
+               pr_warn("failed to find fsl,imx6q-iomuxc-gpr regmap\n");
+       }
 }
 
 static void __init imx6q_init_machine(void)
@@ -212,15 +279,18 @@ static void __init imx6q_init_machine(void)
        of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
 
        imx_anatop_init();
-       imx6q_pm_init();
+       cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();
        imx6q_1588_init();
+       imx6q_axi_init();
 }
 
 #define OCOTP_CFG3                     0x440
 #define OCOTP_CFG3_SPEED_SHIFT         16
 #define OCOTP_CFG3_SPEED_1P2GHZ                0x3
+#define OCOTP_CFG3_SPEED_996MHZ                0x2
+#define OCOTP_CFG3_SPEED_852MHZ                0x1
 
-static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
+static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 {
        struct device_node *np;
        void __iomem *base;
@@ -238,11 +308,29 @@ static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
                goto put_node;
        }
 
+       /*
+        * SPEED_GRADING[1:0] defines the max speed of ARM:
+        * 2b'11: 1200000000Hz;
+        * 2b'10: 996000000Hz;
+        * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
+        * 2b'00: 792000000Hz;
+        * We need to set the max speed of ARM according to fuse map.
+        */
        val = readl_relaxed(base + OCOTP_CFG3);
        val >>= OCOTP_CFG3_SPEED_SHIFT;
-       if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
+       val &= 0x3;
+
+       if (val != OCOTP_CFG3_SPEED_1P2GHZ)
                if (dev_pm_opp_disable(cpu_dev, 1200000000))
                        pr_warn("failed to disable 1.2 GHz OPP\n");
+       if (val < OCOTP_CFG3_SPEED_996MHZ)
+               if (dev_pm_opp_disable(cpu_dev, 996000000))
+                       pr_warn("failed to disable 996 MHz OPP\n");
+       if (cpu_is_imx6q()) {
+               if (val != OCOTP_CFG3_SPEED_852MHZ)
+                       if (dev_pm_opp_disable(cpu_dev, 852000000))
+                               pr_warn("failed to disable 852 MHz OPP\n");
+       }
 
 put_node:
        of_node_put(np);
@@ -268,7 +356,7 @@ static void __init imx6q_opp_init(void)
                goto put_node;
        }
 
-       imx6q_opp_check_1p2ghz(cpu_dev);
+       imx6q_opp_check_speed_grading(cpu_dev);
 
 put_node:
        of_node_put(np);
index 0f4fd4c0ab8e7db0cca2e04e2cb65f6dd43092d6..ad323385115c0f2a607c55219a2f5ae8e599a814 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
+#include "cpuidle.h"
 
 static void __init imx6sl_fec_init(void)
 {
@@ -39,6 +40,8 @@ static void __init imx6sl_init_late(void)
        /* imx6sl reuses imx6q cpufreq driver */
        if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
                platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
+
+       imx6sl_cpuidle_init();
 }
 
 static void __init imx6sl_init_machine(void)
@@ -55,8 +58,7 @@ static void __init imx6sl_init_machine(void)
 
        imx6sl_fec_init();
        imx_anatop_init();
-       /* Reuse imx6q pm code */
-       imx6q_pm_init();
+       imx6sl_pm_init();
 }
 
 static void __init imx6sl_init_irq(void)
index 9821b824dcafc43d3380a5e4e5527f825b0ebdcd..a7a4a9c6761544b9e4770461dfbbf2e72090e652 100644 (file)
 #include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
+
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
@@ -195,14 +199,58 @@ static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = {
 static struct i2c_board_info mx27ads_i2c_devices[] = {
 };
 
-void lcd_power(int on)
+static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
-       if (on)
+       if (value)
                __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
        else
                __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
 }
 
+static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+       return 0;
+}
+
+#define MX27ADS_LCD_GPIO       (6 * 32)
+
+static struct regulator_consumer_supply mx27ads_lcd_regulator_consumer =
+       REGULATOR_SUPPLY("lcd", "imx-fb.0");
+
+static struct regulator_init_data mx27ads_lcd_regulator_init_data = {
+       .constraints    = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+},
+       .consumer_supplies      = &mx27ads_lcd_regulator_consumer,
+       .num_consumer_supplies  = 1,
+};
+
+static struct fixed_voltage_config mx27ads_lcd_regulator_pdata = {
+       .supply_name    = "LCD",
+       .microvolts     = 3300000,
+       .gpio           = MX27ADS_LCD_GPIO,
+       .init_data      = &mx27ads_lcd_regulator_init_data,
+};
+
+static void __init mx27ads_regulator_init(void)
+{
+       struct gpio_chip *vchip;
+
+       vchip = kzalloc(sizeof(*vchip), GFP_KERNEL);
+       vchip->owner            = THIS_MODULE;
+       vchip->label            = "LCD";
+       vchip->base             = MX27ADS_LCD_GPIO;
+       vchip->ngpio            = 1;
+       vchip->direction_output = vgpio_dir_out;
+       vchip->set              = vgpio_set;
+       gpiochip_add(vchip);
+
+       platform_device_register_data(&platform_bus, "reg-fixed-voltage",
+                                     PLATFORM_DEVID_AUTO,
+                                     &mx27ads_lcd_regulator_pdata,
+                                     sizeof(mx27ads_lcd_regulator_pdata));
+}
+
 static struct imx_fb_videomode mx27ads_modes[] = {
        {
                .mode = {
@@ -239,8 +287,6 @@ static const struct imx_fb_platform_data mx27ads_fb_data __initconst = {
        .pwmr           = 0x00A903FF,
        .lscr1          = 0x00120300,
        .dmacr          = 0x00020010,
-
-       .lcd_power      = lcd_power,
 };
 
 static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
@@ -304,6 +350,7 @@ static void __init mx27ads_board_init(void)
        i2c_register_board_info(1, mx27ads_i2c_devices,
                                ARRAY_SIZE(mx27ads_i2c_devices));
        imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
+       mx27ads_regulator_init();
        imx27_add_imx_fb(&mx27ads_fb_data);
        imx27_add_mxc_mmc(0, &sdhc1_pdata);
        imx27_add_mxc_mmc(1, &sdhc2_pdata);
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
new file mode 100644 (file)
index 0000000..9392a8f
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * Copyright 2011-2014 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include "common.h"
+#include "hardware.h"
+
+#define CCR                            0x0
+#define BM_CCR_WB_COUNT                        (0x7 << 16)
+#define BM_CCR_RBC_BYPASS_COUNT                (0x3f << 21)
+#define BM_CCR_RBC_EN                  (0x1 << 27)
+
+#define CLPCR                          0x54
+#define BP_CLPCR_LPM                   0
+#define BM_CLPCR_LPM                   (0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY     (0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM    (0x1 << 5)
+#define BM_CLPCR_SBYOS                 (0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC           (0x1 << 7)
+#define BM_CLPCR_VSTBY                 (0x1 << 8)
+#define BP_CLPCR_STBY_COUNT            9
+#define BM_CLPCR_STBY_COUNT            (0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN          (0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM         (0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM                (0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS   (0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS   (0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI                (0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI                (0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI                (0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI                (0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE         (0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE                (0x1 << 27)
+
+#define CGPR                           0x64
+#define BM_CGPR_INT_MEM_CLK_LPM                (0x1 << 17)
+
+#define MX6Q_SUSPEND_OCRAM_SIZE                0x1000
+#define MX6_MAX_MMDC_IO_NUM            33
+
+static void __iomem *ccm_base;
+static void __iomem *suspend_ocram_base;
+static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
+
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ *                              .
+ *                              .
+ *                              .
+ *                              ^
+ *                              ^
+ *                              ^
+ *                      imx6_suspend code
+ *              PM_INFO structure(imx6_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+struct imx6_pm_base {
+       phys_addr_t pbase;
+       void __iomem *vbase;
+};
+
+struct imx6_pm_socdata {
+       u32 cpu_type;
+       const char *mmdc_compat;
+       const char *src_compat;
+       const char *iomuxc_compat;
+       const char *gpc_compat;
+       const u32 mmdc_io_num;
+       const u32 *mmdc_io_offset;
+};
+
+static const u32 imx6q_mmdc_io_offset[] __initconst = {
+       0x5ac, 0x5b4, 0x528, 0x520, /* DQM0 ~ DQM3 */
+       0x514, 0x510, 0x5bc, 0x5c4, /* DQM4 ~ DQM7 */
+       0x56c, 0x578, 0x588, 0x594, /* CAS, RAS, SDCLK_0, SDCLK_1 */
+       0x5a8, 0x5b0, 0x524, 0x51c, /* SDQS0 ~ SDQS3 */
+       0x518, 0x50c, 0x5b8, 0x5c0, /* SDQS4 ~ SDQS7 */
+       0x784, 0x788, 0x794, 0x79c, /* GPR_B0DS ~ GPR_B3DS */
+       0x7a0, 0x7a4, 0x7a8, 0x748, /* GPR_B4DS ~ GPR_B7DS */
+       0x59c, 0x5a0, 0x750, 0x774, /* SODT0, SODT1, MODE_CTL, MODE */
+       0x74c,                      /* GPR_ADDS */
+};
+
+static const u32 imx6dl_mmdc_io_offset[] __initconst = {
+       0x470, 0x474, 0x478, 0x47c, /* DQM0 ~ DQM3 */
+       0x480, 0x484, 0x488, 0x48c, /* DQM4 ~ DQM7 */
+       0x464, 0x490, 0x4ac, 0x4b0, /* CAS, RAS, SDCLK_0, SDCLK_1 */
+       0x4bc, 0x4c0, 0x4c4, 0x4c8, /* DRAM_SDQS0 ~ DRAM_SDQS3 */
+       0x4cc, 0x4d0, 0x4d4, 0x4d8, /* DRAM_SDQS4 ~ DRAM_SDQS7 */
+       0x764, 0x770, 0x778, 0x77c, /* GPR_B0DS ~ GPR_B3DS */
+       0x780, 0x784, 0x78c, 0x748, /* GPR_B4DS ~ GPR_B7DS */
+       0x4b4, 0x4b8, 0x750, 0x760, /* SODT0, SODT1, MODE_CTL, MODE */
+       0x74c,                      /* GPR_ADDS */
+};
+
+static const u32 imx6sl_mmdc_io_offset[] __initconst = {
+       0x30c, 0x310, 0x314, 0x318, /* DQM0 ~ DQM3 */
+       0x5c4, 0x5cc, 0x5d4, 0x5d8, /* GPR_B0DS ~ GPR_B3DS */
+       0x300, 0x31c, 0x338, 0x5ac, /* CAS, RAS, SDCLK_0, GPR_ADDS */
+       0x33c, 0x340, 0x5b0, 0x5c0, /* SODT0, SODT1, MODE_CTL, MODE */
+       0x330, 0x334, 0x320,        /* SDCKE0, SDCKE1, RESET */
+};
+
+static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
+       .cpu_type = MXC_CPU_IMX6Q,
+       .mmdc_compat = "fsl,imx6q-mmdc",
+       .src_compat = "fsl,imx6q-src",
+       .iomuxc_compat = "fsl,imx6q-iomuxc",
+       .gpc_compat = "fsl,imx6q-gpc",
+       .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
+       .mmdc_io_offset = imx6q_mmdc_io_offset,
+};
+
+static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
+       .cpu_type = MXC_CPU_IMX6DL,
+       .mmdc_compat = "fsl,imx6q-mmdc",
+       .src_compat = "fsl,imx6q-src",
+       .iomuxc_compat = "fsl,imx6dl-iomuxc",
+       .gpc_compat = "fsl,imx6q-gpc",
+       .mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
+       .mmdc_io_offset = imx6dl_mmdc_io_offset,
+};
+
+static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
+       .cpu_type = MXC_CPU_IMX6SL,
+       .mmdc_compat = "fsl,imx6sl-mmdc",
+       .src_compat = "fsl,imx6sl-src",
+       .iomuxc_compat = "fsl,imx6sl-iomuxc",
+       .gpc_compat = "fsl,imx6sl-gpc",
+       .mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
+       .mmdc_io_offset = imx6sl_mmdc_io_offset,
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-imx6.S must be also changed accordingly,
+ * otherwise, the suspend to ocram function will be broken!
+ */
+struct imx6_cpu_pm_info {
+       phys_addr_t pbase; /* The physical address of pm_info. */
+       phys_addr_t resume_addr; /* The physical resume address for asm code */
+       u32 cpu_type;
+       u32 pm_info_size; /* Size of pm_info. */
+       struct imx6_pm_base mmdc_base;
+       struct imx6_pm_base src_base;
+       struct imx6_pm_base iomuxc_base;
+       struct imx6_pm_base ccm_base;
+       struct imx6_pm_base gpc_base;
+       struct imx6_pm_base l2_base;
+       u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
+       u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+} __aligned(8);
+
+void imx6q_set_int_mem_clk_lpm(void)
+{
+       u32 val = readl_relaxed(ccm_base + CGPR);
+
+       val |= BM_CGPR_INT_MEM_CLK_LPM;
+       writel_relaxed(val, ccm_base + CGPR);
+}
+
+static void imx6q_enable_rbc(bool enable)
+{
+       u32 val;
+
+       /*
+        * need to mask all interrupts in GPC before
+        * operating RBC configurations
+        */
+       imx_gpc_mask_all();
+
+       /* configure RBC enable bit */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_RBC_EN;
+       val |= enable ? BM_CCR_RBC_EN : 0;
+       writel_relaxed(val, ccm_base + CCR);
+
+       /* configure RBC count */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_RBC_BYPASS_COUNT;
+       val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
+       writel(val, ccm_base + CCR);
+
+       /*
+        * need to delay at least 2 cycles of CKIL(32K)
+        * due to hardware design requirement, which is
+        * ~61us, here we use 65us for safe
+        */
+       udelay(65);
+
+       /* restore GPC interrupt mask settings */
+       imx_gpc_restore_all();
+}
+
+static void imx6q_enable_wb(bool enable)
+{
+       u32 val;
+
+       /* configure well bias enable bit */
+       val = readl_relaxed(ccm_base + CLPCR);
+       val &= ~BM_CLPCR_WB_PER_AT_LPM;
+       val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
+       writel_relaxed(val, ccm_base + CLPCR);
+
+       /* configure well bias count */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_WB_COUNT;
+       val |= enable ? BM_CCR_WB_COUNT : 0;
+       writel_relaxed(val, ccm_base + CCR);
+}
+
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
+{
+       struct irq_data *iomuxc_irq_data = irq_get_irq_data(32);
+       u32 val = readl_relaxed(ccm_base + CLPCR);
+
+       val &= ~BM_CLPCR_LPM;
+       switch (mode) {
+       case WAIT_CLOCKED:
+               break;
+       case WAIT_UNCLOCKED:
+               val |= 0x1 << BP_CLPCR_LPM;
+               val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
+               break;
+       case STOP_POWER_ON:
+               val |= 0x2 << BP_CLPCR_LPM;
+               break;
+       case WAIT_UNCLOCKED_POWER_OFF:
+               val |= 0x1 << BP_CLPCR_LPM;
+               val &= ~BM_CLPCR_VSTBY;
+               val &= ~BM_CLPCR_SBYOS;
+               break;
+       case STOP_POWER_OFF:
+               val |= 0x2 << BP_CLPCR_LPM;
+               val |= 0x3 << BP_CLPCR_STBY_COUNT;
+               val |= BM_CLPCR_VSTBY;
+               val |= BM_CLPCR_SBYOS;
+               if (cpu_is_imx6sl()) {
+                       val |= BM_CLPCR_BYPASS_PMIC_READY;
+                       val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+               } else {
+                       val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * ERR007265: CCM: When improper low-power sequence is used,
+        * the SoC enters low power mode before the ARM core executes WFI.
+        *
+        * Software workaround:
+        * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
+        *    by setting IOMUX_GPR1_GINT.
+        * 2) Software should then unmask IRQ #32 in GPC before setting CCM
+        *    Low-Power mode.
+        * 3) Software should mask IRQ #32 right after CCM Low-Power mode
+        *    is set (set bits 0-1 of CCM_CLPCR).
+        */
+       imx_gpc_irq_unmask(iomuxc_irq_data);
+       writel_relaxed(val, ccm_base + CLPCR);
+       imx_gpc_irq_mask(iomuxc_irq_data);
+
+       return 0;
+}
+
+static int imx6q_suspend_finish(unsigned long val)
+{
+       if (!imx6_suspend_in_ocram_fn) {
+               cpu_do_idle();
+       } else {
+               /*
+                * call low level suspend function in ocram,
+                * as we need to float DDR IO.
+                */
+               local_flush_tlb_all();
+               imx6_suspend_in_ocram_fn(suspend_ocram_base);
+       }
+
+       return 0;
+}
+
+static int imx6q_pm_enter(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_MEM:
+               imx6q_set_lpm(STOP_POWER_OFF);
+               imx6q_enable_wb(true);
+               /*
+                * For suspend into ocram, asm code already take care of
+                * RBC setting, so we do NOT need to do that here.
+                */
+               if (!imx6_suspend_in_ocram_fn)
+                       imx6q_enable_rbc(true);
+               imx_gpc_pre_suspend();
+               imx_anatop_pre_suspend();
+               imx_set_cpu_jump(0, v7_cpu_resume);
+               /* Zzz ... */
+               cpu_suspend(0, imx6q_suspend_finish);
+               if (cpu_is_imx6q() || cpu_is_imx6dl())
+                       imx_smp_prepare();
+               imx_anatop_post_resume();
+               imx_gpc_post_resume();
+               imx6q_enable_rbc(false);
+               imx6q_enable_wb(false);
+               imx6q_set_lpm(WAIT_CLOCKED);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct platform_suspend_ops imx6q_pm_ops = {
+       .enter = imx6q_pm_enter,
+       .valid = suspend_valid_only_mem,
+};
+
+void __init imx6q_pm_set_ccm_base(void __iomem *base)
+{
+       ccm_base = base;
+}
+
+static int __init imx6_pm_get_base(struct imx6_pm_base *base,
+                               const char *compat)
+{
+       struct device_node *node;
+       struct resource res;
+       int ret = 0;
+
+       node = of_find_compatible_node(NULL, NULL, compat);
+       if (!node) {
+               ret = -ENODEV;
+               goto out;
+       }
+
+       ret = of_address_to_resource(node, 0, &res);
+       if (ret)
+               goto put_node;
+
+       base->pbase = res.start;
+       base->vbase = ioremap(res.start, resource_size(&res));
+       if (!base->vbase)
+               ret = -ENOMEM;
+
+put_node:
+       of_node_put(node);
+out:
+       return ret;
+}
+
+static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
+{
+       phys_addr_t ocram_pbase;
+       struct device_node *node;
+       struct platform_device *pdev;
+       struct imx6_cpu_pm_info *pm_info;
+       struct gen_pool *ocram_pool;
+       unsigned long ocram_base;
+       int i, ret = 0;
+       const u32 *mmdc_offset_array;
+
+       suspend_set_ops(&imx6q_pm_ops);
+
+       if (!socdata) {
+               pr_warn("%s: invalid argument!\n", __func__);
+               return -EINVAL;
+       }
+
+       node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+       if (!node) {
+               pr_warn("%s: failed to find ocram node!\n", __func__);
+               return -ENODEV;
+       }
+
+       pdev = of_find_device_by_node(node);
+       if (!pdev) {
+               pr_warn("%s: failed to find ocram device!\n", __func__);
+               ret = -ENODEV;
+               goto put_node;
+       }
+
+       ocram_pool = dev_get_gen_pool(&pdev->dev);
+       if (!ocram_pool) {
+               pr_warn("%s: ocram pool unavailable!\n", __func__);
+               ret = -ENODEV;
+               goto put_node;
+       }
+
+       ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
+       if (!ocram_base) {
+               pr_warn("%s: unable to alloc ocram!\n", __func__);
+               ret = -ENOMEM;
+               goto put_node;
+       }
+
+       ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+
+       suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
+               MX6Q_SUSPEND_OCRAM_SIZE, false);
+
+       pm_info = suspend_ocram_base;
+       pm_info->pbase = ocram_pbase;
+       pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
+       pm_info->pm_info_size = sizeof(*pm_info);
+
+       /*
+        * ccm physical address is not used by asm code currently,
+        * so get ccm virtual address directly, as we already have
+        * it from ccm driver.
+        */
+       pm_info->ccm_base.vbase = ccm_base;
+
+       ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
+       if (ret) {
+               pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
+               goto put_node;
+       }
+
+       ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
+       if (ret) {
+               pr_warn("%s: failed to get src base %d!\n", __func__, ret);
+               goto src_map_failed;
+       }
+
+       ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
+       if (ret) {
+               pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
+               goto iomuxc_map_failed;
+       }
+
+       ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
+       if (ret) {
+               pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
+               goto gpc_map_failed;
+       }
+
+       ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
+       if (ret) {
+               pr_warn("%s: failed to get pl310-cache base %d!\n",
+                       __func__, ret);
+               goto pl310_cache_map_failed;
+       }
+
+       pm_info->cpu_type = socdata->cpu_type;
+       pm_info->mmdc_io_num = socdata->mmdc_io_num;
+       mmdc_offset_array = socdata->mmdc_io_offset;
+
+       for (i = 0; i < pm_info->mmdc_io_num; i++) {
+               pm_info->mmdc_io_val[i][0] =
+                       mmdc_offset_array[i];
+               pm_info->mmdc_io_val[i][1] =
+                       readl_relaxed(pm_info->iomuxc_base.vbase +
+                       mmdc_offset_array[i]);
+       }
+
+       imx6_suspend_in_ocram_fn = fncpy(
+               suspend_ocram_base + sizeof(*pm_info),
+               &imx6_suspend,
+               MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
+
+       goto put_node;
+
+pl310_cache_map_failed:
+       iounmap(&pm_info->gpc_base.vbase);
+gpc_map_failed:
+       iounmap(&pm_info->iomuxc_base.vbase);
+iomuxc_map_failed:
+       iounmap(&pm_info->src_base.vbase);
+src_map_failed:
+       iounmap(&pm_info->mmdc_base.vbase);
+put_node:
+       of_node_put(node);
+
+       return ret;
+}
+
+static void __init imx6_pm_common_init(const struct imx6_pm_socdata
+                                       *socdata)
+{
+       struct regmap *gpr;
+       int ret;
+
+       WARN_ON(!ccm_base);
+
+       if (IS_ENABLED(CONFIG_SUSPEND)) {
+               ret = imx6q_suspend_init(socdata);
+               if (ret)
+                       pr_warn("%s: No DDR LPM support with suspend %d!\n",
+                               __func__, ret);
+       }
+
+       /*
+        * This is for SW workaround step #1 of ERR007265, see comments
+        * in imx6q_set_lpm for details of this errata.
+        * Force IOMUXC irq pending, so that the interrupt to GPC can be
+        * used to deassert dsm_request signal when the signal gets
+        * asserted unexpectedly.
+        */
+       gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+       if (!IS_ERR(gpr))
+               regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
+                                  IMX6Q_GPR1_GINT);
+}
+
+void __init imx6q_pm_init(void)
+{
+       imx6_pm_common_init(&imx6q_pm_data);
+}
+
+void __init imx6dl_pm_init(void)
+{
+       imx6_pm_common_init(&imx6dl_pm_data);
+}
+
+void __init imx6sl_pm_init(void)
+{
+       imx6_pm_common_init(&imx6sl_pm_data);
+}
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
deleted file mode 100644 (file)
index 29e3fe6..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright 2011-2013 Freescale Semiconductor, Inc.
- * Copyright 2011 Linaro Ltd.
- *
- * 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/delay.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/regmap.h>
-#include <linux/suspend.h>
-#include <asm/cacheflush.h>
-#include <asm/proc-fns.h>
-#include <asm/suspend.h>
-#include <asm/hardware/cache-l2x0.h>
-
-#include "common.h"
-#include "hardware.h"
-
-#define CCR                            0x0
-#define BM_CCR_WB_COUNT                        (0x7 << 16)
-#define BM_CCR_RBC_BYPASS_COUNT                (0x3f << 21)
-#define BM_CCR_RBC_EN                  (0x1 << 27)
-
-#define CLPCR                          0x54
-#define BP_CLPCR_LPM                   0
-#define BM_CLPCR_LPM                   (0x3 << 0)
-#define BM_CLPCR_BYPASS_PMIC_READY     (0x1 << 2)
-#define BM_CLPCR_ARM_CLK_DIS_ON_LPM    (0x1 << 5)
-#define BM_CLPCR_SBYOS                 (0x1 << 6)
-#define BM_CLPCR_DIS_REF_OSC           (0x1 << 7)
-#define BM_CLPCR_VSTBY                 (0x1 << 8)
-#define BP_CLPCR_STBY_COUNT            9
-#define BM_CLPCR_STBY_COUNT            (0x3 << 9)
-#define BM_CLPCR_COSC_PWRDOWN          (0x1 << 11)
-#define BM_CLPCR_WB_PER_AT_LPM         (0x1 << 16)
-#define BM_CLPCR_WB_CORE_AT_LPM                (0x1 << 17)
-#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS   (0x1 << 19)
-#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS   (0x1 << 21)
-#define BM_CLPCR_MASK_CORE0_WFI                (0x1 << 22)
-#define BM_CLPCR_MASK_CORE1_WFI                (0x1 << 23)
-#define BM_CLPCR_MASK_CORE2_WFI                (0x1 << 24)
-#define BM_CLPCR_MASK_CORE3_WFI                (0x1 << 25)
-#define BM_CLPCR_MASK_SCU_IDLE         (0x1 << 26)
-#define BM_CLPCR_MASK_L2CC_IDLE                (0x1 << 27)
-
-#define CGPR                           0x64
-#define BM_CGPR_CHICKEN_BIT            (0x1 << 17)
-
-static void __iomem *ccm_base;
-
-void imx6q_set_chicken_bit(void)
-{
-       u32 val = readl_relaxed(ccm_base + CGPR);
-
-       val |= BM_CGPR_CHICKEN_BIT;
-       writel_relaxed(val, ccm_base + CGPR);
-}
-
-static void imx6q_enable_rbc(bool enable)
-{
-       u32 val;
-
-       /*
-        * need to mask all interrupts in GPC before
-        * operating RBC configurations
-        */
-       imx_gpc_mask_all();
-
-       /* configure RBC enable bit */
-       val = readl_relaxed(ccm_base + CCR);
-       val &= ~BM_CCR_RBC_EN;
-       val |= enable ? BM_CCR_RBC_EN : 0;
-       writel_relaxed(val, ccm_base + CCR);
-
-       /* configure RBC count */
-       val = readl_relaxed(ccm_base + CCR);
-       val &= ~BM_CCR_RBC_BYPASS_COUNT;
-       val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
-       writel(val, ccm_base + CCR);
-
-       /*
-        * need to delay at least 2 cycles of CKIL(32K)
-        * due to hardware design requirement, which is
-        * ~61us, here we use 65us for safe
-        */
-       udelay(65);
-
-       /* restore GPC interrupt mask settings */
-       imx_gpc_restore_all();
-}
-
-static void imx6q_enable_wb(bool enable)
-{
-       u32 val;
-
-       /* configure well bias enable bit */
-       val = readl_relaxed(ccm_base + CLPCR);
-       val &= ~BM_CLPCR_WB_PER_AT_LPM;
-       val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
-       writel_relaxed(val, ccm_base + CLPCR);
-
-       /* configure well bias count */
-       val = readl_relaxed(ccm_base + CCR);
-       val &= ~BM_CCR_WB_COUNT;
-       val |= enable ? BM_CCR_WB_COUNT : 0;
-       writel_relaxed(val, ccm_base + CCR);
-}
-
-int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-{
-       struct irq_data *iomuxc_irq_data = irq_get_irq_data(32);
-       u32 val = readl_relaxed(ccm_base + CLPCR);
-
-       val &= ~BM_CLPCR_LPM;
-       switch (mode) {
-       case WAIT_CLOCKED:
-               break;
-       case WAIT_UNCLOCKED:
-               val |= 0x1 << BP_CLPCR_LPM;
-               val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
-               break;
-       case STOP_POWER_ON:
-               val |= 0x2 << BP_CLPCR_LPM;
-               break;
-       case WAIT_UNCLOCKED_POWER_OFF:
-               val |= 0x1 << BP_CLPCR_LPM;
-               val &= ~BM_CLPCR_VSTBY;
-               val &= ~BM_CLPCR_SBYOS;
-               break;
-       case STOP_POWER_OFF:
-               val |= 0x2 << BP_CLPCR_LPM;
-               val |= 0x3 << BP_CLPCR_STBY_COUNT;
-               val |= BM_CLPCR_VSTBY;
-               val |= BM_CLPCR_SBYOS;
-               if (cpu_is_imx6sl()) {
-                       val |= BM_CLPCR_BYPASS_PMIC_READY;
-                       val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
-               } else {
-                       val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /*
-        * ERR007265: CCM: When improper low-power sequence is used,
-        * the SoC enters low power mode before the ARM core executes WFI.
-        *
-        * Software workaround:
-        * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
-        *    by setting IOMUX_GPR1_GINT.
-        * 2) Software should then unmask IRQ #32 in GPC before setting CCM
-        *    Low-Power mode.
-        * 3) Software should mask IRQ #32 right after CCM Low-Power mode
-        *    is set (set bits 0-1 of CCM_CLPCR).
-        */
-       imx_gpc_irq_unmask(iomuxc_irq_data);
-       writel_relaxed(val, ccm_base + CLPCR);
-       imx_gpc_irq_mask(iomuxc_irq_data);
-
-       return 0;
-}
-
-static int imx6q_suspend_finish(unsigned long val)
-{
-       cpu_do_idle();
-       return 0;
-}
-
-static int imx6q_pm_enter(suspend_state_t state)
-{
-       switch (state) {
-       case PM_SUSPEND_MEM:
-               imx6q_set_lpm(STOP_POWER_OFF);
-               imx6q_enable_wb(true);
-               imx6q_enable_rbc(true);
-               imx_gpc_pre_suspend();
-               imx_anatop_pre_suspend();
-               imx_set_cpu_jump(0, v7_cpu_resume);
-               /* Zzz ... */
-               cpu_suspend(0, imx6q_suspend_finish);
-               if (cpu_is_imx6q() || cpu_is_imx6dl())
-                       imx_smp_prepare();
-               imx_anatop_post_resume();
-               imx_gpc_post_resume();
-               imx6q_enable_rbc(false);
-               imx6q_enable_wb(false);
-               imx6q_set_lpm(WAIT_CLOCKED);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static const struct platform_suspend_ops imx6q_pm_ops = {
-       .enter = imx6q_pm_enter,
-       .valid = suspend_valid_only_mem,
-};
-
-void __init imx6q_pm_set_ccm_base(void __iomem *base)
-{
-       ccm_base = base;
-}
-
-void __init imx6q_pm_init(void)
-{
-       struct regmap *gpr;
-
-       WARN_ON(!ccm_base);
-
-       /*
-        * This is for SW workaround step #1 of ERR007265, see comments
-        * in imx6q_set_lpm for details of this errata.
-        * Force IOMUXC irq pending, so that the interrupt to GPC can be
-        * used to deassert dsm_request signal when the signal gets
-        * asserted unexpectedly.
-        */
-       gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
-       if (!IS_ERR(gpr))
-               regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
-                                  IMX6Q_GPR1_GINT);
-
-
-       suspend_set_ops(&imx6q_pm_ops);
-}
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
new file mode 100644 (file)
index 0000000..20048ff
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2014 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/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "hardware.h"
+
+/*
+ * ==================== low level suspend ====================
+ *
+ * Better to follow below rules to use ARM registers:
+ * r0: pm_info structure address;
+ * r1 ~ r4: for saving pm_info members;
+ * r5 ~ r10: free registers;
+ * r11: io base address.
+ *
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ *                              .
+ *                              .
+ *                              .
+ *                              ^
+ *                              ^
+ *                              ^
+ *                      imx6_suspend code
+ *              PM_INFO structure(imx6_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+/*
+ * Below offsets are based on struct imx6_cpu_pm_info
+ * which defined in arch/arm/mach-imx/pm-imx6q.c, this
+ * structure contains necessary pm info for low level
+ * suspend related code.
+ */
+#define PM_INFO_PBASE_OFFSET                   0x0
+#define PM_INFO_RESUME_ADDR_OFFSET             0x4
+#define PM_INFO_CPU_TYPE_OFFSET                        0x8
+#define PM_INFO_PM_INFO_SIZE_OFFSET            0xC
+#define PM_INFO_MX6Q_MMDC_P_OFFSET             0x10
+#define PM_INFO_MX6Q_MMDC_V_OFFSET             0x14
+#define PM_INFO_MX6Q_SRC_P_OFFSET              0x18
+#define PM_INFO_MX6Q_SRC_V_OFFSET              0x1C
+#define PM_INFO_MX6Q_IOMUXC_P_OFFSET           0x20
+#define PM_INFO_MX6Q_IOMUXC_V_OFFSET           0x24
+#define PM_INFO_MX6Q_CCM_P_OFFSET              0x28
+#define PM_INFO_MX6Q_CCM_V_OFFSET              0x2C
+#define PM_INFO_MX6Q_GPC_P_OFFSET              0x30
+#define PM_INFO_MX6Q_GPC_V_OFFSET              0x34
+#define PM_INFO_MX6Q_L2_P_OFFSET               0x38
+#define PM_INFO_MX6Q_L2_V_OFFSET               0x3C
+#define PM_INFO_MMDC_IO_NUM_OFFSET             0x40
+#define PM_INFO_MMDC_IO_VAL_OFFSET             0x44
+
+#define MX6Q_SRC_GPR1  0x20
+#define MX6Q_SRC_GPR2  0x24
+#define MX6Q_MMDC_MAPSR        0x404
+#define MX6Q_MMDC_MPDGCTRL0    0x83c
+#define MX6Q_GPC_IMR1  0x08
+#define MX6Q_GPC_IMR2  0x0c
+#define MX6Q_GPC_IMR3  0x10
+#define MX6Q_GPC_IMR4  0x14
+#define MX6Q_CCM_CCR   0x0
+
+       .align 3
+
+       .macro  sync_l2_cache
+
+       /* sync L2 cache to drain L2's buffers to DRAM. */
+#ifdef CONFIG_CACHE_L2X0
+       ldr     r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+       mov     r6, #0x0
+       str     r6, [r11, #L2X0_CACHE_SYNC]
+1:
+       ldr     r6, [r11, #L2X0_CACHE_SYNC]
+       ands    r6, r6, #0x1
+       bne     1b
+#endif
+
+       .endm
+
+       .macro  resume_mmdc
+
+       /* restore MMDC IO */
+       cmp     r5, #0x0
+       ldreq   r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+       ldrne   r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
+
+       ldr     r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+       ldr     r7, =PM_INFO_MMDC_IO_VAL_OFFSET
+       add     r7, r7, r0
+1:
+       ldr     r8, [r7], #0x4
+       ldr     r9, [r7], #0x4
+       str     r9, [r11, r8]
+       subs    r6, r6, #0x1
+       bne     1b
+
+       cmp     r5, #0x0
+       ldreq   r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+       ldrne   r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
+
+       cmp     r3, #MXC_CPU_IMX6SL
+       bne     4f
+
+       /* reset read FIFO, RST_RD_FIFO */
+       ldr     r7, =MX6Q_MMDC_MPDGCTRL0
+       ldr     r6, [r11, r7]
+       orr     r6, r6, #(1 << 31)
+       str     r6, [r11, r7]
+2:
+       ldr     r6, [r11, r7]
+       ands    r6, r6, #(1 << 31)
+       bne     2b
+
+       /* reset FIFO a second time */
+       ldr     r6, [r11, r7]
+       orr     r6, r6, #(1 << 31)
+       str     r6, [r11, r7]
+3:
+       ldr     r6, [r11, r7]
+       ands    r6, r6, #(1 << 31)
+       bne     3b
+4:
+       /* let DDR out of self-refresh */
+       ldr     r7, [r11, #MX6Q_MMDC_MAPSR]
+       bic     r7, r7, #(1 << 21)
+       str     r7, [r11, #MX6Q_MMDC_MAPSR]
+5:
+       ldr     r7, [r11, #MX6Q_MMDC_MAPSR]
+       ands    r7, r7, #(1 << 25)
+       bne     5b
+
+       /* enable DDR auto power saving */
+       ldr     r7, [r11, #MX6Q_MMDC_MAPSR]
+       bic     r7, r7, #0x1
+       str     r7, [r11, #MX6Q_MMDC_MAPSR]
+
+       .endm
+
+ENTRY(imx6_suspend)
+       ldr     r1, [r0, #PM_INFO_PBASE_OFFSET]
+       ldr     r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+       ldr     r3, [r0, #PM_INFO_CPU_TYPE_OFFSET]
+       ldr     r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
+
+       /*
+        * counting the resume address in iram
+        * to set it in SRC register.
+        */
+       ldr     r6, =imx6_suspend
+       ldr     r7, =resume
+       sub     r7, r7, r6
+       add     r8, r1, r4
+       add     r9, r8, r7
+
+       /*
+        * make sure TLB contain the addr we want,
+        * as we will access them after MMDC IO floated.
+        */
+
+       ldr     r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+       ldr     r6, [r11, #0x0]
+       ldr     r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+       ldr     r6, [r11, #0x0]
+
+       /* use r11 to store the IO address */
+       ldr     r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
+       /* store physical resume addr and pm_info address. */
+       str     r9, [r11, #MX6Q_SRC_GPR1]
+       str     r1, [r11, #MX6Q_SRC_GPR2]
+
+       /* need to sync L2 cache before DSM. */
+       sync_l2_cache
+
+       ldr     r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
+       /*
+        * put DDR explicitly into self-refresh and
+        * disable automatic power savings.
+        */
+       ldr     r7, [r11, #MX6Q_MMDC_MAPSR]
+       orr     r7, r7, #0x1
+       str     r7, [r11, #MX6Q_MMDC_MAPSR]
+
+       /* make the DDR explicitly enter self-refresh. */
+       ldr     r7, [r11, #MX6Q_MMDC_MAPSR]
+       orr     r7, r7, #(1 << 21)
+       str     r7, [r11, #MX6Q_MMDC_MAPSR]
+
+poll_dvfs_set:
+       ldr     r7, [r11, #MX6Q_MMDC_MAPSR]
+       ands    r7, r7, #(1 << 25)
+       beq     poll_dvfs_set
+
+       ldr     r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
+       ldr     r6, =0x0
+       ldr     r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
+       ldr     r8, =PM_INFO_MMDC_IO_VAL_OFFSET
+       add     r8, r8, r0
+       /* i.MX6SL's last 3 IOs need special setting */
+       cmp     r3, #MXC_CPU_IMX6SL
+       subeq   r7, r7, #0x3
+set_mmdc_io_lpm:
+       ldr     r9, [r8], #0x8
+       str     r6, [r11, r9]
+       subs    r7, r7, #0x1
+       bne     set_mmdc_io_lpm
+
+       cmp     r3, #MXC_CPU_IMX6SL
+       bne     set_mmdc_io_lpm_done
+       ldr     r6, =0x1000
+       ldr     r9, [r8], #0x8
+       str     r6, [r11, r9]
+       ldr     r9, [r8], #0x8
+       str     r6, [r11, r9]
+       ldr     r6, =0x80000
+       ldr     r9, [r8]
+       str     r6, [r11, r9]
+set_mmdc_io_lpm_done:
+
+       /*
+        * mask all GPC interrupts before
+        * enabling the RBC counters to
+        * avoid the counter starting too
+        * early if an interupt is already
+        * pending.
+        */
+       ldr     r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+       ldr     r6, [r11, #MX6Q_GPC_IMR1]
+       ldr     r7, [r11, #MX6Q_GPC_IMR2]
+       ldr     r8, [r11, #MX6Q_GPC_IMR3]
+       ldr     r9, [r11, #MX6Q_GPC_IMR4]
+
+       ldr     r10, =0xffffffff
+       str     r10, [r11, #MX6Q_GPC_IMR1]
+       str     r10, [r11, #MX6Q_GPC_IMR2]
+       str     r10, [r11, #MX6Q_GPC_IMR3]
+       str     r10, [r11, #MX6Q_GPC_IMR4]
+
+       /*
+        * enable the RBC bypass counter here
+        * to hold off the interrupts. RBC counter
+        * = 32 (1ms), Minimum RBC delay should be
+        * 400us for the analog LDOs to power down.
+        */
+       ldr     r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
+       ldr     r10, [r11, #MX6Q_CCM_CCR]
+       bic     r10, r10, #(0x3f << 21)
+       orr     r10, r10, #(0x20 << 21)
+       str     r10, [r11, #MX6Q_CCM_CCR]
+
+       /* enable the counter. */
+       ldr     r10, [r11, #MX6Q_CCM_CCR]
+       orr     r10, r10, #(0x1 << 27)
+       str     r10, [r11, #MX6Q_CCM_CCR]
+
+       /* unmask all the GPC interrupts. */
+       ldr     r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
+       str     r6, [r11, #MX6Q_GPC_IMR1]
+       str     r7, [r11, #MX6Q_GPC_IMR2]
+       str     r8, [r11, #MX6Q_GPC_IMR3]
+       str     r9, [r11, #MX6Q_GPC_IMR4]
+
+       /*
+        * now delay for a short while (3usec)
+        * ARM is at 1GHz at this point
+        * so a short loop should be enough.
+        * this delay is required to ensure that
+        * the RBC counter can start counting in
+        * case an interrupt is already pending
+        * or in case an interrupt arrives just
+        * as ARM is about to assert DSM_request.
+        */
+       ldr     r6, =2000
+rbc_loop:
+       subs    r6, r6, #0x1
+       bne     rbc_loop
+
+       /* Zzz, enter stop mode */
+       wfi
+       nop
+       nop
+       nop
+       nop
+
+       /*
+        * run to here means there is pending
+        * wakeup source, system should auto
+        * resume, we need to restore MMDC IO first
+        */
+       mov     r5, #0x0
+       resume_mmdc
+
+       /* return to suspend finish */
+       mov     pc, lr
+
+resume:
+       /* invalidate L1 I-cache first */
+       mov     r6, #0x0
+       mcr     p15, 0, r6, c7, c5, 0
+       mcr     p15, 0, r6, c7, c5, 6
+       /* enable the Icache and branch prediction */
+       mov     r6, #0x1800
+       mcr     p15, 0, r6, c1, c0, 0
+       isb
+
+       /* get physical resume address from pm_info. */
+       ldr     lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
+       /* clear core0's entry and parameter */
+       ldr     r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
+       mov     r7, #0x0
+       str     r7, [r11, #MX6Q_SRC_GPR1]
+       str     r7, [r11, #MX6Q_SRC_GPR2]
+
+       ldr     r3, [r0, #PM_INFO_CPU_TYPE_OFFSET]
+       mov     r5, #0x1
+       resume_mmdc
+
+       mov     pc, lr
+ENDPROC(imx6_suspend)
+
+/*
+ * The following code must assume it is running from physical address
+ * where absolute virtual addresses to the data section have to be
+ * turned into relative ones.
+ */
+
+#ifdef CONFIG_CACHE_L2X0
+       .macro  pl310_resume
+       adr     r0, l2x0_saved_regs_offset
+       ldr     r2, [r0]
+       add     r2, r2, r0
+       ldr     r0, [r2, #L2X0_R_PHY_BASE]      @ get physical base of l2x0
+       ldr     r1, [r2, #L2X0_R_AUX_CTRL]      @ get aux_ctrl value
+       str     r1, [r0, #L2X0_AUX_CTRL]        @ restore aux_ctrl
+       mov     r1, #0x1
+       str     r1, [r0, #L2X0_CTRL]            @ re-enable L2
+       .endm
+
+l2x0_saved_regs_offset:
+       .word   l2x0_saved_regs - .
+
+#else
+       .macro  pl310_resume
+       .endm
+#endif
+
+ENTRY(v7_cpu_resume)
+       bl      v7_invalidate_l1
+       pl310_resume
+       b       cpu_resume
+ENDPROC(v7_cpu_resume)
index 1a3a5f6157706c7f9400d3bfd61ffffcce1b9424..65222ea0df6d7176883a886ed6054eb080c19a0b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/irq.h>
 #include <linux/clockchips.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/sched_clock.h>
 
@@ -116,11 +117,22 @@ static u64 notrace mxc_read_sched_clock(void)
        return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
 }
 
+static struct delay_timer imx_delay_timer;
+
+static unsigned long imx_read_current_timer(void)
+{
+       return __raw_readl(sched_clock_reg);
+}
+
 static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
        unsigned int c = clk_get_rate(timer_clk);
        void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
 
+       imx_delay_timer.read_current_timer = &imx_read_current_timer;
+       imx_delay_timer.freq = c;
+       register_current_timer_delay(&imx_delay_timer);
+
        sched_clock_reg = reg;
 
        sched_clock_register(mxc_read_sched_clock, 32, c);
index abeff25532abce23869a8f5f268cf47545283160..ba43321001d8a5dd95275f31634c61cdd47798d7 100644 (file)
@@ -6,8 +6,8 @@ config ARCH_INTEGRATOR_AP
        bool "Support Integrator/AP and Integrator/PP2 platforms"
        select CLKSRC_MMIO
        select MIGHT_HAVE_PCI
-       select SERIAL_AMBA_PL010
-       select SERIAL_AMBA_PL010_CONSOLE
+       select SERIAL_AMBA_PL010 if TTY
+       select SERIAL_AMBA_PL010_CONSOLE if TTY
        select SOC_BUS
        help
          Include support for the ARM(R) Integrator/AP and
@@ -18,8 +18,8 @@ config ARCH_INTEGRATOR_CP
        select ARCH_CINTEGRATOR
        select ARM_TIMER_SP804
        select PLAT_VERSATILE_CLCD
-       select SERIAL_AMBA_PL011
-       select SERIAL_AMBA_PL011_CONSOLE
+       select SERIAL_AMBA_PL011 if TTY
+       select SERIAL_AMBA_PL011_CONSOLE if TTY
        select SOC_BUS
        help
          Include support for the ARM(R) Integrator CP platform.
@@ -30,6 +30,9 @@ config ARCH_CINTEGRATOR
 config INTEGRATOR_IMPD1
        tristate "Include support for Integrator/IM-PD1"
        depends on ARCH_INTEGRATOR_AP
+       select ARCH_REQUIRE_GPIOLIB
+       select ARM_VIC
+       select GPIO_PL061 if GPIOLIB
        help
          The IM-PD1 is an add-on logic module for the Integrator which
          allows ARM(R) Ltd PrimeCells to be developed and evaluated.
index 00ddf20ed91b384d892248238afe6f008758e303..e3f3aca43efbe65bc9a05e59aa429359ab56918d 100644 (file)
 #include <linux/of.h>
 #include <linux/of_address.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
 #include <asm/pgtable.h>
 
+#include "hardware.h"
 #include "cm.h"
 #include "common.h"
 
diff --git a/arch/arm/mach-integrator/hardware.h b/arch/arm/mach-integrator/hardware.h
new file mode 100644 (file)
index 0000000..857ca5f
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ *  This file contains the hardware definitions of the Integrator.
+ *
+ *  Copyright (C) 1998-1999 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef INTEGRATOR_HARDWARE_H
+#define INTEGRATOR_HARDWARE_H
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE                        0xF0000000                 // VA of IO
+#define IO_SIZE                        0x0B000000                 // How much?
+#define IO_START               INTEGRATOR_HDR_BASE        // PA of IO
+
+/* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
+#define IO_ADDRESS(x)  (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
+#else
+#define IO_ADDRESS(x)  (x)
+#endif
+
+#define __io_address(n)                ((void __iomem *)IO_ADDRESS(n))
+
+/*
+ *  Integrator memory map
+ */
+#define INTEGRATOR_BOOT_ROM_LO          0x00000000
+#define INTEGRATOR_BOOT_ROM_HI          0x20000000
+#define INTEGRATOR_BOOT_ROM_BASE        INTEGRATOR_BOOT_ROM_HI  /*  Normal position */
+#define INTEGRATOR_BOOT_ROM_SIZE        SZ_512K
+
+/*
+ * New Core Modules have different amounts of SSRAM, the amount of SSRAM
+ * fitted can be found in HDR_STAT.
+ *
+ * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to
+ * the minimum amount of SSRAM fitted on any core module.
+ *
+ * New Core Modules also alias the SSRAM.
+ *
+ */
+#define INTEGRATOR_SSRAM_BASE           0x00000000
+#define INTEGRATOR_SSRAM_ALIAS_BASE     0x10800000
+#define INTEGRATOR_SSRAM_SIZE           SZ_256K
+
+#define INTEGRATOR_FLASH_BASE           0x24000000
+#define INTEGRATOR_FLASH_SIZE           SZ_32M
+
+#define INTEGRATOR_MBRD_SSRAM_BASE      0x28000000
+#define INTEGRATOR_MBRD_SSRAM_SIZE      SZ_512K
+
+/*
+ *  SDRAM is a SIMM therefore the size is not known.
+ */
+#define INTEGRATOR_SDRAM_BASE           0x00040000
+
+#define INTEGRATOR_SDRAM_ALIAS_BASE     0x80000000
+#define INTEGRATOR_HDR0_SDRAM_BASE      0x80000000
+#define INTEGRATOR_HDR1_SDRAM_BASE      0x90000000
+#define INTEGRATOR_HDR2_SDRAM_BASE      0xA0000000
+#define INTEGRATOR_HDR3_SDRAM_BASE      0xB0000000
+
+/*
+ *  Logic expansion modules
+ *
+ */
+#define INTEGRATOR_LOGIC_MODULES_BASE   0xC0000000
+#define INTEGRATOR_LOGIC_MODULE0_BASE   0xC0000000
+#define INTEGRATOR_LOGIC_MODULE1_BASE   0xD0000000
+#define INTEGRATOR_LOGIC_MODULE2_BASE   0xE0000000
+#define INTEGRATOR_LOGIC_MODULE3_BASE   0xF0000000
+
+/*
+ * Integrator header card registers
+ */
+#define INTEGRATOR_HDR_ID_OFFSET        0x00
+#define INTEGRATOR_HDR_PROC_OFFSET      0x04
+#define INTEGRATOR_HDR_OSC_OFFSET       0x08
+#define INTEGRATOR_HDR_CTRL_OFFSET      0x0C
+#define INTEGRATOR_HDR_STAT_OFFSET      0x10
+#define INTEGRATOR_HDR_LOCK_OFFSET      0x14
+#define INTEGRATOR_HDR_SDRAM_OFFSET     0x20
+#define INTEGRATOR_HDR_INIT_OFFSET      0x24    /*  CM9x6 */
+#define INTEGRATOR_HDR_IC_OFFSET        0x40
+#define INTEGRATOR_HDR_SPDBASE_OFFSET   0x100
+#define INTEGRATOR_HDR_SPDTOP_OFFSET    0x200
+
+#define INTEGRATOR_HDR_BASE             0x10000000
+#define INTEGRATOR_HDR_ID               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_ID_OFFSET)
+#define INTEGRATOR_HDR_PROC             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_PROC_OFFSET)
+#define INTEGRATOR_HDR_OSC              (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_OSC_OFFSET)
+#define INTEGRATOR_HDR_CTRL             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_CTRL_OFFSET)
+#define INTEGRATOR_HDR_STAT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET)
+#define INTEGRATOR_HDR_LOCK             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_LOCK_OFFSET)
+#define INTEGRATOR_HDR_SDRAM            (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SDRAM_OFFSET)
+#define INTEGRATOR_HDR_INIT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_INIT_OFFSET)
+#define INTEGRATOR_HDR_IC               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_IC_OFFSET)
+#define INTEGRATOR_HDR_SPDBASE          (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDBASE_OFFSET)
+#define INTEGRATOR_HDR_SPDTOP           (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDTOP_OFFSET)
+
+#define INTEGRATOR_HDR_CTRL_LED         0x01
+#define INTEGRATOR_HDR_CTRL_MBRD_DETECH 0x02
+#define INTEGRATOR_HDR_CTRL_REMAP       0x04
+#define INTEGRATOR_HDR_CTRL_RESET       0x08
+#define INTEGRATOR_HDR_CTRL_HIGHVECTORS 0x10
+#define INTEGRATOR_HDR_CTRL_BIG_ENDIAN  0x20
+#define INTEGRATOR_HDR_CTRL_FASTBUS     0x40
+#define INTEGRATOR_HDR_CTRL_SYNC        0x80
+
+#define INTEGRATOR_HDR_OSC_CORE_10MHz   0x102
+#define INTEGRATOR_HDR_OSC_CORE_15MHz   0x107
+#define INTEGRATOR_HDR_OSC_CORE_20MHz   0x10C
+#define INTEGRATOR_HDR_OSC_CORE_25MHz   0x111
+#define INTEGRATOR_HDR_OSC_CORE_30MHz   0x116
+#define INTEGRATOR_HDR_OSC_CORE_35MHz   0x11B
+#define INTEGRATOR_HDR_OSC_CORE_40MHz   0x120
+#define INTEGRATOR_HDR_OSC_CORE_45MHz   0x125
+#define INTEGRATOR_HDR_OSC_CORE_50MHz   0x12A
+#define INTEGRATOR_HDR_OSC_CORE_55MHz   0x12F
+#define INTEGRATOR_HDR_OSC_CORE_60MHz   0x134
+#define INTEGRATOR_HDR_OSC_CORE_65MHz   0x139
+#define INTEGRATOR_HDR_OSC_CORE_70MHz   0x13E
+#define INTEGRATOR_HDR_OSC_CORE_75MHz   0x143
+#define INTEGRATOR_HDR_OSC_CORE_80MHz   0x148
+#define INTEGRATOR_HDR_OSC_CORE_85MHz   0x14D
+#define INTEGRATOR_HDR_OSC_CORE_90MHz   0x152
+#define INTEGRATOR_HDR_OSC_CORE_95MHz   0x157
+#define INTEGRATOR_HDR_OSC_CORE_100MHz  0x15C
+#define INTEGRATOR_HDR_OSC_CORE_105MHz  0x161
+#define INTEGRATOR_HDR_OSC_CORE_110MHz  0x166
+#define INTEGRATOR_HDR_OSC_CORE_115MHz  0x16B
+#define INTEGRATOR_HDR_OSC_CORE_120MHz  0x170
+#define INTEGRATOR_HDR_OSC_CORE_125MHz  0x175
+#define INTEGRATOR_HDR_OSC_CORE_130MHz  0x17A
+#define INTEGRATOR_HDR_OSC_CORE_135MHz  0x17F
+#define INTEGRATOR_HDR_OSC_CORE_140MHz  0x184
+#define INTEGRATOR_HDR_OSC_CORE_145MHz  0x189
+#define INTEGRATOR_HDR_OSC_CORE_150MHz  0x18E
+#define INTEGRATOR_HDR_OSC_CORE_155MHz  0x193
+#define INTEGRATOR_HDR_OSC_CORE_160MHz  0x198
+#define INTEGRATOR_HDR_OSC_CORE_MASK    0x7FF
+
+#define INTEGRATOR_HDR_OSC_MEM_10MHz    0x10C000
+#define INTEGRATOR_HDR_OSC_MEM_15MHz    0x116000
+#define INTEGRATOR_HDR_OSC_MEM_20MHz    0x120000
+#define INTEGRATOR_HDR_OSC_MEM_25MHz    0x12A000
+#define INTEGRATOR_HDR_OSC_MEM_30MHz    0x134000
+#define INTEGRATOR_HDR_OSC_MEM_33MHz    0x13A000
+#define INTEGRATOR_HDR_OSC_MEM_40MHz    0x148000
+#define INTEGRATOR_HDR_OSC_MEM_50MHz    0x15C000
+#define INTEGRATOR_HDR_OSC_MEM_60MHz    0x170000
+#define INTEGRATOR_HDR_OSC_MEM_66MHz    0x17C000
+#define INTEGRATOR_HDR_OSC_MEM_MASK     0x7FF000
+
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM7x0  0x0
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x0  0x0800000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x6  0x1000000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM10x00  0x1800000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_MASK  0x1800000
+
+#define INTEGRATOR_HDR_SDRAM_SPD_OK     (1 << 5)
+
+/*
+ * Integrator system registers
+ */
+
+/*
+ *  System Controller
+ */
+#define INTEGRATOR_SC_ID_OFFSET         0x00
+#define INTEGRATOR_SC_OSC_OFFSET        0x04
+#define INTEGRATOR_SC_CTRLS_OFFSET      0x08
+#define INTEGRATOR_SC_CTRLC_OFFSET      0x0C
+#define INTEGRATOR_SC_DEC_OFFSET        0x10
+#define INTEGRATOR_SC_ARB_OFFSET        0x14
+#define INTEGRATOR_SC_LOCK_OFFSET       0x1C
+
+#define INTEGRATOR_SC_BASE              0x11000000
+#define INTEGRATOR_SC_ID                (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET)
+#define INTEGRATOR_SC_OSC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET)
+#define INTEGRATOR_SC_CTRLS             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
+#define INTEGRATOR_SC_CTRLC             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
+#define INTEGRATOR_SC_DEC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET)
+#define INTEGRATOR_SC_ARB               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET)
+#define INTEGRATOR_SC_PCIENABLE         (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
+#define INTEGRATOR_SC_LOCK              (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET)
+
+#define INTEGRATOR_SC_OSC_SYS_10MHz     0x20
+#define INTEGRATOR_SC_OSC_SYS_15MHz     0x34
+#define INTEGRATOR_SC_OSC_SYS_20MHz     0x48
+#define INTEGRATOR_SC_OSC_SYS_25MHz     0x5C
+#define INTEGRATOR_SC_OSC_SYS_33MHz     0x7C
+#define INTEGRATOR_SC_OSC_SYS_MASK      0xFF
+
+#define INTEGRATOR_SC_OSC_PCI_25MHz     0x100
+#define INTEGRATOR_SC_OSC_PCI_33MHz     0x0
+#define INTEGRATOR_SC_OSC_PCI_MASK      0x100
+
+#define INTEGRATOR_SC_CTRL_SOFTRST      (1 << 0)
+#define INTEGRATOR_SC_CTRL_nFLVPPEN     (1 << 1)
+#define INTEGRATOR_SC_CTRL_nFLWP        (1 << 2)
+#define INTEGRATOR_SC_CTRL_URTS0        (1 << 4)
+#define INTEGRATOR_SC_CTRL_UDTR0        (1 << 5)
+#define INTEGRATOR_SC_CTRL_URTS1        (1 << 6)
+#define INTEGRATOR_SC_CTRL_UDTR1        (1 << 7)
+
+/*
+ *  External Bus Interface
+ */
+#define INTEGRATOR_EBI_BASE             0x12000000
+
+#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
+#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
+#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
+#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
+#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
+
+#define INTEGRATOR_EBI_CSR0             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
+#define INTEGRATOR_EBI_CSR1             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define INTEGRATOR_EBI_CSR2             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
+#define INTEGRATOR_EBI_CSR3             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
+#define INTEGRATOR_EBI_LOCK             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+#define INTEGRATOR_EBI_8_BIT            0x00
+#define INTEGRATOR_EBI_16_BIT           0x01
+#define INTEGRATOR_EBI_32_BIT           0x02
+#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
+#define INTEGRATOR_EBI_SYNC             0x08
+#define INTEGRATOR_EBI_WS_2             0x00
+#define INTEGRATOR_EBI_WS_3             0x10
+#define INTEGRATOR_EBI_WS_4             0x20
+#define INTEGRATOR_EBI_WS_5             0x30
+#define INTEGRATOR_EBI_WS_6             0x40
+#define INTEGRATOR_EBI_WS_7             0x50
+#define INTEGRATOR_EBI_WS_8             0x60
+#define INTEGRATOR_EBI_WS_9             0x70
+#define INTEGRATOR_EBI_WS_10            0x80
+#define INTEGRATOR_EBI_WS_11            0x90
+#define INTEGRATOR_EBI_WS_12            0xA0
+#define INTEGRATOR_EBI_WS_13            0xB0
+#define INTEGRATOR_EBI_WS_14            0xC0
+#define INTEGRATOR_EBI_WS_15            0xD0
+#define INTEGRATOR_EBI_WS_16            0xE0
+#define INTEGRATOR_EBI_WS_17            0xF0
+
+
+#define INTEGRATOR_CT_BASE              0x13000000      /*  Counter/Timers */
+#define INTEGRATOR_IC_BASE              0x14000000      /*  Interrupt Controller */
+#define INTEGRATOR_RTC_BASE             0x15000000      /*  Real Time Clock */
+#define INTEGRATOR_UART0_BASE           0x16000000      /*  UART 0 */
+#define INTEGRATOR_UART1_BASE           0x17000000      /*  UART 1 */
+#define INTEGRATOR_KBD_BASE             0x18000000      /*  Keyboard */
+#define INTEGRATOR_MOUSE_BASE           0x19000000      /*  Mouse */
+
+/*
+ *  LED's & Switches
+ */
+#define INTEGRATOR_DBG_ALPHA_OFFSET     0x00
+#define INTEGRATOR_DBG_LEDS_OFFSET      0x04
+#define INTEGRATOR_DBG_SWITCH_OFFSET    0x08
+
+#define INTEGRATOR_DBG_BASE             0x1A000000
+#define INTEGRATOR_DBG_ALPHA            (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET)
+#define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
+#define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
+
+#define INTEGRATOR_AP_GPIO_BASE                0x1B000000      /* GPIO */
+
+#define INTEGRATOR_CP_MMC_BASE         0x1C000000      /* MMC */
+#define INTEGRATOR_CP_AACI_BASE                0x1D000000      /* AACI */
+#define INTEGRATOR_CP_ETH_BASE         0xC8000000      /* Ethernet */
+#define INTEGRATOR_CP_GPIO_BASE                0xC9000000      /* GPIO */
+#define INTEGRATOR_CP_SIC_BASE         0xCA000000      /* SIC */
+#define INTEGRATOR_CP_CTL_BASE         0xCB000000      /* CP system control */
+
+/* PS2 Keyboard interface */
+#define KMI0_BASE                       INTEGRATOR_KBD_BASE
+
+/* PS2 Mouse interface */
+#define KMI1_BASE                       INTEGRATOR_MOUSE_BASE
+
+/*
+ * Integrator Interrupt Controllers
+ *
+ *
+ * Offsets from interrupt controller base
+ *
+ * System Controller interrupt controller base is
+ *
+ *     INTEGRATOR_IC_BASE + (header_number << 6)
+ *
+ * Core Module interrupt controller base is
+ *
+ *     INTEGRATOR_HDR_IC
+ */
+#define IRQ_STATUS                      0
+#define IRQ_RAW_STATUS                  0x04
+#define IRQ_ENABLE                      0x08
+#define IRQ_ENABLE_SET                  0x08
+#define IRQ_ENABLE_CLEAR                0x0C
+
+#define INT_SOFT_SET                    0x10
+#define INT_SOFT_CLEAR                  0x14
+
+#define FIQ_STATUS                      0x20
+#define FIQ_RAW_STATUS                  0x24
+#define FIQ_ENABLE                      0x28
+#define FIQ_ENABLE_SET                  0x28
+#define FIQ_ENABLE_CLEAR                0x2C
+
+
+/*
+ * LED's
+ */
+#define GREEN_LED                       0x01
+#define YELLOW_LED                      0x02
+#define RED_LED                         0x04
+#define GREEN_LED_2                     0x08
+#define ALL_LEDS                        0x0F
+
+#define LED_BANK                        INTEGRATOR_DBG_LEDS
+
+/*
+ *  Timer definitions
+ *
+ *  Only use timer 1 & 2
+ *  (both run at 24MHz and will need the clock divider set to 16).
+ *
+ *  Timer 0 runs at bus frequency
+ */
+#define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
+#define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
+#define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
+
+#define INTEGRATOR_CSR_BASE             0x10000000
+#define INTEGRATOR_CSR_SIZE             0x10000000
+
+#endif /* INTEGRATOR_HARDWARE_H */
index 9f82f9dcbb9803d195d3fd5d545fe1475db69689..0e870ea818c4e6acd87a48626a994f9bf1ce3016 100644 (file)
 #include <linux/io.h>
 #include <linux/platform_data/clk-integrator.h>
 #include <linux/slab.h>
+#include <linux/irqchip/arm-vic.h>
 
-#include <mach/lm.h>
-#include <mach/impd1.h>
 #include <asm/sizes.h>
+#include "lm.h"
+#include "impd1.h"
 
 static int module_id;
 
@@ -35,6 +36,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
 
 struct impd1_module {
        void __iomem    *base;
+       void __iomem    *vic_base;
 };
 
 void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
@@ -262,9 +264,6 @@ struct impd1_device {
 
 static struct impd1_device impd1_devs[] = {
        {
-               .offset = 0x03000000,
-               .id     = 0x00041190,
-       }, {
                .offset = 0x00100000,
                .irq    = { 1 },
                .id     = 0x00141011,
@@ -304,46 +303,72 @@ static struct impd1_device impd1_devs[] = {
        }
 };
 
-static int impd1_probe(struct lm_device *dev)
+/*
+ * Valid IRQs: 0 thru 9 and 11, 10 unused.
+ */
+#define IMPD1_VALID_IRQS 0x00000bffU
+
+static int __init impd1_probe(struct lm_device *dev)
 {
        struct impd1_module *impd1;
-       int i, ret;
+       int irq_base;
+       int i;
 
        if (dev->id != module_id)
                return -EINVAL;
 
-       if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
+       if (!devm_request_mem_region(&dev->dev, dev->resource.start,
+                                    SZ_4K, "LM registers"))
                return -EBUSY;
 
-       impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL);
-       if (!impd1) {
-               ret = -ENOMEM;
-               goto release_lm;
-       }
+       impd1 = devm_kzalloc(&dev->dev, sizeof(struct impd1_module),
+                            GFP_KERNEL);
+       if (!impd1)
+               return -ENOMEM;
 
-       impd1->base = ioremap(dev->resource.start, SZ_4K);
-       if (!impd1->base) {
-               ret = -ENOMEM;
-               goto free_impd1;
-       }
+       impd1->base = devm_ioremap(&dev->dev, dev->resource.start, SZ_4K);
+       if (!impd1->base)
+               return -ENOMEM;
 
-       lm_set_drvdata(dev, impd1);
+       integrator_impd1_clk_init(impd1->base, dev->id);
 
-       printk("IM-PD1 found at 0x%08lx\n",
-               (unsigned long)dev->resource.start);
+       if (!devm_request_mem_region(&dev->dev,
+                                    dev->resource.start + 0x03000000,
+                                    SZ_4K, "VIC"))
+               return -EBUSY;
 
-       integrator_impd1_clk_init(impd1->base, dev->id);
+       impd1->vic_base = devm_ioremap(&dev->dev,
+                                      dev->resource.start + 0x03000000,
+                                      SZ_4K);
+       if (!impd1->vic_base)
+               return -ENOMEM;
+
+       irq_base = vic_init_cascaded(impd1->vic_base, dev->irq,
+                                    IMPD1_VALID_IRQS, 0);
+
+       lm_set_drvdata(dev, impd1);
+
+       dev_info(&dev->dev, "IM-PD1 found at 0x%08lx\n",
+                (unsigned long)dev->resource.start);
 
        for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
                struct impd1_device *idev = impd1_devs + i;
                struct amba_device *d;
                unsigned long pc_base;
                char devname[32];
+               int irq1 = idev->irq[0];
+               int irq2 = idev->irq[1];
+
+               /* Translate IRQs to IM-PD1 local numberspace */
+               if (irq1)
+                       irq1 += irq_base;
+               if (irq2)
+                       irq2 += irq_base;
 
                pc_base = dev->resource.start + idev->offset;
                snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
                d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K,
-                                           dev->irq, dev->irq,
+                                           irq1, irq2,
                                            idev->platform_data, idev->id,
                                            &dev->resource);
                if (IS_ERR(d)) {
@@ -353,14 +378,6 @@ static int impd1_probe(struct lm_device *dev)
        }
 
        return 0;
-
- free_impd1:
-       if (impd1 && impd1->base)
-               iounmap(impd1->base);
-       kfree(impd1);
- release_lm:
-       release_mem_region(dev->resource.start, SZ_4K);
-       return ret;
 }
 
 static int impd1_remove_one(struct device *dev, void *data)
@@ -371,16 +388,10 @@ static int impd1_remove_one(struct device *dev, void *data)
 
 static void impd1_remove(struct lm_device *dev)
 {
-       struct impd1_module *impd1 = lm_get_drvdata(dev);
-
        device_for_each_child(&dev->dev, NULL, impd1_remove_one);
        integrator_impd1_clk_exit(dev->id);
 
        lm_set_drvdata(dev, NULL);
-
-       iounmap(impd1->base);
-       kfree(impd1);
-       release_mem_region(dev->resource.start, SZ_4K);
 }
 
 static struct lm_driver impd1_driver = {
diff --git a/arch/arm/mach-integrator/impd1.h b/arch/arm/mach-integrator/impd1.h
new file mode 100644 (file)
index 0000000..76de4dc
--- /dev/null
@@ -0,0 +1,14 @@
+#define IMPD1_LEDS     0x0c
+#define IMPD1_INT      0x10
+#define IMPD1_SW       0x14
+#define IMPD1_CTRL     0x18
+
+#define IMPD1_CTRL_DISP_LCD    (0 << 0)
+#define IMPD1_CTRL_DISP_VGA    (1 << 0)
+#define IMPD1_CTRL_DISP_LCD1   (2 << 0)
+#define IMPD1_CTRL_DISP_ENABLE (1 << 2)
+#define IMPD1_CTRL_DISP_MASK   (7 << 0)
+
+struct device;
+
+void impd1_tweak_control(struct device *dev, u32 mask, u32 val);
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h
deleted file mode 100644 (file)
index 65fed7c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  arch/arm/mach-integrator/include/mach/hardware.h
- *
- *  This file contains the hardware definitions of the Integrator.
- *
- *  Copyright (C) 1999 ARM Limited.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/sizes.h>
-
-/*
- * Where in virtual memory the IO devices (timers, system controllers
- * and so on)
- */
-#define IO_BASE                        0xF0000000                 // VA of IO 
-#define IO_SIZE                        0x0B000000                 // How much?
-#define IO_START               INTEGRATOR_HDR_BASE        // PA of IO
-
-/* macro to get at IO space when running virtually */
-#ifdef CONFIG_MMU
-#define IO_ADDRESS(x)  (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
-#else
-#define IO_ADDRESS(x)  (x)
-#endif
-
-#define __io_address(n)                ((void __iomem *)IO_ADDRESS(n))
-
-#endif
-
diff --git a/arch/arm/mach-integrator/include/mach/impd1.h b/arch/arm/mach-integrator/include/mach/impd1.h
deleted file mode 100644 (file)
index d75de4b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#define IMPD1_OSC1     0x00
-#define IMPD1_OSC2     0x04
-#define IMPD1_LOCK     0x08
-#define IMPD1_LEDS     0x0c
-#define IMPD1_INT      0x10
-#define IMPD1_SW       0x14
-#define IMPD1_CTRL     0x18
-
-#define IMPD1_CTRL_DISP_LCD    (0 << 0)
-#define IMPD1_CTRL_DISP_VGA    (1 << 0)
-#define IMPD1_CTRL_DISP_LCD1   (2 << 0)
-#define IMPD1_CTRL_DISP_ENABLE (1 << 2)
-#define IMPD1_CTRL_DISP_MASK   (7 << 0)
-
-struct device;
-
-void impd1_tweak_control(struct device *dev, u32 mask, u32 val);
-
diff --git a/arch/arm/mach-integrator/include/mach/lm.h b/arch/arm/mach-integrator/include/mach/lm.h
deleted file mode 100644 (file)
index 28186b6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-struct lm_device {
-       struct device           dev;
-       struct resource         resource;
-       unsigned int            irq;
-       unsigned int            id;
-};
-
-struct lm_driver {
-       struct device_driver    drv;
-       int                     (*probe)(struct lm_device *);
-       void                    (*remove)(struct lm_device *);
-       int                     (*suspend)(struct lm_device *, pm_message_t);
-       int                     (*resume)(struct lm_device *);
-};
-
-int lm_driver_register(struct lm_driver *drv);
-void lm_driver_unregister(struct lm_driver *drv);
-
-int lm_device_register(struct lm_device *dev);
-
-#define lm_get_drvdata(lm)     dev_get_drvdata(&(lm)->dev)
-#define lm_set_drvdata(lm,d)   dev_set_drvdata(&(lm)->dev, d)
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h
deleted file mode 100644 (file)
index 306d025..0000000
+++ /dev/null
@@ -1,382 +0,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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-/**************************************************************************
- * * Copyright Â© ARM Limited 1998.  All rights reserved.
- * ***********************************************************************/
-/* ************************************************************************
- *
- *   Integrator address map
- *
- * ***********************************************************************/
-
-#ifndef __address_h
-#define __address_h                     1
-
-/* ========================================================================
- *  Integrator definitions
- * ========================================================================
- * ------------------------------------------------------------------------
- *  Memory definitions
- * ------------------------------------------------------------------------
- *  Integrator memory map
- *
- */
-#define INTEGRATOR_BOOT_ROM_LO          0x00000000
-#define INTEGRATOR_BOOT_ROM_HI          0x20000000
-#define INTEGRATOR_BOOT_ROM_BASE        INTEGRATOR_BOOT_ROM_HI  /*  Normal position */
-#define INTEGRATOR_BOOT_ROM_SIZE        SZ_512K
-
-/*
- *  New Core Modules have different amounts of SSRAM, the amount of SSRAM
- *  fitted can be found in HDR_STAT.
- *
- *  The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to
- *  the minimum amount of SSRAM fitted on any core module.
- *
- *  New Core Modules also alias the SSRAM.
- *
- */
-#define INTEGRATOR_SSRAM_BASE           0x00000000
-#define INTEGRATOR_SSRAM_ALIAS_BASE     0x10800000
-#define INTEGRATOR_SSRAM_SIZE           SZ_256K
-
-#define INTEGRATOR_FLASH_BASE           0x24000000
-#define INTEGRATOR_FLASH_SIZE           SZ_32M
-
-#define INTEGRATOR_MBRD_SSRAM_BASE      0x28000000
-#define INTEGRATOR_MBRD_SSRAM_SIZE      SZ_512K
-
-/*
- *  SDRAM is a SIMM therefore the size is not known.
- *
- */
-#define INTEGRATOR_SDRAM_BASE           0x00040000
-
-#define INTEGRATOR_SDRAM_ALIAS_BASE     0x80000000
-#define INTEGRATOR_HDR0_SDRAM_BASE      0x80000000
-#define INTEGRATOR_HDR1_SDRAM_BASE      0x90000000
-#define INTEGRATOR_HDR2_SDRAM_BASE      0xA0000000
-#define INTEGRATOR_HDR3_SDRAM_BASE      0xB0000000
-
-/*
- *  Logic expansion modules
- *
- */
-#define INTEGRATOR_LOGIC_MODULES_BASE   0xC0000000
-#define INTEGRATOR_LOGIC_MODULE0_BASE   0xC0000000
-#define INTEGRATOR_LOGIC_MODULE1_BASE   0xD0000000
-#define INTEGRATOR_LOGIC_MODULE2_BASE   0xE0000000
-#define INTEGRATOR_LOGIC_MODULE3_BASE   0xF0000000
-
-/* ------------------------------------------------------------------------
- *  Integrator header card registers
- * ------------------------------------------------------------------------
- *
- */
-#define INTEGRATOR_HDR_ID_OFFSET        0x00
-#define INTEGRATOR_HDR_PROC_OFFSET      0x04
-#define INTEGRATOR_HDR_OSC_OFFSET       0x08
-#define INTEGRATOR_HDR_CTRL_OFFSET      0x0C
-#define INTEGRATOR_HDR_STAT_OFFSET      0x10
-#define INTEGRATOR_HDR_LOCK_OFFSET      0x14
-#define INTEGRATOR_HDR_SDRAM_OFFSET     0x20
-#define INTEGRATOR_HDR_INIT_OFFSET      0x24    /*  CM9x6 */
-#define INTEGRATOR_HDR_IC_OFFSET        0x40
-#define INTEGRATOR_HDR_SPDBASE_OFFSET   0x100
-#define INTEGRATOR_HDR_SPDTOP_OFFSET    0x200
-
-#define INTEGRATOR_HDR_BASE             0x10000000
-#define INTEGRATOR_HDR_ID               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_ID_OFFSET)
-#define INTEGRATOR_HDR_PROC             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_PROC_OFFSET)
-#define INTEGRATOR_HDR_OSC              (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_OSC_OFFSET)
-#define INTEGRATOR_HDR_CTRL             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_CTRL_OFFSET)
-#define INTEGRATOR_HDR_STAT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET)
-#define INTEGRATOR_HDR_LOCK             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_LOCK_OFFSET)
-#define INTEGRATOR_HDR_SDRAM            (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SDRAM_OFFSET)
-#define INTEGRATOR_HDR_INIT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_INIT_OFFSET)
-#define INTEGRATOR_HDR_IC               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_IC_OFFSET)
-#define INTEGRATOR_HDR_SPDBASE          (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDBASE_OFFSET)
-#define INTEGRATOR_HDR_SPDTOP           (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDTOP_OFFSET)
-
-#define INTEGRATOR_HDR_CTRL_LED         0x01
-#define INTEGRATOR_HDR_CTRL_MBRD_DETECH 0x02
-#define INTEGRATOR_HDR_CTRL_REMAP       0x04
-#define INTEGRATOR_HDR_CTRL_RESET       0x08
-#define INTEGRATOR_HDR_CTRL_HIGHVECTORS 0x10
-#define INTEGRATOR_HDR_CTRL_BIG_ENDIAN  0x20
-#define INTEGRATOR_HDR_CTRL_FASTBUS     0x40
-#define INTEGRATOR_HDR_CTRL_SYNC        0x80
-
-#define INTEGRATOR_HDR_OSC_CORE_10MHz   0x102
-#define INTEGRATOR_HDR_OSC_CORE_15MHz   0x107
-#define INTEGRATOR_HDR_OSC_CORE_20MHz   0x10C
-#define INTEGRATOR_HDR_OSC_CORE_25MHz   0x111
-#define INTEGRATOR_HDR_OSC_CORE_30MHz   0x116
-#define INTEGRATOR_HDR_OSC_CORE_35MHz   0x11B
-#define INTEGRATOR_HDR_OSC_CORE_40MHz   0x120
-#define INTEGRATOR_HDR_OSC_CORE_45MHz   0x125
-#define INTEGRATOR_HDR_OSC_CORE_50MHz   0x12A
-#define INTEGRATOR_HDR_OSC_CORE_55MHz   0x12F
-#define INTEGRATOR_HDR_OSC_CORE_60MHz   0x134
-#define INTEGRATOR_HDR_OSC_CORE_65MHz   0x139
-#define INTEGRATOR_HDR_OSC_CORE_70MHz   0x13E
-#define INTEGRATOR_HDR_OSC_CORE_75MHz   0x143
-#define INTEGRATOR_HDR_OSC_CORE_80MHz   0x148
-#define INTEGRATOR_HDR_OSC_CORE_85MHz   0x14D
-#define INTEGRATOR_HDR_OSC_CORE_90MHz   0x152
-#define INTEGRATOR_HDR_OSC_CORE_95MHz   0x157
-#define INTEGRATOR_HDR_OSC_CORE_100MHz  0x15C
-#define INTEGRATOR_HDR_OSC_CORE_105MHz  0x161
-#define INTEGRATOR_HDR_OSC_CORE_110MHz  0x166
-#define INTEGRATOR_HDR_OSC_CORE_115MHz  0x16B
-#define INTEGRATOR_HDR_OSC_CORE_120MHz  0x170
-#define INTEGRATOR_HDR_OSC_CORE_125MHz  0x175
-#define INTEGRATOR_HDR_OSC_CORE_130MHz  0x17A
-#define INTEGRATOR_HDR_OSC_CORE_135MHz  0x17F
-#define INTEGRATOR_HDR_OSC_CORE_140MHz  0x184
-#define INTEGRATOR_HDR_OSC_CORE_145MHz  0x189
-#define INTEGRATOR_HDR_OSC_CORE_150MHz  0x18E
-#define INTEGRATOR_HDR_OSC_CORE_155MHz  0x193
-#define INTEGRATOR_HDR_OSC_CORE_160MHz  0x198
-#define INTEGRATOR_HDR_OSC_CORE_MASK    0x7FF
-
-#define INTEGRATOR_HDR_OSC_MEM_10MHz    0x10C000
-#define INTEGRATOR_HDR_OSC_MEM_15MHz    0x116000
-#define INTEGRATOR_HDR_OSC_MEM_20MHz    0x120000
-#define INTEGRATOR_HDR_OSC_MEM_25MHz    0x12A000
-#define INTEGRATOR_HDR_OSC_MEM_30MHz    0x134000
-#define INTEGRATOR_HDR_OSC_MEM_33MHz    0x13A000
-#define INTEGRATOR_HDR_OSC_MEM_40MHz    0x148000
-#define INTEGRATOR_HDR_OSC_MEM_50MHz    0x15C000
-#define INTEGRATOR_HDR_OSC_MEM_60MHz    0x170000
-#define INTEGRATOR_HDR_OSC_MEM_66MHz    0x17C000
-#define INTEGRATOR_HDR_OSC_MEM_MASK     0x7FF000
-
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM7x0  0x0
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x0  0x0800000
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x6  0x1000000
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM10x00  0x1800000
-#define INTEGRATOR_HDR_OSC_BUS_MODE_MASK  0x1800000
-
-#define INTEGRATOR_HDR_SDRAM_SPD_OK     (1 << 5)
-
-
-/* ------------------------------------------------------------------------
- *  Integrator system registers
- * ------------------------------------------------------------------------
- *
- */
-
-/*
- *  System Controller
- *
- */
-#define INTEGRATOR_SC_ID_OFFSET         0x00
-#define INTEGRATOR_SC_OSC_OFFSET        0x04
-#define INTEGRATOR_SC_CTRLS_OFFSET      0x08
-#define INTEGRATOR_SC_CTRLC_OFFSET      0x0C
-#define INTEGRATOR_SC_DEC_OFFSET        0x10
-#define INTEGRATOR_SC_ARB_OFFSET        0x14
-#define INTEGRATOR_SC_LOCK_OFFSET       0x1C
-
-#define INTEGRATOR_SC_BASE              0x11000000
-#define INTEGRATOR_SC_ID                (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET)
-#define INTEGRATOR_SC_OSC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET)
-#define INTEGRATOR_SC_CTRLS             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
-#define INTEGRATOR_SC_CTRLC             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
-#define INTEGRATOR_SC_DEC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET)
-#define INTEGRATOR_SC_ARB               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET)
-#define INTEGRATOR_SC_PCIENABLE         (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
-#define INTEGRATOR_SC_LOCK              (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET)
-
-#define INTEGRATOR_SC_OSC_SYS_10MHz     0x20
-#define INTEGRATOR_SC_OSC_SYS_15MHz     0x34
-#define INTEGRATOR_SC_OSC_SYS_20MHz     0x48
-#define INTEGRATOR_SC_OSC_SYS_25MHz     0x5C
-#define INTEGRATOR_SC_OSC_SYS_33MHz     0x7C
-#define INTEGRATOR_SC_OSC_SYS_MASK      0xFF
-
-#define INTEGRATOR_SC_OSC_PCI_25MHz     0x100
-#define INTEGRATOR_SC_OSC_PCI_33MHz     0x0
-#define INTEGRATOR_SC_OSC_PCI_MASK      0x100
-
-#define INTEGRATOR_SC_CTRL_SOFTRST      (1 << 0)
-#define INTEGRATOR_SC_CTRL_nFLVPPEN     (1 << 1)
-#define INTEGRATOR_SC_CTRL_nFLWP        (1 << 2)
-#define INTEGRATOR_SC_CTRL_URTS0        (1 << 4)
-#define INTEGRATOR_SC_CTRL_UDTR0        (1 << 5)
-#define INTEGRATOR_SC_CTRL_URTS1        (1 << 6)
-#define INTEGRATOR_SC_CTRL_UDTR1        (1 << 7)
-
-/*
- *  External Bus Interface
- *
- */
-#define INTEGRATOR_EBI_BASE             0x12000000
-
-#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
-#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
-#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
-#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
-#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
-
-#define INTEGRATOR_EBI_CSR0             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
-#define INTEGRATOR_EBI_CSR1             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
-#define INTEGRATOR_EBI_CSR2             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
-#define INTEGRATOR_EBI_CSR3             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
-#define INTEGRATOR_EBI_LOCK             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
-
-#define INTEGRATOR_EBI_8_BIT            0x00
-#define INTEGRATOR_EBI_16_BIT           0x01
-#define INTEGRATOR_EBI_32_BIT           0x02
-#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
-#define INTEGRATOR_EBI_SYNC             0x08
-#define INTEGRATOR_EBI_WS_2             0x00
-#define INTEGRATOR_EBI_WS_3             0x10
-#define INTEGRATOR_EBI_WS_4             0x20
-#define INTEGRATOR_EBI_WS_5             0x30
-#define INTEGRATOR_EBI_WS_6             0x40
-#define INTEGRATOR_EBI_WS_7             0x50
-#define INTEGRATOR_EBI_WS_8             0x60
-#define INTEGRATOR_EBI_WS_9             0x70
-#define INTEGRATOR_EBI_WS_10            0x80
-#define INTEGRATOR_EBI_WS_11            0x90
-#define INTEGRATOR_EBI_WS_12            0xA0
-#define INTEGRATOR_EBI_WS_13            0xB0
-#define INTEGRATOR_EBI_WS_14            0xC0
-#define INTEGRATOR_EBI_WS_15            0xD0
-#define INTEGRATOR_EBI_WS_16            0xE0
-#define INTEGRATOR_EBI_WS_17            0xF0
-
-
-#define INTEGRATOR_CT_BASE              0x13000000      /*  Counter/Timers */
-#define INTEGRATOR_IC_BASE              0x14000000      /*  Interrupt Controller */
-#define INTEGRATOR_RTC_BASE             0x15000000      /*  Real Time Clock */
-#define INTEGRATOR_UART0_BASE           0x16000000      /*  UART 0 */
-#define INTEGRATOR_UART1_BASE           0x17000000      /*  UART 1 */
-#define INTEGRATOR_KBD_BASE             0x18000000      /*  Keyboard */
-#define INTEGRATOR_MOUSE_BASE           0x19000000      /*  Mouse */
-
-/*
- *  LED's & Switches
- *
- */
-#define INTEGRATOR_DBG_ALPHA_OFFSET     0x00
-#define INTEGRATOR_DBG_LEDS_OFFSET      0x04
-#define INTEGRATOR_DBG_SWITCH_OFFSET    0x08
-
-#define INTEGRATOR_DBG_BASE             0x1A000000
-#define INTEGRATOR_DBG_ALPHA            (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET)
-#define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
-#define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
-
-#define INTEGRATOR_AP_GPIO_BASE                0x1B000000      /* GPIO */
-
-#define INTEGRATOR_CP_MMC_BASE         0x1C000000      /* MMC */
-#define INTEGRATOR_CP_AACI_BASE                0x1D000000      /* AACI */
-#define INTEGRATOR_CP_ETH_BASE         0xC8000000      /* Ethernet */
-#define INTEGRATOR_CP_GPIO_BASE                0xC9000000      /* GPIO */
-#define INTEGRATOR_CP_SIC_BASE         0xCA000000      /* SIC */
-#define INTEGRATOR_CP_CTL_BASE         0xCB000000      /* CP system control */
-
-/* ------------------------------------------------------------------------
- *  KMI keyboard/mouse definitions
- * ------------------------------------------------------------------------
- */
-/* PS2 Keyboard interface */
-#define KMI0_BASE                       INTEGRATOR_KBD_BASE
-
-/* PS2 Mouse interface */
-#define KMI1_BASE                       INTEGRATOR_MOUSE_BASE
-
-/* KMI definitions are now in include/asm-arm/hardware/amba_kmi.h -- rmk */
-
-/* ------------------------------------------------------------------------
- *  Integrator Interrupt Controllers
- * ------------------------------------------------------------------------
- *
- *  Offsets from interrupt controller base
- *
- *  System Controller interrupt controller base is
- *
- *     INTEGRATOR_IC_BASE + (header_number << 6)
- *
- *  Core Module interrupt controller base is
- *
- *     INTEGRATOR_HDR_IC
- *
- */
-#define IRQ_STATUS                      0
-#define IRQ_RAW_STATUS                  0x04
-#define IRQ_ENABLE                      0x08
-#define IRQ_ENABLE_SET                  0x08
-#define IRQ_ENABLE_CLEAR                0x0C
-
-#define INT_SOFT_SET                    0x10
-#define INT_SOFT_CLEAR                  0x14
-
-#define FIQ_STATUS                      0x20
-#define FIQ_RAW_STATUS                  0x24
-#define FIQ_ENABLE                      0x28
-#define FIQ_ENABLE_SET                  0x28
-#define FIQ_ENABLE_CLEAR                0x2C
-
-
-/* ------------------------------------------------------------------------
- *  Interrupts
- * ------------------------------------------------------------------------
- *
- *
- *  Each Core Module has two interrupts controllers, one on the core module
- *  itself and one in the system controller on the motherboard.  The
- *  READ_INT macro in target.s reads both interrupt controllers and returns
- *  a 32 bit bitmask, bits 0 to 23 are interrupts from the system controller
- *  and bits 24 to 31 are from the core module.
- *
- *  The following definitions relate to the bitmask returned by READ_INT.
- *
- */
-
-/* ------------------------------------------------------------------------
- *  LED's
- * ------------------------------------------------------------------------
- *
- */
-#define GREEN_LED                       0x01
-#define YELLOW_LED                      0x02
-#define RED_LED                         0x04
-#define GREEN_LED_2                     0x08
-#define ALL_LEDS                        0x0F
-
-#define LED_BANK                        INTEGRATOR_DBG_LEDS
-
-/*
- *  Timer definitions
- *
- *  Only use timer 1 & 2
- *  (both run at 24MHz and will need the clock divider set to 16).
- *
- *  Timer 0 runs at bus frequency
- */
-
-#define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
-#define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
-#define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
-
-#define INTEGRATOR_CSR_BASE             0x10000000
-#define INTEGRATOR_CSR_SIZE             0x10000000
-
-#endif
diff --git a/arch/arm/mach-integrator/include/mach/timex.h b/arch/arm/mach-integrator/include/mach/timex.h
deleted file mode 100644 (file)
index 1dcb420..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  arch/arm/mach-integrator/include/mach/timex.h
- *
- *  Integrator architecture timex specifications
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/*
- * ??
- */
-#define CLOCK_TICK_RATE                (50000000 / 16)
index 17c0fe6274357842d2769efc2f0bf2ac5241b982..dd0cc677d5960bf2b82d0821ca1b15582f60f4b3 100644 (file)
 #include <linux/sys_soc.h>
 #include <linux/termios.h>
 #include <linux/sched_clock.h>
+#include <linux/clk-provider.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/setup.h>
 #include <asm/param.h>         /* HZ */
 #include <asm/mach-types.h>
 
-#include <mach/lm.h>
-
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
+#include "hardware.h"
 #include "cm.h"
 #include "common.h"
 #include "pci_v3.h"
+#include "lm.h"
 
 /* Base address to the AP system controller */
 void __iomem *ap_syscon_base;
@@ -358,7 +357,7 @@ static struct clock_event_device integrator_clockevent = {
 
 static struct irqaction integrator_timer_irq = {
        .name           = "timer",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = integrator_timer_interrupt,
        .dev_id         = &integrator_clockevent,
 };
@@ -402,10 +401,7 @@ static void __init ap_of_timer_init(void)
        struct clk *clk;
        unsigned long rate;
 
-       clk = clk_get_sys("ap_timer", NULL);
-       BUG_ON(IS_ERR(clk));
-       clk_prepare_enable(clk);
-       rate = clk_get_rate(clk);
+       of_clk_init(NULL);
 
        err = of_property_read_string(of_aliases,
                                "arm,timer-primary", &path);
@@ -415,6 +411,12 @@ static void __init ap_of_timer_init(void)
        base = of_iomap(node, 0);
        if (WARN_ON(!base))
                return;
+
+       clk = of_clk_get(node, 0);
+       BUG_ON(IS_ERR(clk));
+       clk_prepare_enable(clk);
+       rate = clk_get_rate(clk);
+
        writel(0, base + TIMER_CTRL);
        integrator_clocksource_init(rate, base);
 
@@ -427,6 +429,12 @@ static void __init ap_of_timer_init(void)
        if (WARN_ON(!base))
                return;
        irq = irq_of_parse_and_map(node, 0);
+
+       clk = of_clk_get(node, 0);
+       BUG_ON(IS_ERR(clk));
+       clk_prepare_enable(clk);
+       rate = clk_get_rate(clk);
+
        writel(0, base + TIMER_CTRL);
        integrator_clockevent_init(rate, base, irq);
 }
@@ -440,7 +448,6 @@ static void __init ap_init_irq_of(void)
 {
        cm_init();
        of_irq_init(fpga_irq_of_match);
-       integrator_clk_init(false);
 }
 
 /* For the Device Tree, add in the UART callbacks as AUXDATA */
index a3ef961e4a93335308e4bf914e9fb7dceb59f8d3..a938242b0c95ce78e17296f7382a086ae49785fa 100644 (file)
 #include <linux/irqchip/versatile-fpga.h>
 #include <linux/gfp.h>
 #include <linux/mtd/physmap.h>
-#include <linux/platform_data/clk-integrator.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/sys_soc.h>
+#include <linux/sched_clock.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst.h>
-
-#include <mach/lm.h>
-
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <asm/hardware/timer-sp.h>
-
 #include <plat/clcd.h>
-#include <plat/sched_clock.h>
 
+#include "hardware.h"
 #include "cm.h"
 #include "common.h"
 
@@ -234,11 +225,14 @@ static struct clcd_board clcd_data = {
 
 #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
 
+static u64 notrace intcp_read_sched_clock(void)
+{
+       return readl(REFCOUNTER);
+}
+
 static void __init intcp_init_early(void)
 {
-#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
-       versatile_sched_clock_init(REFCOUNTER, 24000000);
-#endif
+       sched_clock_register(intcp_read_sched_clock, 32, 24000000);
 }
 
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
@@ -250,7 +244,6 @@ static void __init intcp_init_irq_of(void)
 {
        cm_init();
        of_irq_init(fpga_irq_of_match);
-       integrator_clk_init(true);
 }
 
 /*
index cb6ac58f5e078656e26936472a891c00ac3d4ecd..f1dcb57a59e2feae26a54d29ee06f54caffc767f 100644 (file)
@@ -11,9 +11,7 @@
 #include <linux/slab.h>
 #include <linux/leds.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
+#include "hardware.h"
 #include "cm.h"
 
 #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
index f52c7af31eaaac41d31bf1fd7c4cc0d9b9f43572..3f9e9f0431683d66a617ac5356f5bc136267d2ae 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 
-#include <mach/lm.h>
+#include "lm.h"
 
 #define to_lm_device(d)        container_of(d, struct lm_device, dev)
 #define to_lm_driver(d)        container_of(d, struct lm_driver, drv)
diff --git a/arch/arm/mach-integrator/lm.h b/arch/arm/mach-integrator/lm.h
new file mode 100644 (file)
index 0000000..28186b6
--- /dev/null
@@ -0,0 +1,23 @@
+
+struct lm_device {
+       struct device           dev;
+       struct resource         resource;
+       unsigned int            irq;
+       unsigned int            id;
+};
+
+struct lm_driver {
+       struct device_driver    drv;
+       int                     (*probe)(struct lm_device *);
+       void                    (*remove)(struct lm_device *);
+       int                     (*suspend)(struct lm_device *, pm_message_t);
+       int                     (*resume)(struct lm_device *);
+};
+
+int lm_driver_register(struct lm_driver *drv);
+void lm_driver_unregister(struct lm_driver *drv);
+
+int lm_device_register(struct lm_device *dev);
+
+#define lm_get_drvdata(lm)     dev_get_drvdata(&(lm)->dev)
+#define lm_set_drvdata(lm,d)   dev_set_drvdata(&(lm)->dev, d)
index c5e01b24d9fb37215deb8988d5bebcf454a252b9..05e1f73a1e8dbd022d1d5be3d72be182d3086c9d 100644 (file)
 #include <linux/of_pci.h>
 #include <video/vga.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
 #include <asm/mach/map.h>
 #include <asm/signal.h>
 #include <asm/mach/pci.h>
 #include <asm/irq_regs.h>
 
 #include "pci_v3.h"
+#include "hardware.h"
 
 /*
  * Where in the memory map does PCI live?
diff --git a/arch/arm/mach-iop13xx/include/mach/timex.h b/arch/arm/mach-iop13xx/include/mach/timex.h
deleted file mode 100644 (file)
index 45fb274..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-iop32x/include/mach/timex.h b/arch/arm/mach-iop32x/include/mach/timex.h
deleted file mode 100644 (file)
index 7262ab8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/timex.h
- *
- * IOP32x architecture timex specifications
- */
-#define CLOCK_TICK_RATE                (100 * HZ)
diff --git a/arch/arm/mach-iop33x/include/mach/timex.h b/arch/arm/mach-iop33x/include/mach/timex.h
deleted file mode 100644 (file)
index 54c5890..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * arch/arm/mach-iop33x/include/mach/timex.h
- *
- * IOP3xx architecture timex specifications
- */
-#define CLOCK_TICK_RATE                (100 * HZ)
index 200970d56f6d8c7c0b9a166584ee38eddad4fe31..4977296f0c7804272a5854ba5223b786761b7716 100644 (file)
@@ -315,33 +315,6 @@ static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *r
        return 0;
 }
 
-
-static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
-{
-       return (dma_addr + size) >= SZ_64M;
-}
-
-/*
- * Setup DMA mask to 64MB on PCI devices. Ignore all other devices.
- */
-static int ixp4xx_pci_platform_notify(struct device *dev)
-{
-       if (dev_is_pci(dev)) {
-               *dev->dma_mask =  SZ_64M - 1;
-               dev->coherent_dma_mask = SZ_64M - 1;
-               dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
-       }
-       return 0;
-}
-
-static int ixp4xx_pci_platform_notify_remove(struct device *dev)
-{
-       if (dev_is_pci(dev))
-               dmabounce_unregister_dev(dev);
-
-       return 0;
-}
-
 void __init ixp4xx_pci_preinit(void)
 {
        unsigned long cpuid = read_cpuid_id();
@@ -475,20 +448,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
        pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
        pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
-       platform_notify = ixp4xx_pci_platform_notify;
-       platform_notify_remove = ixp4xx_pci_platform_notify_remove;
-
        return 1;
 }
 
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
-       if (mask >= SZ_64M - 1)
-               return 0;
-
-       return -EIO;
-}
-
 EXPORT_SYMBOL(ixp4xx_pci_read);
 EXPORT_SYMBOL(ixp4xx_pci_write);
-EXPORT_SYMBOL(dma_set_coherent_mask);
index 6d68aed6548a504c23ba0639ea96871760381f12..fc4b7b24265e91d5c3007cc5d2ffe42229b85427 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
-#include <linux/timex.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/export.h>
 #include <linux/gpio.h>
 #include <linux/cpu.h>
+#include <linux/pci.h>
 #include <linux/sched_clock.h>
-
 #include <mach/udc.h>
 #include <mach/hardware.h>
 #include <mach/io.h>
 #include <asm/page.h>
 #include <asm/irq.h>
 #include <asm/system_misc.h>
-
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 
+#define IXP4XX_TIMER_FREQ 66666000
+
+/*
+ * The timer register doesn't allow to specify the two least significant bits of
+ * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
+ * the best value with the two least significant bits unset.
+ */
+#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
+                                      (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
+                       (IXP4XX_OST_RELOAD_MASK + 1)
+
 static void __init ixp4xx_clocksource_init(void);
 static void __init ixp4xx_clockevent_init(void);
 static struct clock_event_device clockevent_ixp4xx;
@@ -312,7 +321,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction ixp4xx_timer_irq = {
        .name           = "timer1",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = ixp4xx_timer_interrupt,
        .dev_id         = &clockevent_ixp4xx,
 };
@@ -520,7 +529,7 @@ static void ixp4xx_set_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK;
+               osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
                opts = IXP4XX_OST_ENABLE;
                break;
        case CLOCK_EVT_MODE_ONESHOT:
@@ -578,6 +587,54 @@ void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
        }
 }
 
+#ifdef CONFIG_PCI
+static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+       return (dma_addr + size) > SZ_64M;
+}
+
+static int ixp4xx_platform_notify_remove(struct device *dev)
+{
+       if (dev_is_pci(dev))
+               dmabounce_unregister_dev(dev);
+
+       return 0;
+}
+#endif
+
+/*
+ * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
+ */
+static int ixp4xx_platform_notify(struct device *dev)
+{
+       dev->dma_mask = &dev->coherent_dma_mask;
+
+#ifdef CONFIG_PCI
+       if (dev_is_pci(dev)) {
+               dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
+               dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
+               return 0;
+       }
+#endif
+
+       dev->coherent_dma_mask = DMA_BIT_MASK(32);
+       return 0;
+}
+
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+       if (dev_is_pci(dev))
+               mask &= DMA_BIT_MASK(28); /* 64 MB */
+
+       if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
+               dev->coherent_dma_mask = mask;
+               return 0;
+       }
+
+       return -EIO;            /* device wanted sub-64MB mask */
+}
+EXPORT_SYMBOL(dma_set_coherent_mask);
+
 #ifdef CONFIG_IXP4XX_INDIRECT_PCI
 /*
  * In the case of using indirect PCI, we simply return the actual PCI
@@ -600,12 +657,16 @@ static void ixp4xx_iounmap(void __iomem *addr)
        if (!is_pci_memory((__force u32)addr))
                __iounmap(addr);
 }
+#endif
 
 void __init ixp4xx_init_early(void)
 {
+       platform_notify = ixp4xx_platform_notify;
+#ifdef CONFIG_PCI
+       platform_notify_remove = ixp4xx_platform_notify_remove;
+#endif
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
        arch_ioremap_caller = ixp4xx_ioremap_caller;
        arch_iounmap = ixp4xx_iounmap;
-}
-#else
-void __init ixp4xx_init_early(void) {}
 #endif
+}
index 736dc692d54047b7f56e0b409fda416662252ad1..43ee06d3abe50fa9f94aa05c60e0f378cde92be6 100644 (file)
@@ -233,8 +233,7 @@ static int __init dsmg600_gpio_init(void)
 
        gpio_request(DSMG600_RB_GPIO, "reset button");
        if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler,
-               IRQF_DISABLED | IRQF_TRIGGER_LOW,
-               "DSM-G600 reset button", NULL) < 0) {
+               IRQF_TRIGGER_LOW, "DSM-G600 reset button", NULL) < 0) {
 
                printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
                        gpio_to_irq(DSMG600_RB_GPIO));
index 429966b756ed3eddcfd646e7838c163052ff0714..5c4b0c4a1b3787bfe009e3d254db7c8d73b325ac 100644 (file)
@@ -208,16 +208,14 @@ static void __init fsg_init(void)
        platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices));
 
        if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler,
-                       IRQF_DISABLED | IRQF_TRIGGER_LOW,
-                       "FSG reset button", NULL) < 0) {
+                       IRQF_TRIGGER_LOW, "FSG reset button", NULL) < 0) {
 
                printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
                        gpio_to_irq(FSG_RB_GPIO));
        }
 
        if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler,
-                       IRQF_DISABLED | IRQF_TRIGGER_LOW,
-                       "FSG power button", NULL) < 0) {
+                       IRQF_TRIGGER_LOW, "FSG power button", NULL) < 0) {
 
                printk(KERN_DEBUG "Power Button IRQ %d not available\n",
                        gpio_to_irq(FSG_SB_GPIO));
index e54ff491c105fd0949238a9127abff04069216f6..80bd9d6d04de78addde68e35c1207b39e491e409 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/hdlc.h>
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
@@ -79,19 +80,19 @@ static u8 control_value;
 
 static void set_scl(u8 value)
 {
-       gpio_line_set(GPIO_SCL, !!value);
+       gpio_set_value(GPIO_SCL, !!value);
        udelay(3);
 }
 
 static void set_sda(u8 value)
 {
-       gpio_line_set(GPIO_SDA, !!value);
+       gpio_set_value(GPIO_SDA, !!value);
        udelay(3);
 }
 
 static void set_str(u8 value)
 {
-       gpio_line_set(GPIO_STR, !!value);
+       gpio_set_value(GPIO_STR, !!value);
        udelay(3);
 }
 
@@ -108,8 +109,8 @@ static void output_control(void)
 {
        int i;
 
-       gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
-       gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
+       gpio_direction_output(GPIO_SCL, 1);
+       gpio_direction_output(GPIO_SDA, 1);
 
        for (i = 0; i < 8; i++) {
                set_scl(0);
@@ -151,8 +152,8 @@ static int hss_set_clock(int port, unsigned int clock_type)
 
 static irqreturn_t hss_dcd_irq(int irq, void *pdev)
 {
-       int i, port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
-       gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
+       int port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
+       int i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
        set_carrier_cb_tab[port](pdev, !i);
        return IRQ_HANDLED;
 }
@@ -168,7 +169,7 @@ static int hss_open(int port, void *pdev,
        else
                irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
 
-       gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
+       i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
        set_carrier_cb(pdev, !i);
 
        set_carrier_cb_tab[!!port] = set_carrier_cb;
@@ -181,7 +182,7 @@ static int hss_open(int port, void *pdev,
 
        set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
        output_control();
-       gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
+       gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
        return 0;
 }
 
@@ -193,7 +194,7 @@ static void hss_close(int port, void *pdev)
 
        set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
        output_control();
-       gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
+       gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
 }
 
 
@@ -413,13 +414,21 @@ static void __init gmlr_init(void)
        if (hw_bits & CFG_HW_HAS_EEPROM)
                device_tab[devices++] = &device_i2c; /* max index 6 */
 
-       gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
-       gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
-       gpio_line_config(GPIO_STR, IXP4XX_GPIO_OUT);
-       gpio_line_config(GPIO_HSS0_RTS_N, IXP4XX_GPIO_OUT);
-       gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);
-       gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);
-       gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);
+       gpio_request(GPIO_SCL, "SCL/clock");
+       gpio_request(GPIO_SDA, "SDA/data");
+       gpio_request(GPIO_STR, "strobe");
+       gpio_request(GPIO_HSS0_RTS_N, "HSS0 RTS");
+       gpio_request(GPIO_HSS1_RTS_N, "HSS1 RTS");
+       gpio_request(GPIO_HSS0_DCD_N, "HSS0 DCD");
+       gpio_request(GPIO_HSS1_DCD_N, "HSS1 DCD");
+
+       gpio_direction_output(GPIO_SCL, 1);
+       gpio_direction_output(GPIO_SDA, 1);
+       gpio_direction_output(GPIO_STR, 0);
+       gpio_direction_output(GPIO_HSS0_RTS_N, 1);
+       gpio_direction_output(GPIO_HSS1_RTS_N, 1);
+       gpio_direction_input(GPIO_HSS0_DCD_N);
+       gpio_direction_input(GPIO_HSS1_DCD_N);
        irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
        irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
 
index 5cf30d1b78d22b8901865f0426efefcc09d2a9c1..559c69a477317b2b0e718ae64af18ebf5a67b5e5 100644 (file)
@@ -48,9 +48,10 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
  * fallback to the default.
  */
 
+extern unsigned long pcibios_min_mem;
 static inline int is_pci_memory(u32 addr)
 {
-       return (addr >= PCIBIOS_MIN_MEM) && (addr <= 0x4FFFFFFF);
+       return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
 }
 
 #define writeb(v, p)                   __indirect_writeb(v, p)
diff --git a/arch/arm/mach-ixp4xx/include/mach/timex.h b/arch/arm/mach-ixp4xx/include/mach/timex.h
deleted file mode 100644 (file)
index 0396d89..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/timex.h
- * 
- */
-
-#include <mach/ixp4xx-regs.h>
-
-/*
- * We use IXP425 General purpose timer for our timer needs, it runs at 
- * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the
- * timer register ignores the bottom 2 bits of the LATCH value.
- */
-#define IXP4XX_TIMER_FREQ 66666000
-#define CLOCK_TICK_RATE \
-       (((IXP4XX_TIMER_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
-
index 507cb52335373eb3d8857cb2c2380b4e642b7baf..4e0f762bc651a8d7b9ffd380825eb26cedf68a50 100644 (file)
@@ -295,8 +295,7 @@ static void __init nas100d_init(void)
        pm_power_off = nas100d_power_off;
 
        if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
-               IRQF_DISABLED | IRQF_TRIGGER_LOW,
-               "NAS100D reset button", NULL) < 0) {
+               IRQF_TRIGGER_LOW, "NAS100D reset button", NULL) < 0) {
 
                printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
                        gpio_to_irq(NAS100D_RB_GPIO));
index ba5f1cda2a9de20b00daf1f2bfb3e3ec3df6fb86..88c025f52d8d729dd329013d1cd6479cd9992f02 100644 (file)
@@ -265,16 +265,14 @@ static void __init nslu2_init(void)
        pm_power_off = nslu2_power_off;
 
        if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler,
-               IRQF_DISABLED | IRQF_TRIGGER_LOW,
-               "NSLU2 reset button", NULL) < 0) {
+               IRQF_TRIGGER_LOW, "NSLU2 reset button", NULL) < 0) {
 
                printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
                        gpio_to_irq(NSLU2_RB_GPIO));
        }
 
        if (request_irq(gpio_to_irq(NSLU2_PB_GPIO), &nslu2_power_handler,
-               IRQF_DISABLED | IRQF_TRIGGER_HIGH,
-               "NSLU2 power button", NULL) < 0) {
+               IRQF_TRIGGER_HIGH, "NSLU2 power button", NULL) < 0) {
 
                printk(KERN_DEBUG "Power Button IRQ %d not available\n",
                        gpio_to_irq(NSLU2_PB_GPIO));
index 75ef03dc996490893c70c23ceea874b42747a679..2d494b45437670d2ab5c8c4a366c75c43d5d5967 100644 (file)
@@ -17,9 +17,7 @@
 #include <linux/serial_8250.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#ifdef CONFIG_LEDS_CLASS
 #include <linux/leds.h>
-#endif
 
 #include <asm/setup.h>
 #include <asm/memory.h>
index 90a708fef54136b80a1868abd987f663cedf3fb5..f50bc936cb8454e1a0f108a961e3811f6dc823c6 100644 (file)
@@ -1,13 +1,9 @@
 config ARCH_KEYSTONE
        bool "Texas Instruments Keystone Devices"
        depends on ARCH_MULTI_V7
-       select CPU_V7
        select ARM_GIC
        select HAVE_ARM_ARCH_TIMER
-       select HAVE_SMP
        select CLKSRC_MMIO
-       select GENERIC_CLOCKEVENTS
-       select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_ERRATA_798181 if SMP
        select COMMON_CLK_KEYSTONE
        select ARCH_SUPPORTS_BIG_ENDIAN
index 6e6bb7d5ea308ca890e56439481b51e211437346..e0b9e1b9cf303f9f91c8ff4bcff10cd0ab6d0f3c 100644 (file)
@@ -46,7 +46,7 @@ static void __init keystone_init(void)
 }
 
 static const char *keystone_match[] __initconst = {
-       "ti,keystone-evm",
+       "ti,keystone",
        NULL,
 };
 
index fe8319ad3158540355250c030aabd6c7f15878ea..df4b26340ae48d63cc37ecce38f65afe6927ebc7 100644 (file)
@@ -106,13 +106,6 @@ config ARCH_KIRKWOOD_DT
          Say 'Y' here if you want your kernel to support the
          Marvell Kirkwood using flattened device tree.
 
-config MACH_MV88F6281GTW_GE_DT
-       bool "Marvell 88F6281 GTW GE Board (Flattened Device Tree)"
-       depends on ARCH_KIRKWOOD_DT
-       help
-         Say 'Y' here if you want your kernel to support the
-         Marvell 88F6281 GTW GE Board (Flattened Device Tree).
-
 endmenu
 
 endif
index 144b511029399dc58a0049405478570f293ae492..3a72c5c6e7477cd946fdf8ecb0450549241b1dda 100644 (file)
@@ -1,5 +1,4 @@
-obj-y                          += common.o pcie.o
-obj-$(CONFIG_KIRKWOOD_LEGACY)  += irq.o mpp.o
+obj-$(CONFIG_KIRKWOOD_LEGACY)  += irq.o mpp.o common.o pcie.o
 obj-$(CONFIG_PM)               += pm.o
 
 obj-$(CONFIG_MACH_D2NET_V2)            += d2net_v2-setup.o lacie_v2-common.o
@@ -13,4 +12,3 @@ obj-$(CONFIG_MACH_TS219)              += ts219-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_TS41X)               += ts41x-setup.o tsx1x-common.o
 
 obj-$(CONFIG_ARCH_KIRKWOOD_DT)         += board-dt.o
-obj-$(CONFIG_MACH_MV88F6281GTW_GE_DT)  += board-mv88f6281gtw_ge.o
index 78188159484d79e760d8ec22a6303a81d100aeae..2801da49e2a36bfea53cf1fd5a084c51dbac42a6 100644 (file)
 #include <linux/of_platform.h>
 #include <linux/dma-mapping.h>
 #include <linux/irqchip.h>
-#include <linux/kexec.h>
+#include <asm/hardware/cache-feroceon-l2.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/map.h>
 #include <mach/bridge-regs.h>
 #include <plat/common.h>
-#include "common.h"
+#include <plat/pcie.h>
+#include "pm.h"
+
+static struct map_desc kirkwood_io_desc[] __initdata = {
+       {
+               .virtual        = (unsigned long) KIRKWOOD_REGS_VIRT_BASE,
+               .pfn            = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
+               .length         = KIRKWOOD_REGS_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void __init kirkwood_map_io(void)
+{
+       iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
+}
+
+static struct resource kirkwood_cpufreq_resources[] = {
+       [0] = {
+               .start  = CPU_CONTROL_PHYS,
+               .end    = CPU_CONTROL_PHYS + 3,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device kirkwood_cpufreq_device = {
+       .name           = "kirkwood-cpufreq",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(kirkwood_cpufreq_resources),
+       .resource       = kirkwood_cpufreq_resources,
+};
+
+static void __init kirkwood_cpufreq_init(void)
+{
+       platform_device_register(&kirkwood_cpufreq_device);
+}
+
+static struct resource kirkwood_cpuidle_resource[] = {
+       {
+               .flags  = IORESOURCE_MEM,
+               .start  = DDR_OPERATION_BASE,
+               .end    = DDR_OPERATION_BASE + 3,
+       },
+};
+
+static struct platform_device kirkwood_cpuidle = {
+       .name           = "kirkwood_cpuidle",
+       .id             = -1,
+       .resource       = kirkwood_cpuidle_resource,
+       .num_resources  = 1,
+};
+
+static void __init kirkwood_cpuidle_init(void)
+{
+       platform_device_register(&kirkwood_cpuidle);
+}
+
+/* Temporary here since mach-mvebu has a function we can use */
+static void kirkwood_restart(enum reboot_mode mode, const char *cmd)
+{
+       /*
+        * Enable soft reset to assert RSTOUTn.
+        */
+       writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+       /*
+        * Assert soft reset.
+        */
+       writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+       while (1)
+               ;
+}
 
 #define MV643XX_ETH_MAC_ADDR_LOW       0x0414
 #define MV643XX_ETH_MAC_ADDR_HIGH      0x0418
@@ -104,35 +177,35 @@ eth_fixup_skip:
        }
 }
 
-static void __init kirkwood_dt_init(void)
+/*
+ * Disable propagation of mbus errors to the CPU local bus, as this
+ * causes mbus errors (which can occur for example for PCI aborts) to
+ * throw CPU aborts, which we're not set up to deal with.
+ */
+static void __init kirkwood_disable_mbus_error_propagation(void)
 {
-       pr_info("Kirkwood: %s.\n", kirkwood_id());
+       void __iomem *cpu_config;
 
-       /*
-        * Disable propagation of mbus errors to the CPU local bus,
-        * as this causes mbus errors (which can occur for example
-        * for PCI aborts) to throw CPU aborts, which we're not set
-        * up to deal with.
-        */
-       writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+       cpu_config = ioremap(CPU_CONFIG_PHYS, 4);
+       writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config);
+       iounmap(cpu_config);
+}
 
-       BUG_ON(mvebu_mbus_dt_init());
+static void __init kirkwood_dt_init(void)
+{
+       kirkwood_disable_mbus_error_propagation();
 
-       kirkwood_l2_init();
+       BUG_ON(mvebu_mbus_dt_init());
 
+#ifdef CONFIG_CACHE_FEROCEON_L2
+       feroceon_of_init();
+#endif
        kirkwood_cpufreq_init();
        kirkwood_cpuidle_init();
 
        kirkwood_pm_init();
        kirkwood_dt_eth_fixup();
 
-#ifdef CONFIG_KEXEC
-       kexec_reinit = kirkwood_enable_pcie;
-#endif
-
-       if (of_machine_is_compatible("marvell,mv88f6281gtw-ge"))
-               mv88f6281gtw_ge_init();
-
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff --git a/arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c b/arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c
deleted file mode 100644 (file)
index ee5eea6..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/board-mv88f6281gtw_ge.c
- *
- * Marvell 88F6281 GTW GE Board Setup
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/timer.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/ethtool.h>
-#include <linux/gpio.h>
-#include <net/dsa.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
-#include <mach/kirkwood.h>
-#include "common.h"
-
-static struct mv643xx_eth_platform_data mv88f6281gtw_ge_ge00_data = {
-       .phy_addr       = MV643XX_ETH_PHY_NONE,
-       .speed          = SPEED_1000,
-       .duplex         = DUPLEX_FULL,
-};
-
-static struct dsa_chip_data mv88f6281gtw_ge_switch_chip_data = {
-       .port_names[0]  = "lan1",
-       .port_names[1]  = "lan2",
-       .port_names[2]  = "lan3",
-       .port_names[3]  = "lan4",
-       .port_names[4]  = "wan",
-       .port_names[5]  = "cpu",
-};
-
-static struct dsa_platform_data mv88f6281gtw_ge_switch_plat_data = {
-       .nr_chips       = 1,
-       .chip           = &mv88f6281gtw_ge_switch_chip_data,
-};
-
-void __init mv88f6281gtw_ge_init(void)
-{
-       kirkwood_ge00_init(&mv88f6281gtw_ge_ge00_data);
-       kirkwood_ge00_switch_init(&mv88f6281gtw_ge_switch_plat_data, NO_IRQ);
-}
index f3407a5db216498e6d30994c5fad8a872d2ac6b6..255f33a3903ccf7bd58fd4cce844d31f4492ad80 100644 (file)
 #include <asm/page.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
+#include <asm/hardware/cache-feroceon-l2.h>
 #include <mach/kirkwood.h>
 #include <mach/bridge-regs.h>
 #include <linux/platform_data/asoc-kirkwood.h>
-#include <plat/cache-feroceon-l2.h>
 #include <linux/platform_data/mmc-mvsdio.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 #include <linux/platform_data/usb-ehci-orion.h>
@@ -36,6 +36,7 @@
 #include <plat/time.h>
 #include <linux/platform_data/dma-mv_xor.h>
 #include "common.h"
+#include "pm.h"
 
 /* These can go away once Kirkwood uses the mvebu-mbus DT binding */
 #define KIRKWOOD_MBUS_NAND_TARGET 0x01
index 05fd648df543a669d393462e6b3d739cd6992421..832a4e2ab8d70b68ba8f22b8726177177578611b 100644 (file)
@@ -58,19 +58,6 @@ void kirkwood_cpufreq_init(void);
 void kirkwood_restart(enum reboot_mode, const char *);
 void kirkwood_clk_init(void);
 
-#ifdef CONFIG_PM
-void kirkwood_pm_init(void);
-#else
-static inline void kirkwood_pm_init(void) {};
-#endif
-
-/* board init functions for boards not fully converted to fdt */
-#ifdef CONFIG_MACH_MV88F6281GTW_GE_DT
-void mv88f6281gtw_ge_init(void);
-#else
-static inline void mv88f6281gtw_ge_init(void) {};
-#endif
-
 /* early init functions not converted to fdt yet */
 char *kirkwood_id(void);
 void kirkwood_l2_init(void);
index 8b9d1c9ff1996aa58da90edaa572700e794af73b..1c37082c8b39d5158b43938a83d5e0d0680642ac 100644 (file)
@@ -14,6 +14,7 @@
 #include <mach/kirkwood.h>
 
 #define CPU_CONFIG             (BRIDGE_VIRT_BASE + 0x0100)
+#define CPU_CONFIG_PHYS                (BRIDGE_PHYS_BASE + 0x0100)
 #define CPU_CONFIG_ERROR_PROP  0x00000004
 
 #define CPU_CONTROL            (BRIDGE_VIRT_BASE + 0x0104)
@@ -21,6 +22,7 @@
 #define CPU_RESET              0x00000002
 
 #define RSTOUTn_MASK           (BRIDGE_VIRT_BASE + 0x0108)
+#define RSTOUTn_MASK_PHYS      (BRIDGE_PHYS_BASE + 0x0108)
 #define SOFT_RESET_OUT_EN      0x00000004
 
 #define SYSTEM_SOFT_RESET      (BRIDGE_VIRT_BASE + 0x010c)
@@ -79,5 +81,6 @@
 #define CGC_RESERVED           (0x6 << 21)
 
 #define MEMORY_PM_CTRL         (BRIDGE_VIRT_BASE + 0x118)
+#define MEMORY_PM_CTRL_PHYS    (BRIDGE_PHYS_BASE + 0x118)
 
 #endif
diff --git a/arch/arm/mach-kirkwood/include/mach/timex.h b/arch/arm/mach-kirkwood/include/mach/timex.h
deleted file mode 100644 (file)
index c923cd1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/include/mach/timex.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#define CLOCK_TICK_RATE                (100 * HZ)
-
index c6ab8d9303a5b351937a8e3053f4394a6081e60f..8e5e0329d04c4d804259d9ba3faf8f37cc431b1c 100644 (file)
 #include "common.h"
 
 static void __iomem *ddr_operation_base;
+static void __iomem *memory_pm_ctrl;
 
 static void kirkwood_low_power(void)
 {
        u32 mem_pm_ctrl;
 
-       mem_pm_ctrl = readl(MEMORY_PM_CTRL);
+       mem_pm_ctrl = readl(memory_pm_ctrl);
 
        /* Set peripherals to low-power mode */
-       writel_relaxed(~0, MEMORY_PM_CTRL);
+       writel_relaxed(~0, memory_pm_ctrl);
 
        /* Set DDR in self-refresh */
        writel_relaxed(0x7, ddr_operation_base);
@@ -41,7 +42,7 @@ static void kirkwood_low_power(void)
         */
        cpu_do_idle();
 
-       writel_relaxed(mem_pm_ctrl, MEMORY_PM_CTRL);
+       writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
 }
 
 static int kirkwood_suspend_enter(suspend_state_t state)
@@ -69,5 +70,7 @@ static const struct platform_suspend_ops kirkwood_suspend_ops = {
 void __init kirkwood_pm_init(void)
 {
        ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
+       memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
+
        suspend_set_ops(&kirkwood_suspend_ops);
 }
diff --git a/arch/arm/mach-kirkwood/pm.h b/arch/arm/mach-kirkwood/pm.h
new file mode 100644 (file)
index 0000000..21e7530
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Power Management driver for Marvell Kirkwood SoCs
+ *
+ * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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 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 __ARCH_KIRKWOOD_PM_H
+#define __ARCH_KIRKWOOD_PM_H
+
+#ifdef CONFIG_PM
+void kirkwood_pm_init(void);
+#else
+static inline void kirkwood_pm_init(void) {};
+#endif
+
+#endif
index 002bc619bb686538eb06e0a6b9bc32abd3320c8d..f2658168eeff0d34072b2b1498881ded9aca766a 100644 (file)
@@ -44,7 +44,8 @@ static void __init og_register_pci(void)
        if (machine_is_im4004())
                ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_LOW);
 
-       ks8695_init_pci(&og_pci);
+       if (IS_ENABLED(CONFIG_PCI))
+               ks8695_init_pci(&og_pci);
 }
 
 /*
diff --git a/arch/arm/mach-ks8695/include/mach/timex.h b/arch/arm/mach-ks8695/include/mach/timex.h
deleted file mode 100644 (file)
index 10f7163..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/timex.h
- *
- * Copyright (C) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * KS8695 - Time Parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-#include <mach/hardware.h>
-
-#define CLOCK_TICK_RATE        KS8695_CLOCK_RATE
-
-#endif
index 426c97662f5b39372b3ab375ec51bc81b551b872..a197874bf382f68fb6ad1338f0fb23926bebe088 100644 (file)
@@ -122,7 +122,7 @@ static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction ks8695_timer_irq = {
        .name           = "ks8695_tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .flags          = IRQF_TIMER,
        .handler        = ks8695_timer_interrupt,
 };
 
index d7aa54c25c59ddc8b56cfefc7aeebb389bb95627..de03620d7fa71e7daf9018e2e3c9708ad079d9dc 100644 (file)
@@ -99,6 +99,7 @@ u32 lpc32xx_return_iram_size(void)
 
        return iram_size;
 }
+EXPORT_SYMBOL_GPL(lpc32xx_return_iram_size);
 
 /*
  * Computes PLL rate from PLL register and input clock
diff --git a/arch/arm/mach-lpc32xx/include/mach/timex.h b/arch/arm/mach-lpc32xx/include/mach/timex.h
deleted file mode 100644 (file)
index 8d4066b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/include/mach/timex.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/*
- * Rate in Hz of the main system oscillator. This value should match
- * the value 'MAIN_OSC_FREQ' in platform.h
- */
-#define CLOCK_TICK_RATE        13000000
-
-#endif
index 20eab63d10bae08359c18fbafff25c65d3075915..4e5837299c04dc5d4f9eb69b8ecf5fcc217cfc99 100644 (file)
@@ -90,7 +90,7 @@ static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction lpc32xx_timer_irq = {
        .name           = "LPC32XX Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = lpc32xx_timer_interrupt,
 };
 
index 0c002099c3a39e60babe8fffff9634322c8015e4..7e0248582efd340e358a87d652a1bfa7a5ee7404 100644 (file)
@@ -231,7 +231,7 @@ static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
        .debounce_interval      = 30,
 };
 
-#if defined(CONFIG_USB_EHCI_MV)
+#if IS_ENABLED(CONFIG_USB_EHCI_MV)
 static struct mv_usb_platform_data pxa168_sph_pdata = {
        .mode           = MV_USB_MODE_HOST,
        .phy_init       = pxa_usb_phy_init,
@@ -258,7 +258,7 @@ static void __init common_init(void)
        /* off-chip devices */
        platform_device_register(&smc91x_device);
 
-#if defined(CONFIG_USB_EHCI_MV)
+#if IS_ENABLED(CONFIG_USB_EHCI_MV)
        pxa168_add_usb_host(&pxa168_sph_pdata);
 #endif
 }
index dd2d8b103cc8e4416f3e6575524898548d104d4b..2bcb766af05db9c61cc084df16e9eb41bd8509eb 100644 (file)
@@ -72,7 +72,7 @@ int __init pxa_register_device(struct pxa_device_desc *desc,
        return platform_device_add(pdev);
 }
 
-#if defined(CONFIG_USB) || defined(CONFIG_USB_GADGET)
+#if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET)
 
 /*****************************************************************************
  * The registers read/write routines
@@ -112,9 +112,9 @@ static void u2o_write(void __iomem *base, unsigned int offset,
        readl_relaxed(base + offset);
 }
 
-#if defined(CONFIG_USB_MV_UDC) || defined(CONFIG_USB_EHCI_MV)
+#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
 
-#if defined(CONFIG_CPU_PXA910) || defined(CONFIG_CPU_PXA168)
+#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)
 
 static DEFINE_MUTEX(phy_lock);
 static int phy_init_cnt;
@@ -238,10 +238,10 @@ void pxa_usb_phy_deinit(void __iomem *phy_reg)
 #endif
 #endif
 
-#ifdef CONFIG_USB_SUPPORT
+#if IS_ENABLED(CONFIG_USB_SUPPORT)
 static u64 usb_dma_mask = ~(u32)0;
 
-#ifdef CONFIG_USB_MV_UDC
+#if IS_ENABLED(CONFIG_USB_MV_UDC)
 struct resource pxa168_u2o_resources[] = {
        /* regbase */
        [0] = {
@@ -276,7 +276,7 @@ struct platform_device pxa168_device_u2o = {
 };
 #endif /* CONFIG_USB_MV_UDC */
 
-#ifdef CONFIG_USB_EHCI_MV_U2O
+#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
 struct resource pxa168_u2oehci_resources[] = {
        /* regbase */
        [0] = {
@@ -312,7 +312,7 @@ struct platform_device pxa168_device_u2oehci = {
 };
 #endif
 
-#if defined(CONFIG_USB_MV_OTG)
+#if IS_ENABLED(CONFIG_USB_MV_OTG)
 struct resource pxa168_u2ootg_resources[] = {
        /* regbase */
        [0] = {
diff --git a/arch/arm/mach-mmp/include/mach/timex.h b/arch/arm/mach-mmp/include/mach/timex.h
deleted file mode 100644 (file)
index 70c9f1d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/timex.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifdef CONFIG_CPU_MMP2
-#define CLOCK_TICK_RATE                6500000
-#else
-#define CLOCK_TICK_RATE                3250000
-#endif
index 024022d91fe3e453dc4462fae847d12cb87dcdfa..2756351dbb35acac76190f3342a92e006d77c9d6 100644 (file)
 
 #include "clock.h"
 
+#ifdef CONFIG_CPU_MMP2
+#define MMP_CLOCK_FREQ         6500000
+#else
+#define MMP_CLOCK_FREQ         3250000
+#endif
+
 #define TIMERS_VIRT_BASE       TIMERS1_VIRT_BASE
 
 #define MAX_DELTA              (0xfffffffe)
@@ -186,7 +192,7 @@ static void __init timer_config(void)
 
 static struct irqaction timer_irq = {
        .name           = "timer",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = timer_interrupt,
        .dev_id         = &ckevt,
 };
@@ -195,14 +201,14 @@ void __init timer_init(int irq)
 {
        timer_config();
 
-       sched_clock_register(mmp_read_sched_clock, 32, CLOCK_TICK_RATE);
+       sched_clock_register(mmp_read_sched_clock, 32, MMP_CLOCK_FREQ);
 
        ckevt.cpumask = cpumask_of(0);
 
        setup_irq(irq, &timer_irq);
 
-       clocksource_register_hz(&cksrc, CLOCK_TICK_RATE);
-       clockevents_config_and_register(&ckevt, CLOCK_TICK_RATE,
+       clocksource_register_hz(&cksrc, MMP_CLOCK_FREQ);
+       clockevents_config_and_register(&ckevt, MMP_CLOCK_FREQ,
                                        MIN_DELTA, MAX_DELTA);
 }
 
index cfadd974f5ce060942b02a9eff015d322a381d82..ac4af81de3ea4a7313c7b853c2d5daa7528cae7b 100644 (file)
@@ -164,8 +164,8 @@ static struct i2c_board_info ttc_dkb_i2c_info[] = {
        },
 };
 
-#ifdef CONFIG_USB_SUPPORT
-#if defined(CONFIG_USB_MV_UDC) || defined(CONFIG_USB_EHCI_MV_U2O)
+#if IS_ENABLED(CONFIG_USB_SUPPORT)
+#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
 
 static struct mv_usb_platform_data ttc_usb_pdata = {
        .vbus           = NULL,
@@ -178,14 +178,14 @@ static struct mv_usb_platform_data ttc_usb_pdata = {
 #endif
 #endif
 
-#ifdef CONFIG_MTD_NAND_PXA3xx
+#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
 static struct pxa3xx_nand_platform_data dkb_nand_info = {
        .enable_arbiter = 1,
        .num_cs = 1,
 };
 #endif
 
-#ifdef CONFIG_MMP_DISP
+#if IS_ENABLED(CONFIG_MMP_DISP)
 /* path config */
 #define CFG_IOPADMODE(iopad)   (iopad)  /* 0x0 ~ 0xd */
 #define SCLK_SOURCE_SELECT(x)  (x << 30) /* 0x0 ~ 0x3 */
@@ -275,7 +275,7 @@ static void __init ttc_dkb_init(void)
 
        /* on-chip devices */
        pxa910_add_uart(1);
-#ifdef CONFIG_MTD_NAND_PXA3xx
+#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx)
        pxa910_add_nand(&dkb_nand_info);
 #endif
 
@@ -285,22 +285,22 @@ static void __init ttc_dkb_init(void)
                                 sizeof(struct pxa_gpio_platform_data));
        platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
 
-#ifdef CONFIG_USB_MV_UDC
+#if IS_ENABLED(CONFIG_USB_MV_UDC)
        pxa168_device_u2o.dev.platform_data = &ttc_usb_pdata;
        platform_device_register(&pxa168_device_u2o);
 #endif
 
-#ifdef CONFIG_USB_EHCI_MV_U2O
+#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
        pxa168_device_u2oehci.dev.platform_data = &ttc_usb_pdata;
        platform_device_register(&pxa168_device_u2oehci);
 #endif
 
-#ifdef CONFIG_USB_MV_OTG
+#if IS_ENABLED(CONFIG_USB_MV_OTG)
        pxa168_device_u2ootg.dev.platform_data = &ttc_usb_pdata;
        platform_device_register(&pxa168_device_u2ootg);
 #endif
 
-#ifdef CONFIG_MMP_DISP
+#if IS_ENABLED(CONFIG_MMP_DISP)
        add_disp();
 #endif
 }
index 3795ae28a6134637cf06226d2b50629ff5ad586c..82a4ba8578a23ce5fad77bcaa63eaee8e3ac5603 100644 (file)
@@ -1,15 +1,10 @@
 config ARCH_MOXART
-       bool "MOXA ART SoC" if ARCH_MULTI_V4T
+       bool "MOXA ART SoC" if ARCH_MULTI_V4
        select CPU_FA526
        select ARM_DMA_MEM_BUFFERABLE
-       select USE_OF
-       select CLKSRC_OF
        select CLKSRC_MMIO
-       select HAVE_CLK
-       select COMMON_CLK
        select GENERIC_IRQ_CHIP
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_CLOCKEVENTS
        select PHYLIB if NETDEVICES
        help
          Say Y here if you want to run your kernel on hardware with a
index 9625cf378931faa7b3e6740f963ac2128d7f92fe..a7f959e58c3d0c3432ae6bbf603db0ed7ef7320e 100644 (file)
@@ -1,50 +1,9 @@
-config ARCH_MSM
-       bool
-
-config ARCH_MSM_DT
-       bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
-       select ARCH_MSM
-       select ARCH_REQUIRE_GPIOLIB
-       select CLKSRC_OF
-       select GENERIC_CLOCKEVENTS
-       help
-         Support for Qualcomm's devicetree based MSM systems.
-
 if ARCH_MSM
 
-menu "Qualcomm MSM SoC Selection"
-       depends on ARCH_MSM_DT
-
-config ARCH_MSM8X60
-       bool "Enable support for MSM8X60"
-       select ARM_GIC
-       select CPU_V7
-       select HAVE_SMP
-       select MSM_SCM if SMP
-       select MSM_TIMER
-
-config ARCH_MSM8960
-       bool "Enable support for MSM8960"
-       select ARM_GIC
-       select CPU_V7
-       select HAVE_SMP
-       select MSM_SCM if SMP
-       select MSM_TIMER
-
-config ARCH_MSM8974
-       bool "Enable support for MSM8974"
-       select ARM_GIC
-       select CPU_V7
-       select HAVE_ARM_ARCH_TIMER
-       select HAVE_SMP
-       select MSM_SCM if SMP
-
-endmenu
-
 choice
        prompt "Qualcomm MSM SoC Type"
        default ARCH_MSM7X00A
-       depends on ARCH_MSM_NODT
+       depends on ARCH_MSM
 
 config ARCH_MSM7X00A
        bool "MSM7x00A / MSM7x01A"
@@ -54,7 +13,7 @@ config ARCH_MSM7X00A
        select MACH_TROUT if !MACH_HALIBUT
        select MSM_PROC_COMM
        select MSM_SMD
-       select MSM_TIMER
+       select CLKSRC_QCOM
        select MSM_SMD_PKG3
 
 config ARCH_MSM7X30
@@ -66,7 +25,7 @@ config ARCH_MSM7X30
        select MSM_GPIOMUX
        select MSM_PROC_COMM
        select MSM_SMD
-       select MSM_TIMER
+       select CLKSRC_QCOM
        select MSM_VIC
 
 config ARCH_QSD8X50
@@ -78,7 +37,7 @@ config ARCH_QSD8X50
        select MSM_GPIOMUX
        select MSM_PROC_COMM
        select MSM_SMD
-       select MSM_TIMER
+       select CLKSRC_QCOM
        select MSM_VIC
 
 endchoice
@@ -99,7 +58,7 @@ config  MSM_VIC
        bool
 
 menu "Qualcomm MSM Board Type"
-       depends on ARCH_MSM_NODT
+       depends on ARCH_MSM
 
 config MACH_HALIBUT
        depends on ARCH_MSM
@@ -153,7 +112,4 @@ config MSM_GPIOMUX
 config MSM_SCM
        bool
 
-config MSM_TIMER
-       bool
-
 endif
index 8e307a10d3c344a5dd2acb6900812baef9e4b43c..27c078a568dfae79a08da4baa3e47fe3b87cbd3e 100644 (file)
@@ -1,4 +1,3 @@
-obj-$(CONFIG_MSM_TIMER) += timer.o
 obj-$(CONFIG_MSM_PROC_COMM) += clock.o
 
 obj-$(CONFIG_MSM_VIC) += irq-vic.o
@@ -14,18 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
 
 obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
 obj-$(CONFIG_MSM_SMD) += last_radio_log.o
-obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
-
-CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-
-obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_SMP) += headsmp.o platsmp.o
 
 obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
 obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
 obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
 obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
deleted file mode 100644 (file)
index 1f11d93..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-
-static const char * const msm_dt_match[] __initconst = {
-       "qcom,msm8660-fluid",
-       "qcom,msm8660-surf",
-       "qcom,msm8960-cdp",
-       NULL
-};
-
-static const char * const apq8074_dt_match[] __initconst = {
-       "qcom,apq8074-dragonboard",
-       NULL
-};
-
-DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
-       .smp = smp_ops(msm_smp_ops),
-       .dt_compat = msm_dt_match,
-MACHINE_END
-
-DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
-       .dt_compat = apq8074_dt_match,
-MACHINE_END
index 33c7725adae2ffd5f885011c2bcd549030c159fd..572479a3c7be0d52c2a01f31d266ed266093d9a8 100644 (file)
@@ -23,9 +23,6 @@ extern void msm_map_qsd8x50_io(void);
 extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
                                          unsigned int mtype, void *caller);
 
-extern struct smp_operations msm_smp_ops;
-extern void msm_cpu_die(unsigned int cpu);
-
 struct msm_mmc_platform_data;
 
 extern void msm_add_devices(void);
index f8f6adfa07c68d42d60ce6fd8948c6e7283b799c..fb9762464718d3922812536d5c635991aba101f8 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/completion.h>
+#include <linux/module.h>
 #include <mach/dma.h>
 #include <mach/msm_iomap.h>
 
@@ -77,6 +78,7 @@ void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
 {
        writel((graceful << 31), DMOV_FLUSH0(id));
 }
+EXPORT_SYMBOL_GPL(msm_dmov_stop_cmd);
 
 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 {
@@ -115,6 +117,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
        }
        spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
 }
+EXPORT_SYMBOL_GPL(msm_dmov_enqueue_cmd);
 
 struct msm_dmov_exec_cmdptr_cmd {
        struct msm_dmov_cmd dmov_cmd;
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
deleted file mode 100644 (file)
index 6c62c3f..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/headsmp.S
- *
- *  Copyright (c) 2003 ARM Limited
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-/*
- * MSM specific entry point for secondary CPUs.  This provides
- * a "holding pen" into which all secondary cores are held until we're
- * ready for them to initialise.
- */
-ENTRY(msm_secondary_startup)
-       mrc     p15, 0, r0, c0, c0, 5
-       and     r0, r0, #15
-       adr     r4, 1f
-       ldmia   r4, {r5, r6}
-       sub     r4, r4, r5
-       add     r6, r6, r4
-pen:   ldr     r7, [r6]
-       cmp     r7, r0
-       bne     pen
-
-       /*
-        * we've been released from the holding pen: secondary_stack
-        * should now contain the SVC stack for this core
-        */
-       b       secondary_startup
-ENDPROC(msm_secondary_startup)
-
-       .align
-1:     .long   .
-       .long   pen_release
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
deleted file mode 100644 (file)
index 326a872..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-
-#include <asm/smp_plat.h>
-
-#include "common.h"
-
-static inline void cpu_enter_lowpower(void)
-{
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-}
-
-static inline void platform_do_lowpower(unsigned int cpu)
-{
-       /* Just enter wfi for now. TODO: Properly shut off the cpu. */
-       for (;;) {
-               /*
-                * here's the WFI
-                */
-               asm("wfi"
-                   :
-                   :
-                   : "memory", "cc");
-
-               if (pen_release == cpu_logical_map(cpu)) {
-                       /*
-                        * OK, proper wakeup, we're done
-                        */
-                       break;
-               }
-
-               /*
-                * getting here, means that we have come out of WFI without
-                * having been woken up - this shouldn't happen
-                *
-                * The trouble is, letting people know about this is not really
-                * possible, since we are currently running incoherently, and
-                * therefore cannot safely call printk() or anything else
-                */
-               pr_debug("CPU%u: spurious wakeup call\n", cpu);
-       }
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void __ref msm_cpu_die(unsigned int cpu)
-{
-       /*
-        * we're ready for shutdown now, so do it
-        */
-       cpu_enter_lowpower();
-       platform_do_lowpower(cpu);
-
-       /*
-        * bring this CPU back into the world of cache
-        * coherency, and then restore interrupts
-        */
-       cpu_leave_lowpower();
-}
diff --git a/arch/arm/mach-msm/include/mach/timex.h b/arch/arm/mach-msm/include/mach/timex.h
deleted file mode 100644 (file)
index a62e6b2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* arch/arm/mach-msm/include/mach/timex.h
- *
- * Copyright (C) 2007 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.
- *
- */
-
-#ifndef __ASM_ARCH_MSM_TIMEX_H
-#define __ASM_ARCH_MSM_TIMEX_H
-
-#define CLOCK_TICK_RATE                1000000
-
-#endif
index adc8971c726640444d3fa7e14decd81ccac4d750..34e09474636ddeead9dbec440f9991ea54b04e53 100644 (file)
@@ -78,8 +78,10 @@ void __init msm_map_common_io(void)
        asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
 #if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
                defined(CONFIG_DEBUG_MSM_UART3)
+#ifdef CONFIG_MMU
        debug_ll_addr(&msm_io_desc[size - 1].pfn,
                      &msm_io_desc[size - 1].virtual);
+#endif
        msm_io_desc[size - 1].pfn = __phys_to_pfn(msm_io_desc[size - 1].pfn);
 #endif
        iotable_init(msm_io_desc, size);
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
deleted file mode 100644 (file)
index f10a1f5..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *  Copyright (c) 2010, Code Aurora Forum. 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/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/cacheflush.h>
-#include <asm/cputype.h>
-#include <asm/mach-types.h>
-#include <asm/smp_plat.h>
-
-#include "scm-boot.h"
-#include "common.h"
-
-#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
-#define SCSS_CPU1CORE_RESET 0xD80
-#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-
-extern void msm_secondary_startup(void);
-
-static DEFINE_SPINLOCK(boot_lock);
-
-static inline int get_core_count(void)
-{
-       /* 1 + the PART[1:0] field of MIDR */
-       return ((read_cpuid_id() >> 4) & 3) + 1;
-}
-
-static void msm_secondary_init(unsigned int cpu)
-{
-       /*
-        * let the primary processor know we're out of the
-        * pen, then head off into the C entry point
-        */
-       pen_release = -1;
-       smp_wmb();
-
-       /*
-        * Synchronise with the boot thread.
-        */
-       spin_lock(&boot_lock);
-       spin_unlock(&boot_lock);
-}
-
-static void prepare_cold_cpu(unsigned int cpu)
-{
-       int ret;
-       ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
-                               SCM_FLAG_COLDBOOT_CPU1);
-       if (ret == 0) {
-               void __iomem *sc1_base_ptr;
-               sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
-               if (sc1_base_ptr) {
-                       writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-                       writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
-                       writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
-                       iounmap(sc1_base_ptr);
-               }
-       } else
-               printk(KERN_DEBUG "Failed to set secondary core boot "
-                                 "address\n");
-}
-
-static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       unsigned long timeout;
-       static int cold_boot_done;
-
-       /* Only need to bring cpu out of reset this way once */
-       if (cold_boot_done == false) {
-               prepare_cold_cpu(cpu);
-               cold_boot_done = true;
-       }
-
-       /*
-        * set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       spin_lock(&boot_lock);
-
-       /*
-        * The secondary processor is waiting to be released from
-        * the holding pen - release it, then wait for it to flag
-        * that it has been released by resetting pen_release.
-        *
-        * Note that "pen_release" is the hardware CPU ID, whereas
-        * "cpu" is Linux's internal ID.
-        */
-       pen_release = cpu_logical_map(cpu);
-       sync_cache_w(&pen_release);
-
-       /*
-        * Send the secondary CPU a soft interrupt, thereby causing
-        * the boot monitor to read the system wide flags register,
-        * and branch to the address found there.
-        */
-       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-
-       timeout = jiffies + (1 * HZ);
-       while (time_before(jiffies, timeout)) {
-               smp_rmb();
-               if (pen_release == -1)
-                       break;
-
-               udelay(10);
-       }
-
-       /*
-        * now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
-        */
-       spin_unlock(&boot_lock);
-
-       return pen_release != -1 ? -ENOSYS : 0;
-}
-
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system. The msm8x60
- * does not support the ARM SCU, so just set the possible cpu mask to
- * NR_CPUS.
- */
-static void __init msm_smp_init_cpus(void)
-{
-       unsigned int i, ncores = get_core_count();
-
-       if (ncores > nr_cpu_ids) {
-               pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-                       ncores, nr_cpu_ids);
-               ncores = nr_cpu_ids;
-       }
-
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
-}
-
-static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-{
-}
-
-struct smp_operations msm_smp_ops __initdata = {
-       .smp_init_cpus          = msm_smp_init_cpus,
-       .smp_prepare_cpus       = msm_smp_prepare_cpus,
-       .smp_secondary_init     = msm_secondary_init,
-       .smp_boot_secondary     = msm_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
-       .cpu_die                = msm_cpu_die,
-#endif
-};
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
deleted file mode 100644 (file)
index 45cee3e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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.
- *
- * 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/module.h>
-#include <linux/slab.h>
-
-#include "scm.h"
-#include "scm-boot.h"
-
-/*
- * Set the cold/warm boot address for one of the CPU cores.
- */
-int scm_set_boot_addr(phys_addr_t addr, int flags)
-{
-       struct {
-               unsigned int flags;
-               phys_addr_t  addr;
-       } cmd;
-
-       cmd.addr = addr;
-       cmd.flags = flags;
-       return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
-                       &cmd, sizeof(cmd), NULL, 0);
-}
-EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
deleted file mode 100644 (file)
index 7be32ff..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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.
- */
-#ifndef __MACH_SCM_BOOT_H
-#define __MACH_SCM_BOOT_H
-
-#define SCM_BOOT_ADDR                  0x1
-#define SCM_FLAG_COLDBOOT_CPU1         0x1
-#define SCM_FLAG_WARMBOOT_CPU1         0x2
-#define SCM_FLAG_WARMBOOT_CPU0         0x4
-
-int scm_set_boot_addr(phys_addr_t addr, int flags);
-
-#endif
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
deleted file mode 100644 (file)
index c536fd6..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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.
- *
- * 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/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-
-#include <asm/cacheflush.h>
-
-#include "scm.h"
-
-/* Cache line size for msm8x60 */
-#define CACHELINESIZE 32
-
-#define SCM_ENOMEM             -5
-#define SCM_EOPNOTSUPP         -4
-#define SCM_EINVAL_ADDR                -3
-#define SCM_EINVAL_ARG         -2
-#define SCM_ERROR              -1
-#define SCM_INTERRUPTED                1
-
-static DEFINE_MUTEX(scm_lock);
-
-/**
- * struct scm_command - one SCM command buffer
- * @len: total available memory for command and response
- * @buf_offset: start of command buffer
- * @resp_hdr_offset: start of response buffer
- * @id: command to be executed
- * @buf: buffer returned from scm_get_command_buffer()
- *
- * An SCM command is laid out in memory as follows:
- *
- *     ------------------- <--- struct scm_command
- *     | command header  |
- *     ------------------- <--- scm_get_command_buffer()
- *     | command buffer  |
- *     ------------------- <--- struct scm_response and
- *     | response header |      scm_command_to_response()
- *     ------------------- <--- scm_get_response_buffer()
- *     | response buffer |
- *     -------------------
- *
- * There can be arbitrary padding between the headers and buffers so
- * you should always use the appropriate scm_get_*_buffer() routines
- * to access the buffers in a safe manner.
- */
-struct scm_command {
-       u32     len;
-       u32     buf_offset;
-       u32     resp_hdr_offset;
-       u32     id;
-       u32     buf[0];
-};
-
-/**
- * struct scm_response - one SCM response buffer
- * @len: total available memory for response
- * @buf_offset: start of response data relative to start of scm_response
- * @is_complete: indicates if the command has finished processing
- */
-struct scm_response {
-       u32     len;
-       u32     buf_offset;
-       u32     is_complete;
-};
-
-/**
- * alloc_scm_command() - Allocate an SCM command
- * @cmd_size: size of the command buffer
- * @resp_size: size of the response buffer
- *
- * Allocate an SCM command, including enough room for the command
- * and response headers as well as the command and response buffers.
- *
- * Returns a valid &scm_command on success or %NULL if the allocation fails.
- */
-static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
-{
-       struct scm_command *cmd;
-       size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
-               resp_size;
-
-       cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
-       if (cmd) {
-               cmd->len = len;
-               cmd->buf_offset = offsetof(struct scm_command, buf);
-               cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
-       }
-       return cmd;
-}
-
-/**
- * free_scm_command() - Free an SCM command
- * @cmd: command to free
- *
- * Free an SCM command.
- */
-static inline void free_scm_command(struct scm_command *cmd)
-{
-       kfree(cmd);
-}
-
-/**
- * scm_command_to_response() - Get a pointer to a scm_response
- * @cmd: command
- *
- * Returns a pointer to a response for a command.
- */
-static inline struct scm_response *scm_command_to_response(
-               const struct scm_command *cmd)
-{
-       return (void *)cmd + cmd->resp_hdr_offset;
-}
-
-/**
- * scm_get_command_buffer() - Get a pointer to a command buffer
- * @cmd: command
- *
- * Returns a pointer to the command buffer of a command.
- */
-static inline void *scm_get_command_buffer(const struct scm_command *cmd)
-{
-       return (void *)cmd->buf;
-}
-
-/**
- * scm_get_response_buffer() - Get a pointer to a response buffer
- * @rsp: response
- *
- * Returns a pointer to a response buffer of a response.
- */
-static inline void *scm_get_response_buffer(const struct scm_response *rsp)
-{
-       return (void *)rsp + rsp->buf_offset;
-}
-
-static int scm_remap_error(int err)
-{
-       switch (err) {
-       case SCM_ERROR:
-               return -EIO;
-       case SCM_EINVAL_ADDR:
-       case SCM_EINVAL_ARG:
-               return -EINVAL;
-       case SCM_EOPNOTSUPP:
-               return -EOPNOTSUPP;
-       case SCM_ENOMEM:
-               return -ENOMEM;
-       }
-       return -EINVAL;
-}
-
-static u32 smc(u32 cmd_addr)
-{
-       int context_id;
-       register u32 r0 asm("r0") = 1;
-       register u32 r1 asm("r1") = (u32)&context_id;
-       register u32 r2 asm("r2") = cmd_addr;
-       do {
-               asm volatile(
-                       __asmeq("%0", "r0")
-                       __asmeq("%1", "r0")
-                       __asmeq("%2", "r1")
-                       __asmeq("%3", "r2")
-#ifdef REQUIRES_SEC
-                       ".arch_extension sec\n"
-#endif
-                       "smc    #0      @ switch to secure world\n"
-                       : "=r" (r0)
-                       : "r" (r0), "r" (r1), "r" (r2)
-                       : "r3");
-       } while (r0 == SCM_INTERRUPTED);
-
-       return r0;
-}
-
-static int __scm_call(const struct scm_command *cmd)
-{
-       int ret;
-       u32 cmd_addr = virt_to_phys(cmd);
-
-       /*
-        * Flush the entire cache here so callers don't have to remember
-        * to flush the cache when passing physical addresses to the secure
-        * side in the buffer.
-        */
-       flush_cache_all();
-       ret = smc(cmd_addr);
-       if (ret < 0)
-               ret = scm_remap_error(ret);
-
-       return ret;
-}
-
-/**
- * scm_call() - Send an SCM command
- * @svc_id: service identifier
- * @cmd_id: command identifier
- * @cmd_buf: command buffer
- * @cmd_len: length of the command buffer
- * @resp_buf: response buffer
- * @resp_len: length of the response buffer
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- */
-int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-               void *resp_buf, size_t resp_len)
-{
-       int ret;
-       struct scm_command *cmd;
-       struct scm_response *rsp;
-
-       cmd = alloc_scm_command(cmd_len, resp_len);
-       if (!cmd)
-               return -ENOMEM;
-
-       cmd->id = (svc_id << 10) | cmd_id;
-       if (cmd_buf)
-               memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
-
-       mutex_lock(&scm_lock);
-       ret = __scm_call(cmd);
-       mutex_unlock(&scm_lock);
-       if (ret)
-               goto out;
-
-       rsp = scm_command_to_response(cmd);
-       do {
-               u32 start = (u32)rsp;
-               u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
-               start &= ~(CACHELINESIZE - 1);
-               while (start < end) {
-                       asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
-                            : "memory");
-                       start += CACHELINESIZE;
-               }
-       } while (!rsp->is_complete);
-
-       if (resp_buf)
-               memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
-out:
-       free_scm_command(cmd);
-       return ret;
-}
-EXPORT_SYMBOL(scm_call);
-
-u32 scm_get_version(void)
-{
-       int context_id;
-       static u32 version = -1;
-       register u32 r0 asm("r0");
-       register u32 r1 asm("r1");
-
-       if (version != -1)
-               return version;
-
-       mutex_lock(&scm_lock);
-
-       r0 = 0x1 << 8;
-       r1 = (u32)&context_id;
-       do {
-               asm volatile(
-                       __asmeq("%0", "r0")
-                       __asmeq("%1", "r1")
-                       __asmeq("%2", "r0")
-                       __asmeq("%3", "r1")
-#ifdef REQUIRES_SEC
-                       ".arch_extension sec\n"
-#endif
-                       "smc    #0      @ switch to secure world\n"
-                       : "=r" (r0), "=r" (r1)
-                       : "r" (r0), "r" (r1)
-                       : "r2", "r3");
-       } while (r0 == SCM_INTERRUPTED);
-
-       version = r1;
-       mutex_unlock(&scm_lock);
-
-       return version;
-}
-EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-msm/scm.h
deleted file mode 100644 (file)
index 00b31ea..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. 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.
- */
-#ifndef __MACH_SCM_H
-#define __MACH_SCM_H
-
-#define SCM_SVC_BOOT                   0x1
-#define SCM_SVC_PIL                    0x2
-
-extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-               void *resp_buf, size_t resp_len);
-
-#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
-
-extern u32 scm_get_version(void);
-
-#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
deleted file mode 100644 (file)
index fd16449..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
- *
- * 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.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cpu.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/sched_clock.h>
-
-#include <asm/mach/time.h>
-
-#include "common.h"
-
-#define TIMER_MATCH_VAL                        0x0000
-#define TIMER_COUNT_VAL                        0x0004
-#define TIMER_ENABLE                   0x0008
-#define TIMER_ENABLE_CLR_ON_MATCH_EN   BIT(1)
-#define TIMER_ENABLE_EN                        BIT(0)
-#define TIMER_CLEAR                    0x000C
-#define DGT_CLK_CTL                    0x10
-#define DGT_CLK_CTL_DIV_4              0x3
-#define TIMER_STS_GPT0_CLR_PEND                BIT(10)
-
-#define GPT_HZ 32768
-
-#define MSM_DGT_SHIFT 5
-
-static void __iomem *event_base;
-static void __iomem *sts_base;
-
-static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = dev_id;
-       /* Stop the timer tick */
-       if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
-               u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-               ctrl &= ~TIMER_ENABLE_EN;
-               writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-       }
-       evt->event_handler(evt);
-       return IRQ_HANDLED;
-}
-
-static int msm_timer_set_next_event(unsigned long cycles,
-                                   struct clock_event_device *evt)
-{
-       u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-
-       ctrl &= ~TIMER_ENABLE_EN;
-       writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-
-       writel_relaxed(ctrl, event_base + TIMER_CLEAR);
-       writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
-
-       if (sts_base)
-               while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
-                       cpu_relax();
-
-       writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
-       return 0;
-}
-
-static void msm_timer_set_mode(enum clock_event_mode mode,
-                             struct clock_event_device *evt)
-{
-       u32 ctrl;
-
-       ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-       ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_RESUME:
-       case CLOCK_EVT_MODE_PERIODIC:
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* Timer is enabled in set_next_event */
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-               break;
-       }
-       writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-}
-
-static struct clock_event_device __percpu *msm_evt;
-
-static void __iomem *source_base;
-
-static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
-{
-       return readl_relaxed(source_base + TIMER_COUNT_VAL);
-}
-
-static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-{
-       /*
-        * Shift timer count down by a constant due to unreliable lower bits
-        * on some targets.
-        */
-       return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-}
-
-static struct clocksource msm_clocksource = {
-       .name   = "dg_timer",
-       .rating = 300,
-       .read   = msm_read_timer_count,
-       .mask   = CLOCKSOURCE_MASK(32),
-       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int msm_timer_irq;
-static int msm_timer_has_ppi;
-
-static int msm_local_timer_setup(struct clock_event_device *evt)
-{
-       int cpu = smp_processor_id();
-       int err;
-
-       evt->irq = msm_timer_irq;
-       evt->name = "msm_timer";
-       evt->features = CLOCK_EVT_FEAT_ONESHOT;
-       evt->rating = 200;
-       evt->set_mode = msm_timer_set_mode;
-       evt->set_next_event = msm_timer_set_next_event;
-       evt->cpumask = cpumask_of(cpu);
-
-       clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
-
-       if (msm_timer_has_ppi) {
-               enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
-       } else {
-               err = request_irq(evt->irq, msm_timer_interrupt,
-                               IRQF_TIMER | IRQF_NOBALANCING |
-                               IRQF_TRIGGER_RISING, "gp_timer", evt);
-               if (err)
-                       pr_err("request_irq failed\n");
-       }
-
-       return 0;
-}
-
-static void msm_local_timer_stop(struct clock_event_device *evt)
-{
-       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-       disable_percpu_irq(evt->irq);
-}
-
-static int msm_timer_cpu_notify(struct notifier_block *self,
-                                          unsigned long action, void *hcpu)
-{
-       /*
-        * Grab cpu pointer in each case to avoid spurious
-        * preemptible warnings
-        */
-       switch (action & ~CPU_TASKS_FROZEN) {
-       case CPU_STARTING:
-               msm_local_timer_setup(this_cpu_ptr(msm_evt));
-               break;
-       case CPU_DYING:
-               msm_local_timer_stop(this_cpu_ptr(msm_evt));
-               break;
-       }
-
-       return NOTIFY_OK;
-}
-
-static struct notifier_block msm_timer_cpu_nb = {
-       .notifier_call = msm_timer_cpu_notify,
-};
-
-static u64 notrace msm_sched_clock_read(void)
-{
-       return msm_clocksource.read(&msm_clocksource);
-}
-
-static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
-                                 bool percpu)
-{
-       struct clocksource *cs = &msm_clocksource;
-       int res = 0;
-
-       msm_timer_irq = irq;
-       msm_timer_has_ppi = percpu;
-
-       msm_evt = alloc_percpu(struct clock_event_device);
-       if (!msm_evt) {
-               pr_err("memory allocation failed for clockevents\n");
-               goto err;
-       }
-
-       if (percpu)
-               res = request_percpu_irq(irq, msm_timer_interrupt,
-                                        "gp_timer", msm_evt);
-
-       if (res) {
-               pr_err("request_percpu_irq failed\n");
-       } else {
-               res = register_cpu_notifier(&msm_timer_cpu_nb);
-               if (res) {
-                       free_percpu_irq(irq, msm_evt);
-                       goto err;
-               }
-
-               /* Immediately configure the timer on the boot CPU */
-               msm_local_timer_setup(__this_cpu_ptr(msm_evt));
-       }
-
-err:
-       writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
-       res = clocksource_register_hz(cs, dgt_hz);
-       if (res)
-               pr_err("clocksource_register failed\n");
-       sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
-}
-
-#ifdef CONFIG_OF
-static void __init msm_dt_timer_init(struct device_node *np)
-{
-       u32 freq;
-       int irq;
-       struct resource res;
-       u32 percpu_offset;
-       void __iomem *base;
-       void __iomem *cpu0_base;
-
-       base = of_iomap(np, 0);
-       if (!base) {
-               pr_err("Failed to map event base\n");
-               return;
-       }
-
-       /* We use GPT0 for the clockevent */
-       irq = irq_of_parse_and_map(np, 1);
-       if (irq <= 0) {
-               pr_err("Can't get irq\n");
-               return;
-       }
-
-       /* We use CPU0's DGT for the clocksource */
-       if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
-               percpu_offset = 0;
-
-       if (of_address_to_resource(np, 0, &res)) {
-               pr_err("Failed to parse DGT resource\n");
-               return;
-       }
-
-       cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
-       if (!cpu0_base) {
-               pr_err("Failed to map source base\n");
-               return;
-       }
-
-       if (of_property_read_u32(np, "clock-frequency", &freq)) {
-               pr_err("Unknown frequency\n");
-               return;
-       }
-
-       event_base = base + 0x4;
-       sts_base = base + 0x88;
-       source_base = cpu0_base + 0x24;
-       freq /= 4;
-       writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
-
-       msm_timer_init(freq, 32, irq, !!percpu_offset);
-}
-CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
-CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
-#endif
-
-static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
-                               u32 sts)
-{
-       void __iomem *base;
-
-       base = ioremap(addr, SZ_256);
-       if (!base) {
-               pr_err("Failed to map timer base\n");
-               return -ENOMEM;
-       }
-       event_base = base + event;
-       source_base = base + source;
-       if (sts)
-               sts_base = base + sts;
-
-       return 0;
-}
-
-void __init msm7x01_timer_init(void)
-{
-       struct clocksource *cs = &msm_clocksource;
-
-       if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
-               return;
-       cs->read = msm_read_timer_count_shift;
-       cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
-       /* 600 KHz */
-       msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
-                       false);
-}
-
-void __init msm7x30_timer_init(void)
-{
-       if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
-               return;
-       msm_timer_init(24576000 / 4, 32, 1, false);
-}
-
-void __init qsd8x50_timer_init(void)
-{
-       if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
-               return;
-       msm_timer_init(19200000 / 4, 32, 7, false);
-}
index 75062eff2494005cbc6f8537b434feaf737597d6..e6ac679bece9fab3b845ed909dd8475c1359f561 100644 (file)
 #include <linux/ata_platform.h>
 #include <linux/clk-provider.h>
 #include <linux/ethtool.h>
+#include <asm/hardware/cache-feroceon-l2.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <mach/mv78xx0.h>
 #include <mach/bridge-regs.h>
-#include <plat/cache-feroceon-l2.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 #include <plat/time.h>
index 5f03484584d4e1aed603b3df15cf23b7cbced792..e20d6da234a65b439499c4846de6e58d1e9b8eb8 100644 (file)
@@ -15,6 +15,7 @@
 #define L2_WRITETHROUGH                0x00020000
 
 #define RSTOUTn_MASK           (BRIDGE_VIRT_BASE + 0x0108)
+#define RSTOUTn_MASK_PHYS      (BRIDGE_PHYS_BASE + 0x0108)
 #define SOFT_RESET_OUT_EN      0x00000004
 
 #define SYSTEM_SOFT_RESET      (BRIDGE_VIRT_BASE + 0x010c)
diff --git a/arch/arm/mach-mv78xx0/include/mach/timex.h b/arch/arm/mach-mv78xx0/include/mach/timex.h
deleted file mode 100644 (file)
index 0e8c443..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/timex.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#define CLOCK_TICK_RATE                (100 * HZ)
index df9e7d270810aeb7c227812b473f243cea9a88d8..3f73eecbcfb033d3370ad41642f7fe95b9d948b9 100644 (file)
@@ -1,16 +1,11 @@
 config ARCH_MVEBU
-       bool "Marvell SOCs with Device Tree support" if ARCH_MULTI_V7
+       bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5)
        select ARCH_SUPPORTS_BIG_ENDIAN
        select CLKSRC_MMIO
-       select COMMON_CLK
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
        select IRQ_DOMAIN
-       select MULTI_IRQ_HANDLER
        select PINCTRL
        select PLAT_ORION
-       select SPARSE_IRQ
-       select CLKDEV_LOOKUP
        select MVEBU_MBUS
        select ZONE_DMA if ARM_LPAE
        select ARCH_REQUIRE_GPIOLIB
@@ -20,33 +15,95 @@ config ARCH_MVEBU
 
 if ARCH_MVEBU
 
-menu "Marvell SOC with device tree"
+menu "Marvell EBU SoC variants"
 
-config MACH_ARMADA_370_XP
+config MACH_MVEBU_V7
        bool
        select ARMADA_370_XP_TIMER
-       select HAVE_SMP
        select CACHE_L2X0
-       select CPU_PJ4B
 
 config MACH_ARMADA_370
-       bool "Marvell Armada 370 boards"
+       bool "Marvell Armada 370 boards" if ARCH_MULTI_V7
        select ARMADA_370_CLK
-       select MACH_ARMADA_370_XP
+       select CPU_PJ4B
+       select MACH_MVEBU_V7
        select PINCTRL_ARMADA_370
        help
          Say 'Y' here if you want your kernel to support boards based
          on the Marvell Armada 370 SoC with device tree.
 
+config MACH_ARMADA_375
+       bool "Marvell Armada 375 boards" if ARCH_MULTI_V7
+       select ARM_ERRATA_720789
+       select ARM_ERRATA_753970
+       select ARM_GIC
+       select ARMADA_375_CLK
+       select CPU_V7
+       select MACH_MVEBU_V7
+       select PINCTRL_ARMADA_375
+       help
+         Say 'Y' here if you want your kernel to support boards based
+         on the Marvell Armada 375 SoC with device tree.
+
+config MACH_ARMADA_38X
+       bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
+       select ARM_ERRATA_720789
+       select ARM_ERRATA_753970
+       select ARM_GIC
+       select ARMADA_38X_CLK
+       select CPU_V7
+       select MACH_MVEBU_V7
+       select PINCTRL_ARMADA_38X
+       help
+         Say 'Y' here if you want your kernel to support boards based
+         on the Marvell Armada 380/385 SoC with device tree.
+
 config MACH_ARMADA_XP
-       bool "Marvell Armada XP boards"
+       bool "Marvell Armada XP boards" if ARCH_MULTI_V7
        select ARMADA_XP_CLK
-       select MACH_ARMADA_370_XP
+       select CPU_PJ4B
+       select MACH_MVEBU_V7
        select PINCTRL_ARMADA_XP
        help
          Say 'Y' here if you want your kernel to support boards based
          on the Marvell Armada XP SoC with device tree.
 
+config MACH_DOVE
+       bool "Marvell Dove boards" if ARCH_MULTI_V7
+       select CACHE_L2X0
+       select CPU_PJ4
+       select DOVE_CLK
+       select ORION_IRQCHIP
+       select ORION_TIMER
+       select PINCTRL_DOVE
+       help
+         Say 'Y' here if you want your kernel to support the
+         Marvell Dove using flattened device tree.
+
+config MACH_KIRKWOOD
+       bool "Marvell Kirkwood boards" if ARCH_MULTI_V5
+       select ARCH_HAS_CPUFREQ
+       select ARCH_REQUIRE_GPIOLIB
+       select CPU_FEROCEON
+       select KIRKWOOD_CLK
+       select OF_IRQ
+       select ORION_IRQCHIP
+       select ORION_TIMER
+       select PCI
+       select PCI_QUIRKS
+       select PINCTRL_KIRKWOOD
+       select USE_OF
+       help
+         Say 'Y' here if you want your kernel to support boards based
+         on the Marvell Kirkwood device tree.
+
+config MACH_T5325
+       bool "HP T5325 thin client"
+       depends on MACH_KIRKWOOD
+       help
+         Say 'Y' here if you want your kernel to support the
+         HP T5325 Thin client
+
 endmenu
 
 endif
index 878aebe98dcc817029732847f6b2fb39880f8ba2..a63e43b6b451e24c1aba904006f9d5a3c636a47d 100644 (file)
@@ -4,7 +4,10 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
 AFLAGS_coherency_ll.o          := -Wa,-march=armv7-a
 
 obj-y                           += system-controller.o mvebu-soc-id.o
-obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o
+obj-$(CONFIG_MACH_MVEBU_V7)      += board-v7.o
+obj-$(CONFIG_MACH_DOVE)                 += dove.o
 obj-$(CONFIG_ARCH_MVEBU)        += coherency.o coherency_ll.o pmsu.o
 obj-$(CONFIG_SMP)                += platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)        += hotplug.o
+obj-$(CONFIG_MACH_KIRKWOOD)     += kirkwood.o kirkwood-pm.o
+obj-$(CONFIG_MACH_T5325)        += board-t5325.o
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
deleted file mode 100644 (file)
index f6c9d1d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Device Tree support for Armada 370 and XP platforms.
- *
- * Copyright (C) 2012 Marvell
- *
- * Lior Amsalem <alior@marvell.com>
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- * 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>
-#include <linux/init.h>
-#include <linux/clk-provider.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/io.h>
-#include <linux/clocksource.h>
-#include <linux/dma-mapping.h>
-#include <linux/mbus.h>
-#include <linux/slab.h>
-#include <asm/hardware/cache-l2x0.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
-#include "armada-370-xp.h"
-#include "common.h"
-#include "coherency.h"
-#include "mvebu-soc-id.h"
-
-static void __init armada_370_xp_map_io(void)
-{
-       debug_ll_io_init();
-}
-
-static void __init armada_370_xp_timer_and_clk_init(void)
-{
-       of_clk_init(NULL);
-       clocksource_of_init();
-       coherency_init();
-       BUG_ON(mvebu_mbus_dt_init());
-#ifdef CONFIG_CACHE_L2X0
-       l2x0_of_init(0, ~0UL);
-#endif
-}
-
-static void __init i2c_quirk(void)
-{
-       struct device_node *np;
-       u32 dev, rev;
-
-       /*
-        * Only revisons more recent than A0 support the offload
-        * mechanism. We can exit only if we are sure that we can
-        * get the SoC revision and it is more recent than A0.
-        */
-       if (mvebu_get_soc_id(&rev, &dev) == 0 && dev > MV78XX0_A0_REV)
-               return;
-
-       for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") {
-               struct property *new_compat;
-
-               new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
-
-               new_compat->name = kstrdup("compatible", GFP_KERNEL);
-               new_compat->length = sizeof("marvell,mv78230-a0-i2c");
-               new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
-                                               GFP_KERNEL);
-
-               of_update_property(np, new_compat);
-       }
-       return;
-}
-
-static void __init armada_370_xp_dt_init(void)
-{
-       if (of_machine_is_compatible("plathome,openblocks-ax3-4"))
-               i2c_quirk();
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const armada_370_xp_dt_compat[] = {
-       "marvell,armada-370-xp",
-       NULL,
-};
-
-DT_MACHINE_START(ARMADA_XP_DT, "Marvell Armada 370/XP (Device Tree)")
-       .smp            = smp_ops(armada_xp_smp_ops),
-       .init_machine   = armada_370_xp_dt_init,
-       .map_io         = armada_370_xp_map_io,
-       .init_time      = armada_370_xp_timer_and_clk_init,
-       .restart        = mvebu_restart,
-       .dt_compat      = armada_370_xp_dt_compat,
-MACHINE_END
diff --git a/arch/arm/mach-mvebu/board-t5325.c b/arch/arm/mach-mvebu/board-t5325.c
new file mode 100644 (file)
index 0000000..65ace6d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * HP T5325 Board Setup
+ *
+ * Copyright (C) 2014
+ *
+ * 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>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <sound/alc5623.h>
+#include "board.h"
+
+static struct platform_device hp_t5325_audio_device = {
+       .name           = "t5325-audio",
+       .id             = -1,
+};
+
+static struct alc5623_platform_data alc5621_data = {
+       .add_ctrl = 0x3700,
+       .jack_det_ctrl = 0x4810,
+};
+
+static struct i2c_board_info i2c_board_info[] __initdata = {
+       {
+               I2C_BOARD_INFO("alc5621", 0x1a),
+               .platform_data = &alc5621_data,
+       },
+};
+
+void __init t5325_init(void)
+{
+       i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info));
+       platform_device_register(&hp_t5325_audio_device);
+}
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
new file mode 100644 (file)
index 0000000..333fca8
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Device Tree support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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>
+#include <linux/init.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/clocksource.h>
+#include <linux/dma-mapping.h>
+#include <linux/mbus.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include "armada-370-xp.h"
+#include "common.h"
+#include "coherency.h"
+#include "mvebu-soc-id.h"
+
+/*
+ * Early versions of Armada 375 SoC have a bug where the BootROM
+ * leaves an external data abort pending. The kernel is hit by this
+ * data abort as soon as it enters userspace, because it unmasks the
+ * data aborts at this moment. We register a custom abort handler
+ * below to ignore the first data abort to work around this
+ * problem.
+ */
+static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
+                                       struct pt_regs *regs)
+{
+       static int ignore_first;
+
+       if (!ignore_first && fsr == 0x1406) {
+               ignore_first = 1;
+               return 0;
+       }
+
+       return 1;
+}
+
+static void __init mvebu_timer_and_clk_init(void)
+{
+       of_clk_init(NULL);
+       clocksource_of_init();
+       coherency_init();
+       BUG_ON(mvebu_mbus_dt_init());
+#ifdef CONFIG_CACHE_L2X0
+       l2x0_of_init(0, ~0UL);
+#endif
+
+       if (of_machine_is_compatible("marvell,armada375"))
+               hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
+                               "imprecise external abort");
+}
+
+static void __init i2c_quirk(void)
+{
+       struct device_node *np;
+       u32 dev, rev;
+
+       /*
+        * Only revisons more recent than A0 support the offload
+        * mechanism. We can exit only if we are sure that we can
+        * get the SoC revision and it is more recent than A0.
+        */
+       if (mvebu_get_soc_id(&rev, &dev) == 0 && dev > MV78XX0_A0_REV)
+               return;
+
+       for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") {
+               struct property *new_compat;
+
+               new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
+
+               new_compat->name = kstrdup("compatible", GFP_KERNEL);
+               new_compat->length = sizeof("marvell,mv78230-a0-i2c");
+               new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
+                                               GFP_KERNEL);
+
+               of_update_property(np, new_compat);
+       }
+       return;
+}
+
+static void __init mvebu_dt_init(void)
+{
+       if (of_machine_is_compatible("plathome,openblocks-ax3-4"))
+               i2c_quirk();
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const armada_370_xp_dt_compat[] = {
+       "marvell,armada-370-xp",
+       NULL,
+};
+
+DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
+       .smp            = smp_ops(armada_xp_smp_ops),
+       .init_machine   = mvebu_dt_init,
+       .init_time      = mvebu_timer_and_clk_init,
+       .restart        = mvebu_restart,
+       .dt_compat      = armada_370_xp_dt_compat,
+MACHINE_END
+
+static const char * const armada_375_dt_compat[] = {
+       "marvell,armada375",
+       NULL,
+};
+
+DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
+       .init_time      = mvebu_timer_and_clk_init,
+       .restart        = mvebu_restart,
+       .dt_compat      = armada_375_dt_compat,
+MACHINE_END
+
+static const char * const armada_38x_dt_compat[] = {
+       "marvell,armada380",
+       "marvell,armada385",
+       NULL,
+};
+
+DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
+       .init_time      = mvebu_timer_and_clk_init,
+       .restart        = mvebu_restart,
+       .dt_compat      = armada_38x_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/board.h b/arch/arm/mach-mvebu/board.h
new file mode 100644 (file)
index 0000000..de7f0a1
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Board functions for Marvell System On Chip
+ *
+ * Copyright (C) 2014
+ *
+ * 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 __ARCH_MVEBU_BOARD_H
+#define __ARCH_MVEBU_BOARD_H
+
+#ifdef CONFIG_MACH_T5325
+void t5325_init(void);
+#else
+static inline void t5325_init(void) {};
+#endif
+
+#endif
diff --git a/arch/arm/mach-mvebu/dove.c b/arch/arm/mach-mvebu/dove.c
new file mode 100644 (file)
index 0000000..5e5a436
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-mvebu/dove.c
+ *
+ * Marvell Dove 88AP510 System On Chip FDT Board
+ *
+ * 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/init.h>
+#include <linux/mbus.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-tauros2.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static void __init dove_init(void)
+{
+       pr_info("Dove 88AP510 SoC\n");
+
+#ifdef CONFIG_CACHE_TAUROS2
+       tauros2_init(0);
+#endif
+       BUG_ON(mvebu_mbus_dt_init());
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const dove_dt_compat[] = {
+       "marvell,dove",
+       NULL
+};
+
+DT_MACHINE_START(DOVE_DT, "Marvell Dove")
+       .init_machine   = dove_init,
+       .restart        = mvebu_restart,
+       .dt_compat      = dove_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/kirkwood-pm.c b/arch/arm/mach-mvebu/kirkwood-pm.c
new file mode 100644 (file)
index 0000000..cbb816f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Power Management driver for Marvell Kirkwood SoCs
+ *
+ * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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 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/suspend.h>
+#include <linux/io.h>
+#include "kirkwood.h"
+
+static void __iomem *ddr_operation_base;
+static void __iomem *memory_pm_ctrl;
+
+static void kirkwood_low_power(void)
+{
+       u32 mem_pm_ctrl;
+
+       mem_pm_ctrl = readl(memory_pm_ctrl);
+
+       /* Set peripherals to low-power mode */
+       writel_relaxed(~0, memory_pm_ctrl);
+
+       /* Set DDR in self-refresh */
+       writel_relaxed(0x7, ddr_operation_base);
+
+       /*
+        * Set CPU in wait-for-interrupt state.
+        * This disables the CPU core clocks,
+        * the array clocks, and also the L2 controller.
+        */
+       cpu_do_idle();
+
+       writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
+}
+
+static int kirkwood_suspend_enter(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_STANDBY:
+               kirkwood_low_power();
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int kirkwood_pm_valid_standby(suspend_state_t state)
+{
+       return state == PM_SUSPEND_STANDBY;
+}
+
+static const struct platform_suspend_ops kirkwood_suspend_ops = {
+       .enter = kirkwood_suspend_enter,
+       .valid = kirkwood_pm_valid_standby,
+};
+
+int __init kirkwood_pm_init(void)
+{
+       ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
+       memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
+
+       suspend_set_ops(&kirkwood_suspend_ops);
+       return 0;
+}
diff --git a/arch/arm/mach-mvebu/kirkwood-pm.h b/arch/arm/mach-mvebu/kirkwood-pm.h
new file mode 100644 (file)
index 0000000..21e7530
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Power Management driver for Marvell Kirkwood SoCs
+ *
+ * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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 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 __ARCH_KIRKWOOD_PM_H
+#define __ARCH_KIRKWOOD_PM_H
+
+#ifdef CONFIG_PM
+void kirkwood_pm_init(void);
+#else
+static inline void kirkwood_pm_init(void) {};
+#endif
+
+#endif
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
new file mode 100644 (file)
index 0000000..120207f
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
+ *
+ * arch/arm/mach-mvebu/kirkwood.c
+ *
+ * Flattened Device Tree board initialization
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <asm/hardware/cache-feroceon-l2.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "kirkwood.h"
+#include "kirkwood-pm.h"
+#include "common.h"
+#include "board.h"
+
+static struct resource kirkwood_cpufreq_resources[] = {
+       [0] = {
+               .start  = CPU_CONTROL_PHYS,
+               .end    = CPU_CONTROL_PHYS + 3,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device kirkwood_cpufreq_device = {
+       .name           = "kirkwood-cpufreq",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(kirkwood_cpufreq_resources),
+       .resource       = kirkwood_cpufreq_resources,
+};
+
+static void __init kirkwood_cpufreq_init(void)
+{
+       platform_device_register(&kirkwood_cpufreq_device);
+}
+
+static struct resource kirkwood_cpuidle_resource[] = {
+       {
+               .flags  = IORESOURCE_MEM,
+               .start  = DDR_OPERATION_BASE,
+               .end    = DDR_OPERATION_BASE + 3,
+       },
+};
+
+static struct platform_device kirkwood_cpuidle = {
+       .name           = "kirkwood_cpuidle",
+       .id             = -1,
+       .resource       = kirkwood_cpuidle_resource,
+       .num_resources  = 1,
+};
+
+static void __init kirkwood_cpuidle_init(void)
+{
+       platform_device_register(&kirkwood_cpuidle);
+}
+
+#define MV643XX_ETH_MAC_ADDR_LOW       0x0414
+#define MV643XX_ETH_MAC_ADDR_HIGH      0x0418
+
+static void __init kirkwood_dt_eth_fixup(void)
+{
+       struct device_node *np;
+
+       /*
+        * The ethernet interfaces forget the MAC address assigned by u-boot
+        * if the clocks are turned off. Usually, u-boot on kirkwood boards
+        * has no DT support to properly set local-mac-address property.
+        * As a workaround, we get the MAC address from mv643xx_eth registers
+        * and update the port device node if no valid MAC address is set.
+        */
+       for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") {
+               struct device_node *pnp = of_get_parent(np);
+               struct clk *clk;
+               struct property *pmac;
+               void __iomem *io;
+               u8 *macaddr;
+               u32 reg;
+
+               if (!pnp)
+                       continue;
+
+               /* skip disabled nodes or nodes with valid MAC address*/
+               if (!of_device_is_available(pnp) || of_get_mac_address(np))
+                       goto eth_fixup_skip;
+
+               clk = of_clk_get(pnp, 0);
+               if (IS_ERR(clk))
+                       goto eth_fixup_skip;
+
+               io = of_iomap(pnp, 0);
+               if (!io)
+                       goto eth_fixup_no_map;
+
+               /* ensure port clock is not gated to not hang CPU */
+               clk_prepare_enable(clk);
+
+               /* store MAC address register contents in local-mac-address */
+               pr_err(FW_INFO "%s: local-mac-address is not set\n",
+                      np->full_name);
+
+               pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL);
+               if (!pmac)
+                       goto eth_fixup_no_mem;
+
+               pmac->value = pmac + 1;
+               pmac->length = 6;
+               pmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+               if (!pmac->name) {
+                       kfree(pmac);
+                       goto eth_fixup_no_mem;
+               }
+
+               macaddr = pmac->value;
+               reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH);
+               macaddr[0] = (reg >> 24) & 0xff;
+               macaddr[1] = (reg >> 16) & 0xff;
+               macaddr[2] = (reg >> 8) & 0xff;
+               macaddr[3] = reg & 0xff;
+
+               reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW);
+               macaddr[4] = (reg >> 8) & 0xff;
+               macaddr[5] = reg & 0xff;
+
+               of_update_property(np, pmac);
+
+eth_fixup_no_mem:
+               iounmap(io);
+               clk_disable_unprepare(clk);
+eth_fixup_no_map:
+               clk_put(clk);
+eth_fixup_skip:
+               of_node_put(pnp);
+       }
+}
+
+/*
+ * Disable propagation of mbus errors to the CPU local bus, as this
+ * causes mbus errors (which can occur for example for PCI aborts) to
+ * throw CPU aborts, which we're not set up to deal with.
+ */
+void kirkwood_disable_mbus_error_propagation(void)
+{
+       void __iomem *cpu_config;
+
+       cpu_config = ioremap(CPU_CONFIG_PHYS, 4);
+       writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config);
+}
+
+static struct of_dev_auxdata auxdata[] __initdata = {
+       OF_DEV_AUXDATA("marvell,kirkwood-audio", 0xf10a0000,
+                      "mvebu-audio", NULL),
+       { /* sentinel */ }
+};
+
+static void __init kirkwood_dt_init(void)
+{
+       kirkwood_disable_mbus_error_propagation();
+
+       BUG_ON(mvebu_mbus_dt_init());
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+       feroceon_of_init();
+#endif
+       kirkwood_cpufreq_init();
+       kirkwood_cpuidle_init();
+
+       kirkwood_pm_init();
+       kirkwood_dt_eth_fixup();
+
+       if (of_machine_is_compatible("hp,t5325"))
+               t5325_init();
+
+       of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL);
+}
+
+static const char * const kirkwood_dt_board_compat[] = {
+       "marvell,kirkwood",
+       NULL
+};
+
+DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
+       /* Maintainer: Jason Cooper <jason@lakedaemon.net> */
+       .init_machine   = kirkwood_dt_init,
+       .restart        = mvebu_restart,
+       .dt_compat      = kirkwood_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/kirkwood.h b/arch/arm/mach-mvebu/kirkwood.h
new file mode 100644 (file)
index 0000000..89f3d1f
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-mvebu/kirkwood.h
+ *
+ * Generic definitions for Marvell Kirkwood SoC flavors:
+ * 88F6180, 88F6192 and 88F6281.
+ *
+ * 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 KIRKWOOD_REGS_PHYS_BASE        0xf1000000
+#define DDR_PHYS_BASE           (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
+#define BRIDGE_PHYS_BASE       (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
+
+#define DDR_OPERATION_BASE     (DDR_PHYS_BASE + 0x1418)
+
+#define CPU_CONFIG_PHYS                (BRIDGE_PHYS_BASE + 0x0100)
+#define CPU_CONFIG_ERROR_PROP  0x00000004
+
+#define CPU_CONTROL_PHYS       (BRIDGE_PHYS_BASE + 0x0104)
+#define MEMORY_PM_CTRL_PHYS    (BRIDGE_PHYS_BASE + 0x0118)
index f3b325f6cbd4e8cc7c9b493d99bb688c5f3f9511..f3d4cf53f7466ba6c44f5ef1d91484e3ce8f62e6 100644 (file)
@@ -38,6 +38,7 @@ static bool is_id_valid;
 static const struct of_device_id mvebu_pcie_of_match_table[] = {
        { .compatible = "marvell,armada-xp-pcie", },
        { .compatible = "marvell,armada-370-pcie", },
+       { .compatible = "marvell,kirkwood-pcie" },
        {},
 };
 
index a7fb89a5b5d9818db3174916d0e7e0589ed53456..614ba6832ff3ae4e14fe72ff12bdd98c83b95964 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * System controller support for Armada 370 and XP platforms.
+ * System controller support for Armada 370, 375 and XP platforms.
  *
  * Copyright (C) 2012 Marvell
  *
@@ -11,7 +11,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  *
- * The Armada 370 and Armada XP SoCs both have a range of
+ * The Armada 370, 375 and Armada XP SoCs have a range of
  * miscellaneous registers, that do not belong to a particular device,
  * but rather provide system-level features. This basic
  * system-controller driver provides a device tree binding for those
@@ -47,6 +47,13 @@ static const struct mvebu_system_controller armada_370_xp_system_controller = {
        .system_soft_reset = 0x1,
 };
 
+static const struct mvebu_system_controller armada_375_system_controller = {
+       .rstoutn_mask_offset = 0x54,
+       .system_soft_reset_offset = 0x58,
+       .rstoutn_mask_reset_out_en = 0x1,
+       .system_soft_reset = 0x1,
+};
+
 static const struct mvebu_system_controller orion_system_controller = {
        .rstoutn_mask_offset = 0x108,
        .system_soft_reset_offset = 0x10c,
@@ -54,13 +61,16 @@ static const struct mvebu_system_controller orion_system_controller = {
        .system_soft_reset = 0x1,
 };
 
-static struct of_device_id of_system_controller_table[] = {
+static const struct of_device_id of_system_controller_table[] = {
        {
                .compatible = "marvell,orion-system-controller",
                .data = (void *) &orion_system_controller,
        }, {
                .compatible = "marvell,armada-370-xp-system-controller",
                .data = (void *) &armada_370_xp_system_controller,
+       }, {
+               .compatible = "marvell,armada-375-system-controller",
+               .data = (void *) &armada_375_system_controller,
        },
        { /* end of list */ },
 };
@@ -90,13 +100,12 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd)
 
 static int __init mvebu_system_controller_init(void)
 {
+       const struct of_device_id *match;
        struct device_node *np;
 
-       np = of_find_matching_node(NULL, of_system_controller_table);
+       np = of_find_matching_node_and_match(NULL, of_system_controller_table,
+                                            &match);
        if (np) {
-               const struct of_device_id *match =
-                   of_match_node(of_system_controller_table, np);
-               BUG_ON(!match);
                system_controller_base = of_iomap(np, 0);
                mvebu_sc = (struct mvebu_system_controller *)match->data;
                of_node_put(np);
index 8cde9e05b5d65c17194cb8acee8c19a52d5aa025..84794137b17500da75487a5e394be6bea0f30495 100644 (file)
@@ -16,11 +16,7 @@ config ARCH_MXS
        bool "Freescale MXS (i.MX23, i.MX28) support"
        depends on ARCH_MULTI_V5
        select ARCH_REQUIRE_GPIOLIB
-       select CLKDEV_LOOKUP
        select CLKSRC_MMIO
-       select CLKSRC_OF
-       select GENERIC_CLOCKEVENTS
-       select HAVE_CLK_PREPARE
        select PINCTRL
        select SOC_BUS
        select SOC_IMX23
index 1dc5acd4fc99bb7f0001217214d53199dd89174d..2e7cec86e50e94bdb95b2905216614525fe39ff0 100644 (file)
@@ -157,6 +157,8 @@ enum mac_oui {
        OUI_FSL,
        OUI_DENX,
        OUI_CRYSTALFONTZ,
+       OUI_I2SE,
+       OUI_ARMADEUS,
 };
 
 static void __init update_fec_mac_prop(enum mac_oui oui)
@@ -211,6 +213,16 @@ static void __init update_fec_mac_prop(enum mac_oui oui)
                        macaddr[1] = 0xb9;
                        macaddr[2] = 0xe1;
                        break;
+               case OUI_I2SE:
+                       macaddr[0] = 0x00;
+                       macaddr[1] = 0x01;
+                       macaddr[2] = 0x87;
+                       break;
+               case OUI_ARMADEUS:
+                       macaddr[0] = 0x00;
+                       macaddr[1] = 0x1e;
+                       macaddr[2] = 0xac;
+                       break;
                }
                val = ocotp[i];
                macaddr[3] = (val >> 16) & 0xff;
@@ -236,6 +248,11 @@ static void __init imx28_evk_init(void)
        mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
 }
 
+static void __init imx28_apf28_init(void)
+{
+       update_fec_mac_prop(OUI_ARMADEUS);
+}
+
 static int apx4devkit_phy_fixup(struct phy_device *phy)
 {
        phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
@@ -330,6 +347,11 @@ static void __init crystalfontz_init(void)
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
 }
 
+static void __init duckbill_init(void)
+{
+       update_fec_mac_prop(OUI_I2SE);
+}
+
 static void __init m28cu3_init(void)
 {
        update_fec_mac_prop(OUI_DENX);
@@ -426,6 +448,11 @@ static int __init mxs_restart_init(void)
        return 0;
 }
 
+static void __init eukrea_mbmx283lc_init(void)
+{
+       mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
+}
+
 static void __init mxs_machine_init(void)
 {
        struct device_node *root;
@@ -458,10 +485,16 @@ static void __init mxs_machine_init(void)
 
        if (of_machine_is_compatible("fsl,imx28-evk"))
                imx28_evk_init();
+       if (of_machine_is_compatible("armadeus,imx28-apf28"))
+               imx28_apf28_init();
        else if (of_machine_is_compatible("bluegiga,apx4devkit"))
                apx4devkit_init();
        else if (of_machine_is_compatible("crystalfontz,cfa10036"))
                crystalfontz_init();
+       else if (of_machine_is_compatible("eukrea,mbmx283lc"))
+               eukrea_mbmx283lc_init();
+       else if (of_machine_is_compatible("i2se,duckbill"))
+               duckbill_init();
        else if (of_machine_is_compatible("msr,m28cu3"))
                m28cu3_init();
 
diff --git a/arch/arm/mach-netx/include/mach/timex.h b/arch/arm/mach-netx/include/mach/timex.h
deleted file mode 100644 (file)
index 1120dd0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * arch/arm/mach-netx/include/mach/timex.h
- *
- * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define CLOCK_TICK_RATE 100000000
index 6df42e643031aa1cb74bbec4ea0f5b13bd99d8d0..5fb2a590ec17dfe94931c9685d9748ee722e3992 100644 (file)
@@ -28,6 +28,9 @@
 #include <asm/mach/time.h>
 #include <mach/netx-regs.h>
 
+#define NETX_CLOCK_FREQ 100000000
+#define NETX_LATCH DIV_ROUND_CLOSEST(NETX_CLOCK_FREQ, HZ)
+
 #define TIMER_CLOCKEVENT 0
 #define TIMER_CLOCKSOURCE 1
 
@@ -41,7 +44,7 @@ static void netx_set_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               writel(LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
+               writel(NETX_LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
                tmode = NETX_GPIO_COUNTER_CTRL_RST_EN |
                        NETX_GPIO_COUNTER_CTRL_IRQ_EN |
                        NETX_GPIO_COUNTER_CTRL_RUN;
@@ -99,7 +102,7 @@ netx_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction netx_timer_irq = {
        .name           = "NetX Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = netx_timer_interrupt,
 };
 
@@ -114,7 +117,7 @@ void __init netx_timer_init(void)
        /* Reset the timer value to zero */
        writel(0, NETX_GPIO_COUNTER_CURRENT(0));
 
-       writel(LATCH, NETX_GPIO_COUNTER_MAX(0));
+       writel(NETX_LATCH, NETX_GPIO_COUNTER_MAX(0));
 
        /* acknowledge interrupt */
        writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
@@ -137,11 +140,11 @@ void __init netx_timer_init(void)
                        NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
 
        clocksource_mmio_init(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE),
-               "netx_timer", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up);
+               "netx_timer", NETX_CLOCK_FREQ, 200, 32, clocksource_mmio_readl_up);
 
        /* with max_delta_ns >= delta2ns(0x800) the system currently runs fine.
         * Adding some safety ... */
        netx_clockevent.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&netx_clockevent, CLOCK_TICK_RATE,
+       clockevents_config_and_register(&netx_clockevent, NETX_CLOCK_FREQ,
                                        0xa00, 0xfffffffe);
 }
index 4d42da49753c68f1afd914a0a4a4246e09b8893c..486d301f43fdafbf9ab1a20744095bdbaf5fd2ed 100644 (file)
@@ -6,16 +6,11 @@ config ARCH_NOMADIK
        select ARM_VIC
        select CLKSRC_NOMADIK_MTU
        select CLKSRC_NOMADIK_MTU_SCHED_CLOCK
-       select CLKSRC_OF
-       select COMMON_CLK
        select CPU_ARM926T
-       select GENERIC_CLOCKEVENTS
        select MIGHT_HAVE_CACHE_L2X0
        select PINCTRL
        select PINCTRL_NOMADIK
        select PINCTRL_STN8815
-       select SPARSE_IRQ
-       select USE_OF
        help
          Support for the Nomadik platform by ST-Ericsson
 
index 59d8f0a70919a72f875b0a81cd75b388dcf8a5cb..bc41f26c1a1208a7beb0fe2390229a54ef01eff6 100644 (file)
@@ -3,14 +3,9 @@ config ARCH_NSPIRE
        depends on ARCH_MULTI_V4_V5
        depends on MMU
        select CPU_ARM926T
-       select COMMON_CLK
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select SPARSE_IRQ
        select ARM_AMBA
        select ARM_VIC
        select ARM_TIMER_SP804
-       select USE_OF
-       select CLKSRC_OF
        help
          This enables support for systems using the TI-NSPIRE CPU
index 4b2ed2e8352f4fd1433e8ac0e41da26d2b3bdbe5..3d24ebf120953d936fa5785fdcd199fcfbf8f1ba 100644 (file)
@@ -63,7 +63,7 @@ static void __init nspire_init(void)
                        nspire_auxdata, NULL);
 }
 
-static void nspire_restart(char mode, const char *cmd)
+static void nspire_restart(enum reboot_mode mode, const char *cmd)
 {
        void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K);
        if (!base)
index fd90cafc2e36e7b9bc3d5264bc18bfc183965004..65d2acb3149846f60175b2b1f32f9e374300ee33 100644 (file)
@@ -318,6 +318,9 @@ static void __init h2_init_smc91x(void)
 
 static int tps_setup(struct i2c_client *client, void *context)
 {
+       if (!IS_BUILTIN(CONFIG_TPS65010))
+               return -ENOSYS;
+       
        tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V |
                                TPS_LDO1_ENABLE | TPS_VLDO1_3_0V);
 
index d68909b095f1c06b135bac8e07dee46408dd5d40..3a0262156e93ee09bd6b3f2a76f49ac8c1b68fa8 100644 (file)
@@ -191,6 +191,9 @@ static struct platform_device osk5912_tps_leds = {
 
 static int osk_tps_setup(struct i2c_client *client, void *context)
 {
+       if (!IS_BUILTIN(CONFIG_TPS65010))
+               return -ENOSYS;
+
        /* Set GPIO 1 HIGH to disable VBUS power supply;
         * OHCI driver powers it up/down as needed.
         */
index 5bb8ce86d54bb4288e2be7a1319621defa1f0017..4be601b638d7aa8c0d35b7fa5924eb54aa6e2534 100644 (file)
 
 #define OMAP1_DMA_BASE                 (0xfffed800)
 #define OMAP1_LOGICAL_DMA_CH_COUNT     17
-#define OMAP1_DMA_STRIDE               0x40
 
-static u32 errata;
 static u32 enable_1510_mode;
-static u8 dma_stride;
-static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
-
-static u16 reg_map[] = {
-       [GCR]           = 0x400,
-       [GSCR]          = 0x404,
-       [GRST1]         = 0x408,
-       [HW_ID]         = 0x442,
-       [PCH2_ID]       = 0x444,
-       [PCH0_ID]       = 0x446,
-       [PCH1_ID]       = 0x448,
-       [PCHG_ID]       = 0x44a,
-       [PCHD_ID]       = 0x44c,
-       [CAPS_0]        = 0x44e,
-       [CAPS_1]        = 0x452,
-       [CAPS_2]        = 0x456,
-       [CAPS_3]        = 0x458,
-       [CAPS_4]        = 0x45a,
-       [PCH2_SR]       = 0x460,
-       [PCH0_SR]       = 0x480,
-       [PCH1_SR]       = 0x482,
-       [PCHD_SR]       = 0x4c0,
+
+static const struct omap_dma_reg reg_map[] = {
+       [GCR]           = { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
+       [GSCR]          = { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
+       [GRST1]         = { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
+       [HW_ID]         = { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
+       [PCH2_ID]       = { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
+       [PCH0_ID]       = { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
+       [PCH1_ID]       = { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
+       [PCHG_ID]       = { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
+       [PCHD_ID]       = { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
+       [CAPS_0]        = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
+       [CAPS_1]        = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
+       [CAPS_2]        = { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
+       [CAPS_3]        = { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
+       [CAPS_4]        = { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
+       [PCH2_SR]       = { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
+       [PCH0_SR]       = { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
+       [PCH1_SR]       = { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
+       [PCHD_SR]       = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },
 
        /* Common Registers */
-       [CSDP]          = 0x00,
-       [CCR]           = 0x02,
-       [CICR]          = 0x04,
-       [CSR]           = 0x06,
-       [CEN]           = 0x10,
-       [CFN]           = 0x12,
-       [CSFI]          = 0x14,
-       [CSEI]          = 0x16,
-       [CPC]           = 0x18, /* 15xx only */
-       [CSAC]          = 0x18,
-       [CDAC]          = 0x1a,
-       [CDEI]          = 0x1c,
-       [CDFI]          = 0x1e,
-       [CLNK_CTRL]     = 0x28,
+       [CSDP]          = { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
+       [CCR]           = { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
+       [CICR]          = { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
+       [CSR]           = { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
+       [CEN]           = { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
+       [CFN]           = { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
+       [CSFI]          = { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
+       [CSEI]          = { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
+       [CPC]           = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */
+       [CSAC]          = { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
+       [CDAC]          = { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
+       [CDEI]          = { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
+       [CDFI]          = { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
+       [CLNK_CTRL]     = { 0x0028, 0x40, OMAP_DMA_REG_16BIT },
 
        /* Channel specific register offsets */
-       [CSSA]          = 0x08,
-       [CDSA]          = 0x0c,
-       [COLOR]         = 0x20,
-       [CCR2]          = 0x24,
-       [LCH_CTRL]      = 0x2a,
+       [CSSA]          = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
+       [CDSA]          = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
+       [COLOR]         = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
+       [CCR2]          = { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
+       [LCH_CTRL]      = { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
 };
 
 static struct resource res[] __initdata = {
@@ -181,44 +177,36 @@ static struct resource res[] __initdata = {
 static void __iomem *dma_base;
 static inline void dma_write(u32 val, int reg, int lch)
 {
-       u8  stride;
-       u32 offset;
+       void __iomem *addr = dma_base;
 
-       stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
-       offset = reg_map[reg] + (stride * lch);
+       addr += reg_map[reg].offset;
+       addr += reg_map[reg].stride * lch;
 
-       __raw_writew(val, dma_base + offset);
-       if ((reg > CLNK_CTRL && reg < CCEN) ||
-                       (reg > PCHD_ID && reg < CAPS_2)) {
-               u32 offset2 = reg_map[reg] + 2 + (stride * lch);
-               __raw_writew(val >> 16, dma_base + offset2);
-       }
+       __raw_writew(val, addr);
+       if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
+               __raw_writew(val >> 16, addr + 2);
 }
 
 static inline u32 dma_read(int reg, int lch)
 {
-       u8 stride;
-       u32 offset, val;
-
-       stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
-       offset = reg_map[reg] + (stride * lch);
-
-       val = __raw_readw(dma_base + offset);
-       if ((reg > CLNK_CTRL && reg < CCEN) ||
-                       (reg > PCHD_ID && reg < CAPS_2)) {
-               u16 upper;
-               u32 offset2 = reg_map[reg] + 2 + (stride * lch);
-               upper = __raw_readw(dma_base + offset2);
-               val |= (upper << 16);
-       }
+       void __iomem *addr = dma_base;
+       uint32_t val;
+
+       addr += reg_map[reg].offset;
+       addr += reg_map[reg].stride * lch;
+
+       val = __raw_readw(addr);
+       if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
+               val |= __raw_readw(addr + 2) << 16;
+
        return val;
 }
 
 static void omap1_clear_lch_regs(int lch)
 {
-       int i = dma_common_ch_start;
+       int i;
 
-       for (; i <= dma_common_ch_end; i += 1)
+       for (i = CPC; i <= COLOR; i += 1)
                dma_write(0, i, lch);
 }
 
@@ -255,8 +243,9 @@ static void omap1_show_dma_caps(void)
        return;
 }
 
-static u32 configure_dma_errata(void)
+static unsigned configure_dma_errata(void)
 {
+       unsigned errata = 0;
 
        /*
         * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
@@ -272,11 +261,23 @@ static const struct platform_device_info omap_dma_dev_info = {
        .name = "omap-dma-engine",
        .id = -1,
        .dma_mask = DMA_BIT_MASK(32),
+       .res = res,
+       .num_res = 1,
+};
+
+static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+       .reg_map        = reg_map,
+       .channel_stride = 0x40,
+       .show_dma_caps  = omap1_show_dma_caps,
+       .clear_lch_regs = omap1_clear_lch_regs,
+       .clear_dma      = omap1_clear_dma,
+       .dma_write      = dma_write,
+       .dma_read       = dma_read,
 };
 
 static int __init omap1_system_dma_init(void)
 {
-       struct omap_system_dma_plat_info        *p;
+       struct omap_system_dma_plat_info        p;
        struct omap_dma_dev_attr                *d;
        struct platform_device                  *pdev, *dma_pdev;
        int ret;
@@ -302,20 +303,12 @@ static int __init omap1_system_dma_init(void)
                goto exit_iounmap;
        }
 
-       p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
-       if (!p) {
-               dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
-                       __func__, pdev->name);
-               ret = -ENOMEM;
-               goto exit_iounmap;
-       }
-
        d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
        if (!d) {
                dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
                        __func__, pdev->name);
                ret = -ENOMEM;
-               goto exit_release_p;
+               goto exit_iounmap;
        }
 
        d->lch_count            = OMAP1_LOGICAL_DMA_CH_COUNT;
@@ -336,17 +329,6 @@ static int __init omap1_system_dma_init(void)
        d->dev_caps             |= CLEAR_CSR_ON_READ;
        d->dev_caps             |= IS_WORD_16;
 
-
-       d->chan = kzalloc(sizeof(struct omap_dma_lch) *
-                                       (d->lch_count), GFP_KERNEL);
-       if (!d->chan) {
-               dev_err(&pdev->dev,
-                       "%s: Memory allocation failed for d->chan!\n",
-                       __func__);
-               ret = -ENOMEM;
-               goto exit_release_d;
-       }
-
        if (cpu_is_omap15xx())
                d->chan_count = 9;
        else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
@@ -356,35 +338,24 @@ static int __init omap1_system_dma_init(void)
                        d->chan_count = 9;
        }
 
-       p->dma_attr = d;
-
-       p->show_dma_caps        = omap1_show_dma_caps;
-       p->clear_lch_regs       = omap1_clear_lch_regs;
-       p->clear_dma            = omap1_clear_dma;
-       p->dma_write            = dma_write;
-       p->dma_read             = dma_read;
-       p->disable_irq_lch      = NULL;
-
-       p->errata = configure_dma_errata();
+       p = dma_plat_info;
+       p.dma_attr = d;
+       p.errata = configure_dma_errata();
 
-       ret = platform_device_add_data(pdev, p, sizeof(*p));
+       ret = platform_device_add_data(pdev, &p, sizeof(p));
        if (ret) {
                dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
                        __func__, pdev->name, pdev->id);
-               goto exit_release_chan;
+               goto exit_release_d;
        }
 
        ret = platform_device_add(pdev);
        if (ret) {
                dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
                        __func__, pdev->name, pdev->id);
-               goto exit_release_chan;
+               goto exit_release_d;
        }
 
-       dma_stride              = OMAP1_DMA_STRIDE;
-       dma_common_ch_start     = CPC;
-       dma_common_ch_end       = COLOR;
-
        dma_pdev = platform_device_register_full(&omap_dma_dev_info);
        if (IS_ERR(dma_pdev)) {
                ret = PTR_ERR(dma_pdev);
@@ -395,12 +366,8 @@ static int __init omap1_system_dma_init(void)
 
 exit_release_pdev:
        platform_device_del(pdev);
-exit_release_chan:
-       kfree(d->chan);
 exit_release_d:
        kfree(d);
-exit_release_p:
-       kfree(p);
 exit_iounmap:
        iounmap(dma_base);
 exit_device_put:
diff --git a/arch/arm/mach-omap1/include/mach/timex.h b/arch/arm/mach-omap1/include/mach/timex.h
deleted file mode 100644 (file)
index 4793790..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-omap1/include/mach/timex.h
- */
-
-#include <plat/timex.h>
index 40a1ae31961027a5383123cca4da2f672003cd92..dbee729e3b6d552c79421dc40f241f483138da8e 100644 (file)
@@ -71,7 +71,11 @@ static unsigned int mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_SIZE];
 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
 
-#ifdef CONFIG_OMAP_32K_TIMER
+#ifndef CONFIG_OMAP_32K_TIMER
+
+static unsigned short enable_dyn_sleep = 0;
+
+#else
 
 static unsigned short enable_dyn_sleep = 1;
 
index ac488251174961bf41d606f2d633ec09a55cf684..cb31d4390d5290ff7216e6facf9cb0688e71e167 100644 (file)
@@ -6,7 +6,6 @@ config ARCH_OMAP2
        depends on ARCH_MULTI_V6
        select ARCH_OMAP2PLUS
        select CPU_V6
-       select MULTI_IRQ_HANDLER
        select SOC_HAS_OMAP2_SDRC
 
 config ARCH_OMAP3
@@ -15,8 +14,6 @@ config ARCH_OMAP3
        select ARCH_OMAP2PLUS
        select ARCH_HAS_OPP
        select ARM_CPU_SUSPEND if PM
-       select CPU_V7
-       select MULTI_IRQ_HANDLER
        select OMAP_INTERCONNECT
        select PM_OPP if PM
        select PM_RUNTIME if CPU_IDLE
@@ -32,10 +29,8 @@ config ARCH_OMAP4
        select ARM_ERRATA_720789
        select ARM_GIC
        select CACHE_L2X0
-       select CPU_V7
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
        select OMAP_INTERCONNECT
        select PL310_ERRATA_588369
        select PL310_ERRATA_727915
@@ -51,10 +46,8 @@ config SOC_OMAP5
        select ARCH_HAS_OPP
        select ARM_CPU_SUSPEND if PM
        select ARM_GIC
-       select CPU_V7
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
        select HAVE_ARM_ARCH_TIMER
        select ARM_ERRATA_798181 if SMP
 
@@ -64,16 +57,12 @@ config SOC_AM33XX
        select ARCH_OMAP2PLUS
        select ARCH_HAS_OPP
        select ARM_CPU_SUSPEND if PM
-       select CPU_V7
-       select MULTI_IRQ_HANDLER
 
 config SOC_AM43XX
        bool "TI AM43x"
        depends on ARCH_MULTI_V7
-       select CPU_V7
        select ARCH_OMAP2PLUS
        select ARCH_HAS_OPP
-       select MULTI_IRQ_HANDLER
        select ARM_GIC
        select MACH_OMAP_GENERIC
 
@@ -84,9 +73,8 @@ config SOC_DRA7XX
        select ARCH_HAS_OPP
        select ARM_CPU_SUSPEND if PM
        select ARM_GIC
-       select CPU_V7
-       select HAVE_SMP
        select HAVE_ARM_ARCH_TIMER
+       select IRQ_CROSSBAR
 
 config ARCH_OMAP2PLUS
        bool
@@ -96,16 +84,12 @@ config ARCH_OMAP2PLUS
        select ARCH_OMAP
        select ARCH_REQUIRE_GPIOLIB
        select CLKSRC_MMIO
-       select COMMON_CLK
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
        select MACH_OMAP_GENERIC
        select OMAP_DM_TIMER
        select PINCTRL
        select SOC_BUS
-       select SPARSE_IRQ
        select TI_PRIV_EDMA
-       select USE_OF
        help
          Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
 
@@ -166,12 +150,6 @@ config SOC_TI81XX
        depends on ARCH_OMAP3
        default y
 
-config OMAP_PACKAGE_ZAF
-       bool
-
-config OMAP_PACKAGE_ZAC
-       bool
-
 config OMAP_PACKAGE_CBC
        bool
 
@@ -281,7 +259,6 @@ config MACH_NOKIA_N8X0
        default y
        select MACH_NOKIA_N810
        select MACH_NOKIA_N810_WIMAX
-       select OMAP_PACKAGE_ZAC
 
 config MACH_NOKIA_RX51
        bool "Nokia N900 (RX-51) phone"
index e6eec6f72fd3ed76b30af03bb4923fbacc62af7c..8421f38cf445355f2ad84ef5077f4b89523b21fb 100644 (file)
@@ -60,6 +60,7 @@ AFLAGS_sram34xx.o                     :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_OMAP2420)             += omap2-restart.o
 obj-$(CONFIG_SOC_OMAP2430)             += omap2-restart.o
 obj-$(CONFIG_SOC_AM33XX)               += am33xx-restart.o
+obj-$(CONFIG_SOC_AM43XX)               += omap4-restart.o
 obj-$(CONFIG_ARCH_OMAP3)               += omap3-restart.o
 obj-$(CONFIG_ARCH_OMAP4)               += omap4-restart.o
 obj-$(CONFIG_SOC_OMAP5)                        += omap4-restart.o
index 25b79a29736519884306a5c98c742650b35b15c0..6a6935caac1e4dbd9c1eab2a191f64329c082909 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/err.h>
 #include <linux/davinci_emac.h>
-#include <asm/system.h>
 #include "omap_device.h"
 #include "am35xx.h"
 #include "control.h"
index 8dd0ec858cf1cc71372cb1e9d97d23232f7ed0de..018353d88b96820faeef14bdd32f4273cfc0264f 100644 (file)
@@ -16,6 +16,8 @@
  *
  */
 
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -542,8 +544,22 @@ static struct isp_platform_data cm_t35_isp_pdata = {
        .subdevs = cm_t35_isp_subdevs,
 };
 
+static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
+       REGULATOR_SUPPLY("vaa", "3-005d"),
+       REGULATOR_SUPPLY("vdd", "3-005d"),
+};
+
 static void __init cm_t35_init_camera(void)
 {
+       struct clk *clk;
+
+       clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT,
+                                     48000000);
+       clk_register_clkdev(clk, NULL, "3-005d");
+
+       regulator_register_fixed(2, cm_t35_camera_supplies,
+                                ARRAY_SIZE(cm_t35_camera_supplies));
+
        if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
                pr_warn("CM-T3x: Failed registering camera device!\n");
 }
index 8e3daa11602b305473b63ded02749cf152c6f415..b8920b6bc104f21f42dfda19d0ac63dd9db713f6 100644 (file)
@@ -35,7 +35,11 @@ static struct of_device_id omap_dt_match_table[] __initdata = {
 
 static void __init omap_generic_init(void)
 {
+       omapdss_early_init_of();
+
        pdata_quirks_init(omap_dt_match_table);
+
+       omapdss_init_of();
 }
 
 #ifdef CONFIG_SOC_OMAP2420
@@ -229,8 +233,9 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
        .init_late      = am43xx_init_late,
        .init_irq       = omap_gic_of_init,
        .init_machine   = omap_generic_init,
-       .init_time      = omap3_sync32k_timer_init,
+       .init_time      = omap3_gptimer_timer_init,
        .dt_compat      = am43_boards_compat,
+       .restart        = omap44xx_restart,
 MACHINE_END
 #endif
 
index 11ed9152e665274793ee83f50881efc2d9fbdded..8f5121b89688396d1b3fb4551dc55fc0c4395c00 100644 (file)
@@ -3497,10 +3497,6 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK(NULL,       "dss_tv_fck",   &dss_tv_fck),
        CLK(NULL,       "dss_96m_fck",  &dss_96m_fck),
        CLK(NULL,       "dss2_alwon_fck",       &dss2_alwon_fck),
-       CLK(NULL,       "utmi_p1_gfclk",        &dummy_ck),
-       CLK(NULL,       "utmi_p2_gfclk",        &dummy_ck),
-       CLK(NULL,       "xclk60mhsp1_ck",       &dummy_ck),
-       CLK(NULL,       "xclk60mhsp2_ck",       &dummy_ck),
        CLK(NULL,       "init_60m_fclk",        &dummy_ck),
        CLK(NULL,       "gpt1_fck",     &gpt1_fck),
        CLK(NULL,       "aes2_ick",     &aes2_ick),
index 47f9562ca7aa0f3007cfac811ffceb90b7cce80e..2649ce445845288725c011bd66147cc103018339 100644 (file)
@@ -306,7 +306,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
 
        ref_rate = __clk_get_rate(dd->clk_ref);
        clk_name = __clk_get_name(hw->clk);
-       pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
+       pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
                 clk_name, target_rate);
 
        scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR);
@@ -342,7 +342,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
                if (r == DPLL_MULT_UNDERFLOW)
                        continue;
 
-               pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
+               pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n",
                         clk_name, m, n, new_rate);
 
                if (target_rate == new_rate) {
@@ -354,7 +354,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
        }
 
        if (target_rate != new_rate) {
-               pr_debug("clock: %s: cannot round to rate %ld\n",
+               pr_debug("clock: %s: cannot round to rate %lu\n",
                         clk_name, target_rate);
                return ~0;
        }
index e6b91e552d3d9427bbfd5287e6762bbff5aaae54..f03dc97921ad934923ea78ffa7fad8204586cace 100644 (file)
@@ -247,7 +247,7 @@ static struct clockdomain neon_clkdm = {
 static struct clockdomain iva2_clkdm = {
        .name           = "iva2_clkdm",
        .pwrdm          = { .name = "iva2_pwrdm" },
-       .flags          = CLKDM_CAN_HWSUP_SWSUP,
+       .flags          = CLKDM_CAN_SWSUP,
        .dep_bit        = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
        .wkdep_srcs     = iva2_wkdeps,
        .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
index 731ca134348c34906c2e8dc58e5f982aca04f1b5..f5c4731b6f06cc3a6c10e6a0d52840ae53bd1765 100644 (file)
@@ -254,6 +254,11 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs)
  *
  */
 
+void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs)
+{
+       _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
+}
+
 /**
  * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state
  * @part: PRCM partition ID that the CM_CLKCTRL register exists in
@@ -404,8 +409,17 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
 
 static int omap4_clkdm_sleep(struct clockdomain *clkdm)
 {
-       omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
-                                       clkdm->cm_inst, clkdm->clkdm_offs);
+       if (clkdm->flags & CLKDM_CAN_HWSUP)
+               omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+                                               clkdm->cm_inst,
+                                               clkdm->clkdm_offs);
+       else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+               omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+                                              clkdm->cm_inst,
+                                              clkdm->clkdm_offs);
+       else
+               return -EINVAL;
+
        return 0;
 }
 
index a6aae300542cd822a873501e7670ea2dc273dd14..d88aff7baff8d5e7adcc865836649ca5ce1fb4b8 100644 (file)
@@ -315,5 +315,8 @@ extern int omap_dss_reset(struct omap_hwmod *);
 /* SoC specific clock initializer */
 int omap_clk_init(void);
 
+int __init omapdss_init_of(void);
+void __init omapdss_early_init_of(void);
+
 #endif /* __ASSEMBLER__ */
 #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
index 0dd6398bade4787510c4d5c62210b7a61cfb7595..e58609b312c7091b5589314fbb4b457b457ccb0f 100644 (file)
@@ -229,6 +229,9 @@ static struct omap_iommu_arch_data omap3_isp_iommu = {
 
 int omap3_init_camera(struct isp_platform_data *pdata)
 {
+       if (of_have_populated_dt())
+               omap3_isp_iommu.name = "480bd400.mmu";
+
        omap3isp_device.dev.platform_data = pdata;
        omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;
 
index 4cf165502b35cfdd06c09696a20b09758d974169..16d33d831287851ef8be0dca88b6360c6f3b46ba 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <video/omapdss.h>
 #include "omap_hwmod.h"
@@ -301,7 +304,6 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
        board_data->version = ver;
        board_data->dsi_enable_pads = omap_dsi_enable_pads;
        board_data->dsi_disable_pads = omap_dsi_disable_pads;
-       board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count;
        board_data->set_min_bus_tput = omap_dss_set_min_bus_tput;
 
        omap_display_device.dev.platform_data = board_data;
@@ -552,3 +554,166 @@ int omap_dss_reset(struct omap_hwmod *oh)
 
        return r;
 }
+
+/* list of 'compatible' nodes to convert to omapdss specific */
+static const char * const dss_compat_conv_list[] __initconst = {
+       "composite-connector",
+       "dvi-connector",
+       "hdmi-connector",
+       "panel-dpi",
+       "panel-dsi-cm",
+       "sony,acx565akm",
+       "svideo-connector",
+       "ti,tfp410",
+       "ti,tpd12s015",
+};
+
+/* prepend compatible string with "omapdss," */
+static __init void omapdss_omapify_node(struct device_node *node,
+       const char *compat)
+{
+       char *new_compat;
+       struct property *prop;
+
+       new_compat = kasprintf(GFP_KERNEL, "omapdss,%s", compat);
+
+       prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+
+       if (!prop) {
+               pr_err("omapdss_omapify_node: kzalloc failed\n");
+               return;
+       }
+
+       prop->name = "compatible";
+       prop->value = new_compat;
+       prop->length = strlen(new_compat) + 1;
+
+       of_update_property(node, prop);
+}
+
+/*
+ * As omapdss panel drivers are omapdss specific, but we want to define the
+ * DT-data in generic manner, we convert the compatible strings of the panel
+ * nodes from "panel-foo" to "omapdss,panel-foo". This way we can have both
+ * correct DT data and omapdss specific drivers.
+ *
+ * When we get generic panel drivers to the kernel, this will be removed.
+ */
+void __init omapdss_early_init_of(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dss_compat_conv_list); ++i) {
+               const char *compat = dss_compat_conv_list[i];
+               struct device_node *node = NULL;
+
+               while ((node = of_find_compatible_node(node, NULL, compat))) {
+                       if (!of_device_is_available(node))
+                               continue;
+
+                       omapdss_omapify_node(node, compat);
+               }
+       }
+}
+
+struct device_node * __init omapdss_find_dss_of_node(void)
+{
+       struct device_node *node;
+
+       node = of_find_compatible_node(NULL, NULL, "ti,omap2-dss");
+       if (node)
+               return node;
+
+       node = of_find_compatible_node(NULL, NULL, "ti,omap3-dss");
+       if (node)
+               return node;
+
+       node = of_find_compatible_node(NULL, NULL, "ti,omap4-dss");
+       if (node)
+               return node;
+
+       return NULL;
+}
+
+int __init omapdss_init_of(void)
+{
+       int r;
+       enum omapdss_version ver;
+       struct device_node *node;
+       struct platform_device *pdev;
+
+       static struct omap_dss_board_info board_data = {
+               .dsi_enable_pads = omap_dsi_enable_pads,
+               .dsi_disable_pads = omap_dsi_disable_pads,
+               .set_min_bus_tput = omap_dss_set_min_bus_tput,
+       };
+
+       /* only create dss helper devices if dss is enabled in the .dts */
+
+       node = omapdss_find_dss_of_node();
+       if (!node)
+               return 0;
+
+       if (!of_device_is_available(node))
+               return 0;
+
+       ver = omap_display_get_version();
+
+       if (ver == OMAPDSS_VER_UNKNOWN) {
+               pr_err("DSS not supported on this SoC\n");
+               return -ENODEV;
+       }
+
+       pdev = of_find_device_by_node(node);
+
+       if (!pdev) {
+               pr_err("Unable to find DSS platform device\n");
+               return -ENODEV;
+       }
+
+       r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+       if (r) {
+               pr_err("Unable to populate DSS submodule devices\n");
+               return r;
+       }
+
+       board_data.version = ver;
+
+       omap_display_device.dev.platform_data = &board_data;
+
+       r = platform_device_register(&omap_display_device);
+       if (r < 0) {
+               pr_err("Unable to register omapdss device\n");
+               return r;
+       }
+
+       /* create DRM device */
+       r = omap_init_drm();
+       if (r < 0) {
+               pr_err("Unable to register omapdrm device\n");
+               return r;
+       }
+
+       /* create vrfb device */
+       r = omap_init_vrfb();
+       if (r < 0) {
+               pr_err("Unable to register omapvrfb device\n");
+               return r;
+       }
+
+       /* create FB device */
+       r = omap_init_fb();
+       if (r < 0) {
+               pr_err("Unable to register omapfb device\n");
+               return r;
+       }
+
+       /* create V4L2 display device */
+       r = omap_init_vout();
+       if (r < 0) {
+               pr_err("Unable to register omap_vout device\n");
+               return r;
+       }
+
+       return 0;
+}
index f3d2ce4bc262350420d8ff57eb4805d2894ff87a..7375854b16c7a9dd39d7ab5793adc4f1b6669ecf 100644 (file)
@@ -30,4 +30,7 @@ int omap_init_drm(void);
 int omap_init_vrfb(void);
 int omap_init_fb(void);
 int omap_init_vout(void);
+
+struct device_node * __init omapdss_find_dss_of_node(void);
+
 #endif
index 49fd0d501c9bc5edcbb83bbb234891e0c381753c..5689c88d986d64214b07c003eb11c8cbddfa05e6 100644 (file)
 #include "omap_hwmod.h"
 #include "omap_device.h"
 
-#define OMAP2_DMA_STRIDE       0x60
-
-static u32 errata;
-static u8 dma_stride;
-
-static struct omap_dma_dev_attr *d;
-
-static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
-
-static u16 reg_map[] = {
-       [REVISION]              = 0x00,
-       [GCR]                   = 0x78,
-       [IRQSTATUS_L0]          = 0x08,
-       [IRQSTATUS_L1]          = 0x0c,
-       [IRQSTATUS_L2]          = 0x10,
-       [IRQSTATUS_L3]          = 0x14,
-       [IRQENABLE_L0]          = 0x18,
-       [IRQENABLE_L1]          = 0x1c,
-       [IRQENABLE_L2]          = 0x20,
-       [IRQENABLE_L3]          = 0x24,
-       [SYSSTATUS]             = 0x28,
-       [OCP_SYSCONFIG]         = 0x2c,
-       [CAPS_0]                = 0x64,
-       [CAPS_2]                = 0x6c,
-       [CAPS_3]                = 0x70,
-       [CAPS_4]                = 0x74,
+static enum omap_reg_offsets dma_common_ch_end;
+
+static const struct omap_dma_reg reg_map[] = {
+       [REVISION]      = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
+       [GCR]           = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQSTATUS_L0]  = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQSTATUS_L1]  = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQSTATUS_L2]  = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQSTATUS_L3]  = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQENABLE_L0]  = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQENABLE_L1]  = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQENABLE_L2]  = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
+       [IRQENABLE_L3]  = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
+       [SYSSTATUS]     = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
+       [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
+       [CAPS_0]        = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
+       [CAPS_2]        = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
+       [CAPS_3]        = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
+       [CAPS_4]        = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
 
        /* Common register offsets */
-       [CCR]                   = 0x80,
-       [CLNK_CTRL]             = 0x84,
-       [CICR]                  = 0x88,
-       [CSR]                   = 0x8c,
-       [CSDP]                  = 0x90,
-       [CEN]                   = 0x94,
-       [CFN]                   = 0x98,
-       [CSEI]                  = 0xa4,
-       [CSFI]                  = 0xa8,
-       [CDEI]                  = 0xac,
-       [CDFI]                  = 0xb0,
-       [CSAC]                  = 0xb4,
-       [CDAC]                  = 0xb8,
+       [CCR]           = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
+       [CLNK_CTRL]     = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
+       [CICR]          = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
+       [CSR]           = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
+       [CSDP]          = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
+       [CEN]           = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
+       [CFN]           = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
+       [CSEI]          = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
+       [CSFI]          = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
+       [CDEI]          = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
+       [CDFI]          = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
+       [CSAC]          = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
+       [CDAC]          = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
 
        /* Channel specific register offsets */
-       [CSSA]                  = 0x9c,
-       [CDSA]                  = 0xa0,
-       [CCEN]                  = 0xbc,
-       [CCFN]                  = 0xc0,
-       [COLOR]                 = 0xc4,
+       [CSSA]          = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
+       [CDSA]          = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
+       [CCEN]          = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
+       [CCFN]          = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
+       [COLOR]         = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
 
        /* OMAP4 specific registers */
-       [CDP]                   = 0xd0,
-       [CNDP]                  = 0xd4,
-       [CCDN]                  = 0xd8,
+       [CDP]           = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
+       [CNDP]          = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
+       [CCDN]          = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
 };
 
 static void __iomem *dma_base;
 static inline void dma_write(u32 val, int reg, int lch)
 {
-       u8  stride;
-       u32 offset;
+       void __iomem *addr = dma_base;
 
-       stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
-       offset = reg_map[reg] + (stride * lch);
-       __raw_writel(val, dma_base + offset);
+       addr += reg_map[reg].offset;
+       addr += reg_map[reg].stride * lch;
+
+       __raw_writel(val, addr);
 }
 
 static inline u32 dma_read(int reg, int lch)
 {
-       u8 stride;
-       u32 offset, val;
-
-       stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
-       offset = reg_map[reg] + (stride * lch);
-       val = __raw_readl(dma_base + offset);
-       return val;
-}
+       void __iomem *addr = dma_base;
 
-static inline void omap2_disable_irq_lch(int lch)
-{
-       u32 val;
+       addr += reg_map[reg].offset;
+       addr += reg_map[reg].stride * lch;
 
-       val = dma_read(IRQENABLE_L0, lch);
-       val &= ~(1 << lch);
-       dma_write(val, IRQENABLE_L0, lch);
+       return __raw_readl(addr);
 }
 
 static void omap2_clear_dma(int lch)
 {
-       int i = dma_common_ch_start;
+       int i;
 
-       for (; i <= dma_common_ch_end; i += 1)
+       for (i = CSDP; i <= dma_common_ch_end; i += 1)
                dma_write(0, i, lch);
 }
 
@@ -137,8 +120,9 @@ static void omap2_show_dma_caps(void)
        return;
 }
 
-static u32 configure_dma_errata(void)
+static unsigned configure_dma_errata(void)
 {
+       unsigned errata = 0;
 
        /*
         * Errata applicable for OMAP2430ES1.0 and all omap2420
@@ -220,48 +204,50 @@ static u32 configure_dma_errata(void)
        return errata;
 }
 
+static struct omap_system_dma_plat_info dma_plat_info __initdata = {
+       .reg_map        = reg_map,
+       .channel_stride = 0x60,
+       .show_dma_caps  = omap2_show_dma_caps,
+       .clear_dma      = omap2_clear_dma,
+       .dma_write      = dma_write,
+       .dma_read       = dma_read,
+};
+
+static struct platform_device_info omap_dma_dev_info = {
+       .name = "omap-dma-engine",
+       .id = -1,
+       .dma_mask = DMA_BIT_MASK(32),
+};
+
 /* One time initializations */
 static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 {
        struct platform_device                  *pdev;
-       struct omap_system_dma_plat_info        *p;
+       struct omap_system_dma_plat_info        p;
+       struct omap_dma_dev_attr                *d;
        struct resource                         *mem;
        char                                    *name = "omap_dma_system";
 
-       dma_stride              = OMAP2_DMA_STRIDE;
-       dma_common_ch_start     = CSDP;
-
-       p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
-       if (!p) {
-               pr_err("%s: Unable to allocate pdata for %s:%s\n",
-                       __func__, name, oh->name);
-               return -ENOMEM;
-       }
-
-       p->dma_attr             = (struct omap_dma_dev_attr *)oh->dev_attr;
-       p->disable_irq_lch      = omap2_disable_irq_lch;
-       p->show_dma_caps        = omap2_show_dma_caps;
-       p->clear_dma            = omap2_clear_dma;
-       p->dma_write            = dma_write;
-       p->dma_read             = dma_read;
-
-       p->clear_lch_regs       = NULL;
-
-       p->errata               = configure_dma_errata();
+       p = dma_plat_info;
+       p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+       p.errata = configure_dma_errata();
 
-       pdev = omap_device_build(name, 0, oh, p, sizeof(*p));
-       kfree(p);
+       pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
        if (IS_ERR(pdev)) {
                pr_err("%s: Can't build omap_device for %s:%s.\n",
                        __func__, name, oh->name);
                return PTR_ERR(pdev);
        }
 
+       omap_dma_dev_info.res = pdev->resource;
+       omap_dma_dev_info.num_res = pdev->num_resources;
+
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mem) {
                dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
                return -EINVAL;
        }
+
        dma_base = ioremap(mem->start, resource_size(mem));
        if (!dma_base) {
                dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
@@ -269,13 +255,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
        }
 
        d = oh->dev_attr;
-       d->chan = kzalloc(sizeof(struct omap_dma_lch) *
-                                       (d->lch_count), GFP_KERNEL);
-
-       if (!d->chan) {
-               dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
-               return -ENOMEM;
-       }
 
        if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
                d->dev_caps |= HS_CHANNELS_RESERVED;
@@ -289,12 +268,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
        return 0;
 }
 
-static const struct platform_device_info omap_dma_dev_info = {
-       .name = "omap-dma-engine",
-       .id = -1,
-       .dma_mask = DMA_BIT_MASK(32),
-};
-
 static int __init omap2_system_dma_init(void)
 {
        struct platform_device *pdev;
index 3c418ea54bbe1a483ddc37759f0580ca7c949dd5..fcd8036af91041750f529c28f99d665dce86a04f 100644 (file)
@@ -525,7 +525,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
        * stuff is inherited for free
        */
 
-       if (!ret)
+       if (!ret && clk_get_parent(hw->clk) != new_parent)
                __clk_reparent(hw->clk, new_parent);
 
        return 0;
index dadccc91488c64e94c06e9bf93b54bc5c294e26e..ea2be0f5953b53d0b799f871fefd8d6bad0a7931 100644 (file)
 #include "soc.h"
 #include "dss-common.h"
 #include "mux.h"
+#include "display.h"
 
-#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
-#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
-#define HDMI_GPIO_HPD  63 /* Hotplug detect */
-
-#define PANDA_DVI_TFP410_POWER_DOWN_GPIO       0
-
-/* DVI Connector */
-static struct connector_dvi_platform_data omap4_panda_dvi_connector_pdata = {
-       .name                   = "dvi",
-       .source                 = "tfp410.0",
-       .i2c_bus_num            = 2,
-};
-
-static struct platform_device omap4_panda_dvi_connector_device = {
-       .name                   = "connector-dvi",
-       .id                     = 0,
-       .dev.platform_data      = &omap4_panda_dvi_connector_pdata,
-};
-
-/* TFP410 DPI-to-DVI chip */
-static struct encoder_tfp410_platform_data omap4_panda_tfp410_pdata = {
-       .name                   = "tfp410.0",
-       .source                 = "dpi.0",
-       .data_lines             = 24,
-       .power_down_gpio        = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
-};
-
-static struct platform_device omap4_panda_tfp410_device = {
-       .name                   = "tfp410",
-       .id                     = 0,
-       .dev.platform_data      = &omap4_panda_tfp410_pdata,
-};
-
-/* HDMI Connector */
-static struct connector_hdmi_platform_data omap4_panda_hdmi_connector_pdata = {
-       .name                   = "hdmi",
-       .source                 = "tpd12s015.0",
-};
-
-static struct platform_device omap4_panda_hdmi_connector_device = {
-       .name                   = "connector-hdmi",
-       .id                     = 0,
-       .dev.platform_data      = &omap4_panda_hdmi_connector_pdata,
-};
-
-/* TPD12S015 HDMI ESD protection & level shifter chip */
-static struct encoder_tpd12s015_platform_data omap4_panda_tpd_pdata = {
-       .name                   = "tpd12s015.0",
-       .source                 = "hdmi.0",
-
-       .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
-       .ls_oe_gpio = HDMI_GPIO_LS_OE,
-       .hpd_gpio = HDMI_GPIO_HPD,
-};
-
-static struct platform_device omap4_panda_tpd_device = {
-       .name                   = "tpd12s015",
-       .id                     = 0,
-       .dev.platform_data      = &omap4_panda_tpd_pdata,
-};
-
-static struct omap_dss_board_info omap4_panda_dss_data = {
-       .default_display_name = "dvi",
-};
-
-void __init omap4_panda_display_init_of(void)
-{
-       omap_display_init(&omap4_panda_dss_data);
-
-       platform_device_register(&omap4_panda_tfp410_device);
-       platform_device_register(&omap4_panda_dvi_connector_device);
-
-       platform_device_register(&omap4_panda_tpd_device);
-       platform_device_register(&omap4_panda_hdmi_connector_device);
-}
-
-
-/* OMAP4 Blaze display data */
-
-#define DISPLAY_SEL_GPIO       59      /* LCD2/PicoDLP switch */
-#define DLP_POWER_ON_GPIO      40
-
-static struct panel_dsicm_platform_data dsi1_panel = {
-       .name           = "lcd",
-       .source         = "dsi.0",
-       .reset_gpio     = 102,
-       .use_ext_te     = false,
-       .ext_te_gpio    = 101,
-       .pin_config = {
-               .num_pins       = 6,
-               .pins           = { 0, 1, 2, 3, 4, 5 },
-       },
-};
-
-static struct platform_device sdp4430_lcd_device = {
-       .name                   = "panel-dsi-cm",
-       .id                     = 0,
-       .dev.platform_data      = &dsi1_panel,
-};
-
-static struct panel_dsicm_platform_data dsi2_panel = {
-       .name           = "lcd2",
-       .source         = "dsi.1",
-       .reset_gpio     = 104,
-       .use_ext_te     = false,
-       .ext_te_gpio    = 103,
-       .pin_config = {
-               .num_pins       = 6,
-               .pins           = { 0, 1, 2, 3, 4, 5 },
-       },
-};
-
-static struct platform_device sdp4430_lcd2_device = {
-       .name                   = "panel-dsi-cm",
-       .id                     = 1,
-       .dev.platform_data      = &dsi2_panel,
-};
-
-/* HDMI Connector */
-static struct connector_hdmi_platform_data sdp4430_hdmi_connector_pdata = {
-       .name                   = "hdmi",
-       .source                 = "tpd12s015.0",
-};
-
-static struct platform_device sdp4430_hdmi_connector_device = {
-       .name                   = "connector-hdmi",
-       .id                     = 0,
-       .dev.platform_data      = &sdp4430_hdmi_connector_pdata,
-};
-
-/* TPD12S015 HDMI ESD protection & level shifter chip */
-static struct encoder_tpd12s015_platform_data sdp4430_tpd_pdata = {
-       .name                   = "tpd12s015.0",
-       .source                 = "hdmi.0",
-
-       .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
-       .ls_oe_gpio = HDMI_GPIO_LS_OE,
-       .hpd_gpio = HDMI_GPIO_HPD,
-};
-
-static struct platform_device sdp4430_tpd_device = {
-       .name                   = "tpd12s015",
-       .id                     = 0,
-       .dev.platform_data      = &sdp4430_tpd_pdata,
-};
-
-
-static struct omap_dss_board_info sdp4430_dss_data = {
-       .default_display_name = "lcd",
-};
-
-/*
- * we select LCD2 by default (instead of Pico DLP) by setting DISPLAY_SEL_GPIO.
- * Setting DLP_POWER_ON gpio enables the VDLP_2V5 VDLP_1V8 and VDLP_1V0 rails
- * used by picodlp on the 4430sdp platform. Keep this gpio disabled as LCD2 is
- * selected by default
- */
-void __init omap_4430sdp_display_init_of(void)
-{
-       int r;
-
-       r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH,
-                       "display_sel");
-       if (r)
-               pr_err("%s: Could not get display_sel GPIO\n", __func__);
-
-       r = gpio_request_one(DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
-               "DLP POWER ON");
-       if (r)
-               pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__);
-
-       omap_display_init(&sdp4430_dss_data);
-
-       platform_device_register(&sdp4430_lcd_device);
-       platform_device_register(&sdp4430_lcd2_device);
-
-       platform_device_register(&sdp4430_tpd_device);
-       platform_device_register(&sdp4430_hdmi_connector_device);
-}
-
-
-/* OMAP3 IGEPv2 data */
-
-#define IGEP2_DVI_TFP410_POWER_DOWN_GPIO       170
-
-/* DVI Connector */
-static struct connector_dvi_platform_data omap3_igep2_dvi_connector_pdata = {
-       .name                   = "dvi",
-       .source                 = "tfp410.0",
-       .i2c_bus_num            = 2,
-};
-
-static struct platform_device omap3_igep2_dvi_connector_device = {
-       .name                   = "connector-dvi",
-       .id                     = 0,
-       .dev.platform_data      = &omap3_igep2_dvi_connector_pdata,
-};
-
-/* TFP410 DPI-to-DVI chip */
-static struct encoder_tfp410_platform_data omap3_igep2_tfp410_pdata = {
-       .name                   = "tfp410.0",
-       .source                 = "dpi.0",
-       .data_lines             = 24,
-       .power_down_gpio        = IGEP2_DVI_TFP410_POWER_DOWN_GPIO,
-};
-
-static struct platform_device omap3_igep2_tfp410_device = {
-       .name                   = "tfp410",
-       .id                     = 0,
-       .dev.platform_data      = &omap3_igep2_tfp410_pdata,
-};
-
-static struct omap_dss_board_info igep2_dss_data = {
-       .default_display_name = "dvi",
-};
-
-void __init omap3_igep2_display_init_of(void)
-{
-       omap_display_init(&igep2_dss_data);
-
-       platform_device_register(&omap3_igep2_tfp410_device);
-       platform_device_register(&omap3_igep2_dvi_connector_device);
-}
index 174caecc3186cbe6d25cb998be40a32478042484..4349e82debfeac3196363d1ddad7f5d1340f6e94 100644 (file)
@@ -45,24 +45,31 @@ static struct platform_device gpmc_nand_device = {
 
 static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
 {
-       /* support only OMAP3 class */
-       if (!cpu_is_omap34xx() && !soc_is_am33xx()) {
-               pr_err("BCH ecc is not supported on this CPU\n");
+       /* platforms which support all ECC schemes */
+       if (soc_is_am33xx() || cpu_is_omap44xx() ||
+                soc_is_omap54xx() || soc_is_dra7xx())
+               return 1;
+
+       /* OMAP3xxx do not have ELM engine, so cannot support ECC schemes
+        * which require H/W based ECC error detection */
+       if ((cpu_is_omap34xx() || cpu_is_omap3630()) &&
+           ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
+                (ecc_opt == OMAP_ECC_BCH8_CODE_HW)))
                return 0;
-       }
 
        /*
         * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1
         * and AM33xx derivates. Other chips may be added if confirmed to work.
         */
-       if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) &&
-           (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0)) &&
-           (!soc_is_am33xx())) {
-               pr_err("BCH 4-bit mode is not supported on this CPU\n");
+       if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) &&
+           (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0)))
                return 0;
-       }
 
-       return 1;
+       /* legacy platforms support only HAM1 (1-bit Hamming) ECC scheme */
+       if (ecc_opt == OMAP_ECC_HAM1_CODE_HW)
+               return 1;
+       else
+               return 0;
 }
 
 /* This function will go away once the device-tree convertion is complete */
@@ -133,8 +140,10 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 
        gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
 
-       if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt))
+       if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
+               dev_err(dev, "Unsupported NAND ECC scheme selected\n");
                return -EINVAL;
+       }
 
        err = platform_device_register(&gpmc_nand_device);
        if (err < 0) {
index 9428c5f9d4f2faa47e91a2caa193ecf39bba39fb..157412e4273a60fd379cb8426263b93c5eea141d 100644 (file)
@@ -465,8 +465,18 @@ void __init omap3xxx_check_revision(void)
                }
                break;
        case 0xb98c:
-               omap_revision = AM437X_REV_ES1_0;
-               cpu_rev = "1.0";
+               switch (rev) {
+               case 0:
+                       omap_revision = AM437X_REV_ES1_0;
+                       cpu_rev = "1.0";
+                       break;
+               case 1:
+               /* FALLTHROUGH */
+               default:
+                       omap_revision = AM437X_REV_ES1_1;
+                       cpu_rev = "1.1";
+                       break;
+               }
                break;
        case 0xb8f2:
                switch (rev) {
@@ -657,6 +667,8 @@ static const char * __init omap_get_family(void)
                return kasprintf(GFP_KERNEL, "OMAP4");
        else if (soc_is_omap54xx())
                return kasprintf(GFP_KERNEL, "OMAP5");
+       else if (soc_is_am43xx())
+               return kasprintf(GFP_KERNEL, "AM43xx");
        else
                return kasprintf(GFP_KERNEL, "Unknown");
 }
diff --git a/arch/arm/mach-omap2/include/mach/timex.h b/arch/arm/mach-omap2/include/mach/timex.h
deleted file mode 100644 (file)
index de9f8fc..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-omap2/include/mach/timex.h
- */
-
-#include <plat/timex.h>
index af432b191255030a7c8fda2be849be0a75620482..f14f9ac2dca133e4e175cc9ceff96c807e941631 100644 (file)
@@ -604,6 +604,7 @@ void __init am43xx_init_early(void)
        omap_prm_base_init();
        omap_cm_base_init();
        omap3xxx_check_revision();
+       am33xx_check_features();
        am43xx_powerdomains_init();
        am43xx_clockdomains_init();
        am43xx_hwmod_init();
index e022a869bff23894dd28f24274564026841e8608..6037a9a01ed529c1fd4842d5b8819ad21db10d00 100644 (file)
@@ -222,6 +222,7 @@ void __init ti81xx_init_irq(void)
 static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
 {
        u32 irqnr;
+       int handled_irq = 0;
 
        do {
                irqnr = readl_relaxed(base_addr + 0x98);
@@ -249,8 +250,15 @@ out:
                if (irqnr) {
                        irqnr = irq_find_mapping(domain, irqnr);
                        handle_IRQ(irqnr, regs);
+                       handled_irq = 1;
                }
        } while (irqnr);
+
+       /* If an irq is masked or deasserted while active, we will
+        * keep ending up here with no irq handled. So remove it from
+        * the INTC with an ack.*/
+       if (!handled_irq)
+               omap_ack_irq(NULL);
 }
 
 asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs)
index a722330d4d53deb4888df89704c81c1a42936412..d121fb6df4e632e897f5016d944c1b8c07027d3f 100644 (file)
@@ -63,9 +63,6 @@
 #define OMAP_PACKAGE_CUS               5               /* 423-pin 0.65 */
 #define OMAP_PACKAGE_CBB               4               /* 515-pin 0.40 0.50 */
 #define OMAP_PACKAGE_CBC               3               /* 515-pin 0.50 0.65 */
-#define OMAP_PACKAGE_ZAC               2               /* 24xx 447-pin POP */
-#define OMAP_PACKAGE_ZAF               1               /* 2420 447-pin SIP */
-
 
 #define OMAP_MUX_NR_MODES              8               /* Available modes */
 #define OMAP_MUX_NR_SIDES              2               /* Bottom & top */
index f6daae821ebb70e9cd09d2a9f82edfb54885ee47..f1fab5684a24b1fc26a20b180305398be5165c65 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/of.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
@@ -58,6 +59,10 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
 
 static int __init omap_iommu_init(void)
 {
+       /* If dtb is there, the devices will be created dynamically */
+       if (of_have_populated_dt())
+               return -ENODEV;
+
        return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
 }
 /* must be ready before omap3isp is probed */
index 3664562f91481e76487ff77ef8e133ccd7edfaab..693fe486e9172d987879655efc799b531d01bd34 100644 (file)
@@ -138,7 +138,7 @@ static void wakeupgen_mask(struct irq_data *d)
        unsigned long flags;
 
        raw_spin_lock_irqsave(&wakeupgen_lock, flags);
-       _wakeupgen_clear(d->irq, irq_target_cpu[d->irq]);
+       _wakeupgen_clear(d->hwirq, irq_target_cpu[d->hwirq]);
        raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
 }
 
@@ -150,7 +150,7 @@ static void wakeupgen_unmask(struct irq_data *d)
        unsigned long flags;
 
        raw_spin_lock_irqsave(&wakeupgen_lock, flags);
-       _wakeupgen_set(d->irq, irq_target_cpu[d->irq]);
+       _wakeupgen_set(d->hwirq, irq_target_cpu[d->hwirq]);
        raw_spin_unlock_irqrestore(&wakeupgen_lock, flags);
 }
 
index 6cd3f3772ecf4ed5fa83aa4c70ff83cad98db9f6..95e171a055f34a87e8096f5ffacf69e8fe1cd13a 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/export.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/irqchip/irq-crossbar.h>
 #include <linux/of_address.h>
 #include <linux/reboot.h>
 
@@ -288,5 +289,8 @@ void __init omap_gic_of_init(void)
 
 skip_errata_init:
        omap_wakeupgen_init();
+#ifdef CONFIG_IRQ_CROSSBAR
+       irqcrossbar_init();
+#endif
        irqchip_init();
 }
index 4c3b1e6df50806700cbcfc3c4f582650b36cc3a3..a123ff0070bd65138394fa6248f611ef2cc10573 100644 (file)
@@ -1955,10 +1955,6 @@ static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
        .sysc = &omap3xxx_usb_host_hs_sysc,
 };
 
-static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = {
-         { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", },
-};
-
 static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
        { .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
        { .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
@@ -1981,8 +1977,6 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
                        .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
                },
        },
-       .opt_clks       = omap3xxx_usb_host_hs_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks),
 
        /*
         * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
@@ -3029,8 +3023,6 @@ static struct omap_hwmod omap3xxx_mmu_isp_hwmod = {
        .flags          = HWMOD_NO_IDLEST,
 };
 
-#ifdef CONFIG_OMAP_IOMMU_IVA2
-
 /* mmu iva */
 
 static struct omap_mmu_dev_attr mmu_iva_dev_attr = {
@@ -3070,20 +3062,22 @@ static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
        .name           = "mmu_iva",
        .class          = &omap3xxx_mmu_hwmod_class,
        .mpu_irqs       = omap3xxx_mmu_iva_irqs,
+       .clkdm_name     = "iva2_clkdm",
        .rst_lines      = omap3xxx_mmu_iva_resets,
        .rst_lines_cnt  = ARRAY_SIZE(omap3xxx_mmu_iva_resets),
        .main_clk       = "iva2_ck",
        .prcm = {
                .omap2 = {
                        .module_offs = OMAP3430_IVA2_MOD,
+                       .module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+                       .idlest_reg_id = 1,
+                       .idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT,
                },
        },
        .dev_attr       = &mmu_iva_dev_attr,
        .flags          = HWMOD_NO_IDLEST,
 };
 
-#endif
-
 /* l4_per -> gpio4 */
 static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
        {
@@ -3855,9 +3849,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l4_core__hdq1w,
        &omap3xxx_sad2d__l3,
        &omap3xxx_l4_core__mmu_isp,
-#ifdef CONFIG_OMAP_IOMMU_IVA2
        &omap3xxx_l3_main__mmu_iva,
-#endif
        &omap34xx_l4_core__ssi,
        NULL
 };
@@ -3881,9 +3873,7 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l4_core__hdq1w,
        &omap3xxx_sad2d__l3,
        &omap3xxx_l4_core__mmu_isp,
-#ifdef CONFIG_OMAP_IOMMU_IVA2
        &omap3xxx_l3_main__mmu_iva,
-#endif
        NULL
 };
 
index 9002fca766991eb1f6eb850c60bf0fa818e4d26e..5c2cc8083fdd9ba22087f1add79f061a4d5d28b2 100644 (file)
@@ -719,6 +719,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l4_ls__uart4,
        &am33xx_l4_ls__uart5,
        &am33xx_l4_ls__uart6,
+       &am33xx_l4_ls__spinlock,
        &am33xx_l4_ls__elm,
        &am33xx_l4_ls__epwmss0,
        &am33xx_epwmss0__ecap0,
index 3318cae96e7d1e94a8699192d1c00512c8f34f38..1219280bb97628e437236ef06e2318124347171a 100644 (file)
@@ -2541,8 +2541,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_spinlock_sysc = {
        .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
                           SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
                           SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
        .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
index e297d6231c3aa3c35910d25f3115466be2d453ab..892317294fdc0812965910a05f1d895d4c2a03cd 100644 (file)
@@ -1121,6 +1121,71 @@ static struct omap_hwmod omap54xx_mmc5_hwmod = {
        },
 };
 
+/*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_mmu_sysc = {
+       .rev_offs       = 0x0000,
+       .sysc_offs      = 0x0010,
+       .syss_offs      = 0x0014,
+       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+                          SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_mmu_hwmod_class = {
+       .name = "mmu",
+       .sysc = &omap54xx_mmu_sysc,
+};
+
+static struct omap_hwmod_rst_info omap54xx_mmu_dsp_resets[] = {
+       { .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod omap54xx_mmu_dsp_hwmod = {
+       .name           = "mmu_dsp",
+       .class          = &omap54xx_mmu_hwmod_class,
+       .clkdm_name     = "dsp_clkdm",
+       .rst_lines      = omap54xx_mmu_dsp_resets,
+       .rst_lines_cnt  = ARRAY_SIZE(omap54xx_mmu_dsp_resets),
+       .main_clk       = "dpll_iva_h11x2_ck",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET,
+                       .rstctrl_offs = OMAP54XX_RM_DSP_RSTCTRL_OFFSET,
+                       .context_offs = OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET,
+                       .modulemode   = MODULEMODE_HWCTRL,
+               },
+       },
+};
+
+/* mmu ipu */
+static struct omap_hwmod_rst_info omap54xx_mmu_ipu_resets[] = {
+       { .name = "mmu_cache", .rst_shift = 2 },
+};
+
+static struct omap_hwmod omap54xx_mmu_ipu_hwmod = {
+       .name           = "mmu_ipu",
+       .class          = &omap54xx_mmu_hwmod_class,
+       .clkdm_name     = "ipu_clkdm",
+       .rst_lines      = omap54xx_mmu_ipu_resets,
+       .rst_lines_cnt  = ARRAY_SIZE(omap54xx_mmu_ipu_resets),
+       .main_clk       = "dpll_core_h22x2_ck",
+       .prcm = {
+               .omap4 = {
+                       .clkctrl_offs = OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET,
+                       .rstctrl_offs = OMAP54XX_RM_IPU_RSTCTRL_OFFSET,
+                       .context_offs = OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET,
+                       .modulemode   = MODULEMODE_HWCTRL,
+               },
+       },
+};
+
 /*
  * 'mpu' class
  * mpu sub-system
@@ -1763,6 +1828,14 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_1 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_cfg -> mmu_dsp */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mmu_dsp = {
+       .master         = &omap54xx_l4_cfg_hwmod,
+       .slave          = &omap54xx_mmu_dsp_hwmod,
+       .clk            = "l4_root_clk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* mpu -> l3_main_1 */
 static struct omap_hwmod_ocp_if omap54xx_mpu__l3_main_1 = {
        .master         = &omap54xx_mpu_hwmod,
@@ -1787,6 +1860,14 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_2 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l3_main_2 -> mmu_ipu */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__mmu_ipu = {
+       .master         = &omap54xx_l3_main_2_hwmod,
+       .slave          = &omap54xx_mmu_ipu_hwmod,
+       .clk            = "l3_iclk_div",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 /* l3_main_1 -> l3_main_3 */
 static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_3 = {
        .master         = &omap54xx_l3_main_1_hwmod,
@@ -2345,6 +2426,7 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l4_wkup__counter_32k,
        &omap54xx_l4_cfg__dma_system,
        &omap54xx_l4_abe__dmic,
+       &omap54xx_l4_cfg__mmu_dsp,
        &omap54xx_mpu__emif1,
        &omap54xx_mpu__emif2,
        &omap54xx_l4_wkup__gpio1,
@@ -2360,6 +2442,7 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l4_per__i2c3,
        &omap54xx_l4_per__i2c4,
        &omap54xx_l4_per__i2c5,
+       &omap54xx_l3_main_2__mmu_ipu,
        &omap54xx_l4_wkup__kbd,
        &omap54xx_l4_cfg__mailbox,
        &omap54xx_l4_abe__mcbsp1,
index c33e07e2f0d4e3d01b9e58e6347d4ca42ed81a18..c3b73351cb7af37343c7ada35c6e43c581fd04fc 100644 (file)
 #include <linux/wl12xx.h>
 
 #include <linux/platform_data/pinctrl-single.h>
+#include <linux/platform_data/iommu-omap.h>
 
 #include "am35xx.h"
 #include "common.h"
 #include "common-board-devices.h"
 #include "dss-common.h"
 #include "control.h"
+#include "omap_device.h"
 #include "omap-secure.h"
 #include "soc.h"
 
@@ -33,20 +35,6 @@ struct pdata_init {
 struct of_dev_auxdata omap_auxdata_lookup[];
 static struct twl4030_gpio_platform_data twl_gpio_auxdata;
 
-/*
- * Create alias for USB host PHY clock.
- * Remove this when clock phandle can be provided via DT
- */
-static void __init __used legacy_init_ehci_clk(char *clkname)
-{
-       int ret;
-
-       ret = clk_add_alias("main_clk", NULL, clkname, NULL);
-       if (ret)
-               pr_err("%s:Failed to add main_clk alias to %s :%d\n",
-                      __func__, clkname, ret);
-}
-
 #if IS_ENABLED(CONFIG_WL12XX)
 
 static struct wl12xx_platform_data wl12xx __initdata;
@@ -94,6 +82,12 @@ static void __init hsmmc2_internal_input_clk(void)
        omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1);
 }
 
+static struct iommu_platform_data omap3_iommu_pdata = {
+       .reset_name = "mmu",
+       .assert_reset = omap_device_assert_hardreset,
+       .deassert_reset = omap_device_deassert_hardreset,
+};
+
 static int omap3_sbc_t3730_twl_callback(struct device *dev,
                                           unsigned gpio,
                                           unsigned ngpio)
@@ -101,7 +95,7 @@ static int omap3_sbc_t3730_twl_callback(struct device *dev,
        int res;
 
        res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
-                              "wlan rst");
+                              "wlan pwr");
        if (res)
                return res;
 
@@ -110,6 +104,23 @@ static int omap3_sbc_t3730_twl_callback(struct device *dev,
        return 0;
 }
 
+static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name)
+{
+       int err = gpio_request_one(gpio, GPIOF_OUT_INIT_LOW, hub_name);
+
+       if (err) {
+               pr_err("SBC-T3x: %s reset gpio request failed: %d\n",
+                       hub_name, err);
+               return;
+       }
+
+       gpio_export(gpio, 0);
+
+       udelay(10);
+       gpio_set_value(gpio, 1);
+       msleep(1);
+}
+
 static void __init omap3_sbc_t3730_twl_init(void)
 {
        twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback;
@@ -117,13 +128,19 @@ static void __init omap3_sbc_t3730_twl_init(void)
 
 static void __init omap3_sbc_t3730_legacy_init(void)
 {
+       omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 136);
        omap_ads7846_init(1, 57, 0, NULL);
 }
 
+static void __init omap3_sbc_t3530_legacy_init(void)
+{
+       omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
+       omap_ads7846_init(1, 57, 0, NULL);
+}
+
 static void __init omap3_igep0020_legacy_init(void)
 {
-       omap3_igep2_display_init_of();
 }
 
 static void __init omap3_evm_legacy_init(void)
@@ -162,7 +179,7 @@ static struct emac_platform_data am35xx_emac_pdata = {
        .interrupt_disable      = am35xx_disable_emac_int,
 };
 
-static void __init am3517_evm_legacy_init(void)
+static void __init am35xx_emac_reset(void)
 {
        u32 v;
 
@@ -172,6 +189,43 @@ static void __init am3517_evm_legacy_init(void)
        omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
 }
 
+static struct gpio cm_t3517_wlan_gpios[] __initdata = {
+       { 56,   GPIOF_OUT_INIT_HIGH,    "wlan pwr" },
+       { 4,    GPIOF_OUT_INIT_HIGH,    "xcvr noe" },
+};
+
+static void __init omap3_sbc_t3517_wifi_init(void)
+{
+       int err = gpio_request_array(cm_t3517_wlan_gpios,
+                               ARRAY_SIZE(cm_t3517_wlan_gpios));
+       if (err) {
+               pr_err("SBC-T3517: wl12xx gpios request failed: %d\n", err);
+               return;
+       }
+
+       gpio_export(cm_t3517_wlan_gpios[0].gpio, 0);
+       gpio_export(cm_t3517_wlan_gpios[1].gpio, 0);
+
+       msleep(100);
+       gpio_set_value(cm_t3517_wlan_gpios[1].gpio, 0);
+}
+
+static void __init omap3_sbc_t3517_legacy_init(void)
+{
+       omap3_sbc_t3x_usb_hub_init(152, "cm-t3517 usb hub");
+       omap3_sbc_t3x_usb_hub_init(98, "sb-t35 usb hub");
+       am35xx_emac_reset();
+       hsmmc2_internal_input_clk();
+       omap3_sbc_t3517_wifi_init();
+       legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 145);
+       omap_ads7846_init(1, 57, 0, NULL);
+}
+
+static void __init am3517_evm_legacy_init(void)
+{
+       am35xx_emac_reset();
+}
+
 static void __init nokia_n900_legacy_init(void)
 {
        hsmmc2_internal_input_clk();
@@ -192,23 +246,34 @@ static void __init nokia_n900_legacy_init(void)
 #ifdef CONFIG_ARCH_OMAP4
 static void __init omap4_sdp_legacy_init(void)
 {
-       omap_4430sdp_display_init_of();
        legacy_init_wl12xx(WL12XX_REFCLOCK_26,
                           WL12XX_TCXOCLOCK_26, 53);
 }
 
 static void __init omap4_panda_legacy_init(void)
 {
-       omap4_panda_display_init_of();
-       legacy_init_ehci_clk("auxclk3_ck");
        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53);
 }
 #endif
 
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+static struct iommu_platform_data omap4_iommu_pdata = {
+       .reset_name = "mmu_cache",
+       .assert_reset = omap_device_assert_hardreset,
+       .deassert_reset = omap_device_deassert_hardreset,
+};
+#endif
+
+#ifdef CONFIG_SOC_AM33XX
+static void __init am335x_evmsk_legacy_init(void)
+{
+       legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 31);
+}
+#endif
+
 #ifdef CONFIG_SOC_OMAP5
 static void __init omap5_uevm_legacy_init(void)
 {
-       legacy_init_ehci_clk("auxclk1_ck");
 }
 #endif
 
@@ -259,6 +324,8 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
        OF_DEV_AUXDATA("ti,omap3-padconf", 0x480025a0, "480025a0.pinmux", &pcs_pdata),
        OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata),
+       OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu",
+                      &omap3_iommu_pdata),
        /* Only on am3517 */
        OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
        OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
@@ -267,6 +334,12 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 #ifdef CONFIG_ARCH_OMAP4
        OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
        OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
+#endif
+#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
+       OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
+                      &omap4_iommu_pdata),
+       OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
+                      &omap4_iommu_pdata),
 #endif
        { /* sentinel */ },
 };
@@ -277,6 +350,8 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
  */
 static struct pdata_init pdata_quirks[] __initdata = {
 #ifdef CONFIG_ARCH_OMAP3
+       { "compulab,omap3-sbc-t3517", omap3_sbc_t3517_legacy_init, },
+       { "compulab,omap3-sbc-t3530", omap3_sbc_t3530_legacy_init, },
        { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, },
        { "nokia,omap3-n900", nokia_n900_legacy_init, },
        { "nokia,omap3-n9", hsmmc2_internal_input_clk, },
@@ -290,6 +365,9 @@ static struct pdata_init pdata_quirks[] __initdata = {
        { "ti,omap4-sdp", omap4_sdp_legacy_init, },
        { "ti,omap4-panda", omap4_panda_legacy_init, },
 #endif
+#ifdef CONFIG_SOC_AM33XX
+       { "ti,am335x-evmsk", am335x_evmsk_legacy_init, },
+#endif
 #ifdef CONFIG_SOC_OMAP5
        { "ti,omap5-uevm", omap5_uevm_legacy_init, },
 #endif
index 7bdd22afce69b9110006f489eb80495b3f53bb38..d4d0fce325c7f88ffa594c4d76ce8e69efd77816 100644 (file)
@@ -103,7 +103,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
 
 #define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD     (1 << 0)
 
-#if defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
 extern u16 pm44xx_errata;
 #define IS_PM44XX_ERRATUM(id)          (pm44xx_errata & (id))
 #else
index 280f3c58abe505c9047e6027071ec8bafd720c57..05fcf6de44ee51a0377771ef518e71e04d491b2d 100644 (file)
@@ -25,6 +25,7 @@
 #include "prminst44xx.h"
 #include "prm-regbits-44xx.h"
 #include "prcm44xx.h"
+#include "prcm43xx.h"
 #include "prcm_mpu44xx.h"
 #include "soc.h"
 
@@ -176,6 +177,8 @@ void omap4_prminst_global_warm_sw_reset(void)
                dev_inst = OMAP54XX_PRM_DEVICE_INST;
        else if (soc_is_dra7xx())
                dev_inst = DRA7XX_PRM_DEVICE_INST;
+       else if (soc_is_am43xx())
+               dev_inst = AM43XX_PRM_DEVICE_INST;
        else
                return;
 
index 076bd90a6ce0aca8d30914432c293dee1dbb071d..30abcc8b20e007eb878c8d10519ba2759f17d21c 100644 (file)
@@ -438,7 +438,8 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define AM335X_REV_ES2_1       (AM335X_CLASS | (0x2 << 8))
 
 #define AM437X_CLASS           0x43700000
-#define AM437X_REV_ES1_0       AM437X_CLASS
+#define AM437X_REV_ES1_0       (AM437X_CLASS | (0x10 << 8))
+#define AM437X_REV_ES1_1       (AM437X_CLASS | (0x11 << 8))
 
 #define OMAP443X_CLASS         0x44300044
 #define OMAP4430_REV_ES1_0     (OMAP443X_CLASS | (0x10 << 8))
index 74044aaf438b6f2c5fa9c093d40e15077b06f153..b62de9f9d05c1efa2bc8a88683fbcf24c25fe9db 100644 (file)
@@ -604,7 +604,8 @@ OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
                        2, "timer_sys_ck", NULL);
 #endif /* CONFIG_ARCH_OMAP3 */
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
+       defined(CONFIG_SOC_AM43XX)
 OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL,
                       1, "timer_sys_ck", "ti,timer-alwon");
 #endif
index 2cb2f06c20f59130e2b34fc793c67b2a65be3043..14f2cae4109ca10fc61962b4d787a5f89ed70097 100644 (file)
@@ -33,7 +33,6 @@ config MACH_KUROBOX_PRO
 config MACH_DNS323
        bool "D-Link DNS-323"
        select I2C_BOARDINFO
-       select PHYLIB
        help
          Say 'Y' here if you want your kernel to support the
          D-Link DNS-323 platform.
index 70974732cbf0eb541af1f5512567638638d088c8..56edeab17b68dedf77f538fd5fdb1d2465598dab 100644 (file)
@@ -642,6 +642,8 @@ static void __init dns323_init(void)
                platform_device_register_simple("dns323c-fan", 0, NULL, 0);
 
                /* Register fixup for the PHY LEDs */
+               if (!IS_BUILTIN(CONFIG_PHYLIB))
+                       break;
                phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1118,
                                           MARVELL_PHY_ID_MASK,
                                           dns323c_phy_fixup);
index f727d03f16885491dbe81dff36b74a90f6d1d874..5766e3fbff698f47ee033592c174b3cd922a0c32 100644 (file)
@@ -18,6 +18,7 @@
 #define CPU_CTRL               (ORION5X_BRIDGE_VIRT_BASE + 0x104)
 
 #define RSTOUTn_MASK           (ORION5X_BRIDGE_VIRT_BASE + 0x108)
+#define RSTOUTn_MASK_PHYS      (ORION5X_BRIDGE_PHYS_BASE + 0x108)
 
 #define CPU_SOFT_RESET         (ORION5X_BRIDGE_VIRT_BASE + 0x10c)
 
diff --git a/arch/arm/mach-orion5x/include/mach/timex.h b/arch/arm/mach-orion5x/include/mach/timex.h
deleted file mode 100644 (file)
index 4c69820..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/timex.h
- *
- * Tzachi Perelstein <tzachi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#define CLOCK_TICK_RATE                (100 * HZ)
index b1022f4315f7f381accd63b6202acce59a236433..eca9eb1c59316ebabb8f2771905c5766951eeaab 100644 (file)
@@ -1,12 +1,7 @@
 config ARCH_PICOXCELL
        bool "Picochip PicoXcell" if ARCH_MULTI_V6
        select ARCH_REQUIRE_GPIOLIB
-       select ARM_PATCH_PHYS_VIRT
        select ARM_VIC
-       select CPU_V6K
        select DW_APB_TIMER_OF
-       select GENERIC_CLOCKEVENTS
        select HAVE_TCM
        select NO_IOPORT
-       select SPARSE_IRQ
-       select USE_OF
index 6988b117fc174a70e049df575417dea3093daa1b..3e8189186a5b50f9e8906231c6f46f2e81641a9e 100644 (file)
@@ -1,9 +1,8 @@
 config ARCH_SIRF
        bool "CSR SiRF" if ARCH_MULTI_V7
+       select ARCH_HAS_RESET_CONTROLLER
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select MIGHT_HAVE_CACHE_L2X0
        select NO_IOPORT
        select PINCTRL
        select PINCTRL_SIRF
@@ -17,7 +16,6 @@ menu "CSR SiRF atlas6/primaII/Marco/Polo Specific Features"
 config ARCH_ATLAS6
        bool "CSR SiRFSoC ATLAS6 ARM Cortex A9 Platform"
        default y
-       select CPU_V7
        select SIRF_IRQ
        help
           Support for CSR SiRFSoC ARM Cortex A9 Platform
@@ -25,7 +23,6 @@ config ARCH_ATLAS6
 config ARCH_PRIMA2
        bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
        default y
-       select CPU_V7
        select SIRF_IRQ
        select ZONE_DMA
        help
@@ -35,9 +32,7 @@ config ARCH_MARCO
        bool "CSR SiRFSoC MARCO ARM Cortex A9 Platform"
        default y
        select ARM_GIC
-       select CPU_V7
        select HAVE_ARM_SCU if SMP
-       select HAVE_SMP
        select SMP_ON_UP if SMP
        help
           Support for CSR SiRFSoC ARM Cortex A9 Platform
index d49aff74de98a778c14dfc495718adfc6e15fdb6..47c7819edb9bbd56c291ab6f0902c047214aedbf 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/of_platform.h>
 #include "common.h"
 
-void __init sirfsoc_init_late(void)
+static void __init sirfsoc_init_late(void)
 {
        sirfsoc_pm_init();
 }
@@ -27,7 +27,7 @@ static __init void sirfsoc_map_io(void)
 }
 
 #ifdef CONFIG_ARCH_ATLAS6
-static const char *atlas6_dt_match[] __initdata = {
+static const char *atlas6_dt_match[] __initconst = {
        "sirf,atlas6",
        NULL
 };
@@ -37,12 +37,11 @@ DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)")
        .map_io         = sirfsoc_map_io,
        .init_late      = sirfsoc_init_late,
        .dt_compat      = atlas6_dt_match,
-       .restart        = sirfsoc_restart,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_ARCH_PRIMA2
-static const char *prima2_dt_match[] __initdata = {
+static const char *prima2_dt_match[] __initconst = {
        "sirf,prima2",
        NULL
 };
@@ -53,12 +52,11 @@ DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
        .dma_zone_size  = SZ_256M,
        .init_late      = sirfsoc_init_late,
        .dt_compat      = prima2_dt_match,
-       .restart        = sirfsoc_restart,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_ARCH_MARCO
-static const char *marco_dt_match[] __initdata = {
+static const char *marco_dt_match[] __initconst = {
        "sirf,marco",
        NULL
 };
@@ -69,6 +67,5 @@ DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)")
        .map_io         = sirfsoc_map_io,
        .init_late      = sirfsoc_init_late,
        .dt_compat      = marco_dt_match,
-       .restart        = sirfsoc_restart,
 MACHINE_END
 #endif
index 4b768060a858e98c51a085e192cf0e6c43a3c198..07d3e5ed9264f2cce1bfaf584db6fdddd7290175 100644 (file)
@@ -23,7 +23,6 @@ extern void sirfsoc_secondary_startup(void);
 extern void sirfsoc_cpu_die(unsigned int cpu);
 
 extern void __init sirfsoc_of_irq_init(void);
-extern void sirfsoc_restart(enum reboot_mode, const char *);
 extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
 
 #ifndef CONFIG_DEBUG_LL
index cbcbe9cb094c480a928d22ad23642eec3ecc0178..c7102539c0b08cd4cdfa0503b6634f02027b9d81 100644 (file)
 #include <linux/of.h>
 #include <asm/hardware/cache-l2x0.h>
 
-struct l2x0_aux
-{
+struct l2x0_aux {
        u32 val;
        u32 mask;
 };
 
-static struct l2x0_aux prima2_l2x0_aux __initconst = {
+static const struct l2x0_aux prima2_l2x0_aux __initconst = {
        .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
        .mask = 0,
 };
 
-static struct l2x0_aux marco_l2x0_aux __initconst = {
+static const struct l2x0_aux marco_l2x0_aux __initconst = {
        .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
                (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT),
        .mask = L2X0_AUX_CTRL_MASK,
 };
 
-static struct of_device_id sirf_l2x0_ids[] __initconst = {
+static const struct of_device_id sirf_l2x0_ids[] __initconst = {
        { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
        { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
        {},
index e358b0736dea464fbf56d3a0e59858daf7998bfe..335c12e922621a1f67e0e9df730d2bc2cad00e96 100644 (file)
@@ -138,9 +138,9 @@ static void __init sirfsoc_smp_prepare_cpus(unsigned int max_cpus)
 }
 
 struct smp_operations sirfsoc_smp_ops __initdata = {
-        .smp_prepare_cpus       = sirfsoc_smp_prepare_cpus,
-        .smp_secondary_init     = sirfsoc_secondary_init,
-        .smp_boot_secondary     = sirfsoc_boot_secondary,
+       .smp_prepare_cpus       = sirfsoc_smp_prepare_cpus,
+       .smp_secondary_init     = sirfsoc_secondary_init,
+       .smp_boot_secondary     = sirfsoc_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_die                = sirfsoc_cpu_die,
 #endif
index ccb53391147ad008c40b0caf39a6f724bed4f173..4887a2a4c698a7f5b82e0b511af84615cee7dd86 100644 (file)
 #include <linux/device.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 #include <linux/reboot.h>
+#include <linux/reset-controller.h>
 
-void __iomem *sirfsoc_rstc_base;
-static DEFINE_MUTEX(rstc_lock);
-
-static struct of_device_id rstc_ids[]  = {
-       { .compatible = "sirf,prima2-rstc" },
-       { .compatible = "sirf,marco-rstc" },
-       {},
-};
+#include <asm/system_misc.h>
 
-static int __init sirfsoc_of_rstc_init(void)
-{
-       struct device_node *np;
+#define SIRFSOC_RSTBIT_NUM     64
 
-       np = of_find_matching_node(NULL, rstc_ids);
-       if (!np) {
-               pr_err("unable to find compatible sirf rstc node in dtb\n");
-               return -ENOENT;
-       }
-
-       sirfsoc_rstc_base = of_iomap(np, 0);
-       if (!sirfsoc_rstc_base)
-               panic("unable to map rstc cpu registers\n");
-
-       of_node_put(np);
-
-       return 0;
-}
-early_initcall(sirfsoc_of_rstc_init);
+static void __iomem *sirfsoc_rstc_base;
+static DEFINE_MUTEX(rstc_lock);
 
-int sirfsoc_reset_device(struct device *dev)
+static int sirfsoc_reset_module(struct reset_controller_dev *rcdev,
+                                       unsigned long sw_reset_idx)
 {
-       u32 reset_bit;
+       u32 reset_bit = sw_reset_idx;
 
-       if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit))
+       if (reset_bit >= SIRFSOC_RSTBIT_NUM)
                return -EINVAL;
 
        mutex_lock(&rstc_lock);
 
-       if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) {
+       if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) {
                /*
                 * Writing 1 to this bit resets corresponding block. Writing 0 to this
                 * bit de-asserts reset signal of the corresponding block.
                 * datasheet doesn't require explicit delay between the set and clear
                 * of reset bit. it could be shorter if tests pass.
                 */
-               writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit,
+               writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | (1 << reset_bit),
                        sirfsoc_rstc_base + (reset_bit / 32) * 4);
                msleep(10);
-               writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit,
+               writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~(1 << reset_bit),
                        sirfsoc_rstc_base + (reset_bit / 32) * 4);
        } else {
                /*
@@ -73,9 +54,9 @@ int sirfsoc_reset_device(struct device *dev)
                 * datasheet doesn't require explicit delay between the set and clear
                 * of reset bit. it could be shorter if tests pass.
                 */
-               writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8);
+               writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8);
                msleep(10);
-               writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4);
+               writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4);
        }
 
        mutex_unlock(&rstc_lock);
@@ -83,9 +64,57 @@ int sirfsoc_reset_device(struct device *dev)
        return 0;
 }
 
+static struct reset_control_ops sirfsoc_rstc_ops = {
+       .reset = sirfsoc_reset_module,
+};
+
+static struct reset_controller_dev sirfsoc_reset_controller = {
+       .ops = &sirfsoc_rstc_ops,
+       .nr_resets = SIRFSOC_RSTBIT_NUM,
+};
+
 #define SIRFSOC_SYS_RST_BIT  BIT(31)
 
-void sirfsoc_restart(enum reboot_mode mode, const char *cmd)
+static void sirfsoc_restart(enum reboot_mode mode, const char *cmd)
 {
        writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base);
 }
+
+static int sirfsoc_rstc_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       sirfsoc_rstc_base = of_iomap(np, 0);
+       if (!sirfsoc_rstc_base) {
+               dev_err(&pdev->dev, "unable to map rstc cpu registers\n");
+               return -ENOMEM;
+       }
+
+       sirfsoc_reset_controller.of_node = np;
+       arm_pm_restart = sirfsoc_restart;
+
+       if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
+               reset_controller_register(&sirfsoc_reset_controller);
+
+       return 0;
+}
+
+static const struct of_device_id rstc_ids[]  = {
+       { .compatible = "sirf,prima2-rstc" },
+       { .compatible = "sirf,marco-rstc" },
+       {},
+};
+
+static struct platform_driver sirfsoc_rstc_driver = {
+       .probe          = sirfsoc_rstc_probe,
+       .driver         = {
+               .name   = "sirfsoc_rstc",
+               .owner  = THIS_MODULE,
+               .of_match_table = rstc_ids,
+       },
+};
+
+static int __init sirfsoc_rstc_init(void)
+{
+       return platform_driver_register(&sirfsoc_rstc_driver);
+}
+subsys_initcall(sirfsoc_rstc_init);
index 9f2da2eec4dc52bec9629b714d961010abe2529c..a17c88b74fa1d878d14bc7169a65489cd0394217 100644 (file)
@@ -137,4 +137,4 @@ postcore_initcall(sirfsoc_rtciobrg_init);
 MODULE_AUTHOR("Zhiwu Song <zhiwu.song@csr.com>, "
                "Barry Song <baohua.song@csr.com>");
 MODULE_DESCRIPTION("CSR SiRFprimaII rtc io bridge");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 96100dbf5a2e8353e9fad34ded41ec5e83dda7ad..e6690a44917da7808c7e16a0aeb24d7094a5c9a5 100644 (file)
@@ -7,7 +7,6 @@ comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
 config MACH_PXA3XX_DT
        bool "Support PXA3xx platforms from device tree"
        select CPU_PXA300
-       select HAVE_PWM
        select POWER_SUPPLY
        select PXA3xx
        select USE_OF
@@ -23,12 +22,10 @@ config ARCH_LUBBOCK
 
 config MACH_MAINSTONE
        bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
-       select HAVE_PWM
        select PXA27x
 
 config MACH_ZYLONITE
        bool
-       select HAVE_PWM
        select PXA3xx
 
 config MACH_ZYLONITE300
@@ -53,12 +50,16 @@ config MACH_TAVOREVB
        select CPU_PXA930
        select CPU_PXA935
        select PXA3xx
+       select FB
+       select FB_PXA
 
 config MACH_SAAR
        bool "PXA930 Handheld Platform (aka SAAR)"
        select CPU_PXA930
        select CPU_PXA935
        select PXA3xx
+       select FB
+       select FB_PXA
 
 comment "Third Party Dev Platforms (sorted by vendor name)"
 
@@ -69,8 +70,7 @@ config ARCH_PXA_IDP
 config ARCH_VIPER
        bool "Arcom/Eurotech VIPER SBC"
        select ARCOM_PCMCIA
-       select HAVE_PWM
-       select I2C_GPIO
+       select I2C_GPIO if I2C=y
        select ISA
        select PXA25x
        select PXA_HAVE_ISA_IRQS
@@ -120,7 +120,6 @@ config MACH_CM_X300
        bool "CompuLab CM-X300 modules"
        select CPU_PXA300
        select CPU_PXA310
-       select HAVE_PWM
        select PXA3xx
 
 config MACH_CAPC7117
@@ -164,7 +163,6 @@ config MACH_XCEP
        select MTD_CFI_INTELEXT
        select MTD_PHYSMAP
        select PXA25x
-       select SMC91X
        help
          PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
          Tuned for usage in Libera instruments for particle accelerators.
@@ -181,6 +179,7 @@ config MACH_TRIZEPS4
 config MACH_TRIZEPS4WL
        bool "Keith und Koep Trizeps4-WL DIMM-Module"
        depends on TRIZEPS_PXA
+       select MACH_TRIZEPS4
        select PXA27x
        select TRIZEPS_PCMCIA
 
@@ -211,7 +210,6 @@ config TRIZEPS_PCMCIA
 
 config MACH_LOGICPD_PXA270
        bool "LogicPD PXA270 Card Engine Development Platform"
-       select HAVE_PWM
        select PXA27x
 
 config MACH_PCM027
@@ -222,7 +220,6 @@ config MACH_PCM027
 config MACH_PCM990_BASEBOARD
        bool "PHYTEC PCM-990 development board"
        depends on MACH_PCM027
-       select HAVE_PWM
 
 choice
        prompt "display on pcm990"
@@ -246,7 +243,6 @@ config MACH_COLIBRI
 config MACH_COLIBRI_PXA270_INCOME
        bool "Income s.r.o. PXA270 SBC"
        depends on MACH_COLIBRI
-       select HAVE_PWM
        select PXA27x
 
 config MACH_COLIBRI300
@@ -275,7 +271,6 @@ comment "End-user Products (sorted by vendor name)"
 
 config MACH_H4700
        bool "HP iPAQ hx4700"
-       select HAVE_PWM
        select IWMMXT
        select PXA27x
 
@@ -289,14 +284,12 @@ config MACH_HIMALAYA
 
 config MACH_MAGICIAN
        bool "Enable HTC Magician Support"
-       select HAVE_PWM
        select IWMMXT
        select PXA27x
 
 config MACH_MIOA701
        bool "Mitac Mio A701 Support"
        select GPIO_SYSFS
-       select HAVE_PWM
        select IWMMXT
        select PXA27x
        help
@@ -306,7 +299,6 @@ config MACH_MIOA701
 
 config PXA_EZX
        bool "Motorola EZX Platform"
-       select HAVE_PWM
        select IWMMXT
        select PXA27x
 
@@ -346,7 +338,6 @@ config MACH_MP900C
 
 config ARCH_PXA_PALM
        bool "PXA based Palm PDAs"
-       select HAVE_PWM
 
 config MACH_PALM27X
        bool
@@ -444,7 +435,6 @@ config MACH_TREO680
 config MACH_RAUMFELD_RC
        bool "Raumfeld Controller"
        select CPU_PXA300
-       select HAVE_PWM
        select POWER_SUPPLY
        select PXA3xx
 
@@ -608,7 +598,6 @@ config MACH_E800
 
 config MACH_ZIPIT2
        bool "Zipit Z2 Handheld"
-       select HAVE_PWM
        select PXA27x
 endmenu
 
index 2f71b3fbd319d1bdd70749ef52963c284c498ed0..43596e0ed0515597ee786da610eaf22683e8f3f8 100644 (file)
@@ -331,7 +331,6 @@ static struct pxa2xx_udc_mach_info balloon3_udc_info __initdata = {
 static void __init balloon3_udc_init(void)
 {
        pxa_set_udc_info(&balloon3_udc_info);
-       platform_device_register(&balloon3_gpio_vbus);
 }
 #else
 static inline void balloon3_udc_init(void) {}
index 8404b24240eae1d0662bbbb721aa794d75f32ef5..638b0bb88426cf7b0baa8b64e781cc252074fb6b 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/mach/arch.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <asm/io.h>
 
 #include <mach/pxa27x.h>
 #include <mach/colibri.h>
index f162f1b77cd2115cca0bfed2a9006a956b2f4fcf..57d60542f982d03c7a384cd48be29e55823b5e01 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mtd/sharpsl.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/gpio_keys.h>
 #include <linux/module.h>
 #include <video/w100fb.h>
 
@@ -405,6 +406,44 @@ static struct platform_device corgikbd_device = {
        },
 };
 
+static struct gpio_keys_button corgi_gpio_keys[] = {
+       {
+               .type   = EV_SW,
+               .code   = SW_LID,
+               .gpio   = CORGI_GPIO_SWA,
+               .desc   = "Lid close switch",
+               .debounce_interval = 500,
+       },
+       {
+               .type   = EV_SW,
+               .code   = SW_TABLET_MODE,
+               .gpio   = CORGI_GPIO_SWB,
+               .desc   = "Tablet mode switch",
+               .debounce_interval = 500,
+       },
+       {
+               .type   = EV_SW,
+               .code   = SW_HEADPHONE_INSERT,
+               .gpio   = CORGI_GPIO_AK_INT,
+               .desc   = "HeadPhone insert",
+               .debounce_interval = 500,
+       },
+};
+
+static struct gpio_keys_platform_data corgi_gpio_keys_platform_data = {
+       .buttons        = corgi_gpio_keys,
+       .nbuttons       = ARRAY_SIZE(corgi_gpio_keys),
+       .poll_interval  = 250,
+};
+
+static struct platform_device corgi_gpio_keys_device = {
+       .name   = "gpio-keys-polled",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &corgi_gpio_keys_platform_data,
+       },
+};
+
 /*
  * Corgi LEDs
  */
@@ -646,6 +685,7 @@ static struct platform_device sharpsl_rom_device = {
 static struct platform_device *devices[] __initdata = {
        &corgiscoop_device,
        &corgifb_device,
+       &corgi_gpio_keys_device,
        &corgikbd_device,
        &corgiled_device,
        &corgi_audio_device,
diff --git a/arch/arm/mach-pxa/include/mach/timex.h b/arch/arm/mach-pxa/include/mach/timex.h
deleted file mode 100644 (file)
index af6760a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/timex.h
- *
- * Author:     Nicolas Pitre
- * Created:    Jun 15, 2001
- * Copyright:  MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/* Various drivers are still using the constant of CLOCK_TICK_RATE, for
- * those drivers to at least work, the definition is provided here.
- *
- * NOTE: this is no longer accurate when multiple processors and boards
- * are selected, newer drivers should not depend on this any more.  Use
- * either the clocksource/clockevent or get this at run-time by calling
- * get_clock_tick_rate() (as defined in generic.c).
- */
-
-#if defined(CONFIG_PXA25x)
-/* PXA250/210 timer base */
-#define CLOCK_TICK_RATE 3686400
-#elif defined(CONFIG_PXA27x)
-/* PXA27x timer base */
-#ifdef CONFIG_MACH_MAINSTONE
-#define CLOCK_TICK_RATE 3249600
-#else
-#define CLOCK_TICK_RATE 3250000
-#endif
-#else
-#define CLOCK_TICK_RATE 3250000
-#endif
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
new file mode 100644 (file)
index 0000000..a028be2
--- /dev/null
@@ -0,0 +1,33 @@
+config ARCH_QCOM
+       bool "Qualcomm Support" if ARCH_MULTI_V7
+       select ARCH_REQUIRE_GPIOLIB
+       select ARM_GIC
+       select CLKSRC_OF
+       select GENERIC_CLOCKEVENTS
+       select HAVE_SMP
+       select QCOM_SCM if SMP
+       help
+         Support for Qualcomm's devicetree based systems.
+
+if ARCH_QCOM
+
+menu "Qualcomm SoC Selection"
+
+config ARCH_MSM8X60
+       bool "Enable support for MSM8X60"
+       select CLKSRC_QCOM
+
+config ARCH_MSM8960
+       bool "Enable support for MSM8960"
+       select CLKSRC_QCOM
+
+config ARCH_MSM8974
+       bool "Enable support for MSM8974"
+       select HAVE_ARM_ARCH_TIMER
+
+endmenu
+
+config QCOM_SCM
+       bool
+
+endif
diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
new file mode 100644 (file)
index 0000000..8f756ae
--- /dev/null
@@ -0,0 +1,5 @@
+obj-y                  := board.o
+obj-$(CONFIG_SMP)      += platsmp.o
+obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
+
+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
new file mode 100644 (file)
index 0000000..bae617e
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (c) 2010-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.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+
+static const char * const qcom_dt_match[] __initconst = {
+       "qcom,msm8660-surf",
+       "qcom,msm8960-cdp",
+       "qcom,apq8074-dragonboard",
+       NULL
+};
+
+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
+       .dt_compat = qcom_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
new file mode 100644 (file)
index 0000000..d690856
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+
+#include "scm-boot.h"
+
+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL    0x35a0
+#define SCSS_CPU1CORE_RESET            0x2d80
+#define SCSS_DBG_STATUS_CORE_PWRDUP    0x2e64
+
+#define APCS_CPU_PWR_CTL       0x04
+#define PLL_CLAMP              BIT(8)
+#define CORE_PWRD_UP           BIT(7)
+#define COREPOR_RST            BIT(5)
+#define CORE_RST               BIT(4)
+#define L2DT_SLP               BIT(3)
+#define CLAMP                  BIT(0)
+
+#define APC_PWR_GATE_CTL       0x14
+#define BHS_CNT_SHIFT          24
+#define LDO_PWR_DWN_SHIFT      16
+#define LDO_BYP_SHIFT          8
+#define BHS_SEG_SHIFT          1
+#define BHS_EN                 BIT(0)
+
+#define APCS_SAW2_VCTL         0x14
+#define APCS_SAW2_2_VCTL       0x1c
+
+extern void secondary_startup(void);
+
+static DEFINE_SPINLOCK(boot_lock);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __ref qcom_cpu_die(unsigned int cpu)
+{
+       wfi();
+}
+#endif
+
+static void qcom_secondary_init(unsigned int cpu)
+{
+       /*
+        * Synchronise with the boot thread.
+        */
+       spin_lock(&boot_lock);
+       spin_unlock(&boot_lock);
+}
+
+static int scss_release_secondary(unsigned int cpu)
+{
+       struct device_node *node;
+       void __iomem *base;
+
+       node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
+       if (!node) {
+               pr_err("%s: can't find node\n", __func__);
+               return -ENXIO;
+       }
+
+       base = of_iomap(node, 0);
+       of_node_put(node);
+       if (!base)
+               return -ENOMEM;
+
+       writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+       writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
+       writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
+       mb();
+       iounmap(base);
+
+       return 0;
+}
+
+static int kpssv1_release_secondary(unsigned int cpu)
+{
+       int ret = 0;
+       void __iomem *reg, *saw_reg;
+       struct device_node *cpu_node, *acc_node, *saw_node;
+       u32 val;
+
+       cpu_node = of_get_cpu_node(cpu, NULL);
+       if (!cpu_node)
+               return -ENODEV;
+
+       acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
+       if (!acc_node) {
+               ret = -ENODEV;
+               goto out_acc;
+       }
+
+       saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
+       if (!saw_node) {
+               ret = -ENODEV;
+               goto out_saw;
+       }
+
+       reg = of_iomap(acc_node, 0);
+       if (!reg) {
+               ret = -ENOMEM;
+               goto out_acc_map;
+       }
+
+       saw_reg = of_iomap(saw_node, 0);
+       if (!saw_reg) {
+               ret = -ENOMEM;
+               goto out_saw_map;
+       }
+
+       /* Turn on CPU rail */
+       writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
+       mb();
+       udelay(512);
+
+       /* Krait bring-up sequence */
+       val = PLL_CLAMP | L2DT_SLP | CLAMP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       val &= ~L2DT_SLP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       ndelay(300);
+
+       val |= COREPOR_RST;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(2);
+
+       val &= ~CLAMP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(2);
+
+       val &= ~COREPOR_RST;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(100);
+
+       val |= CORE_PWRD_UP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+
+       iounmap(saw_reg);
+out_saw_map:
+       iounmap(reg);
+out_acc_map:
+       of_node_put(saw_node);
+out_saw:
+       of_node_put(acc_node);
+out_acc:
+       of_node_put(cpu_node);
+       return ret;
+}
+
+static int kpssv2_release_secondary(unsigned int cpu)
+{
+       void __iomem *reg;
+       struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
+       void __iomem *l2_saw_base;
+       unsigned reg_val;
+       int ret;
+
+       cpu_node = of_get_cpu_node(cpu, NULL);
+       if (!cpu_node)
+               return -ENODEV;
+
+       acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
+       if (!acc_node) {
+               ret = -ENODEV;
+               goto out_acc;
+       }
+
+       l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
+       if (!l2_node) {
+               ret = -ENODEV;
+               goto out_l2;
+       }
+
+       saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
+       if (!saw_node) {
+               ret = -ENODEV;
+               goto out_saw;
+       }
+
+       reg = of_iomap(acc_node, 0);
+       if (!reg) {
+               ret = -ENOMEM;
+               goto out_map;
+       }
+
+       l2_saw_base = of_iomap(saw_node, 0);
+       if (!l2_saw_base) {
+               ret = -ENOMEM;
+               goto out_saw_map;
+       }
+
+       /* Turn on the BHS, turn off LDO Bypass and power down LDO */
+       reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
+       writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+       mb();
+       /* wait for the BHS to settle */
+       udelay(1);
+
+       /* Turn on BHS segments */
+       reg_val |= 0x3f << BHS_SEG_SHIFT;
+       writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+       mb();
+        /* wait for the BHS to settle */
+       udelay(1);
+
+       /* Finally turn on the bypass so that BHS supplies power */
+       reg_val |= 0x3f << LDO_BYP_SHIFT;
+       writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
+
+       /* enable max phases */
+       writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
+       mb();
+       udelay(50);
+
+       reg_val = COREPOR_RST | CLAMP;
+       writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(2);
+
+       reg_val &= ~CLAMP;
+       writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(2);
+
+       reg_val &= ~COREPOR_RST;
+       writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+       mb();
+
+       reg_val |= CORE_PWRD_UP;
+       writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
+       mb();
+
+       ret = 0;
+
+       iounmap(l2_saw_base);
+out_saw_map:
+       iounmap(reg);
+out_map:
+       of_node_put(saw_node);
+out_saw:
+       of_node_put(l2_node);
+out_l2:
+       of_node_put(acc_node);
+out_acc:
+       of_node_put(cpu_node);
+
+       return ret;
+}
+
+static DEFINE_PER_CPU(int, cold_boot_done);
+
+static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
+{
+       int ret = 0;
+
+       if (!per_cpu(cold_boot_done, cpu)) {
+               ret = func(cpu);
+               if (!ret)
+                       per_cpu(cold_boot_done, cpu) = true;
+       }
+
+       /*
+        * set synchronisation state between this boot processor
+        * and the secondary one
+        */
+       spin_lock(&boot_lock);
+
+       /*
+        * Send the secondary CPU a soft interrupt, thereby causing
+        * the boot monitor to read the system wide flags register,
+        * and branch to the address found there.
+        */
+       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+       /*
+        * now the secondary core is starting up let it run its
+        * calibrations, then wait for it to finish
+        */
+       spin_unlock(&boot_lock);
+
+       return ret;
+}
+
+static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       return qcom_boot_secondary(cpu, scss_release_secondary);
+}
+
+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       return qcom_boot_secondary(cpu, kpssv1_release_secondary);
+}
+
+static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       return qcom_boot_secondary(cpu, kpssv2_release_secondary);
+}
+
+static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
+{
+       int cpu, map;
+       unsigned int flags = 0;
+       static const int cold_boot_flags[] = {
+               0,
+               SCM_FLAG_COLDBOOT_CPU1,
+               SCM_FLAG_COLDBOOT_CPU2,
+               SCM_FLAG_COLDBOOT_CPU3,
+       };
+
+       for_each_present_cpu(cpu) {
+               map = cpu_logical_map(cpu);
+               if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
+                       set_cpu_present(cpu, false);
+                       continue;
+               }
+               flags |= cold_boot_flags[map];
+       }
+
+       if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
+               for_each_present_cpu(cpu) {
+                       if (cpu == smp_processor_id())
+                               continue;
+                       set_cpu_present(cpu, false);
+               }
+               pr_warn("Failed to set CPU boot address, disabling SMP\n");
+       }
+}
+
+static struct smp_operations smp_msm8660_ops __initdata = {
+       .smp_prepare_cpus       = qcom_smp_prepare_cpus,
+       .smp_secondary_init     = qcom_secondary_init,
+       .smp_boot_secondary     = msm8660_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
+
+static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
+       .smp_prepare_cpus       = qcom_smp_prepare_cpus,
+       .smp_secondary_init     = qcom_secondary_init,
+       .smp_boot_secondary     = kpssv1_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
+
+static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
+       .smp_prepare_cpus       = qcom_smp_prepare_cpus,
+       .smp_secondary_init     = qcom_secondary_init,
+       .smp_boot_secondary     = kpssv2_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);
diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
new file mode 100644 (file)
index 0000000..45cee3e
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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.
+ *
+ * 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/module.h>
+#include <linux/slab.h>
+
+#include "scm.h"
+#include "scm-boot.h"
+
+/*
+ * Set the cold/warm boot address for one of the CPU cores.
+ */
+int scm_set_boot_addr(phys_addr_t addr, int flags)
+{
+       struct {
+               unsigned int flags;
+               phys_addr_t  addr;
+       } cmd;
+
+       cmd.addr = addr;
+       cmd.flags = flags;
+       return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
+                       &cmd, sizeof(cmd), NULL, 0);
+}
+EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
new file mode 100644 (file)
index 0000000..6aabb24
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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.
+ */
+#ifndef __MACH_SCM_BOOT_H
+#define __MACH_SCM_BOOT_H
+
+#define SCM_BOOT_ADDR                  0x1
+#define SCM_FLAG_COLDBOOT_CPU1         0x01
+#define SCM_FLAG_COLDBOOT_CPU2         0x08
+#define SCM_FLAG_COLDBOOT_CPU3         0x20
+#define SCM_FLAG_WARMBOOT_CPU0         0x04
+#define SCM_FLAG_WARMBOOT_CPU1         0x02
+
+int scm_set_boot_addr(phys_addr_t addr, int flags);
+
+#endif
diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
new file mode 100644 (file)
index 0000000..c536fd6
--- /dev/null
@@ -0,0 +1,299 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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.
+ *
+ * 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/slab.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/cacheflush.h>
+
+#include "scm.h"
+
+/* Cache line size for msm8x60 */
+#define CACHELINESIZE 32
+
+#define SCM_ENOMEM             -5
+#define SCM_EOPNOTSUPP         -4
+#define SCM_EINVAL_ADDR                -3
+#define SCM_EINVAL_ARG         -2
+#define SCM_ERROR              -1
+#define SCM_INTERRUPTED                1
+
+static DEFINE_MUTEX(scm_lock);
+
+/**
+ * struct scm_command - one SCM command buffer
+ * @len: total available memory for command and response
+ * @buf_offset: start of command buffer
+ * @resp_hdr_offset: start of response buffer
+ * @id: command to be executed
+ * @buf: buffer returned from scm_get_command_buffer()
+ *
+ * An SCM command is laid out in memory as follows:
+ *
+ *     ------------------- <--- struct scm_command
+ *     | command header  |
+ *     ------------------- <--- scm_get_command_buffer()
+ *     | command buffer  |
+ *     ------------------- <--- struct scm_response and
+ *     | response header |      scm_command_to_response()
+ *     ------------------- <--- scm_get_response_buffer()
+ *     | response buffer |
+ *     -------------------
+ *
+ * There can be arbitrary padding between the headers and buffers so
+ * you should always use the appropriate scm_get_*_buffer() routines
+ * to access the buffers in a safe manner.
+ */
+struct scm_command {
+       u32     len;
+       u32     buf_offset;
+       u32     resp_hdr_offset;
+       u32     id;
+       u32     buf[0];
+};
+
+/**
+ * struct scm_response - one SCM response buffer
+ * @len: total available memory for response
+ * @buf_offset: start of response data relative to start of scm_response
+ * @is_complete: indicates if the command has finished processing
+ */
+struct scm_response {
+       u32     len;
+       u32     buf_offset;
+       u32     is_complete;
+};
+
+/**
+ * alloc_scm_command() - Allocate an SCM command
+ * @cmd_size: size of the command buffer
+ * @resp_size: size of the response buffer
+ *
+ * Allocate an SCM command, including enough room for the command
+ * and response headers as well as the command and response buffers.
+ *
+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
+ */
+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
+{
+       struct scm_command *cmd;
+       size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
+               resp_size;
+
+       cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
+       if (cmd) {
+               cmd->len = len;
+               cmd->buf_offset = offsetof(struct scm_command, buf);
+               cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+       }
+       return cmd;
+}
+
+/**
+ * free_scm_command() - Free an SCM command
+ * @cmd: command to free
+ *
+ * Free an SCM command.
+ */
+static inline void free_scm_command(struct scm_command *cmd)
+{
+       kfree(cmd);
+}
+
+/**
+ * scm_command_to_response() - Get a pointer to a scm_response
+ * @cmd: command
+ *
+ * Returns a pointer to a response for a command.
+ */
+static inline struct scm_response *scm_command_to_response(
+               const struct scm_command *cmd)
+{
+       return (void *)cmd + cmd->resp_hdr_offset;
+}
+
+/**
+ * scm_get_command_buffer() - Get a pointer to a command buffer
+ * @cmd: command
+ *
+ * Returns a pointer to the command buffer of a command.
+ */
+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
+{
+       return (void *)cmd->buf;
+}
+
+/**
+ * scm_get_response_buffer() - Get a pointer to a response buffer
+ * @rsp: response
+ *
+ * Returns a pointer to a response buffer of a response.
+ */
+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
+{
+       return (void *)rsp + rsp->buf_offset;
+}
+
+static int scm_remap_error(int err)
+{
+       switch (err) {
+       case SCM_ERROR:
+               return -EIO;
+       case SCM_EINVAL_ADDR:
+       case SCM_EINVAL_ARG:
+               return -EINVAL;
+       case SCM_EOPNOTSUPP:
+               return -EOPNOTSUPP;
+       case SCM_ENOMEM:
+               return -ENOMEM;
+       }
+       return -EINVAL;
+}
+
+static u32 smc(u32 cmd_addr)
+{
+       int context_id;
+       register u32 r0 asm("r0") = 1;
+       register u32 r1 asm("r1") = (u32)&context_id;
+       register u32 r2 asm("r2") = cmd_addr;
+       do {
+               asm volatile(
+                       __asmeq("%0", "r0")
+                       __asmeq("%1", "r0")
+                       __asmeq("%2", "r1")
+                       __asmeq("%3", "r2")
+#ifdef REQUIRES_SEC
+                       ".arch_extension sec\n"
+#endif
+                       "smc    #0      @ switch to secure world\n"
+                       : "=r" (r0)
+                       : "r" (r0), "r" (r1), "r" (r2)
+                       : "r3");
+       } while (r0 == SCM_INTERRUPTED);
+
+       return r0;
+}
+
+static int __scm_call(const struct scm_command *cmd)
+{
+       int ret;
+       u32 cmd_addr = virt_to_phys(cmd);
+
+       /*
+        * Flush the entire cache here so callers don't have to remember
+        * to flush the cache when passing physical addresses to the secure
+        * side in the buffer.
+        */
+       flush_cache_all();
+       ret = smc(cmd_addr);
+       if (ret < 0)
+               ret = scm_remap_error(ret);
+
+       return ret;
+}
+
+/**
+ * scm_call() - Send an SCM command
+ * @svc_id: service identifier
+ * @cmd_id: command identifier
+ * @cmd_buf: command buffer
+ * @cmd_len: length of the command buffer
+ * @resp_buf: response buffer
+ * @resp_len: length of the response buffer
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ */
+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+               void *resp_buf, size_t resp_len)
+{
+       int ret;
+       struct scm_command *cmd;
+       struct scm_response *rsp;
+
+       cmd = alloc_scm_command(cmd_len, resp_len);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->id = (svc_id << 10) | cmd_id;
+       if (cmd_buf)
+               memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
+
+       mutex_lock(&scm_lock);
+       ret = __scm_call(cmd);
+       mutex_unlock(&scm_lock);
+       if (ret)
+               goto out;
+
+       rsp = scm_command_to_response(cmd);
+       do {
+               u32 start = (u32)rsp;
+               u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
+               start &= ~(CACHELINESIZE - 1);
+               while (start < end) {
+                       asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+                            : "memory");
+                       start += CACHELINESIZE;
+               }
+       } while (!rsp->is_complete);
+
+       if (resp_buf)
+               memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
+out:
+       free_scm_command(cmd);
+       return ret;
+}
+EXPORT_SYMBOL(scm_call);
+
+u32 scm_get_version(void)
+{
+       int context_id;
+       static u32 version = -1;
+       register u32 r0 asm("r0");
+       register u32 r1 asm("r1");
+
+       if (version != -1)
+               return version;
+
+       mutex_lock(&scm_lock);
+
+       r0 = 0x1 << 8;
+       r1 = (u32)&context_id;
+       do {
+               asm volatile(
+                       __asmeq("%0", "r0")
+                       __asmeq("%1", "r1")
+                       __asmeq("%2", "r0")
+                       __asmeq("%3", "r1")
+#ifdef REQUIRES_SEC
+                       ".arch_extension sec\n"
+#endif
+                       "smc    #0      @ switch to secure world\n"
+                       : "=r" (r0), "=r" (r1)
+                       : "r" (r0), "r" (r1)
+                       : "r2", "r3");
+       } while (r0 == SCM_INTERRUPTED);
+
+       version = r1;
+       mutex_unlock(&scm_lock);
+
+       return version;
+}
+EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-qcom/scm.h b/arch/arm/mach-qcom/scm.h
new file mode 100644 (file)
index 0000000..00b31ea
--- /dev/null
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. 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.
+ */
+#ifndef __MACH_SCM_H
+#define __MACH_SCM_H
+
+#define SCM_SVC_BOOT                   0x1
+#define SCM_SVC_PIL                    0x2
+
+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+               void *resp_buf, size_t resp_len);
+
+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
+
+extern u32 scm_get_version(void);
+
+#endif
index 2022e092f0cade07c42efcbdf2768ac55658733a..db09170e3832fca5b8bef1f5c87374aac991e04c 100644 (file)
@@ -56,6 +56,8 @@
 #define PAGE_OFFSET1   (PAGE_OFFSET + 0x10000000)
 #define PAGE_OFFSET2   (PAGE_OFFSET + 0x30000000)
 
+#define PHYS_OFFSET PLAT_PHYS_OFFSET
+
 #define __phys_to_virt(phys)                                           \
        ((phys) >= 0x80000000 ? (phys) - 0x80000000 + PAGE_OFFSET2 :    \
         (phys) >= 0x20000000 ? (phys) - 0x20000000 + PAGE_OFFSET1 :    \
diff --git a/arch/arm/mach-realview/include/mach/timex.h b/arch/arm/mach-realview/include/mach/timex.h
deleted file mode 100644 (file)
index 4eeb069..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  arch/arm/mach-realview/include/mach/timex.h
- *
- *  RealView architecture timex specifications
- *
- *  Copyright (C) 2003 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define CLOCK_TICK_RATE                (50000000 / 16)
index cf073dea5784b3c0fa125f1931305c55706f81e3..1caee6d548b84387107e251132a2302a59c48c1a 100644 (file)
@@ -5,10 +5,8 @@ config ARCH_ROCKCHIP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_GIC
        select CACHE_L2X0
+       select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
-       select COMMON_CLK
-       select GENERIC_CLOCKEVENTS
        select DW_APB_TIMER_OF
        select ARM_GLOBAL_TIMER
        select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
index 1547d4fc920a4075dc8fa70d05fc31f2e3a595a1..4377a1436a98bc2acc67ad396d1b6bb39fa7b1cf 100644 (file)
@@ -1 +1,2 @@
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-rockchip/core.h b/arch/arm/mach-rockchip/core.h
new file mode 100644 (file)
index 0000000..e2e7c9d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+extern char rockchip_secondary_trampoline;
+extern char rockchip_secondary_trampoline_end;
+
+extern unsigned long rockchip_boot_fn;
+extern void rockchip_secondary_startup(void);
+
+extern struct smp_operations rockchip_smp_ops;
diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S
new file mode 100644 (file)
index 0000000..73206e3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ENTRY(rockchip_secondary_startup)
+       bl      v7_invalidate_l1
+       b       secondary_startup
+ENDPROC(rockchip_secondary_startup)
+
+ENTRY(rockchip_secondary_trampoline)
+       ldr     pc, 1f
+ENDPROC(rockchip_secondary_trampoline)
+       .globl  rockchip_boot_fn
+rockchip_boot_fn:
+1:     .space  4
+
+ENTRY(rockchip_secondary_trampoline_end)
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
new file mode 100644 (file)
index 0000000..dbfa5a2
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include <asm/mach/map.h>
+
+#include "core.h"
+
+static void __iomem *scu_base_addr;
+static void __iomem *sram_base_addr;
+static int ncores;
+
+#define PMU_PWRDN_CON          0x08
+#define PMU_PWRDN_ST           0x0c
+
+#define PMU_PWRDN_SCU          4
+
+static void __iomem *pmu_base_addr;
+
+static inline bool pmu_power_domain_is_on(int pd)
+{
+       return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd));
+}
+
+static void pmu_set_power_domain(int pd, bool on)
+{
+       u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON);
+       if (on)
+               val &= ~BIT(pd);
+       else
+               val |=  BIT(pd);
+       writel(val, pmu_base_addr + PMU_PWRDN_CON);
+
+       while (pmu_power_domain_is_on(pd) != on) { }
+}
+
+/*
+ * Handling of CPU cores
+ */
+
+static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
+                                            struct task_struct *idle)
+{
+       if (!sram_base_addr || !pmu_base_addr) {
+               pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
+               return -ENXIO;
+       }
+
+       if (cpu >= ncores) {
+               pr_err("%s: cpu %d outside maximum number of cpus %d\n",
+                                                       __func__, cpu, ncores);
+               return -ENXIO;
+       }
+
+       /* start the core */
+       pmu_set_power_domain(0 + cpu, true);
+
+       return 0;
+}
+
+/**
+ * rockchip_smp_prepare_sram - populate necessary sram block
+ * Starting cores execute the code residing at the start of the on-chip sram
+ * after power-on. Therefore make sure, this sram region is reserved and
+ * big enough. After this check, copy the trampoline code that directs the
+ * core to the real startup code in ram into the sram-region.
+ * @node: mmio-sram device node
+ */
+static int __init rockchip_smp_prepare_sram(struct device_node *node)
+{
+       unsigned int trampoline_sz = &rockchip_secondary_trampoline_end -
+                                           &rockchip_secondary_trampoline;
+       struct resource res;
+       unsigned int rsize;
+       int ret;
+
+       ret = of_address_to_resource(node, 0, &res);
+       if (ret < 0) {
+               pr_err("%s: could not get address for node %s\n",
+                      __func__, node->full_name);
+               return ret;
+       }
+
+       rsize = resource_size(&res);
+       if (rsize < trampoline_sz) {
+               pr_err("%s: reserved block with size 0x%x is to small for trampoline size 0x%x\n",
+                      __func__, rsize, trampoline_sz);
+               return -EINVAL;
+       }
+
+       sram_base_addr = of_iomap(node, 0);
+
+       /* set the boot function for the sram code */
+       rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup);
+
+       /* copy the trampoline to sram, that runs during startup of the core */
+       memcpy(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
+       flush_cache_all();
+       outer_clean_range(0, trampoline_sz);
+
+       dsb_sev();
+
+       return 0;
+}
+
+static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *node;
+       unsigned int i;
+
+       node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+       if (!node) {
+               pr_err("%s: missing scu\n", __func__);
+               return;
+       }
+
+       scu_base_addr = of_iomap(node, 0);
+       if (!scu_base_addr) {
+               pr_err("%s: could not map scu registers\n", __func__);
+               return;
+       }
+
+       node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram");
+       if (!node) {
+               pr_err("%s: could not find sram dt node\n", __func__);
+               return;
+       }
+
+       if (rockchip_smp_prepare_sram(node))
+               return;
+
+       node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu");
+       if (!node) {
+               pr_err("%s: could not find sram dt node\n", __func__);
+               return;
+       }
+
+       pmu_base_addr = of_iomap(node, 0);
+       if (!pmu_base_addr) {
+               pr_err("%s: could not map pmu registers\n", __func__);
+               return;
+       }
+
+       /* enable the SCU power domain */
+       pmu_set_power_domain(PMU_PWRDN_SCU, true);
+
+       /*
+        * While the number of cpus is gathered from dt, also get the number
+        * of cores from the scu to verify this value when booting the cores.
+        */
+       ncores = scu_get_core_count(scu_base_addr);
+
+       scu_enable(scu_base_addr);
+
+       /* Make sure that all cores except the first are really off */
+       for (i = 1; i < ncores; i++)
+               pmu_set_power_domain(0 + i, false);
+}
+
+struct smp_operations rockchip_smp_ops __initdata = {
+       .smp_prepare_cpus       = rockchip_smp_prepare_cpus,
+       .smp_boot_secondary     = rockchip_boot_secondary,
+};
index 82c0b0709712465774b2824eef96a8572edb7f51..d211d6fa0d985d643743c75e224ba20eb1b612bf 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/cache-l2x0.h>
+#include "core.h"
 
 static void __init rockchip_dt_init(void)
 {
@@ -38,6 +39,7 @@ static const char * const rockchip_board_dt_compat[] = {
 };
 
 DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
+       .smp            = smp_ops(rockchip_smp_ops),
        .init_machine   = rockchip_dt_init,
        .dt_compat      = rockchip_board_dt_compat,
 MACHINE_END
index 85883b2e0e49cdecb8eed50a3042842972de5a81..6d3517dc4772a05a444842475079d4d66dfcbb2a 100644 (file)
@@ -141,7 +141,7 @@ static int iomd_request_dma(unsigned int chan, dma_t *dma)
        struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
 
        return request_irq(idma->irq, iomd_dma_handle,
-                          IRQF_DISABLED, idma->dma.device_id, idma);
+                          0, idma->dma.device_id, idma);
 }
 
 static void iomd_free_dma(unsigned int chan, dma_t *dma)
diff --git a/arch/arm/mach-rpc/include/mach/timex.h b/arch/arm/mach-rpc/include/mach/timex.h
deleted file mode 100644 (file)
index dd75e73..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- *  arch/arm/mach-rpc/include/mach/timex.h
- *
- *  Copyright (C) 1997, 1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  RiscPC architecture timex specifications
- */
-
-/*
- * On the RiscPC, the clock ticks at 2MHz.
- */
-#define CLOCK_TICK_RATE                2000000
-
index 9a6def14df01ce71e6ad8a34c1a2d7f1cdeadb38..2689771c1d38f351d00630d82a45a00838ea1b33 100644 (file)
@@ -24,6 +24,9 @@
 
 #include <asm/mach/time.h>
 
+#define RPC_CLOCK_FREQ 2000000
+#define RPC_LATCH DIV_ROUND_CLOSEST(RPC_CLOCK_FREQ, HZ)
+
 static u32 ioc_timer_gettimeoffset(void)
 {
        unsigned int count1, count2, status;
@@ -46,23 +49,23 @@ static u32 ioc_timer_gettimeoffset(void)
                 * and count2.
                 */
                if (status & (1 << 5))
-                       offset -= LATCH;
+                       offset -= RPC_LATCH;
        } else if (count2 > count1) {
                /*
                 * We have just had another interrupt between reading
                 * count1 and count2.
                 */
-               offset -= LATCH;
+               offset -= RPC_LATCH;
        }
 
-       offset = (LATCH - offset) * (tick_nsec / 1000);
-       return ((offset + LATCH/2) / LATCH) * 1000;
+       offset = (RPC_LATCH - offset) * (tick_nsec / 1000);
+       return DIV_ROUND_CLOSEST(offset, RPC_LATCH) * 1000;
 }
 
 void __init ioctime_init(void)
 {
-       ioc_writeb(LATCH & 255, IOC_T0LTCHL);
-       ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
+       ioc_writeb(RPC_LATCH & 255, IOC_T0LTCHL);
+       ioc_writeb(RPC_LATCH >> 8, IOC_T0LTCHH);
        ioc_writeb(0, IOC_T0GO);
 }
 
@@ -75,7 +78,6 @@ ioc_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction ioc_timer_irq = {
        .name           = "timer",
-       .flags          = IRQF_DISABLED,
        .handler        = ioc_timer_interrupt
 };
 
index d876431d64c09c7d3f0ad1025a425e8d757a81be..ba1cc62467789225a0008efe0adfc1b32369c9c5 100644 (file)
@@ -521,7 +521,6 @@ config MACH_ANUBIS
        select HAVE_PATA_PLATFORM
        select S3C2440_XTAL_12000000
        select S3C24XX_DCLK
-       select S3C24XX_GPIO_EXTRA64
        select S3C24XX_SIMTEC_PM if PM
        select S3C_DEV_USB_HOST
        help
@@ -537,7 +536,7 @@ config MACH_AT2440EVB
 
 config MACH_MINI2440
        bool "MINI2440 development board"
-       select EEPROM_AT24
+       select EEPROM_AT24 if I2C
        select LEDS_CLASS
        select LEDS_TRIGGERS
        select LEDS_TRIGGER_BACKLIGHT
@@ -562,7 +561,6 @@ config MACH_OSIRIS
        select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
        select S3C2440_XTAL_12000000
        select S3C24XX_DCLK
-       select S3C24XX_GPIO_EXTRA128
        select S3C24XX_SIMTEC_PM if PM
        select S3C_DEV_NAND
        select S3C_DEV_USB_HOST
@@ -573,7 +571,7 @@ config MACH_OSIRIS
 config MACH_OSIRIS_DVS
        tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver"
        depends on MACH_OSIRIS
-       select TPS65010
+       depends on TPS65010
        help
          Say Y/M here if you want to have dynamic voltage scaling support
          on the Simtec IM2440D20 (OSIRIS) module via the TPS65011.
index d39d3c7875803e456c25c37babc8be9f9d30cef5..d1afcf9252d18a1175661c0578f47ae677b842b6 100644 (file)
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
index 11b3b28457bbce9130309d876f9239905f82e7e2..192a5b2550b04a8b639fd8d4613b02f19b25b165 100644 (file)
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
index aaf006d1d6dc9ec6111ae080e3e4f15350615561..5527226fd61f305b514dd688e3dc17eb05bc8df0 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 
 #include <mach/hardware.h>
 #include <linux/atomic.h>
@@ -43,7 +44,6 @@
 
 #include <plat/clock.h>
 #include <plat/cpu.h>
-#include <plat/regs-serial.h>
 
 /* S3C2440 extended clock support */
 
index 4adaa4b43ffe5282f915d83dcdc3d4489c6eebe7..1bc8e73c94f9864d8d7cdfc715c33582f9718005 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
@@ -44,7 +45,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/regs-gpio.h>
-#include <plat/regs-serial.h>
 #include <mach/dma.h>
 
 #include <plat/cpu.h>
@@ -240,7 +240,6 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
        } else {
                samsung_cpu_id = s3c24xx_read_idcode_v4();
        }
-       s3c24xx_init_cpu();
 
        s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 
@@ -484,7 +483,7 @@ struct platform_device s3c2440_device_dma = {
 };
 #endif
 
-#if defined(CONFIG_CPUS_3C2443) || defined(CONFIG_CPU_S3C2416)
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
 static struct resource s3c2443_dma_resource[] = {
        [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
        [1] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA0),
index 30aa53ff07a6b60118a512a65bb387216194ac93..09aa12da1789770df2bbd3ba4a27daf8bc7077d2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 
 #include <mach/map.h>
 #include <mach/dma.h>
@@ -23,7 +24,6 @@
 #include <plat/cpu.h>
 #include <plat/dma-s3c24xx.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
index b7e094671522d33d9b197fc28272d83473031310..0c0106d1a4d1c48826d7d7f1f93779aebbd8cadb 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <mach/dma.h>
@@ -23,7 +24,6 @@
 #include <plat/dma-s3c24xx.h>
 #include <plat/cpu.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
index cd25de28804c935111da58ff97708e56a20d8238..2f8e8a3017dfa84b8e3d98531deb4386a6d4bdb7 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 
 #include <mach/map.h>
 #include <mach/dma.h>
@@ -23,7 +24,6 @@
 #include <plat/dma-s3c24xx.h>
 #include <plat/cpu.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
index 95b9f759fe97fdea1df49efdf78f062f11a8d2aa..f4096ec0700ac7cf7396e2857eef9b26abb426b4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <mach/dma.h>
@@ -23,7 +24,6 @@
 #include <plat/dma-s3c24xx.h>
 #include <plat/cpu.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
index 2558952e3147ee281ecf2a2e2c7fc4df20900925..2f39737544c06789c9b3337282e1fbef0936727d 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
-#include <plat/regs-serial.h>
+#include <linux/serial_s3c.h>
 
 #define S3C2410_UART1_OFF (0x4000)
 #define SHIFT_2440TXF (14-9)
index a6cc14a092fc6a1779606a632c0ef9ae23f09cf7..dedd3837c19353cb79bba4f49c364c4b60f16ae8 100644 (file)
@@ -1,5 +1,4 @@
-/* arch/arm/mach-s3c2410/include/mach/hardware.h
- *
+/*
  * Copyright (c) 2003 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
 
 extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
 
-#ifdef CONFIG_CPU_S3C2440
-
-extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
-
-#endif /* CONFIG_CPU_S3C2440 */
-
 #endif /* __ASSEMBLY__ */
 
 #include <asm/sizes.h>
 #include <mach/map.h>
 
-/* machine specific hardware definitions should go after this */
-
-/* currently here until moved into config (todo) */
-#define CONFIG_NO_MULTIWORD_IO
-
 #endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/rtc-core.h b/arch/arm/mach-s3c24xx/include/mach/rtc-core.h
new file mode 100644 (file)
index 0000000..4d5f576
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
+ *
+ * Samsung RTC Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __RTC_CORE_H
+#define __RTC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+extern struct platform_device s3c_device_rtc;
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+       s3c_device_rtc.name = name;
+}
+
+#endif /* __RTC_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/tick.h b/arch/arm/mach-s3c24xx/include/mach/tick.h
deleted file mode 100644 (file)
index 544da41..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/include/mach/tick.h
- *
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C2410 - timer tick support
- */
-
-#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
-
-static inline int s3c24xx_ostimer_pending(void)
-{
-       return __raw_readl(S3C2410_SRCPND) & SRCPND_TIMER4;
-}
diff --git a/arch/arm/mach-s3c24xx/include/mach/timex.h b/arch/arm/mach-s3c24xx/include/mach/timex.h
deleted file mode 100644 (file)
index fe9ca1f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/timex.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/uncompress.h b/arch/arm/mach-s3c24xx/include/mach/uncompress.h
deleted file mode 100644 (file)
index 7d2ce20..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/uncompress.h
- *
- * Copyright (c) 2003-2007 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/regs-gpio.h>
-#include <mach/map.h>
-
-/* working in physical space... */
-#undef S3C2410_GPIOREG
-#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
-
-#include <plat/uncompress.h>
-
-static inline int is_arm926(void)
-{
-       unsigned int cpuid;
-
-       asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid));
-
-       return ((cpuid & 0xff0) == 0x260);
-}
-
-static void arch_detect_cpu(void)
-{
-       unsigned int cpuid;
-
-       cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1);
-       cpuid &= S3C2410_GSTATUS1_IDMASK;
-
-       if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
-           cpuid == S3C2410_GSTATUS1_2442 ||
-           cpuid == S3C2410_GSTATUS1_2416 ||
-           cpuid == S3C2410_GSTATUS1_2450) {
-               fifo_mask = S3C2440_UFSTAT_TXMASK;
-               fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
-       } else {
-               fifo_mask = S3C2410_UFSTAT_TXMASK;
-               fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
-       }
-
-       uart_base = (volatile u8 *) S3C_PA_UART +
-               (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
index 284ea1f4420507da064d339c4357e864f9d0b1c5..8ac9554aa996c708d8db6047a48d608008c63ceb 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/platform_device.h>
 #include <linux/proc_fs.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <asm/mach/arch.h>
@@ -49,7 +50,6 @@
 #include <asm/mach-types.h>
 #include <mach/fb.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
index 2a16f8fb3584392c41d83f20c6576f2383babebe..81a270af2336f9a75536e36769cac3c8ebe5cc74 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/i2c.h>
@@ -32,7 +33,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 #include <mach/gpio-samsung.h>
index 6beab674c147c43b84a5fe670d87c8ca826558cf..d8f6bb1096cb3b2da4666e1c45df8cacd27eaaa9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/dm9000.h>
 #include <linux/platform_device.h>
 
@@ -33,7 +34,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 #include <mach/gpio-samsung.h>
index 981ba1eb9fdc83b191e911c64ac83c91cdb8fdfa..e371ff53a40820d184c527dec5d7f7ccd19d3779 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/dm9000.h>
 #include <linux/ata_platform.h>
@@ -55,7 +56,6 @@
 #include <plat/cpu-freq.h>
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include "bast.h"
index d9170e9f8ccdf4b8554bc9fa57159725d808dcb9..dc4db849f0fda599e721d1628b7896f32b973703 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/workqueue.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
@@ -81,7 +82,6 @@
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
 #include <plat/pm.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include "common.h"
@@ -196,7 +196,7 @@ static void gta02_charger_worker(struct work_struct *work)
         * If the PCF50633 ADC is disabled we fallback to a
         * 100mA limit for safety.
         */
-       pcf50633_mbc_usb_curlim_set(pcf, 100);
+       pcf50633_mbc_usb_curlim_set(gta02_pcf, 100);
 #endif
 }
 
index de0832181d8c0eb4081ee127369159a23f133be9..e453acd92cbf5cfea4017cd253bbf30a6585e567 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
@@ -62,7 +63,6 @@
 #include <plat/gpio-cfg.h>
 #include <plat/pll.h>
 #include <plat/pm.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include "common.h"
index 67cb8e948b7ed4ee532f5acd9fab59d52ac6e93b..5faa7239e7d6d9ba0e02309ae9783215ad13941e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 
@@ -31,7 +32,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <plat/regs-serial.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
index 1f1559713d8b265c1233f581268f846d837339fa..9e57fd9f4f3bcbae6d9680a487fd945727e76a57 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/dm9000.h>
 #include <linux/platform_data/at24.h>
 #include <linux/platform_device.h>
@@ -37,7 +38,6 @@
 #include <mach/fb.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <linux/platform_data/leds-s3c24xx.h>
 #include <mach/regs-lcd.h>
index 997684f17930836c7e7212ea48a7ac64113373e4..4cccaad34847d69e8d6a4a5700edfa1f415ad190 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/timer.h>
 #include <linux/io.h>
 #include <linux/mmc/host.h>
@@ -43,7 +44,6 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/regs-serial.h>
 
 #include <plat/clock.h>
 #include <plat/cpu.h>
index 575d28c9e6c60fab668992b4c155d905890809a3..3066851f584d4cd10eb9fe58ac17f291d646dd3c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gpio.h>
 #include <linux/string.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -38,7 +39,6 @@
 //#include <asm/debug-ll.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
-#include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
 #include <plat/gpio-cfg.h>
index f84f2a4c0c6d0cb4aa3148d31db5806b870db635..a4ae4bb3666da146cacf8ffdc64af2cd30862801 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/clk.h>
 #include <linux/i2c.h>
 #include <linux/io.h>
@@ -44,7 +45,6 @@
 #include <plat/cpu-freq.h>
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include <mach/hardware.h>
index 7e16b0740ec1eb02208aba8a0f4dc72f13e300fc..bdb3faac2d9b447a5999657640626bb3a43ab253 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -32,7 +33,6 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include "common.h"
index b534b76812e3751d8a145fb50ea935fa05baebf6..8c12787a8fd38537163d460694c4861e3f0c2675 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
 #include <linux/io.h>
@@ -49,7 +50,6 @@
 
 #include <linux/platform_data/leds-s3c24xx.h>
 #include <mach/regs-lcd.h>
-#include <plat/regs-serial.h>
 #include <mach/fb.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
index 0a5456cda1bcd5dc39139f89a2b07c68dcb32372..afb784e934c8b91c8b117e603b6d878fa8637536 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/device.h>
@@ -57,7 +58,6 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 #include <plat/gpio-cfg.h>
 
index b36edce8b2b86ae4e4ec7cc05ee6d87af7e05ace..e6535ce1bc5ce4586afca563474800ab2d134e9a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/serial.h>
 #include <linux/io.h>
 #include <linux/mtd/mtd.h>
@@ -49,7 +50,6 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include "common.h"
index f50454a34f72d09fd28b01f1cd347a1e5468eb6a..70f0900d4bcac263d04085933b996be9b3ec75e9 100644 (file)
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 
 #include <asm/mach/arch.h>
 #include <mach/map.h>
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/regs-serial.h>
 
 #include "common.h"
 
index a773789e4f38ec8cd87a8b8fd80aa2afbd696fbb..f32924ee0e9f671c5326b36fef817c2ae26fae83 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -46,7 +47,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
 #include <plat/devs.h>
index f5bc721217e3227cd4faeef05460b07a4ca6e7f2..233fe52d2015a549c3b6ef507de4019664306f32 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -33,7 +34,6 @@
 #include <asm/mach-types.h>
 
 //#include <asm/debug-ll.h>
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
index 12023cae437834d1acb23dfaee8164218d175a04..b3b54d8e1410dc81a7f8c2c80723e6466f3d49e8 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/mtd/partitions.h>
@@ -34,7 +35,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-s3c2443-clock.h>
index de2e5d39a8471b490a90be86ea966c6b835ba02a..d071dcfea5480dc50688cf0d7cd2378e76623f92 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -31,7 +32,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
index d9933fcc6cc8bb8526af7808c28a5250c2ae2be1..06c4d77de3a5572513558552675505c663107abf 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -31,7 +32,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
index 7fad8f055cabc050b5aba9e1ecaf82c2fc1998f9..4108b2f0cede26e0b22fb9c18b16e5688c27978a 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <asm/mach/arch.h>
@@ -44,7 +45,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index 755df489a45f63ad1bbad111ed24ae53edf26054..1cc5b1bd51cd0fb14d098daa68d584aecc72fbd8 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <asm/mach/arch.h>
@@ -45,7 +46,6 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
-#include <plat/regs-serial.h>
 #include <plat/samsung-time.h>
 
 #include "bast.h"
index f7ec9c55078748782cd3110c8b4cea81a5afc408..40868c0e0a683e673904c4c1a69db23448fef75f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/mtd/mtd.h>
@@ -32,7 +33,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
index 052ca23393a7e0274f52ed442278102584f986f1..68ea5b7e5dc7d57df5f06be4e44d5930b0a97ffb 100644 (file)
@@ -33,9 +33,9 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-irq.h>
index ffb92cbca08cc06e2b23728cd9c88a826c9b52a8..04b58cb4988860bbd46d18e277679930d8674d78 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 #include <linux/io.h>
@@ -37,7 +38,6 @@
 #include <plat/cpu-freq.h>
 
 #include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
index 0251650cbf8084a913290bdafa7f7e6e3f8e7659..657cbaca80ac46cefbfb9c6baa9f7d46432efd43 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/reboot.h>
@@ -43,7 +44,6 @@
 #include <plat/nand-core.h>
 #include <plat/pll.h>
 #include <plat/pm.h>
-#include <plat/regs-serial.h>
 #include <plat/regs-spi.h>
 
 #include "common.h"
index 8e01b4f2df35bc41b4abcaa54f8ec5102b9f998b..9fe260ae11e17b2cdfcce03a862c570c43ba756c 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/system_misc.h>
 
 #include <mach/regs-s3c2443-clock.h>
+#include <mach/rtc-core.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -61,7 +62,6 @@
 #include <plat/fb-core.h>
 #include <plat/nand-core.h>
 #include <plat/adc-core.h>
-#include <plat/rtc-core.h>
 #include <plat/spi-core.h>
 
 #include "common.h"
index 886c2147062bcfd64be98641dd191ff0c40cd84d..c7a804d0348e79be54d800b2207a008991a6dd49 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/system_misc.h>
 
 #include <mach/regs-s3c2443-clock.h>
+#include <mach/rtc-core.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -43,7 +44,6 @@
 #include <plat/fb-core.h>
 #include <plat/nand-core.h>
 #include <plat/adc-core.h>
-#include <plat/rtc-core.h>
 #include <plat/spi-core.h>
 
 static struct map_desc s3c2443_iodesc[] __initdata = {
index 911b555029fc4f69ff4fda3fdcb0748d559deddc..fe30ebb234d28231737a3606ed9942eaaee81cc3 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 #include <linux/device.h>
@@ -35,7 +36,6 @@
 #include <plat/cpu-freq.h>
 
 #include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
 #include <plat/clock.h>
index dd47c8fa07fae7b17e8d9a48c58c3f0d22c13397..c9b91223697c00856f8d687940a143f39e7141d4 100644 (file)
 */
 
 #include <linux/linkage.h>
+#include <linux/serial_s3c.h>
 #include <asm/assembler.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
 
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
 
 #include "regs-mem.h"
 
index 7f378b662da6baf1b4288f21fdd943a7b58f0068..d833d616bd2ed0177d7e7342f6a1673e7051c322 100644 (file)
 */
 
 #include <linux/linkage.h>
+#include <linux/serial_s3c.h>
 #include <asm/assembler.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
 
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
 
 /* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
  * reset the UART configuration, only enable if you really need this!
index 64f04e6f9c317e3b79ceb8a530d21057c0be84f0..3136d86b0d6eef17c219db9f546b0c4de47f1ebc 100644 (file)
@@ -86,8 +86,7 @@ config MACH_SMDK6400
        bool "SMDK6400"
        select CPU_S3C6400
        select S3C64XX_SETUP_SDHCI
-       select S3C_DEV_HSMMC
-       select S3C_DEV_NAND
+       select S3C_DEV_HSMMC1
        help
          Machine support for the Samsung SMDK6400
 
index 76ab595d849bbb22c1cd45ea21c490198c463292..5c45aae675b63e86f21c44aea48e41bfccddb444 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 #include <linux/io.h>
@@ -50,7 +51,6 @@
 #include <plat/irq-uart.h>
 #include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
-#include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
index dd9ccca5de1f3eb2a50ededc605fb5a36f2924e2..c9b95325b672cfe897a0148e7c6f743433bb0817 100644 (file)
@@ -12,8 +12,8 @@
 
 /* pull in the relevant register and map files. */
 
+#include <linux/serial_s3c.h>
 #include <mach/map.h>
-#include <plat/regs-serial.h>
 
        /* note, for the boot process to work we have to keep the UART
         * virtual address aligned to an 1MiB boundary for the L1
index c0537f40a3d859205fb7609ad912fa8ecf64c053..a30a1e3ffc6a3cb1240e9b6140e534c54226a852 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef __MACH_S3C64XX_PM_CORE_H
 #define __MACH_S3C64XX_PM_CORE_H __FILE__
 
+#include <linux/serial_s3c.h>
+
 #include <mach/regs-gpio.h>
 
 static inline void s3c_pm_debug_init_uart(void)
diff --git a/arch/arm/mach-s3c64xx/include/mach/tick.h b/arch/arm/mach-s3c64xx/include/mach/tick.h
deleted file mode 100644 (file)
index db9c1b1..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - Timer tick support definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TICK_H
-#define __ASM_ARCH_TICK_H __FILE__
-
-#include <linux/irqchip/arm-vic.h>
-
-/* note, the timer interrutps turn up in 2 places, the vic and then
- * the timer block. We take the VIC as the base at the moment.
- */
-static inline u32 s3c24xx_ostimer_pending(void)
-{
-       u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
-       return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
-}
-
-#define TICK_MAX       (0xffffffff)
-
-#endif /* __ASM_ARCH_6400_TICK_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/timex.h b/arch/arm/mach-s3c64xx/include/mach/timex.h
deleted file mode 100644 (file)
index fb2e8cd..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s3c64xx/include/mach/timex.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C6400 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/uncompress.h b/arch/arm/mach-s3c64xx/include/mach/uncompress.h
deleted file mode 100644 (file)
index 1c95673..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/uncompress.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C6400 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-       /* we do not need to do any cpu detection here at the moment. */
-       fifo_mask = S3C2440_UFSTAT_TXMASK;
-       fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
-
-       uart_base = (volatile u8 *)S3C_PA_UART +
-               (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
index 1649c0d1c1b80ff6a40f83ceb84881e354a54b1f..ae4ea7601f603dbeff5bf278aa6c125a345db45c 100644 (file)
 #include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/of.h>
 
 #include <mach/map.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
@@ -55,7 +55,13 @@ static struct irq_grp_save {
        u32     mask;
 } eint_grp_save[5];
 
-static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+#ifndef CONFIG_SERIAL_SAMSUNG_UARTS
+#define SERIAL_SAMSUNG_UARTS 0
+#else
+#define        SERIAL_SAMSUNG_UARTS CONFIG_SERIAL_SAMSUNG_UARTS
+#endif
+
+static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS];
 
 static int s3c64xx_irq_pm_suspend(void)
 {
@@ -66,7 +72,7 @@ static int s3c64xx_irq_pm_suspend(void)
 
        s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
 
-       for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+       for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++)
                irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
 
        for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
@@ -87,7 +93,7 @@ static void s3c64xx_irq_pm_resume(void)
 
        s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
 
-       for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+       for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++)
                __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
 
        for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
index ddeb0e51a962ada3645114f4115632ccfaeb6767..55eb6a69655bb14e9b69b76587921e5933c7d178 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
@@ -41,7 +42,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/fb.h>
 
index 7ccfef227c77d654408fc49fdcd62922cfd71e30..9c00d83f7151d83ea4f8a7de6bb8bbc0fde9e34c 100644 (file)
@@ -401,4 +401,4 @@ static int __init wlf_gf_module_register(void)
 {
        return i2c_add_driver(&wlf_gf_module_driver);
 }
-module_init(wlf_gf_module_register);
+device_initcall(wlf_gf_module_register);
index 3df3c372ee1f9aa1f1685913e2b00ba123339513..4b0199fff9f59e9390c23a8a703cbf253bd40bf8 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/io.h>
@@ -51,7 +52,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
 
-#include <plat/regs-serial.h>
 #include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/gpio-cfg.h>
index 0431016925b9c9b0e0bdbcb1025d534354f02e6c..72cee08c8bf53c0a929135b64546705fb40efd74 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
@@ -33,7 +34,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <mach/gpio-samsung.h>
 #include <plat/fb.h>
index 8d553a418e1c9076898878d0a8039f5597804112..9cbc07602ef388cb78a97e0196899c041e7ce927 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/types.h>
 
 #include <asm/mach-types.h>
@@ -38,7 +39,6 @@
 #include <plat/fb.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 #include <linux/platform_data/mmc-sdhci-s3c.h>
-#include <plat/regs-serial.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
 
index 2067b0bf55b43127eef766b52beb283a11db6431..67f06a9ae656bb3c8955a480ef9298bd490b0dc8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
@@ -36,7 +37,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/fb.h>
 
index 5152026f0e191266fc3cf211f0c43dad8388f290..fbad2af1ef1604a46ffa1a06dc0f387ef40006c0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/types.h>
 
 #include <asm/mach-types.h>
@@ -38,7 +39,6 @@
 #include <plat/devs.h>
 #include <plat/fb.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
-#include <plat/regs-serial.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
 
 #include <video/platform_lcd.h>
index 6e72bd5c1d0cc934232ea27d8953a5da8048ecf1..78dd6f73c072fa76c0f1e8a35b5374cec0eca918 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/pwm_backlight.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/spi/spi_gpio.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/platform_data/s3c-hsotg.h>
@@ -33,7 +34,6 @@
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/gpio-cfg.h>
 #include <linux/platform_data/hwmon-s3c.h>
-#include <plat/regs-serial.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
index 150f55fb9e3346500ca144a450bec92eeea7076e..c85d1cbe769f079dfa9800829c8d072041e4d250 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/io.h>
@@ -29,8 +30,6 @@
 #include <mach/hardware.h>
 #include <mach/map.h>
 
-#include <plat/regs-serial.h>
-
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index 43261d24a0a5c6c141a482d73395a48a27191532..c6a8b2ab0240c6978e705635479f9c84c65940f3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
@@ -55,7 +56,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-samsung.h>
 #include <linux/platform_data/ata-samsung_cf.h>
index b5a66986a529ada5d9826405c38a98b306aafa7b..6b37694fa3351fc55a66f0a5b0b4377e23ab734a 100644 (file)
@@ -332,7 +332,6 @@ static __init int s3c64xx_pm_initcall(void)
 {
        pm_cpu_prep = s3c64xx_pm_prepare;
        pm_cpu_sleep = s3c64xx_cpu_suspend;
-       pm_uart_udivslot = 1;
 
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
        gpio_request(S3C64XX_GPN(12), "DEBUG_LED0");
index 3db0c98222f7686574be92d880f1ee25e5369e3f..8c42807bf57903ca19d64caf82448570dffee053 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 
@@ -34,7 +35,6 @@
 #include <asm/irq.h>
 
 #include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 
 #include <plat/cpu.h>
index 72b2278953a896a6dad6ad892e3a1438fd62d882..5be3f09bac92e3395738267b0f7574c4f6a02e3e 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 
@@ -35,7 +36,6 @@
 #include <asm/irq.h>
 
 #include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 
 #include <plat/cpu.h>
index 42e14f2e7ca7d892c3d035bdf64870c0c70c74e1..9a43be002d784c973524371da5f72d916cc684fa 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
@@ -50,7 +51,6 @@
 #include <plat/gpio-cfg.h>
 #include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
-#include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -205,6 +205,7 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
        samsung_pwm_set_platdata(&s5p64x0_pwm_variant);
 }
 
+#ifdef CONFIG_CPU_S5P6440
 void __init s5p6440_map_io(void)
 {
        /* initialize any device information early */
@@ -218,7 +219,9 @@ void __init s5p6440_map_io(void)
 
        iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
 }
+#endif
 
+#ifdef CONFIG_CPU_S5P6450
 void __init s5p6450_map_io(void)
 {
        /* initialize any device information early */
@@ -232,13 +235,14 @@ void __init s5p6450_map_io(void)
 
        iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
 }
+#endif
 
 /*
  * s5p64x0_init_clocks
  *
  * register and setup the CPU clocks
  */
-
+#ifdef CONFIG_CPU_S5P6440
 void __init s5p6440_init_clocks(int xtal)
 {
        printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
@@ -248,7 +252,9 @@ void __init s5p6440_init_clocks(int xtal)
        s5p6440_register_clocks();
        s5p6440_setup_clocks();
 }
+#endif
 
+#ifdef CONFIG_CPU_S5P6450
 void __init s5p6450_init_clocks(int xtal)
 {
        printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
@@ -258,13 +264,14 @@ void __init s5p6450_init_clocks(int xtal)
        s5p6450_register_clocks();
        s5p6450_setup_clocks();
 }
+#endif
 
 /*
  * s5p64x0_init_irq
  *
  * register the CPU interrupts
  */
-
+#ifdef CONFIG_CPU_S5P6440
 void __init s5p6440_init_irq(void)
 {
        /* S5P6440 supports 2 VIC */
@@ -279,7 +286,9 @@ void __init s5p6440_init_irq(void)
 
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
+#endif
 
+#ifdef CONFIG_CPU_S5P6450
 void __init s5p6450_init_irq(void)
 {
        /* S5P6450 supports only 2 VIC */
@@ -294,6 +303,7 @@ void __init s5p6450_init_irq(void)
 
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
+#endif
 
 struct bus_type s5p64x0_subsys = {
        .name           = "s5p64x0-core",
@@ -321,6 +331,7 @@ int __init s5p64x0_init(void)
 }
 
 /* uart registration process */
+#ifdef CONFIG_CPU_S5P6440
 void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
        int uart;
@@ -332,11 +343,14 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 
        s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
 }
+#endif
 
+#ifdef CONFIG_CPU_S5P6450
 void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
        s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
 }
+#endif
 
 #define eint_offset(irq)       ((irq) - IRQ_EINT(0))
 
index f3a9b43cba4aa05a7215022d53f2f7bbed89d9b3..cbe7f3d731d0f9f5bd2e1fa4a31125ceb774f30e 100644 (file)
@@ -25,10 +25,10 @@ void s5p6450_register_clocks(void);
 void s5p6450_setup_clocks(void);
 
 void s5p64x0_restart(enum reboot_mode mode, const char *cmd);
+extern  int s5p64x0_init(void);
 
 #ifdef CONFIG_CPU_S5P6440
 
-extern  int s5p64x0_init(void);
 extern void s5p6440_map_io(void);
 extern void s5p6440_init_clocks(int xtal);
 
@@ -38,12 +38,10 @@ extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 #define s5p6440_init_clocks NULL
 #define s5p6440_init_uarts NULL
 #define s5p6440_map_io NULL
-#define s5p64x0_init NULL
 #endif
 
 #ifdef CONFIG_CPU_S5P6450
 
-extern  int s5p64x0_init(void);
 extern void s5p6450_map_io(void);
 extern void s5p6450_init_clocks(int xtal);
 
@@ -53,7 +51,6 @@ extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 #define s5p6450_init_clocks NULL
 #define s5p6450_init_uarts NULL
 #define s5p6450_map_io NULL
-#define s5p64x0_init NULL
 #endif
 
 #endif /* __ARCH_ARM_MACH_S5P64X0_COMMON_H */
index 5e2916fb19a9f2f4f6f9c95b222cd7af86b09a28..8759e7882bcb0883e268f11d4ef2b09f705ea6a8 100644 (file)
 
 /* pull in the relevant register and map files. */
 
+#include <linux/serial_s3c.h>
 #include <plat/map-base.h>
 #include <plat/map-s5p.h>
 
-#include <plat/regs-serial.h>
-
        .macro addruart, rp, rv, tmp
                mov     \rp, #0xE0000000
                orr     \rp, \rp, #0x00100000
index e52f7545d3aa6d4b3927f6d9e4e7ed8daddcb70a..1e0eb65b2b82fbc23ca955b7ac40781402e3acf4 100644 (file)
@@ -12,6 +12,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/serial_s3c.h>
+
 #include <mach/regs-gpio.h>
 
 static inline void s3c_pm_debug_init_uart(void)
diff --git a/arch/arm/mach-s5p64x0/include/mach/timex.h b/arch/arm/mach-s5p64x0/include/mach/timex.h
deleted file mode 100644 (file)
index 4b91faa..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* linux/arch/arm/mach-s5p64x0/include/mach/timex.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S5P64X0 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/uncompress.h b/arch/arm/mach-s5p64x0/include/mach/uncompress.h
deleted file mode 100644 (file)
index bbcc3f6..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* linux/arch/arm/mach-s5p64x0/include/mach/uncompress.h
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * S5P64X0 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-       unsigned int chipid;
-
-       chipid = *(const volatile unsigned int __force *) 0xE0100118;
-
-       if ((chipid & 0xff000) == 0x50000)
-               uart_base = (volatile u8 *)S5P6450_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
-       else
-               uart_base = (volatile u8 *)S5P6440_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
-
-       fifo_mask = S3C2440_UFSTAT_TXMASK;
-       fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
index 3e6f2456ee9db9913b134eaa95458327591d689c..2ed921e095dcfb6b37a9547453115778f9fc142f 100644 (file)
@@ -14,9 +14,9 @@
 
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
-#include <plat/regs-serial.h>
 #include <plat/pm.h>
 
 #include <mach/regs-gpio.h>
@@ -34,7 +34,9 @@ static struct irq_grp_save {
        u32     mask;
 } eint_grp_save[4];
 
+#ifdef CONFIG_SERIAL_SAMSUNG
 static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+#endif
 
 static int s5p64x0_irq_pm_suspend(void)
 {
@@ -45,8 +47,10 @@ static int s5p64x0_irq_pm_suspend(void)
 
        s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
 
+#ifdef CONFIG_SERIAL_SAMSUNG
        for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
                irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+#endif
 
        for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
                grp->con = __raw_readl(S5P64X0_EINT12CON + (i * 4));
@@ -66,8 +70,10 @@ static void s5p64x0_irq_pm_resume(void)
 
        s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
 
+#ifdef CONFIG_SERIAL_SAMSUNG
        for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
                __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+#endif
 
        for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
                __raw_writel(grp->con, S5P64X0_EINT12CON + (i * 4));
index 9efdcc03df3b5477bc51ccb8196f0f7fcccabd97..6840e197cb2db67a00b5e89b4dc5c540ef367d28 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -39,7 +40,6 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
index c3cacc067efed25aff9740a2d65b795c4dd59266..fa1341c074ca3a922615dfacf06891cf5bc62d5b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -39,7 +40,6 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
index 861e15cea691e62331e293b9639e7d1eb1f07bcb..ec8229cee716fd634a4fb45bf6b1b2016156fc00 100644 (file)
@@ -161,7 +161,6 @@ static int s5p64x0_pm_add(struct device *dev, struct subsys_interface *sif)
 {
        pm_cpu_prep = s5p64x0_pm_prepare;
        pm_cpu_sleep = s5p64x0_cpu_suspend;
-       pm_uart_udivslot = 1;
 
        return 0;
 }
index c5a8eeacf81c1ab8d2b012c9d7d6ddbc93d342e5..6a41bf7dacf6b8f7de9f491d1858ad590ae27264 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
@@ -49,7 +50,6 @@
 #include <plat/onenand-core.h>
 #include <plat/pwm-core.h>
 #include <plat/spi-core.h>
-#include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
index 66cb7f16bf2aa37f9ebfdab4a5ebd38bbf18d821..22c23859e45e20465b014fa2981fde84dea194cf 100644 (file)
@@ -13,8 +13,8 @@
 
 /* pull in the relevant register and map files. */
 
+#include <linux/serial_s3c.h>
 #include <mach/map.h>
-#include <plat/regs-serial.h>
 
        /* note, for the boot process to work we have to keep the UART
         * virtual address aligned to an 1MiB boundary for the L1
diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h
deleted file mode 100644 (file)
index 0af8e41..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/arch/arm/mach-s5pc100/include/mach/tick.h
- *
- * Copyright 2009 Samsung Electronics Co.
- *     Byungho Min <bhmin@samsung.com>
- *
- * S3C64XX - Timer tick support definitions
- *
- * Based on mach-s3c6400/include/mach/tick.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TICK_H
-#define __ASM_ARCH_TICK_H __FILE__
-
-#include <linux/irqchip/arm-vic.h>
-
-/* note, the timer interrutps turn up in 2 places, the vic and then
- * the timer block. We take the VIC as the base at the moment.
- */
-static inline u32 s3c24xx_ostimer_pending(void)
-{
-       u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
-       return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
-}
-
-#define TICK_MAX       (0xffffffff)
-
-#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/timex.h b/arch/arm/mach-s5pc100/include/mach/timex.h
deleted file mode 100644 (file)
index 47ffb17..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s5pc100/include/mach/timex.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C6400 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/uncompress.h b/arch/arm/mach-s5pc100/include/mach/uncompress.h
deleted file mode 100644 (file)
index 720e133..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* arch/arm/mach-s5pc100/include/mach/uncompress.h
- *
- * Copyright 2009 Samsung Electronics Co.
- *     Byungho Min <bhmin@samsung.com>
- *
- * S5PC100 - uncompress code
- *
- * Based on mach-s3c6400/include/mach/uncompress.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-       /* we do not need to do any cpu detection here at the moment. */
-       fifo_mask = S3C2440_UFSTAT_TXMASK;
-       fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
-
-       uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
index 9e256b9fc9303a9bf3b5411e0b8d70287254e036..668af3ac31f30a2d2beba748e1d95def5d1d98f8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
@@ -37,7 +38,6 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
 
 #include <plat/clock.h>
index caaedafbbf5f0b0501a9027af04805f3c451631c..8c3abe521757be48e864ca27cfdea68d00dbbe60 100644 (file)
@@ -189,6 +189,7 @@ config MACH_TORBRECK
        select S5PV210_SETUP_I2C1
        select S5PV210_SETUP_I2C2
        select S5PV210_SETUP_SDHCI
+       select SAMSUNG_DEV_IDE
        help
          Machine support for aESOP Torbreck
 
index 26027a29b8a155e5e37b60f45e9da93cc60b8b6d..7024dcd0e40af503292ddb9cef510f6ce340f585 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 
 #include <asm/proc-fns.h>
 #include <asm/mach/arch.h>
@@ -46,7 +47,6 @@
 #include <plat/pwm-core.h>
 #include <plat/tv-core.h>
 #include <plat/spi-core.h>
-#include <plat/regs-serial.h>
 
 #include "common.h"
 
index 80c21996c9434c02453d98570f5160278d1796ed..30b511a580aabae0c11de499cb8e1713ae07c656 100644 (file)
@@ -12,8 +12,8 @@
 
 /* pull in the relevant register and map files. */
 
+#include <linux/serial_s3c.h>
 #include <mach/map.h>
-#include <plat/regs-serial.h>
 
        /* note, for the boot process to work we have to keep the UART
         * virtual address aligned to an 1MiB boundary for the L1
diff --git a/arch/arm/mach-s5pv210/include/mach/timex.h b/arch/arm/mach-s5pv210/include/mach/timex.h
deleted file mode 100644 (file)
index 73dc854..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/include/mach/timex.h
- *
- * Copyright (c) 2003-2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Based on arch/arm/mach-s5p6442/include/mach/timex.h
- *
- * S5PV210 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H __FILE__
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/uncompress.h b/arch/arm/mach-s5pv210/include/mach/uncompress.h
deleted file mode 100644 (file)
index 231cb07..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/include/mach/uncompress.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5PV210 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-       /* we do not need to do any cpu detection here at the moment. */
-       fifo_mask = S5PV210_UFSTAT_TXMASK;
-       fifo_max = 63 << S5PV210_UFSTAT_TXSHIFT;
-
-       uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
index ad40ab0f5dbd37625f2a2e769f871840f644866b..cc37edacda2651ff29a1fcf1871fc1c3dd34a83f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/fb.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
@@ -32,7 +33,6 @@
 #include <mach/regs-clock.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/regs-serial.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/fb.h>
index e5cd9fbf19e99663f8e3ec052e8add96bf7c24e8..b41a38a758441e10fb027b4be5bb8377aad656b1 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/fb.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
@@ -39,7 +40,6 @@
 #include <mach/regs-clock.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/regs-serial.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/fb.h>
index 7c0ed07a78a3bf9bdb7944e609d1d65a19a1a921..448e1d2eeed6b2ab40b802f57bcaa74230c46f10 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/i2c.h>
 #include <linux/device.h>
 
@@ -23,7 +24,6 @@
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 
-#include <plat/regs-serial.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/ata-samsung_cf.h>
index f52cc15c2d85a221a161f5c5d18fbf30c815dd72..2a6655fb63e7b0fe036fdd26cebf11586c75f406 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/device.h>
 #include <linux/dm9000.h>
 #include <linux/fb.h>
@@ -32,7 +33,6 @@
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 
-#include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/gpio-cfg.h>
 #include <plat/devs.h>
index 579afe89842a3b169c9532e46096cfef7c998b9e..157805529f2670bd83aabbc1cd5621a6b719a90d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -22,7 +23,6 @@
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 
-#include <plat/regs-serial.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/i2c-s3c2410.h>
index 831a15824ec8c5eeed1f4b215a13f2bdcfb3f9c7..f9874ba60cc84a6347f0f6bf7b18d1434c886c9f 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
+#include <asm/mach/irda.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
@@ -96,6 +97,37 @@ static struct mcp_plat_data collie_mcp_data = {
        .codec_pdata    = &collie_ucb1x00_data,
 };
 
+static int collie_ir_startup(struct device *dev)
+{
+       int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
+       if (rc)
+               return rc;
+       rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);
+
+       if (!rc)
+               return 0;
+
+       gpio_free(COLLIE_GPIO_IR_ON);
+       return rc;
+}
+
+static void collie_ir_shutdown(struct device *dev)
+{
+       gpio_free(COLLIE_GPIO_IR_ON);
+}
+
+static int collie_ir_set_power(struct device *dev, unsigned int state)
+{
+       gpio_set_value(COLLIE_GPIO_IR_ON, !state);
+       return 0;
+}
+
+static struct irda_platform_data collie_ir_data = {
+       .startup = collie_ir_startup,
+       .shutdown = collie_ir_shutdown,
+       .set_power = collie_ir_set_power,
+};
+
 /*
  * Collie AC IN
  */
@@ -400,6 +432,7 @@ static void __init collie_init(void)
        sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
                            ARRAY_SIZE(collie_flash_resources));
        sa11x0_register_mcp(&collie_mcp_data);
+       sa11x0_register_irda(&collie_ir_data);
 
        sharpsl_save_param();
 }
index daa27c474c133c460c7515fca129c5742d8c1d03..3c43219bc881640372780bc12ce48d9b518c8302 100644 (file)
@@ -122,15 +122,8 @@ static struct irda_platform_data h3100_irda_data = {
        .shutdown       = h3100_irda_shutdown,
 };
 
-static struct gpio_default_state h3100_default_gpio[] = {
-       { H3XXX_GPIO_COM_DCD,   GPIO_MODE_IN,   "COM DCD" },
-       { H3XXX_GPIO_COM_CTS,   GPIO_MODE_IN,   "COM CTS" },
-       { H3XXX_GPIO_COM_RTS,   GPIO_MODE_OUT0, "COM RTS" },
-};
-
 static void __init h3100_mach_init(void)
 {
-       h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
        h3xxx_mach_init();
 
        sa11x0_register_lcd(&h3100_lcd_info);
index a663e723014142e2fb5fabfb81508e310e0c4c52..5be54c214c7c731f1a3f343fc8e0c83920c003a1 100644 (file)
@@ -130,15 +130,8 @@ static struct irda_platform_data h3600_irda_data = {
        .shutdown       = h3600_irda_shutdown,
 };
 
-static struct gpio_default_state h3600_default_gpio[] = {
-       { H3XXX_GPIO_COM_DCD,   GPIO_MODE_IN,   "COM DCD" },
-       { H3XXX_GPIO_COM_CTS,   GPIO_MODE_IN,   "COM CTS" },
-       { H3XXX_GPIO_COM_RTS,   GPIO_MODE_OUT0, "COM RTS" },
-};
-
 static void __init h3600_mach_init(void)
 {
-       h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
        h3xxx_mach_init();
 
        sa11x0_register_lcd(&h3600_lcd_info);
index f17e7382242a1a8fc851996ca1b59f296299a1f1..c79bf467fb7f8efea5b70f7e2d278e3f30c52864 100644 (file)
 
 #include "generic.h"
 
-void h3xxx_init_gpio(struct gpio_default_state *s, size_t n)
-{
-       while (n--) {
-               const char *name = s->name;
-               int err;
-
-               if (!name)
-                       name = "[init]";
-               err = gpio_request(s->gpio, name);
-               if (err) {
-                       printk(KERN_ERR "gpio%u: unable to request: %d\n",
-                               s->gpio, err);
-                       continue;
-               }
-               if (s->mode >= 0) {
-                       err = gpio_direction_output(s->gpio, s->mode);
-               } else {
-                       err = gpio_direction_input(s->gpio);
-               }
-               if (err) {
-                       printk(KERN_ERR "gpio%u: unable to set direction: %d\n",
-                               s->gpio, err);
-                       continue;
-               }
-               if (!s->name)
-                       gpio_free(s->gpio);
-               s++;
-       }
-}
-
-
 /*
  * H3xxx flash support
  */
@@ -116,9 +85,34 @@ static struct resource h3xxx_flash_resource =
 /*
  * H3xxx uart support
  */
+static struct gpio h3xxx_uart_gpio[] = {
+       { H3XXX_GPIO_COM_DCD,   GPIOF_IN,               "COM DCD" },
+       { H3XXX_GPIO_COM_CTS,   GPIOF_IN,               "COM CTS" },
+       { H3XXX_GPIO_COM_RTS,   GPIOF_OUT_INIT_LOW,     "COM RTS" },
+};
+
+static bool h3xxx_uart_request_gpios(void)
+{
+       static bool h3xxx_uart_gpio_ok;
+       int rc;
+
+       if (h3xxx_uart_gpio_ok)
+               return true;
+
+       rc = gpio_request_array(h3xxx_uart_gpio, ARRAY_SIZE(h3xxx_uart_gpio));
+       if (rc)
+               pr_err("h3xxx_uart_request_gpios: error %d\n", rc);
+       else
+               h3xxx_uart_gpio_ok = true;
+
+       return h3xxx_uart_gpio_ok;
+}
+
 static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
 {
        if (port->mapbase == _Ser3UTCR0) {
+               if (!h3xxx_uart_request_gpios())
+                       return;
                gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
        }
 }
@@ -128,6 +122,8 @@ static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
        u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
 
        if (port->mapbase == _Ser3UTCR0) {
+               if (!h3xxx_uart_request_gpios())
+                       return ret;
                /*
                 * DCD and CTS bits are inverted in GPLR by RS232 transceiver
                 */
index 50e1d850ee2e01d6f29ee5004af4339f40c712b0..b478ca180c1974f73ea18fff7ec1b394601f2ed0 100644 (file)
@@ -80,7 +80,7 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_VERSION0    UCB_IO_0
 #define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1
 #define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2
-#define COLLIE_TC35143_GPIO_IR_ON       UCB_IO_3
+#define COLLIE_GPIO_IR_ON              (COLLIE_TC35143_GPIO_BASE + 3)
 #define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4
 #define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5
 #define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5
index c810620db53d60235916e8ecf25c6402f2b984b1..603d4343f7f678d5b11ca8a0bedbafd6737b9f0b 100644 (file)
 #define H3600_EGPIO_LCD_5V_ON          (H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
 #define H3600_EGPIO_LVDD_ON            (H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */
 
-struct gpio_default_state {
-       int gpio;
-       int mode;
-       const char *name;
-};
-
-#define GPIO_MODE_IN   -1
-#define GPIO_MODE_OUT0 0
-#define GPIO_MODE_OUT1 1
-
-void h3xxx_init_gpio(struct gpio_default_state *s, size_t n);
 void __init h3xxx_map_io(void);
 void __init h3xxx_mach_init(void);
 
diff --git a/arch/arm/mach-sa1100/include/mach/timex.h b/arch/arm/mach-sa1100/include/mach/timex.h
deleted file mode 100644 (file)
index 7a5d017..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/timex.h
- *
- * SA1100 architecture timex specifications
- *
- * Copyright (C) 1998 
- */
-
-/*
- * SA1100 timer
- */
-#define CLOCK_TICK_RATE                3686400
index 6fd4acb8f18713b204e45d2c8a32f8854b061ae9..1dea6cfafb3101710053b51ef9665e0814ac143a 100644 (file)
@@ -9,6 +9,7 @@
  *
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -20,6 +21,9 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+#define SA1100_CLOCK_FREQ 3686400
+#define SA1100_LATCH DIV_ROUND_CLOSEST(SA1100_CLOCK_FREQ, HZ)
+
 static u64 notrace sa1100_read_sched_clock(void)
 {
        return readl_relaxed(OSCR);
@@ -93,7 +97,7 @@ static void sa1100_timer_resume(struct clock_event_device *cedev)
        /*
         * OSMR0 is the system timer: make sure OSCR is sufficiently behind
         */
-       writel_relaxed(OSMR0 - LATCH, OSCR);
+       writel_relaxed(OSMR0 - SA1100_LATCH, OSCR);
 }
 #else
 #define sa1100_timer_suspend NULL
@@ -112,7 +116,7 @@ static struct clock_event_device ckevt_sa1100_osmr0 = {
 
 static struct irqaction sa1100_timer_irq = {
        .name           = "ost0",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = sa1100_ost0_interrupt,
        .dev_id         = &ckevt_sa1100_osmr0,
 };
@@ -128,7 +132,7 @@ void __init sa1100_timer_init(void)
 
        setup_irq(IRQ_OST0, &sa1100_timer_irq);
 
-       clocksource_mmio_init(OSCR, "oscr", CLOCK_TICK_RATE, 200, 32,
+       clocksource_mmio_init(OSCR, "oscr", SA1100_CLOCK_FREQ, 200, 32,
                clocksource_mmio_readl_up);
        clockevents_config_and_register(&ckevt_sa1100_osmr0, 3686400,
                                        MIN_OSCR_DELTA * 2, 0x7fffffff);
index 3b8c87461d6717ca0fc514424de3e443ac3f1990..a182008e3aebced89546424d6fda66232880a590 100644 (file)
@@ -5,18 +5,14 @@ config ARCH_SHMOBILE_MULTI
        bool "Renesas ARM SoCs" if ARCH_MULTI_V7
        depends on MMU
        select ARCH_SHMOBILE
-       select CPU_V7
-       select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
        select ARM_GIC
-       select MIGHT_HAVE_CACHE_L2X0
        select MIGHT_HAVE_PCI
+       select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
        select NO_IOPORT
        select PINCTRL
        select ARCH_REQUIRE_GPIOLIB
-       select CLKDEV_LOOKUP
 
 if ARCH_SHMOBILE_MULTI
 
@@ -49,15 +45,12 @@ config MACH_GENMAI
 config MACH_KOELSCH
        bool "Koelsch board"
        depends on ARCH_R8A7791
-
-config MACH_KZM9D
-       bool "KZM9D board"
-       depends on ARCH_EMEV2
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
+       select MICREL_PHY if SH_ETH
 
 config MACH_LAGER
        bool "Lager board"
        depends on ARCH_R8A7790
+       select MICREL_PHY if SH_ETH
 
 comment "Renesas ARM SoCs System Configuration"
 endif
@@ -134,6 +127,7 @@ config ARCH_R8A7790
        select SH_CLK_CPG
        select RENESAS_IRQC
        select SYS_SUPPORTS_SH_CMT
+       select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 
 config ARCH_R8A7791
        bool "R-Car M2 (R8A77910)"
@@ -144,6 +138,7 @@ config ARCH_R8A7791
        select SH_CLK_CPG
        select RENESAS_IRQC
        select SYS_SUPPORTS_SH_CMT
+       select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 
 config ARCH_EMEV2
        bool "Emma Mobile EV2"
@@ -168,11 +163,13 @@ comment "Renesas ARM SoCs Board Type"
 config MACH_APE6EVM
        bool "APE6EVM board"
        depends on ARCH_R8A73A4
+       select SMSC_PHY if SMSC911X
        select USE_OF
 
 config MACH_APE6EVM_REFERENCE
        bool "APE6EVM board - Reference Device Tree Implementation"
        depends on ARCH_R8A73A4
+       select SMSC_PHY if SMSC911X
        select USE_OF
        ---help---
           Use reference implementation of APE6EVM board support
@@ -186,6 +183,7 @@ config MACH_MACKEREL
        depends on ARCH_SH7372
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
+       select SMSC_PHY if SMSC911X
        select SND_SOC_AK4642 if SND_SIMPLE_CARD
        select USE_OF
 
@@ -194,6 +192,7 @@ config MACH_ARMADILLO800EVA
        depends on ARCH_R8A7740
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
+       select SMSC_PHY if SH_ETH
        select SND_SOC_WM8978 if SND_SIMPLE_CARD
        select USE_OF
 
@@ -202,6 +201,7 @@ config MACH_ARMADILLO800EVA_REFERENCE
        depends on ARCH_R8A7740
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
+       select SMSC_PHY if SH_ETH
        select SND_SOC_WM8978 if SND_SIMPLE_CARD
        select USE_OF
        ---help---
@@ -215,11 +215,11 @@ config MACH_BOCKW
        bool "BOCK-W platform"
        depends on ARCH_R8A7778
        select ARCH_REQUIRE_GPIOLIB
-       select RENESAS_INTC_IRQPIN
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select USE_OF
+       select RENESAS_INTC_IRQPIN
        select SND_SOC_AK4554 if SND_SIMPLE_CARD
        select SND_SOC_AK4642 if SND_SIMPLE_CARD
+       select USE_OF
 
 config MACH_BOCKW_REFERENCE
        bool "BOCK-W  - Reference Device Tree Implementation"
@@ -275,6 +275,8 @@ config MACH_LAGER
        bool "Lager board"
        depends on ARCH_R8A7790
        select USE_OF
+       select MICREL_PHY if SH_ETH
+       select SND_SOC_AK4642 if SND_SIMPLE_CARD
 
 config MACH_KOELSCH
        bool "Koelsch board"
index fe7d4ff706e4d70534b31ab3a93efddb78eabeb2..4caffc912a81ccf442c6929d8f08018faff22fd6 100644 (file)
@@ -52,13 +52,13 @@ obj-$(CONFIG_CPU_IDLE)              += cpuidle.o
 obj-$(CONFIG_ARCH_SH7372)      += pm-sh7372.o sleep-sh7372.o pm-rmobile.o
 obj-$(CONFIG_ARCH_SH73A0)      += pm-sh73a0.o
 obj-$(CONFIG_ARCH_R8A7740)     += pm-r8a7740.o pm-rmobile.o
-obj-$(CONFIG_ARCH_R8A7779)     += pm-r8a7779.o
+obj-$(CONFIG_ARCH_R8A7779)     += pm-r8a7779.o pm-rcar.o
+obj-$(CONFIG_ARCH_R8A7790)     += pm-r8a7790.o pm-rcar.o
 
 # Board objects
 ifdef CONFIG_ARCH_SHMOBILE_MULTI
 obj-$(CONFIG_MACH_GENMAI)      += board-genmai-reference.o
 obj-$(CONFIG_MACH_KOELSCH)     += board-koelsch-reference.o
-obj-$(CONFIG_MACH_KZM9D)       += board-kzm9d-reference.o
 obj-$(CONFIG_MACH_LAGER)       += board-lager-reference.o
 else
 obj-$(CONFIG_MACH_APE6EVM)     += board-ape6evm.o
index 9323854242ca10f8bf0f8f1956ae79828d4505a2..2858f380beaefba938f6dbdf75ec81874af62168 100644 (file)
@@ -383,6 +383,8 @@ static struct platform_device sh_eth_device = {
        .id = -1,
        .dev = {
                .platform_data = &sh_eth_platdata,
+               .dma_mask = &sh_eth_device.dev.coherent_dma_mask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
        },
        .resource = sh_eth_resources,
        .num_resources = ARRAY_SIZE(sh_eth_resources),
index 74c27d9d690092d62e0cfdc2f4a9e70797c9cada..b4122f8cb8d9ff986b62948db81755a6a6ba0248 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * Bock-W board support
  *
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- * Copyright (C) 2013  Cogent Embedded, Inc.
+ * Copyright (C) 2013-2014  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -168,6 +168,8 @@ static struct renesas_usbhs_platform_info usbhs_info __initdata = {
        },
        .driver_param = {
                .buswait_bwait  = 4,
+               .d0_tx_id       = HPBDMA_SLAVE_USBFUNC_TX,
+               .d1_rx_id       = HPBDMA_SLAVE_USBFUNC_RX,
        },
 };
 
@@ -233,6 +235,17 @@ static struct sh_eth_plat_data ether_platform_data __initdata = {
        .no_ether_link  = 1,
 };
 
+static struct platform_device_info ether_info __initdata = {
+       .parent         = &platform_bus,
+       .name           = "r8a777x-ether",
+       .id             = -1,
+       .res            = ether_resources,
+       .num_res        = ARRAY_SIZE(ether_resources),
+       .data           = &ether_platform_data,
+       .size_data      = sizeof(ether_platform_data),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
 /* I2C */
 static struct i2c_board_info i2c0_devices[] = {
        {
@@ -332,16 +345,24 @@ static struct rsnd_ssi_platform_info rsnd_ssi[] = {
        RSND_SSI_UNUSED, /* SSI 0 */
        RSND_SSI_UNUSED, /* SSI 1 */
        RSND_SSI_UNUSED, /* SSI 2 */
-       RSND_SSI_SET(1, 0, gic_iid(0x85), RSND_SSI_PLAY),
-       RSND_SSI_SET(2, 0, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE),
-       RSND_SSI_SET(0, 0, gic_iid(0x86), RSND_SSI_PLAY),
-       RSND_SSI_SET(0, 0, gic_iid(0x86), 0),
-       RSND_SSI_SET(3, 0, gic_iid(0x86), RSND_SSI_PLAY),
-       RSND_SSI_SET(4, 0, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE),
+       RSND_SSI_SET(1, HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), RSND_SSI_PLAY),
+       RSND_SSI_SET(2, HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE),
+       RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), RSND_SSI_PLAY),
+       RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0),
+       RSND_SSI_SET(3, HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), RSND_SSI_PLAY),
+       RSND_SSI_SET(4, HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE),
 };
 
 static struct rsnd_scu_platform_info rsnd_scu[9] = {
-       /* no member at this point */
+       { .flags = 0, }, /* SRU 0 */
+       { .flags = 0, }, /* SRU 1 */
+       { .flags = 0, }, /* SRU 2 */
+       { .flags = RSND_SCU_USE_HPBIF, },
+       { .flags = RSND_SCU_USE_HPBIF, },
+       { .flags = RSND_SCU_USE_HPBIF, },
+       { .flags = RSND_SCU_USE_HPBIF, },
+       { .flags = RSND_SCU_USE_HPBIF, },
+       { .flags = RSND_SCU_USE_HPBIF, },
 };
 
 enum {
@@ -576,11 +597,7 @@ static void __init bockw_init(void)
        r8a7778_init_irq_extpin(1);
        r8a7778_add_standard_devices();
 
-       platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
-                                         ether_resources,
-                                         ARRAY_SIZE(ether_resources),
-                                         &ether_platform_data,
-                                         sizeof(ether_platform_data));
+       platform_device_register_full(&ether_info);
 
        platform_device_register_full(&vin0_info);
        /* VIN1 has a pin conflict with Ether */
index 3e92e3c62d4c96af050eebb27f44ff526ee7253e..6c328d63b8199bb507c9c51e56f5b7ea7eae163d 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * Genmai board support
  *
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2014  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/sh_eth.h>
+#include <linux/spi/rspi.h>
+#include <linux/spi/spi.h>
 #include <mach/common.h>
+#include <mach/irqs.h>
 #include <mach/r7s72100.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+/* Ether */
+static const struct sh_eth_plat_data ether_pdata __initconst = {
+       .phy                    = 0x00, /* PD60610 */
+       .edmac_endian           = EDMAC_LITTLE_ENDIAN,
+       .phy_interface          = PHY_INTERFACE_MODE_MII,
+       .no_ether_link          = 1
+};
+
+static const struct resource ether_resources[] __initconst = {
+       DEFINE_RES_MEM(0xe8203000, 0x800),
+       DEFINE_RES_MEM(0xe8204800, 0x200),
+       DEFINE_RES_IRQ(gic_iid(359)),
+};
+
+static const struct platform_device_info ether_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "r7s72100-ether",
+       .id             = -1,
+       .res            = ether_resources,
+       .num_res        = ARRAY_SIZE(ether_resources),
+       .data           = &ether_pdata,
+       .size_data      = sizeof(ether_pdata),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
+/* RSPI */
+#define RSPI_RESOURCE(idx, baseaddr, irq)                              \
+static const struct resource rspi##idx##_resources[] __initconst = {   \
+       DEFINE_RES_MEM(baseaddr, 0x24),                                 \
+       DEFINE_RES_IRQ_NAMED(irq, "error"),                             \
+       DEFINE_RES_IRQ_NAMED(irq + 1, "rx"),                            \
+       DEFINE_RES_IRQ_NAMED(irq + 2, "tx"),                            \
+}
+
+RSPI_RESOURCE(0, 0xe800c800, gic_iid(270));
+RSPI_RESOURCE(1, 0xe800d000, gic_iid(273));
+RSPI_RESOURCE(2, 0xe800d800, gic_iid(276));
+RSPI_RESOURCE(3, 0xe800e000, gic_iid(279));
+RSPI_RESOURCE(4, 0xe800e800, gic_iid(282));
+
+static const struct rspi_plat_data rspi_pdata __initconst = {
+       .num_chipselect = 1,
+};
+
+#define r7s72100_register_rspi(idx)                                       \
+       platform_device_register_resndata(&platform_bus, "rspi-rz", idx,   \
+                                       rspi##idx##_resources,             \
+                                       ARRAY_SIZE(rspi##idx##_resources), \
+                                       &rspi_pdata, sizeof(rspi_pdata))
+
+static const struct spi_board_info spi_info[] __initconst = {
+       {
+               .modalias               = "wm8978",
+               .max_speed_hz           = 5000000,
+               .bus_num                = 4,
+               .chip_select            = 0,
+       },
+};
+
 static void __init genmai_add_standard_devices(void)
 {
        r7s72100_clock_init();
        r7s72100_add_dt_devices();
+
+       platform_device_register_full(&ether_info);
+
+       r7s72100_register_rspi(0);
+       r7s72100_register_rspi(1);
+       r7s72100_register_rspi(2);
+       r7s72100_register_rspi(3);
+       r7s72100_register_rspi(4);
+       spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
 }
 
 static const char * const genmai_boards_compat_dt[] __initconst = {
index 652b5926841633a467b11ec72f699dfe09a63b31..a3fd30242bd87d2a8c77f2c6ade2a3c96259e039 100644 (file)
 
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/rcar-du.h>
 #include <mach/common.h>
+#include <mach/irqs.h>
 #include <mach/rcar-gen2.h>
 #include <mach/r8a7791.h>
 #include <asm/mach/arch.h>
 
+/* DU */
+static struct rcar_du_encoder_data koelsch_du_encoders[] = {
+       {
+               .type = RCAR_DU_ENCODER_NONE,
+               .output = RCAR_DU_OUTPUT_LVDS0,
+               .connector.lvds.panel = {
+                       .width_mm = 210,
+                       .height_mm = 158,
+                       .mode = {
+                               .clock = 65000,
+                               .hdisplay = 1024,
+                               .hsync_start = 1048,
+                               .hsync_end = 1184,
+                               .htotal = 1344,
+                               .vdisplay = 768,
+                               .vsync_start = 771,
+                               .vsync_end = 777,
+                               .vtotal = 806,
+                               .flags = 0,
+                       },
+               },
+       },
+};
+
+static struct rcar_du_platform_data koelsch_du_pdata = {
+       .encoders = koelsch_du_encoders,
+       .num_encoders = ARRAY_SIZE(koelsch_du_encoders),
+};
+
+static const struct resource du_resources[] __initconst = {
+       DEFINE_RES_MEM(0xfeb00000, 0x40000),
+       DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
+       DEFINE_RES_IRQ(gic_spi(256)),
+       DEFINE_RES_IRQ(gic_spi(268)),
+};
+
+static void __init koelsch_add_du_device(void)
+{
+       struct platform_device_info info = {
+               .name = "rcar-du-r8a7791",
+               .id = -1,
+               .res = du_resources,
+               .num_res = ARRAY_SIZE(du_resources),
+               .data = &koelsch_du_pdata,
+               .size_data = sizeof(koelsch_du_pdata),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+
+       platform_device_register_full(&info);
+}
+
 static void __init koelsch_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
        /*
-        * This is a really crude hack to provide clkdev support to the SCIF
-        * and CMT devices until they get moved to DT.
+        * This is a really crude hack to provide clkdev support to the CMT and
+        * DU devices until they get moved to DT.
         */
-       static const char * const scif_names[] = {
-               "scifa0", "scifa1", "scifb0", "scifb1", "scifb2", "scifa2",
-               "scif0", "scif1", "scif2", "scif3", "scif4", "scif5", "scifa3",
-               "scifa4", "scifa5",
+       static const struct clk_name {
+               const char *clk;
+               const char *con_id;
+               const char *dev_id;
+       } clk_names[] = {
+               { "cmt0", NULL, "sh_cmt.0" },
+               { "scifa0", NULL, "sh-sci.0" },
+               { "scifa1", NULL, "sh-sci.1" },
+               { "scifb0", NULL, "sh-sci.2" },
+               { "scifb1", NULL, "sh-sci.3" },
+               { "scifb2", NULL, "sh-sci.4" },
+               { "scifa2", NULL, "sh-sci.5" },
+               { "scif0", NULL, "sh-sci.6" },
+               { "scif1", NULL, "sh-sci.7" },
+               { "scif2", NULL, "sh-sci.8" },
+               { "scif3", NULL, "sh-sci.9" },
+               { "scif4", NULL, "sh-sci.10" },
+               { "scif5", NULL, "sh-sci.11" },
+               { "scifa3", NULL, "sh-sci.12" },
+               { "scifa4", NULL, "sh-sci.13" },
+               { "scifa5", NULL, "sh-sci.14" },
+               { "du0", "du.0", "rcar-du-r8a7791" },
+               { "du1", "du.1", "rcar-du-r8a7791" },
+               { "lvds0", "lvds.0", "rcar-du-r8a7791" },
        };
        struct clk *clk;
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(scif_names); ++i) {
-               clk = clk_get(NULL, scif_names[i]);
-               if (clk) {
-                       clk_register_clkdev(clk, NULL, "sh-sci.%u", i);
+       for (i = 0; i < ARRAY_SIZE(clk_names); ++i) {
+               clk = clk_get(NULL, clk_names[i].clk);
+               if (!IS_ERR(clk)) {
+                       clk_register_clkdev(clk, clk_names[i].con_id,
+                                           clk_names[i].dev_id);
                        clk_put(clk);
                }
        }
 
-       clk = clk_get(NULL, "cmt0");
-       if (clk) {
-               clk_register_clkdev(clk, NULL, "sh_cmt.0");
-               clk_put(clk);
-       }
-#else
-       r8a7791_clock_init();
-#endif
        r8a7791_add_dt_devices();
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+       koelsch_add_du_device();
 }
 
 static const char * const koelsch_boards_compat_dt[] __initconst = {
index de7cc64b1f3733823fa0b041ad7853ea73ba5c09..5a034ff405d001c82e9c79872296719691f4a378 100644 (file)
@@ -2,8 +2,9 @@
  * Koelsch board support
  *
  * Copyright (C) 2013  Renesas Electronics Corporation
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2014  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/leds.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 #include <linux/phy.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/rcar-du.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/regulator/machine.h>
 #include <linux/sh_eth.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/rspi.h>
+#include <linux/spi/spi.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r8a7791.h>
@@ -92,6 +106,7 @@ static void __init koelsch_add_du_device(void)
 /* Ether */
 static const struct sh_eth_plat_data ether_pdata __initconst = {
        .phy                    = 0x1,
+       .phy_irq                = irq_pin(0),
        .edmac_endian           = EDMAC_LITTLE_ENDIAN,
        .phy_interface          = PHY_INTERFACE_MODE_RMII,
        .ether_link_active_low  = 1,
@@ -102,6 +117,17 @@ static const struct resource ether_resources[] __initconst = {
        DEFINE_RES_IRQ(gic_spi(162)),
 };
 
+static const struct platform_device_info ether_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "r8a7791-ether",
+       .id             = -1,
+       .res            = ether_resources,
+       .num_res        = ARRAY_SIZE(ether_resources),
+       .data           = &ether_pdata,
+       .size_data      = sizeof(ether_pdata),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
 /* LEDS */
 static struct gpio_led koelsch_leds[] = {
        {
@@ -148,6 +174,199 @@ static const struct gpio_keys_platform_data koelsch_keys_pdata __initconst = {
        .nbuttons       = ARRAY_SIZE(gpio_buttons),
 };
 
+/* QSPI */
+static const struct resource qspi_resources[] __initconst = {
+       DEFINE_RES_MEM(0xe6b10000, 0x1000),
+       DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"),
+};
+
+static const struct rspi_plat_data qspi_pdata __initconst = {
+       .num_chipselect = 1,
+};
+
+/* SPI Flash memory (Spansion S25FL512SAGMFIG11 64 MiB) */
+static struct mtd_partition spi_flash_part[] = {
+       {
+               .name           = "loader",
+               .offset         = 0x00000000,
+               .size           = 512 * 1024,
+               .mask_flags     = MTD_WRITEABLE,
+       },
+       {
+               .name           = "bootenv",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 512 * 1024,
+               .mask_flags     = MTD_WRITEABLE,
+       },
+       {
+               .name           = "data",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static const struct flash_platform_data spi_flash_data = {
+       .name           = "m25p80",
+       .parts          = spi_flash_part,
+       .nr_parts       = ARRAY_SIZE(spi_flash_part),
+       .type           = "s25fl512s",
+};
+
+static const struct spi_board_info spi_info[] __initconst = {
+       {
+               .modalias       = "m25p80",
+               .platform_data  = &spi_flash_data,
+               .mode           = SPI_MODE_0,
+               .max_speed_hz   = 30000000,
+               .bus_num        = 0,
+               .chip_select    = 0,
+       },
+};
+
+/* SATA0 */
+static const struct resource sata0_resources[] __initconst = {
+       DEFINE_RES_MEM(0xee300000, 0x2000),
+       DEFINE_RES_IRQ(gic_spi(105)),
+};
+
+static const struct platform_device_info sata0_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "sata-r8a7791",
+       .id             = 0,
+       .res            = sata0_resources,
+       .num_res        = ARRAY_SIZE(sata0_resources),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
+/* I2C */
+static const struct resource i2c_resources[] __initconst = {
+       /* I2C0 */
+       DEFINE_RES_MEM(0xE6508000, 0x40),
+       DEFINE_RES_IRQ(gic_spi(287)),
+       /* I2C1 */
+       DEFINE_RES_MEM(0xE6518000, 0x40),
+       DEFINE_RES_IRQ(gic_spi(288)),
+       /* I2C2 */
+       DEFINE_RES_MEM(0xE6530000, 0x40),
+       DEFINE_RES_IRQ(gic_spi(286)),
+       /* I2C3 */
+       DEFINE_RES_MEM(0xE6540000, 0x40),
+       DEFINE_RES_IRQ(gic_spi(290)),
+       /* I2C4 */
+       DEFINE_RES_MEM(0xE6520000, 0x40),
+       DEFINE_RES_IRQ(gic_spi(19)),
+       /* I2C5 */
+       DEFINE_RES_MEM(0xE6528000, 0x40),
+       DEFINE_RES_IRQ(gic_spi(20)),
+};
+
+static void __init koelsch_add_i2c(unsigned idx)
+{
+       unsigned res_idx = idx * 2;
+
+       BUG_ON(res_idx >= ARRAY_SIZE(i2c_resources));
+
+       platform_device_register_simple("i2c-rcar_gen2", idx,
+                                       i2c_resources + res_idx, 2);
+}
+
+#define SDHI_REGULATOR(idx, vdd_pin, vccq_pin)                         \
+static struct regulator_consumer_supply vcc_sdhi##idx##_consumer =     \
+       REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi." #idx);               \
+                                                                       \
+static struct regulator_init_data vcc_sdhi##idx##_init_data = {                \
+       .constraints = {                                                \
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,              \
+       },                                                              \
+       .consumer_supplies      = &vcc_sdhi##idx##_consumer,            \
+       .num_consumer_supplies  = 1,                                    \
+};                                                                     \
+                                                                       \
+static const struct fixed_voltage_config vcc_sdhi##idx##_info __initconst = {\
+       .supply_name    = "SDHI" #idx "Vcc",                            \
+       .microvolts     = 3300000,                                      \
+       .gpio           = vdd_pin,                                      \
+       .enable_high    = 1,                                            \
+       .init_data      = &vcc_sdhi##idx##_init_data,                   \
+};                                                                     \
+                                                                       \
+static struct regulator_consumer_supply vccq_sdhi##idx##_consumer =    \
+       REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi." #idx);              \
+                                                                       \
+static struct regulator_init_data vccq_sdhi##idx##_init_data = {       \
+       .constraints = {                                                \
+               .input_uV       = 3300000,                              \
+               .min_uV         = 1800000,                              \
+               .max_uV         = 3300000,                              \
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |            \
+                                 REGULATOR_CHANGE_STATUS,              \
+       },                                                              \
+       .consumer_supplies      = &vccq_sdhi##idx##_consumer,           \
+       .num_consumer_supplies  = 1,                                    \
+};                                                                     \
+                                                                       \
+static struct gpio vccq_sdhi##idx##_gpio =                             \
+       { vccq_pin, GPIOF_OUT_INIT_HIGH, "vccq-sdhi" #idx };            \
+                                                                       \
+static struct gpio_regulator_state vccq_sdhi##idx##_states[] = {       \
+       { .value = 1800000, .gpios = 0 },                               \
+       { .value = 3300000, .gpios = 1 },                               \
+};                                                                     \
+                                                                       \
+static const struct gpio_regulator_config vccq_sdhi##idx##_info __initconst = {\
+       .supply_name    = "vqmmc",                                      \
+       .gpios          = &vccq_sdhi##idx##_gpio,                       \
+       .nr_gpios       = 1,                                            \
+       .states         = vccq_sdhi##idx##_states,                      \
+       .nr_states      = ARRAY_SIZE(vccq_sdhi##idx##_states),          \
+       .type           = REGULATOR_VOLTAGE,                            \
+       .init_data      = &vccq_sdhi##idx##_init_data,                  \
+};
+
+SDHI_REGULATOR(0, RCAR_GP_PIN(7, 17), RCAR_GP_PIN(2, 12));
+SDHI_REGULATOR(1, RCAR_GP_PIN(7, 18), RCAR_GP_PIN(2, 13));
+SDHI_REGULATOR(2, RCAR_GP_PIN(7, 19), RCAR_GP_PIN(2, 26));
+
+/* SDHI0 */
+static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
+       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+                         MMC_CAP_POWER_OFF_CARD,
+       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi0_resources[] __initdata = {
+       DEFINE_RES_MEM(0xee100000, 0x200),
+       DEFINE_RES_IRQ(gic_spi(165)),
+};
+
+/* SDHI1 */
+static struct sh_mobile_sdhi_info sdhi1_info __initdata = {
+       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+                         MMC_CAP_POWER_OFF_CARD,
+       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi1_resources[] __initdata = {
+       DEFINE_RES_MEM(0xee140000, 0x100),
+       DEFINE_RES_IRQ(gic_spi(167)),
+};
+
+/* SDHI2 */
+static struct sh_mobile_sdhi_info sdhi2_info __initdata = {
+       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+                         MMC_CAP_POWER_OFF_CARD,
+       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT |
+                         TMIO_MMC_WRPROTECT_DISABLE,
+};
+
+static struct resource sdhi2_resources[] __initdata = {
+       DEFINE_RES_MEM(0xee160000, 0x100),
+       DEFINE_RES_IRQ(gic_spi(168)),
+};
+
 static const struct pinctrl_map koelsch_pinctrl_map[] = {
        /* DU */
        PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791",
@@ -165,12 +384,51 @@ static const struct pinctrl_map koelsch_pinctrl_map[] = {
                                  "eth_rmii", "eth"),
        PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791",
                                  "intc_irq0", "intc"),
+       /* QSPI */
+       PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7791",
+                                 "qspi_ctrl", "qspi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7791",
+                                 "qspi_data4", "qspi"),
        /* SCIF0 (CN19: DEBUG SERIAL0) */
        PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7791",
                                  "scif0_data_d", "scif0"),
        /* SCIF1 (CN20: DEBUG SERIAL1) */
        PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7791",
                                  "scif1_data_d", "scif1"),
+       /* I2C1 */
+       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.1", "pfc-r8a7791",
+                                 "i2c1_e", "i2c1"),
+       /* I2C2 */
+       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.2", "pfc-r8a7791",
+                                 "i2c2", "i2c2"),
+       /* I2C4 */
+       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.4", "pfc-r8a7791",
+                                 "i2c4_c", "i2c4"),
+       /* SDHI0 */
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
+                                 "sdhi0_data4", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
+                                 "sdhi0_ctrl", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
+                                 "sdhi0_cd", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
+                                 "sdhi0_wp", "sdhi0"),
+       /* SDHI2 */
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
+                                 "sdhi1_data4", "sdhi1"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
+                                 "sdhi1_ctrl", "sdhi1"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
+                                 "sdhi1_cd", "sdhi1"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
+                                 "sdhi1_wp", "sdhi1"),
+       /* SDHI2 */
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791",
+                                 "sdhi2_data4", "sdhi2"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791",
+                                 "sdhi2_ctrl", "sdhi2"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791",
+                                 "sdhi2_cd", "sdhi2"),
 };
 
 static void __init koelsch_add_standard_devices(void)
@@ -180,18 +438,53 @@ static void __init koelsch_add_standard_devices(void)
                                  ARRAY_SIZE(koelsch_pinctrl_map));
        r8a7791_pinmux_init();
        r8a7791_add_standard_devices();
-       platform_device_register_resndata(&platform_bus, "r8a7791-ether", -1,
-                                         ether_resources,
-                                         ARRAY_SIZE(ether_resources),
-                                         &ether_pdata, sizeof(ether_pdata));
+       platform_device_register_full(&ether_info);
        platform_device_register_data(&platform_bus, "leds-gpio", -1,
                                      &koelsch_leds_pdata,
                                      sizeof(koelsch_leds_pdata));
        platform_device_register_data(&platform_bus, "gpio-keys", -1,
                                      &koelsch_keys_pdata,
                                      sizeof(koelsch_keys_pdata));
+       platform_device_register_resndata(&platform_bus, "qspi", 0,
+                                         qspi_resources,
+                                         ARRAY_SIZE(qspi_resources),
+                                         &qspi_pdata, sizeof(qspi_pdata));
+       spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
 
        koelsch_add_du_device();
+
+       platform_device_register_full(&sata0_info);
+
+       koelsch_add_i2c(1);
+       koelsch_add_i2c(2);
+       koelsch_add_i2c(4);
+       koelsch_add_i2c(5);
+
+       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 0,
+                                     &vcc_sdhi0_info, sizeof(struct fixed_voltage_config));
+       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 1,
+                                     &vcc_sdhi1_info, sizeof(struct fixed_voltage_config));
+       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2,
+                                     &vcc_sdhi2_info, sizeof(struct fixed_voltage_config));
+       platform_device_register_data(&platform_bus, "gpio-regulator", 0,
+                                     &vccq_sdhi0_info, sizeof(struct gpio_regulator_config));
+       platform_device_register_data(&platform_bus, "gpio-regulator", 1,
+                                     &vccq_sdhi1_info, sizeof(struct gpio_regulator_config));
+       platform_device_register_data(&platform_bus, "gpio-regulator", 2,
+                                     &vccq_sdhi2_info, sizeof(struct gpio_regulator_config));
+
+       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0,
+                                         sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
+                                         &sdhi0_info, sizeof(struct sh_mobile_sdhi_info));
+
+       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1,
+                                         sdhi1_resources, ARRAY_SIZE(sdhi1_resources),
+                                         &sdhi1_info, sizeof(struct sh_mobile_sdhi_info));
+
+       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 2,
+                                         sdhi2_resources, ARRAY_SIZE(sdhi2_resources),
+                                         &sdhi2_info, sizeof(struct sh_mobile_sdhi_info));
+
 }
 
 /*
@@ -215,6 +508,8 @@ static void __init koelsch_init(void)
 {
        koelsch_add_standard_devices();
 
+       irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
+
        if (IS_ENABLED(CONFIG_PHYLIB))
                phy_register_fixup_for_id("r8a7791-ether-ff:01",
                                          koelsch_ksz8041_fixup);
diff --git a/arch/arm/mach-shmobile/board-kzm9d-reference.c b/arch/arm/mach-shmobile/board-kzm9d-reference.c
deleted file mode 100644 (file)
index 054d8d5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * kzm9d board support - Reference DT implementation
- *
- * Copyright (C) 2013  Renesas Solutions Corp.
- * Copyright (C) 2013  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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/init.h>
-#include <linux/of_platform.h>
-#include <mach/emev2.h>
-#include <mach/common.h>
-#include <asm/mach/arch.h>
-
-static void __init kzm9d_add_standard_devices(void)
-{
-       if (!IS_ENABLED(CONFIG_COMMON_CLK))
-               emev2_clock_init();
-
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *kzm9d_boards_compat_dt[] __initdata = {
-       "renesas,kzm9d",
-       "renesas,kzm9d-reference",
-       NULL,
-};
-
-DT_MACHINE_START(KZM9D_DT, "kzm9d")
-       .smp            = smp_ops(emev2_smp_ops),
-       .map_io         = emev2_map_io,
-       .init_early     = emev2_init_delay,
-       .init_machine   = kzm9d_add_standard_devices,
-       .init_late      = shmobile_init_late,
-       .dt_compat      = kzm9d_boards_compat_dt,
-MACHINE_END
index a6e271d92af04b4fb7037f615684d0508375a844..440aac36d6938d1e58b78618d1d1f599665d1f96 100644 (file)
 
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/rcar-du.h>
 #include <mach/common.h>
+#include <mach/irqs.h>
 #include <mach/rcar-gen2.h>
 #include <mach/r8a7790.h>
 #include <asm/mach/arch.h>
 
+/* DU */
+static struct rcar_du_encoder_data lager_du_encoders[] = {
+       {
+               .type = RCAR_DU_ENCODER_VGA,
+               .output = RCAR_DU_OUTPUT_DPAD0,
+       }, {
+               .type = RCAR_DU_ENCODER_NONE,
+               .output = RCAR_DU_OUTPUT_LVDS1,
+               .connector.lvds.panel = {
+                       .width_mm = 210,
+                       .height_mm = 158,
+                       .mode = {
+                               .clock = 65000,
+                               .hdisplay = 1024,
+                               .hsync_start = 1048,
+                               .hsync_end = 1184,
+                               .htotal = 1344,
+                               .vdisplay = 768,
+                               .vsync_start = 771,
+                               .vsync_end = 777,
+                               .vtotal = 806,
+                               .flags = 0,
+                       },
+               },
+       },
+};
+
+static struct rcar_du_platform_data lager_du_pdata = {
+       .encoders = lager_du_encoders,
+       .num_encoders = ARRAY_SIZE(lager_du_encoders),
+};
+
+static const struct resource du_resources[] __initconst = {
+       DEFINE_RES_MEM(0xfeb00000, 0x70000),
+       DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
+       DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"),
+       DEFINE_RES_IRQ(gic_spi(256)),
+       DEFINE_RES_IRQ(gic_spi(268)),
+       DEFINE_RES_IRQ(gic_spi(269)),
+};
+
+static void __init lager_add_du_device(void)
+{
+       struct platform_device_info info = {
+               .name = "rcar-du-r8a7790",
+               .id = -1,
+               .res = du_resources,
+               .num_res = ARRAY_SIZE(du_resources),
+               .data = &lager_du_pdata,
+               .size_data = sizeof(lager_du_pdata),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+
+       platform_device_register_full(&info);
+}
+
 static void __init lager_add_standard_devices(void)
 {
-#ifdef CONFIG_COMMON_CLK
        /*
-        * This is a really crude hack to provide clkdev support to the SCIF
-        * and CMT devices until they get moved to DT.
+        * This is a really crude hack to provide clkdev support to platform
+        * devices until they get moved to DT.
         */
-       static const char * const scif_names[] = {
-               "scifa0", "scifa1", "scifb0", "scifb1",
-               "scifb2", "scifa2", "scif0", "scif1",
-               "hscif0", "hscif1",
+       static const struct clk_name {
+               const char *clk;
+               const char *con_id;
+               const char *dev_id;
+       } clk_names[] = {
+               { "cmt0", NULL, "sh_cmt.0" },
+               { "scifa0", NULL, "sh-sci.0" },
+               { "scifa1", NULL, "sh-sci.1" },
+               { "scifb0", NULL, "sh-sci.2" },
+               { "scifb1", NULL, "sh-sci.3" },
+               { "scifb2", NULL, "sh-sci.4" },
+               { "scifa2", NULL, "sh-sci.5" },
+               { "scif0", NULL, "sh-sci.6" },
+               { "scif1", NULL, "sh-sci.7" },
+               { "hscif0", NULL, "sh-sci.8" },
+               { "hscif1", NULL, "sh-sci.9" },
+               { "du0", "du.0", "rcar-du-r8a7790" },
+               { "du1", "du.1", "rcar-du-r8a7790" },
+               { "du2", "du.2", "rcar-du-r8a7790" },
+               { "lvds0", "lvds.0", "rcar-du-r8a7790" },
+               { "lvds1", "lvds.1", "rcar-du-r8a7790" },
        };
        struct clk *clk;
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(scif_names); ++i) {
-               clk = clk_get(NULL, scif_names[i]);
-               if (clk) {
-                       clk_register_clkdev(clk, NULL, "sh-sci.%u", i);
+       for (i = 0; i < ARRAY_SIZE(clk_names); ++i) {
+               clk = clk_get(NULL, clk_names[i].clk);
+               if (!IS_ERR(clk)) {
+                       clk_register_clkdev(clk, clk_names[i].con_id,
+                                           clk_names[i].dev_id);
                        clk_put(clk);
                }
        }
 
-       clk = clk_get(NULL, "cmt0");
-       if (clk) {
-               clk_register_clkdev(clk, NULL, "sh_cmt.0");
-               clk_put(clk);
-       }
-#else
-       r8a7790_clock_init();
-#endif
-
        r8a7790_add_dt_devices();
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+       lager_add_du_device();
 }
 
 static const char *lager_boards_compat_dt[] __initdata = {
index f20c10a18543973c3d5797d83e8ac4bae26c8708..f0104bfe544e378c6a778d853fbd3fc822669087 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * Lager board support
  *
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2014  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
+#include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/leds.h>
+#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/platform_data/camera-rcar.h>
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/rcar-du.h>
+#include <linux/platform_data/usb-rcar-gen2-phy.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/machine.h>
 #include <linux/sh_eth.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/renesas_usbhs.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r8a7790.h>
+#include <media/soc_camera.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <linux/mtd/partitions.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/rspi.h>
 #include <linux/spi/spi.h>
+#include <sound/rcar_snd.h>
+#include <sound/simple_card.h>
+
+/*
+ * SSI-AK4643
+ *
+ * SW1: 1: AK4643
+ *      2: CN22
+ *      3: ADV7511
+ *
+ * this command is required when playback.
+ *
+ * # amixer set "LINEOUT Mixer DACL" on
+ */
+
+/*
+ * SDHI0 (CN8)
+ *
+ * JP3:  pin1
+ * SW20: pin1
+
+ * GP5_24:     1:  VDD  3.3V (defult)
+ *             0:  VDD  0.0V
+ * GP5_29:     1:  VccQ 3.3V (defult)
+ *             0:  VccQ 1.8V
+ *
+ */
 
 /* DU */
 static struct rcar_du_encoder_data lager_du_encoders[] = {
@@ -228,6 +265,7 @@ static const struct resource mmcif1_resources[] __initconst = {
 /* Ether */
 static const struct sh_eth_plat_data ether_pdata __initconst = {
        .phy                    = 0x1,
+       .phy_irq                = irq_pin(0),
        .edmac_endian           = EDMAC_LITTLE_ENDIAN,
        .phy_interface          = PHY_INTERFACE_MODE_RMII,
        .ether_link_active_low  = 1,
@@ -238,6 +276,17 @@ static const struct resource ether_resources[] __initconst = {
        DEFINE_RES_IRQ(gic_spi(162)),
 };
 
+static const struct platform_device_info ether_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "r8a7790-ether",
+       .id             = -1,
+       .res            = ether_resources,
+       .num_res        = ARRAY_SIZE(ether_resources),
+       .data           = &ether_pdata,
+       .size_data      = sizeof(ether_pdata),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
 /* SPI Flash memory (Spansion S25FL512SAGMFIG11 64Mb) */
 static struct mtd_partition spi_flash_part[] = {
        /* Reserved for user loader program, read-only */
@@ -263,7 +312,7 @@ static struct mtd_partition spi_flash_part[] = {
        },
 };
 
-static struct flash_platform_data spi_flash_data = {
+static const struct flash_platform_data spi_flash_data = {
        .name           = "m25p80",
        .parts          = spi_flash_part,
        .nr_parts       = ARRAY_SIZE(spi_flash_part),
@@ -288,9 +337,361 @@ static const struct spi_board_info spi_info[] __initconst = {
 /* QSPI resource */
 static const struct resource qspi_resources[] __initconst = {
        DEFINE_RES_MEM(0xe6b10000, 0x1000),
-       DEFINE_RES_IRQ(gic_spi(184)),
+       DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"),
+};
+
+/* VIN */
+static const struct resource vin_resources[] __initconst = {
+       /* VIN0 */
+       DEFINE_RES_MEM(0xe6ef0000, 0x1000),
+       DEFINE_RES_IRQ(gic_spi(188)),
+       /* VIN1 */
+       DEFINE_RES_MEM(0xe6ef1000, 0x1000),
+       DEFINE_RES_IRQ(gic_spi(189)),
+};
+
+static void __init lager_add_vin_device(unsigned idx,
+                                       struct rcar_vin_platform_data *pdata)
+{
+       struct platform_device_info vin_info = {
+               .parent         = &platform_bus,
+               .name           = "r8a7790-vin",
+               .id             = idx,
+               .res            = &vin_resources[idx * 2],
+               .num_res        = 2,
+               .dma_mask       = DMA_BIT_MASK(32),
+               .data           = pdata,
+               .size_data      = sizeof(*pdata),
+       };
+
+       BUG_ON(idx > 1);
+
+       platform_device_register_full(&vin_info);
+}
+
+#define LAGER_CAMERA(idx, name, addr, pdata, flag)                     \
+static struct i2c_board_info i2c_cam##idx##_device = {                 \
+       I2C_BOARD_INFO(name, addr),                                     \
+};                                                                     \
+                                                                       \
+static struct rcar_vin_platform_data vin##idx##_pdata = {              \
+       .flags = flag,                                                  \
+};                                                                     \
+                                                                       \
+static struct soc_camera_link cam##idx##_link = {                      \
+       .bus_id = idx,                                                  \
+       .board_info = &i2c_cam##idx##_device,                           \
+       .i2c_adapter_id = 2,                                            \
+       .module_name = name,                                            \
+       .priv = pdata,                                                  \
+}
+
+/* Camera 0 is not currently supported due to adv7612 support missing */
+LAGER_CAMERA(1, "adv7180", 0x20, NULL, RCAR_VIN_BT656);
+
+static void __init lager_add_camera1_device(void)
+{
+       platform_device_register_data(&platform_bus, "soc-camera-pdrv", 1,
+                                     &cam1_link, sizeof(cam1_link));
+       lager_add_vin_device(1, &vin1_pdata);
+}
+
+/* SATA1 */
+static const struct resource sata1_resources[] __initconst = {
+       DEFINE_RES_MEM(0xee500000, 0x2000),
+       DEFINE_RES_IRQ(gic_spi(106)),
+};
+
+static const struct platform_device_info sata1_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "sata-r8a7790",
+       .id             = 1,
+       .res            = sata1_resources,
+       .num_res        = ARRAY_SIZE(sata1_resources),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
+/* USBHS */
+static const struct resource usbhs_resources[] __initconst = {
+       DEFINE_RES_MEM(0xe6590000, 0x100),
+       DEFINE_RES_IRQ(gic_spi(107)),
+};
+
+struct usbhs_private {
+       struct renesas_usbhs_platform_info info;
+       struct usb_phy *phy;
+};
+
+#define usbhs_get_priv(pdev) \
+       container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info)
+
+static int usbhs_power_ctrl(struct platform_device *pdev,
+                               void __iomem *base, int enable)
+{
+       struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+       if (!priv->phy)
+               return -ENODEV;
+
+       if (enable) {
+               int retval = usb_phy_init(priv->phy);
+
+               if (!retval)
+                       retval = usb_phy_set_suspend(priv->phy, 0);
+               return retval;
+       }
+
+       usb_phy_set_suspend(priv->phy, 1);
+       usb_phy_shutdown(priv->phy);
+       return 0;
+}
+
+static int usbhs_hardware_init(struct platform_device *pdev)
+{
+       struct usbhs_private *priv = usbhs_get_priv(pdev);
+       struct usb_phy *phy;
+       int ret;
+
+       /* USB0 Function - use PWEN as GPIO input to detect DIP Switch SW5
+        * setting to avoid VBUS short circuit due to wrong cable.
+        * PWEN should be pulled up high if USB Function is selected by SW5
+        */
+       gpio_request_one(RCAR_GP_PIN(5, 18), GPIOF_IN, NULL); /* USB0_PWEN */
+       if (!gpio_get_value(RCAR_GP_PIN(5, 18))) {
+               pr_warn("Error: USB Function not selected - check SW5 + SW6\n");
+               ret = -ENOTSUPP;
+               goto error;
+       }
+
+       phy = usb_get_phy_dev(&pdev->dev, 0);
+       if (IS_ERR(phy)) {
+               ret = PTR_ERR(phy);
+               goto error;
+       }
+
+       priv->phy = phy;
+       return 0;
+ error:
+       gpio_free(RCAR_GP_PIN(5, 18));
+       return ret;
+}
+
+static int usbhs_hardware_exit(struct platform_device *pdev)
+{
+       struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+       if (!priv->phy)
+               return 0;
+
+       usb_put_phy(priv->phy);
+       priv->phy = NULL;
+
+       gpio_free(RCAR_GP_PIN(5, 18));
+       return 0;
+}
+
+static int usbhs_get_id(struct platform_device *pdev)
+{
+       return USBHS_GADGET;
+}
+
+static u32 lager_usbhs_pipe_type[] = {
+       USB_ENDPOINT_XFER_CONTROL,
+       USB_ENDPOINT_XFER_ISOC,
+       USB_ENDPOINT_XFER_ISOC,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_INT,
+       USB_ENDPOINT_XFER_INT,
+       USB_ENDPOINT_XFER_INT,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
+       USB_ENDPOINT_XFER_BULK,
 };
 
+static struct usbhs_private usbhs_priv __initdata = {
+       .info = {
+               .platform_callback = {
+                       .power_ctrl     = usbhs_power_ctrl,
+                       .hardware_init  = usbhs_hardware_init,
+                       .hardware_exit  = usbhs_hardware_exit,
+                       .get_id         = usbhs_get_id,
+               },
+               .driver_param = {
+                       .buswait_bwait  = 4,
+                       .pipe_type = lager_usbhs_pipe_type,
+                       .pipe_size = ARRAY_SIZE(lager_usbhs_pipe_type),
+               },
+       }
+};
+
+static void __init lager_register_usbhs(void)
+{
+       usb_bind_phy("renesas_usbhs", 0, "usb_phy_rcar_gen2");
+       platform_device_register_resndata(&platform_bus,
+                                         "renesas_usbhs", -1,
+                                         usbhs_resources,
+                                         ARRAY_SIZE(usbhs_resources),
+                                         &usbhs_priv.info,
+                                         sizeof(usbhs_priv.info));
+}
+
+/* USBHS PHY */
+static const struct rcar_gen2_phy_platform_data usbhs_phy_pdata __initconst = {
+       .chan0_pci = 0, /* Channel 0 is USBHS */
+       .chan2_pci = 1, /* Channel 2 is PCI USB */
+};
+
+static const struct resource usbhs_phy_resources[] __initconst = {
+       DEFINE_RES_MEM(0xe6590100, 0x100),
+};
+
+/* I2C */
+static struct i2c_board_info i2c2_devices[] = {
+       {
+               I2C_BOARD_INFO("ak4643", 0x12),
+       }
+};
+
+/* Sound */
+static struct resource rsnd_resources[] __initdata = {
+       [RSND_GEN2_SCU]  = DEFINE_RES_MEM(0xec500000, 0x1000),
+       [RSND_GEN2_ADG]  = DEFINE_RES_MEM(0xec5a0000, 0x100),
+       [RSND_GEN2_SSIU] = DEFINE_RES_MEM(0xec540000, 0x1000),
+       [RSND_GEN2_SSI]  = DEFINE_RES_MEM(0xec541000, 0x1280),
+};
+
+static struct rsnd_ssi_platform_info rsnd_ssi[] = {
+       RSND_SSI_SET(0, 0, gic_spi(370), RSND_SSI_PLAY),
+       RSND_SSI_SET(0, 0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE),
+};
+
+static struct rsnd_scu_platform_info rsnd_scu[2] = {
+       /* no member at this point */
+};
+
+static struct rcar_snd_info rsnd_info = {
+       .flags          = RSND_GEN2,
+       .ssi_info       = rsnd_ssi,
+       .ssi_info_nr    = ARRAY_SIZE(rsnd_ssi),
+       .scu_info       = rsnd_scu,
+       .scu_info_nr    = ARRAY_SIZE(rsnd_scu),
+};
+
+static struct asoc_simple_card_info rsnd_card_info = {
+       .name           = "AK4643",
+       .card           = "SSI01-AK4643",
+       .codec          = "ak4642-codec.2-0012",
+       .platform       = "rcar_sound",
+       .daifmt         = SND_SOC_DAIFMT_LEFT_J,
+       .cpu_dai = {
+               .name   = "rcar_sound",
+               .fmt    = SND_SOC_DAIFMT_CBS_CFS,
+       },
+       .codec_dai = {
+               .name   = "ak4642-hifi",
+               .fmt    = SND_SOC_DAIFMT_CBM_CFM,
+               .sysclk = 11289600,
+       },
+};
+
+static void __init lager_add_rsnd_device(void)
+{
+       struct platform_device_info cardinfo = {
+               .parent         = &platform_bus,
+               .name           = "asoc-simple-card",
+               .id             = -1,
+               .data           = &rsnd_card_info,
+               .size_data      = sizeof(struct asoc_simple_card_info),
+               .dma_mask       = DMA_BIT_MASK(32),
+       };
+
+       i2c_register_board_info(2, i2c2_devices,
+                               ARRAY_SIZE(i2c2_devices));
+
+       platform_device_register_resndata(
+               &platform_bus, "rcar_sound", -1,
+               rsnd_resources, ARRAY_SIZE(rsnd_resources),
+               &rsnd_info, sizeof(rsnd_info));
+
+       platform_device_register_full(&cardinfo);
+}
+
+/* SDHI0 */
+static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
+       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+                         MMC_CAP_POWER_OFF_CARD,
+       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT |
+                         TMIO_MMC_WRPROTECT_DISABLE,
+};
+
+static struct resource sdhi0_resources[] __initdata = {
+       DEFINE_RES_MEM(0xee100000, 0x200),
+       DEFINE_RES_IRQ(gic_spi(165)),
+};
+
+/* SDHI2 */
+static struct sh_mobile_sdhi_info sdhi2_info __initdata = {
+       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+                         MMC_CAP_POWER_OFF_CARD,
+       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT |
+                         TMIO_MMC_WRPROTECT_DISABLE,
+};
+
+static struct resource sdhi2_resources[] __initdata = {
+       DEFINE_RES_MEM(0xee140000, 0x100),
+       DEFINE_RES_IRQ(gic_spi(167)),
+};
+
+/* Internal PCI1 */
+static const struct resource pci1_resources[] __initconst = {
+       DEFINE_RES_MEM(0xee0b0000, 0x10000),    /* CFG */
+       DEFINE_RES_MEM(0xee0a0000, 0x10000),    /* MEM */
+       DEFINE_RES_IRQ(gic_spi(112)),
+};
+
+static const struct platform_device_info pci1_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "pci-rcar-gen2",
+       .id             = 1,
+       .res            = pci1_resources,
+       .num_res        = ARRAY_SIZE(pci1_resources),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
+static void __init lager_add_usb1_device(void)
+{
+       platform_device_register_full(&pci1_info);
+}
+
+/* Internal PCI2 */
+static const struct resource pci2_resources[] __initconst = {
+       DEFINE_RES_MEM(0xee0d0000, 0x10000),    /* CFG */
+       DEFINE_RES_MEM(0xee0c0000, 0x10000),    /* MEM */
+       DEFINE_RES_IRQ(gic_spi(113)),
+};
+
+static const struct platform_device_info pci2_info __initconst = {
+       .parent         = &platform_bus,
+       .name           = "pci-rcar-gen2",
+       .id             = 2,
+       .res            = pci2_resources,
+       .num_res        = ARRAY_SIZE(pci2_resources),
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
+static void __init lager_add_usb2_device(void)
+{
+       platform_device_register_full(&pci2_info);
+}
+
 static const struct pinctrl_map lager_pinctrl_map[] = {
        /* DU (CN10: ARGB0, CN13: LVDS) */
        PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
@@ -299,12 +700,43 @@ static const struct pinctrl_map lager_pinctrl_map[] = {
                                  "du_sync_1", "du"),
        PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
                                  "du_clk_out_0", "du"),
+       /* I2C2 */
+       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar.2", "pfc-r8a7790",
+                                 "i2c2", "i2c2"),
+       /* QSPI */
+       PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790",
+                                 "qspi_ctrl", "qspi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790",
+                                 "qspi_data4", "qspi"),
        /* SCIF0 (CN19: DEBUG SERIAL0) */
        PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790",
                                  "scif0_data", "scif0"),
        /* SCIF1 (CN20: DEBUG SERIAL1) */
        PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7790",
                                  "scif1_data", "scif1"),
+       /* SDHI0 */
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
+                                 "sdhi0_data4", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
+                                 "sdhi0_ctrl", "sdhi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
+                                 "sdhi0_cd", "sdhi0"),
+       /* SDHI2 */
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
+                                 "sdhi2_data4", "sdhi2"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
+                                 "sdhi2_ctrl", "sdhi2"),
+       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
+                                 "sdhi2_cd", "sdhi2"),
+       /* SSI (CN17: sound) */
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
+                                 "ssi0129_ctrl", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
+                                 "ssi0_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
+                                 "ssi1_data", "ssi"),
+       PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
+                                 "audio_clk_a", "audio_clk"),
        /* MMCIF1 */
        PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790",
                                  "mmc1_data8", "mmc1"),
@@ -319,6 +751,31 @@ static const struct pinctrl_map lager_pinctrl_map[] = {
                                  "eth_rmii", "eth"),
        PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
                                  "intc_irq0", "intc"),
+       /* VIN0 */
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
+                                 "vin0_data24", "vin0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
+                                 "vin0_sync", "vin0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
+                                 "vin0_field", "vin0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
+                                 "vin0_clkenb", "vin0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
+                                 "vin0_clk", "vin0"),
+       /* VIN1 */
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790",
+                                 "vin1_data8", "vin1"),
+       PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790",
+                                 "vin1_clk", "vin1"),
+       /* USB0 */
+       PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7790",
+                                 "usb0_ovc_vbus", "usb0"),
+       /* USB1 */
+       PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.1", "pfc-r8a7790",
+                                 "usb1", "usb1"),
+       /* USB2 */
+       PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.2", "pfc-r8a7790",
+                                 "usb2", "usb2"),
 };
 
 static void __init lager_add_standard_devices(void)
@@ -346,10 +803,7 @@ static void __init lager_add_standard_devices(void)
                                          mmcif1_resources, ARRAY_SIZE(mmcif1_resources),
                                          &mmcif1_pdata, sizeof(mmcif1_pdata));
 
-       platform_device_register_resndata(&platform_bus, "r8a7790-ether", -1,
-                                         ether_resources,
-                                         ARRAY_SIZE(ether_resources),
-                                         &ether_pdata, sizeof(ether_pdata));
+       platform_device_register_full(&ether_info);
 
        lager_add_du_device();
 
@@ -368,6 +822,28 @@ static void __init lager_add_standard_devices(void)
                                      &vccq_sdhi0_info, sizeof(struct gpio_regulator_config));
        platform_device_register_data(&platform_bus, "gpio-regulator", gpio_regulator_idx++,
                                      &vccq_sdhi2_info, sizeof(struct gpio_regulator_config));
+
+       lager_add_camera1_device();
+
+       platform_device_register_full(&sata1_info);
+
+       platform_device_register_resndata(&platform_bus, "usb_phy_rcar_gen2",
+                                         -1, usbhs_phy_resources,
+                                         ARRAY_SIZE(usbhs_phy_resources),
+                                         &usbhs_phy_pdata,
+                                         sizeof(usbhs_phy_pdata));
+       lager_register_usbhs();
+       lager_add_usb1_device();
+       lager_add_usb2_device();
+
+       lager_add_rsnd_device();
+
+       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0,
+                                         sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
+                                         &sdhi0_info, sizeof(struct sh_mobile_sdhi_info));
+       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 2,
+                                         sdhi2_resources, ARRAY_SIZE(sdhi2_resources),
+                                         &sdhi2_info, sizeof(struct sh_mobile_sdhi_info));
 }
 
 /*
@@ -391,6 +867,8 @@ static void __init lager_init(void)
 {
        lager_add_standard_devices();
 
+       irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
+
        if (IS_ENABLED(CONFIG_PHYLIB))
                phy_register_fixup_for_id("r8a7790-ether-ff:01",
                                          lager_ksz8041_fixup);
index e6ab0cd5b28628dbd65a5c3f7dfa1cc57428f090..bee0073c9b64f641560c41bf740cde5ce76a7488 100644 (file)
 #include <mach/common.h>
 #include <mach/r7s72100.h>
 
-/* registers */
+/* Frequency Control Registers */
 #define FRQCR          0xfcfe0010
 #define FRQCR2         0xfcfe0014
+/* Standby Control Registers */
 #define STBCR3         0xfcfe0420
 #define STBCR4         0xfcfe0424
+#define STBCR7         0xfcfe0430
 #define STBCR9         0xfcfe0438
+#define STBCR10                0xfcfe043c
 
 #define PLL_RATE 30
 
@@ -67,7 +70,7 @@ static struct clk pll_clk = {
 
 static unsigned long bus_recalc(struct clk *clk)
 {
-       return clk->parent->rate * 2 / 3;
+       return clk->parent->rate / 3;
 }
 
 static struct sh_clk_ops bus_clk_ops = {
@@ -145,15 +148,25 @@ struct clk div4_clks[DIV4_NR] = {
                                        | CLK_ENABLE_ON_INIT),
 };
 
-enum { MSTP97, MSTP96, MSTP95, MSTP94,
+enum {
+       MSTP107, MSTP106, MSTP105, MSTP104, MSTP103,
+       MSTP97, MSTP96, MSTP95, MSTP94,
+       MSTP74,
        MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40,
-       MSTP33, MSTP_NR };
+       MSTP33, MSTP_NR
+};
 
 static struct clk mstp_clks[MSTP_NR] = {
+       [MSTP107] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 7, 0), /* RSPI0 */
+       [MSTP106] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 6, 0), /* RSPI1 */
+       [MSTP105] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 5, 0), /* RSPI2 */
+       [MSTP104] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 4, 0), /* RSPI3 */
+       [MSTP103] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 3, 0), /* RSPI4 */
        [MSTP97] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 7, 0), /* RIIC0 */
        [MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */
        [MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */
        [MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */
+       [MSTP74] = SH_CLK_MSTP8(&peripheral1_clk, STBCR7, 4, 0), /* Ether */
        [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */
        [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */
        [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */
@@ -176,6 +189,21 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
 
        /* MSTP clocks */
+       CLKDEV_DEV_ID("rspi-rz.0", &mstp_clks[MSTP107]),
+       CLKDEV_DEV_ID("rspi-rz.1", &mstp_clks[MSTP106]),
+       CLKDEV_DEV_ID("rspi-rz.2", &mstp_clks[MSTP105]),
+       CLKDEV_DEV_ID("rspi-rz.3", &mstp_clks[MSTP104]),
+       CLKDEV_DEV_ID("rspi-rz.4", &mstp_clks[MSTP103]),
+       CLKDEV_DEV_ID("e800c800.spi", &mstp_clks[MSTP107]),
+       CLKDEV_DEV_ID("e800d000.spi", &mstp_clks[MSTP106]),
+       CLKDEV_DEV_ID("e800d800.spi", &mstp_clks[MSTP105]),
+       CLKDEV_DEV_ID("e800e000.spi", &mstp_clks[MSTP104]),
+       CLKDEV_DEV_ID("e800e800.spi", &mstp_clks[MSTP103]),
+       CLKDEV_DEV_ID("fcfee000.i2c", &mstp_clks[MSTP97]),
+       CLKDEV_DEV_ID("fcfee400.i2c", &mstp_clks[MSTP96]),
+       CLKDEV_DEV_ID("fcfee800.i2c", &mstp_clks[MSTP95]),
+       CLKDEV_DEV_ID("fcfeec00.i2c", &mstp_clks[MSTP94]),
+       CLKDEV_DEV_ID("r7s72100-ether", &mstp_clks[MSTP74]),
        CLKDEV_CON_ID("mtu2_fck", &mstp_clks[MSTP33]),
 
        /* ICK */
index 9783945f8bc7972e9f13123c16335c3cbebefb9e..2009a9bc63562af9d761c47f433a4b3d6a80f25d 100644 (file)
@@ -221,6 +221,10 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
        CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */
 
+       CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
+       CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
+       CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
+       CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk),
        CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]),
        CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]),
        CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]),
index f1fb89b76786a690037b154d907c9668707f192b..8e403ae0c7b24f2950fe768871befbcbd858b7cf 100644 (file)
 
 #define MD(nr) BIT(nr)
 
-#define FRQMR          IOMEM(0xffc80014)
 #define MSTPCR0                IOMEM(0xffc80030)
 #define MSTPCR1                IOMEM(0xffc80034)
 #define MSTPCR3                IOMEM(0xffc8003c)
 #define MSTPSR1                IOMEM(0xffc80044)
-#define MSTPSR4                IOMEM(0xffc80048)
-#define MSTPSR6                IOMEM(0xffc8004c)
-#define MSTPCR4                IOMEM(0xffc80050)
-#define MSTPCR5                IOMEM(0xffc80054)
-#define MSTPCR6                IOMEM(0xffc80058)
-#define MSTPCR7                IOMEM(0xffc80040)
 
 #define MODEMR         0xffcc0020
 
@@ -127,16 +120,16 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
        [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
        [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
-       [MSTP120] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 20, 0), /* VIN3 */
-       [MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */
-       [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
-       [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
-       [MSTP110] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 10, 0), /* VIN0 */
-       [MSTP109] = SH_CLK_MSTP32(&clks_clk, MSTPCR1,  9, 0), /* VIN1 */
-       [MSTP108] = SH_CLK_MSTP32(&clks_clk, MSTPCR1,  8, 0), /* VIN2 */
-       [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1,  3, 0), /* DU */
-       [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1,  1, 0), /* USB2 */
-       [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1,  0, 0), /* USB0/1 */
+       [MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */
+       [MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */
+       [MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */
+       [MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */
+       [MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */
+       [MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  9, MSTPSR1, 0), /* VIN1 */
+       [MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  8, MSTPSR1, 0), /* VIN2 */
+       [MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  3, MSTPSR1, 0), /* DU */
+       [MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  1, MSTPSR1, 0), /* USB2 */
+       [MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  0, MSTPSR1, 0), /* USB0/1 */
        [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
        [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
        [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
index f44987a92ad420d27fb3dab5638a1a1f6a32942a..3f93503f5b96f123fc2441abcd37eccc09972dc4 100644 (file)
  *     see "p1 / 2" on R8A7790_CLOCK_ROOT() below
  */
 
-#define CPG_BASE 0xe6150000
-#define CPG_LEN 0x1000
-
-#define SMSTPCR1 0xe6150134
-#define SMSTPCR2 0xe6150138
-#define SMSTPCR3 0xe615013c
-#define SMSTPCR5 0xe6150144
-#define SMSTPCR7 0xe615014c
-#define SMSTPCR8 0xe6150990
-#define SMSTPCR9 0xe6150994
-#define SMSTPCR10 0xe6150998
+#define CPG_BASE       0xe6150000
+#define CPG_LEN                0x1000
+
+#define SMSTPCR1       0xe6150134
+#define SMSTPCR2       0xe6150138
+#define SMSTPCR3       0xe615013c
+#define SMSTPCR5       0xe6150144
+#define SMSTPCR7       0xe615014c
+#define SMSTPCR8       0xe6150990
+#define SMSTPCR9       0xe6150994
+#define SMSTPCR10      0xe6150998
+
+#define MSTPSR1                IOMEM(0xe6150038)
+#define MSTPSR2                IOMEM(0xe6150040)
+#define MSTPSR3                IOMEM(0xe6150048)
+#define MSTPSR5                IOMEM(0xe615003c)
+#define MSTPSR7                IOMEM(0xe61501c4)
+#define MSTPSR8                IOMEM(0xe61509a0)
+#define MSTPSR9                IOMEM(0xe61509a4)
+#define MSTPSR10       IOMEM(0xe61509a8)
 
 #define SDCKCR         0xE6150074
 #define SD2CKCR                0xE6150078
@@ -82,6 +91,15 @@ static struct clk main_clk = {
        .ops    = &followparent_clk_ops,
 };
 
+static struct clk audio_clk_a = {
+};
+
+static struct clk audio_clk_b = {
+};
+
+static struct clk audio_clk_c = {
+};
+
 /*
  * clock ratio of these clock will be updated
  * on r8a7790_clock_init()
@@ -115,6 +133,9 @@ SH_FIXED_RATIO_CLK_SET(ddr_clk,                     pll3_clk,       1, 8);
 SH_FIXED_RATIO_CLK_SET(mp_clk,                 pll1_div2_clk,  1, 15);
 
 static struct clk *main_clks[] = {
+       &audio_clk_a,
+       &audio_clk_b,
+       &audio_clk_c,
        &extal_clk,
        &extal_div2_clk,
        &main_clk,
@@ -183,15 +204,22 @@ static struct clk div6_clks[DIV6_NR] = {
 
 /* MSTP */
 enum {
+       MSTP1017, /* parent of SCU */
+
+       MSTP1031, MSTP1030,
+       MSTP1029, MSTP1028, MSTP1027, MSTP1026, MSTP1025, MSTP1024, MSTP1023, MSTP1022,
        MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010,
        MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005,
        MSTP931, MSTP930, MSTP929, MSTP928,
        MSTP917,
+       MSTP815, MSTP814,
        MSTP813,
+       MSTP811, MSTP810, MSTP809, MSTP808,
        MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
        MSTP717, MSTP716,
-       MSTP704,
+       MSTP704, MSTP703,
        MSTP522,
+       MSTP502, MSTP501,
        MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
        MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
        MSTP124,
@@ -199,53 +227,77 @@ enum {
 };
 
 static struct clk mstp_clks[MSTP_NR] = {
-       [MSTP1015] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 15, 0), /* SSI0 */
-       [MSTP1014] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 14, 0), /* SSI1 */
-       [MSTP1013] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 13, 0), /* SSI2 */
-       [MSTP1012] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 12, 0), /* SSI3 */
-       [MSTP1011] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 11, 0), /* SSI4 */
-       [MSTP1010] = SH_CLK_MSTP32(&p_clk, SMSTPCR10, 10, 0), /* SSI5 */
-       [MSTP1009] = SH_CLK_MSTP32(&p_clk, SMSTPCR10,  9, 0), /* SSI6 */
-       [MSTP1008] = SH_CLK_MSTP32(&p_clk, SMSTPCR10,  8, 0), /* SSI7 */
-       [MSTP1007] = SH_CLK_MSTP32(&p_clk, SMSTPCR10,  7, 0), /* SSI8 */
-       [MSTP1006] = SH_CLK_MSTP32(&p_clk, SMSTPCR10,  6, 0), /* SSI9 */
-       [MSTP1005] = SH_CLK_MSTP32(&p_clk, SMSTPCR10,  5, 0), /* SSI ALL */
-       [MSTP931] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 31, 0), /* I2C0 */
-       [MSTP930] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 30, 0), /* I2C1 */
-       [MSTP929] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 29, 0), /* I2C2 */
-       [MSTP928] = SH_CLK_MSTP32(&p_clk, SMSTPCR9, 28, 0), /* I2C3 */
-       [MSTP917] = SH_CLK_MSTP32(&qspi_clk, SMSTPCR9, 17, 0), /* QSPI */
-       [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
-       [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
-       [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */
-       [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
-       [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
-       [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */
-       [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
-       [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
-       [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
-       [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
-       [MSTP704] = SH_CLK_MSTP32(&mp_clk, SMSTPCR7, 4, 0), /* HSUSB */
-       [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
-       [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */
-       [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */
-       [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */
-       [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SD2], SMSTPCR3, 12, 0), /* SDHI2 */
-       [MSTP311] = SH_CLK_MSTP32(&div6_clks[DIV6_SD3], SMSTPCR3, 11, 0), /* SDHI3 */
-       [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, 0), /* MMC1 */
-       [MSTP304] = SH_CLK_MSTP32(&cp_clk, SMSTPCR3, 4, 0), /* TPU0 */
-       [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
-       [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
-       [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
-       [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
-       [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
-       [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
-       [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */
+       [MSTP1031] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 31, MSTPSR10, 0), /* SCU0 */
+       [MSTP1030] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 30, MSTPSR10, 0), /* SCU1 */
+       [MSTP1029] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 29, MSTPSR10, 0), /* SCU2 */
+       [MSTP1028] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 28, MSTPSR10, 0), /* SCU3 */
+       [MSTP1027] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 27, MSTPSR10, 0), /* SCU4 */
+       [MSTP1026] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 26, MSTPSR10, 0), /* SCU5 */
+       [MSTP1025] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 25, MSTPSR10, 0), /* SCU6 */
+       [MSTP1024] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 24, MSTPSR10, 0), /* SCU7 */
+       [MSTP1023] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 23, MSTPSR10, 0), /* SCU8 */
+       [MSTP1022] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 22, MSTPSR10, 0), /* SCU9 */
+       [MSTP1017] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 17, MSTPSR10, 0), /* SCU */
+       [MSTP1015] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 15, MSTPSR10, 0), /* SSI0 */
+       [MSTP1014] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 14, MSTPSR10, 0), /* SSI1 */
+       [MSTP1013] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 13, MSTPSR10, 0), /* SSI2 */
+       [MSTP1012] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 12, MSTPSR10, 0), /* SSI3 */
+       [MSTP1011] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 11, MSTPSR10, 0), /* SSI4 */
+       [MSTP1010] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 10, MSTPSR10, 0), /* SSI5 */
+       [MSTP1009] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 9, MSTPSR10, 0), /* SSI6 */
+       [MSTP1008] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 8, MSTPSR10, 0), /* SSI7 */
+       [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */
+       [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */
+       [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */
+       [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
+       [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
+       [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
+       [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
+       [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
+       [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
+       [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
+       [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
+       [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
+       [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
+       [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8,  9, MSTPSR8, 0), /* VIN2 */
+       [MSTP808] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8,  8, MSTPSR8, 0), /* VIN3 */
+       [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
+       [MSTP725] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 25, MSTPSR7, 0), /* LVDS1 */
+       [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
+       [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
+       [MSTP722] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 22, MSTPSR7, 0), /* DU2 */
+       [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
+       [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
+       [MSTP717] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 17, MSTPSR7, 0), /* HSCIF0 */
+       [MSTP716] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 16, MSTPSR7, 0), /* HSCIF1 */
+       [MSTP704] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 4, MSTPSR7, 0), /* HSUSB */
+       [MSTP703] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 3, MSTPSR7, 0), /* EHCI */
+       [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
+       [MSTP502] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 2, MSTPSR5, 0), /* Audio-DMAC low */
+       [MSTP501] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 1, MSTPSR5, 0), /* Audio-DMAC hi */
+       [MSTP315] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, MSTPSR3, 0), /* MMC0 */
+       [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
+       [MSTP313] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD1], SMSTPCR3, 13, MSTPSR3, 0), /* SDHI1 */
+       [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI2 */
+       [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD3], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI3 */
+       [MSTP305] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, MSTPSR3, 0), /* MMC1 */
+       [MSTP304] = SH_CLK_MSTP32_STS(&cp_clk, SMSTPCR3, 4, MSTPSR3, 0), /* TPU0 */
+       [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
+       [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
+       [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
+       [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
+       [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
+       [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
+       [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
 };
 
 static struct clk_lookup lookups[] = {
 
        /* main clocks */
+       CLKDEV_CON_ID("audio_clk_a",    &audio_clk_a),
+       CLKDEV_CON_ID("audio_clk_b",    &audio_clk_b),
+       CLKDEV_CON_ID("audio_clk_c",    &audio_clk_c),
+       CLKDEV_CON_ID("audio_clk_internal",     &m2_clk),
        CLKDEV_CON_ID("extal",          &extal_clk),
        CLKDEV_CON_ID("extal_div2",     &extal_div2_clk),
        CLKDEV_CON_ID("main",           &main_clk),
@@ -291,32 +343,32 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
        CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
        CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
-       CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]),
        CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
-       CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]),
        CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
-       CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]),
        CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
-       CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]),
        CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
        CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
-       CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
+       CLKDEV_DEV_ID("r8a7790-vin.0", &mstp_clks[MSTP811]),
+       CLKDEV_DEV_ID("r8a7790-vin.1", &mstp_clks[MSTP810]),
+       CLKDEV_DEV_ID("r8a7790-vin.2", &mstp_clks[MSTP809]),
+       CLKDEV_DEV_ID("r8a7790-vin.3", &mstp_clks[MSTP808]),
        CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
-       CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]),
+       CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP502]),
+       CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP501]),
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
-       CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
-       CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
-       CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
-       CLKDEV_DEV_ID("ee160000.sd", &mstp_clks[MSTP311]),
        CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
-       CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]),
        CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
        CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
        CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
        CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
+       CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]),
+       CLKDEV_DEV_ID("pci-rcar-gen2.1", &mstp_clks[MSTP703]),
+       CLKDEV_DEV_ID("pci-rcar-gen2.2", &mstp_clks[MSTP703]),
+       CLKDEV_DEV_ID("sata-r8a7790.0", &mstp_clks[MSTP815]),
+       CLKDEV_DEV_ID("sata-r8a7790.1", &mstp_clks[MSTP814]),
 
        /* ICK */
        CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]),
@@ -325,6 +377,20 @@ static struct clk_lookup lookups[] = {
        CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
        CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
        CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
+       CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
+       CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
+       CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
+       CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk),
+       CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP1031]),
+       CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP1030]),
+       CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP1029]),
+       CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP1028]),
+       CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP1027]),
+       CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP1026]),
+       CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP1025]),
+       CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP1024]),
+       CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP1023]),
+       CLKDEV_ICK_ID("scu.9", "rcar_sound", &mstp_clks[MSTP1022]),
        CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]),
        CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]),
        CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]),
index f5461262ee25ab1c04b5074a9055c686df363b94..701383fe32674141434f08767d375e05e00e8174 100644 (file)
 #define SMSTPCR10      0xE6150998
 #define SMSTPCR11      0xE615099C
 
+#define MSTPSR1                IOMEM(0xe6150038)
+#define MSTPSR2                IOMEM(0xe6150040)
+#define MSTPSR3                IOMEM(0xe6150048)
+#define MSTPSR5                IOMEM(0xe615003c)
+#define MSTPSR7                IOMEM(0xe61501c4)
+#define MSTPSR8                IOMEM(0xe61509a0)
+#define MSTPSR9                IOMEM(0xe61509a4)
+#define MSTPSR11       IOMEM(0xe61509ac)
+
 #define MODEMR         0xE6160060
 #define SDCKCR         0xE6150074
-#define SD2CKCR                0xE6150078
-#define SD3CKCR                0xE615007C
+#define SD1CKCR                0xE6150078
+#define SD2CKCR                0xE615026c
 #define MMC0CKCR       0xE6150240
 #define MMC1CKCR       0xE6150244
 #define SSPCKCR                0xE6150248
@@ -93,6 +102,7 @@ static struct clk main_clk = {
  */
 SH_FIXED_RATIO_CLK_SET(pll1_clk,               main_clk,       1, 1);
 SH_FIXED_RATIO_CLK_SET(pll3_clk,               main_clk,       1, 1);
+SH_FIXED_RATIO_CLK_SET(qspi_clk,               pll1_clk,       1, 1);
 
 /* fixed ratio clock */
 SH_FIXED_RATIO_CLK_SET(extal_div2_clk,         extal_clk,      1, 2);
@@ -103,7 +113,9 @@ SH_FIXED_RATIO_CLK_SET(hp_clk,                      pll1_clk,       1, 12);
 SH_FIXED_RATIO_CLK_SET(p_clk,                  pll1_clk,       1, 24);
 SH_FIXED_RATIO_CLK_SET(rclk_clk,               pll1_clk,       1, (48 * 1024));
 SH_FIXED_RATIO_CLK_SET(mp_clk,                 pll1_div2_clk,  1, 15);
+SH_FIXED_RATIO_CLK_SET(zg_clk,                 pll1_clk,       1, 3);
 SH_FIXED_RATIO_CLK_SET(zx_clk,                 pll1_clk,       1, 3);
+SH_FIXED_RATIO_CLK_SET(zs_clk,                 pll1_clk,       1, 6);
 
 static struct clk *main_clks[] = {
        &extal_clk,
@@ -114,46 +126,103 @@ static struct clk *main_clks[] = {
        &pll3_clk,
        &hp_clk,
        &p_clk,
+       &qspi_clk,
        &rclk_clk,
        &mp_clk,
        &cp_clk,
+       &zg_clk,
        &zx_clk,
+       &zs_clk,
+};
+
+/* SDHI (DIV4) clock */
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+       .divisors = divisors,
+       .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+       .div_mult_table = &div4_div_mult_table,
+};
+
+enum {
+       DIV4_SDH, DIV4_SD0,
+       DIV4_NR
+};
+
+static struct clk div4_clks[DIV4_NR] = {
+       [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
+       [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT),
+};
+
+/* DIV6 clocks */
+enum {
+       DIV6_SD1, DIV6_SD2,
+       DIV6_NR
+};
+
+static struct clk div6_clks[DIV6_NR] = {
+       [DIV6_SD1]      = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
+       [DIV6_SD2]      = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
 };
 
 /* MSTP */
 enum {
+       MSTP1108, MSTP1107, MSTP1106,
+       MSTP931, MSTP930, MSTP929, MSTP928, MSTP927, MSTP925,
+       MSTP917,
+       MSTP815, MSTP814,
        MSTP813,
+       MSTP811, MSTP810, MSTP809,
        MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
        MSTP719, MSTP718, MSTP715, MSTP714,
        MSTP522,
+       MSTP314, MSTP312, MSTP311,
        MSTP216, MSTP207, MSTP206,
-       MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107,
+       MSTP204, MSTP203, MSTP202,
        MSTP124,
        MSTP_NR
 };
 
 static struct clk mstp_clks[MSTP_NR] = {
-       [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */
-       [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */
-       [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */
-       [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */
-       [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
-       [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
-       [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */
-       [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */
-       [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */
-       [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */
-       [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */
-       [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
-       [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
-       [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
-       [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
-       [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
-       [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
-       [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */
-       [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */
-       [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */
-       [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */
+       [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */
+       [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */
+       [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */
+       [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
+       [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
+       [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
+       [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
+       [MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */
+       [MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */
+       [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
+       [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
+       [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
+       [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
+       [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
+       [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
+       [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */
+       [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
+       [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
+       [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
+       [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
+       [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
+       [MSTP719] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 19, MSTPSR7, 0), /* SCIF2 */
+       [MSTP718] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 18, MSTPSR7, 0), /* SCIF3 */
+       [MSTP715] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 15, MSTPSR7, 0), /* SCIF4 */
+       [MSTP714] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 14, MSTPSR7, 0), /* SCIF5 */
+       [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
+       [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
+       [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD1], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI1 */
+       [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI2 */
+       [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
+       [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
+       [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
+       [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
+       [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
+       [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
+       [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
 };
 
 static struct clk_lookup lookups[] = {
@@ -165,8 +234,11 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("pll1",           &pll1_clk),
        CLKDEV_CON_ID("pll1_div2",      &pll1_div2_clk),
        CLKDEV_CON_ID("pll3",           &pll3_clk),
+       CLKDEV_CON_ID("zg",             &zg_clk),
+       CLKDEV_CON_ID("zs",             &zs_clk),
        CLKDEV_CON_ID("hp",             &hp_clk),
        CLKDEV_CON_ID("p",              &p_clk),
+       CLKDEV_CON_ID("qspi",           &qspi_clk),
        CLKDEV_CON_ID("rclk",           &rclk_clk),
        CLKDEV_CON_ID("mp",             &mp_clk),
        CLKDEV_CON_ID("cp",             &cp_clk),
@@ -188,13 +260,27 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */
        CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */
        CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */
-       CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */
-       CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */
-       CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */
+       CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1106]), /* SCIFA3 */
+       CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1107]), /* SCIFA4 */
+       CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1108]), /* SCIFA5 */
+       CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+       CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP312]),
+       CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]),
        CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]),
-       CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
+       CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
        CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
+       CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
+       CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
+       CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
+       CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
+       CLKDEV_DEV_ID("i2c-rcar_gen2.4", &mstp_clks[MSTP927]),
+       CLKDEV_DEV_ID("i2c-rcar_gen2.5", &mstp_clks[MSTP925]),
        CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */
+       CLKDEV_DEV_ID("r8a7791-vin.0", &mstp_clks[MSTP811]),
+       CLKDEV_DEV_ID("r8a7791-vin.1", &mstp_clks[MSTP810]),
+       CLKDEV_DEV_ID("r8a7791-vin.2", &mstp_clks[MSTP809]),
+       CLKDEV_DEV_ID("sata-r8a7791.0", &mstp_clks[MSTP815]),
+       CLKDEV_DEV_ID("sata-r8a7791.1", &mstp_clks[MSTP814]),
 };
 
 #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31)             \
@@ -232,9 +318,20 @@ void __init r8a7791_clock_init(void)
                break;
        }
 
+       if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
+               SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
+       else
+               SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
+
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
                ret = clk_register(main_clks[k]);
 
+       if (!ret)
+               ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+       if (!ret)
+               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
        if (!ret)
                ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 
index e31980590eb452bbc209400d303e9d6d016181d7..cb8e32deb2a3c6cadf7efba9f6cb478daa92c241 100644 (file)
@@ -25,7 +25,6 @@ extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
                                            struct task_struct *idle);
 extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
 extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
-extern void shmobile_invalidate_start(void);
 struct clk;
 extern int shmobile_clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
diff --git a/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt b/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt
new file mode 100644 (file)
index 0000000..9531f46
--- /dev/null
@@ -0,0 +1,410 @@
+LIST "KZM9G low-level initialization routine."
+LIST "Adapted from u-boot KZM9G support code."
+
+LIST "Copyright (C) 2013 Ulrich Hecht"
+
+LIST "This program is free software; you can redistribute it and/or modify"
+LIST "it under the terms of the GNU General Public License version 2 as"
+LIST "published by the Free Software Foundation."
+
+LIST "This program is distributed in the hope that it will be useful,"
+LIST "but WITHOUT ANY WARRANTY; without even the implied warranty of"
+LIST "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"
+LIST "GNU General Public License for more details."
+
+
+LIST "Register definitions:"
+
+LIST "Secure control register"
+#define LIFEC_SEC_SRC (0xE6110008)
+
+LIST "RWDT"
+#define RWDT_BASE   (0xE6020000)
+#define RWTCSRA0 (RWDT_BASE + 0x04)
+
+LIST "HPB Semaphore Control Registers"
+#define HPBSCR_BASE (0xE6000000)
+#define HPBCTRL6 (HPBSCR_BASE + 0x1030)
+
+#define SBSC1_BASE  (0xFE400000)
+#define SDCR0A         (SBSC1_BASE + 0x0008)
+#define SDCR1A         (SBSC1_BASE + 0x000C)
+#define SDPCRA         (SBSC1_BASE + 0x0010)
+#define SDCR0SA                (SBSC1_BASE + 0x0018)
+#define SDCR1SA                (SBSC1_BASE + 0x001C)
+#define RTCSRA         (SBSC1_BASE + 0x0020)
+#define RTCORA         (SBSC1_BASE + 0x0028)
+#define RTCORHA                (SBSC1_BASE + 0x002C)
+#define SDWCRC0A       (SBSC1_BASE + 0x0040)
+#define SDWCRC1A       (SBSC1_BASE + 0x0044)
+#define SDWCR00A       (SBSC1_BASE + 0x0048)
+#define SDWCR01A       (SBSC1_BASE + 0x004C)
+#define SDWCR10A       (SBSC1_BASE + 0x0050)
+#define SDWCR11A       (SBSC1_BASE + 0x0054)
+#define SDWCR2A                (SBSC1_BASE + 0x0060)
+#define SDWCRC2A       (SBSC1_BASE + 0x0064)
+#define ZQCCRA         (SBSC1_BASE + 0x0068)
+#define SDMRACR0A      (SBSC1_BASE + 0x0084)
+#define SDMRTMPCRA     (SBSC1_BASE + 0x008C)
+#define SDMRTMPMSKA    (SBSC1_BASE + 0x0094)
+#define SDGENCNTA      (SBSC1_BASE + 0x009C)
+#define SDDRVCR0A      (SBSC1_BASE + 0x00B4)
+#define DLLCNT0A       (SBSC1_BASE + 0x0354)
+
+#define SDMRA1  (0xFE500000)
+#define SDMRA2  (0xFE5C0000)
+#define SDMRA3  (0xFE504000)
+
+#define SBSC2_BASE  (0xFB400000)
+#define SDCR0B         (SBSC2_BASE + 0x0008)
+#define SDCR1B         (SBSC2_BASE + 0x000C)
+#define SDPCRB         (SBSC2_BASE + 0x0010)
+#define SDCR0SB                (SBSC2_BASE + 0x0018)
+#define SDCR1SB                (SBSC2_BASE + 0x001C)
+#define RTCSRB         (SBSC2_BASE + 0x0020)
+#define RTCORB         (SBSC2_BASE + 0x0028)
+#define RTCORHB                (SBSC2_BASE + 0x002C)
+#define SDWCRC0B       (SBSC2_BASE + 0x0040)
+#define SDWCRC1B       (SBSC2_BASE + 0x0044)
+#define SDWCR00B       (SBSC2_BASE + 0x0048)
+#define SDWCR01B       (SBSC2_BASE + 0x004C)
+#define SDWCR10B       (SBSC2_BASE + 0x0050)
+#define SDWCR11B       (SBSC2_BASE + 0x0054)
+#define SDPDCR0B       (SBSC2_BASE + 0x0058)
+#define SDWCR2B                (SBSC2_BASE + 0x0060)
+#define SDWCRC2B       (SBSC2_BASE + 0x0064)
+#define ZQCCRB         (SBSC2_BASE + 0x0068)
+#define SDMRACR0B      (SBSC2_BASE + 0x0084)
+#define SDMRTMPCRB     (SBSC2_BASE + 0x008C)
+#define SDMRTMPMSKB    (SBSC2_BASE + 0x0094)
+#define SDGENCNTB      (SBSC2_BASE + 0x009C)
+#define DPHYCNT0B      (SBSC2_BASE + 0x00A0)
+#define DPHYCNT1B      (SBSC2_BASE + 0x00A4)
+#define DPHYCNT2B      (SBSC2_BASE + 0x00A8)
+#define SDDRVCR0B      (SBSC2_BASE + 0x00B4)
+#define DLLCNT0B       (SBSC2_BASE + 0x0354)
+
+#define SDMRB1  (0xFB500000)
+#define SDMRB2  (0xFB5C0000)
+#define SDMRB3  (0xFB504000)
+
+#define CPG_BASE   (0xE6150000)
+#define FRQCRA         (CPG_BASE + 0x0000)
+#define FRQCRB         (CPG_BASE + 0x0004)
+#define FRQCRD         (CPG_BASE + 0x00E4)
+#define VCLKCR1                (CPG_BASE + 0x0008)
+#define VCLKCR2                (CPG_BASE + 0x000C)
+#define VCLKCR3                (CPG_BASE + 0x001C)
+#define ZBCKCR         (CPG_BASE + 0x0010)
+#define FLCKCR         (CPG_BASE + 0x0014)
+#define SD0CKCR                (CPG_BASE + 0x0074)
+#define SD1CKCR                (CPG_BASE + 0x0078)
+#define SD2CKCR                (CPG_BASE + 0x007C)
+#define FSIACKCR       (CPG_BASE + 0x0018)
+#define SUBCKCR                (CPG_BASE + 0x0080)
+#define SPUACKCR       (CPG_BASE + 0x0084)
+#define SPUVCKCR       (CPG_BASE + 0x0094)
+#define MSUCKCR                (CPG_BASE + 0x0088)
+#define HSICKCR                (CPG_BASE + 0x008C)
+#define FSIBCKCR       (CPG_BASE + 0x0090)
+#define MFCK1CR                (CPG_BASE + 0x0098)
+#define MFCK2CR                (CPG_BASE + 0x009C)
+#define DSITCKCR       (CPG_BASE + 0x0060)
+#define DSI0PCKCR      (CPG_BASE + 0x0064)
+#define DSI1PCKCR      (CPG_BASE + 0x0068)
+#define DSI0PHYCR      (CPG_BASE + 0x006C)
+#define DVFSCR3                (CPG_BASE + 0x0174)
+#define DVFSCR4                (CPG_BASE + 0x0178)
+#define DVFSCR5                (CPG_BASE + 0x017C)
+#define MPMODE         (CPG_BASE + 0x00CC)
+
+#define PLLECR         (CPG_BASE + 0x00D0)
+#define PLL0CR         (CPG_BASE + 0x00D8)
+#define PLL1CR         (CPG_BASE + 0x0028)
+#define PLL2CR         (CPG_BASE + 0x002C)
+#define PLL3CR         (CPG_BASE + 0x00DC)
+#define PLL0STPCR      (CPG_BASE + 0x00F0)
+#define PLL1STPCR      (CPG_BASE + 0x00C8)
+#define PLL2STPCR      (CPG_BASE + 0x00F8)
+#define PLL3STPCR      (CPG_BASE + 0x00FC)
+#define RMSTPCR0       (CPG_BASE + 0x0110)
+#define RMSTPCR1       (CPG_BASE + 0x0114)
+#define RMSTPCR2       (CPG_BASE + 0x0118)
+#define RMSTPCR3       (CPG_BASE + 0x011C)
+#define RMSTPCR4       (CPG_BASE + 0x0120)
+#define RMSTPCR5       (CPG_BASE + 0x0124)
+#define SMSTPCR0       (CPG_BASE + 0x0130)
+#define SMSTPCR2       (CPG_BASE + 0x0138)
+#define SMSTPCR3       (CPG_BASE + 0x013C)
+#define CPGXXCR4       (CPG_BASE + 0x0150)
+#define SRCR0          (CPG_BASE + 0x80A0)
+#define SRCR2          (CPG_BASE + 0x80B0)
+#define SRCR3          (CPG_BASE + 0x80A8)
+#define VREFCR         (CPG_BASE + 0x00EC)
+#define PCLKCR         (CPG_BASE + 0x1020)
+
+#define PORT32CR (0xE6051020)
+#define PORT33CR (0xE6051021)
+#define PORT34CR (0xE6051022)
+#define PORT35CR (0xE6051023)
+
+LIST "DRAM initialization code:"
+
+EW RWTCSRA0, 0xA507
+
+ED_AND LIFEC_SEC_SRC, 0xFFFF7FFF
+
+ED_AND SMSTPCR3,0xFFFF7FFF
+ED_AND SRCR3, 0xFFFF7FFF
+ED_AND SMSTPCR2,0xFFFBFFFF
+ED_AND SRCR2, 0xFFFBFFFF
+ED PLLECR, 0x00000000
+
+WAIT_MASK PLLECR, 0x00000F00, 0x00000000
+WAIT_MASK FRQCRB, 0x80000000, 0x00000000
+
+ED PLL0CR, 0x2D000000
+ED PLL1CR, 0x17100000
+ED FRQCRB, 0x96235880
+WAIT_MASK FRQCRB, 0x80000000, 0x00000000
+
+ED FLCKCR, 0x0000000B
+ED_AND SMSTPCR0, 0xFFFFFFFD
+
+ED_AND SRCR0, 0xFFFFFFFD
+ED 0xE6001628, 0x514
+ED 0xE6001648, 0x514
+ED 0xE6001658, 0x514
+ED 0xE6001678, 0x514
+
+ED DVFSCR4, 0x00092000
+ED DVFSCR5, 0x000000DC
+ED PLLECR, 0x00000000
+WAIT_MASK PLLECR, 0x00000F00, 0x00000000
+
+ED FRQCRA, 0x0012453C
+ED FRQCRB, 0x80431350
+WAIT_MASK FRQCRB, 0x80000000, 0x00000000
+ED FRQCRD, 0x00000B0B
+WAIT_MASK FRQCRD, 0x80000000, 0x00000000
+
+ED PCLKCR, 0x00000003
+ED VCLKCR1, 0x0000012F
+ED VCLKCR2, 0x00000119
+ED VCLKCR3, 0x00000119
+ED ZBCKCR, 0x00000002
+ED FLCKCR, 0x00000005
+ED SD0CKCR, 0x00000080
+ED SD1CKCR, 0x00000080
+ED SD2CKCR, 0x00000080
+ED FSIACKCR, 0x0000003F
+ED FSIBCKCR, 0x0000003F
+ED SUBCKCR, 0x00000080
+ED SPUACKCR, 0x0000000B
+ED SPUVCKCR, 0x0000000B
+ED MSUCKCR, 0x0000013F
+ED HSICKCR, 0x00000080
+ED MFCK1CR, 0x0000003F
+ED MFCK2CR, 0x0000003F
+ED DSITCKCR, 0x00000107
+ED DSI0PCKCR, 0x00000313
+ED DSI1PCKCR, 0x0000130D
+ED DSI0PHYCR, 0x2A800E0E
+ED PLL0CR, 0x1E000000
+ED PLL0CR, 0x2D000000
+ED PLL1CR, 0x17100000
+ED PLL2CR, 0x27000080
+ED PLL3CR, 0x1D000000
+ED PLL0STPCR, 0x00080000
+ED PLL1STPCR, 0x000120C0
+ED PLL2STPCR, 0x00012000
+ED PLL3STPCR, 0x00000030
+ED PLLECR, 0x0000000B
+WAIT_MASK PLLECR, 0x00000B00, 0x00000B00
+
+ED DVFSCR3, 0x000120F0
+ED MPMODE, 0x00000020
+ED VREFCR, 0x0000028A
+ED RMSTPCR0, 0xE4628087
+ED RMSTPCR1, 0xFFFFFFFF
+ED RMSTPCR2, 0x53FFFFFF
+ED RMSTPCR3, 0xFFFFFFFF
+ED RMSTPCR4, 0x00800D3D
+ED RMSTPCR5, 0xFFFFF3FF
+ED SMSTPCR2, 0x00000000
+ED SRCR2,  0x00040000
+ED_AND PLLECR, 0xFFFFFFF7
+WAIT_MASK PLLECR, 0x00000800, 0x00000000
+
+LIST "set SBSC operational"
+ED HPBCTRL6, 0x00000001
+WAIT_MASK HPBCTRL6, 0x00000001, 0x00000001
+
+LIST "set SBSC operating frequency"
+ED FRQCRD, 0x00001414
+WAIT_MASK FRQCRD, 0x80000000, 0x00000000
+ED PLL3CR, 0x1D000000
+ED_OR PLLECR, 0x00000008
+WAIT_MASK PLLECR, 0x00000800, 0x00000800
+
+LIST "enable DLL oscillation in DDRPHY"
+ED_OR DLLCNT0A, 0x00000002
+
+LIST "wait >= 100 ns"
+ED SDGENCNTA, 0x00000005
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "target LPDDR2 device settings"
+ED SDCR0A, 0xACC90159
+ED SDCR1A, 0x00010059
+ED SDWCRC0A, 0x50874114
+ED SDWCRC1A, 0x33199B37
+ED SDWCRC2A, 0x008F2313
+ED SDWCR00A, 0x31020707
+ED SDWCR01A, 0x0017040A
+ED SDWCR10A, 0x31020707
+ED SDWCR11A, 0x0017040A
+
+ED SDDRVCR0A, 0x055557ff
+
+ED SDWCR2A, 0x30000000
+
+LIST "drive CKE high"
+ED_OR SDPCRA, 0x00000080
+WAIT_MASK SDPCRA, 0x00000080, 0x00000080
+
+LIST "wait >= 200 us"
+ED SDGENCNTA, 0x00002710
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "issue reset command to LPDDR2 device"
+ED SDMRACR0A, 0x0000003F
+ED SDMRA1, 0x00000000
+
+LIST "wait >= 10 (or 1) us (docs inconsistent)"
+ED SDGENCNTA, 0x000001F4
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "MRW ZS initialization calibration command"
+ED SDMRACR0A, 0x0000FF0A
+ED SDMRA3, 0x00000000
+
+LIST "wait >= 1 us"
+ED SDGENCNTA, 0x00000032
+WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000
+
+LIST "specify operating mode in LPDDR2"
+ED SDMRACR0A, 0x00002201
+ED SDMRA1, 0x00000000
+ED SDMRACR0A, 0x00000402
+ED SDMRA1, 0x00000000
+ED SDMRACR0A, 0x00000203
+ED SDMRA1, 0x00000000
+
+LIST "initialize DDR interface"
+ED SDMRA2, 0x00000000
+
+LIST "temperature sensor control"
+ED SDMRTMPCRA, 0x88800004
+ED SDMRTMPMSKA,0x00000004
+
+LIST "auto-refreshing control"
+ED RTCORA, 0xA55A0032
+ED RTCORHA, 0xA55A000C
+ED RTCSRA, 0xA55A2048
+
+ED_OR SDCR0A, 0x00000800
+ED_OR SDCR1A, 0x00000400
+
+LIST "auto ZQ calibration control"
+ED ZQCCRA, 0xFFF20000
+
+ED_OR DLLCNT0B, 0x00000002
+ED SDGENCNTB, 0x00000005
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+
+ED SDCR0B, 0xACC90159
+ED SDCR1B, 0x00010059
+ED SDWCRC0B, 0x50874114
+ED SDWCRC1B, 0x33199B37
+ED SDWCRC2B, 0x008F2313
+ED SDWCR00B, 0x31020707
+ED SDWCR01B, 0x0017040A
+ED SDWCR10B, 0x31020707
+ED SDWCR11B, 0x0017040A
+ED SDDRVCR0B, 0x055557ff
+ED SDWCR2B, 0x30000000
+ED_OR SDPCRB, 0x00000080
+WAIT_MASK SDPCRB, 0x00000080, 0x00000080
+
+ED SDGENCNTB, 0x00002710
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+ED SDMRACR0B, 0x0000003F
+
+LIST "upstream u-boot writes to SDMRA1A for both SBSC 1 and 2, which does"
+LIST "not seem to make a lot of sense..."
+ED SDMRB1, 0x00000000
+
+ED SDGENCNTB, 0x000001F4
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+
+ED SDMRACR0B, 0x0000FF0A
+ED SDMRB3, 0x00000000
+ED SDGENCNTB, 0x00000032
+WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000
+
+ED SDMRACR0B, 0x00002201
+ED SDMRB1, 0x00000000
+ED SDMRACR0B, 0x00000402
+ED SDMRB1, 0x00000000
+ED SDMRACR0B, 0x00000203
+ED SDMRB1, 0x00000000
+ED SDMRB2, 0x00000000
+ED SDMRTMPCRB, 0x88800004
+ED SDMRTMPMSKB, 0x00000004
+ED RTCORB,  0xA55A0032
+ED RTCORHB, 0xA55A000C
+ED RTCSRB,  0xA55A2048
+ED_OR SDCR0B, 0x00000800
+ED_OR SDCR1B, 0x00000400
+ED ZQCCRB, 0xFFF20000
+ED_OR SDPDCR0B, 0x00030000
+ED DPHYCNT1B, 0xA5390000
+ED DPHYCNT0B, 0x00001200
+ED DPHYCNT1B, 0x07CE0000
+ED DPHYCNT0B, 0x00001247
+WAIT_MASK DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000
+
+ED_AND SDPDCR0B, 0xFFFCFFFF
+
+ED FRQCRD, 0x00000B0B
+WAIT_MASK FRQCRD, 0x80000000, 0x00000000
+
+ED CPGXXCR4, 0xfffffffc
+
+LIST "Setup SCIF4 / workaround"
+EB PORT32CR, 0x12
+EB PORT33CR, 0x22
+EB PORT34CR, 0x12
+EB PORT35CR, 0x22
+
+EW 0xE6C80000, 0
+EB 0xE6C80004, 0x19
+EW 0xE6C80008, 0x0030
+EW 0xE6C80018, 0
+EW 0xE6C80030, 0x0014
+
+LIST "Magic to avoid hangs and corruption on DRAM writes."
+
+LIST "It has been observed that the system would most often hang while"
+LIST "decompressing the kernel, and if it didn't it would always write"
+LIST "a corrupt image to DRAM."
+LIST "This problem does not occur in u-boot, and the reason is that"
+LIST "u-boot performs an additional cache invalidation after setting up"
+LIST "the DRAM controller. Such an invalidation should not be necessary at"
+LIST "this point, and attempts at removing parts of the routine to arrive"
+LIST "at the minimal snippet of code necessary to avoid the DRAM stability"
+LIST "problem yielded the following:"
+
+MRC p15, 0, r0, c1, c0, 0
+MCR p15, 0, r0, c1, c0, 0
diff --git a/arch/arm/mach-shmobile/include/mach/pm-rcar.h b/arch/arm/mach-shmobile/include/mach/pm-rcar.h
new file mode 100644 (file)
index 0000000..ef3a1ef
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef PM_RCAR_H
+#define PM_RCAR_H
+
+struct rcar_sysc_ch {
+       unsigned long chan_offs;
+       unsigned int chan_bit;
+       unsigned int isr_bit;
+};
+
+int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch);
+int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch);
+bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch);
+void __iomem *rcar_sysc_init(phys_addr_t base);
+
+#endif /* PM_RCAR_H */
index b40e13631f6a2040887ffdada677c7c7ed58b260..88eeceaf108871d19ec8fefeec67c04eef01923a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/sh_clk.h>
 #include <linux/pm_domain.h>
+#include <mach/pm-rcar.h>
 
 /* HPB-DMA slave IDs */
 enum {
@@ -11,18 +12,12 @@ enum {
        HPBDMA_SLAVE_SDHI0_RX,
 };
 
-struct r8a7779_pm_ch {
-       unsigned long chan_offs;
-       unsigned int chan_bit;
-       unsigned int isr_bit;
-};
-
 struct r8a7779_pm_domain {
        struct generic_pm_domain genpd;
-       struct r8a7779_pm_ch ch;
+       struct rcar_sysc_ch ch;
 };
 
-static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d)
+static inline struct rcar_sysc_ch *to_r8a7779_ch(struct generic_pm_domain *d)
 {
        return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
 }
@@ -41,8 +36,6 @@ extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
 extern void r8a7779_pm_init(void);
 extern void r8a7779_register_twd(void);
-extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch);
-extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch);
 
 #ifdef CONFIG_PM
 extern void __init r8a7779_init_pm_domains(void);
index 5fbfa28b40b64353d5f801c4999395ee76f819b0..0b95babe84ba6bae73d11de7f87476b45ba2a0ab 100644 (file)
@@ -3,10 +3,36 @@
 
 #include <mach/rcar-gen2.h>
 
+/* DMA slave IDs */
+enum {
+       RCAR_DMA_SLAVE_INVALID,
+       AUDIO_DMAC_SLAVE_SSI0_TX,
+       AUDIO_DMAC_SLAVE_SSI0_RX,
+       AUDIO_DMAC_SLAVE_SSI1_TX,
+       AUDIO_DMAC_SLAVE_SSI1_RX,
+       AUDIO_DMAC_SLAVE_SSI2_TX,
+       AUDIO_DMAC_SLAVE_SSI2_RX,
+       AUDIO_DMAC_SLAVE_SSI3_TX,
+       AUDIO_DMAC_SLAVE_SSI3_RX,
+       AUDIO_DMAC_SLAVE_SSI4_TX,
+       AUDIO_DMAC_SLAVE_SSI4_RX,
+       AUDIO_DMAC_SLAVE_SSI5_TX,
+       AUDIO_DMAC_SLAVE_SSI5_RX,
+       AUDIO_DMAC_SLAVE_SSI6_TX,
+       AUDIO_DMAC_SLAVE_SSI6_RX,
+       AUDIO_DMAC_SLAVE_SSI7_TX,
+       AUDIO_DMAC_SLAVE_SSI7_RX,
+       AUDIO_DMAC_SLAVE_SSI8_TX,
+       AUDIO_DMAC_SLAVE_SSI8_RX,
+       AUDIO_DMAC_SLAVE_SSI9_TX,
+       AUDIO_DMAC_SLAVE_SSI9_RX,
+};
+
 void r8a7790_add_standard_devices(void);
 void r8a7790_add_dt_devices(void);
 void r8a7790_clock_init(void);
 void r8a7790_pinmux_init(void);
+void r8a7790_pm_init(void);
 void r8a7790_init_early(void);
 extern struct smp_operations r8a7790_smp_ops;
 
diff --git a/arch/arm/mach-shmobile/include/mach/timex.h b/arch/arm/mach-shmobile/include/mach/timex.h
deleted file mode 100644 (file)
index ae0d8d8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_MACH_TIMEX_H
-#define __ASM_MACH_TIMEX_H
-
-#define CLOCK_TICK_RATE                1193180 /* unused i8253 PIT value */
-
-#endif /* __ASM_MACH_TIMEX_H */
index c3c4669a2d722d386e71be713a5a43040e1ca449..727cc78ac8ece93729603fe23188119f9fe1cdcf 100644 (file)
@@ -12,6 +12,9 @@
 #ifdef CONFIG_MACH_MACKEREL
 #define MEMORY_START   0x40000000
 #include "mach/head-mackerel.txt"
+#elif defined(CONFIG_MACH_KZM9G) || defined(CONFIG_MACH_KZM9G_REFERENCE)
+#define MEMORY_START   0x43000000
+#include "mach/head-kzm9g.txt"
 #else
 #error "unsupported board."
 #endif
index aa6111fbc989717bee9b439f6ae710fab69be26a..14fd3d538e9aa11ac3c7a1e3e356601f09d8e535 100644 (file)
 2 :
 .endm
 
+/* loop until a given value has been read (with mask) */
+.macro WAIT_MASK, addr, data, cmp
+       LDR     r0, 2f
+       LDR     r1, 3f
+       LDR     r2, 4f
+1:
+       LDR     r3, [r0, #0]
+       AND     r3, r1, r3
+       CMP     r2, r3
+       BNE     1b
+       B       5f
+2:     .long   \addr
+3:     .long   \data
+4:     .long   \cmp
+5:
+.endm
+
+/* read 32-bit value from addr, "or" an immediate and write back */
+.macro ED_OR, addr, data
+       LDR r4, 1f
+       LDR r5, 2f
+       LDR r6, [r4]
+       ORR r5, r6, r5
+       STR r5, [r4]
+       B       3f
+1:     .long   \addr
+2:     .long   \data
+3:
+.endm
+
+/* read 32-bit value from addr, "and" an immediate and write back */
+.macro ED_AND, addr, data
+       LDR r4, 1f
+       LDR r5, 2f
+       LDR r6, [r4]
+       AND r5, r6, r5
+       STR r5, [r4]
+       B       3f
+1:     .long \addr
+2:     .long \data
+3:
+.endm
+
 #endif /* __ZBOOT_MACRO_H */
index 1da5a72d9642fbc2833e059f2e40aba407cbb795..8cb641c00fdb1f68b4ddd4cc3ad516a3bb994699 100644 (file)
@@ -75,8 +75,7 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
        apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res));
        apmu_cpus[cpu].bit = bit;
 
-       pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit,
-                res->start, resource_size(res));
+       pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res);
 }
 
 static struct {
index d50a8e9b94a4f9ac7030bdc49dc5450674e5af9a..d6fe189b2df6e4176d343b33630085bff7d071c7 100644 (file)
 #include <linux/console.h>
 #include <asm/io.h>
 #include <mach/common.h>
+#include <mach/pm-rcar.h>
 #include <mach/r8a7779.h>
 
-static void __iomem *r8a7779_sysc_base;
-
 /* SYSC */
-#define SYSCSR 0x00
-#define SYSCISR 0x04
-#define SYSCISCR 0x08
 #define SYSCIER 0x0c
 #define SYSCIMR 0x10
-#define PWRSR0 0x40
-#define PWRSR1 0x80
-#define PWRSR2 0xc0
-#define PWRSR3 0x100
-#define PWRSR4 0x140
-
-#define PWRSR_OFFS 0x00
-#define PWROFFCR_OFFS 0x04
-#define PWRONCR_OFFS 0x0c
-#define PWRER_OFFS 0x14
-
-#define SYSCSR_RETRIES 100
-#define SYSCSR_DELAY_US 1
-
-#define SYSCISR_RETRIES 1000
-#define SYSCISR_DELAY_US 1
 
 #if defined(CONFIG_PM) || defined(CONFIG_SMP)
 
-static DEFINE_SPINLOCK(r8a7779_sysc_lock); /* SMP CPUs + I/O devices */
-
-static int r8a7779_sysc_pwr_on_off(struct r8a7779_pm_ch *r8a7779_ch,
-                                  int sr_bit, int reg_offs)
-{
-       int k;
-
-       for (k = 0; k < SYSCSR_RETRIES; k++) {
-               if (ioread32(r8a7779_sysc_base + SYSCSR) & (1 << sr_bit))
-                       break;
-               udelay(SYSCSR_DELAY_US);
-       }
-
-       if (k == SYSCSR_RETRIES)
-               return -EAGAIN;
-
-       iowrite32(1 << r8a7779_ch->chan_bit,
-                 r8a7779_sysc_base + r8a7779_ch->chan_offs + reg_offs);
-
-       return 0;
-}
-
-static int r8a7779_sysc_pwr_off(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_pwr_on_off(r8a7779_ch, 0, PWROFFCR_OFFS);
-}
-
-static int r8a7779_sysc_pwr_on(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_pwr_on_off(r8a7779_ch, 1, PWRONCR_OFFS);
-}
-
-static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
-                              int (*on_off_fn)(struct r8a7779_pm_ch *))
-{
-       unsigned int isr_mask = 1 << r8a7779_ch->isr_bit;
-       unsigned int chan_mask = 1 << r8a7779_ch->chan_bit;
-       unsigned int status;
-       unsigned long flags;
-       int ret = 0;
-       int k;
-
-       spin_lock_irqsave(&r8a7779_sysc_lock, flags);
-
-       iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
-
-       do {
-               ret = on_off_fn(r8a7779_ch);
-               if (ret)
-                       goto out;
-
-               status = ioread32(r8a7779_sysc_base +
-                                 r8a7779_ch->chan_offs + PWRER_OFFS);
-       } while (status & chan_mask);
-
-       for (k = 0; k < SYSCISR_RETRIES; k++) {
-               if (ioread32(r8a7779_sysc_base + SYSCISR) & isr_mask)
-                       break;
-               udelay(SYSCISR_DELAY_US);
-       }
-
-       if (k == SYSCISR_RETRIES)
-               ret = -EIO;
-
-       iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
-
- out:
-       spin_unlock_irqrestore(&r8a7779_sysc_lock, flags);
-
-       pr_debug("r8a7779 power domain %d: %02x %02x %02x %02x %02x -> %d\n",
-                r8a7779_ch->isr_bit, ioread32(r8a7779_sysc_base + PWRSR0),
-                ioread32(r8a7779_sysc_base + PWRSR1),
-                ioread32(r8a7779_sysc_base + PWRSR2),
-                ioread32(r8a7779_sysc_base + PWRSR3),
-                ioread32(r8a7779_sysc_base + PWRSR4), ret);
-       return ret;
-}
-
-int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off);
-}
-
-int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on);
-}
-
 static void __init r8a7779_sysc_init(void)
 {
-       r8a7779_sysc_base = ioremap_nocache(0xffd85000, PAGE_SIZE);
-       if (!r8a7779_sysc_base)
-               panic("unable to ioremap r8a7779 SYSC hardware block\n");
+       void __iomem *base = rcar_sysc_init(0xffd85000);
 
        /* enable all interrupt sources, but do not use interrupt handler */
-       iowrite32(0x0131000e, r8a7779_sysc_base + SYSCIER);
-       iowrite32(0, r8a7779_sysc_base + SYSCIMR);
+       iowrite32(0x0131000e, base + SYSCIER);
+       iowrite32(0, base + SYSCIMR);
 }
 
 #else /* CONFIG_PM || CONFIG_SMP */
@@ -158,24 +48,17 @@ static inline void r8a7779_sysc_init(void) {}
 
 static int pd_power_down(struct generic_pm_domain *genpd)
 {
-       return r8a7779_sysc_power_down(to_r8a7779_ch(genpd));
+       return rcar_sysc_power_down(to_r8a7779_ch(genpd));
 }
 
 static int pd_power_up(struct generic_pm_domain *genpd)
 {
-       return r8a7779_sysc_power_up(to_r8a7779_ch(genpd));
+       return rcar_sysc_power_up(to_r8a7779_ch(genpd));
 }
 
 static bool pd_is_off(struct generic_pm_domain *genpd)
 {
-       struct r8a7779_pm_ch *r8a7779_ch = to_r8a7779_ch(genpd);
-       unsigned int st;
-
-       st = ioread32(r8a7779_sysc_base + r8a7779_ch->chan_offs + PWRSR_OFFS);
-       if (st & (1 << r8a7779_ch->chan_bit))
-               return true;
-
-       return false;
+       return rcar_sysc_power_is_off(to_r8a7779_ch(genpd));
 }
 
 static bool pd_active_wakeup(struct device *dev)
diff --git a/arch/arm/mach-shmobile/pm-r8a7790.c b/arch/arm/mach-shmobile/pm-r8a7790.c
new file mode 100644 (file)
index 0000000..fc82839
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * r8a7790 Power management support
+ *
+ * Copyright (C) 2013  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>
+#include <asm/io.h>
+#include <mach/pm-rcar.h>
+#include <mach/r8a7790.h>
+
+/* SYSC */
+#define SYSCIER 0x0c
+#define SYSCIMR 0x10
+
+#if defined(CONFIG_SMP)
+
+static void __init r8a7790_sysc_init(void)
+{
+       void __iomem *base = rcar_sysc_init(0xe6180000);
+
+       /* enable all interrupt sources, but do not use interrupt handler */
+       iowrite32(0x0131000e, base + SYSCIER);
+       iowrite32(0, base + SYSCIMR);
+}
+
+#else /* CONFIG_SMP */
+
+static inline void r8a7790_sysc_init(void) {}
+
+#endif /* CONFIG_SMP */
+
+void __init r8a7790_pm_init(void)
+{
+       static int once;
+
+       if (!once++)
+               r8a7790_sysc_init();
+}
diff --git a/arch/arm/mach-shmobile/pm-rcar.c b/arch/arm/mach-shmobile/pm-rcar.c
new file mode 100644 (file)
index 0000000..1f465a1
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * R-Car SYSC Power management support
+ *
+ * Copyright (C) 2014  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/delay.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <mach/pm-rcar.h>
+
+/* SYSC */
+#define SYSCSR 0x00
+#define SYSCISR 0x04
+#define SYSCISCR 0x08
+
+#define PWRSR_OFFS 0x00
+#define PWROFFCR_OFFS 0x04
+#define PWRONCR_OFFS 0x0c
+#define PWRER_OFFS 0x14
+
+#define SYSCSR_RETRIES 100
+#define SYSCSR_DELAY_US 1
+
+#define SYSCISR_RETRIES 1000
+#define SYSCISR_DELAY_US 1
+
+#if defined(CONFIG_PM) || defined(CONFIG_SMP)
+
+static void __iomem *rcar_sysc_base;
+static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
+
+static int rcar_sysc_pwr_on_off(struct rcar_sysc_ch *sysc_ch,
+                               int sr_bit, int reg_offs)
+{
+       int k;
+
+       for (k = 0; k < SYSCSR_RETRIES; k++) {
+               if (ioread32(rcar_sysc_base + SYSCSR) & (1 << sr_bit))
+                       break;
+               udelay(SYSCSR_DELAY_US);
+       }
+
+       if (k == SYSCSR_RETRIES)
+               return -EAGAIN;
+
+       iowrite32(1 << sysc_ch->chan_bit,
+                 rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
+
+       return 0;
+}
+
+static int rcar_sysc_pwr_off(struct rcar_sysc_ch *sysc_ch)
+{
+       return rcar_sysc_pwr_on_off(sysc_ch, 0, PWROFFCR_OFFS);
+}
+
+static int rcar_sysc_pwr_on(struct rcar_sysc_ch *sysc_ch)
+{
+       return rcar_sysc_pwr_on_off(sysc_ch, 1, PWRONCR_OFFS);
+}
+
+static int rcar_sysc_update(struct rcar_sysc_ch *sysc_ch,
+                           int (*on_off_fn)(struct rcar_sysc_ch *))
+{
+       unsigned int isr_mask = 1 << sysc_ch->isr_bit;
+       unsigned int chan_mask = 1 << sysc_ch->chan_bit;
+       unsigned int status;
+       unsigned long flags;
+       int ret = 0;
+       int k;
+
+       spin_lock_irqsave(&rcar_sysc_lock, flags);
+
+       iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
+
+       do {
+               ret = on_off_fn(sysc_ch);
+               if (ret)
+                       goto out;
+
+               status = ioread32(rcar_sysc_base +
+                                 sysc_ch->chan_offs + PWRER_OFFS);
+       } while (status & chan_mask);
+
+       for (k = 0; k < SYSCISR_RETRIES; k++) {
+               if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask)
+                       break;
+               udelay(SYSCISR_DELAY_US);
+       }
+
+       if (k == SYSCISR_RETRIES)
+               ret = -EIO;
+
+       iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
+
+ out:
+       spin_unlock_irqrestore(&rcar_sysc_lock, flags);
+
+       pr_debug("sysc power domain %d: %08x -> %d\n",
+                sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
+       return ret;
+}
+
+int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch)
+{
+       return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_off);
+}
+
+int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch)
+{
+       return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_on);
+}
+
+bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch)
+{
+       unsigned int st;
+
+       st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);
+       if (st & (1 << sysc_ch->chan_bit))
+               return true;
+
+       return false;
+}
+
+void __iomem *rcar_sysc_init(phys_addr_t base)
+{
+       rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
+       if (!rcar_sysc_base)
+               panic("unable to ioremap R-Car SYSC hardware block\n");
+
+       return rcar_sysc_base;
+}
+
+#endif /* CONFIG_PM || CONFIG_SMP */
index c8f2a1a69a5274bec8eab99f44549fb3bbbae955..c71d667007b8e4e79811da67513ff3b06b6c38c4 100644 (file)
@@ -58,7 +58,7 @@ static void __init emev2_add_standard_devices_dt(void)
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
-static const char *emev2_boards_compat_dt[] __initdata = {
+static const char *emev2_boards_compat_dt[] __initconst = {
        "renesas,emev2",
        NULL,
 };
index 6ab37aa1e919825aa6584441cffc91b7057fcbf5..c4616f0698c6dcfefc3934cace5fd6c16c37e257 100644 (file)
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-irqc.h>
 #include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
 #include <linux/sh_timer.h>
 #include <mach/common.h>
+#include <mach/dma-register.h>
 #include <mach/irqs.h>
 #include <mach/r8a7790.h>
 #include <asm/mach/arch.h>
 
+/* Audio-DMAC */
+#define AUDIO_DMAC_SLAVE(_id, _addr, t, r)                     \
+{                                                              \
+       .slave_id       = AUDIO_DMAC_SLAVE_## _id ##_TX,        \
+       .addr           = _addr + 0x8,                          \
+       .chcr           = CHCR_TX(XMIT_SZ_32BIT),               \
+       .mid_rid        = t,                                    \
+}, {                                                           \
+       .slave_id       = AUDIO_DMAC_SLAVE_## _id ##_RX,        \
+       .addr           = _addr + 0xc,                          \
+       .chcr           = CHCR_RX(XMIT_SZ_32BIT),               \
+       .mid_rid        = r,                                    \
+}
+
+static const struct sh_dmae_slave_config r8a7790_audio_dmac_slaves[] = {
+       AUDIO_DMAC_SLAVE(SSI0, 0xec241000, 0x01, 0x02),
+       AUDIO_DMAC_SLAVE(SSI1, 0xec241040, 0x03, 0x04),
+       AUDIO_DMAC_SLAVE(SSI2, 0xec241080, 0x05, 0x06),
+       AUDIO_DMAC_SLAVE(SSI3, 0xec2410c0, 0x07, 0x08),
+       AUDIO_DMAC_SLAVE(SSI4, 0xec241100, 0x09, 0x0a),
+       AUDIO_DMAC_SLAVE(SSI5, 0xec241140, 0x0b, 0x0c),
+       AUDIO_DMAC_SLAVE(SSI6, 0xec241180, 0x0d, 0x0e),
+       AUDIO_DMAC_SLAVE(SSI7, 0xec2411c0, 0x0f, 0x10),
+       AUDIO_DMAC_SLAVE(SSI8, 0xec241200, 0x11, 0x12),
+       AUDIO_DMAC_SLAVE(SSI9, 0xec241240, 0x13, 0x14),
+};
+
+#define DMAE_CHANNEL(a, b)                     \
+{                                              \
+       .offset         = (a) - 0x20,           \
+       .dmars          = (a) - 0x20 + 0x40,    \
+       .chclr_bit      = (b),                  \
+       .chclr_offset   = 0x80 - 0x20,          \
+}
+
+static const struct sh_dmae_channel r8a7790_audio_dmac_channels[] = {
+       DMAE_CHANNEL(0x8000, 0),
+       DMAE_CHANNEL(0x8080, 1),
+       DMAE_CHANNEL(0x8100, 2),
+       DMAE_CHANNEL(0x8180, 3),
+       DMAE_CHANNEL(0x8200, 4),
+       DMAE_CHANNEL(0x8280, 5),
+       DMAE_CHANNEL(0x8300, 6),
+       DMAE_CHANNEL(0x8380, 7),
+       DMAE_CHANNEL(0x8400, 8),
+       DMAE_CHANNEL(0x8480, 9),
+       DMAE_CHANNEL(0x8500, 10),
+       DMAE_CHANNEL(0x8580, 11),
+       DMAE_CHANNEL(0x8600, 12),
+};
+
+static struct sh_dmae_pdata r8a7790_audio_dmac_platform_data = {
+       .slave          = r8a7790_audio_dmac_slaves,
+       .slave_num      = ARRAY_SIZE(r8a7790_audio_dmac_slaves),
+       .channel        = r8a7790_audio_dmac_channels,
+       .channel_num    = ARRAY_SIZE(r8a7790_audio_dmac_channels),
+       .ts_low_shift   = TS_LOW_SHIFT,
+       .ts_low_mask    = TS_LOW_BIT << TS_LOW_SHIFT,
+       .ts_high_shift  = TS_HI_SHIFT,
+       .ts_high_mask   = TS_HI_BIT << TS_HI_SHIFT,
+       .ts_shift       = dma_ts_shift,
+       .ts_shift_num   = ARRAY_SIZE(dma_ts_shift),
+       .dmaor_init     = DMAOR_DME,
+       .chclr_present  = 1,
+       .chclr_bitwise  = 1,
+};
+
+static struct resource r8a7790_audio_dmac_resources[] = {
+       /* Channel registers and DMAOR for low */
+       DEFINE_RES_MEM(0xec700020, 0x8663 - 0x20),
+       DEFINE_RES_IRQ(gic_spi(346)),
+       DEFINE_RES_NAMED(gic_spi(320), 13, NULL, IORESOURCE_IRQ),
+
+       /* Channel registers and DMAOR for hi */
+       DEFINE_RES_MEM(0xec720020, 0x8663 - 0x20), /* hi */
+       DEFINE_RES_IRQ(gic_spi(347)),
+       DEFINE_RES_NAMED(gic_spi(333), 13, NULL, IORESOURCE_IRQ),
+};
+
+#define r8a7790_register_audio_dmac(id)                                \
+       platform_device_register_resndata(                      \
+               &platform_bus, "sh-dma-engine", id,             \
+               &r8a7790_audio_dmac_resources[id * 3],  3,      \
+               &r8a7790_audio_dmac_platform_data,              \
+               sizeof(r8a7790_audio_dmac_platform_data))
+
 static const struct resource pfc_resources[] __initconst = {
        DEFINE_RES_MEM(0xe6060000, 0x250),
 };
@@ -101,6 +189,8 @@ void __init r8a7790_pinmux_init(void)
        r8a7790_register_i2c(1);
        r8a7790_register_i2c(2);
        r8a7790_register_i2c(3);
+       r8a7790_register_audio_dmac(0);
+       r8a7790_register_audio_dmac(1);
 }
 
 #define __R8A7790_SCIF(scif_type, _scscr, index, baseaddr, irq)                \
index 69ccc6c6fd334ffe39795bafa3260a7ae422a8c9..10604480f325296347cdfc7a31ed5d40135fd7b1 100644 (file)
@@ -28,7 +28,7 @@
 
 #define MODEMR 0xe6160060
 
-u32 __init rcar_gen2_read_mode_pins(void)
+u32 rcar_gen2_read_mode_pins(void)
 {
        void __iomem *modemr = ioremap_nocache(MODEMR, 4);
        u32 mode;
index 627c1f0d9478b36ff79342d25053b9557d429189..e7a3201473d0733579e57475886624343125727a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <mach/common.h>
+#include <mach/pm-rcar.h>
 #include <mach/r8a7779.h>
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 #define AVECR IOMEM(0xfe700040)
 #define R8A7779_SCU_BASE 0xf0000000
 
-static struct r8a7779_pm_ch r8a7779_ch_cpu1 = {
+static struct rcar_sysc_ch r8a7779_ch_cpu1 = {
        .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
        .chan_bit = 1, /* ARM1 */
        .isr_bit = 1, /* ARM1 */
 };
 
-static struct r8a7779_pm_ch r8a7779_ch_cpu2 = {
+static struct rcar_sysc_ch r8a7779_ch_cpu2 = {
        .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
        .chan_bit = 2, /* ARM2 */
        .isr_bit = 2, /* ARM2 */
 };
 
-static struct r8a7779_pm_ch r8a7779_ch_cpu3 = {
+static struct rcar_sysc_ch r8a7779_ch_cpu3 = {
        .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
        .chan_bit = 3, /* ARM3 */
        .isr_bit = 3, /* ARM3 */
 };
 
-static struct r8a7779_pm_ch *r8a7779_ch_cpu[4] = {
+static struct rcar_sysc_ch *r8a7779_ch_cpu[4] = {
        [1] = &r8a7779_ch_cpu1,
        [2] = &r8a7779_ch_cpu2,
        [3] = &r8a7779_ch_cpu3,
@@ -67,7 +68,7 @@ void __init r8a7779_register_twd(void)
 
 static int r8a7779_platform_cpu_kill(unsigned int cpu)
 {
-       struct r8a7779_pm_ch *ch = NULL;
+       struct rcar_sysc_ch *ch = NULL;
        int ret = -EIO;
 
        cpu = cpu_logical_map(cpu);
@@ -76,14 +77,14 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu)
                ch = r8a7779_ch_cpu[cpu];
 
        if (ch)
-               ret = r8a7779_sysc_power_down(ch);
+               ret = rcar_sysc_power_down(ch);
 
        return ret ? ret : 1;
 }
 
 static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       struct r8a7779_pm_ch *ch = NULL;
+       struct rcar_sysc_ch *ch = NULL;
        unsigned int lcpu = cpu_logical_map(cpu);
        int ret;
 
@@ -91,7 +92,7 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
                ch = r8a7779_ch_cpu[lcpu];
 
        if (ch)
-               ret = r8a7779_sysc_power_up(ch);
+               ret = rcar_sysc_power_up(ch);
        else
                ret = -EIO;
 
index 015e2753de1f27c51e535795ed4d337567496b5d..591052799e8f31fa3dcd7c73360a874a9db2b791 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/io.h>
 #include <asm/smp_plat.h>
 #include <mach/common.h>
+#include <mach/pm-rcar.h>
+#include <mach/r8a7790.h>
 
 #define RST            0xe6160000
 #define CA15BAR                0x0020
 #define CA7RESCNT      0x0044
 #define MERAM          0xe8080000
 
+static struct rcar_sysc_ch r8a7790_ca15_scu = {
+       .chan_offs = 0x180, /* PWRSR5 .. PWRER5 */
+       .isr_bit = 12, /* CA15-SCU */
+};
+
+static struct rcar_sysc_ch r8a7790_ca7_scu = {
+       .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
+       .isr_bit = 21, /* CA7-SCU */
+};
+
 static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
 {
        void __iomem *p;
@@ -54,6 +66,11 @@ static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
        writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000,
                       p + CA7RESCNT);
        iounmap(p);
+
+       /* turn on power to SCU */
+       r8a7790_pm_init();
+       rcar_sysc_power_up(&r8a7790_ca15_scu);
+       rcar_sysc_power_up(&r8a7790_ca7_scu);
 }
 
 struct smp_operations r8a7790_smp_ops __initdata = {
index aee77f06f887da5d8f73e2112333a015640e93ab..b5f8d75d51a0568d603c293df64d403711b77447 100644 (file)
@@ -1,17 +1,10 @@
 config ARCH_SOCFPGA
        bool "Altera SOCFPGA family" if ARCH_MULTI_V7
-       select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_AMBA
        select ARM_GIC
        select CACHE_L2X0
-       select COMMON_CLK
-       select CPU_V7
        select DW_APB_TIMER_OF
-       select GENERIC_CLOCKEVENTS
        select GPIO_PL061 if GPIOLIB
        select HAVE_ARM_SCU
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
        select MFD_SYSCON
-       select SPARSE_IRQ
-       select USE_OF
index dd0d49cdbe097c09fb15d0a652f2aa6d10e60db9..d86231e11b3449665b02a030b849e9cd75cddb0d 100644 (file)
@@ -29,7 +29,6 @@
 void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
 void __iomem *sys_manager_base_addr;
 void __iomem *rst_manager_base_addr;
-void __iomem *clk_mgr_base_addr;
 unsigned long cpu1start_addr;
 
 static struct map_desc scu_io_desc __initdata = {
@@ -78,9 +77,6 @@ void __init socfpga_sysmgr_init(void)
 
        np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
        rst_manager_base_addr = of_iomap(np, 0);
-
-       np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr");
-       clk_mgr_base_addr = of_iomap(np, 0);
 }
 
 static void __init socfpga_init_irq(void)
@@ -106,7 +102,6 @@ static void __init socfpga_cyclone5_init(void)
 {
        l2x0_of_init(0, ~0UL);
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-       socfpga_init_clocks();
 }
 
 static const char *altera_dt_match[] = {
index 308d5b5b3055d35f9e17011c8e4e45999c1f33ad..0786249b283250041f3b7aa824d64bc85e08462f 100644 (file)
@@ -8,8 +8,6 @@ menuconfig PLAT_SPEAR
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select CLKSRC_MMIO
-       select COMMON_CLK
-       select GENERIC_CLOCKEVENTS
 
 if PLAT_SPEAR
 
@@ -18,14 +16,10 @@ config ARCH_SPEAR13XX
        depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE
        select ARCH_HAS_CPUFREQ
        select ARM_GIC
-       select CPU_V7
        select GPIO_SPEAR_SPICS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
-       select MIGHT_HAVE_CACHE_L2X0
        select PINCTRL
-       select USE_OF
        help
          Supports for ARM's SPEAR13XX family
 
@@ -50,9 +44,7 @@ config ARCH_SPEAR3XX
        depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE
        depends on !ARCH_SPEAR13XX
        select ARM_VIC
-       select CPU_ARM926T
        select PINCTRL
-       select USE_OF
        help
          Supports for ARM's SPEAR3XX family
 
@@ -83,14 +75,12 @@ config ARCH_SPEAR6XX
        depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE
        depends on !ARCH_SPEAR13XX
        select ARM_VIC
-       select CPU_ARM926T
        help
          Supports for ARM's SPEAR6XX family
 
 config MACH_SPEAR600
        def_bool y
        depends on ARCH_SPEAR6XX
-       select USE_OF
        help
          Supports ST SPEAr600 boards configured via the device-tree
 
diff --git a/arch/arm/mach-spear/include/mach/timex.h b/arch/arm/mach-spear/include/mach/timex.h
deleted file mode 100644 (file)
index ef95e5b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/plat-spear/include/plat/timex.h
- *
- * SPEAr platform specific timex definitions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar <viresh.linux@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_TIMEX_H
-#define __PLAT_TIMEX_H
-
-#define CLOCK_TICK_RATE                        48000000
-
-#endif /* __PLAT_TIMEX_H */
index d449673e40f79aa8d15c8b75e075bc5ad57570a7..218ba5b67d9298bbd0bc8716fe6e107fe5788782 100644 (file)
@@ -172,7 +172,7 @@ static irqreturn_t spear_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction spear_timer_irq = {
        .name = "timer",
-       .flags = IRQF_DISABLED | IRQF_TIMER,
+       .flags = IRQF_TIMER,
        .handler = spear_timer_interrupt
 };
 
index d71654bc8d54d0be5aef108a43d5f0673bd68d40..abf9ee9bbc3f445c182e4893a8d0f1f9da3f4e9b 100644 (file)
@@ -1,14 +1,11 @@
 menuconfig ARCH_STI
        bool "STMicroelectronics Consumer Electronics SOCs with Device Trees" if ARCH_MULTI_V7
-       select GENERIC_CLOCKEVENTS
-       select CLKDEV_LOOKUP
        select ARM_GIC
        select ARM_GLOBAL_TIMER
        select PINCTRL
        select PINCTRL_ST
        select MFD_SYSCON
-       select MIGHT_HAVE_CACHE_L2X0
-       select HAVE_SMP
+       select ARCH_HAS_RESET_CONTROLLER
        select HAVE_ARM_SCU if SMP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_ERRATA_754322
@@ -28,6 +25,7 @@ if ARCH_STI
 config SOC_STIH415
        bool "STiH415 STMicroelectronics Consumer Electronics family"
        default y
+       select STIH415_RESET
        help
          This enables support for STMicroelectronics Digital Consumer
          Electronics family StiH415 parts, primarily targeted at set-top-box
@@ -37,6 +35,7 @@ config SOC_STIH415
 config SOC_STIH416
        bool "STiH416 STMicroelectronics Consumer Electronics family"
        default y
+       select STIH416_RESET
        help
          This enables support for STMicroelectronics Digital Consumer
          Electronics family StiH416 parts, primarily targeted at set-top-box
index b9d6cad8669b8ea623aa5787de36c80d8caa5621..b57d7d53b9d3626998c38bb23a27b1341f135416 100644 (file)
@@ -5,14 +5,10 @@ config ARCH_SUNXI
        select ARM_GIC
        select ARM_PSCI
        select CLKSRC_MMIO
-       select CLKSRC_OF
-       select COMMON_CLK
-       select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
-       select HAVE_SMP
+       select HAVE_ARM_ARCH_TIMER
        select PINCTRL
        select PINCTRL_SUNXI
        select RESET_CONTROLLER
-       select SPARSE_IRQ
        select SUN4I_TIMER
        select SUN5I_HSTIMER
index d9397202d6ecd8e7ed4d0908fd656b559a41ebb2..27b168f121a1587931ba851c4ecc51cdaa38c026 100644 (file)
@@ -1,2 +1,2 @@
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
-obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S
deleted file mode 100644 (file)
index a10d494..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-        .section ".text.head", "ax"
-
-ENTRY(sun6i_secondary_startup)
-       msr     cpsr_fsxc, #0xd3
-       b       secondary_startup
-ENDPROC(sun6i_secondary_startup)
index 7b141d8342a1382c94a5d518eb60dac7d9cb69cb..0c7dbce033cc28e1fa93cca2500abc3f44113938 100644 (file)
@@ -82,7 +82,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu,
        spin_lock(&cpu_lock);
 
        /* Set CPU boot address */
-       writel(virt_to_phys(sun6i_secondary_startup),
+       writel(virt_to_phys(secondary_startup),
               cpucfg_membase + CPUCFG_PRIVATE0_REG);
 
        /* Assert the CPU core in reset */
index aeea6ceea725f5e8fb8495f09850616400679710..460b5a4962ef264fff0357800f7c526dbded871f 100644 (file)
@@ -94,8 +94,8 @@ static void sun6i_restart(enum reboot_mode mode, const char *cmd)
 }
 
 static struct of_device_id sunxi_restart_ids[] = {
-       { .compatible = "allwinner,sun4i-wdt" },
-       { .compatible = "allwinner,sun6i-wdt" },
+       { .compatible = "allwinner,sun4i-a10-wdt" },
+       { .compatible = "allwinner,sun6i-a31-wdt" },
        { /*sentinel*/ }
 };
 
index 4926bd11f190fc259c82f0311760baaee3502bc8..92d660f9610f4ca94092a81749e578372731939f 100644 (file)
@@ -5,23 +5,15 @@ config ARCH_TEGRA
        select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
        select ARM_GIC
        select CLKSRC_MMIO
-       select CLKSRC_OF
-       select COMMON_CLK
-       select CPU_V7
-       select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
-       select MIGHT_HAVE_CACHE_L2X0
        select MIGHT_HAVE_PCI
        select PINCTRL
        select ARCH_HAS_RESET_CONTROLLER
        select RESET_CONTROLLER
        select SOC_BUS
-       select SPARSE_IRQ
        select USB_ULPI if USB_PHY
        select USB_ULPI_VIEWPORT if USB_PHY
-       select USE_OF
        help
          This enables support for NVIDIA Tegra based systems.
 
index 019bb175866294227f4197633d58d32a7b89004c..6fbfbb77dcd991f496da168542e4f703dd950203 100644 (file)
@@ -14,7 +14,6 @@ obj-y                                 += sleep.o
 obj-y                                  += tegra.o
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra20_speedo.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += sleep-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += pm-tegra20.o
 ifeq ($(CONFIG_CPU_IDLE),y)
index e0b87300243d615712104238ebf1a0b827ee594e..b5fb7c110c64314f2e9b11c218b760d6e9d9e09c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/clockchips.h>
+#include <asm/firmware.h>
 
 #include <asm/cpuidle.h>
 #include <asm/suspend.h>
@@ -45,7 +46,11 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
 
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
 
-       cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+       call_firmware_op(prepare_idle);
+
+       /* Do suspend by ourselves if the firmware does not implement it */
+       if (call_firmware_op(do_idle) == -ENOSYS)
+               cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
 
index eb72ae709124e4978167b2c38c96a63d44543b46..929d1046e2b413b05987b929746fe645be992655 100644 (file)
@@ -114,7 +114,7 @@ static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
                /* Wait for the power to come up. */
                timeout = jiffies + msecs_to_jiffies(100);
-               while (tegra_pmc_cpu_is_powered(cpu)) {
+               while (!tegra_pmc_cpu_is_powered(cpu)) {
                        if (time_after(jiffies, timeout))
                                return -ETIMEDOUT;
                        udelay(10);
index 3d0c537d9b945af08de57ecaa354169674fdc33e..4cefc5cd6bedcc50ddc345c857270fda1ad17d49 100644 (file)
@@ -484,6 +484,7 @@ int tegra_io_rail_power_on(int id)
 
        return 0;
 }
+EXPORT_SYMBOL(tegra_io_rail_power_on);
 
 int tegra_io_rail_power_off(int id)
 {
@@ -511,3 +512,4 @@ int tegra_io_rail_power_off(int id)
 
        return 0;
 }
+EXPORT_SYMBOL(tegra_io_rail_power_off);
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
deleted file mode 100644 (file)
index 3ae4a7f..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc.
- *
- * Author:
- *     Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/tegra_emc.h>
-
-#include "tegra2_emc.h"
-#include "fuse.h"
-
-#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
-static bool emc_enable = true;
-#else
-static bool emc_enable;
-#endif
-module_param(emc_enable, bool, 0644);
-
-static struct platform_device *emc_pdev;
-static void __iomem *emc_regbase;
-
-static inline void emc_writel(u32 val, unsigned long addr)
-{
-       writel(val, emc_regbase + addr);
-}
-
-static inline u32 emc_readl(unsigned long addr)
-{
-       return readl(emc_regbase + addr);
-}
-
-static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
-       0x2c,   /* RC */
-       0x30,   /* RFC */
-       0x34,   /* RAS */
-       0x38,   /* RP */
-       0x3c,   /* R2W */
-       0x40,   /* W2R */
-       0x44,   /* R2P */
-       0x48,   /* W2P */
-       0x4c,   /* RD_RCD */
-       0x50,   /* WR_RCD */
-       0x54,   /* RRD */
-       0x58,   /* REXT */
-       0x5c,   /* WDV */
-       0x60,   /* QUSE */
-       0x64,   /* QRST */
-       0x68,   /* QSAFE */
-       0x6c,   /* RDV */
-       0x70,   /* REFRESH */
-       0x74,   /* BURST_REFRESH_NUM */
-       0x78,   /* PDEX2WR */
-       0x7c,   /* PDEX2RD */
-       0x80,   /* PCHG2PDEN */
-       0x84,   /* ACT2PDEN */
-       0x88,   /* AR2PDEN */
-       0x8c,   /* RW2PDEN */
-       0x90,   /* TXSR */
-       0x94,   /* TCKE */
-       0x98,   /* TFAW */
-       0x9c,   /* TRPAB */
-       0xa0,   /* TCLKSTABLE */
-       0xa4,   /* TCLKSTOP */
-       0xa8,   /* TREFBW */
-       0xac,   /* QUSE_EXTRA */
-       0x114,  /* FBIO_CFG6 */
-       0xb0,   /* ODT_WRITE */
-       0xb4,   /* ODT_READ */
-       0x104,  /* FBIO_CFG5 */
-       0x2bc,  /* CFG_DIG_DLL */
-       0x2c0,  /* DLL_XFORM_DQS */
-       0x2c4,  /* DLL_XFORM_QUSE */
-       0x2e0,  /* ZCAL_REF_CNT */
-       0x2e4,  /* ZCAL_WAIT_CNT */
-       0x2a8,  /* AUTO_CAL_INTERVAL */
-       0x2d0,  /* CFG_CLKTRIM_0 */
-       0x2d4,  /* CFG_CLKTRIM_1 */
-       0x2d8,  /* CFG_CLKTRIM_2 */
-};
-
-/* Select the closest EMC rate that is higher than the requested rate */
-long tegra_emc_round_rate(unsigned long rate)
-{
-       struct tegra_emc_pdata *pdata;
-       int i;
-       int best = -1;
-       unsigned long distance = ULONG_MAX;
-
-       if (!emc_pdev)
-               return -EINVAL;
-
-       pdata = emc_pdev->dev.platform_data;
-
-       pr_debug("%s: %lu\n", __func__, rate);
-
-       /*
-        * The EMC clock rate is twice the bus rate, and the bus rate is
-        * measured in kHz
-        */
-       rate = rate / 2 / 1000;
-
-       for (i = 0; i < pdata->num_tables; i++) {
-               if (pdata->tables[i].rate >= rate &&
-                   (pdata->tables[i].rate - rate) < distance) {
-                       distance = pdata->tables[i].rate - rate;
-                       best = i;
-               }
-       }
-
-       if (best < 0)
-               return -EINVAL;
-
-       pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
-
-       return pdata->tables[best].rate * 2 * 1000;
-}
-
-/*
- * The EMC registers have shadow registers.  When the EMC clock is updated
- * in the clock controller, the shadow registers are copied to the active
- * registers, allowing glitchless memory bus frequency changes.
- * This function updates the shadow registers for a new clock frequency,
- * and relies on the clock lock on the emc clock to avoid races between
- * multiple frequency changes
- */
-int tegra_emc_set_rate(unsigned long rate)
-{
-       struct tegra_emc_pdata *pdata;
-       int i;
-       int j;
-
-       if (!emc_pdev)
-               return -EINVAL;
-
-       pdata = emc_pdev->dev.platform_data;
-
-       /*
-        * The EMC clock rate is twice the bus rate, and the bus rate is
-        * measured in kHz
-        */
-       rate = rate / 2 / 1000;
-
-       for (i = 0; i < pdata->num_tables; i++)
-               if (pdata->tables[i].rate == rate)
-                       break;
-
-       if (i >= pdata->num_tables)
-               return -EINVAL;
-
-       pr_debug("%s: setting to %lu\n", __func__, rate);
-
-       for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
-               emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
-
-       emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
-
-       return 0;
-}
-
-#ifdef CONFIG_OF
-static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
-{
-       struct device_node *iter;
-       u32 reg;
-
-       for_each_child_of_node(np, iter) {
-               if (of_property_read_u32(iter, "nvidia,ram-code", &reg))
-                       continue;
-               if (reg == tegra_bct_strapping)
-                       return of_node_get(iter);
-       }
-
-       return NULL;
-}
-
-static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
-               struct platform_device *pdev)
-{
-       struct device_node *np = pdev->dev.of_node;
-       struct device_node *tnp, *iter;
-       struct tegra_emc_pdata *pdata;
-       int ret, i, num_tables;
-
-       if (!np)
-               return NULL;
-
-       if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
-               tnp = tegra_emc_ramcode_devnode(np);
-               if (!tnp)
-                       dev_warn(&pdev->dev,
-                                "can't find emc table for ram-code 0x%02x\n",
-                                tegra_bct_strapping);
-       } else
-               tnp = of_node_get(np);
-
-       if (!tnp)
-               return NULL;
-
-       num_tables = 0;
-       for_each_child_of_node(tnp, iter)
-               if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
-                       num_tables++;
-
-       if (!num_tables) {
-               pdata = NULL;
-               goto out;
-       }
-
-       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-       pdata->tables = devm_kzalloc(&pdev->dev,
-                                    sizeof(*pdata->tables) * num_tables,
-                                    GFP_KERNEL);
-
-       i = 0;
-       for_each_child_of_node(tnp, iter) {
-               u32 prop;
-
-               ret = of_property_read_u32(iter, "clock-frequency", &prop);
-               if (ret) {
-                       dev_err(&pdev->dev, "no clock-frequency in %s\n",
-                               iter->full_name);
-                       continue;
-               }
-               pdata->tables[i].rate = prop;
-
-               ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
-                                                pdata->tables[i].regs,
-                                                TEGRA_EMC_NUM_REGS);
-               if (ret) {
-                       dev_err(&pdev->dev,
-                               "malformed emc-registers property in %s\n",
-                               iter->full_name);
-                       continue;
-               }
-
-               i++;
-       }
-       pdata->num_tables = i;
-
-out:
-       of_node_put(tnp);
-       return pdata;
-}
-#else
-static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
-               struct platform_device *pdev)
-{
-       return NULL;
-}
-#endif
-
-static struct tegra_emc_pdata *tegra_emc_fill_pdata(struct platform_device *pdev)
-{
-       struct clk *c = clk_get_sys(NULL, "emc");
-       struct tegra_emc_pdata *pdata;
-       unsigned long khz;
-       int i;
-
-       WARN_ON(pdev->dev.platform_data);
-       BUG_ON(IS_ERR(c));
-
-       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-       pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables),
-                                    GFP_KERNEL);
-
-       pdata->tables[0].rate = clk_get_rate(c) / 2 / 1000;
-
-       for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
-               pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
-
-       pdata->num_tables = 1;
-
-       khz = pdata->tables[0].rate;
-       dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, "
-                "%ld kHz mem\n", khz * 2, khz);
-
-       return pdata;
-}
-
-static int tegra_emc_probe(struct platform_device *pdev)
-{
-       struct tegra_emc_pdata *pdata;
-       struct resource *res;
-
-       if (!emc_enable) {
-               dev_err(&pdev->dev, "disabled per module parameter\n");
-               return -ENODEV;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       emc_regbase = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(emc_regbase))
-               return PTR_ERR(emc_regbase);
-
-       pdata = pdev->dev.platform_data;
-
-       if (!pdata)
-               pdata = tegra_emc_dt_parse_pdata(pdev);
-
-       if (!pdata)
-               pdata = tegra_emc_fill_pdata(pdev);
-
-       pdev->dev.platform_data = pdata;
-
-       emc_pdev = pdev;
-
-       return 0;
-}
-
-static struct of_device_id tegra_emc_of_match[] = {
-       { .compatible = "nvidia,tegra20-emc", },
-       { },
-};
-
-static struct platform_driver tegra_emc_driver = {
-       .driver         = {
-               .name   = "tegra-emc",
-               .owner  = THIS_MODULE,
-               .of_match_table = tegra_emc_of_match,
-       },
-       .probe          = tegra_emc_probe,
-};
-
-static int __init tegra_emc_init(void)
-{
-       return platform_driver_register(&tegra_emc_driver);
-}
-device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
deleted file mode 100644 (file)
index f61409b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc.
- *
- * Author:
- *     Colin Cross <ccross@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
-#define __MACH_TEGRA_TEGRA2_EMC_H
-
-int tegra_emc_set_rate(unsigned long rate);
-long tegra_emc_round_rate(unsigned long rate);
-
-#endif
index 8e23071bd1b34ff2a47f729c60721a6fa4a9ec5b..e3a96d7302e9adb402ff2f2e11f0a8bca6210bd6 100644 (file)
@@ -3,20 +3,14 @@ config ARCH_U300
        depends on MMU
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
-       select ARM_PATCH_PHYS_VIRT
        select ARM_VIC
        select CLKSRC_MMIO
-       select CLKSRC_OF
-       select COMMON_CLK
        select CPU_ARM926T
-       select GENERIC_CLOCKEVENTS
        select HAVE_TCM
        select PINCTRL
        select PINCTRL_COH901
        select PINCTRL_U300
-       select SPARSE_IRQ
        select MFD_SYSCON
-       select USE_OF
        help
          Support for ST-Ericsson U300 series mobile platforms.
 
index 0034d2cd69734e7cad97bf11cbc4976a3b9790c5..b41a42da150539b35a3a6c1b441511db15c5054f 100644 (file)
@@ -11,13 +11,8 @@ config ARCH_U8500
        select ARM_GIC
        select CACHE_L2X0
        select CLKSRC_NOMADIK_MTU
-       select COMMON_CLK
-       select CPU_V7
-       select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
-       select HAVE_SMP
-       select MIGHT_HAVE_CACHE_L2X0
        select PINCTRL
        select PINCTRL_ABX500
        select PINCTRL_NOMADIK
@@ -73,11 +68,6 @@ config UX500_AUTO_PLATFORM
          a working kernel. If everything else is disabled, this
          automatically enables MACH_MOP500.
 
-config MACH_UX500_DT
-       bool "Generic U8500 support using device tree"
-       depends on MACH_MOP500
-       select USE_OF
-
 endmenu
 
 config UX500_DEBUG_UART
index d05ba759da3015a1aa54bafc7dceaef190c2a212..de544aabf292589a4de22a4c44e71d1b68476520 100644 (file)
@@ -7,7 +7,6 @@ obj-$(CONFIG_CACHE_L2X0)        += cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o
 obj-$(CONFIG_MACH_MOP500)      += board-mop500-sdi.o \
                                board-mop500-regulators.o \
-                               board-mop500-pins.o \
                                board-mop500-audio.o
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
index 9309ad4cbd09596f215f86dfebe2d0ece9a7ca65..b2a0899e7453b29b083dab3790901294df405481 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/gpio.h>
 #include <linux/platform_data/dma-ste-dma40.h>
 
-#include "irqs.h"
 #include <linux/platform_data/asoc-ux500-msp.h>
 
 #include "ste-dma40-db8500.h"
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
deleted file mode 100644 (file)
index f63619b..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/bug.h>
-#include <linux/string.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinconf-generic.h>
-
-#include <asm/mach-types.h>
-
-#include "board-mop500.h"
-
-/* These simply sets bias for pins */
-#define BIAS(a,b) static unsigned long a[] = { b }
-
-BIAS(abx500_out_lo, PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0));
-BIAS(abx500_in_pd, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 1));
-BIAS(abx500_in_nopull, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0));
-
-#define AB8500_MUX_HOG(group, func) \
-       PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8500.0", group, func)
-#define AB8500_PIN_HOG(pin, conf) \
-       PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-ab8500.0", pin, abx500_##conf)
-
-#define AB8500_MUX_STATE(group, func, dev, state) \
-       PIN_MAP_MUX_GROUP(dev, state, "pinctrl-ab8500.0", group, func)
-#define AB8500_PIN_STATE(pin, conf, dev, state) \
-       PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8500.0", pin, abx500_##conf)
-
-#define AB8505_MUX_HOG(group, func) \
-       PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8505.0", group, func)
-#define AB8505_PIN_HOG(pin, conf) \
-       PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-ab8505.0", pin, abx500_##conf)
-
-#define AB8505_MUX_STATE(group, func, dev, state) \
-       PIN_MAP_MUX_GROUP(dev, state, "pinctrl-ab8505.0", group, func)
-#define AB8505_PIN_STATE(pin, conf, dev, state) \
-       PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8505.0", pin, abx500_##conf)
-
-static struct pinctrl_map __initdata ab8500_pinmap[] = {
-       /* Sysclkreq2 */
-       AB8500_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.35", PINCTRL_STATE_DEFAULT),
-       AB8500_PIN_STATE("GPIO1_T10", in_nopull, "regulator.35", PINCTRL_STATE_DEFAULT),
-       /* sysclkreq2 disable, mux in gpio configured in input pulldown */
-       AB8500_MUX_STATE("gpio1_a_1", "gpio", "regulator.35", PINCTRL_STATE_SLEEP),
-       AB8500_PIN_STATE("GPIO1_T10", in_pd, "regulator.35", PINCTRL_STATE_SLEEP),
-
-       /* pins 2 is muxed in GPIO, configured in INPUT PULL DOWN */
-       AB8500_MUX_HOG("gpio2_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO2_T9", in_pd),
-
-       /* Sysclkreq4 */
-       AB8500_MUX_STATE("sysclkreq4_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
-       AB8500_PIN_STATE("GPIO3_U9", in_nopull, "regulator.36", PINCTRL_STATE_DEFAULT),
-       /* sysclkreq4 disable, mux in gpio configured in input pulldown */
-       AB8500_MUX_STATE("gpio3_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
-       AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
-
-       /* pins 4 is muxed in GPIO, configured in INPUT PULL DOWN */
-       AB8500_MUX_HOG("gpio4_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO4_W2", in_pd),
-
-       /*
-        * pins 6,7,8 and 9 are muxed in YCBCR0123
-        * configured in INPUT PULL UP
-        */
-       AB8500_MUX_HOG("ycbcr0123_d_1", "ycbcr"),
-       AB8500_PIN_HOG("GPIO6_Y18", in_nopull),
-       AB8500_PIN_HOG("GPIO7_AA20", in_nopull),
-       AB8500_PIN_HOG("GPIO8_W18", in_nopull),
-       AB8500_PIN_HOG("GPIO9_AA19", in_nopull),
-
-       /*
-        * pins 10,11,12 and 13 are muxed in GPIO
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("gpio10_d_1", "gpio"),
-       AB8500_PIN_HOG("GPIO10_U17", in_pd),
-
-       AB8500_MUX_HOG("gpio11_d_1", "gpio"),
-       AB8500_PIN_HOG("GPIO11_AA18", in_pd),
-
-       AB8500_MUX_HOG("gpio12_d_1", "gpio"),
-       AB8500_PIN_HOG("GPIO12_U16", in_pd),
-
-       AB8500_MUX_HOG("gpio13_d_1", "gpio"),
-       AB8500_PIN_HOG("GPIO13_W17", in_pd),
-
-       /*
-        * pins 14,15 are muxed in PWM1 and PWM2
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("pwmout1_d_1", "pwmout"),
-       AB8500_PIN_HOG("GPIO14_F14", in_pd),
-
-       AB8500_MUX_HOG("pwmout2_d_1", "pwmout"),
-       AB8500_PIN_HOG("GPIO15_B17", in_pd),
-
-       /*
-        * pins 16 is muxed in GPIO
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("gpio16_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO14_F14", in_pd),
-
-       /*
-        * pins 17,18,19 and 20 are muxed in AUDIO interface 1
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("adi1_d_1", "adi1"),
-       AB8500_PIN_HOG("GPIO17_P5", in_pd),
-       AB8500_PIN_HOG("GPIO18_R5", in_pd),
-       AB8500_PIN_HOG("GPIO19_U5", in_pd),
-       AB8500_PIN_HOG("GPIO20_T5", in_pd),
-
-       /*
-        * pins 21,22 and 23 are muxed in USB UICC
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("usbuicc_d_1", "usbuicc"),
-       AB8500_PIN_HOG("GPIO21_H19", in_pd),
-       AB8500_PIN_HOG("GPIO22_G20", in_pd),
-       AB8500_PIN_HOG("GPIO23_G19", in_pd),
-
-       /*
-        * pins 24,25 are muxed in GPIO
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("gpio24_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO24_T14", in_pd),
-
-       AB8500_MUX_HOG("gpio25_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO25_R16", in_pd),
-
-       /*
-        * pins 26 is muxed in GPIO
-        * configured in OUTPUT LOW
-        */
-       AB8500_MUX_HOG("gpio26_d_1", "gpio"),
-       AB8500_PIN_HOG("GPIO26_M16", out_lo),
-
-       /*
-        * pins 27,28 are muxed in DMIC12
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("dmic12_d_1", "dmic"),
-       AB8500_PIN_HOG("GPIO27_J6", in_pd),
-       AB8500_PIN_HOG("GPIO28_K6", in_pd),
-
-       /*
-        * pins 29,30 are muxed in DMIC34
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("dmic34_d_1", "dmic"),
-       AB8500_PIN_HOG("GPIO29_G6", in_pd),
-       AB8500_PIN_HOG("GPIO30_H6", in_pd),
-
-       /*
-        * pins 31,32 are muxed in DMIC56
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("dmic56_d_1", "dmic"),
-       AB8500_PIN_HOG("GPIO31_F5", in_pd),
-       AB8500_PIN_HOG("GPIO32_G5", in_pd),
-
-       /*
-        * pins 34 is muxed in EXTCPENA
-        * configured INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("extcpena_d_1", "extcpena"),
-       AB8500_PIN_HOG("GPIO34_R17", in_pd),
-
-       /*
-        * pins 35 is muxed in GPIO
-        * configured in OUTPUT LOW
-        */
-       AB8500_MUX_HOG("gpio35_d_1", "gpio"),
-       AB8500_PIN_HOG("GPIO35_W15", in_pd),
-
-       /*
-        * pins 36,37,38 and 39 are muxed in GPIO
-        * configured in INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("gpio36_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO36_A17", in_pd),
-
-       AB8500_MUX_HOG("gpio37_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO37_E15", in_pd),
-
-       AB8500_MUX_HOG("gpio38_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO38_C17", in_pd),
-
-       AB8500_MUX_HOG("gpio39_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO39_E16", in_pd),
-
-       /*
-        * pins 40 and 41 are muxed in MODCSLSDA
-        * configured INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("modsclsda_d_1", "modsclsda"),
-       AB8500_PIN_HOG("GPIO40_T19", in_pd),
-       AB8500_PIN_HOG("GPIO41_U19", in_pd),
-
-       /*
-        * pins 42 is muxed in GPIO
-        * configured INPUT PULL DOWN
-        */
-       AB8500_MUX_HOG("gpio42_a_1", "gpio"),
-       AB8500_PIN_HOG("GPIO42_U2", in_pd),
-};
-
-static struct pinctrl_map __initdata ab8505_pinmap[] = {
-       /* Sysclkreq2 */
-       AB8505_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
-       AB8505_PIN_STATE("GPIO1_N4", in_nopull, "regulator.36", PINCTRL_STATE_DEFAULT),
-       /* sysclkreq2 disable, mux in gpio configured in input pulldown */
-       AB8505_MUX_STATE("gpio1_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
-       AB8505_PIN_STATE("GPIO1_N4", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
-
-       /* pins 2 is muxed in GPIO, configured in INPUT PULL DOWN */
-       AB8505_MUX_HOG("gpio2_a_1", "gpio"),
-       AB8505_PIN_HOG("GPIO2_R5", in_pd),
-
-       /* Sysclkreq4 */
-       AB8505_MUX_STATE("sysclkreq4_d_1", "sysclkreq", "regulator.37", PINCTRL_STATE_DEFAULT),
-       AB8505_PIN_STATE("GPIO3_P5", in_nopull, "regulator.37", PINCTRL_STATE_DEFAULT),
-       /* sysclkreq4 disable, mux in gpio configured in input pulldown */
-       AB8505_MUX_STATE("gpio3_a_1", "gpio", "regulator.37", PINCTRL_STATE_SLEEP),
-       AB8505_PIN_STATE("GPIO3_P5", in_pd, "regulator.37", PINCTRL_STATE_SLEEP),
-
-       AB8505_MUX_HOG("gpio10_d_1", "gpio"),
-       AB8505_PIN_HOG("GPIO10_B16", in_pd),
-
-       AB8505_MUX_HOG("gpio11_d_1", "gpio"),
-       AB8505_PIN_HOG("GPIO11_B17", in_pd),
-
-       AB8505_MUX_HOG("gpio13_d_1", "gpio"),
-       AB8505_PIN_HOG("GPIO13_D17", in_nopull),
-
-       AB8505_MUX_HOG("pwmout1_d_1", "pwmout"),
-       AB8505_PIN_HOG("GPIO14_C16", in_pd),
-
-       AB8505_MUX_HOG("adi2_d_1", "adi2"),
-       AB8505_PIN_HOG("GPIO17_P2", in_pd),
-       AB8505_PIN_HOG("GPIO18_N3", in_pd),
-       AB8505_PIN_HOG("GPIO19_T1", in_pd),
-       AB8505_PIN_HOG("GPIO20_P3", in_pd),
-
-       AB8505_MUX_HOG("gpio34_a_1", "gpio"),
-       AB8505_PIN_HOG("GPIO34_H14", in_pd),
-
-       AB8505_MUX_HOG("modsclsda_d_1", "modsclsda"),
-       AB8505_PIN_HOG("GPIO40_J15", in_pd),
-       AB8505_PIN_HOG("GPIO41_J14", in_pd),
-
-       AB8505_MUX_HOG("gpio50_d_1", "gpio"),
-       AB8505_PIN_HOG("GPIO50_L4", in_nopull),
-
-       AB8505_MUX_HOG("resethw_d_1", "resethw"),
-       AB8505_PIN_HOG("GPIO52_D16", in_pd),
-
-       AB8505_MUX_HOG("service_d_1", "service"),
-       AB8505_PIN_HOG("GPIO53_D15", in_pd),
-};
-
-void __init mop500_pinmaps_init(void)
-{
-       if (machine_is_u8520())
-               pinctrl_register_mappings(ab8505_pinmap,
-                                         ARRAY_SIZE(ab8505_pinmap));
-       else
-               pinctrl_register_mappings(ab8500_pinmap,
-                                         ARRAY_SIZE(ab8500_pinmap));
-}
-
-void __init snowball_pinmaps_init(void)
-{
-       pinctrl_register_mappings(ab8500_pinmap,
-                                 ARRAY_SIZE(ab8500_pinmap));
-}
-
-void __init hrefv60_pinmaps_init(void)
-{
-       pinctrl_register_mappings(ab8500_pinmap,
-                                 ARRAY_SIZE(ab8500_pinmap));
-}
index d48e8662c6763eb8a45bfd72752ab7509e0e9a5a..32cc0d8d8a0ed6576ebbc88a11081cc87d875086 100644 (file)
@@ -7,78 +7,9 @@
 #ifndef __BOARD_MOP500_H
 #define __BOARD_MOP500_H
 
-/* For NOMADIK_NR_GPIO */
-#include "irqs.h"
 #include <linux/platform_data/asoc-ux500-msp.h>
 #include <linux/amba/mmci.h>
 
-/* Snowball specific GPIO assignments, this board has no GPIO expander */
-#define SNOWBALL_ACCEL_INT1_GPIO       163
-#define SNOWBALL_ACCEL_INT2_GPIO       164
-#define SNOWBALL_MAGNET_DRDY_GPIO      165
-#define SNOWBALL_SDMMC_EN_GPIO         217
-#define SNOWBALL_SDMMC_1V8_3V_GPIO     228
-#define SNOWBALL_SDMMC_CD_GPIO         218
-
-/* HREFv60-specific GPIO assignments, this board has no GPIO expander */
-#define HREFV60_SDMMC_1V8_3V_GPIO      5
-#define HREFV60_CAMERA_FLASH_ENABLE    21
-#define HREFV60_MAGNET_DRDY_GPIO       32
-#define HREFV60_DISP1_RST_GPIO         65
-#define HREFV60_DISP2_RST_GPIO         66
-#define HREFV60_ACCEL_INT1_GPIO                82
-#define HREFV60_ACCEL_INT2_GPIO                83
-#define HREFV60_SDMMC_CD_GPIO          95
-#define HREFV60_XSHUTDOWN_SECONDARY_SENSOR 140
-#define HREFV60_TOUCH_RST_GPIO         143
-#define HREFV60_HAL_SW_GPIO            145
-#define HREFV60_SDMMC_EN_GPIO          169
-#define HREFV60_MMIO_XENON_CHARGE      170
-#define HREFV60_PROX_SENSE_GPIO                217
-
-/* MOP500 generic GPIOs */
-#define CAMERA_FLASH_INT_PIN           7
-#define CYPRESS_TOUCH_INT_PIN          84
-#define XSHUTDOWN_PRIMARY_SENSOR       141
-#define XSHUTDOWN_SECONDARY_SENSOR     142
-#define CYPRESS_TOUCH_RST_GPIO         143
-#define MOP500_HDMI_RST_GPIO           196
-#define CYPRESS_SLAVE_SELECT_GPIO      216
-
-/* GPIOs on the TC35892 expander */
-#define MOP500_EGPIO(x)                        (NOMADIK_NR_GPIO + (x))
-#define GPIO_MAGNET_DRDY               MOP500_EGPIO(1)
-#define GPIO_SDMMC_CD                  MOP500_EGPIO(3)
-#define GPIO_CAMERA_FLASH_ENABLE       MOP500_EGPIO(4)
-#define GPIO_MMIO_XENON_CHARGE         MOP500_EGPIO(5)
-#define GPIO_PROX_SENSOR               MOP500_EGPIO(7)
-#define GPIO_HAL_SENSOR                        MOP500_EGPIO(8)
-#define GPIO_ACCEL_INT1                        MOP500_EGPIO(10)
-#define GPIO_ACCEL_INT2                        MOP500_EGPIO(11)
-#define GPIO_BU21013_CS                        MOP500_EGPIO(13)
-#define MOP500_DISP2_RST_GPIO          MOP500_EGPIO(14)
-#define MOP500_DISP1_RST_GPIO          MOP500_EGPIO(15)
-#define GPIO_SDMMC_EN                  MOP500_EGPIO(17)
-#define GPIO_SDMMC_1V8_3V_SEL          MOP500_EGPIO(18)
-#define MOP500_EGPIO_END               MOP500_EGPIO(24)
-
-/*
- * GPIOs on the AB8500 mixed-signals circuit
- * Notice that we subtract 1 from the number passed into the macro, this is
- * because the AB8500 GPIO pins are enumbered starting from 1, so the value in
- * parens matches the GPIO pin number in the data sheet.
- */
-#define MOP500_AB8500_PIN_GPIO(x)      (MOP500_EGPIO_END + (x) - 1)
-/*Snowball AB8500 GPIO */
-#define SNOWBALL_VSMPS2_1V8_GPIO       MOP500_AB8500_PIN_GPIO(1)       /* SYSCLKREQ2/GPIO1 */
-#define SNOWBALL_PM_GPIO1_GPIO         MOP500_AB8500_PIN_GPIO(2)       /* SYSCLKREQ3/GPIO2 */
-#define SNOWBALL_WLAN_CLK_REQ_GPIO     MOP500_AB8500_PIN_GPIO(3)       /* SYSCLKREQ4/GPIO3 */
-#define SNOWBALL_PM_GPIO4_GPIO         MOP500_AB8500_PIN_GPIO(4)       /* SYSCLKREQ6/GPIO4 */
-#define SNOWBALL_EN_3V6_GPIO           MOP500_AB8500_PIN_GPIO(16)      /* PWMOUT3/GPIO16 */
-#define SNOWBALL_PME_ETH_GPIO          MOP500_AB8500_PIN_GPIO(24)      /* SYSCLKREQ7/GPIO24 */
-#define SNOWBALL_EN_3V3_ETH_GPIO       MOP500_AB8500_PIN_GPIO(26)      /* GPIO26 */
-
-struct device;
 extern struct mmci_platform_data mop500_sdi0_data;
 extern struct mmci_platform_data mop500_sdi1_data;
 extern struct mmci_platform_data mop500_sdi2_data;
@@ -88,8 +19,4 @@ extern struct msp_i2s_platform_data msp1_platform_data;
 extern struct msp_i2s_platform_data msp2_platform_data;
 extern struct msp_i2s_platform_data msp3_platform_data;
 
-void __init mop500_pinmaps_init(void);
-void __init snowball_pinmaps_init(void);
-void __init hrefv60_pinmaps_init(void);
-
 #endif
index bc8a6183560dbd0bb3021b61d2b68a83cd20a566..8820f602fcd2c59eba2d44075e0085da87a55855 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/mach/map.h>
 
 #include "setup.h"
-#include "irqs.h"
 
 #include "board-mop500-regulators.h"
 #include "board-mop500.h"
 #include "id.h"
 
 struct ab8500_platform_data ab8500_platdata = {
-       .irq_base       = MOP500_AB8500_IRQ_BASE,
        .regulator      = &ab8500_regulator_plat_data,
 };
 
 struct prcmu_pdata db8500_prcmu_pdata = {
        .ab_platdata    = &ab8500_platdata,
-       .ab_irq         = IRQ_DB8500_AB8500,
-       .irq_base       = IRQ_PRCMU_BASE,
        .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET,
        .legacy_offset  = DB8500_PRCMU_LEGACY_OFFSET,
 };
@@ -146,7 +142,6 @@ static struct device * __init db8500_soc_device_init(void)
        return ux500_soc_device_init(soc_id);
 }
 
-#ifdef CONFIG_MACH_UX500_DT
 static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
        /* Requires call-back bindings. */
        OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
@@ -191,16 +186,6 @@ static void __init u8500_init_machine(void)
 {
        struct device *parent = db8500_soc_device_init();
 
-       /* Pinmaps must be in place before devices register */
-       if (of_machine_is_compatible("st-ericsson,mop500"))
-               mop500_pinmaps_init();
-       else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
-               snowball_pinmaps_init();
-       } else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
-               hrefv60_pinmaps_init();
-       else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
-               /* TODO: Add pinmaps for ccu9540 board. */
-
        /* automatically probe child nodes of dbx5x0 devices */
        if (of_machine_is_compatible("st-ericsson,u8540"))
                of_platform_populate(NULL, u8500_local_bus_nodes,
@@ -229,5 +214,3 @@ DT_MACHINE_START(U8500_DT, "ST-Ericsson Ux5x0 platform (Device Tree Support)")
        .dt_compat      = stericsson_dt_platform_compat,
        .restart        = ux500_restart,
 MACHINE_END
-
-#endif
index d11ac4bf336cb7352ac34ee079fc560a800e036e..db16b5a04ad5c773f63c58ed422059c3c885f5ff 100644 (file)
@@ -52,17 +52,7 @@ void ux500_restart(enum reboot_mode mode, const char *cmd)
 */
 void __init ux500_init_irq(void)
 {
-       void __iomem *dist_base;
-       void __iomem *cpu_base;
-
        gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND;
-
-       if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
-               dist_base = __io_address(U8500_GIC_DIST_BASE);
-               cpu_base = __io_address(U8500_GIC_CPU_BASE);
-       } else
-               ux500_unknown_soc();
-
        irqchip_init();
 
        /*
diff --git a/arch/arm/mach-ux500/irqs-board-mop500.h b/arch/arm/mach-ux500/irqs-board-mop500.h
deleted file mode 100644 (file)
index d526dd8..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Rabin Vincent <rabin.vincent@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef __MACH_IRQS_BOARD_MOP500_H
-#define __MACH_IRQS_BOARD_MOP500_H
-
-/* Number of AB8500 irqs is taken from header file */
-#include <linux/mfd/abx500/ab8500.h>
-
-#define MOP500_AB8500_IRQ_BASE         IRQ_BOARD_START
-#define MOP500_AB8500_IRQ_END          (MOP500_AB8500_IRQ_BASE \
-                                        + AB8500_MAX_NR_IRQS)
-
-/* TC35892 */
-#define TC35892_NR_INTERNAL_IRQS       8
-#define TC35892_INT_GPIO(x)            (TC35892_NR_INTERNAL_IRQS + (x))
-#define TC35892_NR_GPIOS               24
-#define TC35892_NR_IRQS                        TC35892_INT_GPIO(TC35892_NR_GPIOS)
-
-#define MOP500_EGPIO_NR_IRQS           TC35892_NR_IRQS
-
-#define MOP500_EGPIO_IRQ_BASE          MOP500_AB8500_IRQ_END
-#define MOP500_EGPIO_IRQ_END           (MOP500_EGPIO_IRQ_BASE \
-                                        + MOP500_EGPIO_NR_IRQS)
-/* STMPE1601 irqs */
-#define STMPE_NR_INTERNAL_IRQS          9
-#define STMPE_INT_GPIO(x)               (STMPE_NR_INTERNAL_IRQS + (x))
-#define STMPE_NR_GPIOS                  24
-#define STMPE_NR_IRQS                   STMPE_INT_GPIO(STMPE_NR_GPIOS)
-
-#define MOP500_STMPE1601_IRQBASE        MOP500_EGPIO_IRQ_END
-#define MOP500_STMPE1601_IRQ(x)         (MOP500_STMPE1601_IRQBASE + (x))
-
-#define MOP500_STMPE1601_IRQ_END       \
-       MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
-
-#define MOP500_NR_IRQS         MOP500_STMPE1601_IRQ_END
-
-#define MOP500_IRQ_END         MOP500_NR_IRQS
-
-/*
- * We may have several boards, but only one will run at a
- * time, so the one with most IRQs will bump this ahead,
- * but the IRQ_BOARD_START remains the same for either board.
- */
-#if MOP500_IRQ_END > IRQ_BOARD_END
-#undef IRQ_BOARD_END
-#define IRQ_BOARD_END  MOP500_IRQ_END
-#endif
-
-#endif
diff --git a/arch/arm/mach-ux500/irqs-db8500.h b/arch/arm/mach-ux500/irqs-db8500.h
deleted file mode 100644 (file)
index f3a9d59..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Rabin Vincent <rabin.vincent@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef __MACH_IRQS_DB8500_H
-#define __MACH_IRQS_DB8500_H
-
-#define IRQ_DB8500_MTU0                        (IRQ_SHPI_START + 4)
-#define IRQ_DB8500_SPI2                        (IRQ_SHPI_START + 6)
-#define IRQ_DB8500_PMU                 (IRQ_SHPI_START + 7)
-#define IRQ_DB8500_SPI0                        (IRQ_SHPI_START + 8)
-#define IRQ_DB8500_RTT                 (IRQ_SHPI_START + 9)
-#define IRQ_DB8500_PKA                 (IRQ_SHPI_START + 10)
-#define IRQ_DB8500_UART0               (IRQ_SHPI_START + 11)
-#define IRQ_DB8500_I2C3                        (IRQ_SHPI_START + 12)
-#define IRQ_DB8500_L2CC                        (IRQ_SHPI_START + 13)
-#define IRQ_DB8500_SSP0                        (IRQ_SHPI_START + 14)
-#define IRQ_DB8500_CRYP1               (IRQ_SHPI_START + 15)
-#define IRQ_DB8500_MSP1_RX             (IRQ_SHPI_START + 16)
-#define IRQ_DB8500_MTU1                        (IRQ_SHPI_START + 17)
-#define IRQ_DB8500_RTC                 (IRQ_SHPI_START + 18)
-#define IRQ_DB8500_UART1               (IRQ_SHPI_START + 19)
-#define IRQ_DB8500_USB_WAKEUP          (IRQ_SHPI_START + 20)
-#define IRQ_DB8500_I2C0                        (IRQ_SHPI_START + 21)
-#define IRQ_DB8500_I2C1                        (IRQ_SHPI_START + 22)
-#define IRQ_DB8500_USBOTG              (IRQ_SHPI_START + 23)
-#define IRQ_DB8500_DMA_SECURE          (IRQ_SHPI_START + 24)
-#define IRQ_DB8500_DMA                 (IRQ_SHPI_START + 25)
-#define IRQ_DB8500_UART2               (IRQ_SHPI_START + 26)
-#define IRQ_DB8500_ICN_PMU1            (IRQ_SHPI_START + 27)
-#define IRQ_DB8500_ICN_PMU2            (IRQ_SHPI_START + 28)
-#define IRQ_DB8500_HSIR_EXCEP          (IRQ_SHPI_START + 29)
-#define IRQ_DB8500_MSP0                        (IRQ_SHPI_START + 31)
-#define IRQ_DB8500_HSIR_CH0_OVRRUN     (IRQ_SHPI_START + 32)
-#define IRQ_DB8500_HSIR_CH1_OVRRUN     (IRQ_SHPI_START + 33)
-#define IRQ_DB8500_HSIR_CH2_OVRRUN     (IRQ_SHPI_START + 34)
-#define IRQ_DB8500_HSIR_CH3_OVRRUN     (IRQ_SHPI_START + 35)
-#define IRQ_DB8500_HSIR_CH4_OVRRUN     (IRQ_SHPI_START + 36)
-#define IRQ_DB8500_HSIR_CH5_OVRRUN     (IRQ_SHPI_START + 37)
-#define IRQ_DB8500_HSIR_CH6_OVRRUN     (IRQ_SHPI_START + 38)
-#define IRQ_DB8500_HSIR_CH7_OVRRUN     (IRQ_SHPI_START + 39)
-#define IRQ_DB8500_AB8500              (IRQ_SHPI_START + 40)
-#define IRQ_DB8500_SDMMC2              (IRQ_SHPI_START + 41)
-#define IRQ_DB8500_SIA                 (IRQ_SHPI_START + 42)
-#define IRQ_DB8500_SIA2                        (IRQ_SHPI_START + 43)
-#define IRQ_DB8500_SVA                 (IRQ_SHPI_START + 44)
-#define IRQ_DB8500_SVA2                        (IRQ_SHPI_START + 45)
-#define IRQ_DB8500_PRCMU0              (IRQ_SHPI_START + 46)
-#define IRQ_DB8500_PRCMU1              (IRQ_SHPI_START + 47)
-#define IRQ_DB8500_DISP                        (IRQ_SHPI_START + 48)
-#define IRQ_DB8500_SPI3                        (IRQ_SHPI_START + 49)
-#define IRQ_DB8500_SDMMC1              (IRQ_SHPI_START + 50)
-#define IRQ_DB8500_I2C4                        (IRQ_SHPI_START + 51)
-#define IRQ_DB8500_SSP1                        (IRQ_SHPI_START + 52)
-#define IRQ_DB8500_SKE                 (IRQ_SHPI_START + 53)
-#define IRQ_DB8500_KB                  (IRQ_SHPI_START + 54)
-#define IRQ_DB8500_I2C2                        (IRQ_SHPI_START + 55)
-#define IRQ_DB8500_B2R2                        (IRQ_SHPI_START + 56)
-#define IRQ_DB8500_CRYP0               (IRQ_SHPI_START + 57)
-#define IRQ_DB8500_SDMMC3              (IRQ_SHPI_START + 59)
-#define IRQ_DB8500_SDMMC0              (IRQ_SHPI_START + 60)
-#define IRQ_DB8500_HSEM                        (IRQ_SHPI_START + 61)
-#define IRQ_DB8500_MSP1                        (IRQ_SHPI_START + 62)
-#define IRQ_DB8500_SBAG                        (IRQ_SHPI_START + 63)
-#define IRQ_DB8500_SPI1                        (IRQ_SHPI_START + 96)
-#define IRQ_DB8500_SRPTIMER            (IRQ_SHPI_START + 97)
-#define IRQ_DB8500_MSP2                        (IRQ_SHPI_START + 98)
-#define IRQ_DB8500_SDMMC4              (IRQ_SHPI_START + 99)
-#define IRQ_DB8500_SDMMC5              (IRQ_SHPI_START + 100)
-#define IRQ_DB8500_HSIRD0              (IRQ_SHPI_START + 104)
-#define IRQ_DB8500_HSIRD1              (IRQ_SHPI_START + 105)
-#define IRQ_DB8500_HSITD0              (IRQ_SHPI_START + 106)
-#define IRQ_DB8500_HSITD1              (IRQ_SHPI_START + 107)
-#define IRQ_DB8500_CTI0                        (IRQ_SHPI_START + 108)
-#define IRQ_DB8500_CTI1                        (IRQ_SHPI_START + 109)
-#define IRQ_DB8500_ICN_ERR             (IRQ_SHPI_START + 110)
-#define IRQ_DB8500_MALI_PPMMU          (IRQ_SHPI_START + 112)
-#define IRQ_DB8500_MALI_PP             (IRQ_SHPI_START + 113)
-#define IRQ_DB8500_MALI_GPMMU          (IRQ_SHPI_START + 114)
-#define IRQ_DB8500_MALI_GP             (IRQ_SHPI_START + 115)
-#define IRQ_DB8500_MALI                        (IRQ_SHPI_START + 116)
-#define IRQ_DB8500_PRCMU_SEM           (IRQ_SHPI_START + 118)
-#define IRQ_DB8500_GPIO0               (IRQ_SHPI_START + 119)
-#define IRQ_DB8500_GPIO1               (IRQ_SHPI_START + 120)
-#define IRQ_DB8500_GPIO2               (IRQ_SHPI_START + 121)
-#define IRQ_DB8500_GPIO3               (IRQ_SHPI_START + 122)
-#define IRQ_DB8500_GPIO4               (IRQ_SHPI_START + 123)
-#define IRQ_DB8500_GPIO5               (IRQ_SHPI_START + 124)
-#define IRQ_DB8500_GPIO6               (IRQ_SHPI_START + 125)
-#define IRQ_DB8500_GPIO7               (IRQ_SHPI_START + 126)
-#define IRQ_DB8500_GPIO8               (IRQ_SHPI_START + 127)
-
-#define IRQ_CA_WAKE_REQ_ED                     (IRQ_SHPI_START + 71)
-#define IRQ_AC_READ_NOTIFICATION_0_ED          (IRQ_SHPI_START + 66)
-#define IRQ_AC_READ_NOTIFICATION_1_ED          (IRQ_SHPI_START + 64)
-#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED      (IRQ_SHPI_START + 67)
-#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED      (IRQ_SHPI_START + 65)
-
-#define IRQ_CA_WAKE_REQ_V1                     (IRQ_SHPI_START + 83)
-#define IRQ_AC_READ_NOTIFICATION_0_V1          (IRQ_SHPI_START + 78)
-#define IRQ_AC_READ_NOTIFICATION_1_V1          (IRQ_SHPI_START + 76)
-#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1      (IRQ_SHPI_START + 79)
-#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1      (IRQ_SHPI_START + 77)
-
-#ifdef CONFIG_UX500_SOC_DB8500
-
-/* Virtual interrupts corresponding to the PRCMU wakeups.  */
-#define IRQ_PRCMU_BASE IRQ_SOC_START
-#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
-
-/*
- * We may have several SoCs, but only one will run at a
- * time, so the one with most IRQs will bump this ahead,
- * but the IRQ_SOC_START remains the same for either SoC.
- */
-#if IRQ_SOC_END < IRQ_PRCMU_END
-#undef IRQ_SOC_END
-#define IRQ_SOC_END IRQ_PRCMU_END
-#endif
-
-#endif /* CONFIG_UX500_SOC_DB8500 */
-#endif
diff --git a/arch/arm/mach-ux500/irqs.h b/arch/arm/mach-ux500/irqs.h
deleted file mode 100644 (file)
index 15b2af6..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Copyright (C) 2008 STMicroelectronics
- *  Copyright (C) 2009 ST-Ericsson.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef ASM_ARCH_IRQS_H
-#define ASM_ARCH_IRQS_H
-
-#define IRQ_LOCALTIMER                 29
-#define IRQ_LOCALWDOG                  30
-
-/* Shared Peripheral Interrupt (SHPI) */
-#define IRQ_SHPI_START                 32
-
-/*
- * MTU0 preserved for now until plat-nomadik is taught not to use it.  Don't
- * add any other IRQs here, use the irqs-dbx500.h files.
- */
-#define IRQ_MTU0               (IRQ_SHPI_START + 4)
-
-#define DBX500_NR_INTERNAL_IRQS                166
-
-/* After chip-specific IRQ numbers we have the GPIO ones */
-#define NOMADIK_NR_GPIO                        288
-#define NOMADIK_GPIO_TO_IRQ(gpio)      ((gpio) + DBX500_NR_INTERNAL_IRQS)
-#define NOMADIK_IRQ_TO_GPIO(irq)       ((irq) - DBX500_NR_INTERNAL_IRQS)
-#define IRQ_GPIO_END                   NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
-
-#define IRQ_SOC_START          IRQ_GPIO_END
-/* This will be overridden by SoC-specific irq headers */
-#define IRQ_SOC_END            IRQ_SOC_START
-
-#include "irqs-db8500.h"
-
-#define IRQ_BOARD_START                IRQ_SOC_END
-/* This will be overridden by board-specific irq headers */
-#define IRQ_BOARD_END          IRQ_BOARD_START
-
-#ifdef CONFIG_MACH_MOP500
-#include "irqs-board-mop500.h"
-#endif
-
-#define UX500_NR_IRQS          IRQ_BOARD_END
-
-#endif /* ASM_ARCH_IRQS_H */
index a335126ae18f3abc248d1373c2e39659a53431a9..f2c89fb8fca9d6bf6d2324404b45fad1869288f8 100644 (file)
@@ -108,7 +108,7 @@ void __init versatile_init_irq(void)
 
        np = of_find_matching_node_by_address(NULL, vic_of_match,
                                              VERSATILE_VIC_BASE);
-       __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np);
+       __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np);
 
        writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
diff --git a/arch/arm/mach-versatile/include/mach/timex.h b/arch/arm/mach-versatile/include/mach/timex.h
deleted file mode 100644 (file)
index 426199b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  arch/arm/mach-versatile/include/mach/timex.h
- *
- *  Versatile architecture timex specifications
- *
- *  Copyright (C) 2003 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define CLOCK_TICK_RATE                (50000000 / 16)
index 4a70be485ff8fe68fd96a9544ac73117d0f27857..80b4be36f10a22bd69840c99e241eabdb756809a 100644 (file)
@@ -5,16 +5,11 @@ config ARCH_VEXPRESS
        select ARM_AMBA
        select ARM_GIC
        select ARM_TIMER_SP804
-       select COMMON_CLK
        select COMMON_CLK_VERSATILE
-       select CPU_V7
-       select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select HAVE_PATA_PLATFORM
-       select HAVE_SMP
        select ICST
-       select MIGHT_HAVE_CACHE_L2X0
        select NO_IOPORT
        select PLAT_VERSATILE
        select PLAT_VERSATILE_CLCD
index 0997e0b7494c31bcbad551441c074d5bf9bc9873..fc649bc09d0c4a04cd60202406b863fe6ebf2bd8 100644 (file)
@@ -8,8 +8,11 @@ obj-y                                  := v2m.o
 obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)      += ct-ca9x4.o
 obj-$(CONFIG_ARCH_VEXPRESS_DCSCB)      += dcscb.o      dcscb_setup.o
 CFLAGS_dcscb.o                         += -march=armv7-a
+CFLAGS_REMOVE_dcscb.o                  = -pg
 obj-$(CONFIG_ARCH_VEXPRESS_SPC)                += spc.o
+CFLAGS_REMOVE_spc.o                    = -pg
 obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM)     += tc2_pm.o
 CFLAGS_tc2_pm.o                                += -march=armv7-a
+CFLAGS_REMOVE_tc2_pm.o                 = -pg
 obj-$(CONFIG_SMP)                      += platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
diff --git a/arch/arm/mach-virt/Kconfig b/arch/arm/mach-virt/Kconfig
deleted file mode 100644 (file)
index 081d469..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-config ARCH_VIRT
-       bool "Dummy Virtual Machine" if ARCH_MULTI_V7
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       select ARM_GIC
-       select HAVE_ARM_ARCH_TIMER
-       select ARM_PSCI
-       select HAVE_SMP
-       select CPU_V7
-       select SPARSE_IRQ
-       select USE_OF
diff --git a/arch/arm/mach-virt/Makefile b/arch/arm/mach-virt/Makefile
deleted file mode 100644 (file)
index 7ddbfa6..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-obj-y                                  := virt.o
diff --git a/arch/arm/mach-virt/virt.c b/arch/arm/mach-virt/virt.c
deleted file mode 100644 (file)
index b184e57..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Dummy Virtual Machine - does what it says on the tin.
- *
- * Copyright (C) 2012 ARM Ltd
- * Authors: Will Deacon <will.deacon@arm.com>,
- *          Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-#include <linux/smp.h>
-
-#include <asm/mach/arch.h>
-
-static void __init virt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *virt_dt_match[] = {
-       "linux,dummy-virt",
-       "xen,xenvm",
-       NULL
-};
-
-DT_MACHINE_START(VIRT, "Dummy Virtual Machine")
-       .init_machine   = virt_init,
-       .dt_compat      = virt_dt_match,
-MACHINE_END
index 927be93b692ec37fff6e5944649d1237c25617d8..08f56a41cb553145f72390c64f76cdb39a1ddd15 100644 (file)
@@ -3,8 +3,6 @@ config ARCH_VT8500
        select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select CLKDEV_LOOKUP
-       select CLKSRC_OF
-       select GENERIC_CLOCKEVENTS
        select VT8500_TIMER
        select PINCTRL
        help
@@ -21,7 +19,6 @@ config ARCH_WM8750
        bool "WonderMedia WM8750"
        depends on ARCH_MULTI_V6
        select ARCH_VT8500
-       select CPU_V6
        help
          Support for WonderMedia WM8750 System-on-Chip.
 
@@ -29,6 +26,5 @@ config ARCH_WM8850
        bool "WonderMedia WM8850"
        depends on ARCH_MULTI_V7
        select ARCH_VT8500
-       select CPU_V7
        help
          Support for WonderMedia WM8850 System-on-Chip.
diff --git a/arch/arm/mach-w90x900/include/mach/timex.h b/arch/arm/mach-w90x900/include/mach/timex.h
deleted file mode 100644 (file)
index 164dce0..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/timex.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/timex.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE Now, I don't use it. */
-
-#define CLOCK_TICK_RATE 15000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
index 30fbca8445759aed5cef7350f91b4c8881e1da05..9230d3725599c0baeb6bd9e3b46f3b5b29b0bcfe 100644 (file)
@@ -111,7 +111,7 @@ static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id)
 
 static struct irqaction nuc900_timer0_irq = {
        .name           = "nuc900-timer0",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = nuc900_timer0_interrupt,
 };
 
index f03e75bd0b2b232f9afdfbbd4ea30e5da95a0adf..58c2b844e0a3c99cac20e1219d48d1685391fe69 100644 (file)
@@ -4,17 +4,11 @@ config ARCH_ZYNQ
        select ARM_GIC
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
-       select COMMON_CLK
-       select CPU_V7
-       select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select ICST
-       select MIGHT_HAVE_CACHE_L2X0
-       select USE_OF
-       select HAVE_SMP
-       select SPARSE_IRQ
        select CADENCE_TTC_TIMER
        select ARM_GLOBAL_TIMER if !CPU_FREQ
+       select MFD_SYSCON
        help
          Support for Xilinx Zynq ARM Cortex A9 Platform
index a39be8e8085607c49156af97a4ba46462e0dac26..6fcc584c1a110fb1986ee9ddbb0ae99bfbf907a4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/cpumask.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/clk/zynq.h>
 #include <linux/clocksource.h>
 #include <linux/of_address.h>
@@ -75,11 +76,16 @@ static void __init zynq_init_machine(void)
 
        platform_device_register(&zynq_cpuidle_device);
        platform_device_register_full(&devinfo);
+
+       zynq_slcr_init();
 }
 
 static void __init zynq_timer_init(void)
 {
-       zynq_slcr_init();
+       zynq_early_slcr_init();
+
+       zynq_clock_init();
+       of_clk_init(NULL);
        clocksource_of_init();
 }
 
index c22c92cea8cb47e1baba978c93d99b6e8d5ab244..b097844d3175ad7ac8204cfd3dcfd3362e88c265 100644 (file)
@@ -20,6 +20,7 @@
 void zynq_secondary_startup(void);
 
 extern int zynq_slcr_init(void);
+extern int zynq_early_slcr_init(void);
 extern void zynq_slcr_system_reset(void);
 extern void zynq_slcr_cpu_stop(int cpu);
 extern void zynq_slcr_cpu_start(int cpu);
@@ -33,7 +34,6 @@ extern int zynq_cpun_start(u32 address, int cpu);
 extern struct smp_operations zynq_smp_ops __initdata;
 #endif
 
-extern void __iomem *zynq_slcr_base;
 extern void __iomem *zynq_scu_base;
 
 /* Hotplug */
index 1836d5a34606a6a252057e5d060f9f14583c2715..a37d49a6e6578cddf922f45cb8a87c6b306dae25 100644 (file)
@@ -15,7 +15,9 @@
  */
 
 #include <linux/io.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of_address.h>
+#include <linux/regmap.h>
 #include <linux/clk/zynq.h>
 #include "common.h"
 
 #define SLCR_A9_CPU_CLKSTOP            0x10
 #define SLCR_A9_CPU_RST                        0x1
 
-void __iomem *zynq_slcr_base;
+static void __iomem *zynq_slcr_base;
+static struct regmap *zynq_slcr_regmap;
+
+/**
+ * zynq_slcr_write - Write to a register in SLCR block
+ *
+ * @val:       Value to write to the register
+ * @offset:    Register offset in SLCR block
+ *
+ * Return:     a negative value on error, 0 on success
+ */
+static int zynq_slcr_write(u32 val, u32 offset)
+{
+       if (!zynq_slcr_regmap) {
+               writel(val, zynq_slcr_base + offset);
+               return 0;
+       }
+
+       return regmap_write(zynq_slcr_regmap, offset, val);
+}
+
+/**
+ * zynq_slcr_read - Read a register in SLCR block
+ *
+ * @val:       Pointer to value to be read from SLCR
+ * @offset:    Register offset in SLCR block
+ *
+ * Return:     a negative value on error, 0 on success
+ */
+static int zynq_slcr_read(u32 *val, u32 offset)
+{
+       if (zynq_slcr_regmap)
+               return regmap_read(zynq_slcr_regmap, offset, val);
+
+       *val = readl(zynq_slcr_base + offset);
+
+       return 0;
+}
+
+/**
+ * zynq_slcr_unlock - Unlock SLCR registers
+ *
+ * Return:     a negative value on error, 0 on success
+ */
+static inline int zynq_slcr_unlock(void)
+{
+       zynq_slcr_write(SLCR_UNLOCK_MAGIC, SLCR_UNLOCK_OFFSET);
+
+       return 0;
+}
 
 /**
  * zynq_slcr_system_reset - Reset the entire system.
@@ -43,16 +94,16 @@ void zynq_slcr_system_reset(void)
         * Note that this seems to require raw i/o
         * functions or there's a lockup?
         */
-       writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK_OFFSET);
+       zynq_slcr_unlock();
 
        /*
         * Clear 0x0F000000 bits of reboot status register to workaround
         * the FSBL not loading the bitstream after soft-reboot
         * This is a temporary solution until we know more.
         */
-       reboot = readl(zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET);
-       writel(reboot & 0xF0FFFFFF, zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET);
-       writel(1, zynq_slcr_base + SLCR_PS_RST_CTRL_OFFSET);
+       zynq_slcr_read(&reboot, SLCR_REBOOT_STATUS_OFFSET);
+       zynq_slcr_write(reboot & 0xF0FFFFFF, SLCR_REBOOT_STATUS_OFFSET);
+       zynq_slcr_write(1, SLCR_PS_RST_CTRL_OFFSET);
 }
 
 /**
@@ -61,11 +112,13 @@ void zynq_slcr_system_reset(void)
  */
 void zynq_slcr_cpu_start(int cpu)
 {
-       u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
+       u32 reg;
+
+       zynq_slcr_read(&reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
        reg &= ~(SLCR_A9_CPU_RST << cpu);
-       writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
+       zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
        reg &= ~(SLCR_A9_CPU_CLKSTOP << cpu);
-       writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
+       zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
 }
 
 /**
@@ -74,18 +127,39 @@ void zynq_slcr_cpu_start(int cpu)
  */
 void zynq_slcr_cpu_stop(int cpu)
 {
-       u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
+       u32 reg;
+
+       zynq_slcr_read(&reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
        reg |= (SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu;
-       writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET);
+       zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET);
 }
 
 /**
- * zynq_slcr_init
- * Returns 0 on success, negative errno otherwise.
+ * zynq_slcr_init - Regular slcr driver init
+ *
+ * Return:     0 on success, negative errno otherwise.
  *
  * Called early during boot from platform code to remap SLCR area.
  */
 int __init zynq_slcr_init(void)
+{
+       zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
+       if (IS_ERR(zynq_slcr_regmap)) {
+               pr_err("%s: failed to find zynq-slcr\n", __func__);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/**
+ * zynq_early_slcr_init - Early slcr init function
+ *
+ * Return:     0 on success, negative errno otherwise.
+ *
+ * Called very early during boot from platform code to unlock SLCR.
+ */
+int __init zynq_early_slcr_init(void)
 {
        struct device_node *np;
 
@@ -101,13 +175,13 @@ int __init zynq_slcr_init(void)
                BUG();
        }
 
+       np->data = (__force void *)zynq_slcr_base;
+
        /* unlock the SLCR so that registers can be changed */
-       writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK_OFFSET);
+       zynq_slcr_unlock();
 
        pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
 
-       zynq_clock_init(zynq_slcr_base);
-
        of_node_put(np);
 
        return 0;
index 1f8fed94c2a499939354258fc61339a10d229a4f..f5ad9ee70426b0f2a285cc463739a01173994875 100644 (file)
@@ -264,7 +264,7 @@ config CPU_ARM1026
 
 # SA110
 config CPU_SA110
-       bool "Support StrongARM(R) SA-110 processor" if ARCH_RPC
+       bool
        select CPU_32v3 if ARCH_RPC
        select CPU_32v4 if !ARCH_RPC
        select CPU_ABRT_EV4
@@ -446,7 +446,6 @@ config CPU_32v5
 
 config CPU_32v6
        bool
-       select CPU_USE_DOMAINS if CPU_V6 && MMU
        select TLS_REG_EMUL if !CPU_32v6K && !MMU
 
 config CPU_32v6K
@@ -671,7 +670,7 @@ config ARM_VIRT_EXT
 
 config SWP_EMULATE
        bool "Emulate SWP/SWPB instructions"
-       depends on !CPU_USE_DOMAINS && CPU_V7
+       depends on CPU_V7
        default y if SMP
        select HAVE_PROC_CPU if PROC_FS
        help
@@ -855,7 +854,7 @@ config OUTER_CACHE_SYNC
 
 config CACHE_FEROCEON_L2
        bool "Enable the Feroceon L2 cache controller"
-       depends on ARCH_KIRKWOOD || ARCH_MV78XX0
+       depends on ARCH_KIRKWOOD || ARCH_MV78XX0 || ARCH_MVEBU
        default y
        select OUTER_CACHE
        help
index 48bc3c0a87ce321cc2e37c257bf217dc085307e6..dc814a5480560372200a301cf93a22e8076d095c 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/highmem.h>
+#include <linux/io.h>
 #include <asm/cacheflush.h>
 #include <asm/cp15.h>
-#include <plat/cache-feroceon-l2.h>
+#include <asm/hardware/cache-feroceon-l2.h>
+
+#define L2_WRITETHROUGH_KIRKWOOD       BIT(4)
 
 /*
  * Low-level cache maintenance operations.
@@ -331,7 +336,9 @@ static void __init enable_l2(void)
                        enable_icache();
                if (d)
                        enable_dcache();
-       }
+       } else
+               pr_err(FW_BUG
+                      "Feroceon L2: bootloader left the L2 cache on!\n");
 }
 
 void __init feroceon_l2_init(int __l2_wt_override)
@@ -350,3 +357,41 @@ void __init feroceon_l2_init(int __l2_wt_override)
        printk(KERN_INFO "Feroceon L2: Cache support initialised%s.\n",
                         l2_wt_override ? ", in WT override mode" : "");
 }
+#ifdef CONFIG_OF
+static const struct of_device_id feroceon_ids[] __initconst = {
+       { .compatible = "marvell,kirkwood-cache"},
+       { .compatible = "marvell,feroceon-cache"},
+       {}
+};
+
+int __init feroceon_of_init(void)
+{
+       struct device_node *node;
+       void __iomem *base;
+       bool l2_wt_override = false;
+       struct resource res;
+
+#if defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+       l2_wt_override = true;
+#endif
+
+       node = of_find_matching_node(NULL, feroceon_ids);
+       if (node && of_device_is_compatible(node, "marvell,kirkwood-cache")) {
+               if (of_address_to_resource(node, 0, &res))
+                       return -ENODEV;
+
+               base = ioremap(res.start, resource_size(&res));
+               if (!base)
+                       return -ENOMEM;
+
+               if (l2_wt_override)
+                       writel(readl(base) | L2_WRITETHROUGH_KIRKWOOD, base);
+               else
+                       writel(readl(base) & ~L2_WRITETHROUGH_KIRKWOOD, base);
+       }
+
+       feroceon_l2_init(l2_wt_override);
+
+       return 0;
+}
+#endif
index 1be0f4e5e6eb7067b871d32d5eeb7af47954c42e..b273739e63597a747ca8dc96abb99022a529db56 100644 (file)
@@ -33,7 +33,7 @@
  * outer cache operations into the kernel image if the kernel has been
  * configured to support a pre-v7 CPU.
  */
-#if __LINUX_ARM_ARCH__ < 7
+#ifdef CONFIG_CPU_32v5
 /*
  * Low-level cache maintenance operations.
  */
@@ -229,33 +229,6 @@ static void __init tauros2_internal_init(unsigned int features)
        }
 #endif
 
-#ifdef CONFIG_CPU_32v6
-       /*
-        * Check whether this CPU lacks support for the v7 hierarchical
-        * cache ops.  (PJ4 is in its v6 personality mode if the MMFR3
-        * register indicates no support for the v7 hierarchical cache
-        * ops.)
-        */
-       if (cpuid_scheme() && (read_mmfr3() & 0xf) == 0) {
-               /*
-                * When Tauros2 is used in an ARMv6 system, the L2
-                * enable bit is in the ARMv6 ARM-mandated position
-                * (bit [26] of the System Control Register).
-                */
-               if (!(get_cr() & 0x04000000)) {
-                       printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
-                       adjust_cr(0x04000000, 0x04000000);
-               }
-
-               mode = "ARMv6";
-               outer_cache.inv_range = tauros2_inv_range;
-               outer_cache.clean_range = tauros2_clean_range;
-               outer_cache.flush_range = tauros2_flush_range;
-               outer_cache.disable = tauros2_disable;
-               outer_cache.resume = tauros2_resume;
-       }
-#endif
-
 #ifdef CONFIG_CPU_32v7
        /*
         * Check whether this CPU has support for the v7 hierarchical
index 4fe42ce720d2cd8066ab79319db431fdd65ba014..f62aa0677e5c4b69918d1ab36e39fada230d3d59 100644 (file)
@@ -284,9 +284,6 @@ static void __dma_free_buffer(struct page *page, size_t size)
 }
 
 #ifdef CONFIG_MMU
-#ifdef CONFIG_HUGETLB_PAGE
-#warning ARM Coherent DMA allocator does not (yet) support huge TLB
-#endif
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
                                     pgprot_t prot, struct page **ret_page,
index a623cb3ad012b196aacd11fc7f122fb84c0e3765..b68c6b22e1c80f263d46555064b1c1c13f48586c 100644 (file)
@@ -515,6 +515,16 @@ static void __init build_mem_type_table(void)
        hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte;
        s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
 
+       /*
+        * We don't use domains on ARMv6 (since this causes problems with
+        * v6/v7 kernels), so we must use a separate memory type for user
+        * r/o, kernel r/w to map the vectors page.
+        */
+#ifndef CONFIG_ARM_LPAE
+       if (cpu_arch == CPU_ARCH_ARMv6)
+               vecs_pgprot |= L_PTE_MT_VECTORS;
+#endif
+
        /*
         * ARMv6 and above have extended page tables.
         */
index e3c48a3fe0638177f980ead520a2190f089128f2..ee1d80593958715340ce2743b3d0b2370c227848 100644 (file)
  *  100x   1   0   1   r/o     no acc
  *  10x0   1   0   1   r/o     no acc
  *  1011   0   0   1   r/w     no acc
- *  110x   0   1   0   r/w     r/o
- *  11x0   0   1   0   r/w     r/o
- *  1111   0   1   1   r/w     r/w
- *
- * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
  *  110x   1   1   1   r/o     r/o
  *  11x0   1   1   1   r/o     r/o
+ *  1111   0   1   1   r/w     r/w
  */
        .macro  armv6_mt_table pfx
 \pfx\()_mt_table:
        .long   PTE_EXT_TEX(2)                                  @ L_PTE_MT_DEV_NONSHARED
        .long   0x00                                            @ unused
        .long   0x00                                            @ unused
-       .long   0x00                                            @ unused
+       .long   PTE_CACHEABLE | PTE_BUFFERABLE | PTE_EXT_APX    @ L_PTE_MT_VECTORS
        .endm
 
        .macro  armv6_set_pte_ext pfx
 
        tst     r1, #L_PTE_USER
        orrne   r3, r3, #PTE_EXT_AP1
-#ifdef CONFIG_CPU_USE_DOMAINS
-       @ allow kernel read/write access to read-only user pages
        tstne   r3, #PTE_EXT_APX
-       bicne   r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
-#endif
+
+       @ user read-only -> kernel read-only
+       bicne   r3, r3, #PTE_EXT_AP0
 
        tst     r1, #L_PTE_XN
        orrne   r3, r3, #PTE_EXT_XN
 
-       orr     r3, r3, r2
+       eor     r3, r3, r2
 
        tst     r1, #L_PTE_YOUNG
        tstne   r1, #L_PTE_PRESENT
        moveq   r3, #0
-#ifndef CONFIG_CPU_USE_DOMAINS
        tstne   r1, #L_PTE_NONE
        movne   r3, #0
-#endif
 
        str     r3, [r0]
        mcr     p15, 0, r0, c7, c10, 1          @ flush_pte
index bdd3be4be77aa50c93dcc20c8afdaa3af3c0cf5f..1f52915f2b28392e85d83830ada6af96f4a03988 100644 (file)
@@ -90,21 +90,14 @@ ENTRY(cpu_v7_set_pte_ext)
 
        tst     r1, #L_PTE_USER
        orrne   r3, r3, #PTE_EXT_AP1
-#ifdef CONFIG_CPU_USE_DOMAINS
-       @ allow kernel read/write access to read-only user pages
-       tstne   r3, #PTE_EXT_APX
-       bicne   r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
-#endif
 
        tst     r1, #L_PTE_XN
        orrne   r3, r3, #PTE_EXT_XN
 
        tst     r1, #L_PTE_YOUNG
        tstne   r1, #L_PTE_VALID
-#ifndef CONFIG_CPU_USE_DOMAINS
        eorne   r1, r1, #L_PTE_NONE
        tstne   r1, #L_PTE_NONE
-#endif
        moveq   r3, #0
 
  ARM(  str     r3, [r0, #2048]! )
index 74f6033e76dd1702e89631334a813f5ea9ec1046..195731d3813bb5c0ecba68c5c82ead71b4fbe532 100644 (file)
@@ -192,6 +192,7 @@ __v7_cr7mp_setup:
        mov     r10, #(1 << 0)                  @ Cache/TLB ops broadcasting
        b       1f
 __v7_ca7mp_setup:
+__v7_ca12mp_setup:
 __v7_ca15mp_setup:
        mov     r10, #0
 1:
@@ -483,6 +484,16 @@ __v7_ca7mp_proc_info:
        __v7_proc __v7_ca7mp_setup
        .size   __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
 
+       /*
+        * ARM Ltd. Cortex A12 processor.
+        */
+       .type   __v7_ca12mp_proc_info, #object
+__v7_ca12mp_proc_info:
+       .long   0x410fc0d0
+       .long   0xff0ffff0
+       __v7_proc __v7_ca12mp_setup
+       .size   __v7_ca12mp_proc_info, . - __v7_ca12mp_proc_info
+
        /*
         * ARM Ltd. Cortex A15 processor.
         */
index d70b73364a3fe8a549407f51c0f8f35e786360d7..6ad65d8ae237d50da129abbbd9c568d21ce4182d 100644 (file)
@@ -127,7 +127,7 @@ iop_timer_interrupt(int irq, void *dev_id)
 static struct irqaction iop_timer_irq = {
        .name           = "IOP Timer Tick",
        .handler        = iop_timer_interrupt,
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .dev_id         = &iop_clockevent,
 };
 
index 436ea97074cd7af31a4989d66d19c9dd8decfbbf..02fc10d2d63bc28e064d918ea04af3115568600e 100644 (file)
@@ -86,9 +86,6 @@ config OMAP_MUX_WARNINGS
          to change the pin multiplexing setup.  When there are no warnings
          printed, it's safe to deselect OMAP_MUX for your product.
 
-config OMAP_IOMMU_IVA2
-       bool
-
 config OMAP_MPU_TIMER
        bool "Use mpu timer"
        depends on ARCH_OMAP1
index 01619c2910e364271ab565f49c8644850b9fc70b..5f5b975887fc8424723d6566d687c82cf54328bc 100644 (file)
@@ -2000,6 +2000,12 @@ void omap_dma_global_context_restore(void)
                        omap_clear_dma(ch);
 }
 
+struct omap_system_dma_plat_info *omap_get_plat_info(void)
+{
+       return p;
+}
+EXPORT_SYMBOL_GPL(omap_get_plat_info);
+
 static int omap_system_dma_probe(struct platform_device *pdev)
 {
        int ch, ret = 0;
@@ -2024,9 +2030,16 @@ static int omap_system_dma_probe(struct platform_device *pdev)
 
        dma_lch_count           = d->lch_count;
        dma_chan_count          = dma_lch_count;
-       dma_chan                = d->chan;
        enable_1510_mode        = d->dev_caps & ENABLE_1510_MODE;
 
+       dma_chan = devm_kcalloc(&pdev->dev, dma_lch_count,
+                               sizeof(struct omap_dma_lch), GFP_KERNEL);
+       if (!dma_chan) {
+               dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
+               return -ENOMEM;
+       }
+
+
        if (dma_omap2plus()) {
                dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
                                                dma_lch_count, GFP_KERNEL);
@@ -2111,7 +2124,6 @@ exit_dma_irq_fail:
        }
 
 exit_dma_lch_fail:
-       kfree(dma_chan);
        return ret;
 }
 
@@ -2131,7 +2143,6 @@ static int omap_system_dma_remove(struct platform_device *pdev)
                        free_irq(dma_irq, (void *)(irq_rel + 1));
                }
        }
-       kfree(dma_chan);
        return 0;
 }
 
diff --git a/arch/arm/plat-omap/include/plat/timex.h b/arch/arm/plat-omap/include/plat/timex.h
deleted file mode 100644 (file)
index e27d2da..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/timex.h
- *
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author:  Greg Lonnon <glonnon@ridgerun.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
-#define __ASM_ARCH_OMAP_TIMEX_H
-
-#define CLOCK_TICK_RATE                (HZ * 100000UL)
-
-#endif /* __ASM_ARCH_OMAP_TIMEX_H */
index 830ff07f33856dfa886a3224fe352dab2bd336f5..3ec6e8e8d3683f4f76bf8aff68ccfb814441a9e3 100644 (file)
@@ -595,14 +595,16 @@ void __init orion_spi_1_init(unsigned long mapbase)
 /*****************************************************************************
  * Watchdog
  ****************************************************************************/
-static struct resource orion_wdt_resource =
-               DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x28);
+static struct resource orion_wdt_resource[] = {
+               DEFINE_RES_MEM(TIMER_PHYS_BASE, 0x04),
+               DEFINE_RES_MEM(RSTOUTn_MASK_PHYS, 0x04),
+};
 
 static struct platform_device orion_wdt_device = {
        .name           = "orion_wdt",
        .id             = -1,
-       .num_resources  = 1,
-       .resource       = &orion_wdt_resource,
+       .num_resources  = ARRAY_SIZE(orion_wdt_resource),
+       .resource       = orion_wdt_resource,
 };
 
 void __init orion_wdt_init(void)
diff --git a/arch/arm/plat-orion/include/plat/cache-feroceon-l2.h b/arch/arm/plat-orion/include/plat/cache-feroceon-l2.h
deleted file mode 100644 (file)
index 06f982d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * arch/arm/plat-orion/include/plat/cache-feroceon-l2.h
- *
- * Copyright (C) 2008 Marvell Semiconductor
- *
- * 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.
- */
-
-extern void __init feroceon_l2_init(int l2_wt_override);
index 58645a58d0d8823762aafa573ebc4dd9aba5f3cf..b57e922f161465eab5aa57dcfd27704c1d699598 100644 (file)
@@ -427,8 +427,7 @@ comment "Power management"
 
 config SAMSUNG_PM_DEBUG
        bool "S3C2410 PM Suspend debug"
-       depends on PM
-       select DEBUG_LL
+       depends on PM && DEBUG_KERNEL && DEBUG_S3C_UART
        help
          Say Y here if you want verbose debugging from the PM Suspend and
          Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
@@ -445,7 +444,8 @@ config S3C_PM_DEBUG_LED_SMDK
 
 config SAMSUNG_PM_CHECK
        bool "S3C2410 PM Suspend Memory CRC"
-       depends on PM && CRC32
+       depends on PM
+       select CRC32
        help
          Enable the PM code's memory area checksum over sleep. This option
          will generate CRCs of all blocks of memory, and store them before
index 9267d29549b47bd29c2ed6b76f98bd0c8180ce51..25c826ed3b65c6ce0afa2867eb748a1e4112dc1d 100644 (file)
@@ -47,9 +47,11 @@ obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
 
 # PM support
 
+obj-$(CONFIG_PM_SLEEP)         += pm-common.o
 obj-$(CONFIG_SAMSUNG_PM)       += pm.o
 obj-$(CONFIG_SAMSUNG_PM_GPIO)  += pm-gpio.o
 obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
+obj-$(CONFIG_SAMSUNG_PM_DEBUG) += pm-debug.o
 
 obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
 obj-$(CONFIG_SAMSUNG_WDT_RESET)        += watchdog-reset.o
index 47c9fad43f00124ce8e78e3f04b141f716034cd6..d103ac1a52af8541b43ac3d7fa65a8a91b85ea58 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/debugfs.h>
 #endif
 
-#include <mach/hardware.h>
 #include <asm/irq.h>
 
 #include <plat/cpu-freq.h>
@@ -52,7 +51,7 @@
 #include <plat/cpu.h>
 
 #include <linux/serial_core.h>
-#include <plat/regs-serial.h> /* for s3c24xx_uart_devs */
+#include <linux/serial_s3c.h> /* for s3c24xx_uart_devs */
 
 /* clock information */
 
index 46b426e8aff599636314f3d59bc364dd138e09b9..364963a0a34486ec92975888442650da491a7d9b 100644 (file)
@@ -28,13 +28,6 @@ unsigned int samsung_rev(void)
 }
 EXPORT_SYMBOL(samsung_rev);
 
-void __init s3c24xx_init_cpu(void)
-{
-       /* nothing here yet */
-
-       samsung_cpu_rev = 0;
-}
-
 void __init s3c64xx_init_cpu(void)
 {
        samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118);
index ac07e871f6a781594ffae471516527e7ea090941..ead4f1c94058e1ffff2f5a56a4e650510dc56ec8 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -30,6 +31,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mmc/host.h>
 #include <linux/ioport.h>
+#include <linux/sizes.h>
 #include <linux/platform_data/s3c-hsudc.h>
 #include <linux/platform_data/s3c-hsotg.h>
 #include <linux/platform_data/dma-s3c24xx.h>
@@ -41,7 +43,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/hardware.h>
 #include <mach/dma.h>
 #include <mach/irqs.h>
 #include <mach/map.h>
@@ -64,7 +65,6 @@
 #include <linux/platform_data/usb-s3c2410_udc.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
 #include <plat/usb-phy.h>
-#include <plat/regs-serial.h>
 #include <plat/regs-spi.h>
 #include <linux/platform_data/spi-s3c64xx.h>
 
@@ -744,10 +744,7 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)
        if (!pd) {
                pd = &default_i2c_data;
 
-               if (soc_is_exynos4210() ||
-                   soc_is_exynos4212() || soc_is_exynos4412())
-                       pd->bus_num = 8;
-               else if (soc_is_s5pv210())
+               if (soc_is_s5pv210())
                        pd->bus_num = 3;
                else
                        pd->bus_num = 0;
@@ -764,10 +761,7 @@ void __init s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info,
 {
        struct s5p_hdmi_platform_data *pd = &s5p_hdmi_def_platdata;
 
-       if (soc_is_exynos4210() ||
-           soc_is_exynos4212() || soc_is_exynos4412())
-               pd->hdmiphy_bus = 8;
-       else if (soc_is_s5pv210())
+       if (soc_is_s5pv210())
                pd->hdmiphy_bus = 3;
        else
                pd->hdmiphy_bus = 0;
index 335beb3413556637510b10ced41cc7f0a62f0b48..5992b8dd9b8982ded6c3c8c45b0d5de88792a326 100644 (file)
@@ -20,6 +20,9 @@
 
 extern unsigned long samsung_cpu_id;
 
+#define S3C2410_CPU_ID         0x32410000
+#define S3C2410_CPU_MASK       0xFFFFFFFF
+
 #define S3C24XX_CPU_ID         0x32400000
 #define S3C24XX_CPU_MASK       0xFFF00000
 
@@ -56,6 +59,7 @@ static inline int is_samsung_##name(void)     \
        return ((samsung_cpu_id & mask) == (id & mask));        \
 }
 
+IS_SAMSUNG_CPU(s3c2410, S3C2410_CPU_ID, S3C2410_CPU_MASK)
 IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
 IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK)
 IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
@@ -76,8 +80,10 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
     defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
     defined(CONFIG_CPU_S3C2443)
 # define soc_is_s3c24xx()      is_samsung_s3c24xx()
+# define soc_is_s3c2410()      is_samsung_s3c2410()
 #else
 # define soc_is_s3c24xx()      0
+# define soc_is_s3c2410()      0
 #endif
 
 #if defined(CONFIG_CPU_S3C2412)
@@ -160,6 +166,10 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
 # define soc_is_exynos5440()   0
 #endif
 
+#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4212() || \
+                         soc_is_exynos4412())
+#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5420())
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef KHZ
@@ -199,7 +209,6 @@ extern void s5p_init_irq(u32 *vic, u32 num_vic);
 
 extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
 
-extern void s3c24xx_init_cpu(void);
 extern void s3c64xx_init_cpu(void);
 extern void s5p_init_cpu(void __iomem *cpuid_addr);
 
index e6d7c42d68b637e58e20b0186b7326df8a2a279d..033654e91e220f431c95cc7aaf06bbbd247e3759 100644 (file)
@@ -32,7 +32,4 @@ struct s5p_mfc_dt_meminfo {
 void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
                                phys_addr_t lbase, unsigned int lsize);
 
-int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
-                               int depth, void *data);
-
 #endif /* __PLAT_SAMSUNG_MFC_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm-common.h b/arch/arm/plat-samsung/include/plat/pm-common.h
new file mode 100644 (file)
index 0000000..8705f9e
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *     Tomasz Figa <t.figa@samsung.com>
+ * Copyright (c) 2004 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_PM_COMMON_H
+#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__
+
+#include <linux/irq.h>
+
+/* sleep save info */
+
+/**
+ * struct sleep_save - save information for shared peripherals.
+ * @reg: Pointer to the register to save.
+ * @val: Holder for the value saved from reg.
+ *
+ * This describes a list of registers which is used by the pm core and
+ * other subsystem to save and restore register values over suspend.
+ */
+struct sleep_save {
+       void __iomem    *reg;
+       unsigned long   val;
+};
+
+#define SAVE_ITEM(x) \
+       { .reg = (x) }
+
+/* helper functions to save/restore lists of registers. */
+
+extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count);
+
+/* PM debug functions */
+
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+       u32     ulcon;
+       u32     ucon;
+       u32     ufcon;
+       u32     umcon;
+       u32     ubrdiv;
+       u32     udivslot;
+};
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+/**
+ * s3c_pm_dbg() - low level debug function for use in suspend/resume.
+ * @msg: The message to print.
+ *
+ * This function is used mainly to debug the resume process before the system
+ * can rely on printk/console output. It uses the low-level debugging output
+ * routine printascii() to do its work.
+ */
+extern void s3c_pm_dbg(const char *msg, ...);
+
+/**
+ * s3c_pm_debug_init() - suspend/resume low level debug initialization.
+ * @base: Virtual base of UART to use for suspend/resume debugging.
+ *
+ * This function needs to be called before S3C_PMDBG() can be used, to set up
+ * UART port base address and configuration.
+ */
+extern void s3c_pm_debug_init(void);
+
+#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
+
+extern void s3c_pm_save_uarts(void);
+extern void s3c_pm_restore_uarts(void);
+#else
+#define S3C_PMDBG(fmt...) pr_debug(fmt)
+#define s3c_pm_debug_init() do { } while (0)
+
+static inline void s3c_pm_save_uarts(void) { }
+static inline void s3c_pm_restore_uarts(void) { }
+#endif
+
+/* suspend memory checking */
+
+#ifdef CONFIG_SAMSUNG_PM_CHECK
+extern void s3c_pm_check_prepare(void);
+extern void s3c_pm_check_restore(void);
+extern void s3c_pm_check_cleanup(void);
+extern void s3c_pm_check_store(void);
+#else
+#define s3c_pm_check_prepare() do { } while (0)
+#define s3c_pm_check_restore() do { } while (0)
+#define s3c_pm_check_cleanup() do { } while (0)
+#define s3c_pm_check_store()   do { } while (0)
+#endif
+
+#endif
index ff6063f0d5eacb54e458ddd01b1585b7e5862e8c..e17d871b934cc36a5998312b448e8ff54ef80b7a 100644 (file)
@@ -15,7 +15,7 @@
  * management
 */
 
-#include <linux/irq.h>
+#include <plat/pm-common.h>
 
 struct device;
 
@@ -54,56 +54,10 @@ extern int (*pm_cpu_sleep)(unsigned long);
 
 extern unsigned long s3c_pm_flags;
 
-extern unsigned char pm_uart_udivslot;  /* true to save UART UDIVSLOT */
-
 /* from sleep.S */
 
 extern int s3c2410_cpu_suspend(unsigned long);
 
-/* sleep save info */
-
-/**
- * struct sleep_save - save information for shared peripherals.
- * @reg: Pointer to the register to save.
- * @val: Holder for the value saved from reg.
- *
- * This describes a list of registers which is used by the pm core and
- * other subsystem to save and restore register values over suspend.
- */
-struct sleep_save {
-       void __iomem    *reg;
-       unsigned long   val;
-};
-
-#define SAVE_ITEM(x) \
-       { .reg = (x) }
-
-/**
- * struct pm_uart_save - save block for core UART
- * @ulcon: Save value for S3C2410_ULCON
- * @ucon: Save value for S3C2410_UCON
- * @ufcon: Save value for S3C2410_UFCON
- * @umcon: Save value for S3C2410_UMCON
- * @ubrdiv: Save value for S3C2410_UBRDIV
- *
- * Save block for UART registers to be held over sleep and restored if they
- * are needed (say by debug).
-*/
-struct pm_uart_save {
-       u32     ulcon;
-       u32     ucon;
-       u32     ufcon;
-       u32     umcon;
-       u32     ubrdiv;
-       u32     udivslot;
-};
-
-/* helper functions to save/restore lists of registers. */
-
-extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
-extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count);
-extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count);
-
 #ifdef CONFIG_SAMSUNG_PM
 extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
 extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
@@ -114,24 +68,6 @@ extern void s3c_cpu_resume(void);
 #define s3c_cpu_resume NULL
 #endif
 
-/* PM debug functions */
-
-#ifdef CONFIG_SAMSUNG_PM_DEBUG
-/**
- * s3c_pm_dbg() - low level debug function for use in suspend/resume.
- * @msg: The message to print.
- *
- * This function is used mainly to debug the resume process before the system
- * can rely on printk/console output. It uses the low-level debugging output
- * routine printascii() to do its work.
- */
-extern void s3c_pm_dbg(const char *msg, ...);
-
-#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
-#else
-#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
-#endif
-
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
 /**
  * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
@@ -144,20 +80,6 @@ extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
 static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
 #endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
 
-/* suspend memory checking */
-
-#ifdef CONFIG_SAMSUNG_PM_CHECK
-extern void s3c_pm_check_prepare(void);
-extern void s3c_pm_check_restore(void);
-extern void s3c_pm_check_cleanup(void);
-extern void s3c_pm_check_store(void);
-#else
-#define s3c_pm_check_prepare() do { } while(0)
-#define s3c_pm_check_restore() do { } while(0)
-#define s3c_pm_check_cleanup() do { } while(0)
-#define s3c_pm_check_store()   do { } while(0)
-#endif
-
 /**
  * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
  *
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
deleted file mode 100644 (file)
index f05f2af..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <linux/serial_s3c.h>
diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h
deleted file mode 100644 (file)
index 7b542f7..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h
- *
- * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
- *
- * Samsung RTC Controller core functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_RTC_CORE_H
-#define __ASM_PLAT_RTC_CORE_H __FILE__
-
-/* These functions are only for use with the core support code, such as
- * the cpu specific initialisation code
- */
-
-/* re-define device name depending on support. */
-static inline void s3c_rtc_setname(char *name)
-{
-#if defined(CONFIG_S3C_DEV_RTC) || defined(CONFIG_PLAT_S3C24XX)
-       s3c_device_rtc.name = name;
-#endif
-}
-
-#endif /* __ASM_PLAT_RTC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h
deleted file mode 100644 (file)
index f48dc0a..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/uncompress.h
- *
- * Copyright 2003, 2007 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_UNCOMPRESS_H
-#define __ASM_PLAT_UNCOMPRESS_H
-
-typedef unsigned int upf_t;    /* cannot include linux/serial_core.h */
-
-/* uart setup */
-
-unsigned int fifo_mask;
-unsigned int fifo_max;
-
-volatile u8 *uart_base;
-
-/* forward declerations */
-
-static void arch_detect_cpu(void);
-
-/* defines for UART registers */
-
-#include <plat/regs-serial.h>
-
-/* working in physical space... */
-#define S3C_WDOGREG(x) ((S3C_PA_WDT + (x)))
-
-#define S3C2410_WTCON  S3C_WDOGREG(0x00)
-#define S3C2410_WTDAT  S3C_WDOGREG(0x04)
-#define S3C2410_WTCNT  S3C_WDOGREG(0x08)
-
-#define S3C2410_WTCON_RSTEN    (1 << 0)
-#define S3C2410_WTCON_ENABLE   (1 << 5)
-
-#define S3C2410_WTCON_DIV128   (3 << 3)
-
-#define S3C2410_WTCON_PRESCALE(x)      ((x) << 8)
-
-/* how many bytes we allow into the FIFO at a time in FIFO mode */
-#define FIFO_MAX        (14)
-
-static __inline__ void
-uart_wr(unsigned int reg, unsigned int val)
-{
-       volatile unsigned int *ptr;
-
-       ptr = (volatile unsigned int *)(reg + uart_base);
-       *ptr = val;
-}
-
-static __inline__ unsigned int
-uart_rd(unsigned int reg)
-{
-       volatile unsigned int *ptr;
-
-       ptr = (volatile unsigned int *)(reg + uart_base);
-       return *ptr;
-}
-
-/* we can deal with the case the UARTs are being run
- * in FIFO mode, so that we don't hold up our execution
- * waiting for tx to happen...
-*/
-
-static void putc(int ch)
-{
-       if (!config_enabled(CONFIG_DEBUG_LL))
-               return;
-
-       if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
-               int level;
-
-               while (1) {
-                       level = uart_rd(S3C2410_UFSTAT);
-                       level &= fifo_mask;
-
-                       if (level < fifo_max)
-                               break;
-               }
-
-       } else {
-               /* not using fifos */
-
-               while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
-                       barrier();
-       }
-
-       /* write byte to transmission register */
-       uart_wr(S3C2410_UTXH, ch);
-}
-
-static inline void flush(void)
-{
-}
-
-#define __raw_writel(d, ad)                    \
-       do {                                                    \
-               *((volatile unsigned int __force *)(ad)) = (d); \
-       } while (0)
-
-#ifdef CONFIG_S3C_BOOT_ERROR_RESET
-
-static void arch_decomp_error(const char *x)
-{
-       putstr("\n\n");
-       putstr(x);
-       putstr("\n\n -- System resetting\n");
-
-       __raw_writel(0x4000, S3C2410_WTDAT);
-       __raw_writel(0x4000, S3C2410_WTCNT);
-       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
-
-       while(1);
-}
-
-#define arch_error arch_decomp_error
-#endif
-
-#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
-static inline void arch_enable_uart_fifo(void)
-{
-       u32 fifocon;
-
-       if (!config_enabled(CONFIG_DEBUG_LL))
-               return;
-
-       fifocon = uart_rd(S3C2410_UFCON);
-
-       if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
-               fifocon |= S3C2410_UFCON_RESETBOTH;
-               uart_wr(S3C2410_UFCON, fifocon);
-
-               /* wait for fifo reset to complete */
-               while (1) {
-                       fifocon = uart_rd(S3C2410_UFCON);
-                       if (!(fifocon & S3C2410_UFCON_RESETBOTH))
-                               break;
-               }
-
-               uart_wr(S3C2410_UFCON, S3C2410_UFCON_FIFOMODE);
-       }
-}
-#else
-#define arch_enable_uart_fifo() do { } while(0)
-#endif
-
-
-static void
-arch_decomp_setup(void)
-{
-       /* we may need to setup the uart(s) here if we are not running
-        * on an BAST... the BAST will have left the uarts configured
-        * after calling linux.
-        */
-
-       arch_detect_cpu();
-
-       /* Enable the UART FIFOs if they where not enabled and our
-        * configuration says we should turn them on.
-        */
-
-       arch_enable_uart_fifo();
-}
-
-
-#endif /* __ASM_PLAT_UNCOMPRESS_H */
index aa9511b6914a40c92e1cb99c2b544740a8407c24..a1f925f3121f19fe5d14da8d5184b5423eb3d9b5 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 
-#include <mach/hardware.h>
-
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
@@ -33,8 +32,6 @@
 #include <plat/devs.h>
 #include <plat/clock.h>
 
-#include <plat/regs-serial.h>
-
 static struct cpu_table *cpu;
 
 static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
@@ -97,7 +94,9 @@ void __init s3c24xx_init_clocks(int xtal)
 #if IS_ENABLED(CONFIG_SAMSUNG_ATAGS)
 static int nr_uarts __initdata = 0;
 
+#ifdef CONFIG_SERIAL_SAMSUNG_UARTS
 static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
+#endif
 
 /* s3c24xx_init_uartdevs
  *
@@ -112,6 +111,7 @@ void __init s3c24xx_init_uartdevs(char *name,
                                  struct s3c24xx_uart_resources *res,
                                  struct s3c2410_uartcfg *cfg, int no)
 {
+#ifdef CONFIG_SERIAL_SAMSUNG_UARTS
        struct platform_device *platdev;
        struct s3c2410_uartcfg *cfgptr = uart_cfgs;
        struct s3c24xx_uart_resources *resp;
@@ -134,6 +134,7 @@ void __init s3c24xx_init_uartdevs(char *name,
        }
 
        nr_uarts = no;
+#endif
 }
 
 void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
index 3cbd62666b1ef291ba89b3d75a4795a1424cf6f0..04aff2c31b4607a99265d038d3ba0fd3b9a908b3 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 
-#include <plat/pm.h>
+#include <plat/pm-common.h>
 
 #if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1
 #error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value
diff --git a/arch/arm/plat-samsung/pm-common.c b/arch/arm/plat-samsung/pm-common.c
new file mode 100644 (file)
index 0000000..515cd53
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *     Tomasz Figa <t.figa@samsung.com>
+ * Copyright (C) 2008 Openmoko, Inc.
+ * Copyright (C) 2004-2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Samsung common power management helper functions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <plat/pm-common.h>
+
+/* helper functions to save and restore register state */
+
+/**
+ * s3c_pm_do_save() - save a set of registers for restoration on resume.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Run through the list of registers given, saving their contents in the
+ * array for later restoration when we wakeup.
+ */
+void s3c_pm_do_save(struct sleep_save *ptr, int count)
+{
+       for (; count > 0; count--, ptr++) {
+               ptr->val = __raw_readl(ptr->reg);
+               S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+       }
+}
+
+/**
+ * s3c_pm_do_restore() - restore register values from the save list.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Restore the register values saved from s3c_pm_do_save().
+ *
+ * Note, we do not use S3C_PMDBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+void s3c_pm_do_restore(const struct sleep_save *ptr, int count)
+{
+       for (; count > 0; count--, ptr++) {
+               pr_debug("restore %p (restore %08lx, was %08x)\n",
+                               ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+               __raw_writel(ptr->val, ptr->reg);
+       }
+}
+
+/**
+ * s3c_pm_do_restore_core() - early restore register values from save list.
+ *
+ * This is similar to s3c_pm_do_restore() except we try and minimise the
+ * side effects of the function in case registers that hardware might need
+ * to work has been restored.
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count)
+{
+       for (; count > 0; count--, ptr++)
+               __raw_writel(ptr->val, ptr->reg);
+}
diff --git a/arch/arm/plat-samsung/pm-debug.c b/arch/arm/plat-samsung/pm-debug.c
new file mode 100644 (file)
index 0000000..8f19f66
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *     Tomasz Figa <t.figa@samsung.com>
+ * Copyright (C) 2008 Openmoko, Inc.
+ * Copyright (C) 2004-2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Samsung common power management (suspend to RAM) debug support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/pm-common.h>
+
+#ifdef CONFIG_SAMSUNG_ATAGS
+#include <mach/pm-core.h>
+#else
+static inline void s3c_pm_debug_init_uart(void) {}
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+                                          struct pm_uart_save *save) {}
+#endif
+
+static struct pm_uart_save uart_save;
+
+extern void printascii(const char *);
+
+void s3c_pm_dbg(const char *fmt, ...)
+{
+       va_list va;
+       char buff[256];
+
+       va_start(va, fmt);
+       vsnprintf(buff, sizeof(buff), fmt, va);
+       va_end(va);
+
+       printascii(buff);
+}
+
+void s3c_pm_debug_init(void)
+{
+       /* restart uart clocks so we can use them to output */
+       s3c_pm_debug_init_uart();
+}
+
+static inline void __iomem *s3c_pm_uart_base(void)
+{
+       unsigned long paddr;
+       unsigned long vaddr;
+
+       debug_ll_addr(&paddr, &vaddr);
+
+       return (void __iomem *)vaddr;
+}
+
+void s3c_pm_save_uarts(void)
+{
+       void __iomem *regs = s3c_pm_uart_base();
+       struct pm_uart_save *save = &uart_save;
+
+       save->ulcon = __raw_readl(regs + S3C2410_ULCON);
+       save->ucon = __raw_readl(regs + S3C2410_UCON);
+       save->ufcon = __raw_readl(regs + S3C2410_UFCON);
+       save->umcon = __raw_readl(regs + S3C2410_UMCON);
+       save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+
+       if (!soc_is_s3c2410())
+               save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
+
+       S3C_PMDBG("UART[%p]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
+                 regs, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
+}
+
+void s3c_pm_restore_uarts(void)
+{
+       void __iomem *regs = s3c_pm_uart_base();
+       struct pm_uart_save *save = &uart_save;
+
+       s3c_pm_arch_update_uart(regs, save);
+
+       __raw_writel(save->ulcon, regs + S3C2410_ULCON);
+       __raw_writel(save->ucon,  regs + S3C2410_UCON);
+       __raw_writel(save->ufcon, regs + S3C2410_UFCON);
+       __raw_writel(save->umcon, regs + S3C2410_UMCON);
+       __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
+
+       if (!soc_is_s3c2410())
+               __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
+}
index dd4c15d0d68f821112a6f8d4a69e06668e61246d..da268813901bf21cdfdc1ee23c01a43ddcf574ff 100644 (file)
@@ -196,8 +196,7 @@ struct samsung_gpio_pm samsung_gpio_pm_2bit = {
        .resume = samsung_gpio_pm_2bit_resume,
 };
 
-#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) \
-       || defined(CONFIG_ARCH_EXYNOS)
+#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
 static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip)
 {
        chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
@@ -307,7 +306,7 @@ struct samsung_gpio_pm samsung_gpio_pm_4bit = {
        .save   = samsung_gpio_pm_4bit_save,
        .resume = samsung_gpio_pm_4bit_resume,
 };
-#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P || CONFIG_ARCH_EXYNOS */
+#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
 
 /**
  * samsung_pm_save_gpio() - save gpio chip data for suspend
index e5b0f2c2d8845d1573e935feada69e47273a23bd..f8c0f9797dcf4f0f5d041fa9c5a76895d13cf16e 100644 (file)
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/of.h>
-#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
 #include <asm/suspend.h>
 
-#include <plat/regs-serial.h>
-
 #ifdef CONFIG_SAMSUNG_ATAGS
-#include <mach/hardware.h>
 #include <mach/map.h>
 #ifndef CONFIG_ARCH_EXYNOS
 #include <mach/regs-clock.h>
 
 unsigned long s3c_pm_flags;
 
-/* Debug code:
- *
- * This code supports debug output to the low level UARTs for use on
- * resume before the console layer is available.
-*/
-
-#ifdef CONFIG_SAMSUNG_PM_DEBUG
-extern void printascii(const char *);
-
-void s3c_pm_dbg(const char *fmt, ...)
-{
-       va_list va;
-       char buff[256];
-
-       va_start(va, fmt);
-       vsnprintf(buff, sizeof(buff), fmt, va);
-       va_end(va);
-
-       printascii(buff);
-}
-
-static inline void s3c_pm_debug_init(void)
-{
-       /* restart uart clocks so we can use them to output */
-       s3c_pm_debug_init_uart();
-}
-
-#else
-#define s3c_pm_debug_init() do { } while(0)
-
-#endif /* CONFIG_SAMSUNG_PM_DEBUG */
-
-/* Save the UART configurations if we are configured for debug. */
-
-unsigned char pm_uart_udivslot;
-
-#ifdef CONFIG_SAMSUNG_PM_DEBUG
-
-static struct pm_uart_save uart_save;
-
-static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
-{
-       void __iomem *regs = S3C_VA_UARTx(uart);
-
-       save->ulcon = __raw_readl(regs + S3C2410_ULCON);
-       save->ucon = __raw_readl(regs + S3C2410_UCON);
-       save->ufcon = __raw_readl(regs + S3C2410_UFCON);
-       save->umcon = __raw_readl(regs + S3C2410_UMCON);
-       save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
-
-       if (pm_uart_udivslot)
-               save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
-
-       S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
-                 uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
-}
-
-static void s3c_pm_save_uarts(void)
-{
-       s3c_pm_save_uart(CONFIG_DEBUG_S3C_UART, &uart_save);
-}
-
-static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
-{
-       void __iomem *regs = S3C_VA_UARTx(uart);
-
-       s3c_pm_arch_update_uart(regs, save);
-
-       __raw_writel(save->ulcon, regs + S3C2410_ULCON);
-       __raw_writel(save->ucon,  regs + S3C2410_UCON);
-       __raw_writel(save->ufcon, regs + S3C2410_UFCON);
-       __raw_writel(save->umcon, regs + S3C2410_UMCON);
-       __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
-
-       if (pm_uart_udivslot)
-               __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
-}
-
-static void s3c_pm_restore_uarts(void)
-{
-       s3c_pm_restore_uart(CONFIG_DEBUG_S3C_UART, &uart_save);
-}
-#else
-static void s3c_pm_save_uarts(void) { }
-static void s3c_pm_restore_uarts(void) { }
-#endif
-
 /* The IRQ ext-int code goes here, it is too small to currently bother
  * with its own file. */
 
@@ -155,62 +65,6 @@ int s3c_irqext_wake(struct irq_data *data, unsigned int state)
        return 0;
 }
 
-/* helper functions to save and restore register state */
-
-/**
- * s3c_pm_do_save() - save a set of registers for restoration on resume.
- * @ptr: Pointer to an array of registers.
- * @count: Size of the ptr array.
- *
- * Run through the list of registers given, saving their contents in the
- * array for later restoration when we wakeup.
- */
-void s3c_pm_do_save(struct sleep_save *ptr, int count)
-{
-       for (; count > 0; count--, ptr++) {
-               ptr->val = __raw_readl(ptr->reg);
-               S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
-       }
-}
-
-/**
- * s3c_pm_do_restore() - restore register values from the save list.
- * @ptr: Pointer to an array of registers.
- * @count: Size of the ptr array.
- *
- * Restore the register values saved from s3c_pm_do_save().
- *
- * Note, we do not use S3C_PMDBG() in here, as the system may not have
- * restore the UARTs state yet
-*/
-
-void s3c_pm_do_restore(const struct sleep_save *ptr, int count)
-{
-       for (; count > 0; count--, ptr++) {
-               printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
-                      ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
-               __raw_writel(ptr->val, ptr->reg);
-       }
-}
-
-/**
- * s3c_pm_do_restore_core() - early restore register values from save list.
- *
- * This is similar to s3c_pm_do_restore() except we try and minimise the
- * side effects of the function in case registers that hardware might need
- * to work has been restored.
- *
- * WARNING: Do not put any debug in here that may effect memory or use
- * peripherals, as things may be changing!
-*/
-
-void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count)
-{
-       for (; count > 0; count--, ptr++)
-               __raw_writel(ptr->val, ptr->reg);
-}
-
 /* s3c2410_pm_show_resume_irqs
  *
  * print any IRQs asserted at resume time (ie, we woke from)
index ad51f85fbd018019b89e675927f75459553a6179..98087b655df0afd2a1d7307560bbf15759979092 100644 (file)
@@ -122,32 +122,35 @@ device_initcall(s5p_mfc_memory_init);
 #endif
 
 #ifdef CONFIG_OF
-int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
+int __init s5p_fdt_alloc_mfc_mem(unsigned long node, const char *uname,
                                int depth, void *data)
 {
        __be32 *prop;
        unsigned long len;
-       struct s5p_mfc_dt_meminfo *mfc_mem = data;
+       struct s5p_mfc_dt_meminfo mfc_mem;
 
        if (!data)
                return 0;
 
-       if (!of_flat_dt_is_compatible(node, mfc_mem->compatible))
+       if (!of_flat_dt_is_compatible(node, data))
                return 0;
 
        prop = of_get_flat_dt_prop(node, "samsung,mfc-l", &len);
        if (!prop || (len != 2 * sizeof(unsigned long)))
                return 0;
 
-       mfc_mem->loff = be32_to_cpu(prop[0]);
-       mfc_mem->lsize = be32_to_cpu(prop[1]);
+       mfc_mem.loff = be32_to_cpu(prop[0]);
+       mfc_mem.lsize = be32_to_cpu(prop[1]);
 
        prop = of_get_flat_dt_prop(node, "samsung,mfc-r", &len);
        if (!prop || (len != 2 * sizeof(unsigned long)))
                return 0;
 
-       mfc_mem->roff = be32_to_cpu(prop[0]);
-       mfc_mem->rsize = be32_to_cpu(prop[1]);
+       mfc_mem.roff = be32_to_cpu(prop[0]);
+       mfc_mem.rsize = be32_to_cpu(prop[1]);
+
+       s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize,
+                       mfc_mem.loff, mfc_mem.lsize);
 
        return 1;
 }
index cafa3deddcc1bf4900e5f8a573901d5a86fb4766..8c4487af98c89373ccfa77f639365cc88089e896 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
-#include <mach/hardware.h>
 #include <mach/map.h>
 
 #include <plat/devs.h>
index 591498035916d0ae91cd4b1d736d7b282908648a..52b16943617e27a6026e40fedbb25a40605ba110 100644 (file)
 #include <mach/map.h>
 
 #include <mach/regs-gpio.h>
-
-#ifndef CONFIG_ARCH_EXYNOS
 #include <mach/regs-irq.h>
-#endif
 
 /* state for IRQs over sleep */
 
@@ -43,18 +40,8 @@ int s3c_irq_wake(struct irq_data *data, unsigned int state)
        unsigned long irqbit;
        unsigned int irq_rtc_tic, irq_rtc_alarm;
 
-#ifdef CONFIG_ARCH_EXYNOS
-       if (soc_is_exynos5250()) {
-               irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC;
-               irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM;
-       } else {
-               irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC;
-               irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM;
-       }
-#else
        irq_rtc_tic = IRQ_RTC_TIC;
        irq_rtc_alarm = IRQ_RTC_ALARM;
-#endif
 
        if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) {
                irqbit = 1 << (data->irq + 1 - irq_rtc_alarm);
index a030e7301da86a3654fb16cb0f9412280e192594..c5001659bdf8659b92adb6a3d83c4e39ac04f3d1 100644 (file)
 
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
-#include <asm/hardware/cache-l2x0.h>
 
-#define CPU_MASK       0xff0ffff0
-#define CPU_CORTEX_A9  0x410fc090
-
-/*
- *      The following code is located into the .data section. This is to
- *      allow l2x0_regs_phys to be accessed with a relative load while we
- *      can't rely on any MMU translation. We could have put l2x0_regs_phys
- *      in the .text section as well, but some setups might insist on it to
- *      be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
- */
        .data
        .align
 
         */
 
 ENTRY(s3c_cpu_resume)
-#ifdef CONFIG_CACHE_L2X0
-       mrc     p15, 0, r0, c0, c0, 0
-       ldr     r1, =CPU_MASK
-       and     r0, r0, r1
-       ldr     r1, =CPU_CORTEX_A9
-       cmp     r0, r1
-       bne     resume_l2on
-       adr     r0, l2x0_regs_phys
-       ldr     r0, [r0]
-       ldr     r1, [r0, #L2X0_R_PHY_BASE]
-       ldr     r2, [r1, #L2X0_CTRL]
-       tst     r2, #0x1
-       bne     resume_l2on
-       ldr     r2, [r0, #L2X0_R_AUX_CTRL]
-       str     r2, [r1, #L2X0_AUX_CTRL]
-       ldr     r2, [r0, #L2X0_R_TAG_LATENCY]
-       str     r2, [r1, #L2X0_TAG_LATENCY_CTRL]
-       ldr     r2, [r0, #L2X0_R_DATA_LATENCY]
-       str     r2, [r1, #L2X0_DATA_LATENCY_CTRL]
-       ldr     r2, [r0, #L2X0_R_PREFETCH_CTRL]
-       str     r2, [r1, #L2X0_PREFETCH_CTRL]
-       ldr     r2, [r0, #L2X0_R_PWR_CTRL]
-       str     r2, [r1, #L2X0_POWER_CTRL]
-       mov     r2, #1
-       str     r2, [r1, #L2X0_CTRL]
-resume_l2on:
-#endif
        b       cpu_resume
 ENDPROC(s3c_cpu_resume)
-#ifdef CONFIG_CACHE_L2X0
-       .globl l2x0_regs_phys
-l2x0_regs_phys:
-       .long   0
-#endif
index 14ba23c6115367b962922e5decd3afabb59e789e..ed3955a95747286ebcb3f705c107dc1b3af90423 100644 (file)
@@ -154,13 +154,17 @@ static struct notifier_block os_lock_nb = {
 
 static int debug_monitors_init(void)
 {
+       cpu_notifier_register_begin();
+
        /* Clear the OS lock. */
        on_each_cpu(clear_os_lock, NULL, 1);
        isb();
        local_dbg_enable();
 
        /* Register hotplug handler. */
-       register_cpu_notifier(&os_lock_nb);
+       __register_cpu_notifier(&os_lock_nb);
+
+       cpu_notifier_register_done();
        return 0;
 }
 postcore_initcall(debug_monitors_init);
index f17f581116fc15762d7092f1fada45e06e3dd7d6..bee789757806a268864d6dc1fe8ac8a0ebb97fd7 100644 (file)
@@ -913,6 +913,8 @@ static int __init arch_hw_breakpoint_init(void)
        pr_info("found %d breakpoint and %d watchpoint registers.\n",
                core_num_brps, core_num_wrps);
 
+       cpu_notifier_register_begin();
+
        /*
         * Reset the breakpoint resources. We assume that a halting
         * debugger will leave the world in a nice state for us.
@@ -927,7 +929,10 @@ static int __init arch_hw_breakpoint_init(void)
                              TRAP_HWBKPT, "hw-watchpoint handler");
 
        /* Register hotplug notifier. */
-       register_cpu_notifier(&hw_breakpoint_reset_nb);
+       __register_cpu_notifier(&hw_breakpoint_reset_nb);
+
+       cpu_notifier_register_done();
+
        /* Register cpu_suspend hw breakpoint restore hook */
        cpu_suspend_set_dbg_restorer(hw_breakpoint_reset);
 
index 09df2608f40a9c3dc73220abf96e177b5ade447f..fbc5c78c9ac75de0eafdae726b8bc061c73afcce 100644 (file)
@@ -28,6 +28,7 @@ config HEXAGON
        select GENERIC_CLOCKEVENTS_BROADCAST
        select MODULES_USE_ELF_RELA
        select GENERIC_CPU_DEVICES
+       select HAVE_DMA_ATTRS
        ---help---
          Qualcomm Hexagon is a processor architecture designed for high
          performance and low power across a wide variety of applications.
index eadcc118f9506d8fbfddfd5b0dc7e65c6f3f9673..0e69796b58c763d83e5b5eb99ed19cdfb951b9eb 100644 (file)
@@ -41,6 +41,7 @@ generic-y += scatterlist.h
 generic-y += sections.h
 generic-y += segment.h
 generic-y += sembuf.h
+generic-y += serial.h
 generic-y += shmbuf.h
 generic-y += shmparam.h
 generic-y += siginfo.h
@@ -56,4 +57,5 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += ucontext.h
 generic-y += unaligned.h
+generic-y += vga.h
 generic-y += xor.h
index 7aae4cb2a29a217a82b3ac482bfe7a1ea079327a..17dc63780c0695ec36d958bd753820d5ae36797a 100644 (file)
 #include <asm/cmpxchg.h>
 
 #define ATOMIC_INIT(i)         { (i) }
-#define atomic_set(v, i)       ((v)->counter = (i))
+
+/*  Normal writes in our arch don't clear lock reservations  */
+
+static inline void atomic_set(atomic_t *v, int new)
+{
+       asm volatile(
+               "1:     r6 = memw_locked(%0);\n"
+               "       memw_locked(%0,p0) = %1;\n"
+               "       if (!P0) jump 1b;\n"
+               :
+               : "r" (&v->counter), "r" (new)
+               : "memory", "p0", "r6"
+       );
+}
 
 /**
  * atomic_read - reads a word, atomically
index 53079719d6678d4105437986a371f901966a4c39..8933b9b1a3bfd39dc092f7941f5d9d8f9b235f20 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/param.h>
 
+extern void __delay(unsigned long cycles);
 extern void __udelay(unsigned long usecs);
 
 #define udelay(usecs) __udelay((usecs))
index 85e9935660cbaf70626f61bda3e6a4a3f60cc0ef..16965427f6b4827d1b9807fe98248f80540e910b 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/cache.h>
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 #include <linux/dma-attrs.h>
 #include <asm/io.h>
index e1b933a0e121ee92c38d48d93044a431a8d33bd0..80311e7b8ca601c7352be572ad138cab19ed360c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ELF definitions for the Hexagon architecture
  *
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -202,7 +202,7 @@ do {                                        \
 #define CORE_DUMP_USE_REGSET
 
 /* Hrm is this going to cause problems for changing PAGE_SIZE?  */
-#define ELF_EXEC_PAGESIZE      4096
+#define ELF_EXEC_PAGESIZE      PAGE_SIZE
 
 /*
  * This is the location that an ET_DYN program is loaded if exec'ed.  Typical
index 67bb6d6f33372392635e617827ed44e82b3c5188..1f6918b428dec4a520d44a9ca88cbc3969604457 100644 (file)
 #ifndef __ASSEMBLY__
 
 enum VM_CACHE_OPS {
-       ickill,
-       dckill,
-       l2kill,
-       dccleaninva,
-       icinva,
-       idsync,
-       fetch_cfg
+       hvmc_ickill,
+       hvmc_dckill,
+       hvmc_l2kill,
+       hvmc_dccleaninva,
+       hvmc_icinva,
+       hvmc_idsync,
+       hvmc_fetch_cfg
 };
 
 enum VM_INT_OPS {
-       nop,
-       globen,
-       globdis,
-       locen,
-       locdis,
-       affinity,
-       get,
-       peek,
-       status,
-       post,
-       clear
+       hvmi_nop,
+       hvmi_globen,
+       hvmi_globdis,
+       hvmi_locen,
+       hvmi_locdis,
+       hvmi_affinity,
+       hvmi_get,
+       hvmi_peek,
+       hvmi_status,
+       hvmi_post,
+       hvmi_clear
 };
 
 extern void _K_VM_event_vector(void);
@@ -98,95 +98,95 @@ long __vmvpid(void);
 
 static inline long __vmcache_ickill(void)
 {
-       return __vmcache(ickill, 0, 0);
+       return __vmcache(hvmc_ickill, 0, 0);
 }
 
 static inline long __vmcache_dckill(void)
 {
-       return __vmcache(dckill, 0, 0);
+       return __vmcache(hvmc_dckill, 0, 0);
 }
 
 static inline long __vmcache_l2kill(void)
 {
-       return __vmcache(l2kill, 0, 0);
+       return __vmcache(hvmc_l2kill, 0, 0);
 }
 
 static inline long __vmcache_dccleaninva(unsigned long addr, unsigned long len)
 {
-       return __vmcache(dccleaninva, addr, len);
+       return __vmcache(hvmc_dccleaninva, addr, len);
 }
 
 static inline long __vmcache_icinva(unsigned long addr, unsigned long len)
 {
-       return __vmcache(icinva, addr, len);
+       return __vmcache(hvmc_icinva, addr, len);
 }
 
 static inline long __vmcache_idsync(unsigned long addr,
                                           unsigned long len)
 {
-       return __vmcache(idsync, addr, len);
+       return __vmcache(hvmc_idsync, addr, len);
 }
 
 static inline long __vmcache_fetch_cfg(unsigned long val)
 {
-       return __vmcache(fetch_cfg, val, 0);
+       return __vmcache(hvmc_fetch_cfg, val, 0);
 }
 
 /* interrupt operations  */
 
 static inline long __vmintop_nop(void)
 {
-       return __vmintop(nop, 0, 0, 0, 0);
+       return __vmintop(hvmi_nop, 0, 0, 0, 0);
 }
 
 static inline long __vmintop_globen(long i)
 {
-       return __vmintop(globen, i, 0, 0, 0);
+       return __vmintop(hvmi_globen, i, 0, 0, 0);
 }
 
 static inline long __vmintop_globdis(long i)
 {
-       return __vmintop(globdis, i, 0, 0, 0);
+       return __vmintop(hvmi_globdis, i, 0, 0, 0);
 }
 
 static inline long __vmintop_locen(long i)
 {
-       return __vmintop(locen, i, 0, 0, 0);
+       return __vmintop(hvmi_locen, i, 0, 0, 0);
 }
 
 static inline long __vmintop_locdis(long i)
 {
-       return __vmintop(locdis, i, 0, 0, 0);
+       return __vmintop(hvmi_locdis, i, 0, 0, 0);
 }
 
 static inline long __vmintop_affinity(long i, long cpu)
 {
-       return __vmintop(locdis, i, cpu, 0, 0);
+       return __vmintop(hvmi_affinity, i, cpu, 0, 0);
 }
 
 static inline long __vmintop_get(void)
 {
-       return __vmintop(get, 0, 0, 0, 0);
+       return __vmintop(hvmi_get, 0, 0, 0, 0);
 }
 
 static inline long __vmintop_peek(void)
 {
-       return __vmintop(peek, 0, 0, 0, 0);
+       return __vmintop(hvmi_peek, 0, 0, 0, 0);
 }
 
 static inline long __vmintop_status(long i)
 {
-       return __vmintop(status, i, 0, 0, 0);
+       return __vmintop(hvmi_status, i, 0, 0, 0);
 }
 
 static inline long __vmintop_post(long i)
 {
-       return __vmintop(post, i, 0, 0, 0);
+       return __vmintop(hvmi_post, i, 0, 0, 0);
 }
 
 static inline long __vmintop_clear(long i)
 {
-       return __vmintop(clear, i, 0, 0, 0);
+       return __vmintop(hvmi_clear, i, 0, 0, 0);
 }
 
 #else /* Only assembly code should reference these */
index 1b7698e19139000d235fbb1f71674b21b538aa48..70298996e9b2cbb69a4e05d863ce0c7fec6f90c2 100644 (file)
@@ -189,6 +189,8 @@ static inline void writel(u32 data, volatile void __iomem *addr)
 #define writew_relaxed __raw_writew
 #define writel_relaxed __raw_writel
 
+#define mmiowb()
+
 /*
  * Need an mtype somewhere in here, for cache type deals?
  * This is probably too long for an inline.
index 32a6fb66944a96e889a2b861d0f461b3a115d332..ccd3ac336b24387141ed446ce0c4302032a4b696 100644 (file)
@@ -34,10 +34,11 @@ static inline void arch_kgdb_breakpoint(void)
  * 32 gpr + sa0/1 + lc0/1 + m0/1 + gp + ugp + pred + pc = 42 total.
  * vm regs = psp+elr+est+badva = 4
  * syscall+restart = 2 more
- * so 48 = 42 +4 + 2
+ * also add cs0/1 = 2
+ * so 48 = 42 + 4 + 2 + 2
  */
 #define DBG_USER_REGS 42
-#define DBG_MAX_REG_NUM (DBG_USER_REGS + 6)
+#define DBG_MAX_REG_NUM (DBG_USER_REGS + 8)
 #define NUMREGBYTES  (DBG_MAX_REG_NUM*4)
 
 #endif /* __HEXAGON_KGDB_H__ */
index 4c9d382d7798e6640f52034f5e713a025a7bdab8..77da3b0ae3c2b2c37636f4f0e8dc3ee296e80268 100644 (file)
@@ -45,7 +45,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
         * map with a copy of the kernel's persistent map.
         */
 
-       memcpy(pgd, swapper_pg_dir, PTRS_PER_PGD*sizeof(pgd_t *));
+       memcpy(pgd, swapper_pg_dir, PTRS_PER_PGD*sizeof(pgd_t));
        mm->context.generation = kmap_generation;
 
        /* Physical version is what is passed to virtual machine on switch */
index 2b9b974e09522bcbaac7e0e4deac5935694d31e0..ca171c13891d2c3ec449726916fff899ae867586 100644 (file)
@@ -29,7 +29,6 @@ enum ipi_message_type {
        IPI_NOP = 0,
        IPI_RESCHEDULE = 1,
        IPI_CALL_FUNC,
-       IPI_CALL_FUNC_SINGLE,
        IPI_CPU_STOP,
        IPI_TIMER,
 };
index 487d6ceca5e7d407a69bd5c126c1f340bed10fb5..e7be31840a90330d2abc472eceece6e3d15926df 100644 (file)
@@ -6,8 +6,6 @@
 #ifndef _ASM_REGISTERS_H
 #define _ASM_REGISTERS_H
 
-#define SP r29
-
 #ifndef __ASSEMBLY__
 
 /*  See kernel/entry.S for further documentation.  */
@@ -215,7 +213,7 @@ struct pt_regs {
 #define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<<HVM_VMEST_SS_SFT))
 
 #define pt_set_rte_sp(regs, sp) do {\
-       pt_psp(regs) = (regs)->SP = (sp);\
+       pt_psp(regs) = (regs)->r29 = (sp);\
        } while (0)
 
 #define pt_set_kmode(regs) \
index e48285e4af967241e896e5940ea5bf013551b908..7e3952d6221cdf68ac4abf87275dc5d1b9496d2b 100644 (file)
 #ifndef _ASM_SETUP_H
 #define _ASM_SETUP_H
 
+#ifdef __KERNEL__
 #include <linux/init.h>
+#else
+#define __init
+#endif
+
 #include <asm-generic/setup.h>
 
 extern char external_cmdline_buffer;
index 29fc933a77225694b53f34770849b7d1b9d8cf99..009228b8611ca0483f221250d6c57c56ce341b87 100644 (file)
@@ -15,3 +15,5 @@ obj-y += vm_vectors.o
 obj-$(CONFIG_HAS_DMA) += dma.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
+
+obj-$(CONFIG_VGA_CONSOLE) += screen_info.o
index 32b1379d68772a7077929d6bb95f7ea09590458b..c041d8ecb1e2fd9f4b7b45035627968980488bde 100644 (file)
  * 02110-1301, USA.
  */
 
+#include <linux/dma-mapping.h>
 #include <asm/hexagon_vm.h>
+#include <asm/io.h>
 #include <asm/uaccess.h>
 
+/* Additional functions */
+EXPORT_SYMBOL(__clear_user_hexagon);
 EXPORT_SYMBOL(__copy_from_user_hexagon);
 EXPORT_SYMBOL(__copy_to_user_hexagon);
+EXPORT_SYMBOL(__iounmap);
+EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__vmgetie);
 EXPORT_SYMBOL(__vmsetie);
+EXPORT_SYMBOL(__vmyield);
+EXPORT_SYMBOL(empty_zero_page);
+EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
 
+/* Additional variables */
+EXPORT_SYMBOL(__phys_offset);
+EXPORT_SYMBOL(_dflt_cache_att);
+EXPORT_SYMBOL(bad_dma_address);
+
 #define DECLARE_EXPORT(name)     \
        extern void name(void); EXPORT_SYMBOL(name)
 
 /* Symbols found in libgcc that assorted kernel modules need */
 DECLARE_EXPORT(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes);
 
-DECLARE_EXPORT(__hexagon_divsi3);
-DECLARE_EXPORT(__hexagon_modsi3);
-DECLARE_EXPORT(__hexagon_udivsi3);
-DECLARE_EXPORT(__hexagon_umodsi3);
+/* Additional functions */
+DECLARE_EXPORT(__divsi3);
+DECLARE_EXPORT(__modsi3);
+DECLARE_EXPORT(__udivsi3);
+DECLARE_EXPORT(__umodsi3);
+DECLARE_EXPORT(csum_tcpudp_magic);
index 82d5c2593323ed420ac6b9af62309d85a032e355..038580cc5abfa09cbfbbe9c6eee3b6f81a15dc27 100644 (file)
@@ -18,6 +18,8 @@
  * 02110-1301, USA.
  */
 
+#include <linux/irq.h>
+#include <linux/sched.h>
 #include <linux/kdebug.h>
 #include <linux/kgdb.h>
 
index de829eb7f1858f948ac54c7fcbae0c8c91aa6e53..390a9ad14ca15fa9d08b90fe76115ed90ebfeb71 100644 (file)
@@ -183,6 +183,7 @@ static const struct user_regset_view hexagon_user_view = {
        .e_machine = ELF_ARCH,
        .ei_osabi = ELF_OSABI,
        .regsets = hexagon_regsets,
+       .e_flags = ELF_CORE_EFLAGS,
        .n = ARRAY_SIZE(hexagon_regsets)
 };
 
index 6aeabc962b3b41348ea84e55970d4b2db67cd25d..76483c10130d653e8ecc6c287ec1c56e33099e36 100644 (file)
@@ -33,6 +33,5 @@ void machine_restart(char *cmd)
 {
 }
 
-void pm_power_off(void)
-{
-}
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
diff --git a/arch/hexagon/kernel/screen_info.c b/arch/hexagon/kernel/screen_info.c
new file mode 100644 (file)
index 0000000..1e1ceb1
--- /dev/null
@@ -0,0 +1,3 @@
+#include <linux/screen_info.h>
+
+struct screen_info screen_info;
index 9faaa940452b98ad0f10ecd695af138133e990a6..ff759f26b96aef8cbffbfc9c860aa7f2966ff27b 100644 (file)
@@ -64,10 +64,6 @@ static inline void __handle_ipi(unsigned long *ops, struct ipi_data *ipi,
                        generic_smp_call_function_interrupt();
                        break;
 
-               case IPI_CALL_FUNC_SINGLE:
-                       generic_smp_call_function_single_interrupt();
-                       break;
-
                case IPI_CPU_STOP:
                        /*
                         * call vmstop()
@@ -248,7 +244,7 @@ void smp_send_stop(void)
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-       send_ipi(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+       send_ipi(cpumask_of(cpu), IPI_CALL_FUNC);
 }
 
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
index 9903fad997f3e2dc210b85905e832d268df31b5b..17fbf45bf1502ad4c7212346e9333b95d2914937 100644 (file)
@@ -191,9 +191,6 @@ void __init time_init_deferred(void)
 {
        struct resource *resource = NULL;
        struct clock_event_device *ce_dev = &hexagon_clockevent_dev;
-       struct device_node *dn;
-       struct resource r;
-       int err;
 
        ce_dev->cpumask = cpu_all_mask;
 
@@ -232,6 +229,15 @@ void __init time_init(void)
        late_time_init = time_init_deferred;
 }
 
+void __delay(unsigned long cycles)
+{
+       unsigned long long start = __vmgettime();
+
+       while ((__vmgettime() - start) < cycles)
+               cpu_relax();
+}
+EXPORT_SYMBOL(__delay);
+
 /*
  * This could become parametric or perhaps even computed at run-time,
  * but for now we take the observed simulator jitter.
index f59c0b844e8855ea55989ad6b814fad125b45879..0c161ed6d18e6d77433c8bafabfdd48f904a077d 100644 (file)
@@ -269,12 +269,17 @@ err_inject_init(void)
 #ifdef ERR_INJ_DEBUG
        printk(KERN_INFO "Enter error injection driver.\n");
 #endif
+
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(i) {
                err_inject_cpu_callback(&err_inject_cpu_notifier, CPU_ONLINE,
                                (void *)(long)i);
        }
 
-       register_hotcpu_notifier(&err_inject_cpu_notifier);
+       __register_hotcpu_notifier(&err_inject_cpu_notifier);
+
+       cpu_notifier_register_done();
 
        return 0;
 }
@@ -288,11 +293,17 @@ err_inject_exit(void)
 #ifdef ERR_INJ_DEBUG
        printk(KERN_INFO "Exit error injection driver.\n");
 #endif
+
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(i) {
                sys_dev = get_cpu_device(i);
                sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
        }
-       unregister_hotcpu_notifier(&err_inject_cpu_notifier);
+
+       __unregister_hotcpu_notifier(&err_inject_cpu_notifier);
+
+       cpu_notifier_register_done();
 }
 
 module_init(err_inject_init);
index ab333284f4b2eb45ce2294b337d8e3196a081721..c39c3cd3ac348a414787d4db30ec6c6181f7f6d9 100644 (file)
@@ -996,13 +996,17 @@ palinfo_init(void)
        if (!palinfo_dir)
                return -ENOMEM;
 
+       cpu_notifier_register_begin();
+
        /* Create palinfo dirs in /proc for all online cpus */
        for_each_online_cpu(i) {
                create_palinfo_proc_entries(i);
        }
 
        /* Register for future delivery via notify registration */
-       register_hotcpu_notifier(&palinfo_cpu_notifier);
+       __register_hotcpu_notifier(&palinfo_cpu_notifier);
+
+       cpu_notifier_register_done();
 
        return 0;
 }
index 960a396f5929667162bf0bb867ac03d7aa85e302..ee9719eebb1e217989f04de5ae0b72e870c876fa 100644 (file)
@@ -635,6 +635,8 @@ salinfo_init(void)
                                           (void *)salinfo_entries[i].feature);
        }
 
+       cpu_notifier_register_begin();
+
        for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
                data = salinfo_data + i;
                data->type = i;
@@ -669,7 +671,9 @@ salinfo_init(void)
        salinfo_timer.function = &salinfo_timeout;
        add_timer(&salinfo_timer);
 
-       register_hotcpu_notifier(&salinfo_cpu_notifier);
+       __register_hotcpu_notifier(&salinfo_cpu_notifier);
+
+       cpu_notifier_register_done();
 
        return 0;
 }
index ca69a5a96dcc07bb760eabd43ff6a03dfc2d6db2..f295f9abba4b04772679a6ff232a2f1387572c27 100644 (file)
@@ -454,12 +454,16 @@ static int __init cache_sysfs_init(void)
 {
        int i;
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(i) {
                struct device *sys_dev = get_cpu_device((unsigned int)i);
                cache_add_dev(sys_dev);
        }
 
-       register_hotcpu_notifier(&cache_cpu_notifier);
+       __register_hotcpu_notifier(&cache_cpu_notifier);
+
+       cpu_notifier_register_done();
 
        return 0;
 }
index c1616824e201f0e8e53605226dae70cf4feb692a..e7292f460af45665ac7cdbef46c02a56f4b07921 100644 (file)
@@ -40,7 +40,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index a6599e42facfb8cefb1062f7be679366a4ef5210..0cd4b39f325b6c609a385f31de4cf4c76db2a957 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 3fa60a57a0f9a19eab0872db442251c87f65f606..a60cb35091352d20399c39fbfe1cd863b072a5b8 100644 (file)
@@ -36,7 +36,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index a1230e82bb1e5226c3d61968b1c625bbf40c6a17..e6502ab7cb2fee0ac7b2bd7a1089e41450f05780 100644 (file)
@@ -39,7 +39,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 43795f41f7c7b1da1267c8c5bef183cde4e97257..023812abd2e6c6d701015dd99f70693dd1eb7251 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index 72746c57a571312b47b4b2989bd05d08ffa9180c..557b39f3be9094e223fb8715cae927c0c5ba1cd3 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_RAM=y
index e1534783e94e5f1c7d47e7fb713bcace07bf080f..52f7e8499172e101b5ba3d925c9d9d9694c325c1 100644 (file)
@@ -55,7 +55,7 @@ static inline unsigned int _swapl(volatile unsigned long v)
 #define __raw_writew writew
 #define __raw_writel writel
 
-static inline void io_outsb(unsigned int addr, void *buf, int len)
+static inline void io_outsb(unsigned int addr, const void *buf, int len)
 {
        volatile unsigned char *ap = (volatile unsigned char *) addr;
        unsigned char *bp = (unsigned char *) buf;
@@ -63,7 +63,7 @@ static inline void io_outsb(unsigned int addr, void *buf, int len)
                *ap = *bp++;
 }
 
-static inline void io_outsw(unsigned int addr, void *buf, int len)
+static inline void io_outsw(unsigned int addr, const void *buf, int len)
 {
        volatile unsigned short *ap = (volatile unsigned short *) addr;
        unsigned short *bp = (unsigned short *) buf;
@@ -71,7 +71,7 @@ static inline void io_outsw(unsigned int addr, void *buf, int len)
                *ap = _swapw(*bp++);
 }
 
-static inline void io_outsl(unsigned int addr, void *buf, int len)
+static inline void io_outsl(unsigned int addr, const void *buf, int len)
 {
        volatile unsigned int *ap = (volatile unsigned int *) addr;
        unsigned int *bp = (unsigned int *) buf;
index d853d163ba4730ddac3eff5793f5f4fe8861a330..bde5311036384c891463de556bb75e62b6d39a7c 100644 (file)
@@ -25,8 +25,26 @@ static inline int arch_get_random_int(unsigned int *v)
        return rc;
 }
 
+static inline int arch_has_random(void)
+{
+       return !!ppc_md.get_random_long;
+}
+
 int powernv_get_random_long(unsigned long *v);
 
+static inline int arch_get_random_seed_long(unsigned long *v)
+{
+       return 0;
+}
+static inline int arch_get_random_seed_int(unsigned int *v)
+{
+       return 0;
+}
+static inline int arch_has_random_seed(void)
+{
+       return 0;
+}
+
 #endif /* CONFIG_ARCH_RANDOM */
 
 #endif /* _ASM_POWERPC_ARCHRANDOM_H */
index 97e1dc91768374e7a7c5b56eb6752b7df5ae05ea..d90d4b7810d69edfa2283367aa7146edbcac8fa0 100644 (file)
@@ -975,7 +975,8 @@ static int __init topology_init(void)
        int cpu;
 
        register_nodes();
-       register_cpu_notifier(&sysfs_cpu_nb);
+
+       cpu_notifier_register_begin();
 
        for_each_possible_cpu(cpu) {
                struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -999,6 +1000,11 @@ static int __init topology_init(void)
                if (cpu_online(cpu))
                        register_cpu_online(cpu);
        }
+
+       __register_cpu_notifier(&sysfs_cpu_nb);
+
+       cpu_notifier_register_done();
+
 #ifdef CONFIG_PPC64
        sysfs_create_dscr_default();
 #endif /* CONFIG_PPC64 */
index 3a414c0f93edcd08d69d3a1aa2af645c098327c9..c0b03c28d15717448f4f713c083bbd891861f42b 100644 (file)
@@ -378,9 +378,12 @@ static int __init cache_init(void)
        if (!test_facility(34))
                return 0;
        cache_build_info();
+
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu)
                cache_add_cpu(cpu);
-       hotcpu_notifier(cache_hotplug, 0);
+       __hotcpu_notifier(cache_hotplug, 0);
+       cpu_notifier_register_done();
        return 0;
 }
 device_initcall(cache_init);
index 8827883310ddbc05c765f17b2125e804dc2cd85e..5a640b395bd4d37ced17d847fd01e6869b487363 100644 (file)
@@ -1057,19 +1057,24 @@ static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
 
 static int __init s390_smp_init(void)
 {
-       int cpu, rc;
+       int cpu, rc = 0;
 
-       hotcpu_notifier(smp_cpu_notify, 0);
 #ifdef CONFIG_HOTPLUG_CPU
        rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
        if (rc)
                return rc;
 #endif
+       cpu_notifier_register_begin();
        for_each_present_cpu(cpu) {
                rc = smp_add_present_cpu(cpu);
                if (rc)
-                       return rc;
+                       goto out;
        }
-       return 0;
+
+       __hotcpu_notifier(smp_cpu_notify, 0);
+
+out:
+       cpu_notifier_register_done();
+       return rc;
 }
 subsys_initcall(s390_smp_init);
index c21c673e5f7cde71cdeca0c4b48bf565df96bfd7..a364000ca1aa8a495f7e8b9bf59882350f41c6de 100644 (file)
@@ -300,7 +300,7 @@ static int __init topology_init(void)
 
        check_mmu_stats();
 
-       register_cpu_notifier(&sysfs_cpu_nb);
+       cpu_notifier_register_begin();
 
        for_each_possible_cpu(cpu) {
                struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -310,6 +310,10 @@ static int __init topology_init(void)
                        register_cpu_online(cpu);
        }
 
+       __register_cpu_notifier(&sysfs_cpu_nb);
+
+       cpu_notifier_register_done();
+
        return 0;
 }
 
index b3692ce78f9034773415503017c2a4cb24fa1d2c..31c8c62239956a59e44bd650ef8f6c2eebdd7285 100644 (file)
@@ -3,6 +3,8 @@
 
 config TILE
        def_bool y
+       select HAVE_PERF_EVENTS
+       select USE_PMC if PERF_EVENTS
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select HAVE_KVM if !TILEGX
@@ -66,6 +68,10 @@ config HUGETLB_SUPER_PAGES
 config GENERIC_TIME_VSYSCALL
        def_bool y
 
+# Enable PMC if PERF_EVENTS, OPROFILE, or WATCHPOINTS are enabled.
+config USE_PMC
+       bool
+
 # FIXME: tilegx can implement a more efficient rwsem.
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
diff --git a/arch/tile/include/asm/perf_event.h b/arch/tile/include/asm/perf_event.h
new file mode 100644 (file)
index 0000000..59c5b16
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#ifndef _ASM_TILE_PERF_EVENT_H
+#define _ASM_TILE_PERF_EVENT_H
+
+#include <linux/percpu.h>
+DECLARE_PER_CPU(u64, perf_irqs);
+
+unsigned long handle_syscall_link_address(void);
+#endif /* _ASM_TILE_PERF_EVENT_H */
diff --git a/arch/tile/include/asm/pmc.h b/arch/tile/include/asm/pmc.h
new file mode 100644 (file)
index 0000000..7ae3956
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2014 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#ifndef _ASM_TILE_PMC_H
+#define _ASM_TILE_PMC_H
+
+#include <linux/ptrace.h>
+
+#define TILE_BASE_COUNTERS     2
+
+/* Bitfields below are derived from SPR PERF_COUNT_CTL*/
+#ifndef __tilegx__
+/* PERF_COUNT_CTL on TILEPro */
+#define TILE_CTL_EXCL_USER     (1 << 7) /* exclude user level */
+#define TILE_CTL_EXCL_KERNEL   (1 << 8) /* exclude kernel level */
+#define TILE_CTL_EXCL_HV       (1 << 9) /* exclude hypervisor level */
+
+#define TILE_SEL_MASK          0x7f    /* 7 bits for event SEL,
+                                       COUNT_0_SEL */
+#define TILE_PLM_MASK          0x780   /* 4 bits priv level msks,
+                                       COUNT_0_MASK*/
+#define TILE_EVENT_MASK        (TILE_SEL_MASK | TILE_PLM_MASK)
+
+#else /* __tilegx__*/
+/* PERF_COUNT_CTL on TILEGx*/
+#define TILE_CTL_EXCL_USER     (1 << 10) /* exclude user level */
+#define TILE_CTL_EXCL_KERNEL   (1 << 11) /* exclude kernel level */
+#define TILE_CTL_EXCL_HV       (1 << 12) /* exclude hypervisor level */
+
+#define TILE_SEL_MASK          0x3f    /* 6 bits for event SEL,
+                                       COUNT_0_SEL*/
+#define TILE_BOX_MASK          0x1c0   /* 3 bits box msks,
+                                       COUNT_0_BOX */
+#define TILE_PLM_MASK          0x3c00  /* 4 bits priv level msks,
+                                       COUNT_0_MASK */
+#define TILE_EVENT_MASK        (TILE_SEL_MASK | TILE_BOX_MASK | TILE_PLM_MASK)
+#endif /* __tilegx__*/
+
+/* Takes register and fault number.  Returns error to disable the interrupt. */
+typedef int (*perf_irq_t)(struct pt_regs *, int);
+
+int userspace_perf_handler(struct pt_regs *regs, int fault);
+
+perf_irq_t reserve_pmc_hardware(perf_irq_t new_perf_irq);
+void release_pmc_hardware(void);
+
+unsigned long pmc_get_overflow(void);
+void pmc_ack_overflow(unsigned long status);
+
+void unmask_pmc_interrupts(void);
+void mask_pmc_interrupts(void);
+
+#endif /* _ASM_TILE_PMC_H */
index 27a2bf39dae887c9056cfb8aea4e97e72770fde1..21f77bf68c690a438c8ca9540e0f9e7574872c17 100644 (file)
@@ -25,6 +25,8 @@ obj-$(CONFIG_PCI)             += pci_gx.o
 else
 obj-$(CONFIG_PCI)              += pci.o
 endif
+obj-$(CONFIG_PERF_EVENTS)      += perf_event.o
+obj-$(CONFIG_USE_PMC)          += pmc.o
 obj-$(CONFIG_TILE_USB)         += usb.o
 obj-$(CONFIG_TILE_HVGLUE_TRACE)        += hvglue_trace.o
 obj-$(CONFIG_FUNCTION_TRACER)  += ftrace.o mcount_64.o
index 2cbe6d5dd6b04db3ea071fb12c3dbb1866dc818e..cdbda45a4e4bba22c5397338b34f3310426fcd77 100644 (file)
@@ -313,13 +313,13 @@ intvec_\vecname:
         movei  r3, 0
        }
        .else
-       .ifc \c_routine, op_handle_perf_interrupt
+       .ifc \c_routine, handle_perf_interrupt
        {
         mfspr  r2, PERF_COUNT_STS
         movei  r3, -1   /* not used, but set for consistency */
        }
        .else
-       .ifc \c_routine, op_handle_aux_perf_interrupt
+       .ifc \c_routine, handle_perf_interrupt
        {
         mfspr  r2, AUX_PERF_COUNT_STS
         movei  r3, -1   /* not used, but set for consistency */
@@ -946,6 +946,13 @@ STD_ENTRY(interrupt_return)
        bzt     r30, .Lrestore_regs
 3:
 
+       /* We are relying on INT_PERF_COUNT at 33, and AUX_PERF_COUNT at 48 */
+       {
+        moveli r0, lo16(1 << (INT_PERF_COUNT - 32))
+        bz     r31, .Lrestore_regs
+       }
+       auli    r0, r0, ha16(1 << (INT_AUX_PERF_COUNT - 32))
+       mtspr   SPR_INTERRUPT_MASK_RESET_K_1, r0
 
        /*
         * We now commit to returning from this interrupt, since we will be
@@ -1171,6 +1178,10 @@ handle_nmi:
         PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
        }
        FEEDBACK_REENTER(handle_nmi)
+       {
+        movei  r30, 1
+        seq    r31, r0, zero
+       }
        j       interrupt_return
        STD_ENDPROC(handle_nmi)
 
@@ -1835,8 +1846,9 @@ int_unalign:
 /* Include .intrpt array of interrupt vectors */
        .section ".intrpt", "ax"
 
-#define op_handle_perf_interrupt bad_intr
-#define op_handle_aux_perf_interrupt bad_intr
+#ifndef CONFIG_USE_PMC
+#define handle_perf_interrupt bad_intr
+#endif
 
 #ifndef CONFIG_HARDWALL
 #define do_hardwall_trap bad_intr
@@ -1877,7 +1889,7 @@ int_unalign:
        int_hand     INT_IDN_AVAIL, IDN_AVAIL, bad_intr
        int_hand     INT_UDN_AVAIL, UDN_AVAIL, bad_intr
        int_hand     INT_PERF_COUNT, PERF_COUNT, \
-                    op_handle_perf_interrupt, handle_nmi
+                    handle_perf_interrupt, handle_nmi
        int_hand     INT_INTCTRL_3, INTCTRL_3, bad_intr
 #if CONFIG_KERNEL_PL == 2
        dc_dispatch  INT_INTCTRL_2, INTCTRL_2
@@ -1902,7 +1914,7 @@ int_unalign:
        int_hand     INT_SN_CPL, SN_CPL, bad_intr
        int_hand     INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
        int_hand     INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
-                    op_handle_aux_perf_interrupt, handle_nmi
+                    handle_perf_interrupt, handle_nmi
 
        /* Synthetic interrupt delivered only by the simulator */
        int_hand     INT_BREAKPOINT, BREAKPOINT, do_breakpoint
index b8fc497f24370c0d7c17536664cb19c40923e5bf..5b67efcecabd17603deb47cd622d94e9b710d470 100644 (file)
@@ -509,10 +509,10 @@ intvec_\vecname:
        .ifc \c_routine, do_trap
        mfspr   r2, GPV_REASON
        .else
-       .ifc \c_routine, op_handle_perf_interrupt
+       .ifc \c_routine, handle_perf_interrupt
        mfspr   r2, PERF_COUNT_STS
        .else
-       .ifc \c_routine, op_handle_aux_perf_interrupt
+       .ifc \c_routine, handle_perf_interrupt
        mfspr   r2, AUX_PERF_COUNT_STS
        .endif
        .endif
@@ -971,6 +971,15 @@ STD_ENTRY(interrupt_return)
        beqzt   r30, .Lrestore_regs
 3:
 
+#if INT_PERF_COUNT + 1 != INT_AUX_PERF_COUNT
+# error Bad interrupt assumption
+#endif
+       {
+        movei  r0, 3   /* two adjacent bits for the PERF_COUNT mask */
+        beqz   r31, .Lrestore_regs
+       }
+       shli    r0, r0, INT_PERF_COUNT
+       mtspr   SPR_INTERRUPT_MASK_RESET_K, r0
 
        /*
         * We now commit to returning from this interrupt, since we will be
@@ -1187,7 +1196,7 @@ handle_nmi:
        FEEDBACK_REENTER(handle_nmi)
        {
         movei  r30, 1
-        move   r31, r0
+        cmpeq  r31, r0, zero
        }
        j       interrupt_return
        STD_ENDPROC(handle_nmi)
@@ -1491,8 +1500,9 @@ STD_ENTRY(fill_ra_stack)
        .global intrpt_start
 intrpt_start:
 
-#define op_handle_perf_interrupt bad_intr
-#define op_handle_aux_perf_interrupt bad_intr
+#ifndef CONFIG_USE_PMC
+#define handle_perf_interrupt bad_intr
+#endif
 
 #ifndef CONFIG_HARDWALL
 #define do_hardwall_trap bad_intr
@@ -1540,9 +1550,9 @@ intrpt_start:
 #endif
        int_hand     INT_IPI_0, IPI_0, bad_intr
        int_hand     INT_PERF_COUNT, PERF_COUNT, \
-                    op_handle_perf_interrupt, handle_nmi
+                    handle_perf_interrupt, handle_nmi
        int_hand     INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
-                    op_handle_perf_interrupt, handle_nmi
+                    handle_perf_interrupt, handle_nmi
        int_hand     INT_INTCTRL_3, INTCTRL_3, bad_intr
 #if CONFIG_KERNEL_PL == 2
        dc_dispatch  INT_INTCTRL_2, INTCTRL_2
index 0586fdb9352d2b2ca88cf48af4125216f135b3ae..906a76bdb31d488e6ffa7fd4416e091812d611fc 100644 (file)
@@ -21,6 +21,7 @@
 #include <hv/drv_pcie_rc_intf.h>
 #include <arch/spr_def.h>
 #include <asm/traps.h>
+#include <linux/perf_event.h>
 
 /* Bit-flag stored in irq_desc->chip_data to indicate HW-cleared irqs. */
 #define IS_HW_CLEARED 1
@@ -260,6 +261,23 @@ void ack_bad_irq(unsigned int irq)
        pr_err("unexpected IRQ trap at vector %02x\n", irq);
 }
 
+/*
+ * /proc/interrupts printing:
+ */
+int arch_show_interrupts(struct seq_file *p, int prec)
+{
+#ifdef CONFIG_PERF_EVENTS
+       int i;
+
+       seq_printf(p, "%*s: ", prec, "PMI");
+
+       for_each_online_cpu(i)
+               seq_printf(p, "%10llu ", per_cpu(perf_irqs, i));
+       seq_puts(p, "  perf_events\n");
+#endif
+       return 0;
+}
+
 /*
  * Generic, controller-independent functions:
  */
index 00331af9525dcf52c990f3ee30abb13d367d7889..7867266f97169a5dd87fb09508e6833a94ef5b74 100644 (file)
@@ -68,8 +68,8 @@ void hv_message_intr(struct pt_regs *regs, int intnum)
 #endif
 
        while (1) {
-               rmi = hv_receive_message(__get_cpu_var(msg_state),
-                                        (HV_VirtAddr) message,
+               HV_MsgState *state = this_cpu_ptr(&msg_state);
+               rmi = hv_receive_message(*state, (HV_VirtAddr) message,
                                         sizeof(message));
                if (rmi.msglen == 0)
                        break;
index c45593db7718e8f1a589fe081054389d97ee4e6d..1f80a88c75a6ace1369e1888cbf0b369f7dc3cb6 100644 (file)
@@ -250,8 +250,6 @@ static void fixup_read_and_payload_sizes(void)
 
        /* Scan for the smallest maximum payload size. */
        for_each_pci_dev(dev) {
-               u32 devcap;
-
                if (!pci_is_pcie(dev))
                        continue;
 
diff --git a/arch/tile/kernel/perf_event.c b/arch/tile/kernel/perf_event.c
new file mode 100644 (file)
index 0000000..2bf6c9c
--- /dev/null
@@ -0,0 +1,1005 @@
+/*
+ * Copyright 2014 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ * Perf_events support for Tile processor.
+ *
+ * This code is based upon the x86 perf event
+ * code, which is:
+ *
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *  Copyright (C) 2009 Google, Inc., Stephane Eranian
+ */
+
+#include <linux/kprobes.h>
+#include <linux/kernel.h>
+#include <linux/kdebug.h>
+#include <linux/mutex.h>
+#include <linux/bitmap.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/perf_event.h>
+#include <linux/atomic.h>
+#include <asm/traps.h>
+#include <asm/stack.h>
+#include <asm/pmc.h>
+#include <hv/hypervisor.h>
+
+#define TILE_MAX_COUNTERS      4
+
+#define PERF_COUNT_0_IDX       0
+#define PERF_COUNT_1_IDX       1
+#define AUX_PERF_COUNT_0_IDX   2
+#define AUX_PERF_COUNT_1_IDX   3
+
+struct cpu_hw_events {
+       int                     n_events;
+       struct perf_event       *events[TILE_MAX_COUNTERS]; /* counter order */
+       struct perf_event       *event_list[TILE_MAX_COUNTERS]; /* enabled
+                                                               order */
+       int                     assign[TILE_MAX_COUNTERS];
+       unsigned long           active_mask[BITS_TO_LONGS(TILE_MAX_COUNTERS)];
+       unsigned long           used_mask;
+};
+
+/* TILE arch specific performance monitor unit */
+struct tile_pmu {
+       const char      *name;
+       int             version;
+       const int       *hw_events;     /* generic hw events table */
+       /* generic hw cache events table */
+       const int       (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+                                      [PERF_COUNT_HW_CACHE_OP_MAX]
+                                      [PERF_COUNT_HW_CACHE_RESULT_MAX];
+       int             (*map_hw_event)(u64);    /*method used to map
+                                                 hw events */
+       int             (*map_cache_event)(u64); /*method used to map
+                                                 cache events */
+
+       u64             max_period;             /* max sampling period */
+       u64             cntval_mask;            /* counter width mask */
+       int             cntval_bits;            /* counter width */
+       int             max_events;             /* max generic hw events
+                                               in map */
+       int             num_counters;           /* number base + aux counters */
+       int             num_base_counters;      /* number base counters */
+};
+
+DEFINE_PER_CPU(u64, perf_irqs);
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+#define TILE_OP_UNSUPP         (-1)
+
+#ifndef __tilegx__
+/* TILEPro hardware events map */
+static const int tile_hw_event_map[] = {
+       [PERF_COUNT_HW_CPU_CYCLES]              = 0x01, /* ONE */
+       [PERF_COUNT_HW_INSTRUCTIONS]            = 0x06, /* MP_BUNDLE_RETIRED */
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = TILE_OP_UNSUPP,
+       [PERF_COUNT_HW_CACHE_MISSES]            = TILE_OP_UNSUPP,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = 0x16, /*
+                                         MP_CONDITIONAL_BRANCH_ISSUED */
+       [PERF_COUNT_HW_BRANCH_MISSES]           = 0x14, /*
+                                         MP_CONDITIONAL_BRANCH_MISSPREDICT */
+       [PERF_COUNT_HW_BUS_CYCLES]              = TILE_OP_UNSUPP,
+};
+#else
+/* TILEGx hardware events map */
+static const int tile_hw_event_map[] = {
+       [PERF_COUNT_HW_CPU_CYCLES]              = 0x181, /* ONE */
+       [PERF_COUNT_HW_INSTRUCTIONS]            = 0xdb, /* INSTRUCTION_BUNDLE */
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = TILE_OP_UNSUPP,
+       [PERF_COUNT_HW_CACHE_MISSES]            = TILE_OP_UNSUPP,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = 0xd9, /*
+                                               COND_BRANCH_PRED_CORRECT */
+       [PERF_COUNT_HW_BRANCH_MISSES]           = 0xda, /*
+                                               COND_BRANCH_PRED_INCORRECT */
+       [PERF_COUNT_HW_BUS_CYCLES]              = TILE_OP_UNSUPP,
+};
+#endif
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+/*
+ * Generalized hw caching related hw_event table, filled
+ * in on a per model basis. A value of -1 means
+ * 'not supported', any other value means the
+ * raw hw_event ID.
+ */
+#ifndef __tilegx__
+/* TILEPro hardware cache event map */
+static const int tile_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
+                                    [PERF_COUNT_HW_CACHE_OP_MAX]
+                                    [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = 0x21, /* RD_MISS */
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = 0x22, /* WR_MISS */
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(L1I)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = 0x12, /* MP_ICACHE_HIT_ISSUED */
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(LL)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(DTLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = 0x1d, /* TLB_CNT */
+               [C(RESULT_MISS)] = 0x20, /* TLB_EXCEPTION */
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(ITLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = 0x13, /* MP_ITLB_HIT_ISSUED */
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(BPU)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+};
+#else
+/* TILEGx hardware events map */
+static const int tile_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
+                                    [PERF_COUNT_HW_CACHE_OP_MAX]
+                                    [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+       /*
+        * Like some other architectures (e.g. ARM), the performance
+        * counters don't differentiate between read and write
+        * accesses/misses, so this isn't strictly correct, but it's the
+        * best we can do. Writes and reads get combined.
+        */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = 0x44, /* RD_MISS */
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = 0x45, /* WR_MISS */
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(L1I)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(LL)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(DTLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = 0x40, /* TLB_CNT */
+               [C(RESULT_MISS)] = 0x43, /* TLB_EXCEPTION */
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = 0x40, /* TLB_CNT */
+               [C(RESULT_MISS)] = 0x43, /* TLB_EXCEPTION */
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(ITLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = 0xd4, /* ITLB_MISS_INT */
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = 0xd4, /* ITLB_MISS_INT */
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+[C(BPU)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)] = TILE_OP_UNSUPP,
+               [C(RESULT_MISS)] = TILE_OP_UNSUPP,
+       },
+},
+};
+#endif
+
+static atomic_t tile_active_events;
+static DEFINE_MUTEX(perf_intr_reserve_mutex);
+
+static int tile_map_hw_event(u64 config);
+static int tile_map_cache_event(u64 config);
+
+static int tile_pmu_handle_irq(struct pt_regs *regs, int fault);
+
+/*
+ * To avoid new_raw_count getting larger then pre_raw_count
+ * in tile_perf_event_update(), we limit the value of max_period to 2^31 - 1.
+ */
+static const struct tile_pmu tilepmu = {
+#ifndef __tilegx__
+       .name = "tilepro",
+#else
+       .name = "tilegx",
+#endif
+       .max_events = ARRAY_SIZE(tile_hw_event_map),
+       .map_hw_event = tile_map_hw_event,
+       .hw_events = tile_hw_event_map,
+       .map_cache_event = tile_map_cache_event,
+       .cache_events = &tile_cache_event_map,
+       .cntval_bits = 32,
+       .cntval_mask = (1ULL << 32) - 1,
+       .max_period = (1ULL << 31) - 1,
+       .num_counters = TILE_MAX_COUNTERS,
+       .num_base_counters = TILE_BASE_COUNTERS,
+};
+
+static const struct tile_pmu *tile_pmu __read_mostly;
+
+/*
+ * Check whether perf event is enabled.
+ */
+int tile_perf_enabled(void)
+{
+       return atomic_read(&tile_active_events) != 0;
+}
+
+/*
+ * Read Performance Counters.
+ */
+static inline u64 read_counter(int idx)
+{
+       u64 val = 0;
+
+       /* __insn_mfspr() only takes an immediate argument */
+       switch (idx) {
+       case PERF_COUNT_0_IDX:
+               val = __insn_mfspr(SPR_PERF_COUNT_0);
+               break;
+       case PERF_COUNT_1_IDX:
+               val = __insn_mfspr(SPR_PERF_COUNT_1);
+               break;
+       case AUX_PERF_COUNT_0_IDX:
+               val = __insn_mfspr(SPR_AUX_PERF_COUNT_0);
+               break;
+       case AUX_PERF_COUNT_1_IDX:
+               val = __insn_mfspr(SPR_AUX_PERF_COUNT_1);
+               break;
+       default:
+               WARN_ON_ONCE(idx > AUX_PERF_COUNT_1_IDX ||
+                               idx < PERF_COUNT_0_IDX);
+       }
+
+       return val;
+}
+
+/*
+ * Write Performance Counters.
+ */
+static inline void write_counter(int idx, u64 value)
+{
+       /* __insn_mtspr() only takes an immediate argument */
+       switch (idx) {
+       case PERF_COUNT_0_IDX:
+               __insn_mtspr(SPR_PERF_COUNT_0, value);
+               break;
+       case PERF_COUNT_1_IDX:
+               __insn_mtspr(SPR_PERF_COUNT_1, value);
+               break;
+       case AUX_PERF_COUNT_0_IDX:
+               __insn_mtspr(SPR_AUX_PERF_COUNT_0, value);
+               break;
+       case AUX_PERF_COUNT_1_IDX:
+               __insn_mtspr(SPR_AUX_PERF_COUNT_1, value);
+               break;
+       default:
+               WARN_ON_ONCE(idx > AUX_PERF_COUNT_1_IDX ||
+                               idx < PERF_COUNT_0_IDX);
+       }
+}
+
+/*
+ * Enable performance event by setting
+ * Performance Counter Control registers.
+ */
+static inline void tile_pmu_enable_event(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned long cfg, mask;
+       int shift, idx = hwc->idx;
+
+       /*
+        * prevent early activation from tile_pmu_start() in hw_perf_enable
+        */
+
+       if (WARN_ON_ONCE(idx == -1))
+               return;
+
+       if (idx < tile_pmu->num_base_counters)
+               cfg = __insn_mfspr(SPR_PERF_COUNT_CTL);
+       else
+               cfg = __insn_mfspr(SPR_AUX_PERF_COUNT_CTL);
+
+       switch (idx) {
+       case PERF_COUNT_0_IDX:
+       case AUX_PERF_COUNT_0_IDX:
+               mask = TILE_EVENT_MASK;
+               shift = 0;
+               break;
+       case PERF_COUNT_1_IDX:
+       case AUX_PERF_COUNT_1_IDX:
+               mask = TILE_EVENT_MASK << 16;
+               shift = 16;
+               break;
+       default:
+               WARN_ON_ONCE(idx < PERF_COUNT_0_IDX ||
+                       idx > AUX_PERF_COUNT_1_IDX);
+               return;
+       }
+
+       /* Clear mask bits to enable the event. */
+       cfg &= ~mask;
+       cfg |= hwc->config << shift;
+
+       if (idx < tile_pmu->num_base_counters)
+               __insn_mtspr(SPR_PERF_COUNT_CTL, cfg);
+       else
+               __insn_mtspr(SPR_AUX_PERF_COUNT_CTL, cfg);
+}
+
+/*
+ * Disable performance event by clearing
+ * Performance Counter Control registers.
+ */
+static inline void tile_pmu_disable_event(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned long cfg, mask;
+       int idx = hwc->idx;
+
+       if (idx == -1)
+               return;
+
+       if (idx < tile_pmu->num_base_counters)
+               cfg = __insn_mfspr(SPR_PERF_COUNT_CTL);
+       else
+               cfg = __insn_mfspr(SPR_AUX_PERF_COUNT_CTL);
+
+       switch (idx) {
+       case PERF_COUNT_0_IDX:
+       case AUX_PERF_COUNT_0_IDX:
+               mask = TILE_PLM_MASK;
+               break;
+       case PERF_COUNT_1_IDX:
+       case AUX_PERF_COUNT_1_IDX:
+               mask = TILE_PLM_MASK << 16;
+               break;
+       default:
+               WARN_ON_ONCE(idx < PERF_COUNT_0_IDX ||
+                       idx > AUX_PERF_COUNT_1_IDX);
+               return;
+       }
+
+       /* Set mask bits to disable the event. */
+       cfg |= mask;
+
+       if (idx < tile_pmu->num_base_counters)
+               __insn_mtspr(SPR_PERF_COUNT_CTL, cfg);
+       else
+               __insn_mtspr(SPR_AUX_PERF_COUNT_CTL, cfg);
+}
+
+/*
+ * Propagate event elapsed time into the generic event.
+ * Can only be executed on the CPU where the event is active.
+ * Returns the delta events processed.
+ */
+static u64 tile_perf_event_update(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int shift = 64 - tile_pmu->cntval_bits;
+       u64 prev_raw_count, new_raw_count;
+       u64 oldval;
+       int idx = hwc->idx;
+       u64 delta;
+
+       /*
+        * Careful: an NMI might modify the previous event value.
+        *
+        * Our tactic to handle this is to first atomically read and
+        * exchange a new raw count - then add that new-prev delta
+        * count to the generic event atomically:
+        */
+again:
+       prev_raw_count = local64_read(&hwc->prev_count);
+       new_raw_count = read_counter(idx);
+
+       oldval = local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+                                new_raw_count);
+       if (oldval != prev_raw_count)
+               goto again;
+
+       /*
+        * Now we have the new raw value and have updated the prev
+        * timestamp already. We can now calculate the elapsed delta
+        * (event-)time and add that to the generic event.
+        *
+        * Careful, not all hw sign-extends above the physical width
+        * of the count.
+        */
+       delta = (new_raw_count << shift) - (prev_raw_count << shift);
+       delta >>= shift;
+
+       local64_add(delta, &event->count);
+       local64_sub(delta, &hwc->period_left);
+
+       return new_raw_count;
+}
+
+/*
+ * Set the next IRQ period, based on the hwc->period_left value.
+ * To be called with the event disabled in hw:
+ */
+static int tile_event_set_period(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+       s64 left = local64_read(&hwc->period_left);
+       s64 period = hwc->sample_period;
+       int ret = 0;
+
+       /*
+        * If we are way outside a reasonable range then just skip forward:
+        */
+       if (unlikely(left <= -period)) {
+               left = period;
+               local64_set(&hwc->period_left, left);
+               hwc->last_period = period;
+               ret = 1;
+       }
+
+       if (unlikely(left <= 0)) {
+               left += period;
+               local64_set(&hwc->period_left, left);
+               hwc->last_period = period;
+               ret = 1;
+       }
+       if (left > tile_pmu->max_period)
+               left = tile_pmu->max_period;
+
+       /*
+        * The hw event starts counting from this event offset,
+        * mark it to be able to extra future deltas:
+        */
+       local64_set(&hwc->prev_count, (u64)-left);
+
+       write_counter(idx, (u64)(-left) & tile_pmu->cntval_mask);
+
+       perf_event_update_userpage(event);
+
+       return ret;
+}
+
+/*
+ * Stop the event but do not release the PMU counter
+ */
+static void tile_pmu_stop(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+
+       if (__test_and_clear_bit(idx, cpuc->active_mask)) {
+               tile_pmu_disable_event(event);
+               cpuc->events[hwc->idx] = NULL;
+               WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+               hwc->state |= PERF_HES_STOPPED;
+       }
+
+       if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+               /*
+                * Drain the remaining delta count out of a event
+                * that we are disabling:
+                */
+               tile_perf_event_update(event);
+               hwc->state |= PERF_HES_UPTODATE;
+       }
+}
+
+/*
+ * Start an event (without re-assigning counter)
+ */
+static void tile_pmu_start(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int idx = event->hw.idx;
+
+       if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+               return;
+
+       if (WARN_ON_ONCE(idx == -1))
+               return;
+
+       if (flags & PERF_EF_RELOAD) {
+               WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+               tile_event_set_period(event);
+       }
+
+       event->hw.state = 0;
+
+       cpuc->events[idx] = event;
+       __set_bit(idx, cpuc->active_mask);
+
+       unmask_pmc_interrupts();
+
+       tile_pmu_enable_event(event);
+
+       perf_event_update_userpage(event);
+}
+
+/*
+ * Add a single event to the PMU.
+ *
+ * The event is added to the group of enabled events
+ * but only if it can be scehduled with existing events.
+ */
+static int tile_pmu_add(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc;
+       unsigned long mask;
+       int b, max_cnt;
+
+       hwc = &event->hw;
+
+       /*
+        * We are full.
+        */
+       if (cpuc->n_events == tile_pmu->num_counters)
+               return -ENOSPC;
+
+       cpuc->event_list[cpuc->n_events] = event;
+       cpuc->n_events++;
+
+       hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+       if (!(flags & PERF_EF_START))
+               hwc->state |= PERF_HES_ARCH;
+
+       /*
+        * Find first empty counter.
+        */
+       max_cnt = tile_pmu->num_counters;
+       mask = ~cpuc->used_mask;
+
+       /* Find next free counter. */
+       b = find_next_bit(&mask, max_cnt, 0);
+
+       /* Should not happen. */
+       if (WARN_ON_ONCE(b == max_cnt))
+               return -ENOSPC;
+
+       /*
+        * Assign counter to event.
+        */
+       event->hw.idx = b;
+       __set_bit(b, &cpuc->used_mask);
+
+       /*
+        * Start if requested.
+        */
+       if (flags & PERF_EF_START)
+               tile_pmu_start(event, PERF_EF_RELOAD);
+
+       return 0;
+}
+
+/*
+ * Delete a single event from the PMU.
+ *
+ * The event is deleted from the group of enabled events.
+ * If it is the last event, disable PMU interrupt.
+ */
+static void tile_pmu_del(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int i;
+
+       /*
+        * Remove event from list, compact list if necessary.
+        */
+       for (i = 0; i < cpuc->n_events; i++) {
+               if (cpuc->event_list[i] == event) {
+                       while (++i < cpuc->n_events)
+                               cpuc->event_list[i-1] = cpuc->event_list[i];
+                       --cpuc->n_events;
+                       cpuc->events[event->hw.idx] = NULL;
+                       __clear_bit(event->hw.idx, &cpuc->used_mask);
+                       tile_pmu_stop(event, PERF_EF_UPDATE);
+                       break;
+               }
+       }
+       /*
+        * If there are no events left, then mask PMU interrupt.
+        */
+       if (cpuc->n_events == 0)
+               mask_pmc_interrupts();
+       perf_event_update_userpage(event);
+}
+
+/*
+ * Propagate event elapsed time into the event.
+ */
+static inline void tile_pmu_read(struct perf_event *event)
+{
+       tile_perf_event_update(event);
+}
+
+/*
+ * Map generic events to Tile PMU.
+ */
+static int tile_map_hw_event(u64 config)
+{
+       if (config >= tile_pmu->max_events)
+               return -EINVAL;
+       return tile_pmu->hw_events[config];
+}
+
+/*
+ * Map generic hardware cache events to Tile PMU.
+ */
+static int tile_map_cache_event(u64 config)
+{
+       unsigned int cache_type, cache_op, cache_result;
+       int code;
+
+       if (!tile_pmu->cache_events)
+               return -ENOENT;
+
+       cache_type = (config >>  0) & 0xff;
+       if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+               return -EINVAL;
+
+       cache_op = (config >>  8) & 0xff;
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+               return -EINVAL;
+
+       cache_result = (config >> 16) & 0xff;
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+               return -EINVAL;
+
+       code = (*tile_pmu->cache_events)[cache_type][cache_op][cache_result];
+       if (code == TILE_OP_UNSUPP)
+               return -EINVAL;
+
+       return code;
+}
+
+static void tile_event_destroy(struct perf_event *event)
+{
+       if (atomic_dec_return(&tile_active_events) == 0)
+               release_pmc_hardware();
+}
+
+static int __tile_event_init(struct perf_event *event)
+{
+       struct perf_event_attr *attr = &event->attr;
+       struct hw_perf_event *hwc = &event->hw;
+       int code;
+
+       switch (attr->type) {
+       case PERF_TYPE_HARDWARE:
+               code = tile_pmu->map_hw_event(attr->config);
+               break;
+       case PERF_TYPE_HW_CACHE:
+               code = tile_pmu->map_cache_event(attr->config);
+               break;
+       case PERF_TYPE_RAW:
+               code = attr->config & TILE_EVENT_MASK;
+               break;
+       default:
+               /* Should not happen. */
+               return -EOPNOTSUPP;
+       }
+
+       if (code < 0)
+               return code;
+
+       hwc->config = code;
+       hwc->idx = -1;
+
+       if (attr->exclude_user)
+               hwc->config |= TILE_CTL_EXCL_USER;
+
+       if (attr->exclude_kernel)
+               hwc->config |= TILE_CTL_EXCL_KERNEL;
+
+       if (attr->exclude_hv)
+               hwc->config |= TILE_CTL_EXCL_HV;
+
+       if (!hwc->sample_period) {
+               hwc->sample_period = tile_pmu->max_period;
+               hwc->last_period = hwc->sample_period;
+               local64_set(&hwc->period_left, hwc->sample_period);
+       }
+       event->destroy = tile_event_destroy;
+       return 0;
+}
+
+static int tile_event_init(struct perf_event *event)
+{
+       int err = 0;
+       perf_irq_t old_irq_handler = NULL;
+
+       if (atomic_inc_return(&tile_active_events) == 1)
+               old_irq_handler = reserve_pmc_hardware(tile_pmu_handle_irq);
+
+       if (old_irq_handler) {
+               pr_warn("PMC hardware busy (reserved by oprofile)\n");
+
+               atomic_dec(&tile_active_events);
+               return -EBUSY;
+       }
+
+       switch (event->attr.type) {
+       case PERF_TYPE_RAW:
+       case PERF_TYPE_HARDWARE:
+       case PERF_TYPE_HW_CACHE:
+               break;
+
+       default:
+               return -ENOENT;
+       }
+
+       err = __tile_event_init(event);
+       if (err) {
+               if (event->destroy)
+                       event->destroy(event);
+       }
+       return err;
+}
+
+static struct pmu tilera_pmu = {
+       .event_init     = tile_event_init,
+       .add            = tile_pmu_add,
+       .del            = tile_pmu_del,
+
+       .start          = tile_pmu_start,
+       .stop           = tile_pmu_stop,
+
+       .read           = tile_pmu_read,
+};
+
+/*
+ * PMU's IRQ handler, PMU has 2 interrupts, they share the same handler.
+ */
+int tile_pmu_handle_irq(struct pt_regs *regs, int fault)
+{
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct perf_event *event;
+       struct hw_perf_event *hwc;
+       u64 val;
+       unsigned long status;
+       int bit;
+
+       __get_cpu_var(perf_irqs)++;
+
+       if (!atomic_read(&tile_active_events))
+               return 0;
+
+       status = pmc_get_overflow();
+       pmc_ack_overflow(status);
+
+       for_each_set_bit(bit, &status, tile_pmu->num_counters) {
+
+               event = cpuc->events[bit];
+
+               if (!event)
+                       continue;
+
+               if (!test_bit(bit, cpuc->active_mask))
+                       continue;
+
+               hwc = &event->hw;
+
+               val = tile_perf_event_update(event);
+               if (val & (1ULL << (tile_pmu->cntval_bits - 1)))
+                       continue;
+
+               perf_sample_data_init(&data, 0, event->hw.last_period);
+               if (!tile_event_set_period(event))
+                       continue;
+
+               if (perf_event_overflow(event, &data, regs))
+                       tile_pmu_stop(event, 0);
+       }
+
+       return 0;
+}
+
+static bool __init supported_pmu(void)
+{
+       tile_pmu = &tilepmu;
+       return true;
+}
+
+int __init init_hw_perf_events(void)
+{
+       supported_pmu();
+       perf_pmu_register(&tilera_pmu, "cpu", PERF_TYPE_RAW);
+       return 0;
+}
+arch_initcall(init_hw_perf_events);
+
+/* Callchain handling code. */
+
+/*
+ * Tile specific backtracing code for perf_events.
+ */
+static inline void perf_callchain(struct perf_callchain_entry *entry,
+                   struct pt_regs *regs)
+{
+       struct KBacktraceIterator kbt;
+       unsigned int i;
+
+       /*
+        * Get the address just after the "jalr" instruction that
+        * jumps to the handler for a syscall.  When we find this
+        * address in a backtrace, we silently ignore it, which gives
+        * us a one-step backtrace connection from the sys_xxx()
+        * function in the kernel to the xxx() function in libc.
+        * Otherwise, we lose the ability to properly attribute time
+        * from the libc calls to the kernel implementations, since
+        * oprofile only considers PCs from backtraces a pair at a time.
+        */
+       unsigned long handle_syscall_pc = handle_syscall_link_address();
+
+       KBacktraceIterator_init(&kbt, NULL, regs);
+       kbt.profile = 1;
+
+       /*
+        * The sample for the pc is already recorded.  Now we are adding the
+        * address of the callsites on the stack.  Our iterator starts
+        * with the frame of the (already sampled) call site.  If our
+        * iterator contained a "return address" field, we could have just
+        * used it and wouldn't have needed to skip the first
+        * frame.  That's in effect what the arm and x86 versions do.
+        * Instead we peel off the first iteration to get the equivalent
+        * behavior.
+        */
+
+       if (KBacktraceIterator_end(&kbt))
+               return;
+       KBacktraceIterator_next(&kbt);
+
+       /*
+        * Set stack depth to 16 for user and kernel space respectively, that
+        * is, total 32 stack frames.
+        */
+       for (i = 0; i < 16; ++i) {
+               unsigned long pc;
+               if (KBacktraceIterator_end(&kbt))
+                       break;
+               pc = kbt.it.pc;
+               if (pc != handle_syscall_pc)
+                       perf_callchain_store(entry, pc);
+               KBacktraceIterator_next(&kbt);
+       }
+}
+
+void perf_callchain_user(struct perf_callchain_entry *entry,
+                   struct pt_regs *regs)
+{
+       perf_callchain(entry, regs);
+}
+
+void perf_callchain_kernel(struct perf_callchain_entry *entry,
+                     struct pt_regs *regs)
+{
+       perf_callchain(entry, regs);
+}
diff --git a/arch/tile/kernel/pmc.c b/arch/tile/kernel/pmc.c
new file mode 100644 (file)
index 0000000..db62cc3
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2014 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/atomic.h>
+#include <linux/interrupt.h>
+
+#include <asm/processor.h>
+#include <asm/pmc.h>
+
+perf_irq_t perf_irq = NULL;
+int handle_perf_interrupt(struct pt_regs *regs, int fault)
+{
+       int retval;
+
+       if (!perf_irq)
+               panic("Unexpected PERF_COUNT interrupt %d\n", fault);
+
+       nmi_enter();
+       retval = perf_irq(regs, fault);
+       nmi_exit();
+       return retval;
+}
+
+/* Reserve PMC hardware if it is available. */
+perf_irq_t reserve_pmc_hardware(perf_irq_t new_perf_irq)
+{
+       return cmpxchg(&perf_irq, NULL, new_perf_irq);
+}
+EXPORT_SYMBOL(reserve_pmc_hardware);
+
+/* Release PMC hardware. */
+void release_pmc_hardware(void)
+{
+       perf_irq = NULL;
+}
+EXPORT_SYMBOL(release_pmc_hardware);
+
+
+/*
+ * Get current overflow status of each performance counter,
+ * and auxiliary performance counter.
+ */
+unsigned long
+pmc_get_overflow(void)
+{
+       unsigned long status;
+
+       /*
+        * merge base+aux into a single vector
+        */
+       status = __insn_mfspr(SPR_PERF_COUNT_STS);
+       status |= __insn_mfspr(SPR_AUX_PERF_COUNT_STS) << TILE_BASE_COUNTERS;
+       return status;
+}
+
+/*
+ * Clear the status bit for the corresponding counter, if written
+ * with a one.
+ */
+void
+pmc_ack_overflow(unsigned long status)
+{
+       /*
+        * clear overflow status by writing ones
+        */
+       __insn_mtspr(SPR_PERF_COUNT_STS, status);
+       __insn_mtspr(SPR_AUX_PERF_COUNT_STS, status >> TILE_BASE_COUNTERS);
+}
+
+/*
+ * The perf count interrupts are masked and unmasked explicitly,
+ * and only here.  The normal irq_enable() does not enable them,
+ * and irq_disable() does not disable them.  That lets these
+ * routines drive the perf count interrupts orthogonally.
+ *
+ * We also mask the perf count interrupts on entry to the perf count
+ * interrupt handler in assembly code, and by default unmask them
+ * again (with interrupt critical section protection) just before
+ * returning from the interrupt.  If the perf count handler returns
+ * a non-zero error code, then we don't re-enable them before returning.
+ *
+ * For Pro, we rely on both interrupts being in the same word to update
+ * them atomically so we never have one enabled and one disabled.
+ */
+
+#if CHIP_HAS_SPLIT_INTR_MASK()
+# if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32
+#  error Fix assumptions about which word PERF_COUNT interrupts are in
+# endif
+#endif
+
+static inline unsigned long long pmc_mask(void)
+{
+       unsigned long long mask = 1ULL << INT_PERF_COUNT;
+       mask |= 1ULL << INT_AUX_PERF_COUNT;
+       return mask;
+}
+
+void unmask_pmc_interrupts(void)
+{
+       interrupt_mask_reset_mask(pmc_mask());
+}
+
+void mask_pmc_interrupts(void)
+{
+       interrupt_mask_set_mask(pmc_mask());
+}
index 5d10642db63e8e9f98934e36200128a9dfd26073..462dcd0c1700221adda93563b5f7904511a9c656 100644 (file)
@@ -236,7 +236,15 @@ cycles_t ns2cycles(unsigned long nsecs)
         * clock frequency.
         */
        struct clock_event_device *dev = &__raw_get_cpu_var(tile_timer);
-       return ((u64)nsecs * dev->mult) >> dev->shift;
+
+       /*
+        * as in clocksource.h and x86's timer.h, we split the calculation
+        * into 2 parts to avoid unecessary overflow of the intermediate
+        * value. This will not lead to any loss of precision.
+        */
+       u64 quot = (u64)nsecs >> dev->shift;
+       u64 rem  = (u64)nsecs & ((1ULL << dev->shift) - 1);
+       return quot * dev->mult + ((rem * dev->mult) >> dev->shift);
 }
 
 void update_vsyscall_tz(void)
index e2b7a2f4ee4103eebd8b551339c3c3ecddb6ed2e..a025f63d54cd9609820c634da186a5e71a026375 100644 (file)
@@ -104,7 +104,7 @@ $(obj-vdso32:%=%): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
 $(obj-vdso32:%=%): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
 
 $(obj)/vgettimeofday32.o: $(obj)/vgettimeofday.c
-       $(call if_changed,cc_o_c)
+       $(call if_changed_rule,cc_o_c)
 
 $(obj)/vrt_sigreturn32.o: $(obj)/vrt_sigreturn.S
        $(call if_changed,as_o_S)
index e6a92455740e6a5dfc64c5b1a1193a693594feab..69f1366f1aa33721ea160cc831a1345867b7a4b3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the Linux kernel.
  *
- * Copyright (c) 2011, Intel Corporation
+ * Copyright (c) 2011-2014, Intel Corporation
  * Authors: Fenghua Yu <fenghua.yu@intel.com>,
  *          H. Peter Anvin <hpa@linux.intel.com>
  *
 #define RDRAND_RETRY_LOOPS     10
 
 #define RDRAND_INT     ".byte 0x0f,0xc7,0xf0"
+#define RDSEED_INT     ".byte 0x0f,0xc7,0xf8"
 #ifdef CONFIG_X86_64
 # define RDRAND_LONG   ".byte 0x48,0x0f,0xc7,0xf0"
+# define RDSEED_LONG   ".byte 0x48,0x0f,0xc7,0xf8"
 #else
 # define RDRAND_LONG   RDRAND_INT
+# define RDSEED_LONG   RDSEED_INT
 #endif
 
 #ifdef CONFIG_ARCH_RANDOM
@@ -53,6 +56,16 @@ static inline int rdrand_long(unsigned long *v)
        return ok;
 }
 
+/* A single attempt at RDSEED */
+static inline bool rdseed_long(unsigned long *v)
+{
+       unsigned char ok;
+       asm volatile(RDSEED_LONG "\n\t"
+                    "setc %0"
+                    : "=qm" (ok), "=a" (*v));
+       return ok;
+}
+
 #define GET_RANDOM(name, type, rdrand, nop)                    \
 static inline int name(type *v)                                        \
 {                                                              \
@@ -70,18 +83,40 @@ static inline int name(type *v)                                     \
        return ok;                                              \
 }
 
+#define GET_SEED(name, type, rdseed, nop)                      \
+static inline int name(type *v)                                        \
+{                                                              \
+       unsigned char ok;                                       \
+       alternative_io("movb $0, %0\n\t"                        \
+                      nop,                                     \
+                      rdseed "\n\t"                            \
+                      "setc %0",                               \
+                      X86_FEATURE_RDSEED,                      \
+                      ASM_OUTPUT2("=q" (ok), "=a" (*v)));      \
+       return ok;                                              \
+}
+
 #ifdef CONFIG_X86_64
 
 GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP5);
 GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP4);
 
+GET_SEED(arch_get_random_seed_long, unsigned long, RDSEED_LONG, ASM_NOP5);
+GET_SEED(arch_get_random_seed_int, unsigned int, RDSEED_INT, ASM_NOP4);
+
 #else
 
 GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP3);
 GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);
 
+GET_SEED(arch_get_random_seed_long, unsigned long, RDSEED_LONG, ASM_NOP4);
+GET_SEED(arch_get_random_seed_int, unsigned int, RDSEED_INT, ASM_NOP4);
+
 #endif /* CONFIG_X86_64 */
 
+#define arch_has_random()      static_cpu_has(X86_FEATURE_RDRAND)
+#define arch_has_random_seed() static_cpu_has(X86_FEATURE_RDSEED)
+
 #else
 
 static inline int rdrand_long(unsigned long *v)
@@ -89,6 +124,11 @@ static inline int rdrand_long(unsigned long *v)
        return 0;
 }
 
+static inline bool rdseed_long(unsigned long *v)
+{
+       return 0;
+}
+
 #endif  /* CONFIG_ARCH_RANDOM */
 
 extern void x86_init_rdrand(struct cpuinfo_x86 *c);
index 0641113e296598c058cab739d94c0ae2f5280ec0..a952e9c85b6fad81684c4bd39418bd5623a634ff 100644 (file)
@@ -1225,21 +1225,24 @@ static struct notifier_block cacheinfo_cpu_notifier = {
 
 static int __init cache_sysfs_init(void)
 {
-       int i;
+       int i, err = 0;
 
        if (num_cache_leaves == 0)
                return 0;
 
+       cpu_notifier_register_begin();
        for_each_online_cpu(i) {
-               int err;
                struct device *dev = get_cpu_device(i);
 
                err = cache_add_dev(dev);
                if (err)
-                       return err;
+                       goto out;
        }
-       register_hotcpu_notifier(&cacheinfo_cpu_notifier);
-       return 0;
+       __register_hotcpu_notifier(&cacheinfo_cpu_notifier);
+
+out:
+       cpu_notifier_register_done();
+       return err;
 }
 
 device_initcall(cache_sysfs_init);
index 4d5419b249da5353afb24edd23c8410d60f8079d..9b7734b1f975a4c0cfc9776749aecc83ace1cd10 100644 (file)
@@ -2434,14 +2434,18 @@ static __init int mcheck_init_device(void)
        if (err)
                return err;
 
+       cpu_notifier_register_begin();
        for_each_online_cpu(i) {
                err = mce_device_create(i);
-               if (err)
+               if (err) {
+                       cpu_notifier_register_done();
                        return err;
+               }
        }
 
        register_syscore_ops(&mce_syscore_ops);
-       register_hotcpu_notifier(&mce_cpu_notifier);
+       __register_hotcpu_notifier(&mce_cpu_notifier);
+       cpu_notifier_register_done();
 
        /* register character device /dev/mcelog */
        misc_register(&mce_chrdev_device);
index 3eec7de76efbb4650ea760f5163d495f47fd1f1d..d921b7ee659525e7d040ff5ea5c6a569239a64a7 100644 (file)
@@ -271,9 +271,6 @@ static void thermal_throttle_remove_dev(struct device *dev)
        sysfs_remove_group(&dev->kobj, &thermal_attr_group);
 }
 
-/* Mutex protecting device creation against CPU hotplug: */
-static DEFINE_MUTEX(therm_cpu_lock);
-
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
 static int
 thermal_throttle_cpu_callback(struct notifier_block *nfb,
@@ -289,18 +286,14 @@ thermal_throttle_cpu_callback(struct notifier_block *nfb,
        switch (action) {
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
-               mutex_lock(&therm_cpu_lock);
                err = thermal_throttle_add_dev(dev, cpu);
-               mutex_unlock(&therm_cpu_lock);
                WARN_ON(err);
                break;
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               mutex_lock(&therm_cpu_lock);
                thermal_throttle_remove_dev(dev);
-               mutex_unlock(&therm_cpu_lock);
                break;
        }
        return notifier_from_errno(err);
@@ -319,19 +312,16 @@ static __init int thermal_throttle_init_device(void)
        if (!atomic_read(&therm_throt_en))
                return 0;
 
-       register_hotcpu_notifier(&thermal_throttle_cpu_notifier);
+       cpu_notifier_register_begin();
 
-#ifdef CONFIG_HOTPLUG_CPU
-       mutex_lock(&therm_cpu_lock);
-#endif
        /* connect live CPUs to sysfs */
        for_each_online_cpu(cpu) {
                err = thermal_throttle_add_dev(get_cpu_device(cpu), cpu);
                WARN_ON(err);
        }
-#ifdef CONFIG_HOTPLUG_CPU
-       mutex_unlock(&therm_cpu_lock);
-#endif
+
+       __register_hotcpu_notifier(&thermal_throttle_cpu_notifier);
+       cpu_notifier_register_done();
 
        return 0;
 }
index 4b8e4d3cd6ea62bc9c9047e869fa84cbd9cbe33a..4c36bbe3173aa0f683a5a982cc857c6f3ffa3e0a 100644 (file)
@@ -926,13 +926,13 @@ static __init int amd_ibs_init(void)
                goto out;
 
        perf_ibs_pm_init();
-       get_online_cpus();
+       cpu_notifier_register_begin();
        ibs_caps = caps;
        /* make ibs_caps visible to other cpus: */
        smp_mb();
-       perf_cpu_notifier(perf_ibs_cpu_notifier);
        smp_call_function(setup_APIC_ibs, NULL, 1);
-       put_online_cpus();
+       __perf_cpu_notifier(perf_ibs_cpu_notifier);
+       cpu_notifier_register_done();
 
        ret = perf_event_ibs_init();
 out:
index 754291adec338b34317d5c07a359741e5e298d80..3bbdf4cd38b9c4e38dcf8e4f480753e93858631a 100644 (file)
@@ -531,15 +531,16 @@ static int __init amd_uncore_init(void)
        if (ret)
                return -ENODEV;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
+
        /* init cpus already online before registering for hotplug notifier */
        for_each_online_cpu(cpu) {
                amd_uncore_cpu_up_prepare(cpu);
                smp_call_function_single(cpu, init_cpu_already_online, NULL, 1);
        }
 
-       register_cpu_notifier(&amd_uncore_cpu_notifier_block);
-       put_online_cpus();
+       __register_cpu_notifier(&amd_uncore_cpu_notifier_block);
+       cpu_notifier_register_done();
 
        return 0;
 }
index 5ad35ad94d0f819b1cf54f627d5df4fcfc58e460..059218ed5208e83ab40d44374064a53fdeab5568 100644 (file)
@@ -646,19 +646,20 @@ static int __init rapl_pmu_init(void)
                /* unsupported */
                return 0;
        }
-       get_online_cpus();
+
+       cpu_notifier_register_begin();
 
        for_each_online_cpu(cpu) {
                rapl_cpu_prepare(cpu);
                rapl_cpu_init(cpu);
        }
 
-       perf_cpu_notifier(rapl_cpu_notifier);
+       __perf_cpu_notifier(rapl_cpu_notifier);
 
        ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
        if (WARN_ON(ret)) {
                pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
-               put_online_cpus();
+               cpu_notifier_register_done();
                return -1;
        }
 
@@ -672,7 +673,7 @@ static int __init rapl_pmu_init(void)
                hweight32(rapl_cntr_mask),
                ktime_to_ms(pmu->timer_interval));
 
-       put_online_cpus();
+       cpu_notifier_register_done();
 
        return 0;
 }
index bd2253d40cffe16363569384084bdf6d6d73e7f5..65bbbea38b9c9c0f7246a3c4fee4176dd529647b 100644 (file)
@@ -4244,7 +4244,7 @@ static void __init uncore_cpumask_init(void)
        if (!cpumask_empty(&uncore_cpu_mask))
                return;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
 
        for_each_online_cpu(cpu) {
                int i, phys_id = topology_physical_package_id(cpu);
@@ -4263,9 +4263,9 @@ static void __init uncore_cpumask_init(void)
        }
        on_each_cpu(uncore_cpu_setup, NULL, 1);
 
-       register_cpu_notifier(&uncore_cpu_nb);
+       __register_cpu_notifier(&uncore_cpu_nb);
 
-       put_online_cpus();
+       cpu_notifier_register_done();
 }
 
 
index 7d9481c743f8439ae3a36256f008c45380ee49e8..3225ae6c51806af1590ce780a68ff67e6ca8ae77 100644 (file)
@@ -198,14 +198,15 @@ static int __init cpuid_init(void)
                goto out_chrdev;
        }
        cpuid_class->devnode = cpuid_devnode;
-       get_online_cpus();
+
+       cpu_notifier_register_begin();
        for_each_online_cpu(i) {
                err = cpuid_device_create(i);
                if (err != 0)
                        goto out_class;
        }
-       register_hotcpu_notifier(&cpuid_class_cpu_notifier);
-       put_online_cpus();
+       __register_hotcpu_notifier(&cpuid_class_cpu_notifier);
+       cpu_notifier_register_done();
 
        err = 0;
        goto out;
@@ -215,7 +216,7 @@ out_class:
        for_each_online_cpu(i) {
                cpuid_device_destroy(i);
        }
-       put_online_cpus();
+       cpu_notifier_register_done();
        class_destroy(cpuid_class);
 out_chrdev:
        __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
@@ -227,13 +228,13 @@ static void __exit cpuid_exit(void)
 {
        int cpu = 0;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu)
                cpuid_device_destroy(cpu);
        class_destroy(cpuid_class);
        __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
-       unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
-       put_online_cpus();
+       __unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
+       cpu_notifier_register_done();
 }
 
 module_init(cpuid_init);
index 93eed15a8fd41aeb4556117a932c9afa591893b3..8d80ae0116039b6c71945737befc4f88dea097df 100644 (file)
@@ -941,12 +941,14 @@ static __init int hpet_late_init(void)
        if (boot_cpu_has(X86_FEATURE_ARAT))
                return 0;
 
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu) {
                hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
        }
 
        /* This notifier should be called after workqueue is ready */
-       hotcpu_notifier(hpet_cpuhp_notify, -20);
+       __hotcpu_notifier(hpet_cpuhp_notify, -20);
+       cpu_notifier_register_done();
 
        return 0;
 }
index 05266b5aae22916e864bb21e1399193ff253374e..c9603ac80de5ecbc32ac80027d33a815ee6f9e94 100644 (file)
@@ -259,14 +259,15 @@ static int __init msr_init(void)
                goto out_chrdev;
        }
        msr_class->devnode = msr_devnode;
-       get_online_cpus();
+
+       cpu_notifier_register_begin();
        for_each_online_cpu(i) {
                err = msr_device_create(i);
                if (err != 0)
                        goto out_class;
        }
-       register_hotcpu_notifier(&msr_class_cpu_notifier);
-       put_online_cpus();
+       __register_hotcpu_notifier(&msr_class_cpu_notifier);
+       cpu_notifier_register_done();
 
        err = 0;
        goto out;
@@ -275,7 +276,7 @@ out_class:
        i = 0;
        for_each_online_cpu(i)
                msr_device_destroy(i);
-       put_online_cpus();
+       cpu_notifier_register_done();
        class_destroy(msr_class);
 out_chrdev:
        __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
@@ -286,13 +287,14 @@ out:
 static void __exit msr_exit(void)
 {
        int cpu = 0;
-       get_online_cpus();
+
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu)
                msr_device_destroy(cpu);
        class_destroy(msr_class);
        __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
-       unregister_hotcpu_notifier(&msr_class_cpu_notifier);
-       put_online_cpus();
+       __unregister_hotcpu_notifier(&msr_class_cpu_notifier);
+       cpu_notifier_register_done();
 }
 
 module_init(msr_init);
index 9ea287666c6559abaa15a090ab37a0be0eaef1ba..8b3b3eb3cead2dffbdd20d6dd4632595e723a117 100644 (file)
@@ -348,9 +348,13 @@ static int __init vsyscall_init(void)
 {
        BUG_ON(VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE));
 
+       cpu_notifier_register_begin();
+
        on_each_cpu(cpu_vsyscall_init, NULL, 1);
        /* notifier priority > KVM */
-       hotcpu_notifier(cpu_vsyscall_notifier, 30);
+       __hotcpu_notifier(cpu_vsyscall_notifier, 30);
+
+       cpu_notifier_register_done();
 
        return 0;
 }
index d1c55f8722c66cf6139222c3544c97700169c523..9d1b5cd4d34cc6f585b7f18a1ac2c5ba266c9b28 100644 (file)
@@ -5422,7 +5422,8 @@ static void kvm_timer_init(void)
        int cpu;
 
        max_tsc_khz = tsc_khz;
-       register_hotcpu_notifier(&kvmclock_cpu_notifier_block);
+
+       cpu_notifier_register_begin();
        if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
 #ifdef CONFIG_CPU_FREQ
                struct cpufreq_policy policy;
@@ -5439,6 +5440,10 @@ static void kvm_timer_init(void)
        pr_debug("kvm: max_tsc_khz = %ld\n", max_tsc_khz);
        for_each_online_cpu(cpu)
                smp_call_function_single(cpu, tsc_khz_changed, NULL, 1);
+
+       __register_hotcpu_notifier(&kvmclock_cpu_notifier_block);
+       cpu_notifier_register_done();
+
 }
 
 static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
index 6890d8498e0becb308244819265647e6d400513b..379e8bd0deeabf8bb1e839ea6bcb11f0bc1dd12b 100644 (file)
@@ -494,14 +494,19 @@ static int nmi_setup(void)
        if (err)
                goto fail;
 
+       cpu_notifier_register_begin();
+
+       /* Use get/put_online_cpus() to protect 'nmi_enabled' */
        get_online_cpus();
-       register_cpu_notifier(&oprofile_cpu_nb);
        nmi_enabled = 1;
        /* make nmi_enabled visible to the nmi handler: */
        smp_mb();
        on_each_cpu(nmi_cpu_setup, NULL, 1);
+       __register_cpu_notifier(&oprofile_cpu_nb);
        put_online_cpus();
 
+       cpu_notifier_register_done();
+
        return 0;
 fail:
        free_msrs();
@@ -512,12 +517,18 @@ static void nmi_shutdown(void)
 {
        struct op_msrs *msrs;
 
+       cpu_notifier_register_begin();
+
+       /* Use get/put_online_cpus() to protect 'nmi_enabled' & 'ctr_running' */
        get_online_cpus();
-       unregister_cpu_notifier(&oprofile_cpu_nb);
        on_each_cpu(nmi_cpu_shutdown, NULL, 1);
        nmi_enabled = 0;
        ctr_running = 0;
+       __unregister_cpu_notifier(&oprofile_cpu_nb);
        put_online_cpus();
+
+       cpu_notifier_register_done();
+
        /* make variables visible to the nmi handler: */
        smp_mb();
        unregister_nmi_handler(NMI_LOCAL, "oprofile");
index a313a7fb6b862e26b893ad8f5058e8767bf146c1..e88f4c53d7f6b41d4268b4eb51fad5badd514c2b 100644 (file)
@@ -370,10 +370,13 @@ static int __init pci_io_ecs_init(void)
        if (early_pci_allowed())
                pci_enable_pci_io_ecs();
 
-       register_cpu_notifier(&amd_cpu_notifier);
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu)
                amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
                               (void *)(long)cpu);
+       __register_cpu_notifier(&amd_cpu_notifier);
+       cpu_notifier_register_done();
+
        pci_probe |= PCI_HAS_IO_ECS;
 
        return 0;
index a12bddc7ccea11edf9f7125d8353f04759d2cfb0..04376ac3d9efb9f8d73f4d096bea692d891c635b 100644 (file)
 313    common  finit_module            sys_finit_module
 314    common  sched_setattr           sys_sched_setattr
 315    common  sched_getattr           sys_sched_getattr
+316    common  renameat2               sys_renameat2
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
index 9e602910560725acb6a2df4da885bde5312c9919..3cf61a127ee54623f5dc4e99e5e5a0ad46868797 100644 (file)
@@ -83,7 +83,7 @@ static struct device_attribute amba_dev_attrs[] = {
        __ATTR_NULL,
 };
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
  * enable/disable the bus clock at runtime PM suspend/resume as this
@@ -123,7 +123,7 @@ static const struct dev_pm_ops amba_pm = {
        .thaw           = pm_generic_thaw,
        .poweroff       = pm_generic_poweroff,
        .restore        = pm_generic_restore,
-       SET_RUNTIME_PM_OPS(
+       SET_PM_RUNTIME_PM_OPS(
                amba_pm_runtime_suspend,
                amba_pm_runtime_resume,
                NULL
index 1f44e56cc65d3c0262f4217c0040bd7c82c47569..558a239954e84813bb73de6826416341649d64d3 100644 (file)
@@ -256,8 +256,6 @@ static int tegra_ahb_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENODEV;
        ahb->regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(ahb->regs))
                return PTR_ERR(ahb->regs);
index ad9d177626640377de6e517fe6d62db093039166..bbcbd3c4392689ef5022af42d0a09bb504be7253 100644 (file)
@@ -160,16 +160,20 @@ static int topology_cpu_callback(struct notifier_block *nfb,
 static int topology_sysfs_init(void)
 {
        int cpu;
-       int rc;
+       int rc = 0;
+
+       cpu_notifier_register_begin();
 
        for_each_online_cpu(cpu) {
                rc = topology_add_dev(cpu);
                if (rc)
-                       return rc;
+                       goto out;
        }
-       hotcpu_notifier(topology_cpu_callback, 0);
+       __hotcpu_notifier(topology_cpu_callback, 0);
 
-       return 0;
+out:
+       cpu_notifier_register_done();
+       return rc;
 }
 
 device_initcall(topology_sysfs_init);
index 34898d53395b10eae386e06fef3d12b9635fe93a..4c95b503b09ee3593ecfe1e2ca035788295b9f80 100644 (file)
@@ -1654,7 +1654,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
        if (osd_req->r_result < 0)
                obj_request->result = osd_req->r_result;
 
-       BUG_ON(osd_req->r_num_ops > 2);
+       rbd_assert(osd_req->r_num_ops <= CEPH_OSD_MAX_OP);
 
        /*
         * We support a 64-bit length, but ultimately it has to be
@@ -1662,11 +1662,15 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
         */
        obj_request->xferred = osd_req->r_reply_op_len[0];
        rbd_assert(obj_request->xferred < (u64)UINT_MAX);
+
        opcode = osd_req->r_ops[0].op;
        switch (opcode) {
        case CEPH_OSD_OP_READ:
                rbd_osd_read_callback(obj_request);
                break;
+       case CEPH_OSD_OP_SETALLOCHINT:
+               rbd_assert(osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE);
+               /* fall through */
        case CEPH_OSD_OP_WRITE:
                rbd_osd_write_callback(obj_request);
                break;
@@ -1715,9 +1719,16 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request)
                        snapc, CEPH_NOSNAP, &mtime);
 }
 
+/*
+ * Create an osd request.  A read request has one osd op (read).
+ * A write request has either one (watch) or two (hint+write) osd ops.
+ * (All rbd data writes are prefixed with an allocation hint op, but
+ * technically osd watch is a write request, hence this distinction.)
+ */
 static struct ceph_osd_request *rbd_osd_req_create(
                                        struct rbd_device *rbd_dev,
                                        bool write_request,
+                                       unsigned int num_ops,
                                        struct rbd_obj_request *obj_request)
 {
        struct ceph_snap_context *snapc = NULL;
@@ -1733,10 +1744,13 @@ static struct ceph_osd_request *rbd_osd_req_create(
                        snapc = img_request->snapc;
        }
 
-       /* Allocate and initialize the request, for the single op */
+       rbd_assert(num_ops == 1 || (write_request && num_ops == 2));
+
+       /* Allocate and initialize the request, for the num_ops ops */
 
        osdc = &rbd_dev->rbd_client->client->osdc;
-       osd_req = ceph_osdc_alloc_request(osdc, snapc, 1, false, GFP_ATOMIC);
+       osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false,
+                                         GFP_ATOMIC);
        if (!osd_req)
                return NULL;    /* ENOMEM */
 
@@ -1756,8 +1770,8 @@ static struct ceph_osd_request *rbd_osd_req_create(
 
 /*
  * Create a copyup osd request based on the information in the
- * object request supplied.  A copyup request has two osd ops,
- * a copyup method call, and a "normal" write request.
+ * object request supplied.  A copyup request has three osd ops,
+ * a copyup method call, a hint op, and a write op.
  */
 static struct ceph_osd_request *
 rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
@@ -1773,12 +1787,12 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
        rbd_assert(img_request);
        rbd_assert(img_request_write_test(img_request));
 
-       /* Allocate and initialize the request, for the two ops */
+       /* Allocate and initialize the request, for the three ops */
 
        snapc = img_request->snapc;
        rbd_dev = img_request->rbd_dev;
        osdc = &rbd_dev->rbd_client->client->osdc;
-       osd_req = ceph_osdc_alloc_request(osdc, snapc, 2, false, GFP_ATOMIC);
+       osd_req = ceph_osdc_alloc_request(osdc, snapc, 3, false, GFP_ATOMIC);
        if (!osd_req)
                return NULL;    /* ENOMEM */
 
@@ -2178,6 +2192,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
                const char *object_name;
                u64 offset;
                u64 length;
+               unsigned int which = 0;
 
                object_name = rbd_segment_name(rbd_dev, img_offset);
                if (!object_name)
@@ -2190,6 +2205,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
                rbd_segment_name_free(object_name);
                if (!obj_request)
                        goto out_unwind;
+
                /*
                 * set obj_request->img_request before creating the
                 * osd_request so that it gets the right snapc
@@ -2207,7 +2223,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
                                                                clone_size,
                                                                GFP_ATOMIC);
                        if (!obj_request->bio_list)
-                               goto out_partial;
+                               goto out_unwind;
                } else {
                        unsigned int page_count;
 
@@ -2220,19 +2236,27 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
                }
 
                osd_req = rbd_osd_req_create(rbd_dev, write_request,
-                                               obj_request);
+                                            (write_request ? 2 : 1),
+                                            obj_request);
                if (!osd_req)
-                       goto out_partial;
+                       goto out_unwind;
                obj_request->osd_req = osd_req;
                obj_request->callback = rbd_img_obj_callback;
 
-               osd_req_op_extent_init(osd_req, 0, opcode, offset, length,
-                                               0, 0);
+               if (write_request) {
+                       osd_req_op_alloc_hint_init(osd_req, which,
+                                            rbd_obj_bytes(&rbd_dev->header),
+                                            rbd_obj_bytes(&rbd_dev->header));
+                       which++;
+               }
+
+               osd_req_op_extent_init(osd_req, which, opcode, offset, length,
+                                      0, 0);
                if (type == OBJ_REQUEST_BIO)
-                       osd_req_op_extent_osd_data_bio(osd_req, 0,
+                       osd_req_op_extent_osd_data_bio(osd_req, which,
                                        obj_request->bio_list, length);
                else
-                       osd_req_op_extent_osd_data_pages(osd_req, 0,
+                       osd_req_op_extent_osd_data_pages(osd_req, which,
                                        obj_request->pages, length,
                                        offset & ~PAGE_MASK, false, false);
 
@@ -2249,11 +2273,9 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
 
        return 0;
 
-out_partial:
-       rbd_obj_request_put(obj_request);
 out_unwind:
        for_each_obj_request_safe(img_request, obj_request, next_obj_request)
-               rbd_obj_request_put(obj_request);
+               rbd_img_obj_request_del(img_request, obj_request);
 
        return -ENOMEM;
 }
@@ -2353,7 +2375,7 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
 
        /*
         * The original osd request is of no use to use any more.
-        * We need a new one that can hold the two ops in a copyup
+        * We need a new one that can hold the three ops in a copyup
         * request.  Allocate the new copyup osd request for the
         * original request, and release the old one.
         */
@@ -2372,17 +2394,22 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
        osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0,
                                                false, false);
 
-       /* Then the original write request op */
+       /* Then the hint op */
+
+       osd_req_op_alloc_hint_init(osd_req, 1, rbd_obj_bytes(&rbd_dev->header),
+                                  rbd_obj_bytes(&rbd_dev->header));
+
+       /* And the original write request op */
 
        offset = orig_request->offset;
        length = orig_request->length;
-       osd_req_op_extent_init(osd_req, 1, CEPH_OSD_OP_WRITE,
+       osd_req_op_extent_init(osd_req, 2, CEPH_OSD_OP_WRITE,
                                        offset, length, 0, 0);
        if (orig_request->type == OBJ_REQUEST_BIO)
-               osd_req_op_extent_osd_data_bio(osd_req, 1,
+               osd_req_op_extent_osd_data_bio(osd_req, 2,
                                        orig_request->bio_list, length);
        else
-               osd_req_op_extent_osd_data_pages(osd_req, 1,
+               osd_req_op_extent_osd_data_pages(osd_req, 2,
                                        orig_request->pages, length,
                                        offset & ~PAGE_MASK, false, false);
 
@@ -2603,8 +2630,8 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
 
        rbd_assert(obj_request->img_request);
        rbd_dev = obj_request->img_request->rbd_dev;
-       stat_request->osd_req = rbd_osd_req_create(rbd_dev, false,
-                                               stat_request);
+       stat_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
+                                                  stat_request);
        if (!stat_request->osd_req)
                goto out;
        stat_request->callback = rbd_img_obj_exists_callback;
@@ -2807,7 +2834,8 @@ static int rbd_obj_notify_ack_sync(struct rbd_device *rbd_dev, u64 notify_id)
                return -ENOMEM;
 
        ret = -ENOMEM;
-       obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, obj_request);
+       obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
+                                                 obj_request);
        if (!obj_request->osd_req)
                goto out;
 
@@ -2870,7 +2898,8 @@ static int __rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, bool start)
        if (!obj_request)
                goto out_cancel;
 
-       obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, obj_request);
+       obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, 1,
+                                                 obj_request);
        if (!obj_request->osd_req)
                goto out_cancel;
 
@@ -2978,7 +3007,8 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
        obj_request->pages = pages;
        obj_request->page_count = page_count;
 
-       obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, obj_request);
+       obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
+                                                 obj_request);
        if (!obj_request->osd_req)
                goto out;
 
@@ -3211,7 +3241,8 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
        obj_request->pages = pages;
        obj_request->page_count = page_count;
 
-       obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, obj_request);
+       obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, 1,
+                                                 obj_request);
        if (!obj_request->osd_req)
                goto out;
 
index 962fd35cbd8d24f2645d9649dcaf0c7430815ea4..5a86da97a70be0ba58b15a387a6cbd2a0999611a 100644 (file)
@@ -31,7 +31,6 @@
 
 #define DRIVER_NAME            "CCI-400"
 #define DRIVER_NAME_PMU                DRIVER_NAME " PMU"
-#define PMU_NAME               "CCI_400"
 
 #define CCI_PORT_CTRL          0x0
 #define CCI_CTRL_STATUS                0xc
@@ -88,8 +87,7 @@ static unsigned long cci_ctrl_phys;
 
 #define CCI_REV_R0             0
 #define CCI_REV_R1             1
-#define CCI_REV_R0_P4          4
-#define CCI_REV_R1_P2          6
+#define CCI_REV_R1_PX          5
 
 #define CCI_PMU_EVT_SEL                0x000
 #define CCI_PMU_CNTR           0x004
@@ -163,6 +161,15 @@ static struct pmu_port_event_ranges port_event_range[] = {
        },
 };
 
+/*
+ * Export different PMU names for the different revisions so userspace knows
+ * because the event ids are different
+ */
+static char *const pmu_names[] = {
+       [CCI_REV_R0] = "CCI_400",
+       [CCI_REV_R1] = "CCI_400_r1",
+};
+
 struct cci_pmu_drv_data {
        void __iomem *base;
        struct arm_pmu *cci_pmu;
@@ -193,21 +200,16 @@ static int probe_cci_revision(void)
        rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK;
        rev >>= CCI_PID2_REV_SHIFT;
 
-       if (rev <= CCI_REV_R0_P4)
+       if (rev < CCI_REV_R1_PX)
                return CCI_REV_R0;
-       else if (rev <= CCI_REV_R1_P2)
+       else
                return CCI_REV_R1;
-
-       return -ENOENT;
 }
 
 static struct pmu_port_event_ranges *port_range_by_rev(void)
 {
        int rev = probe_cci_revision();
 
-       if (rev < 0)
-               return NULL;
-
        return &port_event_range[rev];
 }
 
@@ -526,7 +528,7 @@ static void pmu_write_counter(struct perf_event *event, u32 value)
 static int cci_pmu_init(struct arm_pmu *cci_pmu, struct platform_device *pdev)
 {
        *cci_pmu = (struct arm_pmu){
-               .name             = PMU_NAME,
+               .name             = pmu_names[probe_cci_revision()],
                .max_period       = (1LLU << 32) - 1,
                .get_hw_events    = pmu_get_hw_events,
                .get_event_idx    = pmu_get_event_idx,
index 3ef58c8dbf1143cb555a1be8cf121d4d456dd854..f8ee13c7bf7b83efca1eebfd5241017e2ae8df57 100644 (file)
@@ -11,6 +11,9 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/regmap.h>
 
 struct imx_weim_devtype {
        unsigned int    cs_count;
@@ -56,6 +59,55 @@ static const struct of_device_id weim_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, weim_id_table);
 
+static int __init imx_weim_gpr_setup(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct property *prop;
+       const __be32 *p;
+       struct regmap *gpr;
+       u32 gprvals[4] = {
+               05,     /* CS0(128M) CS1(0M)  CS2(0M)  CS3(0M)  */
+               033,    /* CS0(64M)  CS1(64M) CS2(0M)  CS3(0M)  */
+               0113,   /* CS0(64M)  CS1(32M) CS2(32M) CS3(0M)  */
+               01111,  /* CS0(32M)  CS1(32M) CS2(32M) CS3(32M) */
+       };
+       u32 gprval = 0;
+       u32 val;
+       int cs = 0;
+       int i = 0;
+
+       gpr = syscon_regmap_lookup_by_phandle(np, "fsl,weim-cs-gpr");
+       if (IS_ERR(gpr)) {
+               dev_dbg(&pdev->dev, "failed to find weim-cs-gpr\n");
+               return 0;
+       }
+
+       of_property_for_each_u32(np, "ranges", prop, p, val) {
+               if (i % 4 == 0) {
+                       cs = val;
+               } else if (i % 4 == 3 && val) {
+                       val = (val / SZ_32M) | 1;
+                       gprval |= val << cs * 3;
+               }
+               i++;
+       }
+
+       if (i == 0 || i % 4)
+               goto err;
+
+       for (i = 0; i < ARRAY_SIZE(gprvals); i++) {
+               if (gprval == gprvals[i]) {
+                       /* Found it. Set up IOMUXC_GPR1[11:0] with it. */
+                       regmap_update_bits(gpr, IOMUXC_GPR1, 0xfff, gprval);
+                       return 0;
+               }
+       }
+
+err:
+       dev_err(&pdev->dev, "Invalid 'ranges' configuration\n");
+       return -EINVAL;
+}
+
 /* Parse and set the timing for this device. */
 static int __init weim_timing_setup(struct device_node *np, void __iomem *base,
                                    const struct imx_weim_devtype *devtype)
@@ -92,6 +144,12 @@ static int __init weim_parse_dt(struct platform_device *pdev,
        struct device_node *child;
        int ret;
 
+       if (devtype == &imx50_weim_devtype) {
+               ret = imx_weim_gpr_setup(pdev);
+               if (ret)
+                       return ret;
+       }
+
        for_each_child_of_node(pdev->dev.of_node, child) {
                if (!child->name)
                        continue;
index 2ac754e18bcf1af6a285c5de9f6df867f4e83298..293e2e0a0a87c7d9877c27524fd98503ba16c1cf 100644 (file)
@@ -890,13 +890,12 @@ int __init mvebu_mbus_dt_init(void)
        const __be32 *prop;
        int ret;
 
-       np = of_find_matching_node(NULL, of_mvebu_mbus_ids);
+       np = of_find_matching_node_and_match(NULL, of_mvebu_mbus_ids, &of_id);
        if (!np) {
                pr_err("could not find a matching SoC family\n");
                return -ENODEV;
        }
 
-       of_id = of_match_node(of_mvebu_mbus_ids, np);
        mbus_state.soc = of_id->data;
 
        prop = of_get_property(np, "controller", NULL);
index 2f2b08457c673547568187f04863a01947163385..244759bbd7b73d0aa3015c915654abd35ac7a193 100644 (file)
@@ -342,11 +342,11 @@ config HW_RANDOM_TPM
          If unsure, say Y.
 
 config HW_RANDOM_MSM
-       tristate "Qualcomm MSM Random Number Generator support"
-       depends on HW_RANDOM && ARCH_MSM
+       tristate "Qualcomm SoCs Random Number Generator support"
+       depends on HW_RANDOM && ARCH_QCOM
        ---help---
          This driver provides kernel-side support for the Random Number
-         Generator hardware found on Qualcomm MSM SoCs.
+         Generator hardware found on Qualcomm SoCs.
 
          To compile this driver as a module, choose M here. the
          module will be called msm-rng.
index 429b75bb60e810946db46b189c4f7f2e173a204f..6b75713d953a4e719cd33610f6034bec430c5d95 100644 (file)
  * The minimum number of bits of entropy before we wake up a read on
  * /dev/random.  Should be enough to do a significant reseed.
  */
-static int random_read_wakeup_thresh = 64;
+static int random_read_wakeup_bits = 64;
 
 /*
  * If the entropy count falls under this number of bits, then we
  * should wake up processes which are selecting or polling on write
  * access to /dev/random.
  */
-static int random_write_wakeup_thresh = 28 * OUTPUT_POOL_WORDS;
+static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
 
 /*
- * The minimum number of seconds between urandom pool resending.  We
+ * The minimum number of seconds between urandom pool reseeding.  We
  * do this to limit the amount of entropy that can be drained from the
  * input pool even if there are heavy demands on /dev/urandom.
  */
@@ -322,7 +322,7 @@ static int random_min_urandom_seed = 60;
  * Register.  (See M. Matsumoto & Y. Kurita, 1992.  Twisted GFSR
  * generators.  ACM Transactions on Modeling and Computer Simulation
  * 2(3):179-194.  Also see M. Matsumoto & Y. Kurita, 1994.  Twisted
- * GFSR generators II.  ACM Transactions on Mdeling and Computer
+ * GFSR generators II.  ACM Transactions on Modeling and Computer
  * Simulation 4:254-266)
  *
  * Thanks to Colin Plumb for suggesting this.
@@ -666,10 +666,10 @@ retry:
                                  r->entropy_total, _RET_IP_);
 
        if (r == &input_pool) {
-               int entropy_bytes = entropy_count >> ENTROPY_SHIFT;
+               int entropy_bits = entropy_count >> ENTROPY_SHIFT;
 
                /* should we wake readers? */
-               if (entropy_bytes >= random_read_wakeup_thresh) {
+               if (entropy_bits >= random_read_wakeup_bits) {
                        wake_up_interruptible(&random_read_wait);
                        kill_fasync(&fasync, SIGIO, POLL_IN);
                }
@@ -678,9 +678,9 @@ retry:
                 * forth between them, until the output pools are 75%
                 * full.
                 */
-               if (entropy_bytes > random_write_wakeup_thresh &&
+               if (entropy_bits > random_write_wakeup_bits &&
                    r->initialized &&
-                   r->entropy_total >= 2*random_read_wakeup_thresh) {
+                   r->entropy_total >= 2*random_read_wakeup_bits) {
                        static struct entropy_store *last = &blocking_pool;
                        struct entropy_store *other = &blocking_pool;
 
@@ -844,6 +844,8 @@ void add_interrupt_randomness(int irq, int irq_flags)
        cycles_t                cycles = random_get_entropy();
        __u32                   input[4], c_high, j_high;
        __u64                   ip;
+       unsigned long           seed;
+       int                     credit;
 
        c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
        j_high = (sizeof(now) > 4) ? now >> 32 : 0;
@@ -862,20 +864,33 @@ void add_interrupt_randomness(int irq, int irq_flags)
 
        r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
        __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
+
        /*
         * If we don't have a valid cycle counter, and we see
         * back-to-back timer interrupts, then skip giving credit for
-        * any entropy.
+        * any entropy, otherwise credit 1 bit.
         */
+       credit = 1;
        if (cycles == 0) {
                if (irq_flags & __IRQF_TIMER) {
                        if (fast_pool->last_timer_intr)
-                               return;
+                               credit = 0;
                        fast_pool->last_timer_intr = 1;
                } else
                        fast_pool->last_timer_intr = 0;
        }
-       credit_entropy_bits(r, 1);
+
+       /*
+        * If we have architectural seed generator, produce a seed and
+        * add it to the pool.  For the sake of paranoia count it as
+        * 50% entropic.
+        */
+       if (arch_get_random_seed_long(&seed)) {
+               __mix_pool_bytes(r, &seed, sizeof(seed), NULL);
+               credit += sizeof(seed) * 4;
+       }
+
+       credit_entropy_bits(r, credit);
 }
 
 #ifdef CONFIG_BLOCK
@@ -924,19 +939,19 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
 {
        __u32   tmp[OUTPUT_POOL_WORDS];
 
-       /* For /dev/random's pool, always leave two wakeup worth's BITS */
-       int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
+       /* For /dev/random's pool, always leave two wakeups' worth */
+       int rsvd_bytes = r->limit ? 0 : random_read_wakeup_bits / 4;
        int bytes = nbytes;
 
-       /* pull at least as many as BYTES as wakeup BITS */
-       bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
+       /* pull at least as much as a wakeup */
+       bytes = max_t(int, bytes, random_read_wakeup_bits / 8);
        /* but never more than the buffer size */
        bytes = min_t(int, bytes, sizeof(tmp));
 
        trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8,
                                  ENTROPY_BITS(r), ENTROPY_BITS(r->pull));
        bytes = extract_entropy(r->pull, tmp, bytes,
-                               random_read_wakeup_thresh / 8, rsvd);
+                               random_read_wakeup_bits / 8, rsvd_bytes);
        mix_pool_bytes(r, tmp, bytes, NULL);
        credit_entropy_bits(r, bytes*8);
 }
@@ -952,35 +967,22 @@ static void push_to_pool(struct work_struct *work)
        struct entropy_store *r = container_of(work, struct entropy_store,
                                              push_work);
        BUG_ON(!r);
-       _xfer_secondary_pool(r, random_read_wakeup_thresh/8);
+       _xfer_secondary_pool(r, random_read_wakeup_bits/8);
        trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT,
                           r->pull->entropy_count >> ENTROPY_SHIFT);
 }
 
 /*
- * These functions extracts randomness from the "entropy pool", and
- * returns it in a buffer.
- *
- * The min parameter specifies the minimum amount we can pull before
- * failing to avoid races that defeat catastrophic reseeding while the
- * reserved parameter indicates how much entropy we must leave in the
- * pool after each pull to avoid starving other readers.
- *
- * Note: extract_entropy() assumes that .poolwords is a multiple of 16 words.
+ * This function decides how many bytes to actually take from the
+ * given pool, and also debits the entropy count accordingly.
  */
-
 static size_t account(struct entropy_store *r, size_t nbytes, int min,
                      int reserved)
 {
-       unsigned long flags;
-       int wakeup_write = 0;
        int have_bytes;
        int entropy_count, orig;
        size_t ibytes;
 
-       /* Hold lock while accounting */
-       spin_lock_irqsave(&r->lock, flags);
-
        BUG_ON(r->entropy_count > r->poolinfo->poolfracbits);
 
        /* Can we pull enough? */
@@ -988,29 +990,19 @@ retry:
        entropy_count = orig = ACCESS_ONCE(r->entropy_count);
        have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
        ibytes = nbytes;
-       if (have_bytes < min + reserved) {
+       /* If limited, never pull more than available */
+       if (r->limit)
+               ibytes = min_t(size_t, ibytes, have_bytes - reserved);
+       if (ibytes < min)
                ibytes = 0;
-       } else {
-               /* If limited, never pull more than available */
-               if (r->limit && ibytes + reserved >= have_bytes)
-                       ibytes = have_bytes - reserved;
-
-               if (have_bytes >= ibytes + reserved)
-                       entropy_count -= ibytes << (ENTROPY_SHIFT + 3);
-               else
-                       entropy_count = reserved << (ENTROPY_SHIFT + 3);
-
-               if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
-                       goto retry;
-
-               if ((r->entropy_count >> ENTROPY_SHIFT)
-                   < random_write_wakeup_thresh)
-                       wakeup_write = 1;
-       }
-       spin_unlock_irqrestore(&r->lock, flags);
+       entropy_count = max_t(int, 0,
+                             entropy_count - (ibytes << (ENTROPY_SHIFT + 3)));
+       if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+               goto retry;
 
        trace_debit_entropy(r->name, 8 * ibytes);
-       if (wakeup_write) {
+       if (ibytes &&
+           (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) {
                wake_up_interruptible(&random_write_wait);
                kill_fasync(&fasync, SIGIO, POLL_OUT);
        }
@@ -1018,6 +1010,12 @@ retry:
        return ibytes;
 }
 
+/*
+ * This function does the actual extraction for extract_entropy and
+ * extract_entropy_user.
+ *
+ * Note: we assume that .poolwords is a multiple of 16 words.
+ */
 static void extract_buf(struct entropy_store *r, __u8 *out)
 {
        int i;
@@ -1029,23 +1027,23 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
        __u8 extract[64];
        unsigned long flags;
 
-       /* Generate a hash across the pool, 16 words (512 bits) at a time */
-       sha_init(hash.w);
-       spin_lock_irqsave(&r->lock, flags);
-       for (i = 0; i < r->poolinfo->poolwords; i += 16)
-               sha_transform(hash.w, (__u8 *)(r->pool + i), workspace);
-
        /*
-        * If we have a architectural hardware random number
-        * generator, mix that in, too.
+        * If we have an architectural hardware random number
+        * generator, use it for SHA's initial vector
         */
+       sha_init(hash.w);
        for (i = 0; i < LONGS(20); i++) {
                unsigned long v;
                if (!arch_get_random_long(&v))
                        break;
-               hash.l[i] ^= v;
+               hash.l[i] = v;
        }
 
+       /* Generate a hash across the pool, 16 words (512 bits) at a time */
+       spin_lock_irqsave(&r->lock, flags);
+       for (i = 0; i < r->poolinfo->poolwords; i += 16)
+               sha_transform(hash.w, (__u8 *)(r->pool + i), workspace);
+
        /*
         * We mix the hash back into the pool to prevent backtracking
         * attacks (where the attacker knows the state of the pool
@@ -1079,6 +1077,15 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
        memset(&hash, 0, sizeof(hash));
 }
 
+/*
+ * This function extracts randomness from the "entropy pool", and
+ * returns it in a buffer.
+ *
+ * The min parameter specifies the minimum amount we can pull before
+ * failing to avoid races that defeat catastrophic reseeding while the
+ * reserved parameter indicates how much entropy we must leave in the
+ * pool after each pull to avoid starving other readers.
+ */
 static ssize_t extract_entropy(struct entropy_store *r, void *buf,
                                 size_t nbytes, int min, int reserved)
 {
@@ -1129,6 +1136,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
        return ret;
 }
 
+/*
+ * This function extracts randomness from the "entropy pool", and
+ * returns it in a userspace buffer.
+ */
 static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
                                    size_t nbytes)
 {
@@ -1170,8 +1181,9 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
 /*
  * This function is the exported kernel interface.  It returns some
  * number of good random numbers, suitable for key generation, seeding
- * TCP sequence numbers, etc.  It does not use the hw random number
- * generator, if available; use get_random_bytes_arch() for that.
+ * TCP sequence numbers, etc.  It does not rely on the hardware random
+ * number generator.  For random bytes direct from the hardware RNG
+ * (when available), use get_random_bytes_arch().
  */
 void get_random_bytes(void *buf, int nbytes)
 {
@@ -1238,7 +1250,8 @@ static void init_std_data(struct entropy_store *r)
        r->last_pulled = jiffies;
        mix_pool_bytes(r, &now, sizeof(now), NULL);
        for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
-               if (!arch_get_random_long(&rv))
+               if (!arch_get_random_seed_long(&rv) &&
+                   !arch_get_random_long(&rv))
                        rv = random_get_entropy();
                mix_pool_bytes(r, &rv, sizeof(rv), NULL);
        }
@@ -1281,56 +1294,71 @@ void rand_initialize_disk(struct gendisk *disk)
 }
 #endif
 
-static ssize_t
-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+/*
+ * Attempt an emergency refill using arch_get_random_seed_long().
+ *
+ * As with add_interrupt_randomness() be paranoid and only
+ * credit the output as 50% entropic.
+ */
+static int arch_random_refill(void)
 {
-       ssize_t n, retval = 0, count = 0;
+       const unsigned int nlongs = 64; /* Arbitrary number */
+       unsigned int n = 0;
+       unsigned int i;
+       unsigned long buf[nlongs];
 
-       if (nbytes == 0)
+       if (!arch_has_random_seed())
                return 0;
 
-       while (nbytes > 0) {
-               n = nbytes;
-               if (n > SEC_XFER_SIZE)
-                       n = SEC_XFER_SIZE;
+       for (i = 0; i < nlongs; i++) {
+               if (arch_get_random_seed_long(&buf[n]))
+                       n++;
+       }
 
-               n = extract_entropy_user(&blocking_pool, buf, n);
+       if (n) {
+               unsigned int rand_bytes = n * sizeof(unsigned long);
 
-               if (n < 0) {
-                       retval = n;
-                       break;
-               }
+               mix_pool_bytes(&input_pool, buf, rand_bytes, NULL);
+               credit_entropy_bits(&input_pool, rand_bytes*4);
+       }
 
+       return n;
+}
+
+static ssize_t
+random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+{
+       ssize_t n;
+
+       if (nbytes == 0)
+               return 0;
+
+       nbytes = min_t(size_t, nbytes, SEC_XFER_SIZE);
+       while (1) {
+               n = extract_entropy_user(&blocking_pool, buf, nbytes);
+               if (n < 0)
+                       return n;
                trace_random_read(n*8, (nbytes-n)*8,
                                  ENTROPY_BITS(&blocking_pool),
                                  ENTROPY_BITS(&input_pool));
+               if (n > 0)
+                       return n;
 
-               if (n == 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               retval = -EAGAIN;
-                               break;
-                       }
-
-                       wait_event_interruptible(random_read_wait,
-                               ENTROPY_BITS(&input_pool) >=
-                               random_read_wakeup_thresh);
-
-                       if (signal_pending(current)) {
-                               retval = -ERESTARTSYS;
-                               break;
-                       }
+               /* Pool is (near) empty.  Maybe wait and retry. */
 
+               /* First try an emergency refill */
+               if (arch_random_refill())
                        continue;
-               }
 
-               count += n;
-               buf += n;
-               nbytes -= n;
-               break;          /* This break makes the device work */
-                               /* like a named pipe */
-       }
+               if (file->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
 
-       return (count ? count : retval);
+               wait_event_interruptible(random_read_wait,
+                       ENTROPY_BITS(&input_pool) >=
+                       random_read_wakeup_bits);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+       }
 }
 
 static ssize_t
@@ -1358,9 +1386,9 @@ random_poll(struct file *file, poll_table * wait)
        poll_wait(file, &random_read_wait, wait);
        poll_wait(file, &random_write_wait, wait);
        mask = 0;
-       if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_thresh)
+       if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)
                mask |= POLLIN | POLLRDNORM;
-       if (ENTROPY_BITS(&input_pool) < random_write_wakeup_thresh)
+       if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits)
                mask |= POLLOUT | POLLWRNORM;
        return mask;
 }
@@ -1507,18 +1535,18 @@ EXPORT_SYMBOL(generate_random_uuid);
 #include <linux/sysctl.h>
 
 static int min_read_thresh = 8, min_write_thresh;
-static int max_read_thresh = INPUT_POOL_WORDS * 32;
+static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
 static int max_write_thresh = INPUT_POOL_WORDS * 32;
 static char sysctl_bootid[16];
 
 /*
- * These functions is used to return both the bootid UUID, and random
+ * This function is used to return both the bootid UUID, and random
  * UUID.  The difference is in whether table->data is NULL; if it is,
  * then a new UUID is generated and returned to the user.
  *
- * If the user accesses this via the proc interface, it will be returned
- * as an ASCII string in the standard UUID format.  If accesses via the
- * sysctl system call, it is returned as 16 bytes of binary data.
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
  */
 static int proc_do_uuid(struct ctl_table *table, int write,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -1583,7 +1611,7 @@ struct ctl_table random_table[] = {
        },
        {
                .procname       = "read_wakeup_threshold",
-               .data           = &random_read_wakeup_thresh,
+               .data           = &random_read_wakeup_bits,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_minmax,
@@ -1592,7 +1620,7 @@ struct ctl_table random_table[] = {
        },
        {
                .procname       = "write_wakeup_threshold",
-               .data           = &random_write_wakeup_thresh,
+               .data           = &random_write_wakeup_bits,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_minmax,
index 7641965d208d62cab3aea35a6af460b8e3ea1c2a..6f56d3a4f01063d06698c46c88e1fce27a096aab 100644 (file)
@@ -65,10 +65,12 @@ config COMMON_CLK_SI570
          clock generators.
 
 config COMMON_CLK_S2MPS11
-       tristate "Clock driver for S2MPS11 MFD"
+       tristate "Clock driver for S2MPS11/S5M8767 MFD"
        depends on MFD_SEC_CORE
        ---help---
-         This driver supports S2MPS11 crystal oscillator clock.
+         This driver supports S2MPS11/S5M8767 crystal oscillator clock. These
+         multi-function devices have 3 fixed-rate oscillators, clocked at
+         32KHz each.
 
 config CLK_TWL6040
        tristate "External McPDM functional clock from twl6040"
@@ -111,4 +113,5 @@ source "drivers/clk/qcom/Kconfig"
 
 endmenu
 
+source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
index a367a98317175f59745e5b61e6fdf175f29342bc..5f8a28735c9661acdec4d5631899b12dc59f97c4 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_ARCH_EFM32)              += clk-efm32gg.o
 obj-$(CONFIG_ARCH_HIGHBANK)            += clk-highbank.o
 obj-$(CONFIG_MACH_LOONGSON1)           += clk-ls1x.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)      += clk-max77686.o
+obj-$(CONFIG_ARCH_MOXART)              += clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)             += clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)              += clk-nspire.o
 obj-$(CONFIG_CLK_PPC_CORENET)          += clk-ppc-corenet.o
@@ -29,7 +30,9 @@ obj-$(CONFIG_ARCH_VT8500)             += clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_WM831X)                += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)         += clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_AT91)          += at91/
+obj-$(CONFIG_ARCH_BCM_MOBILE)          += bcm/
 obj-$(CONFIG_ARCH_HI3xxx)              += hisilicon/
+obj-$(CONFIG_ARCH_HIP04)               += hisilicon/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)      += keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)                 += mmp/
@@ -43,6 +46,7 @@ obj-$(CONFIG_ARCH_SHMOBILE_MULTI)     += shmobile/
 obj-$(CONFIG_ARCH_SIRF)                        += sirf/
 obj-$(CONFIG_ARCH_SOCFPGA)             += socfpga/
 obj-$(CONFIG_PLAT_SPEAR)               += spear/
+obj-$(CONFIG_ARCH_STI)                 += st/
 obj-$(CONFIG_ARCH_SUNXI)               += sunxi/
 obj-$(CONFIG_ARCH_TEGRA)               += tegra/
 obj-$(CONFIG_ARCH_OMAP2PLUS)           += ti/
index fd792b203eaf2fcf1ca8037a86b34247ba94e36f..62e2509f9df16d52352da1d4aaa13b06d65b4824 100644 (file)
 #include <linux/clk/at91_pmc.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_irq.h>
 #include <linux/io.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
 
 #include "pmc.h"
 
@@ -38,104 +35,59 @@ struct clk_programmable_layout {
 struct clk_programmable {
        struct clk_hw hw;
        struct at91_pmc *pmc;
-       unsigned int irq;
-       wait_queue_head_t wait;
        u8 id;
-       u8 css;
-       u8 pres;
-       u8 slckmck;
        const struct clk_programmable_layout *layout;
 };
 
 #define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw)
 
-
-static irqreturn_t clk_programmable_irq_handler(int irq, void *dev_id)
-{
-       struct clk_programmable *prog = (struct clk_programmable *)dev_id;
-
-       wake_up(&prog->wait);
-
-       return IRQ_HANDLED;
-}
-
-static int clk_programmable_prepare(struct clk_hw *hw)
+static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
 {
-       u32 tmp;
+       u32 pres;
        struct clk_programmable *prog = to_clk_programmable(hw);
        struct at91_pmc *pmc = prog->pmc;
        const struct clk_programmable_layout *layout = prog->layout;
-       u8 id = prog->id;
-       u32 mask = PROG_STATUS_MASK(id);
-
-       tmp = prog->css | (prog->pres << layout->pres_shift);
-       if (layout->have_slck_mck && prog->slckmck)
-               tmp |= AT91_PMC_CSSMCK_MCK;
-
-       pmc_write(pmc, AT91_PMC_PCKR(id), tmp);
-
-       while (!(pmc_read(pmc, AT91_PMC_SR) & mask))
-               wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask);
 
-       return 0;
+       pres = (pmc_read(pmc, AT91_PMC_PCKR(prog->id)) >> layout->pres_shift) &
+              PROG_PRES_MASK;
+       return parent_rate >> pres;
 }
 
-static int clk_programmable_is_ready(struct clk_hw *hw)
+static long clk_programmable_determine_rate(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long *best_parent_rate,
+                                           struct clk **best_parent_clk)
 {
-       struct clk_programmable *prog = to_clk_programmable(hw);
-       struct at91_pmc *pmc = prog->pmc;
-
-       return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id));
-}
+       struct clk *parent = NULL;
+       long best_rate = -EINVAL;
+       unsigned long parent_rate;
+       unsigned long tmp_rate;
+       int shift;
+       int i;
 
-static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       u32 tmp;
-       struct clk_programmable *prog = to_clk_programmable(hw);
-       struct at91_pmc *pmc = prog->pmc;
-       const struct clk_programmable_layout *layout = prog->layout;
+       for (i = 0; i < __clk_get_num_parents(hw->clk); i++) {
+               parent = clk_get_parent_by_index(hw->clk, i);
+               if (!parent)
+                       continue;
 
-       tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
-       prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK;
+               parent_rate = __clk_get_rate(parent);
+               for (shift = 0; shift < PROG_PRES_MASK; shift++) {
+                       tmp_rate = parent_rate >> shift;
+                       if (tmp_rate <= rate)
+                               break;
+               }
 
-       return parent_rate >> prog->pres;
-}
+               if (tmp_rate > rate)
+                       continue;
 
-static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate,
-                                       unsigned long *parent_rate)
-{
-       unsigned long best_rate = *parent_rate;
-       unsigned long best_diff;
-       unsigned long new_diff;
-       unsigned long cur_rate;
-       int shift = shift;
-
-       if (rate > *parent_rate)
-               return *parent_rate;
-       else
-               best_diff = *parent_rate - rate;
-
-       if (!best_diff)
-               return best_rate;
-
-       for (shift = 1; shift < PROG_PRES_MASK; shift++) {
-               cur_rate = *parent_rate >> shift;
-
-               if (cur_rate > rate)
-                       new_diff = cur_rate - rate;
-               else
-                       new_diff = rate - cur_rate;
-
-               if (!new_diff)
-                       return cur_rate;
-
-               if (new_diff < best_diff) {
-                       best_diff = new_diff;
-                       best_rate = cur_rate;
+               if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) {
+                       best_rate = tmp_rate;
+                       *best_parent_rate = parent_rate;
+                       *best_parent_clk = parent;
                }
 
-               if (rate > cur_rate)
+               if (!best_rate)
                        break;
        }
 
@@ -146,17 +98,22 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
 {
        struct clk_programmable *prog = to_clk_programmable(hw);
        const struct clk_programmable_layout *layout = prog->layout;
+       struct at91_pmc *pmc = prog->pmc;
+       u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & ~layout->css_mask;
+
+       if (layout->have_slck_mck)
+               tmp &= AT91_PMC_CSSMCK_MCK;
+
        if (index > layout->css_mask) {
                if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) {
-                       prog->css = 0;
-                       prog->slckmck = 1;
+                       tmp |= AT91_PMC_CSSMCK_MCK;
                        return 0;
                } else {
                        return -EINVAL;
                }
        }
 
-       prog->css = index;
+       pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | index);
        return 0;
 }
 
@@ -169,13 +126,9 @@ static u8 clk_programmable_get_parent(struct clk_hw *hw)
        const struct clk_programmable_layout *layout = prog->layout;
 
        tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
-       prog->css = tmp & layout->css_mask;
-       ret = prog->css;
-       if (layout->have_slck_mck) {
-               prog->slckmck = !!(tmp & AT91_PMC_CSSMCK_MCK);
-               if (prog->slckmck && !ret)
-                       ret = PROG_MAX_RM9200_CSS + 1;
-       }
+       ret = tmp & layout->css_mask;
+       if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !ret)
+               ret = PROG_MAX_RM9200_CSS + 1;
 
        return ret;
 }
@@ -184,67 +137,47 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
                                     unsigned long parent_rate)
 {
        struct clk_programmable *prog = to_clk_programmable(hw);
-       unsigned long best_rate = parent_rate;
-       unsigned long best_diff;
-       unsigned long new_diff;
-       unsigned long cur_rate;
+       struct at91_pmc *pmc = prog->pmc;
+       const struct clk_programmable_layout *layout = prog->layout;
+       unsigned long div = parent_rate / rate;
        int shift = 0;
+       u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
+                 ~(PROG_PRES_MASK << layout->pres_shift);
 
-       if (rate > parent_rate)
-               return parent_rate;
-       else
-               best_diff = parent_rate - rate;
-
-       if (!best_diff) {
-               prog->pres = shift;
-               return 0;
-       }
+       if (!div)
+               return -EINVAL;
 
-       for (shift = 1; shift < PROG_PRES_MASK; shift++) {
-               cur_rate = parent_rate >> shift;
+       shift = fls(div) - 1;
 
-               if (cur_rate > rate)
-                       new_diff = cur_rate - rate;
-               else
-                       new_diff = rate - cur_rate;
+       if (div != (1<<shift))
+               return -EINVAL;
 
-               if (!new_diff)
-                       break;
+       if (shift >= PROG_PRES_MASK)
+               return -EINVAL;
 
-               if (new_diff < best_diff) {
-                       best_diff = new_diff;
-                       best_rate = cur_rate;
-               }
+       pmc_write(pmc, AT91_PMC_PCKR(prog->id),
+                 tmp | (shift << layout->pres_shift));
 
-               if (rate > cur_rate)
-                       break;
-       }
-
-       prog->pres = shift;
        return 0;
 }
 
 static const struct clk_ops programmable_ops = {
-       .prepare = clk_programmable_prepare,
-       .is_prepared = clk_programmable_is_ready,
        .recalc_rate = clk_programmable_recalc_rate,
-       .round_rate = clk_programmable_round_rate,
+       .determine_rate = clk_programmable_determine_rate,
        .get_parent = clk_programmable_get_parent,
        .set_parent = clk_programmable_set_parent,
        .set_rate = clk_programmable_set_rate,
 };
 
 static struct clk * __init
-at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
+at91_clk_register_programmable(struct at91_pmc *pmc,
                               const char *name, const char **parent_names,
                               u8 num_parents, u8 id,
                               const struct clk_programmable_layout *layout)
 {
-       int ret;
        struct clk_programmable *prog;
        struct clk *clk = NULL;
        struct clk_init_data init;
-       char irq_name[11];
 
        if (id > PROG_ID_MAX)
                return ERR_PTR(-EINVAL);
@@ -263,14 +196,6 @@ at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
        prog->layout = layout;
        prog->hw.init = &init;
        prog->pmc = pmc;
-       prog->irq = irq;
-       init_waitqueue_head(&prog->wait);
-       irq_set_status_flags(prog->irq, IRQ_NOAUTOEN);
-       snprintf(irq_name, sizeof(irq_name), "clk-prog%d", id);
-       ret = request_irq(prog->irq, clk_programmable_irq_handler,
-                         IRQF_TRIGGER_HIGH, irq_name, prog);
-       if (ret)
-               return ERR_PTR(ret);
 
        clk = clk_register(NULL, &prog->hw);
        if (IS_ERR(clk))
@@ -304,7 +229,6 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
        int num;
        u32 id;
        int i;
-       unsigned int irq;
        struct clk *clk;
        int num_parents;
        const char *parent_names[PROG_SOURCE_MAX];
@@ -332,11 +256,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
                if (of_property_read_string(np, "clock-output-names", &name))
                        name = progclknp->name;
 
-               irq = irq_of_parse_and_map(progclknp, 0);
-               if (!irq)
-                       continue;
-
-               clk = at91_clk_register_programmable(pmc, irq, name,
+               clk = at91_clk_register_programmable(pmc, name,
                                                     parent_names, num_parents,
                                                     id, layout);
                if (IS_ERR(clk))
index 8f7c0434a09f6020daf5685a7e07d72190c1a9ca..8c96307d736343e3cbc6924c09580408f32c2da7 100644 (file)
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 
 #include "pmc.h"
 
 struct clk_system {
        struct clk_hw hw;
        struct at91_pmc *pmc;
+       unsigned int irq;
+       wait_queue_head_t wait;
        u8 id;
 };
 
-static int clk_system_enable(struct clk_hw *hw)
+static inline int is_pck(int id)
+{
+       return (id >= 8) && (id <= 15);
+}
+static irqreturn_t clk_system_irq_handler(int irq, void *dev_id)
+{
+       struct clk_system *sys = (struct clk_system *)dev_id;
+
+       wake_up(&sys->wait);
+       disable_irq_nosync(sys->irq);
+
+       return IRQ_HANDLED;
+}
+
+static int clk_system_prepare(struct clk_hw *hw)
 {
        struct clk_system *sys = to_clk_system(hw);
        struct at91_pmc *pmc = sys->pmc;
+       u32 mask = 1 << sys->id;
 
-       pmc_write(pmc, AT91_PMC_SCER, 1 << sys->id);
+       pmc_write(pmc, AT91_PMC_SCER, mask);
+
+       if (!is_pck(sys->id))
+               return 0;
+
+       while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
+               if (sys->irq) {
+                       enable_irq(sys->irq);
+                       wait_event(sys->wait,
+                                  pmc_read(pmc, AT91_PMC_SR) & mask);
+               } else
+                       cpu_relax();
+       }
        return 0;
 }
 
-static void clk_system_disable(struct clk_hw *hw)
+static void clk_system_unprepare(struct clk_hw *hw)
 {
        struct clk_system *sys = to_clk_system(hw);
        struct at91_pmc *pmc = sys->pmc;
@@ -45,27 +79,34 @@ static void clk_system_disable(struct clk_hw *hw)
        pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
 }
 
-static int clk_system_is_enabled(struct clk_hw *hw)
+static int clk_system_is_prepared(struct clk_hw *hw)
 {
        struct clk_system *sys = to_clk_system(hw);
        struct at91_pmc *pmc = sys->pmc;
 
-       return !!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id));
+       if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)))
+               return 0;
+
+       if (!is_pck(sys->id))
+               return 1;
+
+       return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id));
 }
 
 static const struct clk_ops system_ops = {
-       .enable = clk_system_enable,
-       .disable = clk_system_disable,
-       .is_enabled = clk_system_is_enabled,
+       .prepare = clk_system_prepare,
+       .unprepare = clk_system_unprepare,
+       .is_prepared = clk_system_is_prepared,
 };
 
 static struct clk * __init
 at91_clk_register_system(struct at91_pmc *pmc, const char *name,
-                        const char *parent_name, u8 id)
+                        const char *parent_name, u8 id, int irq)
 {
        struct clk_system *sys;
        struct clk *clk = NULL;
        struct clk_init_data init;
+       int ret;
 
        if (!parent_name || id > SYSTEM_MAX_ID)
                return ERR_PTR(-EINVAL);
@@ -84,11 +125,20 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
         * (see drivers/memory) which would request and enable the ddrck clock.
         * When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
         */
-       init.flags = CLK_IGNORE_UNUSED;
+       init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
 
        sys->id = id;
        sys->hw.init = &init;
        sys->pmc = pmc;
+       sys->irq = irq;
+       if (irq) {
+               init_waitqueue_head(&sys->wait);
+               irq_set_status_flags(sys->irq, IRQ_NOAUTOEN);
+               ret = request_irq(sys->irq, clk_system_irq_handler,
+                               IRQF_TRIGGER_HIGH, name, sys);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
 
        clk = clk_register(NULL, &sys->hw);
        if (IS_ERR(clk))
@@ -101,6 +151,7 @@ static void __init
 of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
 {
        int num;
+       int irq = 0;
        u32 id;
        struct clk *clk;
        const char *name;
@@ -118,9 +169,12 @@ of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
                if (of_property_read_string(np, "clock-output-names", &name))
                        name = sysclknp->name;
 
+               if (is_pck(id))
+                       irq = irq_of_parse_and_map(sysclknp, 0);
+
                parent_name = of_clk_get_parent_name(sysclknp, 0);
 
-               clk = at91_clk_register_system(pmc, name, parent_name, id);
+               clk = at91_clk_register_system(pmc, name, parent_name, id, irq);
                if (IS_ERR(clk))
                        continue;
 
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
new file mode 100644 (file)
index 0000000..a7262fb
--- /dev/null
@@ -0,0 +1,9 @@
+config CLK_BCM_KONA
+       bool "Broadcom Kona CCU clock support"
+       depends on ARCH_BCM_MOBILE
+       depends on COMMON_CLK
+       default y
+       help
+         Enable common clock framework support for Broadcom SoCs
+         using "Kona" style clock control units, including those
+         in the BCM281xx family.
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
new file mode 100644 (file)
index 0000000..cf93359
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_CLK_BCM_KONA)     += clk-kona.o
+obj-$(CONFIG_CLK_BCM_KONA)     += clk-kona-setup.o
+obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm281xx.o
diff --git a/drivers/clk/bcm/clk-bcm281xx.c b/drivers/clk/bcm/clk-bcm281xx.c
new file mode 100644 (file)
index 0000000..3c66de6
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ * Copyright 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "clk-kona.h"
+#include "dt-bindings/clock/bcm281xx.h"
+
+/* bcm11351 CCU device tree "compatible" strings */
+#define BCM11351_DT_ROOT_CCU_COMPAT    "brcm,bcm11351-root-ccu"
+#define BCM11351_DT_AON_CCU_COMPAT     "brcm,bcm11351-aon-ccu"
+#define BCM11351_DT_HUB_CCU_COMPAT     "brcm,bcm11351-hub-ccu"
+#define BCM11351_DT_MASTER_CCU_COMPAT  "brcm,bcm11351-master-ccu"
+#define BCM11351_DT_SLAVE_CCU_COMPAT   "brcm,bcm11351-slave-ccu"
+
+/* Root CCU clocks */
+
+static struct peri_clk_data frac_1m_data = {
+       .gate           = HW_SW_GATE(0x214, 16, 0, 1),
+       .trig           = TRIGGER(0x0e04, 0),
+       .div            = FRAC_DIVIDER(0x0e00, 0, 22, 16),
+       .clocks         = CLOCKS("ref_crystal"),
+};
+
+/* AON CCU clocks */
+
+static struct peri_clk_data hub_timer_data = {
+       .gate           = HW_SW_GATE(0x0414, 16, 0, 1),
+       .clocks         = CLOCKS("bbl_32k",
+                                "frac_1m",
+                                "dft_19_5m"),
+       .sel            = SELECTOR(0x0a10, 0, 2),
+       .trig           = TRIGGER(0x0a40, 4),
+};
+
+static struct peri_clk_data pmu_bsc_data = {
+       .gate           = HW_SW_GATE(0x0418, 16, 0, 1),
+       .clocks         = CLOCKS("ref_crystal",
+                                "pmu_bsc_var",
+                                "bbl_32k"),
+       .sel            = SELECTOR(0x0a04, 0, 2),
+       .div            = DIVIDER(0x0a04, 3, 4),
+       .trig           = TRIGGER(0x0a40, 0),
+};
+
+static struct peri_clk_data pmu_bsc_var_data = {
+       .clocks         = CLOCKS("var_312m",
+                                "ref_312m"),
+       .sel            = SELECTOR(0x0a00, 0, 2),
+       .div            = DIVIDER(0x0a00, 4, 5),
+       .trig           = TRIGGER(0x0a40, 2),
+};
+
+/* Hub CCU clocks */
+
+static struct peri_clk_data tmon_1m_data = {
+       .gate           = HW_SW_GATE(0x04a4, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "frac_1m"),
+       .sel            = SELECTOR(0x0e74, 0, 2),
+       .trig           = TRIGGER(0x0e84, 1),
+};
+
+/* Master CCU clocks */
+
+static struct peri_clk_data sdio1_data = {
+       .gate           = HW_SW_GATE(0x0358, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_52m",
+                                "ref_52m",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a28, 0, 3),
+       .div            = DIVIDER(0x0a28, 4, 14),
+       .trig           = TRIGGER(0x0afc, 9),
+};
+
+static struct peri_clk_data sdio2_data = {
+       .gate           = HW_SW_GATE(0x035c, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_52m",
+                                "ref_52m",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a2c, 0, 3),
+       .div            = DIVIDER(0x0a2c, 4, 14),
+       .trig           = TRIGGER(0x0afc, 10),
+};
+
+static struct peri_clk_data sdio3_data = {
+       .gate           = HW_SW_GATE(0x0364, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_52m",
+                                "ref_52m",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a34, 0, 3),
+       .div            = DIVIDER(0x0a34, 4, 14),
+       .trig           = TRIGGER(0x0afc, 12),
+};
+
+static struct peri_clk_data sdio4_data = {
+       .gate           = HW_SW_GATE(0x0360, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_52m",
+                                "ref_52m",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a30, 0, 3),
+       .div            = DIVIDER(0x0a30, 4, 14),
+       .trig           = TRIGGER(0x0afc, 11),
+};
+
+static struct peri_clk_data usb_ic_data = {
+       .gate           = HW_SW_GATE(0x0354, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_96m",
+                                "ref_96m"),
+       .div            = FIXED_DIVIDER(2),
+       .sel            = SELECTOR(0x0a24, 0, 2),
+       .trig           = TRIGGER(0x0afc, 7),
+};
+
+/* also called usbh_48m */
+static struct peri_clk_data hsic2_48m_data = {
+       .gate           = HW_SW_GATE(0x0370, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a38, 0, 2),
+       .div            = FIXED_DIVIDER(2),
+       .trig           = TRIGGER(0x0afc, 5),
+};
+
+/* also called usbh_12m */
+static struct peri_clk_data hsic2_12m_data = {
+       .gate           = HW_SW_GATE(0x0370, 20, 4, 5),
+       .div            = DIVIDER(0x0a38, 12, 2),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_96m",
+                                "ref_96m"),
+       .pre_div        = FIXED_DIVIDER(2),
+       .sel            = SELECTOR(0x0a38, 0, 2),
+       .trig           = TRIGGER(0x0afc, 5),
+};
+
+/* Slave CCU clocks */
+
+static struct peri_clk_data uartb_data = {
+       .gate           = HW_SW_GATE(0x0400, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_156m",
+                                "ref_156m"),
+       .sel            = SELECTOR(0x0a10, 0, 2),
+       .div            = FRAC_DIVIDER(0x0a10, 4, 12, 8),
+       .trig           = TRIGGER(0x0afc, 2),
+};
+
+static struct peri_clk_data uartb2_data = {
+       .gate           = HW_SW_GATE(0x0404, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_156m",
+                                "ref_156m"),
+       .sel            = SELECTOR(0x0a14, 0, 2),
+       .div            = FRAC_DIVIDER(0x0a14, 4, 12, 8),
+       .trig           = TRIGGER(0x0afc, 3),
+};
+
+static struct peri_clk_data uartb3_data = {
+       .gate           = HW_SW_GATE(0x0408, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_156m",
+                                "ref_156m"),
+       .sel            = SELECTOR(0x0a18, 0, 2),
+       .div            = FRAC_DIVIDER(0x0a18, 4, 12, 8),
+       .trig           = TRIGGER(0x0afc, 4),
+};
+
+static struct peri_clk_data uartb4_data = {
+       .gate           = HW_SW_GATE(0x0408, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_156m",
+                                "ref_156m"),
+       .sel            = SELECTOR(0x0a1c, 0, 2),
+       .div            = FRAC_DIVIDER(0x0a1c, 4, 12, 8),
+       .trig           = TRIGGER(0x0afc, 5),
+};
+
+static struct peri_clk_data ssp0_data = {
+       .gate           = HW_SW_GATE(0x0410, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_104m",
+                                "ref_104m",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a20, 0, 3),
+       .div            = DIVIDER(0x0a20, 4, 14),
+       .trig           = TRIGGER(0x0afc, 6),
+};
+
+static struct peri_clk_data ssp2_data = {
+       .gate           = HW_SW_GATE(0x0418, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_104m",
+                                "ref_104m",
+                                "var_96m",
+                                "ref_96m"),
+       .sel            = SELECTOR(0x0a28, 0, 3),
+       .div            = DIVIDER(0x0a28, 4, 14),
+       .trig           = TRIGGER(0x0afc, 8),
+};
+
+static struct peri_clk_data bsc1_data = {
+       .gate           = HW_SW_GATE(0x0458, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_104m",
+                                "ref_104m",
+                                "var_13m",
+                                "ref_13m"),
+       .sel            = SELECTOR(0x0a64, 0, 3),
+       .trig           = TRIGGER(0x0afc, 23),
+};
+
+static struct peri_clk_data bsc2_data = {
+       .gate           = HW_SW_GATE(0x045c, 18, 2, 3),
+       .clocks = CLOCKS("ref_crystal",
+                                "var_104m",
+                                "ref_104m",
+                                "var_13m",
+                                "ref_13m"),
+       .sel            = SELECTOR(0x0a68, 0, 3),
+       .trig           = TRIGGER(0x0afc, 24),
+};
+
+static struct peri_clk_data bsc3_data = {
+       .gate           = HW_SW_GATE(0x0484, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_104m",
+                                "ref_104m",
+                                "var_13m",
+                                "ref_13m"),
+       .sel            = SELECTOR(0x0a84, 0, 3),
+       .trig           = TRIGGER(0x0b00, 2),
+};
+
+static struct peri_clk_data pwm_data = {
+       .gate           = HW_SW_GATE(0x0468, 18, 2, 3),
+       .clocks         = CLOCKS("ref_crystal",
+                                "var_104m"),
+       .sel            = SELECTOR(0x0a70, 0, 2),
+       .div            = DIVIDER(0x0a70, 4, 3),
+       .trig           = TRIGGER(0x0afc, 15),
+};
+
+/*
+ * CCU setup routines
+ *
+ * These are called from kona_dt_ccu_setup() to initialize the array
+ * of clocks provided by the CCU.  Once allocated, the entries in
+ * the array are initialized by calling kona_clk_setup() with the
+ * initialization data for each clock.  They return 0 if successful
+ * or an error code otherwise.
+ */
+static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu)
+{
+       struct clk **clks;
+       size_t count = BCM281XX_ROOT_CCU_CLOCK_COUNT;
+
+       clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
+       if (!clks) {
+               pr_err("%s: failed to allocate root clocks\n", __func__);
+               return -ENOMEM;
+       }
+       ccu->data.clks = clks;
+       ccu->data.clk_num = count;
+
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m);
+
+       return 0;
+}
+
+static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu)
+{
+       struct clk **clks;
+       size_t count = BCM281XX_AON_CCU_CLOCK_COUNT;
+
+       clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
+       if (!clks) {
+               pr_err("%s: failed to allocate aon clocks\n", __func__);
+               return -ENOMEM;
+       }
+       ccu->data.clks = clks;
+       ccu->data.clk_num = count;
+
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var);
+
+       return 0;
+}
+
+static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu)
+{
+       struct clk **clks;
+       size_t count = BCM281XX_HUB_CCU_CLOCK_COUNT;
+
+       clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
+       if (!clks) {
+               pr_err("%s: failed to allocate hub clocks\n", __func__);
+               return -ENOMEM;
+       }
+       ccu->data.clks = clks;
+       ccu->data.clk_num = count;
+
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m);
+
+       return 0;
+}
+
+static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu)
+{
+       struct clk **clks;
+       size_t count = BCM281XX_MASTER_CCU_CLOCK_COUNT;
+
+       clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
+       if (!clks) {
+               pr_err("%s: failed to allocate master clocks\n", __func__);
+               return -ENOMEM;
+       }
+       ccu->data.clks = clks;
+       ccu->data.clk_num = count;
+
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m);
+
+       return 0;
+}
+
+static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu)
+{
+       struct clk **clks;
+       size_t count = BCM281XX_SLAVE_CCU_CLOCK_COUNT;
+
+       clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
+       if (!clks) {
+               pr_err("%s: failed to allocate slave clocks\n", __func__);
+               return -ENOMEM;
+       }
+       ccu->data.clks = clks;
+       ccu->data.clk_num = count;
+
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB, uartb);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3);
+       PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_PWM, pwm);
+
+       return 0;
+}
+
+/* Device tree match table callback functions */
+
+static void __init kona_dt_root_ccu_setup(struct device_node *node)
+{
+       kona_dt_ccu_setup(node, bcm281xx_root_ccu_clks_setup);
+}
+
+static void __init kona_dt_aon_ccu_setup(struct device_node *node)
+{
+       kona_dt_ccu_setup(node, bcm281xx_aon_ccu_clks_setup);
+}
+
+static void __init kona_dt_hub_ccu_setup(struct device_node *node)
+{
+       kona_dt_ccu_setup(node, bcm281xx_hub_ccu_clks_setup);
+}
+
+static void __init kona_dt_master_ccu_setup(struct device_node *node)
+{
+       kona_dt_ccu_setup(node, bcm281xx_master_ccu_clks_setup);
+}
+
+static void __init kona_dt_slave_ccu_setup(struct device_node *node)
+{
+       kona_dt_ccu_setup(node, bcm281xx_slave_ccu_clks_setup);
+}
+
+CLK_OF_DECLARE(bcm11351_root_ccu, BCM11351_DT_ROOT_CCU_COMPAT,
+                       kona_dt_root_ccu_setup);
+CLK_OF_DECLARE(bcm11351_aon_ccu, BCM11351_DT_AON_CCU_COMPAT,
+                       kona_dt_aon_ccu_setup);
+CLK_OF_DECLARE(bcm11351_hub_ccu, BCM11351_DT_HUB_CCU_COMPAT,
+                       kona_dt_hub_ccu_setup);
+CLK_OF_DECLARE(bcm11351_master_ccu, BCM11351_DT_MASTER_CCU_COMPAT,
+                       kona_dt_master_ccu_setup);
+CLK_OF_DECLARE(bcm11351_slave_ccu, BCM11351_DT_SLAVE_CCU_COMPAT,
+                       kona_dt_slave_ccu_setup);
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
new file mode 100644 (file)
index 0000000..c7607fe
--- /dev/null
@@ -0,0 +1,769 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ * Copyright 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <linux/of_address.h>
+
+#include "clk-kona.h"
+
+/* These are used when a selector or trigger is found to be unneeded */
+#define selector_clear_exists(sel)     ((sel)->width = 0)
+#define trigger_clear_exists(trig)     FLAG_CLEAR(trig, TRIG, EXISTS)
+
+LIST_HEAD(ccu_list);   /* The list of set up CCUs */
+
+/* Validity checking */
+
+static bool clk_requires_trigger(struct kona_clk *bcm_clk)
+{
+       struct peri_clk_data *peri = bcm_clk->peri;
+       struct bcm_clk_sel *sel;
+       struct bcm_clk_div *div;
+
+       if (bcm_clk->type != bcm_clk_peri)
+               return false;
+
+       sel = &peri->sel;
+       if (sel->parent_count && selector_exists(sel))
+               return true;
+
+       div = &peri->div;
+       if (!divider_exists(div))
+               return false;
+
+       /* Fixed dividers don't need triggers */
+       if (!divider_is_fixed(div))
+               return true;
+
+       div = &peri->pre_div;
+
+       return divider_exists(div) && !divider_is_fixed(div);
+}
+
+static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk)
+{
+       struct peri_clk_data *peri;
+       struct bcm_clk_gate *gate;
+       struct bcm_clk_div *div;
+       struct bcm_clk_sel *sel;
+       struct bcm_clk_trig *trig;
+       const char *name;
+       u32 range;
+       u32 limit;
+
+       BUG_ON(bcm_clk->type != bcm_clk_peri);
+       peri = bcm_clk->peri;
+       name = bcm_clk->name;
+       range = bcm_clk->ccu->range;
+
+       limit = range - sizeof(u32);
+       limit = round_down(limit, sizeof(u32));
+
+       gate = &peri->gate;
+       if (gate_exists(gate)) {
+               if (gate->offset > limit) {
+                       pr_err("%s: bad gate offset for %s (%u > %u)\n",
+                               __func__, name, gate->offset, limit);
+                       return false;
+               }
+       }
+
+       div = &peri->div;
+       if (divider_exists(div)) {
+               if (div->offset > limit) {
+                       pr_err("%s: bad divider offset for %s (%u > %u)\n",
+                               __func__, name, div->offset, limit);
+                       return false;
+               }
+       }
+
+       div = &peri->pre_div;
+       if (divider_exists(div)) {
+               if (div->offset > limit) {
+                       pr_err("%s: bad pre-divider offset for %s "
+                                       "(%u > %u)\n",
+                               __func__, name, div->offset, limit);
+                       return false;
+               }
+       }
+
+       sel = &peri->sel;
+       if (selector_exists(sel)) {
+               if (sel->offset > limit) {
+                       pr_err("%s: bad selector offset for %s (%u > %u)\n",
+                               __func__, name, sel->offset, limit);
+                       return false;
+               }
+       }
+
+       trig = &peri->trig;
+       if (trigger_exists(trig)) {
+               if (trig->offset > limit) {
+                       pr_err("%s: bad trigger offset for %s (%u > %u)\n",
+                               __func__, name, trig->offset, limit);
+                       return false;
+               }
+       }
+
+       trig = &peri->pre_trig;
+       if (trigger_exists(trig)) {
+               if (trig->offset > limit) {
+                       pr_err("%s: bad pre-trigger offset for %s (%u > %u)\n",
+                               __func__, name, trig->offset, limit);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+/* A bit position must be less than the number of bits in a 32-bit register. */
+static bool bit_posn_valid(u32 bit_posn, const char *field_name,
+                       const char *clock_name)
+{
+       u32 limit = BITS_PER_BYTE * sizeof(u32) - 1;
+
+       if (bit_posn > limit) {
+               pr_err("%s: bad %s bit for %s (%u > %u)\n", __func__,
+                       field_name, clock_name, bit_posn, limit);
+               return false;
+       }
+       return true;
+}
+
+/*
+ * A bitfield must be at least 1 bit wide.  Both the low-order and
+ * high-order bits must lie within a 32-bit register.  We require
+ * fields to be less than 32 bits wide, mainly because we use
+ * shifting to produce field masks, and shifting a full word width
+ * is not well-defined by the C standard.
+ */
+static bool bitfield_valid(u32 shift, u32 width, const char *field_name,
+                       const char *clock_name)
+{
+       u32 limit = BITS_PER_BYTE * sizeof(u32);
+
+       if (!width) {
+               pr_err("%s: bad %s field width 0 for %s\n", __func__,
+                       field_name, clock_name);
+               return false;
+       }
+       if (shift + width > limit) {
+               pr_err("%s: bad %s for %s (%u + %u > %u)\n", __func__,
+                       field_name, clock_name, shift, width, limit);
+               return false;
+       }
+       return true;
+}
+
+/*
+ * All gates, if defined, have a status bit, and for hardware-only
+ * gates, that's it.  Gates that can be software controlled also
+ * have an enable bit.  And a gate that can be hardware or software
+ * controlled will have a hardware/software select bit.
+ */
+static bool gate_valid(struct bcm_clk_gate *gate, const char *field_name,
+                       const char *clock_name)
+{
+       if (!bit_posn_valid(gate->status_bit, "gate status", clock_name))
+               return false;
+
+       if (gate_is_sw_controllable(gate)) {
+               if (!bit_posn_valid(gate->en_bit, "gate enable", clock_name))
+                       return false;
+
+               if (gate_is_hw_controllable(gate)) {
+                       if (!bit_posn_valid(gate->hw_sw_sel_bit,
+                                               "gate hw/sw select",
+                                               clock_name))
+                               return false;
+               }
+       } else {
+               BUG_ON(!gate_is_hw_controllable(gate));
+       }
+
+       return true;
+}
+
+/*
+ * A selector bitfield must be valid.  Its parent_sel array must
+ * also be reasonable for the field.
+ */
+static bool sel_valid(struct bcm_clk_sel *sel, const char *field_name,
+                       const char *clock_name)
+{
+       if (!bitfield_valid(sel->shift, sel->width, field_name, clock_name))
+               return false;
+
+       if (sel->parent_count) {
+               u32 max_sel;
+               u32 limit;
+
+               /*
+                * Make sure the selector field can hold all the
+                * selector values we expect to be able to use.  A
+                * clock only needs to have a selector defined if it
+                * has more than one parent.  And in that case the
+                * highest selector value will be in the last entry
+                * in the array.
+                */
+               max_sel = sel->parent_sel[sel->parent_count - 1];
+               limit = (1 << sel->width) - 1;
+               if (max_sel > limit) {
+                       pr_err("%s: bad selector for %s "
+                                       "(%u needs > %u bits)\n",
+                               __func__, clock_name, max_sel,
+                               sel->width);
+                       return false;
+               }
+       } else {
+               pr_warn("%s: ignoring selector for %s (no parents)\n",
+                       __func__, clock_name);
+               selector_clear_exists(sel);
+               kfree(sel->parent_sel);
+               sel->parent_sel = NULL;
+       }
+
+       return true;
+}
+
+/*
+ * A fixed divider just needs to be non-zero.  A variable divider
+ * has to have a valid divider bitfield, and if it has a fraction,
+ * the width of the fraction must not be no more than the width of
+ * the divider as a whole.
+ */
+static bool div_valid(struct bcm_clk_div *div, const char *field_name,
+                       const char *clock_name)
+{
+       if (divider_is_fixed(div)) {
+               /* Any fixed divider value but 0 is OK */
+               if (div->fixed == 0) {
+                       pr_err("%s: bad %s fixed value 0 for %s\n", __func__,
+                               field_name, clock_name);
+                       return false;
+               }
+               return true;
+       }
+       if (!bitfield_valid(div->shift, div->width, field_name, clock_name))
+               return false;
+
+       if (divider_has_fraction(div))
+               if (div->frac_width > div->width) {
+                       pr_warn("%s: bad %s fraction width for %s (%u > %u)\n",
+                               __func__, field_name, clock_name,
+                               div->frac_width, div->width);
+                       return false;
+               }
+
+       return true;
+}
+
+/*
+ * If a clock has two dividers, the combined number of fractional
+ * bits must be representable in a 32-bit unsigned value.  This
+ * is because we scale up a dividend using both dividers before
+ * dividing to improve accuracy, and we need to avoid overflow.
+ */
+static bool kona_dividers_valid(struct kona_clk *bcm_clk)
+{
+       struct peri_clk_data *peri = bcm_clk->peri;
+       struct bcm_clk_div *div;
+       struct bcm_clk_div *pre_div;
+       u32 limit;
+
+       BUG_ON(bcm_clk->type != bcm_clk_peri);
+
+       if (!divider_exists(&peri->div) || !divider_exists(&peri->pre_div))
+               return true;
+
+       div = &peri->div;
+       pre_div = &peri->pre_div;
+       if (divider_is_fixed(div) || divider_is_fixed(pre_div))
+               return true;
+
+       limit = BITS_PER_BYTE * sizeof(u32);
+
+       return div->frac_width + pre_div->frac_width <= limit;
+}
+
+
+/* A trigger just needs to represent a valid bit position */
+static bool trig_valid(struct bcm_clk_trig *trig, const char *field_name,
+                       const char *clock_name)
+{
+       return bit_posn_valid(trig->bit, field_name, clock_name);
+}
+
+/* Determine whether the set of peripheral clock registers are valid. */
+static bool
+peri_clk_data_valid(struct kona_clk *bcm_clk)
+{
+       struct peri_clk_data *peri;
+       struct bcm_clk_gate *gate;
+       struct bcm_clk_sel *sel;
+       struct bcm_clk_div *div;
+       struct bcm_clk_div *pre_div;
+       struct bcm_clk_trig *trig;
+       const char *name;
+
+       BUG_ON(bcm_clk->type != bcm_clk_peri);
+
+       /*
+        * First validate register offsets.  This is the only place
+        * where we need something from the ccu, so we do these
+        * together.
+        */
+       if (!peri_clk_data_offsets_valid(bcm_clk))
+               return false;
+
+       peri = bcm_clk->peri;
+       name = bcm_clk->name;
+       gate = &peri->gate;
+       if (gate_exists(gate) && !gate_valid(gate, "gate", name))
+               return false;
+
+       sel = &peri->sel;
+       if (selector_exists(sel)) {
+               if (!sel_valid(sel, "selector", name))
+                       return false;
+
+       } else if (sel->parent_count > 1) {
+               pr_err("%s: multiple parents but no selector for %s\n",
+                       __func__, name);
+
+               return false;
+       }
+
+       div = &peri->div;
+       pre_div = &peri->pre_div;
+       if (divider_exists(div)) {
+               if (!div_valid(div, "divider", name))
+                       return false;
+
+               if (divider_exists(pre_div))
+                       if (!div_valid(pre_div, "pre-divider", name))
+                               return false;
+       } else if (divider_exists(pre_div)) {
+               pr_err("%s: pre-divider but no divider for %s\n", __func__,
+                       name);
+               return false;
+       }
+
+       trig = &peri->trig;
+       if (trigger_exists(trig)) {
+               if (!trig_valid(trig, "trigger", name))
+                       return false;
+
+               if (trigger_exists(&peri->pre_trig)) {
+                       if (!trig_valid(trig, "pre-trigger", name)) {
+                               return false;
+                       }
+               }
+               if (!clk_requires_trigger(bcm_clk)) {
+                       pr_warn("%s: ignoring trigger for %s (not needed)\n",
+                               __func__, name);
+                       trigger_clear_exists(trig);
+               }
+       } else if (trigger_exists(&peri->pre_trig)) {
+               pr_err("%s: pre-trigger but no trigger for %s\n", __func__,
+                       name);
+               return false;
+       } else if (clk_requires_trigger(bcm_clk)) {
+               pr_err("%s: required trigger missing for %s\n", __func__,
+                       name);
+               return false;
+       }
+
+       return kona_dividers_valid(bcm_clk);
+}
+
+static bool kona_clk_valid(struct kona_clk *bcm_clk)
+{
+       switch (bcm_clk->type) {
+       case bcm_clk_peri:
+               if (!peri_clk_data_valid(bcm_clk))
+                       return false;
+               break;
+       default:
+               pr_err("%s: unrecognized clock type (%d)\n", __func__,
+                       (int)bcm_clk->type);
+               return false;
+       }
+       return true;
+}
+
+/*
+ * Scan an array of parent clock names to determine whether there
+ * are any entries containing BAD_CLK_NAME.  Such entries are
+ * placeholders for non-supported clocks.  Keep track of the
+ * position of each clock name in the original array.
+ *
+ * Allocates an array of pointers to to hold the names of all
+ * non-null entries in the original array, and returns a pointer to
+ * that array in *names.  This will be used for registering the
+ * clock with the common clock code.  On successful return,
+ * *count indicates how many entries are in that names array.
+ *
+ * If there is more than one entry in the resulting names array,
+ * another array is allocated to record the parent selector value
+ * for each (defined) parent clock.  This is the value that
+ * represents this parent clock in the clock's source selector
+ * register.  The position of the clock in the original parent array
+ * defines that selector value.  The number of entries in this array
+ * is the same as the number of entries in the parent names array.
+ *
+ * The array of selector values is returned.  If the clock has no
+ * parents, no selector is required and a null pointer is returned.
+ *
+ * Returns a null pointer if the clock names array supplied was
+ * null.  (This is not an error.)
+ *
+ * Returns a pointer-coded error if an error occurs.
+ */
+static u32 *parent_process(const char *clocks[],
+                       u32 *count, const char ***names)
+{
+       static const char **parent_names;
+       static u32 *parent_sel;
+       const char **clock;
+       u32 parent_count;
+       u32 bad_count = 0;
+       u32 orig_count;
+       u32 i;
+       u32 j;
+
+       *count = 0;     /* In case of early return */
+       *names = NULL;
+       if (!clocks)
+               return NULL;
+
+       /*
+        * Count the number of names in the null-terminated array,
+        * and find out how many of those are actually clock names.
+        */
+       for (clock = clocks; *clock; clock++)
+               if (*clock == BAD_CLK_NAME)
+                       bad_count++;
+       orig_count = (u32)(clock - clocks);
+       parent_count = orig_count - bad_count;
+
+       /* If all clocks are unsupported, we treat it as no clock */
+       if (!parent_count)
+               return NULL;
+
+       /* Avoid exceeding our parent clock limit */
+       if (parent_count > PARENT_COUNT_MAX) {
+               pr_err("%s: too many parents (%u > %u)\n", __func__,
+                       parent_count, PARENT_COUNT_MAX);
+               return ERR_PTR(-EINVAL);
+       }
+
+       /*
+        * There is one parent name for each defined parent clock.
+        * We also maintain an array containing the selector value
+        * for each defined clock.  If there's only one clock, the
+        * selector is not required, but we allocate space for the
+        * array anyway to keep things simple.
+        */
+       parent_names = kmalloc(parent_count * sizeof(parent_names), GFP_KERNEL);
+       if (!parent_names) {
+               pr_err("%s: error allocating %u parent names\n", __func__,
+                               parent_count);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       /* There is at least one parent, so allocate a selector array */
+
+       parent_sel = kmalloc(parent_count * sizeof(*parent_sel), GFP_KERNEL);
+       if (!parent_sel) {
+               pr_err("%s: error allocating %u parent selectors\n", __func__,
+                               parent_count);
+               kfree(parent_names);
+
+               return ERR_PTR(-ENOMEM);
+       }
+
+       /* Now fill in the parent names and selector arrays */
+       for (i = 0, j = 0; i < orig_count; i++) {
+               if (clocks[i] != BAD_CLK_NAME) {
+                       parent_names[j] = clocks[i];
+                       parent_sel[j] = i;
+                       j++;
+               }
+       }
+       *names = parent_names;
+       *count = parent_count;
+
+       return parent_sel;
+}
+
+static int
+clk_sel_setup(const char **clocks, struct bcm_clk_sel *sel,
+               struct clk_init_data *init_data)
+{
+       const char **parent_names = NULL;
+       u32 parent_count = 0;
+       u32 *parent_sel;
+
+       /*
+        * If a peripheral clock has multiple parents, the value
+        * used by the hardware to select that parent is represented
+        * by the parent clock's position in the "clocks" list.  Some
+        * values don't have defined or supported clocks; these will
+        * have BAD_CLK_NAME entries in the parents[] array.  The
+        * list is terminated by a NULL entry.
+        *
+        * We need to supply (only) the names of defined parent
+        * clocks when registering a clock though, so we use an
+        * array of parent selector values to map between the
+        * indexes the common clock code uses and the selector
+        * values we need.
+        */
+       parent_sel = parent_process(clocks, &parent_count, &parent_names);
+       if (IS_ERR(parent_sel)) {
+               int ret = PTR_ERR(parent_sel);
+
+               pr_err("%s: error processing parent clocks for %s (%d)\n",
+                       __func__, init_data->name, ret);
+
+               return ret;
+       }
+
+       init_data->parent_names = parent_names;
+       init_data->num_parents = parent_count;
+
+       sel->parent_count = parent_count;
+       sel->parent_sel = parent_sel;
+
+       return 0;
+}
+
+static void clk_sel_teardown(struct bcm_clk_sel *sel,
+               struct clk_init_data *init_data)
+{
+       kfree(sel->parent_sel);
+       sel->parent_sel = NULL;
+       sel->parent_count = 0;
+
+       init_data->num_parents = 0;
+       kfree(init_data->parent_names);
+       init_data->parent_names = NULL;
+}
+
+static void peri_clk_teardown(struct peri_clk_data *data,
+                               struct clk_init_data *init_data)
+{
+       clk_sel_teardown(&data->sel, init_data);
+       init_data->ops = NULL;
+}
+
+/*
+ * Caller is responsible for freeing the parent_names[] and
+ * parent_sel[] arrays in the peripheral clock's "data" structure
+ * that can be assigned if the clock has one or more parent clocks
+ * associated with it.
+ */
+static int peri_clk_setup(struct ccu_data *ccu, struct peri_clk_data *data,
+                       struct clk_init_data *init_data)
+{
+       init_data->ops = &kona_peri_clk_ops;
+       init_data->flags = CLK_IGNORE_UNUSED;
+
+       return clk_sel_setup(data->clocks, &data->sel, init_data);
+}
+
+static void bcm_clk_teardown(struct kona_clk *bcm_clk)
+{
+       switch (bcm_clk->type) {
+       case bcm_clk_peri:
+               peri_clk_teardown(bcm_clk->data, &bcm_clk->init_data);
+               break;
+       default:
+               break;
+       }
+       bcm_clk->data = NULL;
+       bcm_clk->type = bcm_clk_none;
+}
+
+static void kona_clk_teardown(struct clk *clk)
+{
+       struct clk_hw *hw;
+       struct kona_clk *bcm_clk;
+
+       if (!clk)
+               return;
+
+       hw = __clk_get_hw(clk);
+       if (!hw) {
+               pr_err("%s: clk %p has null hw pointer\n", __func__, clk);
+               return;
+       }
+       clk_unregister(clk);
+
+       bcm_clk = to_kona_clk(hw);
+       bcm_clk_teardown(bcm_clk);
+}
+
+struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name,
+                       enum bcm_clk_type type, void *data)
+{
+       struct kona_clk *bcm_clk;
+       struct clk_init_data *init_data;
+       struct clk *clk = NULL;
+
+       bcm_clk = kzalloc(sizeof(*bcm_clk), GFP_KERNEL);
+       if (!bcm_clk) {
+               pr_err("%s: failed to allocate bcm_clk for %s\n", __func__,
+                       name);
+               return NULL;
+       }
+       bcm_clk->ccu = ccu;
+       bcm_clk->name = name;
+
+       init_data = &bcm_clk->init_data;
+       init_data->name = name;
+       switch (type) {
+       case bcm_clk_peri:
+               if (peri_clk_setup(ccu, data, init_data))
+                       goto out_free;
+               break;
+       default:
+               data = NULL;
+               break;
+       }
+       bcm_clk->type = type;
+       bcm_clk->data = data;
+
+       /* Make sure everything makes sense before we set it up */
+       if (!kona_clk_valid(bcm_clk)) {
+               pr_err("%s: clock data invalid for %s\n", __func__, name);
+               goto out_teardown;
+       }
+
+       bcm_clk->hw.init = init_data;
+       clk = clk_register(NULL, &bcm_clk->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: error registering clock %s (%ld)\n", __func__,
+                               name, PTR_ERR(clk));
+               goto out_teardown;
+       }
+       BUG_ON(!clk);
+
+       return clk;
+out_teardown:
+       bcm_clk_teardown(bcm_clk);
+out_free:
+       kfree(bcm_clk);
+
+       return NULL;
+}
+
+static void ccu_clks_teardown(struct ccu_data *ccu)
+{
+       u32 i;
+
+       for (i = 0; i < ccu->data.clk_num; i++)
+               kona_clk_teardown(ccu->data.clks[i]);
+       kfree(ccu->data.clks);
+}
+
+static void kona_ccu_teardown(struct ccu_data *ccu)
+{
+       if (!ccu)
+               return;
+
+       if (!ccu->base)
+               goto done;
+
+       of_clk_del_provider(ccu->node); /* safe if never added */
+       ccu_clks_teardown(ccu);
+       list_del(&ccu->links);
+       of_node_put(ccu->node);
+       iounmap(ccu->base);
+done:
+       kfree(ccu->name);
+       kfree(ccu);
+}
+
+/*
+ * Set up a CCU.  Call the provided ccu_clks_setup callback to
+ * initialize the array of clocks provided by the CCU.
+ */
+void __init kona_dt_ccu_setup(struct device_node *node,
+                       int (*ccu_clks_setup)(struct ccu_data *))
+{
+       struct ccu_data *ccu;
+       struct resource res = { 0 };
+       resource_size_t range;
+       int ret;
+
+       ccu = kzalloc(sizeof(*ccu), GFP_KERNEL);
+       if (ccu)
+               ccu->name = kstrdup(node->name, GFP_KERNEL);
+       if (!ccu || !ccu->name) {
+               pr_err("%s: unable to allocate CCU struct for %s\n",
+                       __func__, node->name);
+               kfree(ccu);
+
+               return;
+       }
+
+       ret = of_address_to_resource(node, 0, &res);
+       if (ret) {
+               pr_err("%s: no valid CCU registers found for %s\n", __func__,
+                       node->name);
+               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);
+               goto out_err;
+       }
+
+       ccu->range = (u32)range;
+       ccu->base = ioremap(res.start, ccu->range);
+       if (!ccu->base) {
+               pr_err("%s: unable to map CCU registers for %s\n", __func__,
+                       node->name);
+               goto out_err;
+       }
+
+       spin_lock_init(&ccu->lock);
+       INIT_LIST_HEAD(&ccu->links);
+       ccu->node = of_node_get(node);
+
+       list_add_tail(&ccu->links, &ccu_list);
+
+       /* Set up clocks array (in ccu->data) */
+       if (ccu_clks_setup(ccu))
+               goto out_err;
+
+       ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->data);
+       if (ret) {
+               pr_err("%s: error adding ccu %s as provider (%d)\n", __func__,
+                               node->name, ret);
+               goto out_err;
+       }
+
+       if (!kona_ccu_init(ccu))
+               pr_err("Broadcom %s initialization had errors\n", node->name);
+
+       return;
+out_err:
+       kona_ccu_teardown(ccu);
+       pr_err("Broadcom %s setup aborted\n", node->name);
+}
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
new file mode 100644 (file)
index 0000000..e3d339e
--- /dev/null
@@ -0,0 +1,1033 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ * Copyright 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "clk-kona.h"
+
+#include <linux/delay.h>
+
+#define CCU_ACCESS_PASSWORD      0xA5A500
+#define CLK_GATE_DELAY_LOOP      2000
+
+/* Bitfield operations */
+
+/* Produces a mask of set bits covering a range of a 32-bit value */
+static inline u32 bitfield_mask(u32 shift, u32 width)
+{
+       return ((1 << width) - 1) << shift;
+}
+
+/* Extract the value of a bitfield found within a given register value */
+static inline u32 bitfield_extract(u32 reg_val, u32 shift, u32 width)
+{
+       return (reg_val & bitfield_mask(shift, width)) >> shift;
+}
+
+/* Replace the value of a bitfield found within a given register value */
+static inline u32 bitfield_replace(u32 reg_val, u32 shift, u32 width, u32 val)
+{
+       u32 mask = bitfield_mask(shift, width);
+
+       return (reg_val & ~mask) | (val << shift);
+}
+
+/* Divider and scaling helpers */
+
+/*
+ * Implement DIV_ROUND_CLOSEST() for 64-bit dividend and both values
+ * unsigned.  Note that unlike do_div(), the remainder is discarded
+ * and the return value is the quotient (not the remainder).
+ */
+u64 do_div_round_closest(u64 dividend, unsigned long divisor)
+{
+       u64 result;
+
+       result = dividend + ((u64)divisor >> 1);
+       (void)do_div(result, divisor);
+
+       return result;
+}
+
+/* Convert a divider into the scaled divisor value it represents. */
+static inline u64 scaled_div_value(struct bcm_clk_div *div, u32 reg_div)
+{
+       return (u64)reg_div + ((u64)1 << div->frac_width);
+}
+
+/*
+ * Build a scaled divider value as close as possible to the
+ * given whole part (div_value) and fractional part (expressed
+ * in billionths).
+ */
+u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, u32 billionths)
+{
+       u64 combined;
+
+       BUG_ON(!div_value);
+       BUG_ON(billionths >= BILLION);
+
+       combined = (u64)div_value * BILLION + billionths;
+       combined <<= div->frac_width;
+
+       return do_div_round_closest(combined, BILLION);
+}
+
+/* The scaled minimum divisor representable by a divider */
+static inline u64
+scaled_div_min(struct bcm_clk_div *div)
+{
+       if (divider_is_fixed(div))
+               return (u64)div->fixed;
+
+       return scaled_div_value(div, 0);
+}
+
+/* The scaled maximum divisor representable by a divider */
+u64 scaled_div_max(struct bcm_clk_div *div)
+{
+       u32 reg_div;
+
+       if (divider_is_fixed(div))
+               return (u64)div->fixed;
+
+       reg_div = ((u32)1 << div->width) - 1;
+
+       return scaled_div_value(div, reg_div);
+}
+
+/*
+ * Convert a scaled divisor into its divider representation as
+ * stored in a divider register field.
+ */
+static inline u32
+divider(struct bcm_clk_div *div, u64 scaled_div)
+{
+       BUG_ON(scaled_div < scaled_div_min(div));
+       BUG_ON(scaled_div > scaled_div_max(div));
+
+       return (u32)(scaled_div - ((u64)1 << div->frac_width));
+}
+
+/* Return a rate scaled for use when dividing by a scaled divisor. */
+static inline u64
+scale_rate(struct bcm_clk_div *div, u32 rate)
+{
+       if (divider_is_fixed(div))
+               return (u64)rate;
+
+       return (u64)rate << div->frac_width;
+}
+
+/* CCU access */
+
+/* Read a 32-bit register value from a CCU's address space. */
+static inline u32 __ccu_read(struct ccu_data *ccu, u32 reg_offset)
+{
+       return readl(ccu->base + reg_offset);
+}
+
+/* Write a 32-bit register value into a CCU's address space. */
+static inline void
+__ccu_write(struct ccu_data *ccu, u32 reg_offset, u32 reg_val)
+{
+       writel(reg_val, ccu->base + reg_offset);
+}
+
+static inline unsigned long ccu_lock(struct ccu_data *ccu)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ccu->lock, flags);
+
+       return flags;
+}
+static inline void ccu_unlock(struct ccu_data *ccu, unsigned long flags)
+{
+       spin_unlock_irqrestore(&ccu->lock, flags);
+}
+
+/*
+ * Enable/disable write access to CCU protected registers.  The
+ * WR_ACCESS register for all CCUs is at offset 0.
+ */
+static inline void __ccu_write_enable(struct ccu_data *ccu)
+{
+       if (ccu->write_enabled) {
+               pr_err("%s: access already enabled for %s\n", __func__,
+                       ccu->name);
+               return;
+       }
+       ccu->write_enabled = true;
+       __ccu_write(ccu, 0, CCU_ACCESS_PASSWORD | 1);
+}
+
+static inline void __ccu_write_disable(struct ccu_data *ccu)
+{
+       if (!ccu->write_enabled) {
+               pr_err("%s: access wasn't enabled for %s\n", __func__,
+                       ccu->name);
+               return;
+       }
+
+       __ccu_write(ccu, 0, CCU_ACCESS_PASSWORD);
+       ccu->write_enabled = false;
+}
+
+/*
+ * Poll a register in a CCU's address space, returning when the
+ * specified bit in that register's value is set (or clear).  Delay
+ * a microsecond after each read of the register.  Returns true if
+ * successful, or false if we gave up trying.
+ *
+ * Caller must ensure the CCU lock is held.
+ */
+static inline bool
+__ccu_wait_bit(struct ccu_data *ccu, u32 reg_offset, u32 bit, bool want)
+{
+       unsigned int tries;
+       u32 bit_mask = 1 << bit;
+
+       for (tries = 0; tries < CLK_GATE_DELAY_LOOP; tries++) {
+               u32 val;
+               bool bit_val;
+
+               val = __ccu_read(ccu, reg_offset);
+               bit_val = (val & bit_mask) != 0;
+               if (bit_val == want)
+                       return true;
+               udelay(1);
+       }
+       return false;
+}
+
+/* Gate operations */
+
+/* Determine whether a clock is gated.  CCU lock must be held.  */
+static bool
+__is_clk_gate_enabled(struct ccu_data *ccu, struct bcm_clk_gate *gate)
+{
+       u32 bit_mask;
+       u32 reg_val;
+
+       /* If there is no gate we can assume it's enabled. */
+       if (!gate_exists(gate))
+               return true;
+
+       bit_mask = 1 << gate->status_bit;
+       reg_val = __ccu_read(ccu, gate->offset);
+
+       return (reg_val & bit_mask) != 0;
+}
+
+/* Determine whether a clock is gated. */
+static bool
+is_clk_gate_enabled(struct ccu_data *ccu, struct bcm_clk_gate *gate)
+{
+       long flags;
+       bool ret;
+
+       /* Avoid taking the lock if we can */
+       if (!gate_exists(gate))
+               return true;
+
+       flags = ccu_lock(ccu);
+       ret = __is_clk_gate_enabled(ccu, gate);
+       ccu_unlock(ccu, flags);
+
+       return ret;
+}
+
+/*
+ * Commit our desired gate state to the hardware.
+ * Returns true if successful, false otherwise.
+ */
+static bool
+__gate_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate)
+{
+       u32 reg_val;
+       u32 mask;
+       bool enabled = false;
+
+       BUG_ON(!gate_exists(gate));
+       if (!gate_is_sw_controllable(gate))
+               return true;            /* Nothing we can change */
+
+       reg_val = __ccu_read(ccu, gate->offset);
+
+       /* For a hardware/software gate, set which is in control */
+       if (gate_is_hw_controllable(gate)) {
+               mask = (u32)1 << gate->hw_sw_sel_bit;
+               if (gate_is_sw_managed(gate))
+                       reg_val |= mask;
+               else
+                       reg_val &= ~mask;
+       }
+
+       /*
+        * If software is in control, enable or disable the gate.
+        * If hardware is, clear the enabled bit for good measure.
+        * If a software controlled gate can't be disabled, we're
+        * required to write a 0 into the enable bit (but the gate
+        * will be enabled).
+        */
+       mask = (u32)1 << gate->en_bit;
+       if (gate_is_sw_managed(gate) && (enabled = gate_is_enabled(gate)) &&
+                       !gate_is_no_disable(gate))
+               reg_val |= mask;
+       else
+               reg_val &= ~mask;
+
+       __ccu_write(ccu, gate->offset, reg_val);
+
+       /* For a hardware controlled gate, we're done */
+       if (!gate_is_sw_managed(gate))
+               return true;
+
+       /* Otherwise wait for the gate to be in desired state */
+       return __ccu_wait_bit(ccu, gate->offset, gate->status_bit, enabled);
+}
+
+/*
+ * Initialize a gate.  Our desired state (hardware/software select,
+ * and if software, its enable state) is committed to hardware
+ * without the usual checks to see if it's already set up that way.
+ * Returns true if successful, false otherwise.
+ */
+static bool gate_init(struct ccu_data *ccu, struct bcm_clk_gate *gate)
+{
+       if (!gate_exists(gate))
+               return true;
+       return __gate_commit(ccu, gate);
+}
+
+/*
+ * Set a gate to enabled or disabled state.  Does nothing if the
+ * gate is not currently under software control, or if it is already
+ * in the requested state.  Returns true if successful, false
+ * otherwise.  CCU lock must be held.
+ */
+static bool
+__clk_gate(struct ccu_data *ccu, struct bcm_clk_gate *gate, bool enable)
+{
+       bool ret;
+
+       if (!gate_exists(gate) || !gate_is_sw_managed(gate))
+               return true;    /* Nothing to do */
+
+       if (!enable && gate_is_no_disable(gate)) {
+               pr_warn("%s: invalid gate disable request (ignoring)\n",
+                       __func__);
+               return true;
+       }
+
+       if (enable == gate_is_enabled(gate))
+               return true;    /* No change */
+
+       gate_flip_enabled(gate);
+       ret = __gate_commit(ccu, gate);
+       if (!ret)
+               gate_flip_enabled(gate);        /* Revert the change */
+
+       return ret;
+}
+
+/* Enable or disable a gate.  Returns 0 if successful, -EIO otherwise */
+static int clk_gate(struct ccu_data *ccu, const char *name,
+                       struct bcm_clk_gate *gate, bool enable)
+{
+       unsigned long flags;
+       bool success;
+
+       /*
+        * Avoid taking the lock if we can.  We quietly ignore
+        * requests to change state that don't make sense.
+        */
+       if (!gate_exists(gate) || !gate_is_sw_managed(gate))
+               return 0;
+       if (!enable && gate_is_no_disable(gate))
+               return 0;
+
+       flags = ccu_lock(ccu);
+       __ccu_write_enable(ccu);
+
+       success = __clk_gate(ccu, gate, enable);
+
+       __ccu_write_disable(ccu);
+       ccu_unlock(ccu, flags);
+
+       if (success)
+               return 0;
+
+       pr_err("%s: failed to %s gate for %s\n", __func__,
+               enable ? "enable" : "disable", name);
+
+       return -EIO;
+}
+
+/* Trigger operations */
+
+/*
+ * Caller must ensure CCU lock is held and access is enabled.
+ * Returns true if successful, false otherwise.
+ */
+static bool __clk_trigger(struct ccu_data *ccu, struct bcm_clk_trig *trig)
+{
+       /* Trigger the clock and wait for it to finish */
+       __ccu_write(ccu, trig->offset, 1 << trig->bit);
+
+       return __ccu_wait_bit(ccu, trig->offset, trig->bit, false);
+}
+
+/* Divider operations */
+
+/* Read a divider value and return the scaled divisor it represents. */
+static u64 divider_read_scaled(struct ccu_data *ccu, struct bcm_clk_div *div)
+{
+       unsigned long flags;
+       u32 reg_val;
+       u32 reg_div;
+
+       if (divider_is_fixed(div))
+               return (u64)div->fixed;
+
+       flags = ccu_lock(ccu);
+       reg_val = __ccu_read(ccu, div->offset);
+       ccu_unlock(ccu, flags);
+
+       /* Extract the full divider field from the register value */
+       reg_div = bitfield_extract(reg_val, div->shift, div->width);
+
+       /* Return the scaled divisor value it represents */
+       return scaled_div_value(div, reg_div);
+}
+
+/*
+ * Convert a divider's scaled divisor value into its recorded form
+ * and commit it into the hardware divider register.
+ *
+ * Returns 0 on success.  Returns -EINVAL for invalid arguments.
+ * Returns -ENXIO if gating failed, and -EIO if a trigger failed.
+ */
+static int __div_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate,
+                       struct bcm_clk_div *div, struct bcm_clk_trig *trig)
+{
+       bool enabled;
+       u32 reg_div;
+       u32 reg_val;
+       int ret = 0;
+
+       BUG_ON(divider_is_fixed(div));
+
+       /*
+        * If we're just initializing the divider, and no initial
+        * state was defined in the device tree, we just find out
+        * what its current value is rather than updating it.
+        */
+       if (div->scaled_div == BAD_SCALED_DIV_VALUE) {
+               reg_val = __ccu_read(ccu, div->offset);
+               reg_div = bitfield_extract(reg_val, div->shift, div->width);
+               div->scaled_div = scaled_div_value(div, reg_div);
+
+               return 0;
+       }
+
+       /* Convert the scaled divisor to the value we need to record */
+       reg_div = divider(div, div->scaled_div);
+
+       /* Clock needs to be enabled before changing the rate */
+       enabled = __is_clk_gate_enabled(ccu, gate);
+       if (!enabled && !__clk_gate(ccu, gate, true)) {
+               ret = -ENXIO;
+               goto out;
+       }
+
+       /* Replace the divider value and record the result */
+       reg_val = __ccu_read(ccu, div->offset);
+       reg_val = bitfield_replace(reg_val, div->shift, div->width, reg_div);
+       __ccu_write(ccu, div->offset, reg_val);
+
+       /* If the trigger fails we still want to disable the gate */
+       if (!__clk_trigger(ccu, trig))
+               ret = -EIO;
+
+       /* Disable the clock again if it was disabled to begin with */
+       if (!enabled && !__clk_gate(ccu, gate, false))
+               ret = ret ? ret : -ENXIO;       /* return first error */
+out:
+       return ret;
+}
+
+/*
+ * Initialize a divider by committing our desired state to hardware
+ * without the usual checks to see if it's already set up that way.
+ * Returns true if successful, false otherwise.
+ */
+static bool div_init(struct ccu_data *ccu, struct bcm_clk_gate *gate,
+                       struct bcm_clk_div *div, struct bcm_clk_trig *trig)
+{
+       if (!divider_exists(div) || divider_is_fixed(div))
+               return true;
+       return !__div_commit(ccu, gate, div, trig);
+}
+
+static int divider_write(struct ccu_data *ccu, struct bcm_clk_gate *gate,
+                       struct bcm_clk_div *div, struct bcm_clk_trig *trig,
+                       u64 scaled_div)
+{
+       unsigned long flags;
+       u64 previous;
+       int ret;
+
+       BUG_ON(divider_is_fixed(div));
+
+       previous = div->scaled_div;
+       if (previous == scaled_div)
+               return 0;       /* No change */
+
+       div->scaled_div = scaled_div;
+
+       flags = ccu_lock(ccu);
+       __ccu_write_enable(ccu);
+
+       ret = __div_commit(ccu, gate, div, trig);
+
+       __ccu_write_disable(ccu);
+       ccu_unlock(ccu, flags);
+
+       if (ret)
+               div->scaled_div = previous;             /* Revert the change */
+
+       return ret;
+
+}
+
+/* Common clock rate helpers */
+
+/*
+ * Implement the common clock framework recalc_rate method, taking
+ * into account a divider and an optional pre-divider.  The
+ * pre-divider register pointer may be NULL.
+ */
+static unsigned long clk_recalc_rate(struct ccu_data *ccu,
+                       struct bcm_clk_div *div, struct bcm_clk_div *pre_div,
+                       unsigned long parent_rate)
+{
+       u64 scaled_parent_rate;
+       u64 scaled_div;
+       u64 result;
+
+       if (!divider_exists(div))
+               return parent_rate;
+
+       if (parent_rate > (unsigned long)LONG_MAX)
+               return 0;       /* actually this would be a caller bug */
+
+       /*
+        * If there is a pre-divider, divide the scaled parent rate
+        * by the pre-divider value first.  In this case--to improve
+        * accuracy--scale the parent rate by *both* the pre-divider
+        * value and the divider before actually computing the
+        * result of the pre-divider.
+        *
+        * If there's only one divider, just scale the parent rate.
+        */
+       if (pre_div && divider_exists(pre_div)) {
+               u64 scaled_rate;
+
+               scaled_rate = scale_rate(pre_div, parent_rate);
+               scaled_rate = scale_rate(div, scaled_rate);
+               scaled_div = divider_read_scaled(ccu, pre_div);
+               scaled_parent_rate = do_div_round_closest(scaled_rate,
+                                                       scaled_div);
+       } else  {
+               scaled_parent_rate = scale_rate(div, parent_rate);
+       }
+
+       /*
+        * Get the scaled divisor value, and divide the scaled
+        * parent rate by that to determine this clock's resulting
+        * rate.
+        */
+       scaled_div = divider_read_scaled(ccu, div);
+       result = do_div_round_closest(scaled_parent_rate, scaled_div);
+
+       return (unsigned long)result;
+}
+
+/*
+ * Compute the output rate produced when a given parent rate is fed
+ * into two dividers.  The pre-divider can be NULL, and even if it's
+ * non-null it may be nonexistent.  It's also OK for the divider to
+ * be nonexistent, and in that case the pre-divider is also ignored.
+ *
+ * If scaled_div is non-null, it is used to return the scaled divisor
+ * value used by the (downstream) divider to produce that rate.
+ */
+static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div,
+                               struct bcm_clk_div *pre_div,
+                               unsigned long rate, unsigned long parent_rate,
+                               u64 *scaled_div)
+{
+       u64 scaled_parent_rate;
+       u64 min_scaled_div;
+       u64 max_scaled_div;
+       u64 best_scaled_div;
+       u64 result;
+
+       BUG_ON(!divider_exists(div));
+       BUG_ON(!rate);
+       BUG_ON(parent_rate > (u64)LONG_MAX);
+
+       /*
+        * If there is a pre-divider, divide the scaled parent rate
+        * by the pre-divider value first.  In this case--to improve
+        * accuracy--scale the parent rate by *both* the pre-divider
+        * value and the divider before actually computing the
+        * result of the pre-divider.
+        *
+        * If there's only one divider, just scale the parent rate.
+        *
+        * For simplicity we treat the pre-divider as fixed (for now).
+        */
+       if (divider_exists(pre_div)) {
+               u64 scaled_rate;
+               u64 scaled_pre_div;
+
+               scaled_rate = scale_rate(pre_div, parent_rate);
+               scaled_rate = scale_rate(div, scaled_rate);
+               scaled_pre_div = divider_read_scaled(ccu, pre_div);
+               scaled_parent_rate = do_div_round_closest(scaled_rate,
+                                                       scaled_pre_div);
+       } else {
+               scaled_parent_rate = scale_rate(div, parent_rate);
+       }
+
+       /*
+        * Compute the best possible divider and ensure it is in
+        * range.  A fixed divider can't be changed, so just report
+        * the best we can do.
+        */
+       if (!divider_is_fixed(div)) {
+               best_scaled_div = do_div_round_closest(scaled_parent_rate,
+                                                       rate);
+               min_scaled_div = scaled_div_min(div);
+               max_scaled_div = scaled_div_max(div);
+               if (best_scaled_div > max_scaled_div)
+                       best_scaled_div = max_scaled_div;
+               else if (best_scaled_div < min_scaled_div)
+                       best_scaled_div = min_scaled_div;
+       } else {
+               best_scaled_div = divider_read_scaled(ccu, div);
+       }
+
+       /* OK, figure out the resulting rate */
+       result = do_div_round_closest(scaled_parent_rate, best_scaled_div);
+
+       if (scaled_div)
+               *scaled_div = best_scaled_div;
+
+       return (long)result;
+}
+
+/* Common clock parent helpers */
+
+/*
+ * For a given parent selector (register field) value, find the
+ * index into a selector's parent_sel array that contains it.
+ * Returns the index, or BAD_CLK_INDEX if it's not found.
+ */
+static u8 parent_index(struct bcm_clk_sel *sel, u8 parent_sel)
+{
+       u8 i;
+
+       BUG_ON(sel->parent_count > (u32)U8_MAX);
+       for (i = 0; i < sel->parent_count; i++)
+               if (sel->parent_sel[i] == parent_sel)
+                       return i;
+       return BAD_CLK_INDEX;
+}
+
+/*
+ * Fetch the current value of the selector, and translate that into
+ * its corresponding index in the parent array we registered with
+ * the clock framework.
+ *
+ * Returns parent array index that corresponds with the value found,
+ * or BAD_CLK_INDEX if the found value is out of range.
+ */
+static u8 selector_read_index(struct ccu_data *ccu, struct bcm_clk_sel *sel)
+{
+       unsigned long flags;
+       u32 reg_val;
+       u32 parent_sel;
+       u8 index;
+
+       /* If there's no selector, there's only one parent */
+       if (!selector_exists(sel))
+               return 0;
+
+       /* Get the value in the selector register */
+       flags = ccu_lock(ccu);
+       reg_val = __ccu_read(ccu, sel->offset);
+       ccu_unlock(ccu, flags);
+
+       parent_sel = bitfield_extract(reg_val, sel->shift, sel->width);
+
+       /* Look up that selector's parent array index and return it */
+       index = parent_index(sel, parent_sel);
+       if (index == BAD_CLK_INDEX)
+               pr_err("%s: out-of-range parent selector %u (%s 0x%04x)\n",
+                       __func__, parent_sel, ccu->name, sel->offset);
+
+       return index;
+}
+
+/*
+ * Commit our desired selector value to the hardware.
+ *
+ * Returns 0 on success.  Returns -EINVAL for invalid arguments.
+ * Returns -ENXIO if gating failed, and -EIO if a trigger failed.
+ */
+static int
+__sel_commit(struct ccu_data *ccu, struct bcm_clk_gate *gate,
+                       struct bcm_clk_sel *sel, struct bcm_clk_trig *trig)
+{
+       u32 parent_sel;
+       u32 reg_val;
+       bool enabled;
+       int ret = 0;
+
+       BUG_ON(!selector_exists(sel));
+
+       /*
+        * If we're just initializing the selector, and no initial
+        * state was defined in the device tree, we just find out
+        * what its current value is rather than updating it.
+        */
+       if (sel->clk_index == BAD_CLK_INDEX) {
+               u8 index;
+
+               reg_val = __ccu_read(ccu, sel->offset);
+               parent_sel = bitfield_extract(reg_val, sel->shift, sel->width);
+               index = parent_index(sel, parent_sel);
+               if (index == BAD_CLK_INDEX)
+                       return -EINVAL;
+               sel->clk_index = index;
+
+               return 0;
+       }
+
+       BUG_ON((u32)sel->clk_index >= sel->parent_count);
+       parent_sel = sel->parent_sel[sel->clk_index];
+
+       /* Clock needs to be enabled before changing the parent */
+       enabled = __is_clk_gate_enabled(ccu, gate);
+       if (!enabled && !__clk_gate(ccu, gate, true))
+               return -ENXIO;
+
+       /* Replace the selector value and record the result */
+       reg_val = __ccu_read(ccu, sel->offset);
+       reg_val = bitfield_replace(reg_val, sel->shift, sel->width, parent_sel);
+       __ccu_write(ccu, sel->offset, reg_val);
+
+       /* If the trigger fails we still want to disable the gate */
+       if (!__clk_trigger(ccu, trig))
+               ret = -EIO;
+
+       /* Disable the clock again if it was disabled to begin with */
+       if (!enabled && !__clk_gate(ccu, gate, false))
+               ret = ret ? ret : -ENXIO;       /* return first error */
+
+       return ret;
+}
+
+/*
+ * Initialize a selector by committing our desired state to hardware
+ * without the usual checks to see if it's already set up that way.
+ * Returns true if successful, false otherwise.
+ */
+static bool sel_init(struct ccu_data *ccu, struct bcm_clk_gate *gate,
+                       struct bcm_clk_sel *sel, struct bcm_clk_trig *trig)
+{
+       if (!selector_exists(sel))
+               return true;
+       return !__sel_commit(ccu, gate, sel, trig);
+}
+
+/*
+ * Write a new value into a selector register to switch to a
+ * different parent clock.  Returns 0 on success, or an error code
+ * (from __sel_commit()) otherwise.
+ */
+static int selector_write(struct ccu_data *ccu, struct bcm_clk_gate *gate,
+                       struct bcm_clk_sel *sel, struct bcm_clk_trig *trig,
+                       u8 index)
+{
+       unsigned long flags;
+       u8 previous;
+       int ret;
+
+       previous = sel->clk_index;
+       if (previous == index)
+               return 0;       /* No change */
+
+       sel->clk_index = index;
+
+       flags = ccu_lock(ccu);
+       __ccu_write_enable(ccu);
+
+       ret = __sel_commit(ccu, gate, sel, trig);
+
+       __ccu_write_disable(ccu);
+       ccu_unlock(ccu, flags);
+
+       if (ret)
+               sel->clk_index = previous;      /* Revert the change */
+
+       return ret;
+}
+
+/* Clock operations */
+
+static int kona_peri_clk_enable(struct clk_hw *hw)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct bcm_clk_gate *gate = &bcm_clk->peri->gate;
+
+       return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true);
+}
+
+static void kona_peri_clk_disable(struct clk_hw *hw)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct bcm_clk_gate *gate = &bcm_clk->peri->gate;
+
+       (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false);
+}
+
+static int kona_peri_clk_is_enabled(struct clk_hw *hw)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct bcm_clk_gate *gate = &bcm_clk->peri->gate;
+
+       return is_clk_gate_enabled(bcm_clk->ccu, gate) ? 1 : 0;
+}
+
+static unsigned long kona_peri_clk_recalc_rate(struct clk_hw *hw,
+                       unsigned long parent_rate)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct peri_clk_data *data = bcm_clk->peri;
+
+       return clk_recalc_rate(bcm_clk->ccu, &data->div, &data->pre_div,
+                               parent_rate);
+}
+
+static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                       unsigned long *parent_rate)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct bcm_clk_div *div = &bcm_clk->peri->div;
+
+       if (!divider_exists(div))
+               return __clk_get_rate(hw->clk);
+
+       /* Quietly avoid a zero rate */
+       return round_rate(bcm_clk->ccu, div, &bcm_clk->peri->pre_div,
+                               rate ? rate : 1, *parent_rate, NULL);
+}
+
+static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct peri_clk_data *data = bcm_clk->peri;
+       struct bcm_clk_sel *sel = &data->sel;
+       struct bcm_clk_trig *trig;
+       int ret;
+
+       BUG_ON(index >= sel->parent_count);
+
+       /* If there's only one parent we don't require a selector */
+       if (!selector_exists(sel))
+               return 0;
+
+       /*
+        * The regular trigger is used by default, but if there's a
+        * pre-trigger we want to use that instead.
+        */
+       trig = trigger_exists(&data->pre_trig) ? &data->pre_trig
+                                              : &data->trig;
+
+       ret = selector_write(bcm_clk->ccu, &data->gate, sel, trig, index);
+       if (ret == -ENXIO) {
+               pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name);
+               ret = -EIO;     /* Don't proliferate weird errors */
+       } else if (ret == -EIO) {
+               pr_err("%s: %strigger failed for %s\n", __func__,
+                       trig == &data->pre_trig ? "pre-" : "",
+                       bcm_clk->name);
+       }
+
+       return ret;
+}
+
+static u8 kona_peri_clk_get_parent(struct clk_hw *hw)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct peri_clk_data *data = bcm_clk->peri;
+       u8 index;
+
+       index = selector_read_index(bcm_clk->ccu, &data->sel);
+
+       /* Not all callers would handle an out-of-range value gracefully */
+       return index == BAD_CLK_INDEX ? 0 : index;
+}
+
+static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                       unsigned long parent_rate)
+{
+       struct kona_clk *bcm_clk = to_kona_clk(hw);
+       struct peri_clk_data *data = bcm_clk->peri;
+       struct bcm_clk_div *div = &data->div;
+       u64 scaled_div = 0;
+       int ret;
+
+       if (parent_rate > (unsigned long)LONG_MAX)
+               return -EINVAL;
+
+       if (rate == __clk_get_rate(hw->clk))
+               return 0;
+
+       if (!divider_exists(div))
+               return rate == parent_rate ? 0 : -EINVAL;
+
+       /*
+        * A fixed divider can't be changed.  (Nor can a fixed
+        * pre-divider be, but for now we never actually try to
+        * change that.)  Tolerate a request for a no-op change.
+        */
+       if (divider_is_fixed(&data->div))
+               return rate == parent_rate ? 0 : -EINVAL;
+
+       /*
+        * Get the scaled divisor value needed to achieve a clock
+        * rate as close as possible to what was requested, given
+        * the parent clock rate supplied.
+        */
+       (void)round_rate(bcm_clk->ccu, div, &data->pre_div,
+                               rate ? rate : 1, parent_rate, &scaled_div);
+
+       /*
+        * We aren't updating any pre-divider at this point, so
+        * we'll use the regular trigger.
+        */
+       ret = divider_write(bcm_clk->ccu, &data->gate, &data->div,
+                               &data->trig, scaled_div);
+       if (ret == -ENXIO) {
+               pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name);
+               ret = -EIO;     /* Don't proliferate weird errors */
+       } else if (ret == -EIO) {
+               pr_err("%s: trigger failed for %s\n", __func__, bcm_clk->name);
+       }
+
+       return ret;
+}
+
+struct clk_ops kona_peri_clk_ops = {
+       .enable = kona_peri_clk_enable,
+       .disable = kona_peri_clk_disable,
+       .is_enabled = kona_peri_clk_is_enabled,
+       .recalc_rate = kona_peri_clk_recalc_rate,
+       .round_rate = kona_peri_clk_round_rate,
+       .set_parent = kona_peri_clk_set_parent,
+       .get_parent = kona_peri_clk_get_parent,
+       .set_rate = kona_peri_clk_set_rate,
+};
+
+/* Put a peripheral clock into its initial state */
+static bool __peri_clk_init(struct kona_clk *bcm_clk)
+{
+       struct ccu_data *ccu = bcm_clk->ccu;
+       struct peri_clk_data *peri = bcm_clk->peri;
+       const char *name = bcm_clk->name;
+       struct bcm_clk_trig *trig;
+
+       BUG_ON(bcm_clk->type != bcm_clk_peri);
+
+       if (!gate_init(ccu, &peri->gate)) {
+               pr_err("%s: error initializing gate for %s\n", __func__, name);
+               return false;
+       }
+       if (!div_init(ccu, &peri->gate, &peri->div, &peri->trig)) {
+               pr_err("%s: error initializing divider for %s\n", __func__,
+                       name);
+               return false;
+       }
+
+       /*
+        * For the pre-divider and selector, the pre-trigger is used
+        * if it's present, otherwise we just use the regular trigger.
+        */
+       trig = trigger_exists(&peri->pre_trig) ? &peri->pre_trig
+                                              : &peri->trig;
+
+       if (!div_init(ccu, &peri->gate, &peri->pre_div, trig)) {
+               pr_err("%s: error initializing pre-divider for %s\n", __func__,
+                       name);
+               return false;
+       }
+
+       if (!sel_init(ccu, &peri->gate, &peri->sel, trig)) {
+               pr_err("%s: error initializing selector for %s\n", __func__,
+                       name);
+               return false;
+       }
+
+       return true;
+}
+
+static bool __kona_clk_init(struct kona_clk *bcm_clk)
+{
+       switch (bcm_clk->type) {
+       case bcm_clk_peri:
+               return __peri_clk_init(bcm_clk);
+       default:
+               BUG();
+       }
+       return -EINVAL;
+}
+
+/* Set a CCU and all its clocks into their desired initial state */
+bool __init kona_ccu_init(struct ccu_data *ccu)
+{
+       unsigned long flags;
+       unsigned int which;
+       struct clk **clks = ccu->data.clks;
+       bool success = true;
+
+       flags = ccu_lock(ccu);
+       __ccu_write_enable(ccu);
+
+       for (which = 0; which < ccu->data.clk_num; which++) {
+               struct kona_clk *bcm_clk;
+
+               if (!clks[which])
+                       continue;
+               bcm_clk = to_kona_clk(__clk_get_hw(clks[which]));
+               success &= __kona_clk_init(bcm_clk);
+       }
+
+       __ccu_write_disable(ccu);
+       ccu_unlock(ccu, flags);
+       return success;
+}
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h
new file mode 100644 (file)
index 0000000..5e139ad
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ * Copyright 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CLK_KONA_H
+#define _CLK_KONA_H
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+
+#define        BILLION         1000000000
+
+/* The common clock framework uses u8 to represent a parent index */
+#define PARENT_COUNT_MAX       ((u32)U8_MAX)
+
+#define BAD_CLK_INDEX          U8_MAX  /* Can't ever be valid */
+#define BAD_CLK_NAME           ((const char *)-1)
+
+#define BAD_SCALED_DIV_VALUE   U64_MAX
+
+/*
+ * Utility macros for object flag management.  If possible, flags
+ * should be defined such that 0 is the desired default value.
+ */
+#define FLAG(type, flag)               BCM_CLK_ ## type ## _FLAGS_ ## flag
+#define FLAG_SET(obj, type, flag)      ((obj)->flags |= FLAG(type, flag))
+#define FLAG_CLEAR(obj, type, flag)    ((obj)->flags &= ~(FLAG(type, flag)))
+#define FLAG_FLIP(obj, type, flag)     ((obj)->flags ^= FLAG(type, flag))
+#define FLAG_TEST(obj, type, flag)     (!!((obj)->flags & FLAG(type, flag)))
+
+/* Clock field state tests */
+
+#define gate_exists(gate)              FLAG_TEST(gate, GATE, EXISTS)
+#define gate_is_enabled(gate)          FLAG_TEST(gate, GATE, ENABLED)
+#define gate_is_hw_controllable(gate)  FLAG_TEST(gate, GATE, HW)
+#define gate_is_sw_controllable(gate)  FLAG_TEST(gate, GATE, SW)
+#define gate_is_sw_managed(gate)       FLAG_TEST(gate, GATE, SW_MANAGED)
+#define gate_is_no_disable(gate)       FLAG_TEST(gate, GATE, NO_DISABLE)
+
+#define gate_flip_enabled(gate)                FLAG_FLIP(gate, GATE, ENABLED)
+
+#define divider_exists(div)            FLAG_TEST(div, DIV, EXISTS)
+#define divider_is_fixed(div)          FLAG_TEST(div, DIV, FIXED)
+#define divider_has_fraction(div)      (!divider_is_fixed(div) && \
+                                               (div)->frac_width > 0)
+
+#define selector_exists(sel)           ((sel)->width != 0)
+#define trigger_exists(trig)           FLAG_TEST(trig, TRIG, EXISTS)
+
+/* Clock type, used to tell common block what it's part of */
+enum bcm_clk_type {
+       bcm_clk_none,           /* undefined clock type */
+       bcm_clk_bus,
+       bcm_clk_core,
+       bcm_clk_peri
+};
+
+/*
+ * Each CCU defines a mapped area of memory containing registers
+ * used to manage clocks implemented by the CCU.  Access to memory
+ * within the CCU's space is serialized by a spinlock.  Before any
+ * (other) address can be written, a special access "password" value
+ * must be written to its WR_ACCESS register (located at the base
+ * address of the range).  We keep track of the name of each CCU as
+ * it is set up, and maintain them in a list.
+ */
+struct ccu_data {
+       void __iomem *base;     /* base of mapped address space */
+       spinlock_t lock;        /* serialization lock */
+       bool write_enabled;     /* write access is currently enabled */
+       struct list_head links; /* for ccu_list */
+       struct device_node *node;
+       struct clk_onecell_data data;
+       const char *name;
+       u32 range;              /* byte range of address space */
+};
+
+/*
+ * Gating control and status is managed by a 32-bit gate register.
+ *
+ * There are several types of gating available:
+ * - (no gate)
+ *     A clock with no gate is assumed to be always enabled.
+ * - hardware-only gating (auto-gating)
+ *     Enabling or disabling clocks with this type of gate is
+ *     managed automatically by the hardware.  Such clocks can be
+ *     considered by the software to be enabled.  The current status
+ *     of auto-gated clocks can be read from the gate status bit.
+ * - software-only gating
+ *     Auto-gating is not available for this type of clock.
+ *     Instead, software manages whether it's enabled by setting or
+ *     clearing the enable bit.  The current gate status of a gate
+ *     under software control can be read from the gate status bit.
+ *     To ensure a change to the gating status is complete, the
+ *     status bit can be polled to verify that the gate has entered
+ *     the desired state.
+ * - selectable hardware or software gating
+ *     Gating for this type of clock can be configured to be either
+ *     under software or hardware control.  Which type is in use is
+ *     determined by the hw_sw_sel bit of the gate register.
+ */
+struct bcm_clk_gate {
+       u32 offset;             /* gate register offset */
+       u32 status_bit;         /* 0: gate is disabled; 0: gatge is enabled */
+       u32 en_bit;             /* 0: disable; 1: enable */
+       u32 hw_sw_sel_bit;      /* 0: hardware gating; 1: software gating */
+       u32 flags;              /* BCM_CLK_GATE_FLAGS_* below */
+};
+
+/*
+ * Gate flags:
+ *   HW         means this gate can be auto-gated
+ *   SW         means the state of this gate can be software controlled
+ *   NO_DISABLE means this gate is (only) enabled if under software control
+ *   SW_MANAGED means the status of this gate is under software control
+ *   ENABLED    means this software-managed gate is *supposed* to be enabled
+ */
+#define BCM_CLK_GATE_FLAGS_EXISTS      ((u32)1 << 0)   /* Gate is valid */
+#define BCM_CLK_GATE_FLAGS_HW          ((u32)1 << 1)   /* Can auto-gate */
+#define BCM_CLK_GATE_FLAGS_SW          ((u32)1 << 2)   /* Software control */
+#define BCM_CLK_GATE_FLAGS_NO_DISABLE  ((u32)1 << 3)   /* HW or enabled */
+#define BCM_CLK_GATE_FLAGS_SW_MANAGED  ((u32)1 << 4)   /* SW now in control */
+#define BCM_CLK_GATE_FLAGS_ENABLED     ((u32)1 << 5)   /* If SW_MANAGED */
+
+/*
+ * Gate initialization macros.
+ *
+ * Any gate initially under software control will be enabled.
+ */
+
+/* A hardware/software gate initially under software control */
+#define HW_SW_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit)      \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .status_bit = (_status_bit),                            \
+               .en_bit = (_en_bit),                                    \
+               .hw_sw_sel_bit = (_hw_sw_sel_bit),                      \
+               .flags = FLAG(GATE, HW)|FLAG(GATE, SW)|                 \
+                       FLAG(GATE, SW_MANAGED)|FLAG(GATE, ENABLED)|     \
+                       FLAG(GATE, EXISTS),                             \
+       }
+
+/* A hardware/software gate initially under hardware control */
+#define HW_SW_GATE_AUTO(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .status_bit = (_status_bit),                            \
+               .en_bit = (_en_bit),                                    \
+               .hw_sw_sel_bit = (_hw_sw_sel_bit),                      \
+               .flags = FLAG(GATE, HW)|FLAG(GATE, SW)|                 \
+                       FLAG(GATE, EXISTS),                             \
+       }
+
+/* A hardware-or-enabled gate (enabled if not under hardware control) */
+#define HW_ENABLE_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit)  \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .status_bit = (_status_bit),                            \
+               .en_bit = (_en_bit),                                    \
+               .hw_sw_sel_bit = (_hw_sw_sel_bit),                      \
+               .flags = FLAG(GATE, HW)|FLAG(GATE, SW)|                 \
+                       FLAG(GATE, NO_DISABLE)|FLAG(GATE, EXISTS),      \
+       }
+
+/* A software-only gate */
+#define SW_ONLY_GATE(_offset, _status_bit, _en_bit)                    \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .status_bit = (_status_bit),                            \
+               .en_bit = (_en_bit),                                    \
+               .flags = FLAG(GATE, SW)|FLAG(GATE, SW_MANAGED)|         \
+                       FLAG(GATE, ENABLED)|FLAG(GATE, EXISTS),         \
+       }
+
+/* A hardware-only gate */
+#define HW_ONLY_GATE(_offset, _status_bit)                             \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .status_bit = (_status_bit),                            \
+               .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS),             \
+       }
+
+/*
+ * Each clock can have zero, one, or two dividers which change the
+ * output rate of the clock.  Each divider can be either fixed or
+ * variable.  If there are two dividers, they are the "pre-divider"
+ * and the "regular" or "downstream" divider.  If there is only one,
+ * there is no pre-divider.
+ *
+ * A fixed divider is any non-zero (positive) value, and it
+ * indicates how the input rate is affected by the divider.
+ *
+ * The value of a variable divider is maintained in a sub-field of a
+ * 32-bit divider register.  The position of the field in the
+ * register is defined by its offset and width.  The value recorded
+ * in this field is always 1 less than the value it represents.
+ *
+ * In addition, a variable divider can indicate that some subset
+ * of its bits represent a "fractional" part of the divider.  Such
+ * bits comprise the low-order portion of the divider field, and can
+ * be viewed as representing the portion of the divider that lies to
+ * the right of the decimal point.  Most variable dividers have zero
+ * fractional bits.  Variable dividers with non-zero fraction width
+ * still record a value 1 less than the value they represent; the
+ * added 1 does *not* affect the low-order bit in this case, it
+ * affects the bits above the fractional part only.  (Often in this
+ * code a divider field value is distinguished from the value it
+ * represents by referring to the latter as a "divisor".)
+ *
+ * In order to avoid dealing with fractions, divider arithmetic is
+ * performed using "scaled" values.  A scaled value is one that's
+ * been left-shifted by the fractional width of a divider.  Dividing
+ * a scaled value by a scaled divisor produces the desired quotient
+ * without loss of precision and without any other special handling
+ * for fractions.
+ *
+ * The recorded value of a variable divider can be modified.  To
+ * modify either divider (or both), a clock must be enabled (i.e.,
+ * using its gate).  In addition, a trigger register (described
+ * below) must be used to commit the change, and polled to verify
+ * the change is complete.
+ */
+struct bcm_clk_div {
+       union {
+               struct {        /* variable divider */
+                       u32 offset;     /* divider register offset */
+                       u32 shift;      /* field shift */
+                       u32 width;      /* field width */
+                       u32 frac_width; /* field fraction width */
+
+                       u64 scaled_div; /* scaled divider value */
+               };
+               u32 fixed;      /* non-zero fixed divider value */
+       };
+       u32 flags;              /* BCM_CLK_DIV_FLAGS_* below */
+};
+
+/*
+ * Divider flags:
+ *   EXISTS means this divider exists
+ *   FIXED means it is a fixed-rate divider
+ */
+#define BCM_CLK_DIV_FLAGS_EXISTS       ((u32)1 << 0)   /* Divider is valid */
+#define BCM_CLK_DIV_FLAGS_FIXED                ((u32)1 << 1)   /* Fixed-value */
+
+/* Divider initialization macros */
+
+/* A fixed (non-zero) divider */
+#define FIXED_DIVIDER(_value)                                          \
+       {                                                               \
+               .fixed = (_value),                                      \
+               .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED),            \
+       }
+
+/* A divider with an integral divisor */
+#define DIVIDER(_offset, _shift, _width)                               \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .shift = (_shift),                                      \
+               .width = (_width),                                      \
+               .scaled_div = BAD_SCALED_DIV_VALUE,                     \
+               .flags = FLAG(DIV, EXISTS),                             \
+       }
+
+/* A divider whose divisor has an integer and fractional part */
+#define FRAC_DIVIDER(_offset, _shift, _width, _frac_width)             \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .shift = (_shift),                                      \
+               .width = (_width),                                      \
+               .frac_width = (_frac_width),                            \
+               .scaled_div = BAD_SCALED_DIV_VALUE,                     \
+               .flags = FLAG(DIV, EXISTS),                             \
+       }
+
+/*
+ * Clocks may have multiple "parent" clocks.  If there is more than
+ * one, a selector must be specified to define which of the parent
+ * clocks is currently in use.  The selected clock is indicated in a
+ * sub-field of a 32-bit selector register.  The range of
+ * representable selector values typically exceeds the number of
+ * available parent clocks.  Occasionally the reset value of a
+ * selector field is explicitly set to a (specific) value that does
+ * not correspond to a defined input clock.
+ *
+ * We register all known parent clocks with the common clock code
+ * using a packed array (i.e., no empty slots) of (parent) clock
+ * names, and refer to them later using indexes into that array.
+ * We maintain an array of selector values indexed by common clock
+ * index values in order to map between these common clock indexes
+ * and the selector values used by the hardware.
+ *
+ * Like dividers, a selector can be modified, but to do so a clock
+ * must be enabled, and a trigger must be used to commit the change.
+ */
+struct bcm_clk_sel {
+       u32 offset;             /* selector register offset */
+       u32 shift;              /* field shift */
+       u32 width;              /* field width */
+
+       u32 parent_count;       /* number of entries in parent_sel[] */
+       u32 *parent_sel;        /* array of parent selector values */
+       u8 clk_index;           /* current selected index in parent_sel[] */
+};
+
+/* Selector initialization macro */
+#define SELECTOR(_offset, _shift, _width)                              \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .shift = (_shift),                                      \
+               .width = (_width),                                      \
+               .clk_index = BAD_CLK_INDEX,                             \
+       }
+
+/*
+ * Making changes to a variable divider or a selector for a clock
+ * requires the use of a trigger.  A trigger is defined by a single
+ * bit within a register.  To signal a change, a 1 is written into
+ * that bit.  To determine when the change has been completed, that
+ * trigger bit is polled; the read value will be 1 while the change
+ * is in progress, and 0 when it is complete.
+ *
+ * Occasionally a clock will have more than one trigger.  In this
+ * case, the "pre-trigger" will be used when changing a clock's
+ * selector and/or its pre-divider.
+ */
+struct bcm_clk_trig {
+       u32 offset;             /* trigger register offset */
+       u32 bit;                /* trigger bit */
+       u32 flags;              /* BCM_CLK_TRIG_FLAGS_* below */
+};
+
+/*
+ * Trigger flags:
+ *   EXISTS means this trigger exists
+ */
+#define BCM_CLK_TRIG_FLAGS_EXISTS      ((u32)1 << 0)   /* Trigger is valid */
+
+/* Trigger initialization macro */
+#define TRIGGER(_offset, _bit)                                         \
+       {                                                               \
+               .offset = (_offset),                                    \
+               .bit = (_bit),                                          \
+               .flags = FLAG(TRIG, EXISTS),                            \
+       }
+
+struct peri_clk_data {
+       struct bcm_clk_gate gate;
+       struct bcm_clk_trig pre_trig;
+       struct bcm_clk_div pre_div;
+       struct bcm_clk_trig trig;
+       struct bcm_clk_div div;
+       struct bcm_clk_sel sel;
+       const char *clocks[];   /* must be last; use CLOCKS() to declare */
+};
+#define CLOCKS(...)    { __VA_ARGS__, NULL, }
+#define NO_CLOCKS      { NULL, }       /* Must use of no parent clocks */
+
+struct kona_clk {
+       struct clk_hw hw;
+       struct clk_init_data init_data;
+       const char *name;       /* name of this clock */
+       struct ccu_data *ccu;   /* ccu this clock is associated with */
+       enum bcm_clk_type type;
+       union {
+               void *data;
+               struct peri_clk_data *peri;
+       };
+};
+#define to_kona_clk(_hw) \
+       container_of(_hw, struct kona_clk, hw)
+
+/* Exported globals */
+
+extern struct clk_ops kona_peri_clk_ops;
+
+/* Help functions */
+
+#define PERI_CLK_SETUP(clks, ccu, id, name) \
+       clks[id] = kona_clk_setup(ccu, #name, bcm_clk_peri, &name ## _data)
+
+/* Externally visible functions */
+
+extern u64 do_div_round_closest(u64 dividend, unsigned long divisor);
+extern u64 scaled_div_max(struct bcm_clk_div *div);
+extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
+                               u32 billionths);
+
+extern struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name,
+                       enum bcm_clk_type type, void *data);
+extern void __init kona_dt_ccu_setup(struct device_node *node,
+                       int (*ccu_clks_setup)(struct ccu_data *));
+extern bool __init kona_ccu_init(struct ccu_data *ccu);
+
+#endif /* _CLK_KONA_H */
index 8137327847c3af40ab3fb4e512592f68c92e4b85..1127ee46b8024548151b9920246ef286cc887b99 100644 (file)
 #include <linux/module.h>
 #include <linux/err.h>
 
-#define AXI_CLKGEN_REG_UPDATE_ENABLE   0x04
-#define AXI_CLKGEN_REG_CLK_OUT1                0x08
-#define AXI_CLKGEN_REG_CLK_OUT2                0x0c
-#define AXI_CLKGEN_REG_CLK_DIV         0x10
-#define AXI_CLKGEN_REG_CLK_FB1         0x14
-#define AXI_CLKGEN_REG_CLK_FB2         0x18
-#define AXI_CLKGEN_REG_LOCK1           0x1c
-#define AXI_CLKGEN_REG_LOCK2           0x20
-#define AXI_CLKGEN_REG_LOCK3           0x24
-#define AXI_CLKGEN_REG_FILTER1         0x28
-#define AXI_CLKGEN_REG_FILTER2         0x2c
+#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE        0x04
+#define AXI_CLKGEN_V1_REG_CLK_OUT1     0x08
+#define AXI_CLKGEN_V1_REG_CLK_OUT2     0x0c
+#define AXI_CLKGEN_V1_REG_CLK_DIV      0x10
+#define AXI_CLKGEN_V1_REG_CLK_FB1      0x14
+#define AXI_CLKGEN_V1_REG_CLK_FB2      0x18
+#define AXI_CLKGEN_V1_REG_LOCK1                0x1c
+#define AXI_CLKGEN_V1_REG_LOCK2                0x20
+#define AXI_CLKGEN_V1_REG_LOCK3                0x24
+#define AXI_CLKGEN_V1_REG_FILTER1      0x28
+#define AXI_CLKGEN_V1_REG_FILTER2      0x2c
+
+#define AXI_CLKGEN_V2_REG_RESET                0x40
+#define AXI_CLKGEN_V2_REG_DRP_CNTRL    0x70
+#define AXI_CLKGEN_V2_REG_DRP_STATUS   0x74
+
+#define AXI_CLKGEN_V2_RESET_MMCM_ENABLE        BIT(1)
+#define AXI_CLKGEN_V2_RESET_ENABLE     BIT(0)
+
+#define AXI_CLKGEN_V2_DRP_CNTRL_SEL    BIT(29)
+#define AXI_CLKGEN_V2_DRP_CNTRL_READ   BIT(28)
+
+#define AXI_CLKGEN_V2_DRP_STATUS_BUSY  BIT(16)
+
+#define MMCM_REG_CLKOUT0_1     0x08
+#define MMCM_REG_CLKOUT0_2     0x09
+#define MMCM_REG_CLK_FB1       0x14
+#define MMCM_REG_CLK_FB2       0x15
+#define MMCM_REG_CLK_DIV       0x16
+#define MMCM_REG_LOCK1         0x18
+#define MMCM_REG_LOCK2         0x19
+#define MMCM_REG_LOCK3         0x1a
+#define MMCM_REG_FILTER1       0x4e
+#define MMCM_REG_FILTER2       0x4f
+
+struct axi_clkgen;
+
+struct axi_clkgen_mmcm_ops {
+       void (*enable)(struct axi_clkgen *axi_clkgen, bool enable);
+       int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg,
+                    unsigned int val, unsigned int mask);
+       int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg,
+                   unsigned int *val);
+};
 
 struct axi_clkgen {
        void __iomem *base;
+       const struct axi_clkgen_mmcm_ops *mmcm_ops;
        struct clk_hw clk_hw;
 };
 
+static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
+       bool enable)
+{
+       axi_clkgen->mmcm_ops->enable(axi_clkgen, enable);
+}
+
+static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int val, unsigned int mask)
+{
+       return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask);
+}
+
+static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int *val)
+{
+       return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val);
+}
+
 static uint32_t axi_clkgen_lookup_filter(unsigned int m)
 {
        switch (m) {
@@ -156,6 +208,148 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
        *val = readl(axi_clkgen->base + reg);
 }
 
+static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg)
+{
+       switch (reg) {
+       case MMCM_REG_CLKOUT0_1:
+               return AXI_CLKGEN_V1_REG_CLK_OUT1;
+       case MMCM_REG_CLKOUT0_2:
+               return AXI_CLKGEN_V1_REG_CLK_OUT2;
+       case MMCM_REG_CLK_FB1:
+               return AXI_CLKGEN_V1_REG_CLK_FB1;
+       case MMCM_REG_CLK_FB2:
+               return AXI_CLKGEN_V1_REG_CLK_FB2;
+       case MMCM_REG_CLK_DIV:
+               return AXI_CLKGEN_V1_REG_CLK_DIV;
+       case MMCM_REG_LOCK1:
+               return AXI_CLKGEN_V1_REG_LOCK1;
+       case MMCM_REG_LOCK2:
+               return AXI_CLKGEN_V1_REG_LOCK2;
+       case MMCM_REG_LOCK3:
+               return AXI_CLKGEN_V1_REG_LOCK3;
+       case MMCM_REG_FILTER1:
+               return AXI_CLKGEN_V1_REG_FILTER1;
+       case MMCM_REG_FILTER2:
+               return AXI_CLKGEN_V1_REG_FILTER2;
+       default:
+               return 0;
+       }
+}
+
+static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int val, unsigned int mask)
+{
+       reg = axi_clkgen_v1_map_mmcm_reg(reg);
+       if (reg == 0)
+               return -EINVAL;
+
+       axi_clkgen_write(axi_clkgen, reg, val);
+
+       return 0;
+}
+
+static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int *val)
+{
+       reg = axi_clkgen_v1_map_mmcm_reg(reg);
+       if (reg == 0)
+               return -EINVAL;
+
+       axi_clkgen_read(axi_clkgen, reg, val);
+
+       return 0;
+}
+
+static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen,
+       bool enable)
+{
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable);
+}
+
+static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = {
+       .write = axi_clkgen_v1_mmcm_write,
+       .read = axi_clkgen_v1_mmcm_read,
+       .enable = axi_clkgen_v1_mmcm_enable,
+};
+
+static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
+{
+       unsigned int timeout = 10000;
+       unsigned int val;
+
+       do {
+               axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_STATUS, &val);
+       } while ((val & AXI_CLKGEN_V2_DRP_STATUS_BUSY) && --timeout);
+
+       if (val & AXI_CLKGEN_V2_DRP_STATUS_BUSY)
+               return -EIO;
+
+       return val & 0xffff;
+}
+
+static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int *val)
+{
+       unsigned int reg_val;
+       int ret;
+
+       ret = axi_clkgen_wait_non_busy(axi_clkgen);
+       if (ret < 0)
+               return ret;
+
+       reg_val = AXI_CLKGEN_V2_DRP_CNTRL_SEL | AXI_CLKGEN_V2_DRP_CNTRL_READ;
+       reg_val |= (reg << 16);
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
+
+       ret = axi_clkgen_wait_non_busy(axi_clkgen);
+       if (ret < 0)
+               return ret;
+
+       *val = ret;
+
+       return 0;
+}
+
+static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int val, unsigned int mask)
+{
+       unsigned int reg_val = 0;
+       int ret;
+
+       ret = axi_clkgen_wait_non_busy(axi_clkgen);
+       if (ret < 0)
+               return ret;
+
+       if (mask != 0xffff) {
+               axi_clkgen_v2_mmcm_read(axi_clkgen, reg, &reg_val);
+               reg_val &= ~mask;
+       }
+
+       reg_val |= AXI_CLKGEN_V2_DRP_CNTRL_SEL | (reg << 16) | (val & mask);
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
+
+       return 0;
+}
+
+static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
+       bool enable)
+{
+       unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
+
+       if (enable)
+               val |= AXI_CLKGEN_V2_RESET_MMCM_ENABLE;
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
+}
+
+static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = {
+       .write = axi_clkgen_v2_mmcm_write,
+       .read = axi_clkgen_v2_mmcm_read,
+       .enable = axi_clkgen_v2_mmcm_enable,
+};
+
 static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
 {
        return container_of(clk_hw, struct axi_clkgen, clk_hw);
@@ -184,33 +378,29 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
        filter = axi_clkgen_lookup_filter(m - 1);
        lock = axi_clkgen_lookup_lock(m - 1);
 
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0);
-
        axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1,
-               (high << 6) | low);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2,
-               (edge << 7) | (nocount << 6));
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_1,
+               (high << 6) | low, 0xefff);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_2,
+               (edge << 7) | (nocount << 6), 0x03ff);
 
        axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV,
-               (edge << 13) | (nocount << 12) | (high << 6) | low);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV,
+               (edge << 13) | (nocount << 12) | (high << 6) | low, 0x3fff);
 
        axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1,
-               (high << 6) | low);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2,
-               (edge << 7) | (nocount << 6));
-
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2,
-               (((lock >> 16) & 0x1f) << 10) | 0x1);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3,
-               (((lock >> 24) & 0x1f) << 10) | 0x3e9);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16);
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter);
-
-       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB1,
+               (high << 6) | low, 0xefff);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB2,
+               (edge << 7) | (nocount << 6), 0x03ff);
+
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2,
+               (((lock >> 16) & 0x1f) << 10) | 0x1, 0x7fff);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK3,
+               (((lock >> 24) & 0x1f) << 10) | 0x3e9, 0x7fff);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER1, filter >> 16, 0x9900);
+       axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER2, filter, 0x9900);
 
        return 0;
 }
@@ -236,11 +426,11 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
        unsigned int reg;
        unsigned long long tmp;
 
-       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, &reg);
+       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
        dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
-       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, &reg);
+       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &reg);
        d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
-       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, &reg);
+       axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
        m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
 
        if (d == 0 || dout == 0)
@@ -255,14 +445,45 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
        return tmp;
 }
 
+static int axi_clkgen_enable(struct clk_hw *clk_hw)
+{
+       struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+
+       axi_clkgen_mmcm_enable(axi_clkgen, true);
+
+       return 0;
+}
+
+static void axi_clkgen_disable(struct clk_hw *clk_hw)
+{
+       struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+
+       axi_clkgen_mmcm_enable(axi_clkgen, false);
+}
+
 static const struct clk_ops axi_clkgen_ops = {
        .recalc_rate = axi_clkgen_recalc_rate,
        .round_rate = axi_clkgen_round_rate,
        .set_rate = axi_clkgen_set_rate,
+       .enable = axi_clkgen_enable,
+       .disable = axi_clkgen_disable,
 };
 
+static const struct of_device_id axi_clkgen_ids[] = {
+       {
+               .compatible = "adi,axi-clkgen-1.00.a",
+               .data = &axi_clkgen_v1_mmcm_ops
+       }, {
+               .compatible = "adi,axi-clkgen-2.00.a",
+               .data = &axi_clkgen_v2_mmcm_ops,
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
+
 static int axi_clkgen_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *id;
        struct axi_clkgen *axi_clkgen;
        struct clk_init_data init;
        const char *parent_name;
@@ -270,10 +491,19 @@ static int axi_clkgen_probe(struct platform_device *pdev)
        struct resource *mem;
        struct clk *clk;
 
+       if (!pdev->dev.of_node)
+               return -ENODEV;
+
+       id = of_match_node(axi_clkgen_ids, pdev->dev.of_node);
+       if (!id)
+               return -ENODEV;
+
        axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
        if (!axi_clkgen)
                return -ENOMEM;
 
+       axi_clkgen->mmcm_ops = id->data;
+
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
        if (IS_ERR(axi_clkgen->base))
@@ -289,10 +519,12 @@ static int axi_clkgen_probe(struct platform_device *pdev)
 
        init.name = clk_name;
        init.ops = &axi_clkgen_ops;
-       init.flags = 0;
+       init.flags = CLK_SET_RATE_GATE;
        init.parent_names = &parent_name;
        init.num_parents = 1;
 
+       axi_clkgen_mmcm_enable(axi_clkgen, false);
+
        axi_clkgen->clk_hw.init = &init;
        clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
        if (IS_ERR(clk))
@@ -309,12 +541,6 @@ static int axi_clkgen_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id axi_clkgen_ids[] = {
-       { .compatible = "adi,axi-clkgen-1.00.a" },
-       { },
-};
-MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
-
 static struct platform_driver axi_clkgen_driver = {
        .driver = {
                .name = "adi-axi-clkgen",
index 5543b7df8e16c736c210407a5d837ffb32ab3beb..ec22112e569f7f3dc8f7c9477d0e3f99951e66c6 100644 (file)
@@ -24,7 +24,7 @@
  * 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 = parent->rate / divisor
+ * rate - rate is adjustable.  clk->rate = DIV_ROUND_UP(parent->rate / divisor)
  * parent - fixed parent.  No clk_set_parent support
  */
 
@@ -115,7 +115,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
                return parent_rate;
        }
 
-       return parent_rate / div;
+       return DIV_ROUND_UP(parent_rate, div);
 }
 
 /*
@@ -185,7 +185,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
                }
                parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
                                MULT_ROUND_UP(rate, i));
-               now = parent_rate / i;
+               now = DIV_ROUND_UP(parent_rate, i);
                if (now <= rate && now > best) {
                        bestdiv = i;
                        best = now;
@@ -207,7 +207,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
        int div;
        div = clk_divider_bestdiv(hw, rate, prate);
 
-       return *prate / div;
+       return DIV_ROUND_UP(*prate, div);
 }
 
 static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -218,7 +218,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        unsigned long flags = 0;
        u32 val;
 
-       div = parent_rate / rate;
+       div = DIV_ROUND_UP(parent_rate, rate);
        value = _get_val(divider, div);
 
        if (value > div_mask(divider))
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
new file mode 100644 (file)
index 0000000..30a3b69
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * MOXA ART SoCs clock driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.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>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/clkdev.h>
+
+void __init moxart_of_pll_clk_init(struct device_node *node)
+{
+       static void __iomem *base;
+       struct clk *clk, *ref_clk;
+       unsigned int mul;
+       const char *name = node->name;
+       const char *parent_name;
+
+       of_property_read_string(node, "clock-output-names", &name);
+       parent_name = of_clk_get_parent_name(node, 0);
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s: of_iomap failed\n", node->full_name);
+               return;
+       }
+
+       mul = readl(base + 0x30) >> 3 & 0x3f;
+       iounmap(base);
+
+       ref_clk = of_clk_get(node, 0);
+       if (IS_ERR(ref_clk)) {
+               pr_err("%s: of_clk_get failed\n", node->full_name);
+               return;
+       }
+
+       clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register clock\n", node->full_name);
+               return;
+       }
+
+       clk_register_clkdev(clk, NULL, name);
+       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
+              moxart_of_pll_clk_init);
+
+void __init moxart_of_apb_clk_init(struct device_node *node)
+{
+       static void __iomem *base;
+       struct clk *clk, *pll_clk;
+       unsigned int div, val;
+       unsigned int div_idx[] = { 2, 3, 4, 6, 8};
+       const char *name = node->name;
+       const char *parent_name;
+
+       of_property_read_string(node, "clock-output-names", &name);
+       parent_name = of_clk_get_parent_name(node, 0);
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s: of_iomap failed\n", node->full_name);
+               return;
+       }
+
+       val = readl(base + 0xc) >> 4 & 0x7;
+       iounmap(base);
+
+       if (val > 4)
+               val = 0;
+       div = div_idx[val] * 2;
+
+       pll_clk = of_clk_get(node, 0);
+       if (IS_ERR(pll_clk)) {
+               pr_err("%s: of_clk_get failed\n", node->full_name);
+               return;
+       }
+
+       clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register clock\n", node->full_name);
+               return;
+       }
+
+       clk_register_clkdev(clk, NULL, name);
+       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
+              moxart_of_apb_clk_init);
index c4f76ed914b023420aaf012b25369c88c3090a1a..8b284be4efa4ad7ae65d1c0947715c5522785cae 100644 (file)
@@ -27,7 +27,6 @@ struct cmux_clk {
 #define CLKSEL_ADJUST          BIT(0)
 #define to_cmux_clk(p)         container_of(p, struct cmux_clk, hw)
 
-static void __iomem *base;
 static unsigned int clocks_per_pll;
 
 static int cmux_set_parent(struct clk_hw *hw, u8 idx)
@@ -100,7 +99,11 @@ static void __init core_mux_init(struct device_node *np)
                pr_err("%s: could not allocate cmux_clk\n", __func__);
                goto err_name;
        }
-       cmux_clk->reg = base + offset;
+       cmux_clk->reg = of_iomap(np, 0);
+       if (!cmux_clk->reg) {
+               pr_err("%s: could not map register\n", __func__);
+               goto err_clk;
+       }
 
        node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
        if (node && (offset >= 0x80))
@@ -143,38 +146,39 @@ err_name:
 
 static void __init core_pll_init(struct device_node *np)
 {
-       u32 offset, mult;
+       u32 mult;
        int i, rc, count;
        const char *clk_name, *parent_name;
        struct clk_onecell_data *onecell_data;
        struct clk      **subclks;
+       void __iomem *base;
 
-       rc = of_property_read_u32(np, "reg", &offset);
-       if (rc) {
-               pr_err("%s: could not get reg property\n", np->name);
+       base = of_iomap(np, 0);
+       if (!base) {
+               pr_err("clk-ppc: iomap error\n");
                return;
        }
 
        /* get the multiple of PLL */
-       mult = ioread32be(base + offset);
+       mult = ioread32be(base);
 
        /* check if this PLL is disabled */
        if (mult & PLL_KILL) {
                pr_debug("PLL:%s is disabled\n", np->name);
-               return;
+               goto err_map;
        }
        mult = (mult >> 1) & 0x3f;
 
        parent_name = of_clk_get_parent_name(np, 0);
        if (!parent_name) {
                pr_err("PLL: %s must have a parent\n", np->name);
-               return;
+               goto err_map;
        }
 
        count = of_property_count_strings(np, "clock-output-names");
        if (count < 0 || count > 4) {
                pr_err("%s: clock is not supported\n", np->name);
-               return;
+               goto err_map;
        }
 
        /* output clock number per PLL */
@@ -183,7 +187,7 @@ static void __init core_pll_init(struct device_node *np)
        subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
        if (!subclks) {
                pr_err("%s: could not allocate subclks\n", __func__);
-               return;
+               goto err_map;
        }
 
        onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
@@ -230,30 +234,52 @@ static void __init core_pll_init(struct device_node *np)
                goto err_cell;
        }
 
+       iounmap(base);
        return;
 err_cell:
        kfree(onecell_data);
 err_clks:
        kfree(subclks);
+err_map:
+       iounmap(base);
+}
+
+static void __init sysclk_init(struct device_node *node)
+{
+       struct clk *clk;
+       const char *clk_name = node->name;
+       struct device_node *np = of_get_parent(node);
+       u32 rate;
+
+       if (!np) {
+               pr_err("ppc-clk: could not get parent node\n");
+               return;
+       }
+
+       if (of_property_read_u32(np, "clock-frequency", &rate)) {
+               of_node_put(node);
+               return;
+       }
+
+       of_property_read_string(np, "clock-output-names", &clk_name);
+
+       clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate);
+       if (!IS_ERR(clk))
+               of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
 
 static const struct of_device_id clk_match[] __initconst = {
-       { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
-       { .compatible = "fsl,core-pll-clock", .data = core_pll_init, },
-       { .compatible = "fsl,core-mux-clock", .data = core_mux_init, },
+       { .compatible = "fsl,qoriq-sysclk-1.0", .data = sysclk_init, },
+       { .compatible = "fsl,qoriq-sysclk-2.0", .data = sysclk_init, },
+       { .compatible = "fsl,qoriq-core-pll-1.0", .data = core_pll_init, },
+       { .compatible = "fsl,qoriq-core-pll-2.0", .data = core_pll_init, },
+       { .compatible = "fsl,qoriq-core-mux-1.0", .data = core_mux_init, },
+       { .compatible = "fsl,qoriq-core-mux-2.0", .data = core_mux_init, },
        {}
 };
 
 static int __init ppc_corenet_clk_probe(struct platform_device *pdev)
 {
-       struct device_node *np;
-
-       np = pdev->dev.of_node;
-       base = of_iomap(np, 0);
-       if (!base) {
-               dev_err(&pdev->dev, "iomap error\n");
-               return -ENOMEM;
-       }
        of_clk_init(clk_match);
 
        return 0;
index 00a3abe103a5ac472dfb352a1bb0cec42cd29ddb..f2f62a1bf61aaae9094e316eeddb4830a3286a55 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s5m8767.h>
 #include <linux/mfd/samsung/core.h>
 
 #define s2mps11_name(a) (a->hw.init->name)
@@ -48,6 +49,7 @@ struct s2mps11_clk {
        struct clk_lookup *lookup;
        u32 mask;
        bool enabled;
+       unsigned int reg;
 };
 
 static struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw)
@@ -61,7 +63,7 @@ static int s2mps11_clk_prepare(struct clk_hw *hw)
        int ret;
 
        ret = regmap_update_bits(s2mps11->iodev->regmap_pmic,
-                               S2MPS11_REG_RTC_CTRL,
+                                s2mps11->reg,
                                 s2mps11->mask, s2mps11->mask);
        if (!ret)
                s2mps11->enabled = true;
@@ -74,7 +76,7 @@ static void s2mps11_clk_unprepare(struct clk_hw *hw)
        struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
        int ret;
 
-       ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, S2MPS11_REG_RTC_CTRL,
+       ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, s2mps11->reg,
                           s2mps11->mask, ~s2mps11->mask);
 
        if (!ret)
@@ -130,9 +132,9 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev)
        int i;
 
        if (!iodev->dev->of_node)
-               return NULL;
+               return ERR_PTR(-EINVAL);
 
-       clk_np = of_find_node_by_name(iodev->dev->of_node, "clocks");
+       clk_np = of_get_child_by_name(iodev->dev->of_node, "clocks");
        if (!clk_np) {
                dev_err(&pdev->dev, "could not find clock sub-node\n");
                return ERR_PTR(-EINVAL);
@@ -155,6 +157,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
        struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct s2mps11_clk *s2mps11_clks, *s2mps11_clk;
        struct device_node *clk_np = NULL;
+       unsigned int s2mps11_reg;
        int i, ret = 0;
        u32 val;
 
@@ -169,13 +172,26 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
        if (IS_ERR(clk_np))
                return PTR_ERR(clk_np);
 
+       switch(platform_get_device_id(pdev)->driver_data) {
+       case S2MPS11X:
+               s2mps11_reg = S2MPS11_REG_RTC_CTRL;
+               break;
+       case S5M8767X:
+               s2mps11_reg = S5M8767_REG_CTRL1;
+               break;
+       default:
+               dev_err(&pdev->dev, "Invalid device type\n");
+               return -EINVAL;
+       };
+
        for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) {
                s2mps11_clk->iodev = iodev;
                s2mps11_clk->hw.init = &s2mps11_clks_init[i];
                s2mps11_clk->mask = 1 << i;
+               s2mps11_clk->reg = s2mps11_reg;
 
                ret = regmap_read(s2mps11_clk->iodev->regmap_pmic,
-                                 S2MPS11_REG_RTC_CTRL, &val);
+                                 s2mps11_clk->reg, &val);
                if (ret < 0)
                        goto err_reg;
 
@@ -241,7 +257,8 @@ static int s2mps11_clk_remove(struct platform_device *pdev)
 }
 
 static const struct platform_device_id s2mps11_clk_id[] = {
-       { "s2mps11-clk", 0},
+       { "s2mps11-clk", S2MPS11X},
+       { "s5m8767-clk", S5M8767X},
        { },
 };
 MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
index c42e608af6bbe0980717a74e69a143cdc742f1b1..dff0373f53c1fb1df1784366a28c35323cde17a5 100644 (file)
@@ -277,6 +277,10 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
        if (!d)
                goto err_out;
 
+       if (clk->ops->debug_init)
+               if (clk->ops->debug_init(clk->hw, clk->dentry))
+                       goto err_out;
+
        ret = 0;
        goto out;
 
@@ -1339,8 +1343,11 @@ static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
        if (clk->notifier_count)
                ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate);
 
-       if (ret & NOTIFY_STOP_MASK)
+       if (ret & NOTIFY_STOP_MASK) {
+               pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n",
+                               __func__, clk->name, ret);
                goto out;
+       }
 
        hlist_for_each_entry(child, &clk->children, child_node) {
                ret = __clk_speculate_rates(child, new_rate);
@@ -1588,7 +1595,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        /* notify that we are about to change rates */
        fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
        if (fail_clk) {
-               pr_warn("%s: failed to set %s rate\n", __func__,
+               pr_debug("%s: failed to set %s rate\n", __func__,
                                fail_clk->name);
                clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
                ret = -EBUSY;
@@ -2260,20 +2267,11 @@ void __clk_put(struct clk *clk)
  * re-enter into the clk framework by calling any top-level clk APIs;
  * this will cause a nested prepare_lock mutex.
  *
- * Pre-change notifier callbacks will be passed the current, pre-change
- * rate of the clk via struct clk_notifier_data.old_rate.  The new,
- * post-change rate of the clk is passed via struct
- * clk_notifier_data.new_rate.
- *
- * Post-change notifiers will pass the now-current, post-change rate of
- * the clk in both struct clk_notifier_data.old_rate and struct
+ * In all notification cases cases (pre, post and abort rate change) the
+ * original clock rate is passed to the callback via struct
+ * clk_notifier_data.old_rate and the new frequency is passed via struct
  * clk_notifier_data.new_rate.
  *
- * Abort-change notifiers are effectively the opposite of pre-change
- * notifiers: the original pre-change clk rate is passed in via struct
- * clk_notifier_data.new_rate and the failed post-change rate is passed
- * in via struct clk_notifier_data.old_rate.
- *
  * clk_notifier_register() must be called from non-atomic context.
  * Returns -EINVAL if called with null arguments, -ENOMEM upon
  * allocation failure; otherwise, passes along the return value of
@@ -2473,7 +2471,7 @@ EXPORT_SYMBOL_GPL(of_clk_del_provider);
 struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
        struct of_clk_provider *provider;
-       struct clk *clk = ERR_PTR(-ENOENT);
+       struct clk *clk = ERR_PTR(-EPROBE_DEFER);
 
        /* Check if we have such a provider in our array */
        list_for_each_entry(provider, &of_clk_providers, link) {
@@ -2506,8 +2504,12 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
 const char *of_clk_get_parent_name(struct device_node *np, int index)
 {
        struct of_phandle_args clkspec;
+       struct property *prop;
        const char *clk_name;
+       const __be32 *vp;
+       u32 pv;
        int rc;
+       int count;
 
        if (index < 0)
                return NULL;
@@ -2517,8 +2519,22 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
        if (rc)
                return NULL;
 
+       index = clkspec.args_count ? clkspec.args[0] : 0;
+       count = 0;
+
+       /* if there is an indices property, use it to transfer the index
+        * specified into an array offset for the clock-output-names property.
+        */
+       of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) {
+               if (index == pv) {
+                       index = count;
+                       break;
+               }
+               count++;
+       }
+
        if (of_property_read_string_index(clkspec.np, "clock-output-names",
-                                         clkspec.args_count ? clkspec.args[0] : 0,
+                                         index,
                                          &clk_name) < 0)
                clk_name = clkspec.np->name;
 
@@ -2527,24 +2543,99 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
 }
 EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
 
+struct clock_provider {
+       of_clk_init_cb_t clk_init_cb;
+       struct device_node *np;
+       struct list_head node;
+};
+
+static LIST_HEAD(clk_provider_list);
+
+/*
+ * This function looks for a parent clock. If there is one, then it
+ * checks that the provider for this parent clock was initialized, in
+ * this case the parent clock will be ready.
+ */
+static int parent_ready(struct device_node *np)
+{
+       int i = 0;
+
+       while (true) {
+               struct clk *clk = of_clk_get(np, i);
+
+               /* this parent is ready we can check the next one */
+               if (!IS_ERR(clk)) {
+                       clk_put(clk);
+                       i++;
+                       continue;
+               }
+
+               /* at least one parent is not ready, we exit now */
+               if (PTR_ERR(clk) == -EPROBE_DEFER)
+                       return 0;
+
+               /*
+                * Here we make assumption that the device tree is
+                * written correctly. So an error means that there is
+                * no more parent. As we didn't exit yet, then the
+                * previous parent are ready. If there is no clock
+                * parent, no need to wait for them, then we can
+                * consider their absence as being ready
+                */
+               return 1;
+       }
+}
+
 /**
  * of_clk_init() - Scan and init clock providers from the DT
  * @matches: array of compatible values and init functions for providers.
  *
- * This function scans the device tree for matching clock providers and
- * calls their initialization functions
+ * This function scans the device tree for matching clock providers
+ * and calls their initialization functions. It also does it by trying
+ * to follow the dependencies.
  */
 void __init of_clk_init(const struct of_device_id *matches)
 {
        const struct of_device_id *match;
        struct device_node *np;
+       struct clock_provider *clk_provider, *next;
+       bool is_init_done;
+       bool force = false;
 
        if (!matches)
                matches = &__clk_of_table;
 
+       /* First prepare the list of the clocks providers */
        for_each_matching_node_and_match(np, matches, &match) {
-               of_clk_init_cb_t clk_init_cb = match->data;
-               clk_init_cb(np);
+               struct clock_provider *parent =
+                       kzalloc(sizeof(struct clock_provider),  GFP_KERNEL);
+
+               parent->clk_init_cb = match->data;
+               parent->np = np;
+               list_add_tail(&parent->node, &clk_provider_list);
+       }
+
+       while (!list_empty(&clk_provider_list)) {
+               is_init_done = false;
+               list_for_each_entry_safe(clk_provider, next,
+                                       &clk_provider_list, node) {
+                       if (force || parent_ready(clk_provider->np)) {
+                               clk_provider->clk_init_cb(clk_provider->np);
+                               list_del(&clk_provider->node);
+                               kfree(clk_provider);
+                               is_init_done = true;
+                       }
+               }
+
+               /*
+                * We didn't manage to initialize any of the
+                * remaining providers during the last loop, so now we
+                * initialize all the remaining ones unconditionally
+                * in case the clock parent was not mandatory
+                */
+               if (!is_init_done)
+                       force = true;
+
        }
 }
 #endif
index 48f67218247cb0cb44cfa92b8ed4903a0f193531..a360b2eca5cbff29c793c2100f97b81b22b74f3b 100644 (file)
@@ -167,6 +167,8 @@ struct clk *clk_get(struct device *dev, const char *con_id)
                clk = of_clk_get_by_name(dev->of_node, con_id);
                if (!IS_ERR(clk))
                        return clk;
+               if (PTR_ERR(clk) == -EPROBE_DEFER)
+                       return clk;
        }
 
        return clk_get_sys(dev_id, con_id);
index a049108341fc60e0b14d50f6f59b5ae51943c5d6..40b33c6a8257af88fb5f66601bbf4a9a1321980d 100644 (file)
@@ -2,4 +2,7 @@
 # Hisilicon Clock specific Makefile
 #
 
-obj-y  += clk.o clkgate-separated.o clk-hi3620.o
+obj-y  += clk.o clkgate-separated.o
+
+obj-$(CONFIG_ARCH_HI3xxx)      += clk-hi3620.o
+obj-$(CONFIG_ARCH_HIP04)       += clk-hip04.o
index f24ad6a3a7970c346001fd4798dbb69b6c11a096..339945d2503b33798ca4e98b51e140f2b8f658ae 100644 (file)
@@ -210,33 +210,297 @@ static struct hisi_gate_clock hi3620_seperated_gate_clks[] __initdata = {
 
 static void __init hi3620_clk_init(struct device_node *np)
 {
-       void __iomem *base;
+       struct hisi_clock_data *clk_data;
 
-       if (np) {
-               base = of_iomap(np, 0);
-               if (!base) {
-                       pr_err("failed to map Hi3620 clock registers\n");
-                       return;
-               }
-       } else {
-               pr_err("failed to find Hi3620 clock node in DTS\n");
+       clk_data = hisi_clk_init(np, HI3620_NR_CLKS);
+       if (!clk_data)
                return;
-       }
-
-       hisi_clk_init(np, HI3620_NR_CLKS);
 
        hisi_clk_register_fixed_rate(hi3620_fixed_rate_clks,
                                     ARRAY_SIZE(hi3620_fixed_rate_clks),
-                                    base);
+                                    clk_data);
        hisi_clk_register_fixed_factor(hi3620_fixed_factor_clks,
                                       ARRAY_SIZE(hi3620_fixed_factor_clks),
-                                      base);
+                                      clk_data);
        hisi_clk_register_mux(hi3620_mux_clks, ARRAY_SIZE(hi3620_mux_clks),
-                             base);
+                             clk_data);
        hisi_clk_register_divider(hi3620_div_clks, ARRAY_SIZE(hi3620_div_clks),
-                                 base);
+                                 clk_data);
        hisi_clk_register_gate_sep(hi3620_seperated_gate_clks,
                                   ARRAY_SIZE(hi3620_seperated_gate_clks),
-                                  base);
+                                  clk_data);
 }
 CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
+
+struct hisi_mmc_clock {
+       unsigned int            id;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       u32                     clken_reg;
+       u32                     clken_bit;
+       u32                     div_reg;
+       u32                     div_off;
+       u32                     div_bits;
+       u32                     drv_reg;
+       u32                     drv_off;
+       u32                     drv_bits;
+       u32                     sam_reg;
+       u32                     sam_off;
+       u32                     sam_bits;
+};
+
+struct clk_mmc {
+       struct clk_hw   hw;
+       u32             id;
+       void __iomem    *clken_reg;
+       u32             clken_bit;
+       void __iomem    *div_reg;
+       u32             div_off;
+       u32             div_bits;
+       void __iomem    *drv_reg;
+       u32             drv_off;
+       u32             drv_bits;
+       void __iomem    *sam_reg;
+       u32             sam_off;
+       u32             sam_bits;
+};
+
+#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
+
+static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
+       { HI3620_SD_CIUCLK,     "sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4},
+       { HI3620_MMC_CIUCLK1,   "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4},
+       { HI3620_MMC_CIUCLK2,   "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4},
+       { HI3620_MMC_CIUCLK3,   "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4},
+};
+
+static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
+                      unsigned long parent_rate)
+{
+       switch (parent_rate) {
+       case 26000000:
+               return 13000000;
+       case 180000000:
+               return 25000000;
+       case 360000000:
+               return 50000000;
+       case 720000000:
+               return 100000000;
+       case 1440000000:
+               return 180000000;
+       default:
+               return parent_rate;
+       }
+}
+
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long *best_parent_rate,
+                             struct clk **best_parent_p)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long best = 0;
+
+       if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {
+               rate = 13000000;
+               best = 26000000;
+       } else if (rate <= 26000000) {
+               rate = 25000000;
+               best = 180000000;
+       } else if (rate <= 52000000) {
+               rate = 50000000;
+               best = 360000000;
+       } else if (rate <= 100000000) {
+               rate = 100000000;
+               best = 720000000;
+       } else {
+               /* max is 180M */
+               rate = 180000000;
+               best = 1440000000;
+       }
+       *best_parent_rate = best;
+       return rate;
+}
+
+static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
+{
+       u32 i;
+
+       for (i = 0; i < len; i++) {
+               if (para % 2)
+                       val |= 1 << (off + i);
+               else
+                       val &= ~(1 << (off + i));
+               para = para >> 1;
+       }
+
+       return val;
+}
+
+static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long flags;
+       u32 sam, drv, div, val;
+       static DEFINE_SPINLOCK(mmc_clk_lock);
+
+       switch (rate) {
+       case 13000000:
+               sam = 3;
+               drv = 1;
+               div = 1;
+               break;
+       case 25000000:
+               sam = 13;
+               drv = 6;
+               div = 6;
+               break;
+       case 50000000:
+               sam = 3;
+               drv = 6;
+               div = 6;
+               break;
+       case 100000000:
+               sam = 6;
+               drv = 4;
+               div = 6;
+               break;
+       case 180000000:
+               sam = 6;
+               drv = 4;
+               div = 7;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&mmc_clk_lock, flags);
+
+       val = readl_relaxed(mclk->clken_reg);
+       val &= ~(1 << mclk->clken_bit);
+       writel_relaxed(val, mclk->clken_reg);
+
+       val = readl_relaxed(mclk->sam_reg);
+       val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
+       writel_relaxed(val, mclk->sam_reg);
+
+       val = readl_relaxed(mclk->drv_reg);
+       val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
+       writel_relaxed(val, mclk->drv_reg);
+
+       val = readl_relaxed(mclk->div_reg);
+       val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
+       writel_relaxed(val, mclk->div_reg);
+
+       val = readl_relaxed(mclk->clken_reg);
+       val |= 1 << mclk->clken_bit;
+       writel_relaxed(val, mclk->clken_reg);
+
+       spin_unlock_irqrestore(&mmc_clk_lock, flags);
+
+       return 0;
+}
+
+static int mmc_clk_prepare(struct clk_hw *hw)
+{
+       struct clk_mmc *mclk = to_mmc(hw);
+       unsigned long rate;
+
+       if (mclk->id == HI3620_MMC_CIUCLK1)
+               rate = 13000000;
+       else
+               rate = 25000000;
+
+       return mmc_clk_set_timing(hw, rate);
+}
+
+static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                            unsigned long parent_rate)
+{
+       return mmc_clk_set_timing(hw, rate);
+}
+
+static struct clk_ops clk_mmc_ops = {
+       .prepare = mmc_clk_prepare,
+       .determine_rate = mmc_clk_determine_rate,
+       .set_rate = mmc_clk_set_rate,
+       .recalc_rate = mmc_clk_recalc_rate,
+};
+
+static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+                       void __iomem *base, struct device_node *np)
+{
+       struct clk_mmc *mclk;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
+       if (!mclk) {
+               pr_err("%s: fail to allocate mmc clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = mmc_clk->name;
+       init.ops = &clk_mmc_ops;
+       init.flags = mmc_clk->flags | CLK_IS_BASIC;
+       init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
+       init.num_parents = (mmc_clk->parent_name ? 1 : 0);
+       mclk->hw.init = &init;
+
+       mclk->id = mmc_clk->id;
+       mclk->clken_reg = base + mmc_clk->clken_reg;
+       mclk->clken_bit = mmc_clk->clken_bit;
+       mclk->div_reg = base + mmc_clk->div_reg;
+       mclk->div_off = mmc_clk->div_off;
+       mclk->div_bits = mmc_clk->div_bits;
+       mclk->drv_reg = base + mmc_clk->drv_reg;
+       mclk->drv_off = mmc_clk->drv_off;
+       mclk->drv_bits = mmc_clk->drv_bits;
+       mclk->sam_reg = base + mmc_clk->sam_reg;
+       mclk->sam_off = mmc_clk->sam_off;
+       mclk->sam_bits = mmc_clk->sam_bits;
+
+       clk = clk_register(NULL, &mclk->hw);
+       if (WARN_ON(IS_ERR(clk)))
+               kfree(mclk);
+       return clk;
+}
+
+static void __init hi3620_mmc_clk_init(struct device_node *node)
+{
+       void __iomem *base;
+       int i, num = ARRAY_SIZE(hi3620_mmc_clks);
+       struct clk_onecell_data *clk_data;
+
+       if (!node) {
+               pr_err("failed to find pctrl node in DTS\n");
+               return;
+       }
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("failed to map pctrl\n");
+               return;
+       }
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (WARN_ON(!clk_data))
+               return;
+
+       clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
+       if (!clk_data->clks) {
+               pr_err("%s: fail to allocate mmc clk\n", __func__);
+               return;
+       }
+
+       for (i = 0; i < num; i++) {
+               struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
+               clk_data->clks[mmc_clk->id] =
+                       hisi_register_clk_mmc(mmc_clk, base, node);
+       }
+
+       clk_data->clk_num = num;
+       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
diff --git a/drivers/clk/hisilicon/clk-hip04.c b/drivers/clk/hisilicon/clk-hip04.c
new file mode 100644 (file)
index 0000000..132b57a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Hisilicon HiP04 clock driver
+ *
+ * Copyright (c) 2013-2014 Hisilicon Limited.
+ * Copyright (c) 2013-2014 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.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/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#include <dt-bindings/clock/hip04-clock.h>
+
+#include "clk.h"
+
+/* fixed rate clocks */
+static struct hisi_fixed_rate_clock hip04_fixed_rate_clks[] __initdata = {
+       { HIP04_OSC50M,   "osc50m",   NULL, CLK_IS_ROOT, 50000000, },
+       { HIP04_CLK_50M,  "clk50m",   NULL, CLK_IS_ROOT, 50000000, },
+       { HIP04_CLK_168M, "clk168m",  NULL, CLK_IS_ROOT, 168750000, },
+};
+
+static void __init hip04_clk_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+
+       clk_data = hisi_clk_init(np, HIP04_NR_CLKS);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_fixed_rate(hip04_fixed_rate_clks,
+                                    ARRAY_SIZE(hip04_fixed_rate_clks),
+                                    clk_data);
+}
+CLK_OF_DECLARE(hip04_clk, "hisilicon,hip04-clock", hip04_clk_init);
index a3a7152c92d97008babad2df47245273db6a9338..276f672e7b1aff8f45b4a8cb86481fa57f5cf3d3 100644 (file)
 #include "clk.h"
 
 static DEFINE_SPINLOCK(hisi_clk_lock);
-static struct clk **clk_table;
-static struct clk_onecell_data clk_data;
 
-void __init hisi_clk_init(struct device_node *np, int nr_clks)
+struct hisi_clock_data __init *hisi_clk_init(struct device_node *np,
+                                            int nr_clks)
 {
+       struct hisi_clock_data *clk_data;
+       struct clk **clk_table;
+       void __iomem *base;
+
+       if (np) {
+               base = of_iomap(np, 0);
+               if (!base) {
+                       pr_err("failed to map Hisilicon clock registers\n");
+                       goto err;
+               }
+       } else {
+               pr_err("failed to find Hisilicon clock node in DTS\n");
+               goto err;
+       }
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data) {
+               pr_err("%s: could not allocate clock data\n", __func__);
+               goto err;
+       }
+       clk_data->base = base;
+
        clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
        if (!clk_table) {
                pr_err("%s: could not allocate clock lookup table\n", __func__);
-               return;
+               goto err_data;
        }
-       clk_data.clks = clk_table;
-       clk_data.clk_num = nr_clks;
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       clk_data->clk_data.clks = clk_table;
+       clk_data->clk_data.clk_num = nr_clks;
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
+       return clk_data;
+err_data:
+       kfree(clk_data);
+err:
+       return NULL;
 }
 
 void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
-                                        int nums, void __iomem *base)
+                                        int nums, struct hisi_clock_data *data)
 {
        struct clk *clk;
        int i;
@@ -68,11 +94,13 @@ void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
                               __func__, clks[i].name);
                        continue;
                }
+               data->clk_data.clks[clks[i].id] = clk;
        }
 }
 
 void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
-                                          int nums, void __iomem *base)
+                                          int nums,
+                                          struct hisi_clock_data *data)
 {
        struct clk *clk;
        int i;
@@ -87,13 +115,15 @@ void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
                               __func__, clks[i].name);
                        continue;
                }
+               data->clk_data.clks[clks[i].id] = clk;
        }
 }
 
 void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
-                                 int nums, void __iomem *base)
+                                 int nums, struct hisi_clock_data *data)
 {
        struct clk *clk;
+       void __iomem *base = data->base;
        int i;
 
        for (i = 0; i < nums; i++) {
@@ -111,14 +141,15 @@ void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
                if (clks[i].alias)
                        clk_register_clkdev(clk, clks[i].alias, NULL);
 
-               clk_table[clks[i].id] = clk;
+               data->clk_data.clks[clks[i].id] = clk;
        }
 }
 
 void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
-                                     int nums, void __iomem *base)
+                                     int nums, struct hisi_clock_data *data)
 {
        struct clk *clk;
+       void __iomem *base = data->base;
        int i;
 
        for (i = 0; i < nums; i++) {
@@ -139,14 +170,15 @@ void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
                if (clks[i].alias)
                        clk_register_clkdev(clk, clks[i].alias, NULL);
 
-               clk_table[clks[i].id] = clk;
+               data->clk_data.clks[clks[i].id] = clk;
        }
 }
 
 void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
-                                      int nums, void __iomem *base)
+                                      int nums, struct hisi_clock_data *data)
 {
        struct clk *clk;
+       void __iomem *base = data->base;
        int i;
 
        for (i = 0; i < nums; i++) {
@@ -166,6 +198,6 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
                if (clks[i].alias)
                        clk_register_clkdev(clk, clks[i].alias, NULL);
 
-               clk_table[clks[i].id] = clk;
+               data->clk_data.clks[clks[i].id] = clk;
        }
 }
index 4a6beebefb7a691d4dc3b6bb4a5d0c29d93b0a32..43fa5da88f0209760cf79f53a5745c3da99a3e6e 100644 (file)
 #include <linux/io.h>
 #include <linux/spinlock.h>
 
+struct hisi_clock_data {
+       struct clk_onecell_data clk_data;
+       void __iomem            *base;
+};
+
 struct hisi_fixed_rate_clock {
        unsigned int            id;
        char                    *name;
@@ -89,15 +94,15 @@ struct clk *hisi_register_clkgate_sep(struct device *, const char *,
                                void __iomem *, u8,
                                u8, spinlock_t *);
 
-void __init hisi_clk_init(struct device_node *, int);
+struct hisi_clock_data __init *hisi_clk_init(struct device_node *, int);
 void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *,
-                                       int, void __iomem *);
+                                       int, struct hisi_clock_data *);
 void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *,
-                                       int, void __iomem *);
+                                       int, struct hisi_clock_data *);
 void __init hisi_clk_register_mux(struct hisi_mux_clock *, int,
-                               void __iomem *);
+                               struct hisi_clock_data *);
 void __init hisi_clk_register_divider(struct hisi_divider_clock *,
-                               int, void __iomem *);
+                               int, struct hisi_clock_data *);
 void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *,
-                                       int, void __iomem *);
+                                       int, struct hisi_clock_data *);
 #endif /* __HISI_CLK_H */
index 80c1dd15d15cf267270cacb34549cb9cc304eb27..23a56f561812decc149624fe72b803a7bbb726ab 100644 (file)
@@ -40,15 +40,19 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
 
        for (i = 0; i < factor->ftbl_cnt; i++) {
                prev_rate = rate;
-               rate = (((*prate / 10000) * factor->ftbl[i].num) /
-                       (factor->ftbl[i].den * factor->masks->factor)) * 10000;
+               rate = (((*prate / 10000) * factor->ftbl[i].den) /
+                       (factor->ftbl[i].num * factor->masks->factor)) * 10000;
                if (rate > drate)
                        break;
        }
-       if (i == 0)
+       if ((i == 0) || (i == factor->ftbl_cnt)) {
                return rate;
-       else
-               return prev_rate;
+       } else {
+               if ((drate - prev_rate) > (rate - drate))
+                       return rate;
+               else
+                       return prev_rate;
+       }
 }
 
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
@@ -64,7 +68,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
        num = (val >> masks->num_shift) & masks->num_mask;
 
        /* calculate denominator */
-       den = (val >> masks->den_shift) & masks->num_mask;
+       den = (val >> masks->den_shift) & masks->den_mask;
 
        if (!den)
                return 0;
@@ -85,8 +89,8 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
 
        for (i = 0; i < factor->ftbl_cnt; i++) {
                prev_rate = rate;
-               rate = (((prate / 10000) * factor->ftbl[i].num) /
-                       (factor->ftbl[i].den * factor->masks->factor)) * 10000;
+               rate = (((prate / 10000) * factor->ftbl[i].den) /
+                       (factor->ftbl[i].num * factor->masks->factor)) * 10000;
                if (rate > drate)
                        break;
        }
index c339b829d3e33fe60af81cbfb0317cecdb12add5..693f7be129f12a0d159727c33cd126e68cf957e0 100644 (file)
@@ -13,6 +13,14 @@ config ARMADA_370_CLK
        select MVEBU_CLK_CPU
        select MVEBU_CLK_COREDIV
 
+config ARMADA_375_CLK
+       bool
+       select MVEBU_CLK_COMMON
+
+config ARMADA_38X_CLK
+       bool
+       select MVEBU_CLK_COMMON
+
 config ARMADA_XP_CLK
        bool
        select MVEBU_CLK_COMMON
index 21bbfb4a9f42e9edcda25a0705ff1f9f701ac8bd..4c66162fb0b440ca326f3f5b1510f71dbf3b755f 100644 (file)
@@ -3,6 +3,8 @@ obj-$(CONFIG_MVEBU_CLK_CPU)     += clk-cpu.o
 obj-$(CONFIG_MVEBU_CLK_COREDIV)        += clk-corediv.o
 
 obj-$(CONFIG_ARMADA_370_CLK)   += armada-370.o
+obj-$(CONFIG_ARMADA_375_CLK)   += armada-375.o
+obj-$(CONFIG_ARMADA_38X_CLK)   += armada-38x.o
 obj-$(CONFIG_ARMADA_XP_CLK)    += armada-xp.o
 obj-$(CONFIG_DOVE_CLK)         += dove.o
 obj-$(CONFIG_KIRKWOOD_CLK)     += kirkwood.o
diff --git a/drivers/clk/mvebu/armada-375.c b/drivers/clk/mvebu/armada-375.c
new file mode 100644 (file)
index 0000000..c991a4d
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Marvell Armada 375 SoC clocks
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "common.h"
+
+/*
+ * Core Clocks
+ */
+
+/*
+ * For the Armada 375 SoCs, the CPU, DDR and L2 clocks frequencies are
+ * all modified at the same time, and not separately as for the Armada
+ * 370 or the Armada XP SoCs.
+ *
+ * SAR0[21:17]   : CPU frequency    DDR frequency   L2 frequency
+ *              6   =  400 MHz     400 MHz         200 MHz
+ *              15  =  600 MHz     600 MHz         300 MHz
+ *              21  =  800 MHz     534 MHz         400 MHz
+ *              25  = 1000 MHz     500 MHz         500 MHz
+ *              others reserved.
+ *
+ * SAR0[22]   : TCLK frequency
+ *              0 = 166 MHz
+ *              1 = 200 MHz
+ */
+
+#define SAR1_A375_TCLK_FREQ_OPT                   22
+#define SAR1_A375_TCLK_FREQ_OPT_MASK      0x1
+#define SAR1_A375_CPU_DDR_L2_FREQ_OPT     17
+#define SAR1_A375_CPU_DDR_L2_FREQ_OPT_MASK 0x1F
+
+static const u32 armada_375_tclk_frequencies[] __initconst = {
+       166000000,
+       200000000,
+};
+
+static u32 __init armada_375_get_tclk_freq(void __iomem *sar)
+{
+       u8 tclk_freq_select;
+
+       tclk_freq_select = ((readl(sar) >> SAR1_A375_TCLK_FREQ_OPT) &
+                           SAR1_A375_TCLK_FREQ_OPT_MASK);
+       return armada_375_tclk_frequencies[tclk_freq_select];
+}
+
+
+static const u32 armada_375_cpu_frequencies[] __initconst = {
+       0, 0, 0, 0, 0, 0,
+       400000000,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       600000000,
+       0, 0, 0, 0, 0,
+       800000000,
+       0, 0, 0,
+       1000000000,
+};
+
+static u32 __init armada_375_get_cpu_freq(void __iomem *sar)
+{
+       u8 cpu_freq_select;
+
+       cpu_freq_select = ((readl(sar) >> SAR1_A375_CPU_DDR_L2_FREQ_OPT) &
+                          SAR1_A375_CPU_DDR_L2_FREQ_OPT_MASK);
+       if (cpu_freq_select >= ARRAY_SIZE(armada_375_cpu_frequencies)) {
+               pr_err("Selected CPU frequency (%d) unsupported\n",
+                       cpu_freq_select);
+               return 0;
+       } else
+               return armada_375_cpu_frequencies[cpu_freq_select];
+}
+
+enum { A375_CPU_TO_DDR, A375_CPU_TO_L2 };
+
+static const struct coreclk_ratio armada_375_coreclk_ratios[] __initconst = {
+       { .id = A375_CPU_TO_L2,  .name = "l2clk" },
+       { .id = A375_CPU_TO_DDR, .name = "ddrclk" },
+};
+
+static const int armada_375_cpu_l2_ratios[32][2] __initconst = {
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {1, 2}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {1, 2},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {1, 2}, {0, 1}, {0, 1},
+       {0, 1}, {1, 2}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int armada_375_cpu_ddr_ratios[32][2] __initconst = {
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {1, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {2, 3},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {2, 3}, {0, 1}, {0, 1},
+       {0, 1}, {1, 2}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static void __init armada_375_get_clk_ratio(
+       void __iomem *sar, int id, int *mult, int *div)
+{
+       u32 opt = ((readl(sar) >> SAR1_A375_CPU_DDR_L2_FREQ_OPT) &
+               SAR1_A375_CPU_DDR_L2_FREQ_OPT_MASK);
+
+       switch (id) {
+       case A375_CPU_TO_L2:
+               *mult = armada_375_cpu_l2_ratios[opt][0];
+               *div = armada_375_cpu_l2_ratios[opt][1];
+               break;
+       case A375_CPU_TO_DDR:
+               *mult = armada_375_cpu_ddr_ratios[opt][0];
+               *div = armada_375_cpu_ddr_ratios[opt][1];
+               break;
+       }
+}
+
+static const struct coreclk_soc_desc armada_375_coreclks = {
+       .get_tclk_freq = armada_375_get_tclk_freq,
+       .get_cpu_freq = armada_375_get_cpu_freq,
+       .get_clk_ratio = armada_375_get_clk_ratio,
+       .ratios = armada_375_coreclk_ratios,
+       .num_ratios = ARRAY_SIZE(armada_375_coreclk_ratios),
+};
+
+static void __init armada_375_coreclk_init(struct device_node *np)
+{
+       mvebu_coreclk_setup(np, &armada_375_coreclks);
+}
+CLK_OF_DECLARE(armada_375_core_clk, "marvell,armada-375-core-clock",
+              armada_375_coreclk_init);
+
+/*
+ * Clock Gating Control
+ */
+static const struct clk_gating_soc_desc armada_375_gating_desc[] __initconst = {
+       { "mu", NULL, 2 },
+       { "pp", NULL, 3 },
+       { "ptp", NULL, 4 },
+       { "pex0", NULL, 5 },
+       { "pex1", NULL, 6 },
+       { "audio", NULL, 8 },
+       { "nd_clk", "nand", 11 },
+       { "sata0_link", "sata0_core", 14 },
+       { "sata0_core", NULL, 15 },
+       { "usb3", NULL, 16 },
+       { "sdio", NULL, 17 },
+       { "usb", NULL, 18 },
+       { "gop", NULL, 19 },
+       { "sata1_link", "sata1_core", 20 },
+       { "sata1_core", NULL, 21 },
+       { "xor0", NULL, 22 },
+       { "xor1", NULL, 23 },
+       { "copro", NULL, 24 },
+       { "tdm", NULL, 25 },
+       { "crypto0_enc", NULL, 28 },
+       { "crypto0_core", NULL, 29 },
+       { "crypto1_enc", NULL, 30 },
+       { "crypto1_core", NULL, 31 },
+       { }
+};
+
+static void __init armada_375_clk_gating_init(struct device_node *np)
+{
+       mvebu_clk_gating_setup(np, armada_375_gating_desc);
+}
+CLK_OF_DECLARE(armada_375_clk_gating, "marvell,armada-375-gating-clock",
+              armada_375_clk_gating_init);
diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c
new file mode 100644 (file)
index 0000000..8bccf4e
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Marvell Armada 380/385 SoC clocks
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * 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>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "common.h"
+
+/*
+ * SAR[14:10] : Ratios between PCLK0, NBCLK, HCLK and DRAM clocks
+ *
+ * SAR[15]    : TCLK frequency
+ *              0 = 250 MHz
+ *              1 = 200 MHz
+ */
+
+#define SAR_A380_TCLK_FREQ_OPT           15
+#define SAR_A380_TCLK_FREQ_OPT_MASK      0x1
+#define SAR_A380_CPU_DDR_L2_FREQ_OPT     10
+#define SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK 0x1F
+
+static const u32 armada_38x_tclk_frequencies[] __initconst = {
+       250000000,
+       200000000,
+};
+
+static u32 __init armada_38x_get_tclk_freq(void __iomem *sar)
+{
+       u8 tclk_freq_select;
+
+       tclk_freq_select = ((readl(sar) >> SAR_A380_TCLK_FREQ_OPT) &
+                           SAR_A380_TCLK_FREQ_OPT_MASK);
+       return armada_38x_tclk_frequencies[tclk_freq_select];
+}
+
+static const u32 armada_38x_cpu_frequencies[] __initconst = {
+       0, 0, 0, 0,
+       1066 * 1000 * 1000, 0, 0, 0,
+       1332 * 1000 * 1000, 0, 0, 0,
+       1600 * 1000 * 1000,
+};
+
+static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
+{
+       u8 cpu_freq_select;
+
+       cpu_freq_select = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) &
+                          SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK);
+       if (cpu_freq_select >= ARRAY_SIZE(armada_38x_cpu_frequencies)) {
+               pr_err("Selected CPU frequency (%d) unsupported\n",
+                       cpu_freq_select);
+               return 0;
+       }
+
+       return armada_38x_cpu_frequencies[cpu_freq_select];
+}
+
+enum { A380_CPU_TO_DDR, A380_CPU_TO_L2 };
+
+static const struct coreclk_ratio armada_38x_coreclk_ratios[] __initconst = {
+       { .id = A380_CPU_TO_L2,  .name = "l2clk" },
+       { .id = A380_CPU_TO_DDR, .name = "ddrclk" },
+};
+
+static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = {
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static void __init armada_38x_get_clk_ratio(
+       void __iomem *sar, int id, int *mult, int *div)
+{
+       u32 opt = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) &
+               SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK);
+
+       switch (id) {
+       case A380_CPU_TO_L2:
+               *mult = armada_38x_cpu_l2_ratios[opt][0];
+               *div = armada_38x_cpu_l2_ratios[opt][1];
+               break;
+       case A380_CPU_TO_DDR:
+               *mult = armada_38x_cpu_ddr_ratios[opt][0];
+               *div = armada_38x_cpu_ddr_ratios[opt][1];
+               break;
+       }
+}
+
+static const struct coreclk_soc_desc armada_38x_coreclks = {
+       .get_tclk_freq = armada_38x_get_tclk_freq,
+       .get_cpu_freq = armada_38x_get_cpu_freq,
+       .get_clk_ratio = armada_38x_get_clk_ratio,
+       .ratios = armada_38x_coreclk_ratios,
+       .num_ratios = ARRAY_SIZE(armada_38x_coreclk_ratios),
+};
+
+static void __init armada_38x_coreclk_init(struct device_node *np)
+{
+       mvebu_coreclk_setup(np, &armada_38x_coreclks);
+}
+CLK_OF_DECLARE(armada_38x_core_clk, "marvell,armada-380-core-clock",
+              armada_38x_coreclk_init);
+
+/*
+ * Clock Gating Control
+ */
+static const struct clk_gating_soc_desc armada_38x_gating_desc[] __initconst = {
+       { "audio", NULL, 0 },
+       { "ge2", NULL, 2 },
+       { "ge1", NULL, 3 },
+       { "ge0", NULL, 4 },
+       { "pex1", NULL, 5 },
+       { "pex2", NULL, 6 },
+       { "pex3", NULL, 7 },
+       { "pex0", NULL, 8 },
+       { "usb3h0", NULL, 9 },
+       { "usb3h1", NULL, 10 },
+       { "usb3d", NULL, 11 },
+       { "bm", NULL, 13 },
+       { "crypto0z", NULL, 14 },
+       { "sata0", NULL, 15 },
+       { "crypto1z", NULL, 16 },
+       { "sdio", NULL, 17 },
+       { "usb2", NULL, 18 },
+       { "crypto1", NULL, 21 },
+       { "xor0", NULL, 22 },
+       { "crypto0", NULL, 23 },
+       { "tdm", NULL, 25 },
+       { "xor1", NULL, 28 },
+       { "sata1", NULL, 30 },
+       { }
+};
+
+static void __init armada_38x_clk_gating_init(struct device_node *np)
+{
+       mvebu_clk_gating_setup(np, armada_38x_gating_desc);
+}
+CLK_OF_DECLARE(armada_38x_clk_gating, "marvell,armada-380-gating-clock",
+              armada_38x_clk_gating_init);
index 7162615bcdcdda802e782fb631051c75b0921261..d1e5863d337525ba5138c1505bca994e1d2b3268 100644 (file)
 #include "common.h"
 
 #define CORE_CLK_DIV_RATIO_MASK                0xff
-#define CORE_CLK_DIV_RATIO_RELOAD      BIT(8)
-#define CORE_CLK_DIV_ENABLE_OFFSET     24
-#define CORE_CLK_DIV_RATIO_OFFSET      0x8
 
+/*
+ * This structure describes the hardware details (bit offset and mask)
+ * to configure one particular core divider clock. Those hardware
+ * details may differ from one SoC to another. This structure is
+ * therefore typically instantiated statically to describe the
+ * hardware details.
+ */
 struct clk_corediv_desc {
        unsigned int mask;
        unsigned int offset;
        unsigned int fieldbit;
 };
 
+/*
+ * This structure describes the hardware details to configure the core
+ * divider clocks on a given SoC. Amongst others, it points to the
+ * array of core divider clock descriptors for this SoC, as well as
+ * the corresponding operations to manipulate them.
+ */
+struct clk_corediv_soc_desc {
+       const struct clk_corediv_desc *descs;
+       unsigned int ndescs;
+       const struct clk_ops ops;
+       u32 ratio_reload;
+       u32 enable_bit_offset;
+       u32 ratio_offset;
+};
+
+/*
+ * This structure represents one core divider clock for the clock
+ * framework, and is dynamically allocated for each core divider clock
+ * existing in the current SoC.
+ */
 struct clk_corediv {
        struct clk_hw hw;
        void __iomem *reg;
-       struct clk_corediv_desc desc;
+       const struct clk_corediv_desc *desc;
+       const struct clk_corediv_soc_desc *soc_desc;
        spinlock_t lock;
 };
 
 static struct clk_onecell_data clk_data;
 
-static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
+/*
+ * Description of the core divider clocks available. For now, we
+ * support only NAND, and it is available at the same register
+ * locations regardless of the SoC.
+ */
+static const struct clk_corediv_desc mvebu_corediv_desc[] = {
        { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
 };
 
@@ -46,8 +76,9 @@ static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
 static int clk_corediv_is_enabled(struct clk_hw *hwclk)
 {
        struct clk_corediv *corediv = to_corediv_clk(hwclk);
-       struct clk_corediv_desc *desc = &corediv->desc;
-       u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET;
+       const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
+       const struct clk_corediv_desc *desc = corediv->desc;
+       u32 enable_mask = BIT(desc->fieldbit) << soc_desc->enable_bit_offset;
 
        return !!(readl(corediv->reg) & enable_mask);
 }
@@ -55,14 +86,15 @@ static int clk_corediv_is_enabled(struct clk_hw *hwclk)
 static int clk_corediv_enable(struct clk_hw *hwclk)
 {
        struct clk_corediv *corediv = to_corediv_clk(hwclk);
-       struct clk_corediv_desc *desc = &corediv->desc;
+       const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
+       const struct clk_corediv_desc *desc = corediv->desc;
        unsigned long flags = 0;
        u32 reg;
 
        spin_lock_irqsave(&corediv->lock, flags);
 
        reg = readl(corediv->reg);
-       reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+       reg |= (BIT(desc->fieldbit) << soc_desc->enable_bit_offset);
        writel(reg, corediv->reg);
 
        spin_unlock_irqrestore(&corediv->lock, flags);
@@ -73,14 +105,15 @@ static int clk_corediv_enable(struct clk_hw *hwclk)
 static void clk_corediv_disable(struct clk_hw *hwclk)
 {
        struct clk_corediv *corediv = to_corediv_clk(hwclk);
-       struct clk_corediv_desc *desc = &corediv->desc;
+       const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
+       const struct clk_corediv_desc *desc = corediv->desc;
        unsigned long flags = 0;
        u32 reg;
 
        spin_lock_irqsave(&corediv->lock, flags);
 
        reg = readl(corediv->reg);
-       reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+       reg &= ~(BIT(desc->fieldbit) << soc_desc->enable_bit_offset);
        writel(reg, corediv->reg);
 
        spin_unlock_irqrestore(&corediv->lock, flags);
@@ -90,10 +123,11 @@ static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
                                         unsigned long parent_rate)
 {
        struct clk_corediv *corediv = to_corediv_clk(hwclk);
-       struct clk_corediv_desc *desc = &corediv->desc;
+       const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
+       const struct clk_corediv_desc *desc = corediv->desc;
        u32 reg, div;
 
-       reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+       reg = readl(corediv->reg + soc_desc->ratio_offset);
        div = (reg >> desc->offset) & desc->mask;
        return parent_rate / div;
 }
@@ -117,7 +151,8 @@ static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
                            unsigned long parent_rate)
 {
        struct clk_corediv *corediv = to_corediv_clk(hwclk);
-       struct clk_corediv_desc *desc = &corediv->desc;
+       const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
+       const struct clk_corediv_desc *desc = corediv->desc;
        unsigned long flags = 0;
        u32 reg, div;
 
@@ -126,17 +161,17 @@ static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
        spin_lock_irqsave(&corediv->lock, flags);
 
        /* Write new divider to the divider ratio register */
-       reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+       reg = readl(corediv->reg + soc_desc->ratio_offset);
        reg &= ~(desc->mask << desc->offset);
        reg |= (div & desc->mask) << desc->offset;
-       writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+       writel(reg, corediv->reg + soc_desc->ratio_offset);
 
        /* Set reload-force for this clock */
        reg = readl(corediv->reg) | BIT(desc->fieldbit);
        writel(reg, corediv->reg);
 
        /* Now trigger the clock update */
-       reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD;
+       reg = readl(corediv->reg) | soc_desc->ratio_reload;
        writel(reg, corediv->reg);
 
        /*
@@ -144,7 +179,7 @@ static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
         * ratios request and the reload request.
         */
        udelay(1000);
-       reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD);
+       reg &= ~(CORE_CLK_DIV_RATIO_MASK | soc_desc->ratio_reload);
        writel(reg, corediv->reg);
        udelay(1000);
 
@@ -153,16 +188,53 @@ static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
        return 0;
 }
 
-static const struct clk_ops corediv_ops = {
-       .enable = clk_corediv_enable,
-       .disable = clk_corediv_disable,
-       .is_enabled = clk_corediv_is_enabled,
-       .recalc_rate = clk_corediv_recalc_rate,
-       .round_rate = clk_corediv_round_rate,
-       .set_rate = clk_corediv_set_rate,
+static const struct clk_corediv_soc_desc armada370_corediv_soc = {
+       .descs = mvebu_corediv_desc,
+       .ndescs = ARRAY_SIZE(mvebu_corediv_desc),
+       .ops = {
+               .enable = clk_corediv_enable,
+               .disable = clk_corediv_disable,
+               .is_enabled = clk_corediv_is_enabled,
+               .recalc_rate = clk_corediv_recalc_rate,
+               .round_rate = clk_corediv_round_rate,
+               .set_rate = clk_corediv_set_rate,
+       },
+       .ratio_reload = BIT(8),
+       .enable_bit_offset = 24,
+       .ratio_offset = 0x8,
+};
+
+static const struct clk_corediv_soc_desc armada380_corediv_soc = {
+       .descs = mvebu_corediv_desc,
+       .ndescs = ARRAY_SIZE(mvebu_corediv_desc),
+       .ops = {
+               .enable = clk_corediv_enable,
+               .disable = clk_corediv_disable,
+               .is_enabled = clk_corediv_is_enabled,
+               .recalc_rate = clk_corediv_recalc_rate,
+               .round_rate = clk_corediv_round_rate,
+               .set_rate = clk_corediv_set_rate,
+       },
+       .ratio_reload = BIT(8),
+       .enable_bit_offset = 16,
+       .ratio_offset = 0x4,
 };
 
-static void __init mvebu_corediv_clk_init(struct device_node *node)
+static const struct clk_corediv_soc_desc armada375_corediv_soc = {
+       .descs = mvebu_corediv_desc,
+       .ndescs = ARRAY_SIZE(mvebu_corediv_desc),
+       .ops = {
+               .recalc_rate = clk_corediv_recalc_rate,
+               .round_rate = clk_corediv_round_rate,
+               .set_rate = clk_corediv_set_rate,
+       },
+       .ratio_reload = BIT(8),
+       .ratio_offset = 0x4,
+};
+
+static void __init
+mvebu_corediv_clk_init(struct device_node *node,
+                      const struct clk_corediv_soc_desc *soc_desc)
 {
        struct clk_init_data init;
        struct clk_corediv *corediv;
@@ -178,7 +250,7 @@ static void __init mvebu_corediv_clk_init(struct device_node *node)
 
        parent_name = of_clk_get_parent_name(node, 0);
 
-       clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc);
+       clk_data.clk_num = soc_desc->ndescs;
 
        /* clks holds the clock array */
        clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
@@ -199,10 +271,11 @@ static void __init mvebu_corediv_clk_init(struct device_node *node)
                init.num_parents = 1;
                init.parent_names = &parent_name;
                init.name = clk_name;
-               init.ops = &corediv_ops;
+               init.ops = &soc_desc->ops;
                init.flags = 0;
 
-               corediv[i].desc = mvebu_corediv_desc[i];
+               corediv[i].soc_desc = soc_desc;
+               corediv[i].desc = soc_desc->descs + i;
                corediv[i].reg = base;
                corediv[i].hw.init = &init;
 
@@ -219,5 +292,24 @@ err_free_clks:
 err_unmap:
        iounmap(base);
 }
-CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock",
-              mvebu_corediv_clk_init);
+
+static void __init armada370_corediv_clk_init(struct device_node *node)
+{
+       return mvebu_corediv_clk_init(node, &armada370_corediv_soc);
+}
+CLK_OF_DECLARE(armada370_corediv_clk, "marvell,armada-370-corediv-clock",
+              armada370_corediv_clk_init);
+
+static void __init armada375_corediv_clk_init(struct device_node *node)
+{
+       return mvebu_corediv_clk_init(node, &armada375_corediv_soc);
+}
+CLK_OF_DECLARE(armada375_corediv_clk, "marvell,armada-375-corediv-clock",
+              armada375_corediv_clk_init);
+
+static void __init armada380_corediv_clk_init(struct device_node *node)
+{
+       return mvebu_corediv_clk_init(node, &armada380_corediv_soc);
+}
+CLK_OF_DECLARE(armada380_corediv_clk, "marvell,armada-380-corediv-clock",
+              armada380_corediv_clk_init);
index 884187fbfe00666ce109a5537e6c1b430f6359ae..13eae14c2cc22ead1f1c05f26c80905797240d1e 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <dt-bindings/clk/exynos-audss-clk.h>
+#include <dt-bindings/clock/exynos-audss-clk.h>
 
 enum exynos_audss_clk_type {
        TYPE_EXYNOS4210,
index 010f071af88321b288c0d9d0d5f17e5ed352fc01..b4f9672101755e6e451d882e04299865807b457a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/syscore_ops.h>
 
 #include "clk.h"
 
@@ -130,6 +131,17 @@ enum exynos4_plls {
        nr_plls                 /* number of 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.
@@ -154,6 +166,17 @@ static unsigned long exynos4x12_clk_save[] __initdata = {
        E4X12_MPLL_CON0,
 };
 
+static unsigned long exynos4_clk_pll_regs[] __initdata = {
+       EPLL_LOCK,
+       VPLL_LOCK,
+       EPLL_CON0,
+       EPLL_CON1,
+       EPLL_CON2,
+       VPLL_CON0,
+       VPLL_CON1,
+       VPLL_CON2,
+};
+
 static unsigned long exynos4_clk_regs[] __initdata = {
        SRC_LEFTBUS,
        DIV_LEFTBUS,
@@ -161,12 +184,6 @@ static unsigned long exynos4_clk_regs[] __initdata = {
        SRC_RIGHTBUS,
        DIV_RIGHTBUS,
        GATE_IP_RIGHTBUS,
-       EPLL_CON0,
-       EPLL_CON1,
-       EPLL_CON2,
-       VPLL_CON0,
-       VPLL_CON1,
-       VPLL_CON2,
        SRC_TOP0,
        SRC_TOP1,
        SRC_CAM,
@@ -227,6 +244,124 @@ static unsigned long exynos4_clk_regs[] __initdata = {
        GATE_IP_CPU,
 };
 
+static const struct samsung_clk_reg_dump src_mask_suspend[] = {
+       { .offset = SRC_MASK_TOP,               .value = 0x00000001, },
+       { .offset = SRC_MASK_CAM,               .value = 0x11111111, },
+       { .offset = SRC_MASK_TV,                .value = 0x00000111, },
+       { .offset = SRC_MASK_LCD0,              .value = 0x00001111, },
+       { .offset = SRC_MASK_MAUDIO,            .value = 0x00000001, },
+       { .offset = SRC_MASK_FSYS,              .value = 0x01011111, },
+       { .offset = SRC_MASK_PERIL0,            .value = 0x01111111, },
+       { .offset = SRC_MASK_PERIL1,            .value = 0x01110111, },
+       { .offset = SRC_MASK_DMC,               .value = 0x00010000, },
+};
+
+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_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));
+
+       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 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 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", };
@@ -908,12 +1043,13 @@ static unsigned long exynos4_get_xom(void)
        return xom;
 }
 
-static void __init exynos4_clk_register_finpll(unsigned long xom)
+static void __init exynos4_clk_register_finpll(void)
 {
        struct samsung_fixed_rate_clock fclk;
        struct clk *clk;
        unsigned long finpll_f = 24000000;
        char *parent_name;
+       unsigned int xom = exynos4_get_xom();
 
        parent_name = xom & 1 ? "xusbxti" : "xxti";
        clk = clk_get(NULL, parent_name);
@@ -1038,27 +1174,21 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
 
 /* register exynos4 clocks */
 static void __init exynos4_clk_init(struct device_node *np,
-                                   enum exynos4_soc exynos4_soc,
-                                   void __iomem *reg_base, unsigned long xom)
+                                   enum exynos4_soc soc)
 {
+       exynos4_soc = soc;
+
        reg_base = of_iomap(np, 0);
        if (!reg_base)
                panic("%s: failed to map registers\n", __func__);
 
-       if (exynos4_soc == EXYNOS4210)
-               samsung_clk_init(np, reg_base, CLK_NR_CLKS,
-                       exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
-                       exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save));
-       else
-               samsung_clk_init(np, reg_base, CLK_NR_CLKS,
-                       exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
-                       exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save));
+       samsung_clk_init(np, reg_base, CLK_NR_CLKS);
 
        samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks,
                        ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
                        ext_clk_match);
 
-       exynos4_clk_register_finpll(xom);
+       exynos4_clk_register_finpll();
 
        if (exynos4_soc == EXYNOS4210) {
                samsung_clk_register_mux(exynos4210_mux_early,
@@ -1125,6 +1255,8 @@ static void __init exynos4_clk_init(struct device_node *np,
        samsung_clk_register_alias(exynos4_aliases,
                        ARRAY_SIZE(exynos4_aliases));
 
+       exynos4_clk_sleep_init();
+
        pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
                "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
                exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
@@ -1136,12 +1268,12 @@ static void __init exynos4_clk_init(struct device_node *np,
 
 static void __init exynos4210_clk_init(struct device_node *np)
 {
-       exynos4_clk_init(np, EXYNOS4210, NULL, exynos4_get_xom());
+       exynos4_clk_init(np, EXYNOS4210);
 }
 CLK_OF_DECLARE(exynos4210_clk, "samsung,exynos4210-clock", exynos4210_clk_init);
 
 static void __init exynos4412_clk_init(struct device_node *np)
 {
-       exynos4_clk_init(np, EXYNOS4X12, NULL, exynos4_get_xom());
+       exynos4_clk_init(np, EXYNOS4X12);
 }
 CLK_OF_DECLARE(exynos4412_clk, "samsung,exynos4412-clock", exynos4412_clk_init);
index ff4beebe1f0b797de6fe0b465fc73d713065e612..e7ee4420da8178fd5a55525b9d994f37fcb7895a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/syscore_ops.h>
 
 #include "clk.h"
 
@@ -85,6 +86,11 @@ enum exynos5250_plls {
        nr_plls                 /* number of 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.
@@ -137,6 +143,41 @@ static unsigned long exynos5250_clk_regs[] __initdata = {
        GATE_IP_ACP,
 };
 
+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 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 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", };
@@ -645,8 +686,6 @@ static struct of_device_id ext_clk_match[] __initdata = {
 /* register exynox5250 clocks */
 static void __init exynos5250_clk_init(struct device_node *np)
 {
-       void __iomem *reg_base;
-
        if (np) {
                reg_base = of_iomap(np, 0);
                if (!reg_base)
@@ -655,9 +694,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
                panic("%s: unable to determine soc\n", __func__);
        }
 
-       samsung_clk_init(np, reg_base, CLK_NR_CLKS,
-                       exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs),
-                       NULL, 0);
+       samsung_clk_init(np, reg_base, CLK_NR_CLKS);
        samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
                        ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
                        ext_clk_match);
@@ -685,6 +722,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
        samsung_clk_register_gate(exynos5250_gate_clks,
                        ARRAY_SIZE(exynos5250_gate_clks));
 
+       exynos5250_clk_sleep_init();
+
        pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
                        _get_rate("div_arm2"));
 }
index ab4f2f7d88ef5ec5369ed28f7e11e0496148c8e2..60b26819bed51691b6d5f2c4c5c2d10521f9b4d3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/syscore_ops.h>
 
 #include "clk.h"
 
@@ -108,6 +109,11 @@ enum exynos5420_plls {
        nr_plls                 /* number of PLLs */
 };
 
+static void __iomem *reg_base;
+
+#ifdef CONFIG_PM_SLEEP
+static struct samsung_clk_reg_dump *exynos5420_save;
+
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -174,6 +180,41 @@ static unsigned long exynos5420_clk_regs[] __initdata = {
        DIV_KFC0,
 };
 
+static int exynos5420_clk_suspend(void)
+{
+       samsung_clk_save(reg_base, exynos5420_save,
+                               ARRAY_SIZE(exynos5420_clk_regs));
+
+       return 0;
+}
+
+static void exynos5420_clk_resume(void)
+{
+       samsung_clk_restore(reg_base, exynos5420_save,
+                               ARRAY_SIZE(exynos5420_clk_regs));
+}
+
+static struct syscore_ops exynos5420_clk_syscore_ops = {
+       .suspend = exynos5420_clk_suspend,
+       .resume = exynos5420_clk_resume,
+};
+
+static void exynos5420_clk_sleep_init(void)
+{
+       exynos5420_save = samsung_clk_alloc_reg_dump(exynos5420_clk_regs,
+                                       ARRAY_SIZE(exynos5420_clk_regs));
+       if (!exynos5420_save) {
+               pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
+                       __func__);
+               return;
+       }
+
+       register_syscore_ops(&exynos5420_clk_syscore_ops);
+}
+#else
+static void exynos5420_clk_sleep_init(void) {}
+#endif
+
 /* list of all parent clocks */
 PNAME(mspll_cpu_p)     = { "sclk_cpll", "sclk_dpll",
                                "sclk_mpll", "sclk_spll" };
@@ -737,8 +778,6 @@ static struct of_device_id ext_clk_match[] __initdata = {
 /* register exynos5420 clocks */
 static void __init exynos5420_clk_init(struct device_node *np)
 {
-       void __iomem *reg_base;
-
        if (np) {
                reg_base = of_iomap(np, 0);
                if (!reg_base)
@@ -747,9 +786,7 @@ static void __init exynos5420_clk_init(struct device_node *np)
                panic("%s: unable to determine soc\n", __func__);
        }
 
-       samsung_clk_init(np, reg_base, CLK_NR_CLKS,
-                       exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
-                       NULL, 0);
+       samsung_clk_init(np, reg_base, CLK_NR_CLKS);
        samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
                        ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
                        ext_clk_match);
@@ -765,5 +802,7 @@ static void __init exynos5420_clk_init(struct device_node *np)
                        ARRAY_SIZE(exynos5420_div_clks));
        samsung_clk_register_gate(exynos5420_gate_clks,
                        ARRAY_SIZE(exynos5420_gate_clks));
+
+       exynos5420_clk_sleep_init();
 }
 CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init);
index cbc15b56891d75740cb149c03e91a28f10b09f60..2bfad5a993d01fb247dec96c0c052137998435c2 100644 (file)
@@ -101,7 +101,7 @@ static void __init exynos5440_clk_init(struct device_node *np)
                return;
        }
 
-       samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0);
+       samsung_clk_init(np, reg_base, CLK_NR_CLKS);
        samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks,
                ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match);
 
index 8e27aee6887eed36c2ebaf7c82bd705672ab5784..8bda658137a8ced3ecf8090db65fedb91625ed2f 100644 (file)
@@ -13,6 +13,7 @@
 #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>
 
@@ -61,6 +62,13 @@ enum s3c64xx_plls {
        apll, mpll, epll,
 };
 
+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.
@@ -87,6 +95,60 @@ 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 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 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" };
@@ -391,11 +453,11 @@ static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f,
 
 /* Register s3c64xx clocks. */
 void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
-                            unsigned long xusbxti_f, bool is_s3c6400,
-                            void __iomem *reg_base)
+                            unsigned long xusbxti_f, bool s3c6400,
+                            void __iomem *base)
 {
-       unsigned long *soc_regs = NULL;
-       unsigned long nr_soc_regs = 0;
+       reg_base = base;
+       is_s3c6400 = s3c6400;
 
        if (np) {
                reg_base = of_iomap(np, 0);
@@ -403,13 +465,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
                        panic("%s: failed to map registers\n", __func__);
        }
 
-       if (!is_s3c6400) {
-               soc_regs = s3c6410_clk_regs;
-               nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
-       }
-
-       samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
-                       ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs);
+       samsung_clk_init(np, reg_base, NR_CLKS);
 
        /* Register external clocks. */
        if (!np)
@@ -452,6 +508,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
 
        samsung_clk_register_alias(s3c64xx_clock_aliases,
                                        ARRAY_SIZE(s3c64xx_clock_aliases));
+       s3c64xx_clk_sleep_init();
 
        pr_info("%s clocks: apll = %lu, mpll = %lu\n"
                "\tepll = %lu, arm_clk = %lu\n",
index f503f32e2f80b2832519927894e8c84ba0d81e60..91bec3ebdc8fba0306ee9b7e91d72f2fa433cf4a 100644 (file)
@@ -21,64 +21,45 @@ static void __iomem *reg_base;
 static struct clk_onecell_data clk_data;
 #endif
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *reg_dump;
-static unsigned long nr_reg_dump;
-
-static int samsung_clk_suspend(void)
+void samsung_clk_save(void __iomem *base,
+                                   struct samsung_clk_reg_dump *rd,
+                                   unsigned int num_regs)
 {
-       struct samsung_clk_reg_dump *rd = reg_dump;
-       unsigned long i;
-
-       for (i = 0; i < nr_reg_dump; i++, rd++)
-               rd->value = __raw_readl(reg_base + rd->offset);
+       for (; num_regs > 0; --num_regs, ++rd)
+               rd->value = readl(base + rd->offset);
+}
 
-       return 0;
+void samsung_clk_restore(void __iomem *base,
+                                     const struct samsung_clk_reg_dump *rd,
+                                     unsigned int num_regs)
+{
+       for (; num_regs > 0; --num_regs, ++rd)
+               writel(rd->value, base + rd->offset);
 }
 
-static void samsung_clk_resume(void)
+struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
+                                               const unsigned long *rdump,
+                                               unsigned long nr_rdump)
 {
-       struct samsung_clk_reg_dump *rd = reg_dump;
-       unsigned long i;
+       struct samsung_clk_reg_dump *rd;
+       unsigned int i;
 
-       for (i = 0; i < nr_reg_dump; i++, rd++)
-               __raw_writel(rd->value, reg_base + rd->offset);
-}
+       rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
+       if (!rd)
+               return NULL;
+
+       for (i = 0; i < nr_rdump; ++i)
+               rd[i].offset = rdump[i];
 
-static struct syscore_ops samsung_clk_syscore_ops = {
-       .suspend        = samsung_clk_suspend,
-       .resume         = samsung_clk_resume,
-};
-#endif /* CONFIG_PM_SLEEP */
+       return rd;
+}
 
 /* setup the essentials required to support clock lookup using ccf */
 void __init samsung_clk_init(struct device_node *np, void __iomem *base,
-               unsigned long nr_clks, unsigned long *rdump,
-               unsigned long nr_rdump, unsigned long *soc_rdump,
-               unsigned long nr_soc_rdump)
+                            unsigned long nr_clks)
 {
        reg_base = base;
 
-#ifdef CONFIG_PM_SLEEP
-       if (rdump && nr_rdump) {
-               unsigned int idx;
-               reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump)
-                               * (nr_rdump + nr_soc_rdump), GFP_KERNEL);
-               if (!reg_dump) {
-                       pr_err("%s: memory alloc for register dump failed\n",
-                                       __func__);
-                       return;
-               }
-
-               for (idx = 0; idx < nr_rdump; idx++)
-                       reg_dump[idx].offset = rdump[idx];
-               for (idx = 0; idx < nr_soc_rdump; idx++)
-                       reg_dump[nr_rdump + idx].offset = soc_rdump[idx];
-               nr_reg_dump = nr_rdump + nr_soc_rdump;
-               register_syscore_ops(&samsung_clk_syscore_ops);
-       }
-#endif
-
        clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
        if (!clk_table)
                panic("could not allocate clock lookup table\n");
index 31b4174e7a5bfa1b47fd2d9e0e5da6240a305acf..c7141ba826e0c9100b9860bdfe718f358e83d887 100644 (file)
@@ -313,9 +313,7 @@ struct samsung_pll_clock {
                _lock, _con, _rtable, _alias)
 
 extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
-               unsigned long nr_clks, unsigned long *rdump,
-               unsigned long nr_rdump, unsigned long *soc_rdump,
-               unsigned long nr_soc_rdump);
+                                   unsigned long nr_clks);
 extern void __init samsung_clk_of_register_fixed_ext(
                struct samsung_fixed_rate_clock *fixed_rate_clk,
                unsigned int nr_fixed_rate_clk,
@@ -340,4 +338,14 @@ extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
 
 extern unsigned long _get_rate(const char *clk_name);
 
+extern void samsung_clk_save(void __iomem *base,
+                            struct samsung_clk_reg_dump *rd,
+                            unsigned int num_regs);
+extern void samsung_clk_restore(void __iomem *base,
+                               const struct samsung_clk_reg_dump *rd,
+                               unsigned int num_regs);
+extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
+                                               const unsigned long *rdump,
+                                               unsigned long nr_rdump);
+
 #endif /* __SAMSUNG_CLK_H */
index 9ecef140dba7a663b0a86c3338ea61d5ba21a39f..5404cb931ebf5b9e07b0de1198e3b88b7ed8831d 100644 (file)
@@ -1,4 +1,5 @@
 obj-$(CONFIG_ARCH_EMEV2)               += clk-emev2.o
+obj-$(CONFIG_ARCH_R7S72100)            += clk-rz.o
 obj-$(CONFIG_ARCH_R8A7790)             += clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)             += clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)      += clk-div6.o
index aac4756ec52e68e641c740667c8f31cb32cac0eb..f065f694cb65699705def0036c3f47e903e813ae 100644 (file)
@@ -23,7 +23,7 @@
 #define CPG_DIV6_DIV_MASK      0x3f
 
 /**
- * struct div6_clock - MSTP gating clock
+ * struct div6_clock - CPG 6 bit divider clock
  * @hw: handle between common and hardware-specific interfaces
  * @reg: IO-remapped register
  * @div: divisor value (1-64)
index 42d5912b1d25aa908314f62c4138052e9fd51a15..2e5810c88d1150874ece970fb64136a450ef64a6 100644 (file)
@@ -137,7 +137,7 @@ cpg_mstp_clock_register(const char *name, const char *parent_name,
 
        init.name = name;
        init.ops = &cpg_mstp_clock_ops;
-       init.flags = CLK_IS_BASIC;
+       init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
        init.parent_names = &parent_name;
        init.num_parents = 1;
 
index 99c27b1c625b8e3eaf514895a0a13ebf8b94fdef..dff7f79a19b9514cf4fff4091fd4d35b5ae11a30 100644 (file)
@@ -242,22 +242,22 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
                parent_name = "main";
                mult = config->pll3_mult;
        } else if (!strcmp(name, "lb")) {
-               parent_name = "pll1_div2";
+               parent_name = "pll1";
                div = cpg_mode & BIT(18) ? 36 : 24;
        } else if (!strcmp(name, "qspi")) {
                parent_name = "pll1_div2";
                div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2)
                    ? 8 : 10;
        } else if (!strcmp(name, "sdh")) {
-               parent_name = "pll1_div2";
+               parent_name = "pll1";
                table = cpg_sdh_div_table;
                shift = 8;
        } else if (!strcmp(name, "sd0")) {
-               parent_name = "pll1_div2";
+               parent_name = "pll1";
                table = cpg_sd01_div_table;
                shift = 4;
        } else if (!strcmp(name, "sd1")) {
-               parent_name = "pll1_div2";
+               parent_name = "pll1";
                table = cpg_sd01_div_table;
                shift = 0;
        } else if (!strcmp(name, "z")) {
diff --git a/drivers/clk/shmobile/clk-rz.c b/drivers/clk/shmobile/clk-rz.c
new file mode 100644 (file)
index 0000000..7e68e86
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * rz 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>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+struct rz_cpg {
+       struct clk_onecell_data data;
+       void __iomem *reg;
+};
+
+#define CPG_FRQCR      0x10
+#define CPG_FRQCR2     0x14
+
+/* -----------------------------------------------------------------------------
+ * Initialization
+ */
+
+static struct clk * __init
+rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *name)
+{
+       u32 val;
+       unsigned mult;
+       static const unsigned frqcr_tab[4] = { 3, 2, 0, 1 };
+
+       if (strcmp(name, "pll") == 0) {
+               /* FIXME: cpg_mode should be read from GPIO. But no GPIO support yet */
+               unsigned cpg_mode = 0; /* hardcoded to EXTAL for now */
+               const char *parent_name = of_clk_get_parent_name(np, cpg_mode);
+
+               mult = cpg_mode ? (32 / 4) : 30;
+
+               return clk_register_fixed_factor(NULL, name, parent_name, 0, mult, 1);
+       }
+
+       /* If mapping regs failed, skip non-pll clocks. System will boot anyhow */
+       if (!cpg->reg)
+               return ERR_PTR(-ENXIO);
+
+       /* FIXME:"i" and "g" are variable clocks with non-integer dividers (e.g. 2/3)
+        * and the constraint that always g <= i. To get the rz platform started,
+        * let them run at fixed current speed and implement the details later.
+        */
+       if (strcmp(name, "i") == 0)
+               val = (clk_readl(cpg->reg + CPG_FRQCR) >> 8) & 3;
+       else if (strcmp(name, "g") == 0)
+               val = clk_readl(cpg->reg + CPG_FRQCR2) & 3;
+       else
+               return ERR_PTR(-EINVAL);
+
+       mult = frqcr_tab[val];
+       return clk_register_fixed_factor(NULL, name, "pll", 0, mult, 3);
+}
+
+static void __init rz_cpg_clocks_init(struct device_node *np)
+{
+       struct rz_cpg *cpg;
+       struct clk **clks;
+       unsigned i;
+       int num_clks;
+
+       num_clks = of_property_count_strings(np, "clock-output-names");
+       if (WARN(num_clks <= 0, "can't count CPG clocks\n"))
+               return;
+
+       cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+       clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL);
+       BUG_ON(!cpg || !clks);
+
+       cpg->data.clks = clks;
+       cpg->data.clk_num = num_clks;
+
+       cpg->reg = of_iomap(np, 0);
+
+       for (i = 0; i < num_clks; ++i) {
+               const char *name;
+               struct clk *clk;
+
+               of_property_read_string_index(np, "clock-output-names", i, &name);
+
+               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));
+               else
+                       cpg->data.clks[i] = clk;
+       }
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(rz_cpg_clks, "renesas,rz-cpg-clocks", rz_cpg_clocks_init);
index f9f4a15a64ab30306b49e6c2574dde157fbe6b25..d63b76ca60c311edd1dcb66ef35d364e0cb27247 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Clock tree for CSR SiRFatlasVI
  *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
+ * company.
  *
  * Licensed under GPLv2 or later.
  */
index 7dde6a82f514834ac76ed9a457f6ccc7a5176a03..37af51c5f213bb496c2dce74ba975cbc4227a22f 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * common clks module for all SiRF SoCs
  *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
+ * company.
  *
  * Licensed under GPLv2 or later.
  */
index 7adc5c70c7ff82e51e6c4d42cb72fef02f603492..6968e2ebcd8a4d09959d02b2edbf5ffe19e7b9da 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Clock tree for CSR SiRFprimaII
  *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
+ * company.
  *
  * Licensed under GPLv2 or later.
  */
index 0303c0b99cd0926c6185244ebf74db4911d41538..7e2d15a0c7b8aec7c28e9074727c76406abc6918 100644 (file)
@@ -1 +1,4 @@
 obj-y += clk.o
+obj-y += clk-gate.o
+obj-y += clk-pll.o
+obj-y += clk-periph.o
diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
new file mode 100644 (file)
index 0000000..501d513
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ *  Copyright 2011-2012 Calxeda, Inc.
+ *  Copyright (C) 2012-2013 Altera Corporation <www.altera.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.
+ *
+ * Based from clk-highbank.c
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include "clk.h"
+
+#define SOCFPGA_L4_MP_CLK              "l4_mp_clk"
+#define SOCFPGA_L4_SP_CLK              "l4_sp_clk"
+#define SOCFPGA_NAND_CLK               "nand_clk"
+#define SOCFPGA_NAND_X_CLK             "nand_x_clk"
+#define SOCFPGA_MMC_CLK                        "sdmmc_clk"
+#define SOCFPGA_GPIO_DB_CLK_OFFSET     0xA8
+
+#define div_mask(width)        ((1 << (width)) - 1)
+#define streq(a, b) (strcmp((a), (b)) == 0)
+
+#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
+
+/* SDMMC Group for System Manager defines */
+#define SYSMGR_SDMMCGRP_CTRL_OFFSET    0x108
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
+       ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
+
+static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
+{
+       u32 l4_src;
+       u32 perpll_src;
+
+       if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+               l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+               return l4_src &= 0x1;
+       }
+       if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+               l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+               return !!(l4_src & 2);
+       }
+
+       perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
+       if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
+               return perpll_src &= 0x3;
+       if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
+                       streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
+                       return (perpll_src >> 2) & 3;
+
+       /* QSPI clock */
+       return (perpll_src >> 4) & 3;
+
+}
+
+static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
+{
+       u32 src_reg;
+
+       if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+               src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+               src_reg &= ~0x1;
+               src_reg |= parent;
+               writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
+       } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+               src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+               src_reg &= ~0x2;
+               src_reg |= (parent << 1);
+               writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
+       } else {
+               src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
+               if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
+                       src_reg &= ~0x3;
+                       src_reg |= parent;
+               } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
+                       streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
+                       src_reg &= ~0xC;
+                       src_reg |= (parent << 2);
+               } else {/* QSPI clock */
+                       src_reg &= ~0x30;
+                       src_reg |= (parent << 4);
+               }
+               writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
+       }
+
+       return 0;
+}
+
+static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
+       unsigned long parent_rate)
+{
+       struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
+       u32 div = 1, val;
+
+       if (socfpgaclk->fixed_div)
+               div = socfpgaclk->fixed_div;
+       else if (socfpgaclk->div_reg) {
+               val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
+               val &= div_mask(socfpgaclk->width);
+               /* Check for GPIO_DB_CLK by its offset */
+               if ((int) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET)
+                       div = val + 1;
+               else
+                       div = (1 << val);
+       }
+
+       return parent_rate / div;
+}
+
+static int socfpga_clk_prepare(struct clk_hw *hwclk)
+{
+       struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
+       struct regmap *sys_mgr_base_addr;
+       int i;
+       u32 hs_timing;
+       u32 clk_phase[2];
+
+       if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
+               sys_mgr_base_addr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
+               if (IS_ERR(sys_mgr_base_addr)) {
+                       pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__);
+                       return -EINVAL;
+               }
+
+               for (i = 0; i < 2; i++) {
+                       switch (socfpgaclk->clk_phase[i]) {
+                       case 0:
+                               clk_phase[i] = 0;
+                               break;
+                       case 45:
+                               clk_phase[i] = 1;
+                               break;
+                       case 90:
+                               clk_phase[i] = 2;
+                               break;
+                       case 135:
+                               clk_phase[i] = 3;
+                               break;
+                       case 180:
+                               clk_phase[i] = 4;
+                               break;
+                       case 225:
+                               clk_phase[i] = 5;
+                               break;
+                       case 270:
+                               clk_phase[i] = 6;
+                               break;
+                       case 315:
+                               clk_phase[i] = 7;
+                               break;
+                       default:
+                               clk_phase[i] = 0;
+                               break;
+                       }
+               }
+               hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
+               regmap_write(sys_mgr_base_addr, SYSMGR_SDMMCGRP_CTRL_OFFSET,
+                       hs_timing);
+       }
+       return 0;
+}
+
+static struct clk_ops gateclk_ops = {
+       .prepare = socfpga_clk_prepare,
+       .recalc_rate = socfpga_clk_recalc_rate,
+       .get_parent = socfpga_clk_get_parent,
+       .set_parent = socfpga_clk_set_parent,
+};
+
+static void __init __socfpga_gate_init(struct device_node *node,
+       const struct clk_ops *ops)
+{
+       u32 clk_gate[2];
+       u32 div_reg[3];
+       u32 clk_phase[2];
+       u32 fixed_div;
+       struct clk *clk;
+       struct socfpga_gate_clk *socfpga_clk;
+       const char *clk_name = node->name;
+       const char *parent_name[SOCFPGA_MAX_PARENTS];
+       struct clk_init_data init;
+       int rc;
+       int i = 0;
+
+       socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
+       if (WARN_ON(!socfpga_clk))
+               return;
+
+       rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
+       if (rc)
+               clk_gate[0] = 0;
+
+       if (clk_gate[0]) {
+               socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
+               socfpga_clk->hw.bit_idx = clk_gate[1];
+
+               gateclk_ops.enable = clk_gate_ops.enable;
+               gateclk_ops.disable = clk_gate_ops.disable;
+       }
+
+       rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
+       if (rc)
+               socfpga_clk->fixed_div = 0;
+       else
+               socfpga_clk->fixed_div = fixed_div;
+
+       rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
+       if (!rc) {
+               socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0];
+               socfpga_clk->shift = div_reg[1];
+               socfpga_clk->width = div_reg[2];
+       } else {
+               socfpga_clk->div_reg = 0;
+       }
+
+       rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
+       if (!rc) {
+               socfpga_clk->clk_phase[0] = clk_phase[0];
+               socfpga_clk->clk_phase[1] = clk_phase[1];
+       }
+
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
+       init.name = clk_name;
+       init.ops = ops;
+       init.flags = 0;
+       while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] =
+                       of_clk_get_parent_name(node, i)) != NULL)
+               i++;
+
+       init.parent_names = parent_name;
+       init.num_parents = i;
+       socfpga_clk->hw.hw.init = &init;
+
+       clk = clk_register(NULL, &socfpga_clk->hw.hw);
+       if (WARN_ON(IS_ERR(clk))) {
+               kfree(socfpga_clk);
+               return;
+       }
+       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (WARN_ON(rc))
+               return;
+}
+
+void __init socfpga_gate_init(struct device_node *node)
+{
+       __socfpga_gate_init(node, &gateclk_ops);
+}
diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c
new file mode 100644 (file)
index 0000000..81623a3
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  Copyright 2011-2012 Calxeda, Inc.
+ *  Copyright (C) 2012-2013 Altera Corporation <www.altera.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.
+ *
+ * Based from clk-highbank.c
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include "clk.h"
+
+#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw)
+
+static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
+                                            unsigned long parent_rate)
+{
+       struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
+       u32 div;
+
+       if (socfpgaclk->fixed_div)
+               div = socfpgaclk->fixed_div;
+       else
+               div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1);
+
+       return parent_rate / div;
+}
+
+static const struct clk_ops periclk_ops = {
+       .recalc_rate = clk_periclk_recalc_rate,
+};
+
+static __init void __socfpga_periph_init(struct device_node *node,
+       const struct clk_ops *ops)
+{
+       u32 reg;
+       struct clk *clk;
+       struct socfpga_periph_clk *periph_clk;
+       const char *clk_name = node->name;
+       const char *parent_name;
+       struct clk_init_data init;
+       int rc;
+       u32 fixed_div;
+
+       of_property_read_u32(node, "reg", &reg);
+
+       periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
+       if (WARN_ON(!periph_clk))
+               return;
+
+       periph_clk->hw.reg = clk_mgr_base_addr + reg;
+
+       rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
+       if (rc)
+               periph_clk->fixed_div = 0;
+       else
+               periph_clk->fixed_div = fixed_div;
+
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
+       init.name = clk_name;
+       init.ops = ops;
+       init.flags = 0;
+       parent_name = of_clk_get_parent_name(node, 0);
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       periph_clk->hw.hw.init = &init;
+
+       clk = clk_register(NULL, &periph_clk->hw.hw);
+       if (WARN_ON(IS_ERR(clk))) {
+               kfree(periph_clk);
+               return;
+       }
+       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+
+void __init socfpga_periph_init(struct device_node *node)
+{
+       __socfpga_periph_init(node, &periclk_ops);
+}
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
new file mode 100644 (file)
index 0000000..88dafb5
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *  Copyright 2011-2012 Calxeda, Inc.
+ *  Copyright (C) 2012-2013 Altera Corporation <www.altera.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.
+ *
+ * Based from clk-highbank.c
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include "clk.h"
+
+/* Clock bypass bits */
+#define MAINPLL_BYPASS         (1<<0)
+#define SDRAMPLL_BYPASS                (1<<1)
+#define SDRAMPLL_SRC_BYPASS    (1<<2)
+#define PERPLL_BYPASS          (1<<3)
+#define PERPLL_SRC_BYPASS      (1<<4)
+
+#define SOCFPGA_PLL_BG_PWRDWN          0
+#define SOCFPGA_PLL_EXT_ENA            1
+#define SOCFPGA_PLL_PWR_DOWN           2
+#define SOCFPGA_PLL_DIVF_MASK          0x0000FFF8
+#define SOCFPGA_PLL_DIVF_SHIFT         3
+#define SOCFPGA_PLL_DIVQ_MASK          0x003F0000
+#define SOCFPGA_PLL_DIVQ_SHIFT         16
+
+#define CLK_MGR_PLL_CLK_SRC_SHIFT      22
+#define CLK_MGR_PLL_CLK_SRC_MASK       0x3
+
+#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
+                                        unsigned long parent_rate)
+{
+       struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+       unsigned long divf, divq, reg;
+       unsigned long long vco_freq;
+       unsigned long bypass;
+
+       reg = readl(socfpgaclk->hw.reg);
+       bypass = readl(clk_mgr_base_addr + CLKMGR_BYPASS);
+       if (bypass & MAINPLL_BYPASS)
+               return parent_rate;
+
+       divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
+       divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
+       vco_freq = (unsigned long long)parent_rate * (divf + 1);
+       do_div(vco_freq, (1 + divq));
+       return (unsigned long)vco_freq;
+}
+
+static u8 clk_pll_get_parent(struct clk_hw *hwclk)
+{
+       u32 pll_src;
+       struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+
+       pll_src = readl(socfpgaclk->hw.reg);
+       return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) &
+                       CLK_MGR_PLL_CLK_SRC_MASK;
+}
+
+static struct clk_ops clk_pll_ops = {
+       .recalc_rate = clk_pll_recalc_rate,
+       .get_parent = clk_pll_get_parent,
+};
+
+static __init struct clk *__socfpga_pll_init(struct device_node *node,
+       const struct clk_ops *ops)
+{
+       u32 reg;
+       struct clk *clk;
+       struct socfpga_pll *pll_clk;
+       const char *clk_name = node->name;
+       const char *parent_name[SOCFPGA_MAX_PARENTS];
+       struct clk_init_data init;
+       int rc;
+       int i = 0;
+
+       of_property_read_u32(node, "reg", &reg);
+
+       pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
+       if (WARN_ON(!pll_clk))
+               return NULL;
+
+       pll_clk->hw.reg = clk_mgr_base_addr + reg;
+
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
+       init.name = clk_name;
+       init.ops = ops;
+       init.flags = 0;
+
+       while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] =
+                       of_clk_get_parent_name(node, i)) != NULL)
+               i++;
+
+       init.num_parents = i;
+       init.parent_names = parent_name;
+       pll_clk->hw.hw.init = &init;
+
+       pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
+       clk_pll_ops.enable = clk_gate_ops.enable;
+       clk_pll_ops.disable = clk_gate_ops.disable;
+
+       clk = clk_register(NULL, &pll_clk->hw.hw);
+       if (WARN_ON(IS_ERR(clk))) {
+               kfree(pll_clk);
+               return NULL;
+       }
+       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       return clk;
+}
+
+void __init socfpga_pll_init(struct device_node *node)
+{
+       __socfpga_pll_init(node, &clk_pll_ops);
+}
index 5983a26a8c5fabb04e36425e6eef74939dffbe56..35a960a993f95c72b6247e52032c4184cbdd00b1 100644 (file)
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 
-/* Clock Manager offsets */
-#define CLKMGR_CTRL    0x0
-#define CLKMGR_BYPASS  0x4
-#define CLKMGR_L4SRC   0x70
-#define CLKMGR_PERPLL_SRC      0xAC
+#include "clk.h"
 
-/* Clock bypass bits */
-#define MAINPLL_BYPASS         (1<<0)
-#define SDRAMPLL_BYPASS                (1<<1)
-#define SDRAMPLL_SRC_BYPASS    (1<<2)
-#define PERPLL_BYPASS          (1<<3)
-#define PERPLL_SRC_BYPASS      (1<<4)
+void __iomem *clk_mgr_base_addr;
 
-#define SOCFPGA_PLL_BG_PWRDWN          0
-#define SOCFPGA_PLL_EXT_ENA            1
-#define SOCFPGA_PLL_PWR_DOWN           2
-#define SOCFPGA_PLL_DIVF_MASK          0x0000FFF8
-#define SOCFPGA_PLL_DIVF_SHIFT 3
-#define SOCFPGA_PLL_DIVQ_MASK          0x003F0000
-#define SOCFPGA_PLL_DIVQ_SHIFT 16
-#define SOCFGPA_MAX_PARENTS    3
-
-#define SOCFPGA_L4_MP_CLK              "l4_mp_clk"
-#define SOCFPGA_L4_SP_CLK              "l4_sp_clk"
-#define SOCFPGA_NAND_CLK               "nand_clk"
-#define SOCFPGA_NAND_X_CLK             "nand_x_clk"
-#define SOCFPGA_MMC_CLK                        "sdmmc_clk"
-#define SOCFPGA_DB_CLK                 "gpio_db_clk"
-
-#define div_mask(width)        ((1 << (width)) - 1)
-#define streq(a, b) (strcmp((a), (b)) == 0)
-
-extern void __iomem *clk_mgr_base_addr;
-
-struct socfpga_clk {
-       struct clk_gate hw;
-       char *parent_name;
-       char *clk_name;
-       u32 fixed_div;
-       void __iomem *div_reg;
-       u32 width;      /* only valid if div_reg != 0 */
-       u32 shift;      /* only valid if div_reg != 0 */
-};
-#define to_socfpga_clk(p) container_of(p, struct socfpga_clk, hw.hw)
-
-static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
-                                        unsigned long parent_rate)
-{
-       struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
-       unsigned long divf, divq, vco_freq, reg;
-       unsigned long bypass;
-
-       reg = readl(socfpgaclk->hw.reg);
-       bypass = readl(clk_mgr_base_addr + CLKMGR_BYPASS);
-       if (bypass & MAINPLL_BYPASS)
-               return parent_rate;
-
-       divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
-       divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
-       vco_freq = parent_rate * (divf + 1);
-       return vco_freq / (1 + divq);
-}
-
-
-static struct clk_ops clk_pll_ops = {
-       .recalc_rate = clk_pll_recalc_rate,
-};
-
-static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
-                                            unsigned long parent_rate)
-{
-       struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
-       u32 div;
-
-       if (socfpgaclk->fixed_div)
-               div = socfpgaclk->fixed_div;
-       else
-               div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1);
-
-       return parent_rate / div;
-}
-
-static const struct clk_ops periclk_ops = {
-       .recalc_rate = clk_periclk_recalc_rate,
-};
-
-static __init struct clk *socfpga_clk_init(struct device_node *node,
-       const struct clk_ops *ops)
-{
-       u32 reg;
-       struct clk *clk;
-       struct socfpga_clk *socfpga_clk;
-       const char *clk_name = node->name;
-       const char *parent_name;
-       struct clk_init_data init;
-       int rc;
-       u32 fixed_div;
-
-       of_property_read_u32(node, "reg", &reg);
-
-       socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
-       if (WARN_ON(!socfpga_clk))
-               return NULL;
-
-       socfpga_clk->hw.reg = clk_mgr_base_addr + reg;
-
-       rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
-       if (rc)
-               socfpga_clk->fixed_div = 0;
-       else
-               socfpga_clk->fixed_div = fixed_div;
-
-       of_property_read_string(node, "clock-output-names", &clk_name);
-
-       init.name = clk_name;
-       init.ops = ops;
-       init.flags = 0;
-       parent_name = of_clk_get_parent_name(node, 0);
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       socfpga_clk->hw.hw.init = &init;
-
-       if (streq(clk_name, "main_pll") ||
-               streq(clk_name, "periph_pll") ||
-               streq(clk_name, "sdram_pll")) {
-               socfpga_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
-               clk_pll_ops.enable = clk_gate_ops.enable;
-               clk_pll_ops.disable = clk_gate_ops.disable;
-       }
-
-       clk = clk_register(NULL, &socfpga_clk->hw.hw);
-       if (WARN_ON(IS_ERR(clk))) {
-               kfree(socfpga_clk);
-               return NULL;
-       }
-       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
-       return clk;
-}
-
-static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
-{
-       u32 l4_src;
-       u32 perpll_src;
-
-       if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
-               l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
-               return l4_src &= 0x1;
-       }
-       if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
-               l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
-               return !!(l4_src & 2);
-       }
-
-       perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-       if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
-               return perpll_src &= 0x3;
-       if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
-                       streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
-                       return (perpll_src >> 2) & 3;
-
-       /* QSPI clock */
-       return (perpll_src >> 4) & 3;
-
-}
-
-static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
-{
-       u32 src_reg;
-
-       if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
-               src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
-               src_reg &= ~0x1;
-               src_reg |= parent;
-               writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
-       } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
-               src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
-               src_reg &= ~0x2;
-               src_reg |= (parent << 1);
-               writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
-       } else {
-               src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-               if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
-                       src_reg &= ~0x3;
-                       src_reg |= parent;
-               } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
-                       streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
-                       src_reg &= ~0xC;
-                       src_reg |= (parent << 2);
-               } else {/* QSPI clock */
-                       src_reg &= ~0x30;
-                       src_reg |= (parent << 4);
-               }
-               writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
-       }
-
-       return 0;
-}
-
-static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
-       unsigned long parent_rate)
-{
-       struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
-       u32 div = 1, val;
-
-       if (socfpgaclk->fixed_div)
-               div = socfpgaclk->fixed_div;
-       else if (socfpgaclk->div_reg) {
-               val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
-               val &= div_mask(socfpgaclk->width);
-               if (streq(hwclk->init->name, SOCFPGA_DB_CLK))
-                       div = val + 1;
-               else
-                       div = (1 << val);
-       }
-
-       return parent_rate / div;
-}
-
-static struct clk_ops gateclk_ops = {
-       .recalc_rate = socfpga_clk_recalc_rate,
-       .get_parent = socfpga_clk_get_parent,
-       .set_parent = socfpga_clk_set_parent,
+static const struct of_device_id socfpga_child_clocks[] __initconst = {
+       { .compatible = "altr,socfpga-pll-clock", socfpga_pll_init, },
+       { .compatible = "altr,socfpga-perip-clk", socfpga_periph_init, },
+       { .compatible = "altr,socfpga-gate-clk", socfpga_gate_init, },
+       {},
 };
 
-static void __init socfpga_gate_clk_init(struct device_node *node,
-       const struct clk_ops *ops)
-{
-       u32 clk_gate[2];
-       u32 div_reg[3];
-       u32 fixed_div;
-       struct clk *clk;
-       struct socfpga_clk *socfpga_clk;
-       const char *clk_name = node->name;
-       const char *parent_name[SOCFGPA_MAX_PARENTS];
-       struct clk_init_data init;
-       int rc;
-       int i = 0;
-
-       socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
-       if (WARN_ON(!socfpga_clk))
-               return;
-
-       rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
-       if (rc)
-               clk_gate[0] = 0;
-
-       if (clk_gate[0]) {
-               socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
-               socfpga_clk->hw.bit_idx = clk_gate[1];
-
-               gateclk_ops.enable = clk_gate_ops.enable;
-               gateclk_ops.disable = clk_gate_ops.disable;
-       }
-
-       rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
-       if (rc)
-               socfpga_clk->fixed_div = 0;
-       else
-               socfpga_clk->fixed_div = fixed_div;
-
-       rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
-       if (!rc) {
-               socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0];
-               socfpga_clk->shift = div_reg[1];
-               socfpga_clk->width = div_reg[2];
-       } else {
-               socfpga_clk->div_reg = NULL;
-       }
-
-       of_property_read_string(node, "clock-output-names", &clk_name);
-
-       init.name = clk_name;
-       init.ops = ops;
-       init.flags = 0;
-       while (i < SOCFGPA_MAX_PARENTS && (parent_name[i] =
-                       of_clk_get_parent_name(node, i)) != NULL)
-               i++;
-
-       init.parent_names = parent_name;
-       init.num_parents = i;
-       socfpga_clk->hw.hw.init = &init;
-
-       clk = clk_register(NULL, &socfpga_clk->hw.hw);
-       if (WARN_ON(IS_ERR(clk))) {
-               kfree(socfpga_clk);
-               return;
-       }
-       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
-       if (WARN_ON(rc))
-               return;
-}
-
-static void __init socfpga_pll_init(struct device_node *node)
+static void __init socfpga_clkmgr_init(struct device_node *node)
 {
-       socfpga_clk_init(node, &clk_pll_ops);
+       clk_mgr_base_addr = of_iomap(node, 0);
+       of_clk_init(socfpga_child_clocks);
 }
-CLK_OF_DECLARE(socfpga_pll, "altr,socfpga-pll-clock", socfpga_pll_init);
+CLK_OF_DECLARE(socfpga_mgr, "altr,clk-mgr", socfpga_clkmgr_init);
 
-static void __init socfpga_periph_init(struct device_node *node)
-{
-       socfpga_clk_init(node, &periclk_ops);
-}
-CLK_OF_DECLARE(socfpga_periph, "altr,socfpga-perip-clk", socfpga_periph_init);
-
-static void __init socfpga_gate_init(struct device_node *node)
-{
-       socfpga_gate_clk_init(node, &gateclk_ops);
-}
-CLK_OF_DECLARE(socfpga_gate, "altr,socfpga-gate-clk", socfpga_gate_init);
-
-void __init socfpga_init_clocks(void)
-{
-       struct clk *clk;
-       int ret;
-
-       clk = clk_register_fixed_factor(NULL, "smp_twd", "mpuclk", 0, 1, 4);
-       ret = clk_register_clkdev(clk, NULL, "smp_twd");
-       if (ret)
-               pr_err("smp_twd alias not registered\n");
-}
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
new file mode 100644 (file)
index 0000000..d2e5401
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * based on drivers/clk/tegra/clk.h
+ *
+ * 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 __SOCFPGA_CLK_H
+#define __SOCFPGA_CLK_H
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+/* Clock Manager offsets */
+#define CLKMGR_CTRL            0x0
+#define CLKMGR_BYPASS          0x4
+#define CLKMGR_L4SRC           0x70
+#define CLKMGR_PERPLL_SRC      0xAC
+
+#define SOCFPGA_MAX_PARENTS            3
+
+extern void __iomem *clk_mgr_base_addr;
+
+void __init socfpga_pll_init(struct device_node *node);
+void __init socfpga_periph_init(struct device_node *node);
+void __init socfpga_gate_init(struct device_node *node);
+
+struct socfpga_pll {
+       struct clk_gate hw;
+};
+
+struct socfpga_gate_clk {
+       struct clk_gate hw;
+       char *parent_name;
+       u32 fixed_div;
+       void __iomem *div_reg;
+       u32 width;      /* only valid if div_reg != 0 */
+       u32 shift;      /* only valid if div_reg != 0 */
+       u32 clk_phase[2];
+};
+
+struct socfpga_periph_clk {
+       struct clk_gate hw;
+       char *parent_name;
+       u32 fixed_div;
+};
+
+#endif /* SOCFPGA_CLK_H */
diff --git a/drivers/clk/st/Makefile b/drivers/clk/st/Makefile
new file mode 100644 (file)
index 0000000..c7455ff
--- /dev/null
@@ -0,0 +1 @@
+obj-y += clkgen-mux.o clkgen-pll.o clkgen-fsyn.o
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
new file mode 100644 (file)
index 0000000..4f53ee0
--- /dev/null
@@ -0,0 +1,1039 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics R&D Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*
+ * Authors:
+ * Stephen Gallimore <stephen.gallimore@st.com>,
+ * Pankaj Dev <pankaj.dev@st.com>.
+ */
+
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+
+#include "clkgen.h"
+
+/*
+ * Maximum input clock to the PLL before we divide it down by 2
+ * although in reality in actual systems this has never been seen to
+ * be used.
+ */
+#define QUADFS_NDIV_THRESHOLD 30000000
+
+#define PLL_BW_GOODREF   (0L)
+#define PLL_BW_VBADREF   (1L)
+#define PLL_BW_BADREF    (2L)
+#define PLL_BW_VGOODREF  (3L)
+
+#define QUADFS_MAX_CHAN 4
+
+struct stm_fs {
+       unsigned long ndiv;
+       unsigned long mdiv;
+       unsigned long pe;
+       unsigned long sdiv;
+       unsigned long nsdiv;
+};
+
+static struct stm_fs fs216c65_rtbl[] = {
+       { .mdiv = 0x1f, .pe = 0x0,      .sdiv = 0x7,    .nsdiv = 0 },   /* 312.5 Khz */
+       { .mdiv = 0x17, .pe = 0x25ed,   .sdiv = 0x1,    .nsdiv = 0 },   /* 27    MHz */
+       { .mdiv = 0x1a, .pe = 0x7b36,   .sdiv = 0x2,    .nsdiv = 1 },   /* 36.87 MHz */
+       { .mdiv = 0x13, .pe = 0x0,      .sdiv = 0x2,    .nsdiv = 1 },   /* 48    MHz */
+       { .mdiv = 0x11, .pe = 0x1c72,   .sdiv = 0x1,    .nsdiv = 1 },   /* 108   MHz */
+};
+
+static struct stm_fs fs432c65_rtbl[] = {
+       { .mdiv = 0x1f, .pe = 0x0,      .sdiv = 0x7,    .nsdiv = 0 },   /* 625   Khz */
+       { .mdiv = 0x11, .pe = 0x1c72,   .sdiv = 0x2,    .nsdiv = 1 },   /* 108   MHz */
+       { .mdiv = 0x19, .pe = 0x121a,   .sdiv = 0x0,    .nsdiv = 1 },   /* 297   MHz */
+};
+
+static struct stm_fs fs660c32_rtbl[] = {
+       { .mdiv = 0x01, .pe = 0x2aaa,   .sdiv = 0x8,    .nsdiv = 0 },   /* 600   KHz */
+       { .mdiv = 0x02, .pe = 0x3d33,   .sdiv = 0x0,    .nsdiv = 0 },   /* 148.5 Mhz */
+       { .mdiv = 0x13, .pe = 0x5bcc,   .sdiv = 0x0,    .nsdiv = 1 },   /* 297   Mhz */
+       { .mdiv = 0x0e, .pe = 0x1025,   .sdiv = 0x0,    .nsdiv = 1 },   /* 333   Mhz */
+       { .mdiv = 0x0b, .pe = 0x715f,   .sdiv = 0x0,    .nsdiv = 1 },   /* 350   Mhz */
+};
+
+struct clkgen_quadfs_data {
+       bool reset_present;
+       bool bwfilter_present;
+       bool lockstatus_present;
+       bool nsdiv_present;
+       struct clkgen_field ndiv;
+       struct clkgen_field ref_bw;
+       struct clkgen_field nreset;
+       struct clkgen_field npda;
+       struct clkgen_field lock_status;
+
+       struct clkgen_field nsb[QUADFS_MAX_CHAN];
+       struct clkgen_field en[QUADFS_MAX_CHAN];
+       struct clkgen_field mdiv[QUADFS_MAX_CHAN];
+       struct clkgen_field pe[QUADFS_MAX_CHAN];
+       struct clkgen_field sdiv[QUADFS_MAX_CHAN];
+       struct clkgen_field nsdiv[QUADFS_MAX_CHAN];
+
+       const struct clk_ops *pll_ops;
+       struct stm_fs *rtbl;
+       u8 rtbl_cnt;
+       int  (*get_rate)(unsigned long , struct stm_fs *,
+                       unsigned long *);
+};
+
+static const struct clk_ops st_quadfs_pll_c65_ops;
+static const struct clk_ops st_quadfs_pll_c32_ops;
+static const struct clk_ops st_quadfs_fs216c65_ops;
+static const struct clk_ops st_quadfs_fs432c65_ops;
+static const struct clk_ops st_quadfs_fs660c32_ops;
+
+static int clk_fs216c65_get_rate(unsigned long, struct stm_fs *,
+               unsigned long *);
+static int clk_fs432c65_get_rate(unsigned long, struct stm_fs *,
+               unsigned long *);
+static int clk_fs660c32_dig_get_rate(unsigned long, struct stm_fs *,
+               unsigned long *);
+/*
+ * Values for all of the standalone instances of this clock
+ * generator found in STiH415 and STiH416 SYSCFG register banks. Note
+ * that the individual channel standby control bits (nsb) are in the
+ * first register along with the PLL control bits.
+ */
+static struct clkgen_quadfs_data st_fs216c65_416 = {
+       /* 416 specific */
+       .npda   = CLKGEN_FIELD(0x0, 0x1, 14),
+       .nsb    = { CLKGEN_FIELD(0x0, 0x1, 10),
+                   CLKGEN_FIELD(0x0, 0x1, 11),
+                   CLKGEN_FIELD(0x0, 0x1, 12),
+                   CLKGEN_FIELD(0x0, 0x1, 13) },
+       .nsdiv_present = true,
+       .nsdiv  = { CLKGEN_FIELD(0x0, 0x1, 18),
+                   CLKGEN_FIELD(0x0, 0x1, 19),
+                   CLKGEN_FIELD(0x0, 0x1, 20),
+                   CLKGEN_FIELD(0x0, 0x1, 21) },
+       .mdiv   = { CLKGEN_FIELD(0x4, 0x1f, 0),
+                   CLKGEN_FIELD(0x14, 0x1f, 0),
+                   CLKGEN_FIELD(0x24, 0x1f, 0),
+                   CLKGEN_FIELD(0x34, 0x1f, 0) },
+       .en     = { CLKGEN_FIELD(0x10, 0x1, 0),
+                   CLKGEN_FIELD(0x20, 0x1, 0),
+                   CLKGEN_FIELD(0x30, 0x1, 0),
+                   CLKGEN_FIELD(0x40, 0x1, 0) },
+       .ndiv   = CLKGEN_FIELD(0x0, 0x1, 15),
+       .bwfilter_present = true,
+       .ref_bw = CLKGEN_FIELD(0x0, 0x3, 16),
+       .pe     = { CLKGEN_FIELD(0x8, 0xffff, 0),
+                   CLKGEN_FIELD(0x18, 0xffff, 0),
+                   CLKGEN_FIELD(0x28, 0xffff, 0),
+                   CLKGEN_FIELD(0x38, 0xffff, 0) },
+       .sdiv   = { CLKGEN_FIELD(0xC, 0x7, 0),
+                   CLKGEN_FIELD(0x1C, 0x7, 0),
+                   CLKGEN_FIELD(0x2C, 0x7, 0),
+                   CLKGEN_FIELD(0x3C, 0x7, 0) },
+       .pll_ops        = &st_quadfs_pll_c65_ops,
+       .rtbl           = fs216c65_rtbl,
+       .rtbl_cnt       = ARRAY_SIZE(fs216c65_rtbl),
+       .get_rate       = clk_fs216c65_get_rate,
+};
+
+static struct clkgen_quadfs_data st_fs432c65_416 = {
+       .npda   = CLKGEN_FIELD(0x0, 0x1, 14),
+       .nsb    = { CLKGEN_FIELD(0x0, 0x1, 10),
+                   CLKGEN_FIELD(0x0, 0x1, 11),
+                   CLKGEN_FIELD(0x0, 0x1, 12),
+                   CLKGEN_FIELD(0x0, 0x1, 13) },
+       .nsdiv_present = true,
+       .nsdiv  = { CLKGEN_FIELD(0x0, 0x1, 18),
+                  CLKGEN_FIELD(0x0, 0x1, 19),
+                  CLKGEN_FIELD(0x0, 0x1, 20),
+                  CLKGEN_FIELD(0x0, 0x1, 21) },
+       .mdiv   = { CLKGEN_FIELD(0x4, 0x1f, 0),
+                   CLKGEN_FIELD(0x14, 0x1f, 0),
+                   CLKGEN_FIELD(0x24, 0x1f, 0),
+                   CLKGEN_FIELD(0x34, 0x1f, 0) },
+       .en     = { CLKGEN_FIELD(0x10, 0x1, 0),
+                   CLKGEN_FIELD(0x20, 0x1, 0),
+                   CLKGEN_FIELD(0x30, 0x1, 0),
+                   CLKGEN_FIELD(0x40, 0x1, 0) },
+       .ndiv   = CLKGEN_FIELD(0x0, 0x1, 15),
+       .bwfilter_present = true,
+       .ref_bw = CLKGEN_FIELD(0x0, 0x3, 16),
+       .pe     = { CLKGEN_FIELD(0x8, 0xffff, 0),
+                   CLKGEN_FIELD(0x18, 0xffff, 0),
+                   CLKGEN_FIELD(0x28, 0xffff, 0),
+                   CLKGEN_FIELD(0x38, 0xffff, 0) },
+       .sdiv   = { CLKGEN_FIELD(0xC, 0x7, 0),
+                   CLKGEN_FIELD(0x1C, 0x7, 0),
+                   CLKGEN_FIELD(0x2C, 0x7, 0),
+                   CLKGEN_FIELD(0x3C, 0x7, 0) },
+       .pll_ops        = &st_quadfs_pll_c65_ops,
+       .rtbl           = fs432c65_rtbl,
+       .rtbl_cnt       = ARRAY_SIZE(fs432c65_rtbl),
+       .get_rate       = clk_fs432c65_get_rate,
+};
+
+static struct clkgen_quadfs_data st_fs660c32_E_416 = {
+       .npda   = CLKGEN_FIELD(0x0, 0x1, 14),
+       .nsb    = { CLKGEN_FIELD(0x0, 0x1, 10),
+                   CLKGEN_FIELD(0x0, 0x1, 11),
+                   CLKGEN_FIELD(0x0, 0x1, 12),
+                   CLKGEN_FIELD(0x0, 0x1, 13) },
+       .nsdiv_present = true,
+       .nsdiv  = { CLKGEN_FIELD(0x0, 0x1, 18),
+                   CLKGEN_FIELD(0x0, 0x1, 19),
+                   CLKGEN_FIELD(0x0, 0x1, 20),
+                   CLKGEN_FIELD(0x0, 0x1, 21) },
+       .mdiv   = { CLKGEN_FIELD(0x4, 0x1f, 0),
+                   CLKGEN_FIELD(0x14, 0x1f, 0),
+                   CLKGEN_FIELD(0x24, 0x1f, 0),
+                   CLKGEN_FIELD(0x34, 0x1f, 0) },
+       .en     = { CLKGEN_FIELD(0x10, 0x1, 0),
+                   CLKGEN_FIELD(0x20, 0x1, 0),
+                   CLKGEN_FIELD(0x30, 0x1, 0),
+                   CLKGEN_FIELD(0x40, 0x1, 0) },
+       .ndiv   = CLKGEN_FIELD(0x0, 0x7, 15),
+       .pe     = { CLKGEN_FIELD(0x8, 0x7fff, 0),
+                   CLKGEN_FIELD(0x18, 0x7fff, 0),
+                   CLKGEN_FIELD(0x28, 0x7fff, 0),
+                   CLKGEN_FIELD(0x38, 0x7fff, 0) },
+       .sdiv   = { CLKGEN_FIELD(0xC, 0xf, 0),
+                   CLKGEN_FIELD(0x1C, 0xf, 0),
+                   CLKGEN_FIELD(0x2C, 0xf, 0),
+                   CLKGEN_FIELD(0x3C, 0xf, 0) },
+       .lockstatus_present = true,
+       .lock_status = CLKGEN_FIELD(0xAC, 0x1, 0),
+       .pll_ops        = &st_quadfs_pll_c32_ops,
+       .rtbl           = fs660c32_rtbl,
+       .rtbl_cnt       = ARRAY_SIZE(fs660c32_rtbl),
+       .get_rate       = clk_fs660c32_dig_get_rate,
+};
+
+static struct clkgen_quadfs_data st_fs660c32_F_416 = {
+       .npda   = CLKGEN_FIELD(0x0, 0x1, 14),
+       .nsb    = { CLKGEN_FIELD(0x0, 0x1, 10),
+                   CLKGEN_FIELD(0x0, 0x1, 11),
+                   CLKGEN_FIELD(0x0, 0x1, 12),
+                   CLKGEN_FIELD(0x0, 0x1, 13) },
+       .nsdiv_present = true,
+       .nsdiv  = { CLKGEN_FIELD(0x0, 0x1, 18),
+                   CLKGEN_FIELD(0x0, 0x1, 19),
+                   CLKGEN_FIELD(0x0, 0x1, 20),
+                   CLKGEN_FIELD(0x0, 0x1, 21) },
+       .mdiv   = { CLKGEN_FIELD(0x4, 0x1f, 0),
+                   CLKGEN_FIELD(0x14, 0x1f, 0),
+                   CLKGEN_FIELD(0x24, 0x1f, 0),
+                   CLKGEN_FIELD(0x34, 0x1f, 0) },
+       .en     = { CLKGEN_FIELD(0x10, 0x1, 0),
+                   CLKGEN_FIELD(0x20, 0x1, 0),
+                   CLKGEN_FIELD(0x30, 0x1, 0),
+                   CLKGEN_FIELD(0x40, 0x1, 0) },
+       .ndiv   = CLKGEN_FIELD(0x0, 0x7, 15),
+       .pe     = { CLKGEN_FIELD(0x8, 0x7fff, 0),
+                   CLKGEN_FIELD(0x18, 0x7fff, 0),
+                   CLKGEN_FIELD(0x28, 0x7fff, 0),
+                   CLKGEN_FIELD(0x38, 0x7fff, 0) },
+       .sdiv   = { CLKGEN_FIELD(0xC, 0xf, 0),
+                   CLKGEN_FIELD(0x1C, 0xf, 0),
+                   CLKGEN_FIELD(0x2C, 0xf, 0),
+                   CLKGEN_FIELD(0x3C, 0xf, 0) },
+       .lockstatus_present = true,
+       .lock_status = CLKGEN_FIELD(0xEC, 0x1, 0),
+       .pll_ops        = &st_quadfs_pll_c32_ops,
+       .rtbl           = fs660c32_rtbl,
+       .rtbl_cnt       = ARRAY_SIZE(fs660c32_rtbl),
+       .get_rate       = clk_fs660c32_dig_get_rate,
+};
+
+/**
+ * DOC: A Frequency Synthesizer that multiples its input clock by a fixed factor
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control the Fsyn
+ * rate - inherits rate from parent. set_rate/round_rate/recalc_rate
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+/**
+ * struct st_clk_quadfs_pll - A pll which outputs a fixed multiplier of
+ *                                  its parent clock, found inside a type of
+ *                                  ST quad channel frequency synthesizer block
+ *
+ * @hw: handle between common and hardware-specific interfaces.
+ * @ndiv: regmap field for the ndiv control.
+ * @regs_base: base address of the configuration registers.
+ * @lock: spinlock.
+ *
+ */
+struct st_clk_quadfs_pll {
+       struct clk_hw   hw;
+       void __iomem    *regs_base;
+       spinlock_t      *lock;
+       struct clkgen_quadfs_data *data;
+       u32 ndiv;
+};
+
+#define to_quadfs_pll(_hw) container_of(_hw, struct st_clk_quadfs_pll, hw)
+
+static int quadfs_pll_enable(struct clk_hw *hw)
+{
+       struct st_clk_quadfs_pll *pll = to_quadfs_pll(hw);
+       unsigned long flags = 0, timeout = jiffies + msecs_to_jiffies(10);
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       /*
+        * Bring block out of reset if we have reset control.
+        */
+       if (pll->data->reset_present)
+               CLKGEN_WRITE(pll, nreset, 1);
+
+       /*
+        * Use a fixed input clock noise bandwidth filter for the moment
+        */
+       if (pll->data->bwfilter_present)
+               CLKGEN_WRITE(pll, ref_bw, PLL_BW_GOODREF);
+
+
+       CLKGEN_WRITE(pll, ndiv, pll->ndiv);
+
+       /*
+        * Power up the PLL
+        */
+       CLKGEN_WRITE(pll, npda, 1);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       if (pll->data->lockstatus_present)
+               while (!CLKGEN_READ(pll, lock_status)) {
+                       if (time_after(jiffies, timeout))
+                               return -ETIMEDOUT;
+                       cpu_relax();
+               }
+
+       return 0;
+}
+
+static void quadfs_pll_disable(struct clk_hw *hw)
+{
+       struct st_clk_quadfs_pll *pll = to_quadfs_pll(hw);
+       unsigned long flags = 0;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       /*
+        * Powerdown the PLL and then put block into soft reset if we have
+        * reset control.
+        */
+       CLKGEN_WRITE(pll, npda, 0);
+
+       if (pll->data->reset_present)
+               CLKGEN_WRITE(pll, nreset, 0);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static int quadfs_pll_is_enabled(struct clk_hw *hw)
+{
+       struct st_clk_quadfs_pll *pll = to_quadfs_pll(hw);
+       u32 npda = CLKGEN_READ(pll, npda);
+
+       return !!npda;
+}
+
+int clk_fs660c32_vco_get_rate(unsigned long input, struct stm_fs *fs,
+                          unsigned long *rate)
+{
+       unsigned long nd = fs->ndiv + 16; /* ndiv value */
+
+       *rate = input * nd;
+
+       return 0;
+}
+
+static unsigned long quadfs_pll_fs660c32_recalc_rate(struct clk_hw *hw,
+                                       unsigned long parent_rate)
+{
+       struct st_clk_quadfs_pll *pll = to_quadfs_pll(hw);
+       unsigned long rate = 0;
+       struct stm_fs params;
+
+       params.ndiv = CLKGEN_READ(pll, ndiv);
+       if (clk_fs660c32_vco_get_rate(parent_rate, &params, &rate))
+               pr_err("%s:%s error calculating rate\n",
+                      __clk_get_name(hw->clk), __func__);
+
+       pll->ndiv = params.ndiv;
+
+       return rate;
+}
+
+int clk_fs660c32_vco_get_params(unsigned long input,
+                               unsigned long output, struct stm_fs *fs)
+{
+/* Formula
+   VCO frequency = (fin x ndiv) / pdiv
+   ndiv = VCOfreq * pdiv / fin
+   */
+       unsigned long pdiv = 1, n;
+
+       /* Output clock range: 384Mhz to 660Mhz */
+       if (output < 384000000 || output > 660000000)
+               return -EINVAL;
+
+       if (input > 40000000)
+               /* This means that PDIV would be 2 instead of 1.
+                  Not supported today. */
+               return -EINVAL;
+
+       input /= 1000;
+       output /= 1000;
+
+       n = output * pdiv / input;
+       if (n < 16)
+               n = 16;
+       fs->ndiv = n - 16; /* Converting formula value to reg value */
+
+       return 0;
+}
+
+static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, unsigned long rate
+               , unsigned long *prate)
+{
+       struct stm_fs params;
+
+       if (!clk_fs660c32_vco_get_params(*prate, rate, &params))
+               clk_fs660c32_vco_get_rate(*prate, &params, &rate);
+
+       pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
+                __func__, __clk_get_name(hw->clk),
+                rate, (unsigned int)params.sdiv,
+                (unsigned int)params.mdiv,
+                (unsigned int)params.pe, (unsigned int)params.nsdiv);
+
+       return rate;
+}
+
+static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct st_clk_quadfs_pll *pll = to_quadfs_pll(hw);
+       struct stm_fs params;
+       long hwrate = 0;
+       unsigned long flags = 0;
+
+       if (!rate || !parent_rate)
+               return -EINVAL;
+
+       if (!clk_fs660c32_vco_get_params(parent_rate, rate, &params))
+               clk_fs660c32_vco_get_rate(parent_rate, &params, &hwrate);
+
+       pr_debug("%s: %s new rate %ld [ndiv=0x%x]\n",
+                __func__, __clk_get_name(hw->clk),
+                hwrate, (unsigned int)params.ndiv);
+
+       if (!hwrate)
+               return -EINVAL;
+
+       pll->ndiv = params.ndiv;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       CLKGEN_WRITE(pll, ndiv, pll->ndiv);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops st_quadfs_pll_c65_ops = {
+       .enable         = quadfs_pll_enable,
+       .disable        = quadfs_pll_disable,
+       .is_enabled     = quadfs_pll_is_enabled,
+};
+
+static const struct clk_ops st_quadfs_pll_c32_ops = {
+       .enable         = quadfs_pll_enable,
+       .disable        = quadfs_pll_disable,
+       .is_enabled     = quadfs_pll_is_enabled,
+       .recalc_rate    = quadfs_pll_fs660c32_recalc_rate,
+       .round_rate     = quadfs_pll_fs660c32_round_rate,
+       .set_rate       = quadfs_pll_fs660c32_set_rate,
+};
+
+static struct clk * __init st_clk_register_quadfs_pll(
+               const char *name, const char *parent_name,
+               struct clkgen_quadfs_data *quadfs, void __iomem *reg,
+               spinlock_t *lock)
+{
+       struct st_clk_quadfs_pll *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       /*
+        * Sanity check required pointers.
+        */
+       if (WARN_ON(!name || !parent_name))
+               return ERR_PTR(-EINVAL);
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = quadfs->pll_ops;
+       init.flags = CLK_IS_BASIC;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       pll->data = quadfs;
+       pll->regs_base = reg;
+       pll->lock = lock;
+       pll->hw.init = &init;
+
+       clk = clk_register(NULL, &pll->hw);
+
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+/**
+ * DOC: A digital frequency synthesizer
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional
+ * rate - set rate is functional
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+/**
+ * struct st_clk_quadfs_fsynth - One clock output from a four channel digital
+ *                                  frequency synthesizer (fsynth) block.
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ *
+ * @nsb: regmap field in the output control register for the digital
+ *       standby of this fsynth channel. This control is active low so
+ *       the channel is in standby when the control bit is cleared.
+ *
+ * @nsdiv: regmap field in the output control register for
+ *          for the optional divide by 3 of this fsynth channel. This control
+ *          is active low so the divide by 3 is active when the control bit is
+ *          cleared and the divide is bypassed when the bit is set.
+ */
+struct st_clk_quadfs_fsynth {
+       struct clk_hw   hw;
+       void __iomem    *regs_base;
+       spinlock_t      *lock;
+       struct clkgen_quadfs_data *data;
+
+       u32 chan;
+       /*
+        * Cached hardware values from set_rate so we can program the
+        * hardware in enable. There are two reasons for this:
+        *
+        *  1. The registers may not be writable until the parent has been
+        *     enabled.
+        *
+        *  2. It restores the clock rate when a driver does an enable
+        *     on PM restore, after a suspend to RAM has lost the hardware
+        *     setup.
+        */
+       u32 md;
+       u32 pe;
+       u32 sdiv;
+       u32 nsdiv;
+};
+
+#define to_quadfs_fsynth(_hw) \
+       container_of(_hw, struct st_clk_quadfs_fsynth, hw)
+
+static void quadfs_fsynth_program_enable(struct st_clk_quadfs_fsynth *fs)
+{
+       /*
+        * Pulse the program enable register lsb to make the hardware take
+        * notice of the new md/pe values with a glitchless transition.
+        */
+       CLKGEN_WRITE(fs, en[fs->chan], 1);
+       CLKGEN_WRITE(fs, en[fs->chan], 0);
+}
+
+static void quadfs_fsynth_program_rate(struct st_clk_quadfs_fsynth *fs)
+{
+       unsigned long flags = 0;
+
+       /*
+        * Ensure the md/pe parameters are ignored while we are
+        * reprogramming them so we can get a glitchless change
+        * when fine tuning the speed of a running clock.
+        */
+       CLKGEN_WRITE(fs, en[fs->chan], 0);
+
+       CLKGEN_WRITE(fs, mdiv[fs->chan], fs->md);
+       CLKGEN_WRITE(fs, pe[fs->chan], fs->pe);
+       CLKGEN_WRITE(fs, sdiv[fs->chan], fs->sdiv);
+
+       if (fs->lock)
+               spin_lock_irqsave(fs->lock, flags);
+
+       if (fs->data->nsdiv_present)
+               CLKGEN_WRITE(fs, nsdiv[fs->chan], fs->nsdiv);
+
+       if (fs->lock)
+               spin_unlock_irqrestore(fs->lock, flags);
+}
+
+static int quadfs_fsynth_enable(struct clk_hw *hw)
+{
+       struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
+       unsigned long flags = 0;
+
+       pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
+
+       quadfs_fsynth_program_rate(fs);
+
+       if (fs->lock)
+               spin_lock_irqsave(fs->lock, flags);
+
+       CLKGEN_WRITE(fs, nsb[fs->chan], 1);
+
+       if (fs->lock)
+               spin_unlock_irqrestore(fs->lock, flags);
+
+       quadfs_fsynth_program_enable(fs);
+
+       return 0;
+}
+
+static void quadfs_fsynth_disable(struct clk_hw *hw)
+{
+       struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
+       unsigned long flags = 0;
+
+       pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
+
+       if (fs->lock)
+               spin_lock_irqsave(fs->lock, flags);
+
+       CLKGEN_WRITE(fs, nsb[fs->chan], 0);
+
+       if (fs->lock)
+               spin_unlock_irqrestore(fs->lock, flags);
+}
+
+static int quadfs_fsynth_is_enabled(struct clk_hw *hw)
+{
+       struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
+       u32 nsb = CLKGEN_READ(fs, nsb[fs->chan]);
+
+       pr_debug("%s: %s enable bit = 0x%x\n",
+                __func__, __clk_get_name(hw->clk), nsb);
+
+       return !!nsb;
+}
+
+#define P15                    (uint64_t)(1 << 15)
+
+static int clk_fs216c65_get_rate(unsigned long input, struct stm_fs *fs,
+               unsigned long *rate)
+{
+       uint64_t res;
+       unsigned long ns;
+       unsigned long nd = 8; /* ndiv stuck at 0 => val = 8 */
+       unsigned long s;
+       long m;
+
+       m = fs->mdiv - 32;
+       s = 1 << (fs->sdiv + 1);
+       ns = (fs->nsdiv ? 1 : 3);
+
+       res = (uint64_t)(s * ns * P15 * (uint64_t)(m + 33));
+       res = res - (s * ns * fs->pe);
+       *rate = div64_u64(P15 * nd * input * 32, res);
+
+       return 0;
+}
+
+static int clk_fs432c65_get_rate(unsigned long input, struct stm_fs *fs,
+               unsigned long *rate)
+{
+       uint64_t res;
+       unsigned long nd = 16; /* ndiv value; stuck at 0 (30Mhz input) */
+       long m;
+       unsigned long sd;
+       unsigned long ns;
+
+       m = fs->mdiv - 32;
+       sd = 1 << (fs->sdiv + 1);
+       ns = (fs->nsdiv ? 1 : 3);
+
+       res = (uint64_t)(sd * ns * P15 * (uint64_t)(m + 33));
+       res = res - (sd * ns * fs->pe);
+       *rate = div64_u64(P15 * nd * input * 32, res);
+
+       return 0;
+}
+
+#define P20            (uint64_t)(1 << 20)
+
+static int clk_fs660c32_dig_get_rate(unsigned long input,
+                               struct stm_fs *fs, unsigned long *rate)
+{
+       unsigned long s = (1 << fs->sdiv);
+       unsigned long ns;
+       uint64_t res;
+
+       /*
+        * 'nsdiv' is a register value ('BIN') which is translated
+        * to a decimal value according to following rules.
+        *
+        *     nsdiv      ns.dec
+        *       0        3
+        *       1        1
+        */
+       ns = (fs->nsdiv == 1) ? 1 : 3;
+
+       res = (P20 * (32 + fs->mdiv) + 32 * fs->pe) * s * ns;
+       *rate = (unsigned long)div64_u64(input * P20 * 32, res);
+
+       return 0;
+}
+
+static int quadfs_fsynt_get_hw_value_for_recalc(struct st_clk_quadfs_fsynth *fs,
+               struct stm_fs *params)
+{
+       /*
+        * Get the initial hardware values for recalc_rate
+        */
+       params->mdiv    = CLKGEN_READ(fs, mdiv[fs->chan]);
+       params->pe      = CLKGEN_READ(fs, pe[fs->chan]);
+       params->sdiv    = CLKGEN_READ(fs, sdiv[fs->chan]);
+
+       if (fs->data->nsdiv_present)
+               params->nsdiv = CLKGEN_READ(fs, nsdiv[fs->chan]);
+       else
+               params->nsdiv = 1;
+
+       /*
+        * If All are NULL then assume no clock rate is programmed.
+        */
+       if (!params->mdiv && !params->pe && !params->sdiv)
+               return 1;
+
+       fs->md = params->mdiv;
+       fs->pe = params->pe;
+       fs->sdiv = params->sdiv;
+       fs->nsdiv = params->nsdiv;
+
+       return 0;
+}
+
+static long quadfs_find_best_rate(struct clk_hw *hw, unsigned long drate,
+                               unsigned long prate, struct stm_fs *params)
+{
+       struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
+       int (*clk_fs_get_rate)(unsigned long ,
+                               struct stm_fs *, unsigned long *);
+       struct stm_fs prev_params;
+       unsigned long prev_rate, rate = 0;
+       unsigned long diff_rate, prev_diff_rate = ~0;
+       int index;
+
+       clk_fs_get_rate = fs->data->get_rate;
+
+       for (index = 0; index < fs->data->rtbl_cnt; index++) {
+               prev_rate = rate;
+
+               *params = fs->data->rtbl[index];
+               prev_params = *params;
+
+               clk_fs_get_rate(prate, &fs->data->rtbl[index], &rate);
+
+               diff_rate = abs(drate - rate);
+
+               if (diff_rate > prev_diff_rate) {
+                       rate = prev_rate;
+                       *params = prev_params;
+                       break;
+               }
+
+               prev_diff_rate = diff_rate;
+
+               if (drate == rate)
+                       return rate;
+       }
+
+
+       if (index == fs->data->rtbl_cnt)
+               *params = prev_params;
+
+       return rate;
+}
+
+static unsigned long quadfs_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
+       unsigned long rate = 0;
+       struct stm_fs params;
+       int (*clk_fs_get_rate)(unsigned long ,
+                               struct stm_fs *, unsigned long *);
+
+       clk_fs_get_rate = fs->data->get_rate;
+
+       if (quadfs_fsynt_get_hw_value_for_recalc(fs, &params))
+               return 0;
+
+       if (clk_fs_get_rate(parent_rate, &params, &rate)) {
+               pr_err("%s:%s error calculating rate\n",
+                      __clk_get_name(hw->clk), __func__);
+       }
+
+       pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+       return rate;
+}
+
+static long quadfs_round_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long *prate)
+{
+       struct stm_fs params;
+
+       rate = quadfs_find_best_rate(hw, rate, *prate, &params);
+
+       pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
+                __func__, __clk_get_name(hw->clk),
+                rate, (unsigned int)params.sdiv, (unsigned int)params.mdiv,
+                        (unsigned int)params.pe, (unsigned int)params.nsdiv);
+
+       return rate;
+}
+
+
+static void quadfs_program_and_enable(struct st_clk_quadfs_fsynth *fs,
+               struct stm_fs *params)
+{
+       fs->md = params->mdiv;
+       fs->pe = params->pe;
+       fs->sdiv = params->sdiv;
+       fs->nsdiv = params->nsdiv;
+
+       /*
+        * In some integrations you can only change the fsynth programming when
+        * the parent entity containing it is enabled.
+        */
+       quadfs_fsynth_program_rate(fs);
+       quadfs_fsynth_program_enable(fs);
+}
+
+static int quadfs_set_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long parent_rate)
+{
+       struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
+       struct stm_fs params;
+       long hwrate;
+       int uninitialized_var(i);
+
+       if (!rate || !parent_rate)
+               return -EINVAL;
+
+       memset(&params, 0, sizeof(struct stm_fs));
+
+       hwrate = quadfs_find_best_rate(hw, rate, parent_rate, &params);
+       if (!hwrate)
+               return -EINVAL;
+
+       quadfs_program_and_enable(fs, &params);
+
+       return 0;
+}
+
+
+
+static const struct clk_ops st_quadfs_ops = {
+       .enable         = quadfs_fsynth_enable,
+       .disable        = quadfs_fsynth_disable,
+       .is_enabled     = quadfs_fsynth_is_enabled,
+       .round_rate     = quadfs_round_rate,
+       .set_rate       = quadfs_set_rate,
+       .recalc_rate    = quadfs_recalc_rate,
+};
+
+static struct clk * __init st_clk_register_quadfs_fsynth(
+               const char *name, const char *parent_name,
+               struct clkgen_quadfs_data *quadfs, void __iomem *reg, u32 chan,
+               spinlock_t *lock)
+{
+       struct st_clk_quadfs_fsynth *fs;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       /*
+        * Sanity check required pointers, note that nsdiv3 is optional.
+        */
+       if (WARN_ON(!name || !parent_name))
+               return ERR_PTR(-EINVAL);
+
+       fs = kzalloc(sizeof(*fs), GFP_KERNEL);
+       if (!fs)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &st_quadfs_ops;
+       init.flags = CLK_GET_RATE_NOCACHE | CLK_IS_BASIC;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       fs->data = quadfs;
+       fs->regs_base = reg;
+       fs->chan = chan;
+       fs->lock = lock;
+       fs->hw.init = &init;
+
+       clk = clk_register(NULL, &fs->hw);
+
+       if (IS_ERR(clk))
+               kfree(fs);
+
+       return clk;
+}
+
+static struct of_device_id quadfs_of_match[] = {
+       {
+               .compatible = "st,stih416-quadfs216",
+               .data = (void *)&st_fs216c65_416
+       },
+       {
+               .compatible = "st,stih416-quadfs432",
+               .data = (void *)&st_fs432c65_416
+       },
+       {
+               .compatible = "st,stih416-quadfs660-E",
+               .data = (void *)&st_fs660c32_E_416
+       },
+       {
+               .compatible = "st,stih416-quadfs660-F",
+               .data = (void *)&st_fs660c32_F_416
+       },
+       {}
+};
+
+static void __init st_of_create_quadfs_fsynths(
+               struct device_node *np, const char *pll_name,
+               struct clkgen_quadfs_data *quadfs, void __iomem *reg,
+               spinlock_t *lock)
+{
+       struct clk_onecell_data *clk_data;
+       int fschan;
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return;
+
+       clk_data->clk_num = QUADFS_MAX_CHAN;
+       clk_data->clks = kzalloc(QUADFS_MAX_CHAN * sizeof(struct clk *),
+                                GFP_KERNEL);
+
+       if (!clk_data->clks) {
+               kfree(clk_data);
+               return;
+       }
+
+       for (fschan = 0; fschan < QUADFS_MAX_CHAN; fschan++) {
+               struct clk *clk;
+               const char *clk_name;
+
+               if (of_property_read_string_index(np, "clock-output-names",
+                                                 fschan, &clk_name)) {
+                       break;
+               }
+
+               /*
+                * If we read an empty clock name then the channel is unused
+                */
+               if (*clk_name == '\0')
+                       continue;
+
+               clk = st_clk_register_quadfs_fsynth(clk_name, pll_name,
+                               quadfs, reg, fschan, lock);
+
+               /*
+                * If there was an error registering this clock output, clean
+                * up and move on to the next one.
+                */
+               if (!IS_ERR(clk)) {
+                       clk_data->clks[fschan] = clk;
+                       pr_debug("%s: parent %s rate %u\n",
+                               __clk_get_name(clk),
+                               __clk_get_name(clk_get_parent(clk)),
+                               (unsigned int)clk_get_rate(clk));
+               }
+       }
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+}
+
+static void __init st_of_quadfs_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       struct clk *clk;
+       const char *pll_name, *clk_parent_name;
+       void __iomem *reg;
+       spinlock_t *lock;
+
+       match = of_match_node(quadfs_of_match, np);
+       if (WARN_ON(!match))
+               return;
+
+       reg = of_iomap(np, 0);
+       if (!reg)
+               return;
+
+       clk_parent_name = of_clk_get_parent_name(np, 0);
+       if (!clk_parent_name)
+               return;
+
+       pll_name = kasprintf(GFP_KERNEL, "%s.pll", np->name);
+       if (!pll_name)
+               return;
+
+       lock = kzalloc(sizeof(*lock), GFP_KERNEL);
+       if (!lock)
+               goto err_exit;
+
+       spin_lock_init(lock);
+
+       clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name,
+                       (struct clkgen_quadfs_data *) match->data, reg, lock);
+       if (IS_ERR(clk))
+               goto err_exit;
+       else
+               pr_debug("%s: parent %s rate %u\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       (unsigned int)clk_get_rate(clk));
+
+       st_of_create_quadfs_fsynths(np, pll_name,
+                                   (struct clkgen_quadfs_data *)match->data,
+                                   reg, lock);
+
+err_exit:
+       kfree(pll_name); /* No longer need local copy of the PLL name */
+}
+CLK_OF_DECLARE(quadfs, "st,quadfs", st_of_quadfs_setup);
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
new file mode 100644 (file)
index 0000000..a329906
--- /dev/null
@@ -0,0 +1,820 @@
+/*
+ * clkgen-mux.c: ST GEN-MUX Clock driver
+ *
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited
+ *
+ * Authors: Stephen Gallimore <stephen.gallimore@st.com>
+ *         Pankaj Dev <pankaj.dev@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+
+static DEFINE_SPINLOCK(clkgena_divmux_lock);
+static DEFINE_SPINLOCK(clkgenf_lock);
+
+static const char ** __init clkgen_mux_get_parents(struct device_node *np,
+                                                      int *num_parents)
+{
+       const char **parents;
+       int nparents, i;
+
+       nparents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+       if (WARN_ON(nparents <= 0))
+               return ERR_PTR(-EINVAL);
+
+       parents = kzalloc(nparents * sizeof(const char *), GFP_KERNEL);
+       if (!parents)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < nparents; i++)
+               parents[i] = of_clk_get_parent_name(np, i);
+
+       *num_parents = nparents;
+       return parents;
+}
+
+/**
+ * DOC: Clock mux with a programmable divider on each of its three inputs.
+ *      The mux has an input setting which effectively gates its output.
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - set rate is supported
+ * parent - set/get parent
+ */
+
+#define NUM_INPUTS 3
+
+struct clkgena_divmux {
+       struct clk_hw hw;
+       /* Subclassed mux and divider structures */
+       struct clk_mux mux;
+       struct clk_divider div[NUM_INPUTS];
+       /* Enable/running feedback register bits for each input */
+       void __iomem *feedback_reg[NUM_INPUTS];
+       int feedback_bit_idx;
+
+       u8              muxsel;
+};
+
+#define to_clkgena_divmux(_hw) container_of(_hw, struct clkgena_divmux, hw)
+
+struct clkgena_divmux_data {
+       int num_outputs;
+       int mux_offset;
+       int mux_offset2;
+       int mux_start_bit;
+       int div_offsets[NUM_INPUTS];
+       int fb_offsets[NUM_INPUTS];
+       int fb_start_bit_idx;
+};
+
+#define CKGAX_CLKOPSRC_SWITCH_OFF 0x3
+
+static int clkgena_divmux_is_running(struct clkgena_divmux *mux)
+{
+       u32 regval = readl(mux->feedback_reg[mux->muxsel]);
+       u32 running = regval & BIT(mux->feedback_bit_idx);
+       return !!running;
+}
+
+static int clkgena_divmux_enable(struct clk_hw *hw)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *mux_hw = &genamux->mux.hw;
+       unsigned long timeout;
+       int ret = 0;
+
+       mux_hw->clk = hw->clk;
+
+       ret = clk_mux_ops.set_parent(mux_hw, genamux->muxsel);
+       if (ret)
+               return ret;
+
+       timeout = jiffies + msecs_to_jiffies(10);
+
+       while (!clkgena_divmux_is_running(genamux)) {
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+               cpu_relax();
+       }
+
+       return 0;
+}
+
+static void clkgena_divmux_disable(struct clk_hw *hw)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *mux_hw = &genamux->mux.hw;
+
+       mux_hw->clk = hw->clk;
+
+       clk_mux_ops.set_parent(mux_hw, CKGAX_CLKOPSRC_SWITCH_OFF);
+}
+
+static int clkgena_divmux_is_enabled(struct clk_hw *hw)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *mux_hw = &genamux->mux.hw;
+
+       mux_hw->clk = hw->clk;
+
+       return (s8)clk_mux_ops.get_parent(mux_hw) > 0;
+}
+
+u8 clkgena_divmux_get_parent(struct clk_hw *hw)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *mux_hw = &genamux->mux.hw;
+
+       mux_hw->clk = hw->clk;
+
+       genamux->muxsel = clk_mux_ops.get_parent(mux_hw);
+       if ((s8)genamux->muxsel < 0) {
+               pr_debug("%s: %s: Invalid parent, setting to default.\n",
+                     __func__, __clk_get_name(hw->clk));
+               genamux->muxsel = 0;
+       }
+
+       return genamux->muxsel;
+}
+
+static int clkgena_divmux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+
+       if (index >= CKGAX_CLKOPSRC_SWITCH_OFF)
+               return -EINVAL;
+
+       genamux->muxsel = index;
+
+       /*
+        * If the mux is already enabled, call enable directly to set the
+        * new mux position and wait for it to start running again. Otherwise
+        * do nothing.
+        */
+       if (clkgena_divmux_is_enabled(hw))
+               clkgena_divmux_enable(hw);
+
+       return 0;
+}
+
+unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
+
+       div_hw->clk = hw->clk;
+
+       return clk_divider_ops.recalc_rate(div_hw, parent_rate);
+}
+
+static int clkgena_divmux_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
+
+       div_hw->clk = hw->clk;
+
+       return clk_divider_ops.set_rate(div_hw, rate, parent_rate);
+}
+
+static long clkgena_divmux_round_rate(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long *prate)
+{
+       struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
+       struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw;
+
+       div_hw->clk = hw->clk;
+
+       return clk_divider_ops.round_rate(div_hw, rate, prate);
+}
+
+static const struct clk_ops clkgena_divmux_ops = {
+       .enable = clkgena_divmux_enable,
+       .disable = clkgena_divmux_disable,
+       .is_enabled = clkgena_divmux_is_enabled,
+       .get_parent = clkgena_divmux_get_parent,
+       .set_parent = clkgena_divmux_set_parent,
+       .round_rate = clkgena_divmux_round_rate,
+       .recalc_rate = clkgena_divmux_recalc_rate,
+       .set_rate = clkgena_divmux_set_rate,
+};
+
+/**
+ * clk_register_genamux - register a genamux clock with the clock framework
+ */
+struct clk *clk_register_genamux(const char *name,
+                               const char **parent_names, u8 num_parents,
+                               void __iomem *reg,
+                               const struct clkgena_divmux_data *muxdata,
+                               u32 idx)
+{
+       /*
+        * Fixed constants across all ClockgenA variants
+        */
+       const int mux_width = 2;
+       const int divider_width = 5;
+       struct clkgena_divmux *genamux;
+       struct clk *clk;
+       struct clk_init_data init;
+       int i;
+
+       genamux = kzalloc(sizeof(*genamux), GFP_KERNEL);
+       if (!genamux)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &clkgena_divmux_ops;
+       init.flags = CLK_IS_BASIC;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+
+       genamux->mux.lock  = &clkgena_divmux_lock;
+       genamux->mux.mask = BIT(mux_width) - 1;
+       genamux->mux.shift = muxdata->mux_start_bit + (idx * mux_width);
+       if (genamux->mux.shift > 31) {
+               /*
+                * We have spilled into the second mux register so
+                * adjust the register address and the bit shift accordingly
+                */
+               genamux->mux.reg = reg + muxdata->mux_offset2;
+               genamux->mux.shift -= 32;
+       } else {
+               genamux->mux.reg   = reg + muxdata->mux_offset;
+       }
+
+       for (i = 0; i < NUM_INPUTS; i++) {
+               /*
+                * Divider config for each input
+                */
+               void __iomem *divbase = reg + muxdata->div_offsets[i];
+               genamux->div[i].width = divider_width;
+               genamux->div[i].reg = divbase + (idx * sizeof(u32));
+
+               /*
+                * Mux enabled/running feedback register for each input.
+                */
+               genamux->feedback_reg[i] = reg + muxdata->fb_offsets[i];
+       }
+
+       genamux->feedback_bit_idx = muxdata->fb_start_bit_idx + idx;
+       genamux->hw.init = &init;
+
+       clk = clk_register(NULL, &genamux->hw);
+       if (IS_ERR(clk)) {
+               kfree(genamux);
+               goto err;
+       }
+
+       pr_debug("%s: parent %s rate %lu\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       clk_get_rate(clk));
+err:
+       return clk;
+}
+
+static struct clkgena_divmux_data st_divmux_c65hs = {
+       .num_outputs = 4,
+       .mux_offset = 0x14,
+       .mux_start_bit = 0,
+       .div_offsets = { 0x800, 0x900, 0xb00 },
+       .fb_offsets = { 0x18, 0x1c, 0x20 },
+       .fb_start_bit_idx = 0,
+};
+
+static struct clkgena_divmux_data st_divmux_c65ls = {
+       .num_outputs = 14,
+       .mux_offset = 0x14,
+       .mux_offset2 = 0x24,
+       .mux_start_bit = 8,
+       .div_offsets = { 0x810, 0xa10, 0xb10 },
+       .fb_offsets = { 0x18, 0x1c, 0x20 },
+       .fb_start_bit_idx = 4,
+};
+
+static struct clkgena_divmux_data st_divmux_c32odf0 = {
+       .num_outputs = 8,
+       .mux_offset = 0x1c,
+       .mux_start_bit = 0,
+       .div_offsets = { 0x800, 0x900, 0xa60 },
+       .fb_offsets = { 0x2c, 0x24, 0x28 },
+       .fb_start_bit_idx = 0,
+};
+
+static struct clkgena_divmux_data st_divmux_c32odf1 = {
+       .num_outputs = 8,
+       .mux_offset = 0x1c,
+       .mux_start_bit = 16,
+       .div_offsets = { 0x820, 0x980, 0xa80 },
+       .fb_offsets = { 0x2c, 0x24, 0x28 },
+       .fb_start_bit_idx = 8,
+};
+
+static struct clkgena_divmux_data st_divmux_c32odf2 = {
+       .num_outputs = 8,
+       .mux_offset = 0x20,
+       .mux_start_bit = 0,
+       .div_offsets = { 0x840, 0xa20, 0xb10 },
+       .fb_offsets = { 0x2c, 0x24, 0x28 },
+       .fb_start_bit_idx = 16,
+};
+
+static struct clkgena_divmux_data st_divmux_c32odf3 = {
+       .num_outputs = 8,
+       .mux_offset = 0x20,
+       .mux_start_bit = 16,
+       .div_offsets = { 0x860, 0xa40, 0xb30 },
+       .fb_offsets = { 0x2c, 0x24, 0x28 },
+       .fb_start_bit_idx = 24,
+};
+
+static struct of_device_id clkgena_divmux_of_match[] = {
+       {
+               .compatible = "st,clkgena-divmux-c65-hs",
+               .data = &st_divmux_c65hs,
+       },
+       {
+               .compatible = "st,clkgena-divmux-c65-ls",
+               .data = &st_divmux_c65ls,
+       },
+       {
+               .compatible = "st,clkgena-divmux-c32-odf0",
+               .data = &st_divmux_c32odf0,
+       },
+       {
+               .compatible = "st,clkgena-divmux-c32-odf1",
+               .data = &st_divmux_c32odf1,
+       },
+       {
+               .compatible = "st,clkgena-divmux-c32-odf2",
+               .data = &st_divmux_c32odf2,
+       },
+       {
+               .compatible = "st,clkgena-divmux-c32-odf3",
+               .data = &st_divmux_c32odf3,
+       },
+       {}
+};
+
+static void __iomem * __init clkgen_get_register_base(
+                               struct device_node *np)
+{
+       struct device_node *pnode;
+       void __iomem *reg = NULL;
+
+       pnode = of_get_parent(np);
+       if (!pnode)
+               return NULL;
+
+       reg = of_iomap(pnode, 0);
+
+       of_node_put(pnode);
+       return reg;
+}
+
+void __init st_of_clkgena_divmux_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       const struct clkgena_divmux_data *data;
+       struct clk_onecell_data *clk_data;
+       void __iomem *reg;
+       const char **parents;
+       int num_parents = 0, i;
+
+       match = of_match_node(clkgena_divmux_of_match, np);
+       if (WARN_ON(!match))
+               return;
+
+       data = (struct clkgena_divmux_data *)match->data;
+
+       reg = clkgen_get_register_base(np);
+       if (!reg)
+               return;
+
+       parents = clkgen_mux_get_parents(np, &num_parents);
+       if (IS_ERR(parents))
+               return;
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               goto err;
+
+       clk_data->clk_num = data->num_outputs;
+       clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
+                                GFP_KERNEL);
+
+       if (!clk_data->clks)
+               goto err;
+
+       for (i = 0; i < clk_data->clk_num; i++) {
+               struct clk *clk;
+               const char *clk_name;
+
+               if (of_property_read_string_index(np, "clock-output-names",
+                                                 i, &clk_name))
+                       break;
+
+               /*
+                * If we read an empty clock name then the output is unused
+                */
+               if (*clk_name == '\0')
+                       continue;
+
+               clk = clk_register_genamux(clk_name, parents, num_parents,
+                                          reg, data, i);
+
+               if (IS_ERR(clk))
+                       goto err;
+
+               clk_data->clks[i] = clk;
+       }
+
+       kfree(parents);
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+       return;
+err:
+       if (clk_data)
+               kfree(clk_data->clks);
+
+       kfree(clk_data);
+       kfree(parents);
+}
+CLK_OF_DECLARE(clkgenadivmux, "st,clkgena-divmux", st_of_clkgena_divmux_setup);
+
+struct clkgena_prediv_data {
+       u32 offset;
+       u8 shift;
+       struct clk_div_table *table;
+};
+
+static struct clk_div_table prediv_table16[] = {
+       { .val = 0, .div = 1 },
+       { .val = 1, .div = 16 },
+       { .div = 0 },
+};
+
+static struct clkgena_prediv_data prediv_c65_data = {
+       .offset = 0x4c,
+       .shift = 31,
+       .table = prediv_table16,
+};
+
+static struct clkgena_prediv_data prediv_c32_data = {
+       .offset = 0x50,
+       .shift = 1,
+       .table = prediv_table16,
+};
+
+static struct of_device_id clkgena_prediv_of_match[] = {
+       { .compatible = "st,clkgena-prediv-c65", .data = &prediv_c65_data },
+       { .compatible = "st,clkgena-prediv-c32", .data = &prediv_c32_data },
+       {}
+};
+
+void __init st_of_clkgena_prediv_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       void __iomem *reg;
+       const char *parent_name, *clk_name;
+       struct clk *clk;
+       struct clkgena_prediv_data *data;
+
+       match = of_match_node(clkgena_prediv_of_match, np);
+       if (!match) {
+               pr_err("%s: No matching data\n", __func__);
+               return;
+       }
+
+       data = (struct clkgena_prediv_data *)match->data;
+
+       reg = clkgen_get_register_base(np);
+       if (!reg)
+               return;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       if (of_property_read_string_index(np, "clock-output-names",
+                                         0, &clk_name))
+               return;
+
+       clk = clk_register_divider_table(NULL, clk_name, parent_name, 0,
+                                        reg + data->offset, data->shift, 1,
+                                        0, data->table, NULL);
+       if (IS_ERR(clk))
+               return;
+
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       pr_debug("%s: parent %s rate %u\n",
+               __clk_get_name(clk),
+               __clk_get_name(clk_get_parent(clk)),
+               (unsigned int)clk_get_rate(clk));
+
+       return;
+}
+CLK_OF_DECLARE(clkgenaprediv, "st,clkgena-prediv", st_of_clkgena_prediv_setup);
+
+struct clkgen_mux_data {
+       u32 offset;
+       u8 shift;
+       u8 width;
+       spinlock_t *lock;
+       unsigned long clk_flags;
+       u8 mux_flags;
+};
+
+static struct clkgen_mux_data clkgen_mux_c_vcc_hd_416 = {
+       .offset = 0,
+       .shift = 0,
+       .width = 1,
+};
+
+static struct clkgen_mux_data clkgen_mux_f_vcc_fvdp_416 = {
+       .offset = 0,
+       .shift = 0,
+       .width = 1,
+};
+
+static struct clkgen_mux_data clkgen_mux_f_vcc_hva_416 = {
+       .offset = 0,
+       .shift = 0,
+       .width = 1,
+};
+
+static struct clkgen_mux_data clkgen_mux_f_vcc_hd_416 = {
+       .offset = 0,
+       .shift = 16,
+       .width = 1,
+       .lock = &clkgenf_lock,
+};
+
+static struct clkgen_mux_data clkgen_mux_c_vcc_sd_416 = {
+       .offset = 0,
+       .shift = 17,
+       .width = 1,
+       .lock = &clkgenf_lock,
+};
+
+static struct clkgen_mux_data stih415_a9_mux_data = {
+       .offset = 0,
+       .shift = 1,
+       .width = 2,
+};
+static struct clkgen_mux_data stih416_a9_mux_data = {
+       .offset = 0,
+       .shift = 0,
+       .width = 2,
+};
+
+static struct of_device_id mux_of_match[] = {
+       {
+               .compatible = "st,stih416-clkgenc-vcc-hd",
+               .data = &clkgen_mux_c_vcc_hd_416,
+       },
+       {
+               .compatible = "st,stih416-clkgenf-vcc-fvdp",
+               .data = &clkgen_mux_f_vcc_fvdp_416,
+       },
+       {
+               .compatible = "st,stih416-clkgenf-vcc-hva",
+               .data = &clkgen_mux_f_vcc_hva_416,
+       },
+       {
+               .compatible = "st,stih416-clkgenf-vcc-hd",
+               .data = &clkgen_mux_f_vcc_hd_416,
+       },
+       {
+               .compatible = "st,stih416-clkgenf-vcc-sd",
+               .data = &clkgen_mux_c_vcc_sd_416,
+       },
+       {
+               .compatible = "st,stih415-clkgen-a9-mux",
+               .data = &stih415_a9_mux_data,
+       },
+       {
+               .compatible = "st,stih416-clkgen-a9-mux",
+               .data = &stih416_a9_mux_data,
+       },
+       {}
+};
+
+void __init st_of_clkgen_mux_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       struct clk *clk;
+       void __iomem *reg;
+       const char **parents;
+       int num_parents;
+       struct clkgen_mux_data *data;
+
+       match = of_match_node(mux_of_match, np);
+       if (!match) {
+               pr_err("%s: No matching data\n", __func__);
+               return;
+       }
+
+       data = (struct clkgen_mux_data *)match->data;
+
+       reg = of_iomap(np, 0);
+       if (!reg) {
+               pr_err("%s: Failed to get base address\n", __func__);
+               return;
+       }
+
+       parents = clkgen_mux_get_parents(np, &num_parents);
+       if (IS_ERR(parents)) {
+               pr_err("%s: Failed to get parents (%ld)\n",
+                               __func__, PTR_ERR(parents));
+               return;
+       }
+
+       clk = clk_register_mux(NULL, np->name, parents, num_parents,
+                               data->clk_flags | CLK_SET_RATE_PARENT,
+                               reg + data->offset,
+                               data->shift, data->width, data->mux_flags,
+                               data->lock);
+       if (IS_ERR(clk))
+               goto err;
+
+       pr_debug("%s: parent %s rate %u\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       (unsigned int)clk_get_rate(clk));
+
+       of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+err:
+       kfree(parents);
+
+       return;
+}
+CLK_OF_DECLARE(clkgen_mux, "st,clkgen-mux", st_of_clkgen_mux_setup);
+
+#define VCC_MAX_CHANNELS 16
+
+#define VCC_GATE_OFFSET 0x0
+#define VCC_MUX_OFFSET 0x4
+#define VCC_DIV_OFFSET 0x8
+
+struct clkgen_vcc_data {
+       spinlock_t *lock;
+       unsigned long clk_flags;
+};
+
+static struct clkgen_vcc_data st_clkgenc_vcc_416 = {
+       .clk_flags = CLK_SET_RATE_PARENT,
+};
+
+static struct clkgen_vcc_data st_clkgenf_vcc_416 = {
+       .lock = &clkgenf_lock,
+};
+
+static struct of_device_id vcc_of_match[] = {
+       { .compatible = "st,stih416-clkgenc", .data = &st_clkgenc_vcc_416 },
+       { .compatible = "st,stih416-clkgenf", .data = &st_clkgenf_vcc_416 },
+       {}
+};
+
+void __init st_of_clkgen_vcc_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       void __iomem *reg;
+       const char **parents;
+       int num_parents, i;
+       struct clk_onecell_data *clk_data;
+       struct clkgen_vcc_data *data;
+
+       match = of_match_node(vcc_of_match, np);
+       if (WARN_ON(!match))
+               return;
+       data = (struct clkgen_vcc_data *)match->data;
+
+       reg = of_iomap(np, 0);
+       if (!reg)
+               return;
+
+       parents = clkgen_mux_get_parents(np, &num_parents);
+       if (IS_ERR(parents))
+               return;
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               goto err;
+
+       clk_data->clk_num = VCC_MAX_CHANNELS;
+       clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
+                                GFP_KERNEL);
+
+       if (!clk_data->clks)
+               goto err;
+
+       for (i = 0; i < clk_data->clk_num; i++) {
+               struct clk *clk;
+               const char *clk_name;
+               struct clk_gate *gate;
+               struct clk_divider *div;
+               struct clk_mux *mux;
+
+               if (of_property_read_string_index(np, "clock-output-names",
+                                                 i, &clk_name))
+                       break;
+
+               /*
+                * If we read an empty clock name then the output is unused
+                */
+               if (*clk_name == '\0')
+                       continue;
+
+               gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+               if (!gate)
+                       break;
+
+               div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
+               if (!div) {
+                       kfree(gate);
+                       break;
+               }
+
+               mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+               if (!mux) {
+                       kfree(gate);
+                       kfree(div);
+                       break;
+               }
+
+               gate->reg = reg + VCC_GATE_OFFSET;
+               gate->bit_idx = i;
+               gate->flags = CLK_GATE_SET_TO_DISABLE;
+               gate->lock = data->lock;
+
+               div->reg = reg + VCC_DIV_OFFSET;
+               div->shift = 2 * i;
+               div->width = 2;
+               div->flags = CLK_DIVIDER_POWER_OF_TWO;
+
+               mux->reg = reg + VCC_MUX_OFFSET;
+               mux->shift = 2 * i;
+               mux->mask = 0x3;
+
+               clk = clk_register_composite(NULL, clk_name, parents,
+                                            num_parents,
+                                            &mux->hw, &clk_mux_ops,
+                                            &div->hw, &clk_divider_ops,
+                                            &gate->hw, &clk_gate_ops,
+                                            data->clk_flags);
+               if (IS_ERR(clk)) {
+                       kfree(gate);
+                       kfree(div);
+                       kfree(mux);
+                       goto err;
+               }
+
+               pr_debug("%s: parent %s rate %u\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       (unsigned int)clk_get_rate(clk));
+
+               clk_data->clks[i] = clk;
+       }
+
+       kfree(parents);
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+       return;
+
+err:
+       for (i = 0; i < clk_data->clk_num; i++) {
+               struct clk_composite *composite;
+
+               if (!clk_data->clks[i])
+                       continue;
+
+               composite = container_of(__clk_get_hw(clk_data->clks[i]),
+                                        struct clk_composite, hw);
+               kfree(container_of(composite->gate_hw, struct clk_gate, hw));
+               kfree(container_of(composite->rate_hw, struct clk_divider, hw));
+               kfree(container_of(composite->mux_hw, struct clk_mux, hw));
+       }
+
+       if (clk_data)
+               kfree(clk_data->clks);
+
+       kfree(clk_data);
+       kfree(parents);
+}
+CLK_OF_DECLARE(clkgen_vcc, "st,clkgen-vcc", st_of_clkgen_vcc_setup);
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
new file mode 100644 (file)
index 0000000..bca0a0b
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics (R&D) Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+/*
+ * Authors:
+ * Stephen Gallimore <stephen.gallimore@st.com>,
+ * Pankaj Dev <pankaj.dev@st.com>.
+ */
+
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+
+#include "clkgen.h"
+
+static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
+
+/*
+ * Common PLL configuration register bits for PLL800 and PLL1600 C65
+ */
+#define C65_MDIV_PLL800_MASK   (0xff)
+#define C65_MDIV_PLL1600_MASK  (0x7)
+#define C65_NDIV_MASK          (0xff)
+#define C65_PDIV_MASK          (0x7)
+
+/*
+ * PLL configuration register bits for PLL3200 C32
+ */
+#define C32_NDIV_MASK (0xff)
+#define C32_IDF_MASK (0x7)
+#define C32_ODF_MASK (0x3f)
+#define C32_LDF_MASK (0x7f)
+
+#define C32_MAX_ODFS (4)
+
+struct clkgen_pll_data {
+       struct clkgen_field pdn_status;
+       struct clkgen_field locked_status;
+       struct clkgen_field mdiv;
+       struct clkgen_field ndiv;
+       struct clkgen_field pdiv;
+       struct clkgen_field idf;
+       struct clkgen_field ldf;
+       unsigned int num_odfs;
+       struct clkgen_field odf[C32_MAX_ODFS];
+       struct clkgen_field odf_gate[C32_MAX_ODFS];
+       const struct clk_ops *ops;
+};
+
+static const struct clk_ops st_pll1600c65_ops;
+static const struct clk_ops st_pll800c65_ops;
+static const struct clk_ops stm_pll3200c32_ops;
+static const struct clk_ops st_pll1200c32_ops;
+
+static struct clkgen_pll_data st_pll1600c65_ax = {
+       .pdn_status     = CLKGEN_FIELD(0x0, 0x1,                        19),
+       .locked_status  = CLKGEN_FIELD(0x0, 0x1,                        31),
+       .mdiv           = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK,      0),
+       .ndiv           = CLKGEN_FIELD(0x0, C65_NDIV_MASK,              8),
+       .ops            = &st_pll1600c65_ops
+};
+
+static struct clkgen_pll_data st_pll800c65_ax = {
+       .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    19),
+       .locked_status  = CLKGEN_FIELD(0x0,     0x1,                    31),
+       .mdiv           = CLKGEN_FIELD(0x0,     C65_MDIV_PLL800_MASK,   0),
+       .ndiv           = CLKGEN_FIELD(0x0,     C65_NDIV_MASK,          8),
+       .pdiv           = CLKGEN_FIELD(0x0,     C65_PDIV_MASK,          16),
+       .ops            = &st_pll800c65_ops
+};
+
+static struct clkgen_pll_data st_pll3200c32_a1x_0 = {
+       .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    31),
+       .locked_status  = CLKGEN_FIELD(0x4,     0x1,                    31),
+       .ndiv           = CLKGEN_FIELD(0x0,     C32_NDIV_MASK,          0x0),
+       .idf            = CLKGEN_FIELD(0x4,     C32_IDF_MASK,           0x0),
+       .num_odfs = 4,
+       .odf =  {       CLKGEN_FIELD(0x54,      C32_ODF_MASK,           4),
+                       CLKGEN_FIELD(0x54,      C32_ODF_MASK,           10),
+                       CLKGEN_FIELD(0x54,      C32_ODF_MASK,           16),
+                       CLKGEN_FIELD(0x54,      C32_ODF_MASK,           22) },
+       .odf_gate = {   CLKGEN_FIELD(0x54,      0x1,                    0),
+                       CLKGEN_FIELD(0x54,      0x1,                    1),
+                       CLKGEN_FIELD(0x54,      0x1,                    2),
+                       CLKGEN_FIELD(0x54,      0x1,                    3) },
+       .ops            = &stm_pll3200c32_ops,
+};
+
+static struct clkgen_pll_data st_pll3200c32_a1x_1 = {
+       .pdn_status     = CLKGEN_FIELD(0xC,     0x1,                    31),
+       .locked_status  = CLKGEN_FIELD(0x10,    0x1,                    31),
+       .ndiv           = CLKGEN_FIELD(0xC,     C32_NDIV_MASK,          0x0),
+       .idf            = CLKGEN_FIELD(0x10,    C32_IDF_MASK,           0x0),
+       .num_odfs = 4,
+       .odf = {        CLKGEN_FIELD(0x58,      C32_ODF_MASK,           4),
+                       CLKGEN_FIELD(0x58,      C32_ODF_MASK,           10),
+                       CLKGEN_FIELD(0x58,      C32_ODF_MASK,           16),
+                       CLKGEN_FIELD(0x58,      C32_ODF_MASK,           22) },
+       .odf_gate = {   CLKGEN_FIELD(0x58,      0x1,                    0),
+                       CLKGEN_FIELD(0x58,      0x1,                    1),
+                       CLKGEN_FIELD(0x58,      0x1,                    2),
+                       CLKGEN_FIELD(0x58,      0x1,                    3) },
+       .ops            = &stm_pll3200c32_ops,
+};
+
+/* 415 specific */
+static struct clkgen_pll_data st_pll3200c32_a9_415 = {
+       .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .locked_status  = CLKGEN_FIELD(0x6C,    0x1,                    0),
+       .ndiv           = CLKGEN_FIELD(0x0,     C32_NDIV_MASK,          9),
+       .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           22),
+       .num_odfs = 1,
+       .odf =          { CLKGEN_FIELD(0x0,     C32_ODF_MASK,           3) },
+       .odf_gate =     { CLKGEN_FIELD(0x0,     0x1,                    28) },
+       .ops            = &stm_pll3200c32_ops,
+};
+
+static struct clkgen_pll_data st_pll3200c32_ddr_415 = {
+       .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .locked_status  = CLKGEN_FIELD(0x100,   0x1,                    0),
+       .ndiv           = CLKGEN_FIELD(0x8,     C32_NDIV_MASK,          0),
+       .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           25),
+       .num_odfs = 2,
+       .odf            = { CLKGEN_FIELD(0x8,   C32_ODF_MASK,           8),
+                           CLKGEN_FIELD(0x8,   C32_ODF_MASK,           14) },
+       .odf_gate       = { CLKGEN_FIELD(0x4,   0x1,                    28),
+                           CLKGEN_FIELD(0x4,   0x1,                    29) },
+       .ops            = &stm_pll3200c32_ops,
+};
+
+static struct clkgen_pll_data st_pll1200c32_gpu_415 = {
+       .pdn_status     = CLKGEN_FIELD(0x144,   0x1,                    3),
+       .locked_status  = CLKGEN_FIELD(0x168,   0x1,                    0),
+       .ldf            = CLKGEN_FIELD(0x0,     C32_LDF_MASK,           3),
+       .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           0),
+       .num_odfs = 0,
+       .odf            = { CLKGEN_FIELD(0x0,   C32_ODF_MASK,           10) },
+       .ops            = &st_pll1200c32_ops,
+};
+
+/* 416 specific */
+static struct clkgen_pll_data st_pll3200c32_a9_416 = {
+       .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .locked_status  = CLKGEN_FIELD(0x6C,    0x1,                    0),
+       .ndiv           = CLKGEN_FIELD(0x8,     C32_NDIV_MASK,          0),
+       .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           25),
+       .num_odfs = 1,
+       .odf            = { CLKGEN_FIELD(0x8,   C32_ODF_MASK,           8) },
+       .odf_gate       = { CLKGEN_FIELD(0x4,   0x1,                    28) },
+       .ops            = &stm_pll3200c32_ops,
+};
+
+static struct clkgen_pll_data st_pll3200c32_ddr_416 = {
+       .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .locked_status  = CLKGEN_FIELD(0x10C,   0x1,                    0),
+       .ndiv           = CLKGEN_FIELD(0x8,     C32_NDIV_MASK,          0),
+       .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           25),
+       .num_odfs = 2,
+       .odf            = { CLKGEN_FIELD(0x8,   C32_ODF_MASK,           8),
+                           CLKGEN_FIELD(0x8,   C32_ODF_MASK,           14) },
+       .odf_gate       = { CLKGEN_FIELD(0x4,   0x1,                    28),
+                           CLKGEN_FIELD(0x4,   0x1,                    29) },
+       .ops            = &stm_pll3200c32_ops,
+};
+
+static struct clkgen_pll_data st_pll1200c32_gpu_416 = {
+       .pdn_status     = CLKGEN_FIELD(0x8E4,   0x1,                    3),
+       .locked_status  = CLKGEN_FIELD(0x90C,   0x1,                    0),
+       .ldf            = CLKGEN_FIELD(0x0,     C32_LDF_MASK,           3),
+       .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           0),
+       .num_odfs = 0,
+       .odf            = { CLKGEN_FIELD(0x0,   C32_ODF_MASK,           10) },
+       .ops            = &st_pll1200c32_ops,
+};
+
+/**
+ * DOC: Clock Generated by PLL, rate set and enabled by bootloader
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable/disable only ensures parent is enabled
+ * rate - rate is fixed. No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+/**
+ * PLL clock that is integrated in the ClockGenA instances on the STiH415
+ * and STiH416.
+ *
+ * @hw: handle between common and hardware-specific interfaces.
+ * @type: PLL instance type.
+ * @regs_base: base of the PLL configuration register(s).
+ *
+ */
+struct clkgen_pll {
+       struct clk_hw           hw;
+       struct clkgen_pll_data  *data;
+       void __iomem            *regs_base;
+};
+
+#define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
+
+static int clkgen_pll_is_locked(struct clk_hw *hw)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       u32 locked = CLKGEN_READ(pll, locked_status);
+
+       return !!locked;
+}
+
+static int clkgen_pll_is_enabled(struct clk_hw *hw)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       u32 poweroff = CLKGEN_READ(pll, pdn_status);
+       return !poweroff;
+}
+
+unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       unsigned long mdiv, ndiv, pdiv;
+       unsigned long rate;
+       uint64_t res;
+
+       if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
+               return 0;
+
+       pdiv = CLKGEN_READ(pll, pdiv);
+       mdiv = CLKGEN_READ(pll, mdiv);
+       ndiv = CLKGEN_READ(pll, ndiv);
+
+       if (!mdiv)
+               mdiv++; /* mdiv=0 or 1 => MDIV=1 */
+
+       res = (uint64_t)2 * (uint64_t)parent_rate * (uint64_t)ndiv;
+       rate = (unsigned long)div64_u64(res, mdiv * (1 << pdiv));
+
+       pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+       return rate;
+
+}
+
+unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       unsigned long mdiv, ndiv;
+       unsigned long rate;
+
+       if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
+               return 0;
+
+       mdiv = CLKGEN_READ(pll, mdiv);
+       ndiv = CLKGEN_READ(pll, ndiv);
+
+       if (!mdiv)
+               mdiv = 1;
+
+       /* Note: input is divided by 1000 to avoid overflow */
+       rate = ((2 * (parent_rate / 1000) * ndiv) / mdiv) * 1000;
+
+       pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+       return rate;
+}
+
+unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       unsigned long ndiv, idf;
+       unsigned long rate = 0;
+
+       if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
+               return 0;
+
+       ndiv = CLKGEN_READ(pll, ndiv);
+       idf = CLKGEN_READ(pll, idf);
+
+       if (idf)
+               /* Note: input is divided to avoid overflow */
+               rate = ((2 * (parent_rate/1000) * ndiv) / idf) * 1000;
+
+       pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+       return rate;
+}
+
+unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       unsigned long odf, ldf, idf;
+       unsigned long rate;
+
+       if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
+               return 0;
+
+       odf = CLKGEN_READ(pll, odf[0]);
+       ldf = CLKGEN_READ(pll, ldf);
+       idf = CLKGEN_READ(pll, idf);
+
+       if (!idf) /* idf==0 means 1 */
+               idf = 1;
+       if (!odf) /* odf==0 means 1 */
+               odf = 1;
+
+       /* Note: input is divided by 1000 to avoid overflow */
+       rate = (((parent_rate / 1000) * ldf) / (odf * idf)) * 1000;
+
+       pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+       return rate;
+}
+
+static const struct clk_ops st_pll1600c65_ops = {
+       .is_enabled     = clkgen_pll_is_enabled,
+       .recalc_rate    = recalc_stm_pll1600c65,
+};
+
+static const struct clk_ops st_pll800c65_ops = {
+       .is_enabled     = clkgen_pll_is_enabled,
+       .recalc_rate    = recalc_stm_pll800c65,
+};
+
+static const struct clk_ops stm_pll3200c32_ops = {
+       .is_enabled     = clkgen_pll_is_enabled,
+       .recalc_rate    = recalc_stm_pll3200c32,
+};
+
+static const struct clk_ops st_pll1200c32_ops = {
+       .is_enabled     = clkgen_pll_is_enabled,
+       .recalc_rate    = recalc_stm_pll1200c32,
+};
+
+static struct clk * __init clkgen_pll_register(const char *parent_name,
+                               struct clkgen_pll_data  *pll_data,
+                               void __iomem *reg,
+                               const char *clk_name)
+{
+       struct clkgen_pll *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = clk_name;
+       init.ops = pll_data->ops;
+
+       init.flags = CLK_IS_BASIC;
+       init.parent_names = &parent_name;
+       init.num_parents  = 1;
+
+       pll->data = pll_data;
+       pll->regs_base = reg;
+       pll->hw.init = &init;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               kfree(pll);
+               return clk;
+       }
+
+       pr_debug("%s: parent %s rate %lu\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       clk_get_rate(clk));
+
+       return clk;
+}
+
+static struct clk * __init clkgen_c65_lsdiv_register(const char *parent_name,
+                                                    const char *clk_name)
+{
+       struct clk *clk;
+
+       clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 1, 2);
+       if (IS_ERR(clk))
+               return clk;
+
+       pr_debug("%s: parent %s rate %lu\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       clk_get_rate(clk));
+       return clk;
+}
+
+static void __iomem * __init clkgen_get_register_base(
+                               struct device_node *np)
+{
+       struct device_node *pnode;
+       void __iomem *reg = NULL;
+
+       pnode = of_get_parent(np);
+       if (!pnode)
+               return NULL;
+
+       reg = of_iomap(pnode, 0);
+
+       of_node_put(pnode);
+       return reg;
+}
+
+#define CLKGENAx_PLL0_OFFSET 0x0
+#define CLKGENAx_PLL1_OFFSET 0x4
+
+static void __init clkgena_c65_pll_setup(struct device_node *np)
+{
+       const int num_pll_outputs = 3;
+       struct clk_onecell_data *clk_data;
+       const char *parent_name;
+       void __iomem *reg;
+       const char *clk_name;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       reg = clkgen_get_register_base(np);
+       if (!reg)
+               return;
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return;
+
+       clk_data->clk_num = num_pll_outputs;
+       clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
+                                GFP_KERNEL);
+
+       if (!clk_data->clks)
+               goto err;
+
+       if (of_property_read_string_index(np, "clock-output-names",
+                                         0, &clk_name))
+               goto err;
+
+       /*
+        * PLL0 HS (high speed) output
+        */
+       clk_data->clks[0] = clkgen_pll_register(parent_name,
+                                               &st_pll1600c65_ax,
+                                               reg + CLKGENAx_PLL0_OFFSET,
+                                               clk_name);
+
+       if (IS_ERR(clk_data->clks[0]))
+               goto err;
+
+       if (of_property_read_string_index(np, "clock-output-names",
+                                         1, &clk_name))
+               goto err;
+
+       /*
+        * PLL0 LS (low speed) output, which is a fixed divide by 2 of the
+        * high speed output.
+        */
+       clk_data->clks[1] = clkgen_c65_lsdiv_register(__clk_get_name
+                                                     (clk_data->clks[0]),
+                                                     clk_name);
+
+       if (IS_ERR(clk_data->clks[1]))
+               goto err;
+
+       if (of_property_read_string_index(np, "clock-output-names",
+                                         2, &clk_name))
+               goto err;
+
+       /*
+        * PLL1 output
+        */
+       clk_data->clks[2] = clkgen_pll_register(parent_name,
+                                               &st_pll800c65_ax,
+                                               reg + CLKGENAx_PLL1_OFFSET,
+                                               clk_name);
+
+       if (IS_ERR(clk_data->clks[2]))
+               goto err;
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+       return;
+
+err:
+       kfree(clk_data->clks);
+       kfree(clk_data);
+}
+CLK_OF_DECLARE(clkgena_c65_plls,
+              "st,clkgena-plls-c65", clkgena_c65_pll_setup);
+
+static struct clk * __init clkgen_odf_register(const char *parent_name,
+                                              void * __iomem reg,
+                                              struct clkgen_pll_data *pll_data,
+                                              int odf,
+                                              spinlock_t *odf_lock,
+                                              const char *odf_name)
+{
+       struct clk *clk;
+       unsigned long flags;
+       struct clk_gate *gate;
+       struct clk_divider *div;
+
+       flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE;
+
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       gate->flags = CLK_GATE_SET_TO_DISABLE;
+       gate->reg = reg + pll_data->odf_gate[odf].offset;
+       gate->bit_idx = pll_data->odf_gate[odf].shift;
+       gate->lock = odf_lock;
+
+       div = kzalloc(sizeof(*div), GFP_KERNEL);
+       if (!div)
+               return ERR_PTR(-ENOMEM);
+
+       div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+       div->reg = reg + pll_data->odf[odf].offset;
+       div->shift = pll_data->odf[odf].shift;
+       div->width = fls(pll_data->odf[odf].mask);
+       div->lock = odf_lock;
+
+       clk = clk_register_composite(NULL, odf_name, &parent_name, 1,
+                                    NULL, NULL,
+                                    &div->hw, &clk_divider_ops,
+                                    &gate->hw, &clk_gate_ops,
+                                    flags);
+       if (IS_ERR(clk))
+               return clk;
+
+       pr_debug("%s: parent %s rate %lu\n",
+                       __clk_get_name(clk),
+                       __clk_get_name(clk_get_parent(clk)),
+                       clk_get_rate(clk));
+       return clk;
+}
+
+static struct of_device_id c32_pll_of_match[] = {
+       {
+               .compatible = "st,plls-c32-a1x-0",
+               .data = &st_pll3200c32_a1x_0,
+       },
+       {
+               .compatible = "st,plls-c32-a1x-1",
+               .data = &st_pll3200c32_a1x_1,
+       },
+       {
+               .compatible = "st,stih415-plls-c32-a9",
+               .data = &st_pll3200c32_a9_415,
+       },
+       {
+               .compatible = "st,stih415-plls-c32-ddr",
+               .data = &st_pll3200c32_ddr_415,
+       },
+       {
+               .compatible = "st,stih416-plls-c32-a9",
+               .data = &st_pll3200c32_a9_416,
+       },
+       {
+               .compatible = "st,stih416-plls-c32-ddr",
+               .data = &st_pll3200c32_ddr_416,
+       },
+       {}
+};
+
+static void __init clkgen_c32_pll_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       struct clk *clk;
+       const char *parent_name, *pll_name;
+       void __iomem *pll_base;
+       int num_odfs, odf;
+       struct clk_onecell_data *clk_data;
+       struct clkgen_pll_data  *data;
+
+       match = of_match_node(c32_pll_of_match, np);
+       if (!match) {
+               pr_err("%s: No matching data\n", __func__);
+               return;
+       }
+
+       data = (struct clkgen_pll_data *) match->data;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       pll_base = clkgen_get_register_base(np);
+       if (!pll_base)
+               return;
+
+       clk = clkgen_pll_register(parent_name, data, pll_base, np->name);
+       if (IS_ERR(clk))
+               return;
+
+       pll_name = __clk_get_name(clk);
+
+       num_odfs = data->num_odfs;
+
+       clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return;
+
+       clk_data->clk_num = num_odfs;
+       clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
+                                GFP_KERNEL);
+
+       if (!clk_data->clks)
+               goto err;
+
+       for (odf = 0; odf < num_odfs; odf++) {
+               struct clk *clk;
+               const char *clk_name;
+
+               if (of_property_read_string_index(np, "clock-output-names",
+                                                 odf, &clk_name))
+                       return;
+
+               clk = clkgen_odf_register(pll_name, pll_base, data,
+                               odf, &clkgena_c32_odf_lock, clk_name);
+               if (IS_ERR(clk))
+                       goto err;
+
+               clk_data->clks[odf] = clk;
+       }
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+       return;
+
+err:
+       kfree(pll_name);
+       kfree(clk_data->clks);
+       kfree(clk_data);
+}
+CLK_OF_DECLARE(clkgen_c32_pll, "st,clkgen-plls-c32", clkgen_c32_pll_setup);
+
+static struct of_device_id c32_gpu_pll_of_match[] = {
+       {
+               .compatible = "st,stih415-gpu-pll-c32",
+               .data = &st_pll1200c32_gpu_415,
+       },
+       {
+               .compatible = "st,stih416-gpu-pll-c32",
+               .data = &st_pll1200c32_gpu_416,
+       },
+};
+
+static void __init clkgengpu_c32_pll_setup(struct device_node *np)
+{
+       const struct of_device_id *match;
+       struct clk *clk;
+       const char *parent_name;
+       void __iomem *reg;
+       const char *clk_name;
+       struct clkgen_pll_data  *data;
+
+       match = of_match_node(c32_gpu_pll_of_match, np);
+       if (!match) {
+               pr_err("%s: No matching data\n", __func__);
+               return;
+       }
+
+       data = (struct clkgen_pll_data *)match->data;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       reg = clkgen_get_register_base(np);
+       if (!reg)
+               return;
+
+       if (of_property_read_string_index(np, "clock-output-names",
+                                         0, &clk_name))
+               return;
+
+       /*
+        * PLL 1200MHz output
+        */
+       clk = clkgen_pll_register(parent_name, data, reg, clk_name);
+
+       if (!IS_ERR(clk))
+               of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+       return;
+}
+CLK_OF_DECLARE(clkgengpu_c32_pll,
+              "st,clkgengpu-pll-c32", clkgengpu_c32_pll_setup);
diff --git a/drivers/clk/st/clkgen.h b/drivers/clk/st/clkgen.h
new file mode 100644 (file)
index 0000000..35c8632
--- /dev/null
@@ -0,0 +1,48 @@
+/************************************************************************
+File  : Clock H/w specific Information
+
+Author: Pankaj Dev <pankaj.dev@st.com>
+
+Copyright (C) 2014 STMicroelectronics
+************************************************************************/
+
+#ifndef __CLKGEN_INFO_H
+#define __CLKGEN_INFO_H
+
+struct clkgen_field {
+       unsigned int offset;
+       unsigned int mask;
+       unsigned int shift;
+};
+
+static inline unsigned long clkgen_read(void __iomem   *base,
+                                         struct clkgen_field *field)
+{
+       return (readl(base + field->offset) >> field->shift) & field->mask;
+}
+
+
+static inline void clkgen_write(void __iomem *base, struct clkgen_field *field,
+                                 unsigned long val)
+{
+       writel((readl(base + field->offset) &
+              ~(field->mask << field->shift)) | (val << field->shift),
+              base + field->offset);
+
+       return;
+}
+
+#define CLKGEN_FIELD(_offset, _mask, _shift) {         \
+                               .offset = _offset,      \
+                               .mask   = _mask,        \
+                               .shift  = _shift,       \
+                               }
+
+#define CLKGEN_READ(pll, field) clkgen_read(pll->regs_base, \
+               &pll->data->field)
+
+#define CLKGEN_WRITE(pll, field, val) clkgen_write(pll->regs_base, \
+               &pll->data->field, val)
+
+#endif /*__CLKGEN_INFO_H*/
+
index abb6c5ac8a10297505a8a7f1cb1cb0d5f8eccf16..bd7dc733c1ca52170c2a5fd6418770794630235b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/clkdev.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/reset-controller.h>
 
 #include "clk-factors.h"
 
@@ -51,6 +52,8 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
        if (!gate)
                goto err_free_fixed;
 
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
        /* set up gate and fixed rate properties */
        gate->reg = of_iomap(node, 0);
        gate->bit_idx = SUNXI_OSC24M_GATE;
@@ -77,7 +80,7 @@ err_free_gate:
 err_free_fixed:
        kfree(fixed);
 }
-CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup);
+CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-a10-osc-clk", sun4i_osc_clk_setup);
 
 
 
@@ -249,7 +252,38 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
        *n = DIV_ROUND_UP(div, (*k+1));
 }
 
+/**
+ * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6
+ * PLL6 rate is calculated as follows
+ * rate = parent_rate * n * (k + 1) / 2
+ * parent_rate is always 24Mhz
+ */
+
+static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
+                                      u8 *n, u8 *k, u8 *m, u8 *p)
+{
+       u8 div;
+
+       /*
+        * We always have 24MHz / 2, so we can just say that our
+        * parent clock is 12MHz.
+        */
+       parent_rate = parent_rate / 2;
 
+       /* Normalize value to a parent_rate multiple (24M / 2) */
+       div = *freq / parent_rate;
+       *freq = parent_rate * div;
+
+       /* we were called to round the frequency, we can now return */
+       if (n == NULL)
+               return;
+
+       *k = div / 32;
+       if (*k > 3)
+               *k = 3;
+
+       *n = DIV_ROUND_UP(div, (*k+1));
+}
 
 /**
  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
@@ -265,7 +299,7 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
        if (parent_rate < *freq)
                *freq = parent_rate;
 
-       parent_rate = (parent_rate + (*freq - 1)) / *freq;
+       parent_rate = DIV_ROUND_UP(parent_rate, *freq);
 
        /* Invalid rate! */
        if (parent_rate > 32)
@@ -296,7 +330,7 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
 
 /**
  * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
- * MMC rate is calculated as follows
+ * MOD0 rate is calculated as follows
  * rate = (parent_rate >> p) / (m + 1);
  */
 
@@ -310,7 +344,7 @@ static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
        if (*freq > parent_rate)
                *freq = parent_rate;
 
-       div = parent_rate / *freq;
+       div = DIV_ROUND_UP(parent_rate, *freq);
 
        if (div < 16)
                calcp = 0;
@@ -351,7 +385,7 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
        if (*freq > parent_rate)
                *freq = parent_rate;
 
-       div = parent_rate / *freq;
+       div = DIV_ROUND_UP(parent_rate, *freq);
 
        if (div < 32)
                calcp = 0;
@@ -376,6 +410,102 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
 
 
 
+/**
+ * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module
+ *
+ * This clock looks something like this
+ *                               ________________________
+ *  MII TX clock from PHY >-----|___________    _________|----> to GMAC core
+ *  GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY
+ *  Ext. 125MHz RGMII TX clk >--|__divider__/            |
+ *                              |________________________|
+ *
+ * The external 125 MHz reference is optional, i.e. GMAC can use its
+ * internal TX clock just fine. The A31 GMAC clock module does not have
+ * the divider controls for the external reference.
+ *
+ * To keep it simple, let the GMAC use either the MII TX clock for MII mode,
+ * and its internal TX clock for GMII and RGMII modes. The GMAC driver should
+ * select the appropriate source and gate/ungate the output to the PHY.
+ *
+ * Only the GMAC should use this clock. Altering the clock so that it doesn't
+ * match the GMAC's operation parameters will result in the GMAC not being
+ * able to send traffic out. The GMAC driver should set the clock rate and
+ * enable/disable this clock to configure the required state. The clock
+ * driver then responds by auto-reparenting the clock.
+ */
+
+#define SUN7I_A20_GMAC_GPIT    2
+#define SUN7I_A20_GMAC_MASK    0x3
+#define SUN7I_A20_GMAC_PARENTS 2
+
+static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
+{
+       struct clk *clk;
+       struct clk_mux *mux;
+       struct clk_gate *gate;
+       const char *clk_name = node->name;
+       const char *parents[SUN7I_A20_GMAC_PARENTS];
+       void *reg;
+
+       if (of_property_read_string(node, "clock-output-names", &clk_name))
+               return;
+
+       /* allocate mux and gate clock structs */
+       mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+       if (!mux)
+               return;
+
+       gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+       if (!gate)
+               goto free_mux;
+
+       /* gmac clock requires exactly 2 parents */
+       parents[0] = of_clk_get_parent_name(node, 0);
+       parents[1] = of_clk_get_parent_name(node, 1);
+       if (!parents[0] || !parents[1])
+               goto free_gate;
+
+       reg = of_iomap(node, 0);
+       if (!reg)
+               goto free_gate;
+
+       /* set up gate and fixed rate properties */
+       gate->reg = reg;
+       gate->bit_idx = SUN7I_A20_GMAC_GPIT;
+       gate->lock = &clk_lock;
+       mux->reg = reg;
+       mux->mask = SUN7I_A20_GMAC_MASK;
+       mux->flags = CLK_MUX_INDEX_BIT;
+       mux->lock = &clk_lock;
+
+       clk = clk_register_composite(NULL, clk_name,
+                       parents, SUN7I_A20_GMAC_PARENTS,
+                       &mux->hw, &clk_mux_ops,
+                       NULL, NULL,
+                       &gate->hw, &clk_gate_ops,
+                       0);
+
+       if (IS_ERR(clk))
+               goto iounmap_reg;
+
+       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       clk_register_clkdev(clk, clk_name, NULL);
+
+       return;
+
+iounmap_reg:
+       iounmap(reg);
+free_gate:
+       kfree(gate);
+free_mux:
+       kfree(mux);
+}
+CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk",
+               sun7i_a20_gmac_clk_setup);
+
+
+
 /**
  * sunxi_factors_clk_setup() - Setup function for factor clocks
  */
@@ -387,6 +517,7 @@ struct factors_data {
        int mux;
        struct clk_factors_config *table;
        void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
+       const char *name;
 };
 
 static struct clk_factors_config sun4i_pll1_config = {
@@ -416,6 +547,13 @@ static struct clk_factors_config sun4i_pll5_config = {
        .kwidth = 2,
 };
 
+static struct clk_factors_config sun6i_a31_pll6_config = {
+       .nshift = 8,
+       .nwidth = 5,
+       .kshift = 4,
+       .kwidth = 2,
+};
+
 static struct clk_factors_config sun4i_apb1_config = {
        .mshift = 0,
        .mwidth = 5,
@@ -451,10 +589,30 @@ static const struct factors_data sun6i_a31_pll1_data __initconst = {
        .getter = sun6i_a31_get_pll1_factors,
 };
 
+static const struct factors_data sun7i_a20_pll4_data __initconst = {
+       .enable = 31,
+       .table = &sun4i_pll5_config,
+       .getter = sun4i_get_pll5_factors,
+};
+
 static const struct factors_data sun4i_pll5_data __initconst = {
        .enable = 31,
        .table = &sun4i_pll5_config,
        .getter = sun4i_get_pll5_factors,
+       .name = "pll5",
+};
+
+static const struct factors_data sun4i_pll6_data __initconst = {
+       .enable = 31,
+       .table = &sun4i_pll5_config,
+       .getter = sun4i_get_pll5_factors,
+       .name = "pll6",
+};
+
+static const struct factors_data sun6i_a31_pll6_data __initconst = {
+       .enable = 31,
+       .table = &sun6i_a31_pll6_config,
+       .getter = sun6i_a31_get_pll6_factors,
 };
 
 static const struct factors_data sun4i_apb1_data __initconst = {
@@ -497,14 +655,14 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
               (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
                i++;
 
-       /* Nodes should be providing the name via clock-output-names
-        * but originally our dts didn't, and so we used node->name.
-        * The new, better nodes look like clk@deadbeef, so we pull the
-        * name just in this case */
-       if (!strcmp("clk", clk_name)) {
-               of_property_read_string_index(node, "clock-output-names",
-                                             0, &clk_name);
-       }
+       /*
+        * some factor clocks, such as pll5 and pll6, may have multiple
+        * outputs, and have their name designated in factors_data
+        */
+       if (data->name)
+               clk_name = data->name;
+       else
+               of_property_read_string(node, "clock-output-names", &clk_name);
 
        factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
        if (!factors)
@@ -601,6 +759,8 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
               (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
                i++;
 
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
        clk = clk_register_mux(NULL, clk_name, parents, i,
                               CLK_SET_RATE_NO_REPARENT, reg,
                               data->shift, SUNXI_MUX_GATE_WIDTH,
@@ -660,6 +820,8 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
 
        clk_parent = of_clk_get_parent_name(node, 0);
 
+       of_property_read_string(node, "clock-output-names", &clk_name);
+
        clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
                                   reg, data->shift, data->width,
                                   data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
@@ -672,6 +834,59 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
 
 
 
+/**
+ * sunxi_gates_reset... - reset bits in leaf gate clk registers handling
+ */
+
+struct gates_reset_data {
+       void __iomem                    *reg;
+       spinlock_t                      *lock;
+       struct reset_controller_dev     rcdev;
+};
+
+static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev,
+                             unsigned long id)
+{
+       struct gates_reset_data *data = container_of(rcdev,
+                                                    struct gates_reset_data,
+                                                    rcdev);
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(data->lock, flags);
+
+       reg = readl(data->reg);
+       writel(reg & ~BIT(id), data->reg);
+
+       spin_unlock_irqrestore(data->lock, flags);
+
+       return 0;
+}
+
+static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       struct gates_reset_data *data = container_of(rcdev,
+                                                    struct gates_reset_data,
+                                                    rcdev);
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(data->lock, flags);
+
+       reg = readl(data->reg);
+       writel(reg | BIT(id), data->reg);
+
+       spin_unlock_irqrestore(data->lock, flags);
+
+       return 0;
+}
+
+static struct reset_control_ops sunxi_gates_reset_ops = {
+       .assert         = sunxi_gates_reset_assert,
+       .deassert       = sunxi_gates_reset_deassert,
+};
+
 /**
  * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
  */
@@ -680,6 +895,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
 
 struct gates_data {
        DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
+       u32 reset_mask;
 };
 
 static const struct gates_data sun4i_axi_gates_data __initconst = {
@@ -746,10 +962,21 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
        .mask = { 0xff80ff },
 };
 
+static const struct gates_data sun4i_a10_usb_gates_data __initconst = {
+       .mask = {0x1C0},
+       .reset_mask = 0x07,
+};
+
+static const struct gates_data sun5i_a13_usb_gates_data __initconst = {
+       .mask = {0x140},
+       .reset_mask = 0x03,
+};
+
 static void __init sunxi_gates_clk_setup(struct device_node *node,
                                         struct gates_data *data)
 {
        struct clk_onecell_data *clk_data;
+       struct gates_reset_data *reset_data;
        const char *clk_parent;
        const char *clk_name;
        void *reg;
@@ -793,6 +1020,21 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
        clk_data->clk_num = i;
 
        of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       /* Register a reset controler for gates with reset bits */
+       if (data->reset_mask == 0)
+               return;
+
+       reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
+       if (!reset_data)
+               return;
+
+       reset_data->reg = reg;
+       reset_data->lock = &clk_lock;
+       reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1;
+       reset_data->rcdev.ops = &sunxi_gates_reset_ops;
+       reset_data->rcdev.of_node = node;
+       reset_controller_register(&reset_data->rcdev);
 }
 
 
@@ -832,7 +1074,7 @@ static const struct divs_data pll5_divs_data __initconst = {
 };
 
 static const struct divs_data pll6_divs_data __initconst = {
-       .factors = &sun4i_pll5_data,
+       .factors = &sun4i_pll6_data,
        .div = {
                { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
                { .fixed = 2 }, /* P, other */
@@ -854,7 +1096,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
                                        struct divs_data *data)
 {
        struct clk_onecell_data *clk_data;
-       const char *parent  = node->name;
+       const char *parent;
        const char *clk_name;
        struct clk **clks, *pclk;
        struct clk_hw *gate_hw, *rate_hw;
@@ -868,6 +1110,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
 
        /* Set up factor clock that we will be dividing */
        pclk = sunxi_factors_clk_setup(node, data->factors);
+       parent = __clk_get_name(pclk);
 
        reg = of_iomap(node, 0);
 
@@ -970,56 +1213,60 @@ free_clkdata:
 
 /* Matches for factors clocks */
 static const struct of_device_id clk_factors_match[] __initconst = {
-       {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
+       {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,},
        {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
-       {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
-       {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
+       {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
+       {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
+       {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
+       {.compatible = "allwinner,sun4i-a10-mod0-clk", .data = &sun4i_mod0_data,},
        {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
        {}
 };
 
 /* Matches for divider clocks */
 static const struct of_device_id clk_div_match[] __initconst = {
-       {.compatible = "allwinner,sun4i-axi-clk", .data = &sun4i_axi_data,},
-       {.compatible = "allwinner,sun4i-ahb-clk", .data = &sun4i_ahb_data,},
-       {.compatible = "allwinner,sun4i-apb0-clk", .data = &sun4i_apb0_data,},
+       {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,},
+       {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,},
+       {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,},
        {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,},
        {}
 };
 
 /* Matches for divided outputs */
 static const struct of_device_id clk_divs_match[] __initconst = {
-       {.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,},
-       {.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,},
+       {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,},
+       {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,},
        {}
 };
 
 /* Matches for mux clocks */
 static const struct of_device_id clk_mux_match[] __initconst = {
-       {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
-       {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
+       {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,},
+       {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
        {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
        {}
 };
 
 /* Matches for gate clocks */
 static const struct of_device_id clk_gates_match[] __initconst = {
-       {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,},
-       {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
+       {.compatible = "allwinner,sun4i-a10-axi-gates-clk", .data = &sun4i_axi_gates_data,},
+       {.compatible = "allwinner,sun4i-a10-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
        {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
        {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
        {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
        {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
-       {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
+       {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
        {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
        {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
        {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,},
-       {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,},
+       {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,},
        {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,},
        {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
        {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
        {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
        {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
+       {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
+       {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
        {}
 };
 
index 356e9b804421ee7a27ba8a9cba960c3263260a10..9e899c18af8678c8eac70fab0ede9d8631fff3f3 100644 (file)
@@ -130,7 +130,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
        .disable = clk_periph_disable,
 };
 
-const struct clk_ops tegra_clk_periph_no_gate_ops = {
+static const struct clk_ops tegra_clk_periph_no_gate_ops = {
        .get_parent = clk_periph_get_parent,
        .set_parent = clk_periph_set_parent,
        .recalc_rate = clk_periph_recalc_rate,
index 776ee4594bd44aebe2c457ba40ed6aea8ddd81fd..028b33783d383c695a8c3ef6a467e09634094ad5 100644 (file)
@@ -34,7 +34,6 @@ static struct ti_dt_clk am33xx_clks[] = {
        DT_CLK(NULL, "dpll_core_m5_ck", "dpll_core_m5_ck"),
        DT_CLK(NULL, "dpll_core_m6_ck", "dpll_core_m6_ck"),
        DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
-       DT_CLK("cpu0", NULL, "dpll_mpu_ck"),
        DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
        DT_CLK(NULL, "dpll_ddr_ck", "dpll_ddr_ck"),
        DT_CLK(NULL, "dpll_ddr_m2_ck", "dpll_ddr_m2_ck"),
index d3230234f07b980e7de341d2ff8f2b4912a8d010..0d1750a8aea40db16a470c697418d1dbd8b6bb45 100644 (file)
@@ -130,10 +130,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
        DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
        DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
        DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"),
-       DT_CLK(NULL, "utmi_p1_gfclk", "dummy_ck"),
-       DT_CLK(NULL, "utmi_p2_gfclk", "dummy_ck"),
-       DT_CLK(NULL, "xclk60mhsp1_ck", "dummy_ck"),
-       DT_CLK(NULL, "xclk60mhsp2_ck", "dummy_ck"),
        DT_CLK(NULL, "init_60m_fclk", "dummy_ck"),
        DT_CLK(NULL, "gpt1_fck", "gpt1_fck"),
        DT_CLK(NULL, "aes2_ick", "aes2_ick"),
index ae00218b5da34a0c6f64a1c3be0353d9c0478cb7..02517a8206bda8eda55ef32aac17f8163dc2d064 100644 (file)
@@ -222,7 +222,6 @@ static struct ti_dt_clk omap44xx_clks[] = {
        DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"),
        DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"),
        DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"),
-       DT_CLK("50000000.gpmc", "fck", "dummy_ck"),
        DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
        DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
        DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
index 0ef9f581286bccf578500d08d19afee2a2537d3d..08f3d1b915b396d393e2a9bf0aa444784f39388d 100644 (file)
@@ -182,7 +182,6 @@ static struct ti_dt_clk omap54xx_clks[] = {
        DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"),
        DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"),
        DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"),
-       DT_CLK(NULL, "gpmc_ck", "dummy_ck"),
        DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
        DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
        DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
index 9977653f2d6317a3fa3894db38d6e1e3139bfc78..f7e40734c819f045caa9be5f5a32c299c7fa3344 100644 (file)
@@ -262,7 +262,6 @@ static struct ti_dt_clk dra7xx_clks[] = {
        DT_CLK(NULL, "vip1_gclk_mux", "vip1_gclk_mux"),
        DT_CLK(NULL, "vip2_gclk_mux", "vip2_gclk_mux"),
        DT_CLK(NULL, "vip3_gclk_mux", "vip3_gclk_mux"),
-       DT_CLK(NULL, "gpmc_ck", "dummy_ck"),
        DT_CLK("omap_i2c.1", "ick", "dummy_ck"),
        DT_CLK("omap_i2c.2", "ick", "dummy_ck"),
        DT_CLK("omap_i2c.3", "ick", "dummy_ck"),
index a15e445570b288afee9a8fb0db109b9f1fefb884..e6aa10db7bba1f78116ff6cd0b02a49b65bea857 100644 (file)
@@ -112,7 +112,7 @@ static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
                return parent_rate;
        }
 
-       return parent_rate / div;
+       return DIV_ROUND_UP(parent_rate, div);
 }
 
 /*
@@ -182,7 +182,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
                }
                parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
                                MULT_ROUND_UP(rate, i));
-               now = parent_rate / i;
+               now = DIV_ROUND_UP(parent_rate, i);
                if (now <= rate && now > best) {
                        bestdiv = i;
                        best = now;
@@ -205,7 +205,7 @@ static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
        int div;
        div = ti_clk_divider_bestdiv(hw, rate, prate);
 
-       return *prate / div;
+       return DIV_ROUND_UP(*prate, div);
 }
 
 static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -216,7 +216,7 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        unsigned long flags = 0;
        u32 val;
 
-       div = parent_rate / rate;
+       div = DIV_ROUND_UP(parent_rate, rate);
        value = _get_val(divider, div);
 
        if (value > div_mask(divider))
index cdeff299de26d3a78320022b3473c484bbb78faf..7b55ef89baa53c7ef6d59c19dcf8c9287b773199 100644 (file)
@@ -29,7 +29,8 @@ static struct clk *prcc_kclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_C
 #define PRCC_KCLK_STORE(clk, base, bit)        \
        prcc_kclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk
 
-struct clk *ux500_twocell_get(struct of_phandle_args *clkspec, void *data)
+static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec,
+                                    void *data)
 {
        struct clk **clk_data = data;
        unsigned int base, bit;
index 8cbfcf88fae3ed6eaabe1a7af8dd1d1c7fd33d27..a820b0cfcf576f0b2a0d724860461c8f22df508f 100644 (file)
@@ -33,7 +33,7 @@ struct clk_icst {
        struct clk_hw hw;
        void __iomem *vcoreg;
        void __iomem *lockreg;
-       const struct icst_params *params;
+       struct icst_params *params;
        unsigned long rate;
 };
 
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
        struct clk_icst *icst = to_icst(hw);
        struct icst_vco vco;
 
+       if (parent_rate)
+               icst->params->ref = parent_rate;
        vco = vco_get(icst->vcoreg);
        icst->rate = icst_hz(icst->params, vco);
        return icst->rate;
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_icst *icst = to_icst(hw);
        struct icst_vco vco;
 
+       if (parent_rate)
+               icst->params->ref = parent_rate;
        vco = icst_hz_to_vco(icst->params, rate);
        icst->rate = icst_hz(icst->params, vco);
        vco_set(icst->lockreg, icst->vcoreg, vco);
@@ -120,24 +124,33 @@ static const struct clk_ops icst_ops = {
 struct clk *icst_clk_register(struct device *dev,
                        const struct clk_icst_desc *desc,
                        const char *name,
+                       const char *parent_name,
                        void __iomem *base)
 {
        struct clk *clk;
        struct clk_icst *icst;
        struct clk_init_data init;
+       struct icst_params *pclone;
 
        icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
        if (!icst) {
                pr_err("could not allocate ICST clock!\n");
                return ERR_PTR(-ENOMEM);
        }
+
+       pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
+       if (!pclone) {
+               pr_err("could not clone ICST params\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
        init.name = name;
        init.ops = &icst_ops;
        init.flags = CLK_IS_ROOT;
-       init.parent_names = NULL;
-       init.num_parents = 0;
+       init.parent_names = (parent_name ? &parent_name : NULL);
+       init.num_parents = (parent_name ? 1 : 0);
        icst->hw.init = &init;
-       icst->params = desc->params;
+       icst->params = pclone;
        icst->vcoreg = base + desc->vco_offset;
        icst->lockreg = base + desc->lock_offset;
 
index be99dd0da7850ee7c35ce2c09e871fb71bb355a8..04e6f0aef5889ad260aaced2b427f7487240dd37 100644 (file)
@@ -16,4 +16,5 @@ struct clk_icst_desc {
 struct clk *icst_clk_register(struct device *dev,
                              const struct clk_icst_desc *desc,
                              const char *name,
+                             const char *parent_name,
                              void __iomem *base);
index 844f8d711a1271ab85265d373e530919807081c7..31b44f025f9e2af0a85941f71b8a6d006d806346 100644 (file)
 #include <linux/io.h>
 #include <linux/platform_data/clk-integrator.h>
 
-#include <mach/impd1.h>
-
 #include "clk-icst.h"
 
+#define IMPD1_OSC1     0x00
+#define IMPD1_OSC2     0x04
+#define IMPD1_LOCK     0x08
+
 struct impd1_clk {
        char *vco1name;
        struct clk *vco1clk;
@@ -93,13 +95,15 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
        imc = &impd1_clks[id];
 
        imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id);
-       clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base);
+       clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL,
+                               base);
        imc->vco1clk = clk;
        imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
 
        /* VCO2 is also called "CLK2" */
        imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id);
-       clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base);
+       clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, NULL,
+                               base);
        imc->vco2clk = clk;
 
        /* MMCI uses CLK2 right off */
index bda8967e09c25efb24c586892ba85cad89945e67..734c4b8fe6ab848abadf42765289bdbfb341399f 100644 (file)
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/err.h>
-#include <linux/platform_data/clk-integrator.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include "clk-icst.h"
 
-/*
- * Implementation of the ARM Integrator/AP and Integrator/CP clock tree.
- * Inspired by portions of:
- * plat-versatile/clock.c and plat-versatile/include/plat/clock.h
- */
+#define INTEGRATOR_HDR_LOCK_OFFSET     0x14
 
-static const struct icst_params cp_auxvco_params = {
-       .ref            = 24000000,
+/* Base offset for the core module */
+static void __iomem *cm_base;
+
+static const struct icst_params cp_auxosc_params = {
        .vco_max        = ICST525_VCO_MAX_5V,
        .vco_min        = ICST525_VCO_MIN,
        .vd_min         = 8,
@@ -35,50 +31,39 @@ static const struct icst_params cp_auxvco_params = {
        .idx2s          = icst525_idx2s,
 };
 
-static const struct clk_icst_desc __initdata cp_icst_desc = {
-       .params = &cp_auxvco_params,
+static const struct clk_icst_desc __initdata cm_auxosc_desc = {
+       .params = &cp_auxosc_params,
        .vco_offset = 0x1c,
        .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
 };
 
-/*
- * integrator_clk_init() - set up the integrator clock tree
- * @is_cp: pass true if it's the Integrator/CP else AP is assumed
- */
-void __init integrator_clk_init(bool is_cp)
+static void __init of_integrator_cm_osc_setup(struct device_node *np)
 {
-       struct clk *clk;
-
-       /* APB clock dummy */
-       clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
-       clk_register_clkdev(clk, "apb_pclk", NULL);
-
-       /* UART reference clock */
-       clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT,
-                               14745600);
-       clk_register_clkdev(clk, NULL, "uart0");
-       clk_register_clkdev(clk, NULL, "uart1");
-       if (is_cp)
-               clk_register_clkdev(clk, NULL, "mmci");
-
-       /* 24 MHz clock */
-       clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT,
-                               24000000);
-       clk_register_clkdev(clk, NULL, "kmi0");
-       clk_register_clkdev(clk, NULL, "kmi1");
-       if (!is_cp)
-               clk_register_clkdev(clk, NULL, "ap_timer");
+       struct clk *clk = ERR_PTR(-EINVAL);
+       const char *clk_name = np->name;
+       const struct clk_icst_desc *desc = &cm_auxosc_desc;
+       const char *parent_name;
 
-       if (!is_cp)
-               return;
+       if (!cm_base) {
+               /* Remap the core module base if not done yet */
+               struct device_node *parent;
 
-       /* 1 MHz clock */
-       clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT,
-                               1000000);
-       clk_register_clkdev(clk, NULL, "sp804");
+               parent = of_get_parent(np);
+               if (!np) {
+                       pr_err("no parent on core module clock\n");
+                       return;
+               }
+               cm_base = of_iomap(parent, 0);
+               if (!cm_base) {
+                       pr_err("could not remap core module base\n");
+                       return;
+               }
+       }
 
-       /* ICST VCO clock used on the Integrator/CP CLCD */
-       clk = icst_clk_register(NULL, &cp_icst_desc, "icst",
-                               __io_address(INTEGRATOR_HDR_BASE));
-       clk_register_clkdev(clk, NULL, "clcd");
+       parent_name = of_clk_get_parent_name(np, 0);
+       clk = icst_clk_register(NULL, desc, clk_name, parent_name, cm_base);
+       if (!IS_ERR(clk))
+               of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
+CLK_OF_DECLARE(integrator_cm_auxosc_clk,
+       "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);
index 747e7b31117cb6c0dd84eaa6a984e512f8ac406b..c8b523117fb7ed4e971b5582f802cab0fb7c0eee 100644 (file)
@@ -85,10 +85,10 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
        /* ICST VCO clock */
        if (is_pb1176)
                clk = icst_clk_register(NULL, &realview_osc0_desc,
-                                       "osc0", sysbase);
+                                       "osc0", NULL, sysbase);
        else
                clk = icst_clk_register(NULL, &realview_osc4_desc,
-                                       "osc4", sysbase);
+                                       "osc4", NULL, sysbase);
 
        clk_register_clkdev(clk, NULL, "dev:clcd");
        clk_register_clkdev(clk, NULL, "issp:clcd");
index 09dd0173ea0ae616dc4395f2b76724740310522c..52c09afdcfb724d9c7206c23233b46364cf1b28a 100644 (file)
 #include <linux/clk/zynq.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/io.h>
 
-static void __iomem *zynq_slcr_base_priv;
-
-#define SLCR_ARMPLL_CTRL               (zynq_slcr_base_priv + 0x100)
-#define SLCR_DDRPLL_CTRL               (zynq_slcr_base_priv + 0x104)
-#define SLCR_IOPLL_CTRL                        (zynq_slcr_base_priv + 0x108)
-#define SLCR_PLL_STATUS                        (zynq_slcr_base_priv + 0x10c)
-#define SLCR_ARM_CLK_CTRL              (zynq_slcr_base_priv + 0x120)
-#define SLCR_DDR_CLK_CTRL              (zynq_slcr_base_priv + 0x124)
-#define SLCR_DCI_CLK_CTRL              (zynq_slcr_base_priv + 0x128)
-#define SLCR_APER_CLK_CTRL             (zynq_slcr_base_priv + 0x12c)
-#define SLCR_GEM0_CLK_CTRL             (zynq_slcr_base_priv + 0x140)
-#define SLCR_GEM1_CLK_CTRL             (zynq_slcr_base_priv + 0x144)
-#define SLCR_SMC_CLK_CTRL              (zynq_slcr_base_priv + 0x148)
-#define SLCR_LQSPI_CLK_CTRL            (zynq_slcr_base_priv + 0x14c)
-#define SLCR_SDIO_CLK_CTRL             (zynq_slcr_base_priv + 0x150)
-#define SLCR_UART_CLK_CTRL             (zynq_slcr_base_priv + 0x154)
-#define SLCR_SPI_CLK_CTRL              (zynq_slcr_base_priv + 0x158)
-#define SLCR_CAN_CLK_CTRL              (zynq_slcr_base_priv + 0x15c)
-#define SLCR_CAN_MIOCLK_CTRL           (zynq_slcr_base_priv + 0x160)
-#define SLCR_DBG_CLK_CTRL              (zynq_slcr_base_priv + 0x164)
-#define SLCR_PCAP_CLK_CTRL             (zynq_slcr_base_priv + 0x168)
-#define SLCR_FPGA0_CLK_CTRL            (zynq_slcr_base_priv + 0x170)
-#define SLCR_621_TRUE                  (zynq_slcr_base_priv + 0x1c4)
-#define SLCR_SWDT_CLK_SEL              (zynq_slcr_base_priv + 0x304)
+static void __iomem *zynq_clkc_base;
+
+#define SLCR_ARMPLL_CTRL               (zynq_clkc_base + 0x00)
+#define SLCR_DDRPLL_CTRL               (zynq_clkc_base + 0x04)
+#define SLCR_IOPLL_CTRL                        (zynq_clkc_base + 0x08)
+#define SLCR_PLL_STATUS                        (zynq_clkc_base + 0x0c)
+#define SLCR_ARM_CLK_CTRL              (zynq_clkc_base + 0x20)
+#define SLCR_DDR_CLK_CTRL              (zynq_clkc_base + 0x24)
+#define SLCR_DCI_CLK_CTRL              (zynq_clkc_base + 0x28)
+#define SLCR_APER_CLK_CTRL             (zynq_clkc_base + 0x2c)
+#define SLCR_GEM0_CLK_CTRL             (zynq_clkc_base + 0x40)
+#define SLCR_GEM1_CLK_CTRL             (zynq_clkc_base + 0x44)
+#define SLCR_SMC_CLK_CTRL              (zynq_clkc_base + 0x48)
+#define SLCR_LQSPI_CLK_CTRL            (zynq_clkc_base + 0x4c)
+#define SLCR_SDIO_CLK_CTRL             (zynq_clkc_base + 0x50)
+#define SLCR_UART_CLK_CTRL             (zynq_clkc_base + 0x54)
+#define SLCR_SPI_CLK_CTRL              (zynq_clkc_base + 0x58)
+#define SLCR_CAN_CLK_CTRL              (zynq_clkc_base + 0x5c)
+#define SLCR_CAN_MIOCLK_CTRL           (zynq_clkc_base + 0x60)
+#define SLCR_DBG_CLK_CTRL              (zynq_clkc_base + 0x64)
+#define SLCR_PCAP_CLK_CTRL             (zynq_clkc_base + 0x68)
+#define SLCR_FPGA0_CLK_CTRL            (zynq_clkc_base + 0x70)
+#define SLCR_621_TRUE                  (zynq_clkc_base + 0xc4)
+#define SLCR_SWDT_CLK_SEL              (zynq_clkc_base + 0x204)
 
 #define NUM_MIO_PINS   54
 
@@ -148,7 +149,7 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
        clks[fclk] = clk_register_gate(NULL, clk_name,
                        div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
                        0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
-       enable_reg = readl(fclk_gate_reg) & 1;
+       enable_reg = clk_readl(fclk_gate_reg) & 1;
        if (enable && !enable_reg) {
                if (clk_prepare_enable(clks[fclk]))
                        pr_warn("%s: FCLK%u enable failed\n", __func__,
@@ -277,7 +278,7 @@ static void __init zynq_clk_setup(struct device_node *np)
                        SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock);
 
        /* CPU clocks */
-       tmp = readl(SLCR_621_TRUE) & 1;
+       tmp = clk_readl(SLCR_621_TRUE) & 1;
        clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4,
                        CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0,
                        &armclk_lock);
@@ -569,8 +570,42 @@ static void __init zynq_clk_setup(struct device_node *np)
 
 CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc", zynq_clk_setup);
 
-void __init zynq_clock_init(void __iomem *slcr_base)
+void __init zynq_clock_init(void)
 {
-       zynq_slcr_base_priv = slcr_base;
-       of_clk_init(NULL);
+       struct device_node *np;
+       struct device_node *slcr;
+       struct resource res;
+
+       np = of_find_compatible_node(NULL, NULL, "xlnx,ps7-clkc");
+       if (!np) {
+               pr_err("%s: clkc node not found\n", __func__);
+               goto np_err;
+       }
+
+       if (of_address_to_resource(np, 0, &res)) {
+               pr_err("%s: failed to get resource\n", np->name);
+               goto np_err;
+       }
+
+       slcr = of_get_parent(np);
+
+       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);
+               of_node_put(slcr);
+               goto np_err;
+       }
+
+       pr_info("%s: clkc starts at %p\n", __func__, zynq_clkc_base);
+
+       of_node_put(slcr);
+       of_node_put(np);
+
+       return;
+
+np_err:
+       of_node_put(np);
+       BUG();
+       return;
 }
index 3226f54fa5956a357104f3f8675779179067b717..cec97596fe65988ff473e7f6d08302a7f68ba375 100644 (file)
@@ -90,7 +90,7 @@ static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
         * makes probably sense to redundantly save fbdiv in the struct
         * zynq_pll to save the IO access.
         */
-       fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
+       fbdiv = (clk_readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
                        PLLCTRL_FBDIV_SHIFT;
 
        return parent_rate * fbdiv;
@@ -112,7 +112,7 @@ static int zynq_pll_is_enabled(struct clk_hw *hw)
 
        spin_lock_irqsave(clk->lock, flags);
 
-       reg = readl(clk->pll_ctrl);
+       reg = clk_readl(clk->pll_ctrl);
 
        spin_unlock_irqrestore(clk->lock, flags);
 
@@ -138,10 +138,10 @@ static int zynq_pll_enable(struct clk_hw *hw)
        /* Power up PLL and wait for lock */
        spin_lock_irqsave(clk->lock, flags);
 
-       reg = readl(clk->pll_ctrl);
+       reg = clk_readl(clk->pll_ctrl);
        reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
-       writel(reg, clk->pll_ctrl);
-       while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
+       clk_writel(reg, clk->pll_ctrl);
+       while (!(clk_readl(clk->pll_status) & (1 << clk->lockbit)))
                ;
 
        spin_unlock_irqrestore(clk->lock, flags);
@@ -168,9 +168,9 @@ static void zynq_pll_disable(struct clk_hw *hw)
        /* shut down PLL */
        spin_lock_irqsave(clk->lock, flags);
 
-       reg = readl(clk->pll_ctrl);
+       reg = clk_readl(clk->pll_ctrl);
        reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
-       writel(reg, clk->pll_ctrl);
+       clk_writel(reg, clk->pll_ctrl);
 
        spin_unlock_irqrestore(clk->lock, flags);
 }
@@ -225,9 +225,9 @@ struct clk *clk_register_zynq_pll(const char *name, const char *parent,
 
        spin_lock_irqsave(pll->lock, flags);
 
-       reg = readl(pll->pll_ctrl);
+       reg = clk_readl(pll->pll_ctrl);
        reg &= ~PLLCTRL_BPQUAL_MASK;
-       writel(reg, pll->pll_ctrl);
+       clk_writel(reg, pll->pll_ctrl);
 
        spin_unlock_irqrestore(pll->lock, flags);
 
index 52e9329e3c51c05419a2d811ad3ed8fd271baa66..96918e1f26a39bab1d14193114cbdb29f38235b8 100644 (file)
@@ -188,3 +188,6 @@ config EM_TIMER_STI
          This enables build of a clocksource and clockevent driver for
          the 48-bit System Timer (STI) hardware available on a SoCs
          such as EMEV2 from former NEC Electronics.
+
+config CLKSRC_QCOM
+       bool
index f3fe4cb4974b22dddd3561fc1d9a8d5c568032ed..98cb6c51aa878ba9c43e23f7b2ed161ce037e449 100644 (file)
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32)    += time-efm32.o
 obj-$(CONFIG_CLKSRC_EXYNOS_MCT)        += exynos_mct.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)       += samsung_pwm_timer.o
 obj-$(CONFIG_VF_PIT_TIMER)     += vf_pit_timer.o
+obj-$(CONFIG_CLKSRC_QCOM)      += qcom-timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)           += arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)         += arm_global_timer.o
index b3eb582d6a6f1956bc870067188bb03a090fd30b..ad357254172890ff4170c2a32634f57ad831b26e 100644 (file)
@@ -56,14 +56,19 @@ static struct notifier_block dummy_timer_cpu_nb = {
 
 static int __init dummy_timer_register(void)
 {
-       int err = register_cpu_notifier(&dummy_timer_cpu_nb);
+       int err = 0;
+
+       cpu_notifier_register_begin();
+       err = __register_cpu_notifier(&dummy_timer_cpu_nb);
        if (err)
-               return err;
+               goto out;
 
        /* We won't get a call on the boot CPU, so register immediately */
        if (num_possible_cpus() > 1)
                dummy_timer_setup();
 
-       return 0;
+out:
+       cpu_notifier_register_done();
+       return err;
 }
 early_initcall(dummy_timer_register);
index c2e390efbdca6fc2b71a3e39356ddb9c2156200a..a6ee6d7cd63f19a4cdad01a1a82956f990a76194 100644 (file)
@@ -25,8 +25,6 @@
 #include <linux/of_address.h>
 #include <linux/clocksource.h>
 
-#include <asm/mach/time.h>
-
 #define EXYNOS4_MCTREG(x)              (x)
 #define EXYNOS4_MCT_G_CNT_L            EXYNOS4_MCTREG(0x100)
 #define EXYNOS4_MCT_G_CNT_U            EXYNOS4_MCTREG(0x104)
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
new file mode 100644 (file)
index 0000000..e807acf
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define TIMER_MATCH_VAL                        0x0000
+#define TIMER_COUNT_VAL                        0x0004
+#define TIMER_ENABLE                   0x0008
+#define TIMER_ENABLE_CLR_ON_MATCH_EN   BIT(1)
+#define TIMER_ENABLE_EN                        BIT(0)
+#define TIMER_CLEAR                    0x000C
+#define DGT_CLK_CTL                    0x10
+#define DGT_CLK_CTL_DIV_4              0x3
+#define TIMER_STS_GPT0_CLR_PEND                BIT(10)
+
+#define GPT_HZ 32768
+
+#define MSM_DGT_SHIFT 5
+
+static void __iomem *event_base;
+static void __iomem *sts_base;
+
+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+       /* Stop the timer tick */
+       if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
+               u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+               ctrl &= ~TIMER_ENABLE_EN;
+               writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+       }
+       evt->event_handler(evt);
+       return IRQ_HANDLED;
+}
+
+static int msm_timer_set_next_event(unsigned long cycles,
+                                   struct clock_event_device *evt)
+{
+       u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+
+       ctrl &= ~TIMER_ENABLE_EN;
+       writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+
+       writel_relaxed(ctrl, event_base + TIMER_CLEAR);
+       writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
+
+       if (sts_base)
+               while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
+                       cpu_relax();
+
+       writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
+       return 0;
+}
+
+static void msm_timer_set_mode(enum clock_event_mode mode,
+                             struct clock_event_device *evt)
+{
+       u32 ctrl;
+
+       ctrl = readl_relaxed(event_base + TIMER_ENABLE);
+       ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_RESUME:
+       case CLOCK_EVT_MODE_PERIODIC:
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               /* Timer is enabled in set_next_event */
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               break;
+       }
+       writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+}
+
+static struct clock_event_device __percpu *msm_evt;
+
+static void __iomem *source_base;
+
+static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
+{
+       return readl_relaxed(source_base + TIMER_COUNT_VAL);
+}
+
+static struct clocksource msm_clocksource = {
+       .name   = "dg_timer",
+       .rating = 300,
+       .read   = msm_read_timer_count,
+       .mask   = CLOCKSOURCE_MASK(32),
+       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int msm_timer_irq;
+static int msm_timer_has_ppi;
+
+static int msm_local_timer_setup(struct clock_event_device *evt)
+{
+       int cpu = smp_processor_id();
+       int err;
+
+       evt->irq = msm_timer_irq;
+       evt->name = "msm_timer";
+       evt->features = CLOCK_EVT_FEAT_ONESHOT;
+       evt->rating = 200;
+       evt->set_mode = msm_timer_set_mode;
+       evt->set_next_event = msm_timer_set_next_event;
+       evt->cpumask = cpumask_of(cpu);
+
+       clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
+
+       if (msm_timer_has_ppi) {
+               enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
+       } else {
+               err = request_irq(evt->irq, msm_timer_interrupt,
+                               IRQF_TIMER | IRQF_NOBALANCING |
+                               IRQF_TRIGGER_RISING, "gp_timer", evt);
+               if (err)
+                       pr_err("request_irq failed\n");
+       }
+
+       return 0;
+}
+
+static void msm_local_timer_stop(struct clock_event_device *evt)
+{
+       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+       disable_percpu_irq(evt->irq);
+}
+
+static int msm_timer_cpu_notify(struct notifier_block *self,
+                                          unsigned long action, void *hcpu)
+{
+       /*
+        * Grab cpu pointer in each case to avoid spurious
+        * preemptible warnings
+        */
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_STARTING:
+               msm_local_timer_setup(this_cpu_ptr(msm_evt));
+               break;
+       case CPU_DYING:
+               msm_local_timer_stop(this_cpu_ptr(msm_evt));
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block msm_timer_cpu_nb = {
+       .notifier_call = msm_timer_cpu_notify,
+};
+
+static u64 notrace msm_sched_clock_read(void)
+{
+       return msm_clocksource.read(&msm_clocksource);
+}
+
+static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
+                                 bool percpu)
+{
+       struct clocksource *cs = &msm_clocksource;
+       int res = 0;
+
+       msm_timer_irq = irq;
+       msm_timer_has_ppi = percpu;
+
+       msm_evt = alloc_percpu(struct clock_event_device);
+       if (!msm_evt) {
+               pr_err("memory allocation failed for clockevents\n");
+               goto err;
+       }
+
+       if (percpu)
+               res = request_percpu_irq(irq, msm_timer_interrupt,
+                                        "gp_timer", msm_evt);
+
+       if (res) {
+               pr_err("request_percpu_irq failed\n");
+       } else {
+               res = register_cpu_notifier(&msm_timer_cpu_nb);
+               if (res) {
+                       free_percpu_irq(irq, msm_evt);
+                       goto err;
+               }
+
+               /* Immediately configure the timer on the boot CPU */
+               msm_local_timer_setup(__this_cpu_ptr(msm_evt));
+       }
+
+err:
+       writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
+       res = clocksource_register_hz(cs, dgt_hz);
+       if (res)
+               pr_err("clocksource_register failed\n");
+       sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
+}
+
+#ifdef CONFIG_ARCH_QCOM
+static void __init msm_dt_timer_init(struct device_node *np)
+{
+       u32 freq;
+       int irq;
+       struct resource res;
+       u32 percpu_offset;
+       void __iomem *base;
+       void __iomem *cpu0_base;
+
+       base = of_iomap(np, 0);
+       if (!base) {
+               pr_err("Failed to map event base\n");
+               return;
+       }
+
+       /* We use GPT0 for the clockevent */
+       irq = irq_of_parse_and_map(np, 1);
+       if (irq <= 0) {
+               pr_err("Can't get irq\n");
+               return;
+       }
+
+       /* We use CPU0's DGT for the clocksource */
+       if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
+               percpu_offset = 0;
+
+       if (of_address_to_resource(np, 0, &res)) {
+               pr_err("Failed to parse DGT resource\n");
+               return;
+       }
+
+       cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
+       if (!cpu0_base) {
+               pr_err("Failed to map source base\n");
+               return;
+       }
+
+       if (of_property_read_u32(np, "clock-frequency", &freq)) {
+               pr_err("Unknown frequency\n");
+               return;
+       }
+
+       event_base = base + 0x4;
+       sts_base = base + 0x88;
+       source_base = cpu0_base + 0x24;
+       freq /= 4;
+       writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
+
+       msm_timer_init(freq, 32, irq, !!percpu_offset);
+}
+CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
+CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
+#else
+
+static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
+                               u32 sts)
+{
+       void __iomem *base;
+
+       base = ioremap(addr, SZ_256);
+       if (!base) {
+               pr_err("Failed to map timer base\n");
+               return -ENOMEM;
+       }
+       event_base = base + event;
+       source_base = base + source;
+       if (sts)
+               sts_base = base + sts;
+
+       return 0;
+}
+
+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
+{
+       /*
+        * Shift timer count down by a constant due to unreliable lower bits
+        * on some targets.
+        */
+       return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
+}
+
+void __init msm7x01_timer_init(void)
+{
+       struct clocksource *cs = &msm_clocksource;
+
+       if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
+               return;
+       cs->read = msm_read_timer_count_shift;
+       cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
+       /* 600 KHz */
+       msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
+                       false);
+}
+
+void __init msm7x30_timer_init(void)
+{
+       if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
+               return;
+       msm_timer_init(24576000 / 4, 32, 1, false);
+}
+
+void __init qsd8x50_timer_init(void)
+{
+       if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
+               return;
+       msm_timer_init(19200000 / 4, 32, 7, false);
+}
+#endif
index 09a17d9a6594c80e38c64bd18d6827db427df18b..b52e1c078b9955330dda32f803a26e8fa1527ab7 100644 (file)
@@ -19,7 +19,8 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 #include <linux/sched_clock.h>
-#include <asm/mach/time.h>
+
+#define MARCO_CLOCK_FREQ 1000000
 
 #define SIRFSOC_TIMER_32COUNTER_0_CTRL                 0x0000
 #define SIRFSOC_TIMER_32COUNTER_1_CTRL                 0x0004
@@ -191,7 +192,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
        ce->rating = 200;
        ce->set_mode = sirfsoc_timer_set_mode;
        ce->set_next_event = sirfsoc_timer_set_next_event;
-       clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60);
+       clockevents_calc_mult_shift(ce, MARCO_CLOCK_FREQ, 60);
        ce->max_delta_ns = clockevent_delta2ns(-2, ce);
        ce->min_delta_ns = clockevent_delta2ns(2, ce);
        ce->cpumask = cpumask_of(cpu);
@@ -263,11 +264,11 @@ static void __init sirfsoc_marco_timer_init(void)
        BUG_ON(IS_ERR(clk));
        rate = clk_get_rate(clk);
 
-       BUG_ON(rate < CLOCK_TICK_RATE);
-       BUG_ON(rate % CLOCK_TICK_RATE);
+       BUG_ON(rate < MARCO_CLOCK_FREQ);
+       BUG_ON(rate % MARCO_CLOCK_FREQ);
 
        /* Initialize the timer dividers */
-       timer_div = rate / CLOCK_TICK_RATE - 1;
+       timer_div = rate / MARCO_CLOCK_FREQ - 1;
        writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
        writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
        writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
@@ -283,7 +284,7 @@ static void __init sirfsoc_marco_timer_init(void)
        /* Clear all interrupts */
        writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
 
-       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
+       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, MARCO_CLOCK_FREQ));
 
        sirfsoc_clockevent_init();
 }
index 8a492d34ff9f52813655b056bad5c17f9c305220..1a6b2d6356d630ca65cca3f988d39d553171c038 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/sched_clock.h>
 #include <asm/mach/time.h>
 
+#define PRIMA2_CLOCK_FREQ 1000000
+
 #define SIRFSOC_TIMER_COUNTER_LO       0x0000
 #define SIRFSOC_TIMER_COUNTER_HI       0x0004
 #define SIRFSOC_TIMER_MATCH_0          0x0008
@@ -173,7 +175,7 @@ static u64 notrace sirfsoc_read_sched_clock(void)
 static void __init sirfsoc_clockevent_init(void)
 {
        sirfsoc_clockevent.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&sirfsoc_clockevent, CLOCK_TICK_RATE,
+       clockevents_config_and_register(&sirfsoc_clockevent, PRIMA2_CLOCK_FREQ,
                                        2, -2);
 }
 
@@ -190,8 +192,8 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
 
        rate = clk_get_rate(clk);
 
-       BUG_ON(rate < CLOCK_TICK_RATE);
-       BUG_ON(rate % CLOCK_TICK_RATE);
+       BUG_ON(rate < PRIMA2_CLOCK_FREQ);
+       BUG_ON(rate % PRIMA2_CLOCK_FREQ);
 
        sirfsoc_timer_base = of_iomap(np, 0);
        if (!sirfsoc_timer_base)
@@ -199,14 +201,16 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
 
        sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0);
 
-       writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
+       writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1,
+                      sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
        writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
        writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
        writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
 
-       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
+       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource,
+                                      PRIMA2_CLOCK_FREQ));
 
-       sched_clock_register(sirfsoc_read_sched_clock, 64, CLOCK_TICK_RATE);
+       sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ);
 
        BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
 
index e63d469661fd547d49154643ed58bb2dcf100023..5dcf756970e7f733decb1aa437f3f7b20467044b 100644 (file)
@@ -333,7 +333,7 @@ static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction u300_timer_irq = {
        .name           = "U300 Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = u300_timer_interrupt,
 };
 
index 9fb627046e17ad33c5f1c2cc1078a27e1df1245b..1e2b9db563ec1ac74b39516a9438fc360cf658fa 100644 (file)
@@ -122,7 +122,7 @@ config ARM_INTEGRATOR
          If in doubt, say Y.
 
 config ARM_KIRKWOOD_CPUFREQ
-       def_bool ARCH_KIRKWOOD && OF
+       def_bool MACH_KIRKWOOD
        help
          This adds the CPUFreq driver for Marvell Kirkwood
          SoCs.
index 822ca03a87f796ae321cb9c2bd54ffe7380b5581..d5eaedbe464f873e5a32978ac6cf86eb70169188 100644 (file)
@@ -906,15 +906,16 @@ static void __init acpi_cpufreq_boost_init(void)
 
                acpi_cpufreq_driver.boost_supported = true;
                acpi_cpufreq_driver.boost_enabled = boost_state(0);
-               get_online_cpus();
+
+               cpu_notifier_register_begin();
 
                /* Force all MSRs to the same value */
                boost_set_msrs(acpi_cpufreq_driver.boost_enabled,
                               cpu_online_mask);
 
-               register_cpu_notifier(&boost_nb);
+               __register_cpu_notifier(&boost_nb);
 
-               put_online_cpus();
+               cpu_notifier_register_done();
        }
 }
 
index d988948a89a069510c32bda5ca79a1a422b8827b..97ccc31dbdd8fb8c48510cc00f5472ea6aefa191 100644 (file)
@@ -22,7 +22,7 @@ config ARM_HIGHBANK_CPUIDLE
 
 config ARM_KIRKWOOD_CPUIDLE
        bool "CPU Idle Driver for Marvell Kirkwood SoCs"
-       depends on ARCH_KIRKWOOD
+       depends on ARCH_KIRKWOOD || MACH_KIRKWOOD
        help
          This adds the CPU Idle driver for Marvell Kirkwood SoCs.
 
index 362e7c49f2e1ad9d264eef1acff1b3102f0e1212..64ceca2920b87402230159d8111021248d1d2b60 100644 (file)
@@ -5,6 +5,7 @@
  * 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/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
@@ -26,11 +27,21 @@ struct omap_dmadev {
        spinlock_t lock;
        struct tasklet_struct task;
        struct list_head pending;
+       void __iomem *base;
+       const struct omap_dma_reg *reg_map;
+       struct omap_system_dma_plat_info *plat;
+       bool legacy;
+       spinlock_t irq_lock;
+       uint32_t irq_enable_mask;
+       struct omap_chan *lch_map[32];
 };
 
 struct omap_chan {
        struct virt_dma_chan vc;
        struct list_head node;
+       void __iomem *channel_base;
+       const struct omap_dma_reg *reg_map;
+       uint32_t ccr;
 
        struct dma_slave_config cfg;
        unsigned dma_sig;
@@ -54,19 +65,93 @@ struct omap_desc {
        dma_addr_t dev_addr;
 
        int16_t fi;             /* for OMAP_DMA_SYNC_PACKET */
-       uint8_t es;             /* OMAP_DMA_DATA_TYPE_xxx */
-       uint8_t sync_mode;      /* OMAP_DMA_SYNC_xxx */
-       uint8_t sync_type;      /* OMAP_DMA_xxx_SYNC* */
-       uint8_t periph_port;    /* Peripheral port */
+       uint8_t es;             /* CSDP_DATA_TYPE_xxx */
+       uint32_t ccr;           /* CCR value */
+       uint16_t clnk_ctrl;     /* CLNK_CTRL value */
+       uint16_t cicr;          /* CICR value */
+       uint32_t csdp;          /* CSDP value */
 
        unsigned sglen;
        struct omap_sg sg[0];
 };
 
+enum {
+       CCR_FS                  = BIT(5),
+       CCR_READ_PRIORITY       = BIT(6),
+       CCR_ENABLE              = BIT(7),
+       CCR_AUTO_INIT           = BIT(8),       /* OMAP1 only */
+       CCR_REPEAT              = BIT(9),       /* OMAP1 only */
+       CCR_OMAP31_DISABLE      = BIT(10),      /* OMAP1 only */
+       CCR_SUSPEND_SENSITIVE   = BIT(8),       /* OMAP2+ only */
+       CCR_RD_ACTIVE           = BIT(9),       /* OMAP2+ only */
+       CCR_WR_ACTIVE           = BIT(10),      /* OMAP2+ only */
+       CCR_SRC_AMODE_CONSTANT  = 0 << 12,
+       CCR_SRC_AMODE_POSTINC   = 1 << 12,
+       CCR_SRC_AMODE_SGLIDX    = 2 << 12,
+       CCR_SRC_AMODE_DBLIDX    = 3 << 12,
+       CCR_DST_AMODE_CONSTANT  = 0 << 14,
+       CCR_DST_AMODE_POSTINC   = 1 << 14,
+       CCR_DST_AMODE_SGLIDX    = 2 << 14,
+       CCR_DST_AMODE_DBLIDX    = 3 << 14,
+       CCR_CONSTANT_FILL       = BIT(16),
+       CCR_TRANSPARENT_COPY    = BIT(17),
+       CCR_BS                  = BIT(18),
+       CCR_SUPERVISOR          = BIT(22),
+       CCR_PREFETCH            = BIT(23),
+       CCR_TRIGGER_SRC         = BIT(24),
+       CCR_BUFFERING_DISABLE   = BIT(25),
+       CCR_WRITE_PRIORITY      = BIT(26),
+       CCR_SYNC_ELEMENT        = 0,
+       CCR_SYNC_FRAME          = CCR_FS,
+       CCR_SYNC_BLOCK          = CCR_BS,
+       CCR_SYNC_PACKET         = CCR_BS | CCR_FS,
+
+       CSDP_DATA_TYPE_8        = 0,
+       CSDP_DATA_TYPE_16       = 1,
+       CSDP_DATA_TYPE_32       = 2,
+       CSDP_SRC_PORT_EMIFF     = 0 << 2, /* OMAP1 only */
+       CSDP_SRC_PORT_EMIFS     = 1 << 2, /* OMAP1 only */
+       CSDP_SRC_PORT_OCP_T1    = 2 << 2, /* OMAP1 only */
+       CSDP_SRC_PORT_TIPB      = 3 << 2, /* OMAP1 only */
+       CSDP_SRC_PORT_OCP_T2    = 4 << 2, /* OMAP1 only */
+       CSDP_SRC_PORT_MPUI      = 5 << 2, /* OMAP1 only */
+       CSDP_SRC_PACKED         = BIT(6),
+       CSDP_SRC_BURST_1        = 0 << 7,
+       CSDP_SRC_BURST_16       = 1 << 7,
+       CSDP_SRC_BURST_32       = 2 << 7,
+       CSDP_SRC_BURST_64       = 3 << 7,
+       CSDP_DST_PORT_EMIFF     = 0 << 9, /* OMAP1 only */
+       CSDP_DST_PORT_EMIFS     = 1 << 9, /* OMAP1 only */
+       CSDP_DST_PORT_OCP_T1    = 2 << 9, /* OMAP1 only */
+       CSDP_DST_PORT_TIPB      = 3 << 9, /* OMAP1 only */
+       CSDP_DST_PORT_OCP_T2    = 4 << 9, /* OMAP1 only */
+       CSDP_DST_PORT_MPUI      = 5 << 9, /* OMAP1 only */
+       CSDP_DST_PACKED         = BIT(13),
+       CSDP_DST_BURST_1        = 0 << 14,
+       CSDP_DST_BURST_16       = 1 << 14,
+       CSDP_DST_BURST_32       = 2 << 14,
+       CSDP_DST_BURST_64       = 3 << 14,
+
+       CICR_TOUT_IE            = BIT(0),       /* OMAP1 only */
+       CICR_DROP_IE            = BIT(1),
+       CICR_HALF_IE            = BIT(2),
+       CICR_FRAME_IE           = BIT(3),
+       CICR_LAST_IE            = BIT(4),
+       CICR_BLOCK_IE           = BIT(5),
+       CICR_PKT_IE             = BIT(7),       /* OMAP2+ only */
+       CICR_TRANS_ERR_IE       = BIT(8),       /* OMAP2+ only */
+       CICR_SUPERVISOR_ERR_IE  = BIT(10),      /* OMAP2+ only */
+       CICR_MISALIGNED_ERR_IE  = BIT(11),      /* OMAP2+ only */
+       CICR_DRAIN_IE           = BIT(12),      /* OMAP2+ only */
+       CICR_SUPER_BLOCK_IE     = BIT(14),      /* OMAP2+ only */
+
+       CLNK_CTRL_ENABLE_LNK    = BIT(15),
+};
+
 static const unsigned es_bytes[] = {
-       [OMAP_DMA_DATA_TYPE_S8] = 1,
-       [OMAP_DMA_DATA_TYPE_S16] = 2,
-       [OMAP_DMA_DATA_TYPE_S32] = 4,
+       [CSDP_DATA_TYPE_8] = 1,
+       [CSDP_DATA_TYPE_16] = 2,
+       [CSDP_DATA_TYPE_32] = 4,
 };
 
 static struct of_dma_filter_info omap_dma_info = {
@@ -93,28 +178,214 @@ static void omap_dma_desc_free(struct virt_dma_desc *vd)
        kfree(container_of(vd, struct omap_desc, vd));
 }
 
+static void omap_dma_write(uint32_t val, unsigned type, void __iomem *addr)
+{
+       switch (type) {
+       case OMAP_DMA_REG_16BIT:
+               writew_relaxed(val, addr);
+               break;
+       case OMAP_DMA_REG_2X16BIT:
+               writew_relaxed(val, addr);
+               writew_relaxed(val >> 16, addr + 2);
+               break;
+       case OMAP_DMA_REG_32BIT:
+               writel_relaxed(val, addr);
+               break;
+       default:
+               WARN_ON(1);
+       }
+}
+
+static unsigned omap_dma_read(unsigned type, void __iomem *addr)
+{
+       unsigned val;
+
+       switch (type) {
+       case OMAP_DMA_REG_16BIT:
+               val = readw_relaxed(addr);
+               break;
+       case OMAP_DMA_REG_2X16BIT:
+               val = readw_relaxed(addr);
+               val |= readw_relaxed(addr + 2) << 16;
+               break;
+       case OMAP_DMA_REG_32BIT:
+               val = readl_relaxed(addr);
+               break;
+       default:
+               WARN_ON(1);
+               val = 0;
+       }
+
+       return val;
+}
+
+static void omap_dma_glbl_write(struct omap_dmadev *od, unsigned reg, unsigned val)
+{
+       const struct omap_dma_reg *r = od->reg_map + reg;
+
+       WARN_ON(r->stride);
+
+       omap_dma_write(val, r->type, od->base + r->offset);
+}
+
+static unsigned omap_dma_glbl_read(struct omap_dmadev *od, unsigned reg)
+{
+       const struct omap_dma_reg *r = od->reg_map + reg;
+
+       WARN_ON(r->stride);
+
+       return omap_dma_read(r->type, od->base + r->offset);
+}
+
+static void omap_dma_chan_write(struct omap_chan *c, unsigned reg, unsigned val)
+{
+       const struct omap_dma_reg *r = c->reg_map + reg;
+
+       omap_dma_write(val, r->type, c->channel_base + r->offset);
+}
+
+static unsigned omap_dma_chan_read(struct omap_chan *c, unsigned reg)
+{
+       const struct omap_dma_reg *r = c->reg_map + reg;
+
+       return omap_dma_read(r->type, c->channel_base + r->offset);
+}
+
+static void omap_dma_clear_csr(struct omap_chan *c)
+{
+       if (dma_omap1())
+               omap_dma_chan_read(c, CSR);
+       else
+               omap_dma_chan_write(c, CSR, ~0);
+}
+
+static unsigned omap_dma_get_csr(struct omap_chan *c)
+{
+       unsigned val = omap_dma_chan_read(c, CSR);
+
+       if (!dma_omap1())
+               omap_dma_chan_write(c, CSR, val);
+
+       return val;
+}
+
+static void omap_dma_assign(struct omap_dmadev *od, struct omap_chan *c,
+       unsigned lch)
+{
+       c->channel_base = od->base + od->plat->channel_stride * lch;
+
+       od->lch_map[lch] = c;
+}
+
+static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
+{
+       struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+
+       if (__dma_omap15xx(od->plat->dma_attr))
+               omap_dma_chan_write(c, CPC, 0);
+       else
+               omap_dma_chan_write(c, CDAC, 0);
+
+       omap_dma_clear_csr(c);
+
+       /* Enable interrupts */
+       omap_dma_chan_write(c, CICR, d->cicr);
+
+       /* Enable channel */
+       omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE);
+}
+
+static void omap_dma_stop(struct omap_chan *c)
+{
+       struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+       uint32_t val;
+
+       /* disable irq */
+       omap_dma_chan_write(c, CICR, 0);
+
+       omap_dma_clear_csr(c);
+
+       val = omap_dma_chan_read(c, CCR);
+       if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) {
+               uint32_t sysconfig;
+               unsigned i;
+
+               sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
+               val = sysconfig & ~DMA_SYSCONFIG_MIDLEMODE_MASK;
+               val |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
+               omap_dma_glbl_write(od, OCP_SYSCONFIG, val);
+
+               val = omap_dma_chan_read(c, CCR);
+               val &= ~CCR_ENABLE;
+               omap_dma_chan_write(c, CCR, val);
+
+               /* Wait for sDMA FIFO to drain */
+               for (i = 0; ; i++) {
+                       val = omap_dma_chan_read(c, CCR);
+                       if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
+                               break;
+
+                       if (i > 100)
+                               break;
+
+                       udelay(5);
+               }
+
+               if (val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
+                       dev_err(c->vc.chan.device->dev,
+                               "DMA drain did not complete on lch %d\n",
+                               c->dma_ch);
+
+               omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
+       } else {
+               val &= ~CCR_ENABLE;
+               omap_dma_chan_write(c, CCR, val);
+       }
+
+       mb();
+
+       if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) {
+               val = omap_dma_chan_read(c, CLNK_CTRL);
+
+               if (dma_omap1())
+                       val |= 1 << 14; /* set the STOP_LNK bit */
+               else
+                       val &= ~CLNK_CTRL_ENABLE_LNK;
+
+               omap_dma_chan_write(c, CLNK_CTRL, val);
+       }
+}
+
 static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
        unsigned idx)
 {
        struct omap_sg *sg = d->sg + idx;
+       unsigned cxsa, cxei, cxfi;
 
-       if (d->dir == DMA_DEV_TO_MEM)
-               omap_set_dma_dest_params(c->dma_ch, OMAP_DMA_PORT_EMIFF,
-                       OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0);
-       else
-               omap_set_dma_src_params(c->dma_ch, OMAP_DMA_PORT_EMIFF,
-                       OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0);
+       if (d->dir == DMA_DEV_TO_MEM) {
+               cxsa = CDSA;
+               cxei = CDEI;
+               cxfi = CDFI;
+       } else {
+               cxsa = CSSA;
+               cxei = CSEI;
+               cxfi = CSFI;
+       }
 
-       omap_set_dma_transfer_params(c->dma_ch, d->es, sg->en, sg->fn,
-               d->sync_mode, c->dma_sig, d->sync_type);
+       omap_dma_chan_write(c, cxsa, sg->addr);
+       omap_dma_chan_write(c, cxei, 0);
+       omap_dma_chan_write(c, cxfi, 0);
+       omap_dma_chan_write(c, CEN, sg->en);
+       omap_dma_chan_write(c, CFN, sg->fn);
 
-       omap_start_dma(c->dma_ch);
+       omap_dma_start(c, d);
 }
 
 static void omap_dma_start_desc(struct omap_chan *c)
 {
        struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
        struct omap_desc *d;
+       unsigned cxsa, cxei, cxfi;
 
        if (!vd) {
                c->desc = NULL;
@@ -126,12 +397,32 @@ static void omap_dma_start_desc(struct omap_chan *c)
        c->desc = d = to_omap_dma_desc(&vd->tx);
        c->sgidx = 0;
 
-       if (d->dir == DMA_DEV_TO_MEM)
-               omap_set_dma_src_params(c->dma_ch, d->periph_port,
-                       OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi);
-       else
-               omap_set_dma_dest_params(c->dma_ch, d->periph_port,
-                       OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi);
+       /*
+        * This provides the necessary barrier to ensure data held in
+        * DMA coherent memory is visible to the DMA engine prior to
+        * the transfer starting.
+        */
+       mb();
+
+       omap_dma_chan_write(c, CCR, d->ccr);
+       if (dma_omap1())
+               omap_dma_chan_write(c, CCR2, d->ccr >> 16);
+
+       if (d->dir == DMA_DEV_TO_MEM) {
+               cxsa = CSSA;
+               cxei = CSEI;
+               cxfi = CSFI;
+       } else {
+               cxsa = CDSA;
+               cxei = CDEI;
+               cxfi = CDFI;
+       }
+
+       omap_dma_chan_write(c, cxsa, d->dev_addr);
+       omap_dma_chan_write(c, cxei, 0);
+       omap_dma_chan_write(c, cxfi, d->fi);
+       omap_dma_chan_write(c, CSDP, d->csdp);
+       omap_dma_chan_write(c, CLNK_CTRL, d->clnk_ctrl);
 
        omap_dma_start_sg(c, d, 0);
 }
@@ -186,24 +477,118 @@ static void omap_dma_sched(unsigned long data)
        }
 }
 
+static irqreturn_t omap_dma_irq(int irq, void *devid)
+{
+       struct omap_dmadev *od = devid;
+       unsigned status, channel;
+
+       spin_lock(&od->irq_lock);
+
+       status = omap_dma_glbl_read(od, IRQSTATUS_L1);
+       status &= od->irq_enable_mask;
+       if (status == 0) {
+               spin_unlock(&od->irq_lock);
+               return IRQ_NONE;
+       }
+
+       while ((channel = ffs(status)) != 0) {
+               unsigned mask, csr;
+               struct omap_chan *c;
+
+               channel -= 1;
+               mask = BIT(channel);
+               status &= ~mask;
+
+               c = od->lch_map[channel];
+               if (c == NULL) {
+                       /* This should never happen */
+                       dev_err(od->ddev.dev, "invalid channel %u\n", channel);
+                       continue;
+               }
+
+               csr = omap_dma_get_csr(c);
+               omap_dma_glbl_write(od, IRQSTATUS_L1, mask);
+
+               omap_dma_callback(channel, csr, c);
+       }
+
+       spin_unlock(&od->irq_lock);
+
+       return IRQ_HANDLED;
+}
+
 static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
 {
+       struct omap_dmadev *od = to_omap_dma_dev(chan->device);
        struct omap_chan *c = to_omap_dma_chan(chan);
+       int ret;
+
+       if (od->legacy) {
+               ret = omap_request_dma(c->dma_sig, "DMA engine",
+                                      omap_dma_callback, c, &c->dma_ch);
+       } else {
+               ret = omap_request_dma(c->dma_sig, "DMA engine", NULL, NULL,
+                                      &c->dma_ch);
+       }
+
+       dev_dbg(od->ddev.dev, "allocating channel %u for %u\n",
+               c->dma_ch, c->dma_sig);
 
-       dev_dbg(c->vc.chan.device->dev, "allocating channel for %u\n", c->dma_sig);
+       if (ret >= 0) {
+               omap_dma_assign(od, c, c->dma_ch);
 
-       return omap_request_dma(c->dma_sig, "DMA engine",
-               omap_dma_callback, c, &c->dma_ch);
+               if (!od->legacy) {
+                       unsigned val;
+
+                       spin_lock_irq(&od->irq_lock);
+                       val = BIT(c->dma_ch);
+                       omap_dma_glbl_write(od, IRQSTATUS_L1, val);
+                       od->irq_enable_mask |= val;
+                       omap_dma_glbl_write(od, IRQENABLE_L1, od->irq_enable_mask);
+
+                       val = omap_dma_glbl_read(od, IRQENABLE_L0);
+                       val &= ~BIT(c->dma_ch);
+                       omap_dma_glbl_write(od, IRQENABLE_L0, val);
+                       spin_unlock_irq(&od->irq_lock);
+               }
+       }
+
+       if (dma_omap1()) {
+               if (__dma_omap16xx(od->plat->dma_attr)) {
+                       c->ccr = CCR_OMAP31_DISABLE;
+                       /* Duplicate what plat-omap/dma.c does */
+                       c->ccr |= c->dma_ch + 1;
+               } else {
+                       c->ccr = c->dma_sig & 0x1f;
+               }
+       } else {
+               c->ccr = c->dma_sig & 0x1f;
+               c->ccr |= (c->dma_sig & ~0x1f) << 14;
+       }
+       if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
+               c->ccr |= CCR_BUFFERING_DISABLE;
+
+       return ret;
 }
 
 static void omap_dma_free_chan_resources(struct dma_chan *chan)
 {
+       struct omap_dmadev *od = to_omap_dma_dev(chan->device);
        struct omap_chan *c = to_omap_dma_chan(chan);
 
+       if (!od->legacy) {
+               spin_lock_irq(&od->irq_lock);
+               od->irq_enable_mask &= ~BIT(c->dma_ch);
+               omap_dma_glbl_write(od, IRQENABLE_L1, od->irq_enable_mask);
+               spin_unlock_irq(&od->irq_lock);
+       }
+
+       c->channel_base = NULL;
+       od->lch_map[c->dma_ch] = NULL;
        vchan_free_chan_resources(&c->vc);
        omap_free_dma(c->dma_ch);
 
-       dev_dbg(c->vc.chan.device->dev, "freeing channel for %u\n", c->dma_sig);
+       dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
 }
 
 static size_t omap_dma_sg_size(struct omap_sg *sg)
@@ -239,6 +624,74 @@ static size_t omap_dma_desc_size_pos(struct omap_desc *d, dma_addr_t addr)
        return size;
 }
 
+/*
+ * OMAP 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+static uint32_t omap_dma_chan_read_3_3(struct omap_chan *c, unsigned reg)
+{
+       struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+       uint32_t val;
+
+       val = omap_dma_chan_read(c, reg);
+       if (val == 0 && od->plat->errata & DMA_ERRATA_3_3)
+               val = omap_dma_chan_read(c, reg);
+
+       return val;
+}
+
+static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
+{
+       struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+       dma_addr_t addr, cdac;
+
+       if (__dma_omap15xx(od->plat->dma_attr)) {
+               addr = omap_dma_chan_read(c, CPC);
+       } else {
+               addr = omap_dma_chan_read_3_3(c, CSAC);
+               cdac = omap_dma_chan_read_3_3(c, CDAC);
+
+               /*
+                * CDAC == 0 indicates that the DMA transfer on the channel has
+                * not been started (no data has been transferred so far).
+                * Return the programmed source start address in this case.
+                */
+               if (cdac == 0)
+                       addr = omap_dma_chan_read(c, CSSA);
+       }
+
+       if (dma_omap1())
+               addr |= omap_dma_chan_read(c, CSSA) & 0xffff0000;
+
+       return addr;
+}
+
+static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c)
+{
+       struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
+       dma_addr_t addr;
+
+       if (__dma_omap15xx(od->plat->dma_attr)) {
+               addr = omap_dma_chan_read(c, CPC);
+       } else {
+               addr = omap_dma_chan_read_3_3(c, CDAC);
+
+               /*
+                * CDAC == 0 indicates that the DMA transfer on the channel
+                * has not been started (no data has been transferred so
+                * far).  Return the programmed destination start address in
+                * this case.
+                */
+               if (addr == 0)
+                       addr = omap_dma_chan_read(c, CDSA);
+       }
+
+       if (dma_omap1())
+               addr |= omap_dma_chan_read(c, CDSA) & 0xffff0000;
+
+       return addr;
+}
+
 static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
        dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
@@ -260,9 +713,9 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
                dma_addr_t pos;
 
                if (d->dir == DMA_MEM_TO_DEV)
-                       pos = omap_get_dma_src_pos(c->dma_ch);
+                       pos = omap_dma_get_src_pos(c);
                else if (d->dir == DMA_DEV_TO_MEM)
-                       pos = omap_get_dma_dst_pos(c->dma_ch);
+                       pos = omap_dma_get_dst_pos(c);
                else
                        pos = 0;
 
@@ -304,24 +757,23 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
        struct dma_chan *chan, struct scatterlist *sgl, unsigned sglen,
        enum dma_transfer_direction dir, unsigned long tx_flags, void *context)
 {
+       struct omap_dmadev *od = to_omap_dma_dev(chan->device);
        struct omap_chan *c = to_omap_dma_chan(chan);
        enum dma_slave_buswidth dev_width;
        struct scatterlist *sgent;
        struct omap_desc *d;
        dma_addr_t dev_addr;
-       unsigned i, j = 0, es, en, frame_bytes, sync_type;
+       unsigned i, j = 0, es, en, frame_bytes;
        u32 burst;
 
        if (dir == DMA_DEV_TO_MEM) {
                dev_addr = c->cfg.src_addr;
                dev_width = c->cfg.src_addr_width;
                burst = c->cfg.src_maxburst;
-               sync_type = OMAP_DMA_SRC_SYNC;
        } else if (dir == DMA_MEM_TO_DEV) {
                dev_addr = c->cfg.dst_addr;
                dev_width = c->cfg.dst_addr_width;
                burst = c->cfg.dst_maxburst;
-               sync_type = OMAP_DMA_DST_SYNC;
        } else {
                dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
                return NULL;
@@ -330,13 +782,13 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
        /* Bus width translates to the element size (ES) */
        switch (dev_width) {
        case DMA_SLAVE_BUSWIDTH_1_BYTE:
-               es = OMAP_DMA_DATA_TYPE_S8;
+               es = CSDP_DATA_TYPE_8;
                break;
        case DMA_SLAVE_BUSWIDTH_2_BYTES:
-               es = OMAP_DMA_DATA_TYPE_S16;
+               es = CSDP_DATA_TYPE_16;
                break;
        case DMA_SLAVE_BUSWIDTH_4_BYTES:
-               es = OMAP_DMA_DATA_TYPE_S32;
+               es = CSDP_DATA_TYPE_32;
                break;
        default: /* not reached */
                return NULL;
@@ -350,9 +802,31 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
        d->dir = dir;
        d->dev_addr = dev_addr;
        d->es = es;
-       d->sync_mode = OMAP_DMA_SYNC_FRAME;
-       d->sync_type = sync_type;
-       d->periph_port = OMAP_DMA_PORT_TIPB;
+
+       d->ccr = c->ccr | CCR_SYNC_FRAME;
+       if (dir == DMA_DEV_TO_MEM)
+               d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
+       else
+               d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC;
+
+       d->cicr = CICR_DROP_IE | CICR_BLOCK_IE;
+       d->csdp = es;
+
+       if (dma_omap1()) {
+               d->cicr |= CICR_TOUT_IE;
+
+               if (dir == DMA_DEV_TO_MEM)
+                       d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_TIPB;
+               else
+                       d->csdp |= CSDP_DST_PORT_TIPB | CSDP_SRC_PORT_EMIFF;
+       } else {
+               if (dir == DMA_DEV_TO_MEM)
+                       d->ccr |= CCR_TRIGGER_SRC;
+
+               d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
+       }
+       if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
+               d->clnk_ctrl = c->dma_ch;
 
        /*
         * Build our scatterlist entries: each contains the address,
@@ -382,23 +856,22 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
        size_t period_len, enum dma_transfer_direction dir, unsigned long flags,
        void *context)
 {
+       struct omap_dmadev *od = to_omap_dma_dev(chan->device);
        struct omap_chan *c = to_omap_dma_chan(chan);
        enum dma_slave_buswidth dev_width;
        struct omap_desc *d;
        dma_addr_t dev_addr;
-       unsigned es, sync_type;
+       unsigned es;
        u32 burst;
 
        if (dir == DMA_DEV_TO_MEM) {
                dev_addr = c->cfg.src_addr;
                dev_width = c->cfg.src_addr_width;
                burst = c->cfg.src_maxburst;
-               sync_type = OMAP_DMA_SRC_SYNC;
        } else if (dir == DMA_MEM_TO_DEV) {
                dev_addr = c->cfg.dst_addr;
                dev_width = c->cfg.dst_addr_width;
                burst = c->cfg.dst_maxburst;
-               sync_type = OMAP_DMA_DST_SYNC;
        } else {
                dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
                return NULL;
@@ -407,13 +880,13 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
        /* Bus width translates to the element size (ES) */
        switch (dev_width) {
        case DMA_SLAVE_BUSWIDTH_1_BYTE:
-               es = OMAP_DMA_DATA_TYPE_S8;
+               es = CSDP_DATA_TYPE_8;
                break;
        case DMA_SLAVE_BUSWIDTH_2_BYTES:
-               es = OMAP_DMA_DATA_TYPE_S16;
+               es = CSDP_DATA_TYPE_16;
                break;
        case DMA_SLAVE_BUSWIDTH_4_BYTES:
-               es = OMAP_DMA_DATA_TYPE_S32;
+               es = CSDP_DATA_TYPE_32;
                break;
        default: /* not reached */
                return NULL;
@@ -428,32 +901,51 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
        d->dev_addr = dev_addr;
        d->fi = burst;
        d->es = es;
-       if (burst)
-               d->sync_mode = OMAP_DMA_SYNC_PACKET;
-       else
-               d->sync_mode = OMAP_DMA_SYNC_ELEMENT;
-       d->sync_type = sync_type;
-       d->periph_port = OMAP_DMA_PORT_MPUI;
        d->sg[0].addr = buf_addr;
        d->sg[0].en = period_len / es_bytes[es];
        d->sg[0].fn = buf_len / period_len;
        d->sglen = 1;
 
-       if (!c->cyclic) {
-               c->cyclic = true;
-               omap_dma_link_lch(c->dma_ch, c->dma_ch);
+       d->ccr = c->ccr;
+       if (dir == DMA_DEV_TO_MEM)
+               d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
+       else
+               d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC;
 
-               if (flags & DMA_PREP_INTERRUPT)
-                       omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ);
+       d->cicr = CICR_DROP_IE;
+       if (flags & DMA_PREP_INTERRUPT)
+               d->cicr |= CICR_FRAME_IE;
 
-               omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ);
-       }
+       d->csdp = es;
+
+       if (dma_omap1()) {
+               d->cicr |= CICR_TOUT_IE;
+
+               if (dir == DMA_DEV_TO_MEM)
+                       d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_MPUI;
+               else
+                       d->csdp |= CSDP_DST_PORT_MPUI | CSDP_SRC_PORT_EMIFF;
+       } else {
+               if (burst)
+                       d->ccr |= CCR_SYNC_PACKET;
+               else
+                       d->ccr |= CCR_SYNC_ELEMENT;
+
+               if (dir == DMA_DEV_TO_MEM)
+                       d->ccr |= CCR_TRIGGER_SRC;
+
+               d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
 
-       if (dma_omap2plus()) {
-               omap_set_dma_src_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16);
-               omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16);
+               d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
        }
 
+       if (__dma_omap15xx(od->plat->dma_attr))
+               d->ccr |= CCR_AUTO_INIT | CCR_REPEAT;
+       else
+               d->clnk_ctrl = c->dma_ch | CLNK_CTRL_ENABLE_LNK;
+
+       c->cyclic = true;
+
        return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
 
@@ -483,20 +975,19 @@ static int omap_dma_terminate_all(struct omap_chan *c)
 
        /*
         * Stop DMA activity: we assume the callback will not be called
-        * after omap_stop_dma() returns (even if it does, it will see
+        * after omap_dma_stop() returns (even if it does, it will see
         * c->desc is NULL and exit.)
         */
        if (c->desc) {
                c->desc = NULL;
                /* Avoid stopping the dma twice */
                if (!c->paused)
-                       omap_stop_dma(c->dma_ch);
+                       omap_dma_stop(c);
        }
 
        if (c->cyclic) {
                c->cyclic = false;
                c->paused = false;
-               omap_dma_unlink_lch(c->dma_ch, c->dma_ch);
        }
 
        vchan_get_all_descriptors(&c->vc, &head);
@@ -513,7 +1004,7 @@ static int omap_dma_pause(struct omap_chan *c)
                return -EINVAL;
 
        if (!c->paused) {
-               omap_stop_dma(c->dma_ch);
+               omap_dma_stop(c);
                c->paused = true;
        }
 
@@ -527,7 +1018,7 @@ static int omap_dma_resume(struct omap_chan *c)
                return -EINVAL;
 
        if (c->paused) {
-               omap_start_dma(c->dma_ch);
+               omap_dma_start(c, c->desc);
                c->paused = false;
        }
 
@@ -573,6 +1064,7 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
        if (!c)
                return -ENOMEM;
 
+       c->reg_map = od->reg_map;
        c->dma_sig = dma_sig;
        c->vc.desc_free = omap_dma_desc_free;
        vchan_init(&c->vc, &od->ddev);
@@ -594,18 +1086,29 @@ static void omap_dma_free(struct omap_dmadev *od)
                tasklet_kill(&c->vc.task);
                kfree(c);
        }
-       kfree(od);
 }
 
 static int omap_dma_probe(struct platform_device *pdev)
 {
        struct omap_dmadev *od;
-       int rc, i;
+       struct resource *res;
+       int rc, i, irq;
 
-       od = kzalloc(sizeof(*od), GFP_KERNEL);
+       od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
        if (!od)
                return -ENOMEM;
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       od->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(od->base))
+               return PTR_ERR(od->base);
+
+       od->plat = omap_get_plat_info();
+       if (!od->plat)
+               return -EPROBE_DEFER;
+
+       od->reg_map = od->plat->reg_map;
+
        dma_cap_set(DMA_SLAVE, od->ddev.cap_mask);
        dma_cap_set(DMA_CYCLIC, od->ddev.cap_mask);
        od->ddev.device_alloc_chan_resources = omap_dma_alloc_chan_resources;
@@ -619,6 +1122,7 @@ static int omap_dma_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&od->ddev.channels);
        INIT_LIST_HEAD(&od->pending);
        spin_lock_init(&od->lock);
+       spin_lock_init(&od->irq_lock);
 
        tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
@@ -630,6 +1134,21 @@ static int omap_dma_probe(struct platform_device *pdev)
                }
        }
 
+       irq = platform_get_irq(pdev, 1);
+       if (irq <= 0) {
+               dev_info(&pdev->dev, "failed to get L1 IRQ: %d\n", irq);
+               od->legacy = true;
+       } else {
+               /* Disable all interrupts */
+               od->irq_enable_mask = 0;
+               omap_dma_glbl_write(od, IRQENABLE_L1, 0);
+
+               rc = devm_request_irq(&pdev->dev, irq, omap_dma_irq,
+                                     IRQF_SHARED, "omap-dma-engine", od);
+               if (rc)
+                       return rc;
+       }
+
        rc = dma_async_device_register(&od->ddev);
        if (rc) {
                pr_warn("OMAP-DMA: failed to register slave DMA engine device: %d\n",
@@ -666,6 +1185,12 @@ static int omap_dma_remove(struct platform_device *pdev)
                of_dma_controller_free(pdev->dev.of_node);
 
        dma_async_device_unregister(&od->ddev);
+
+       if (!od->legacy) {
+               /* Disable all interrupts */
+               omap_dma_glbl_write(od, IRQENABLE_L0, 0);
+       }
+
        omap_dma_free(od);
 
        return 0;
index b335c6ab5efe02e0ef9b5742e8691e617b5a30af..01fae8289cf05fe5f9f95bd3da13628f471aa260 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Written Doug Thompson <norsk5@xmission.com> www.softwarebitmaker.com
  *
- * (c) 2012-2013 - Mauro Carvalho Chehab <mchehab@redhat.com>
+ * (c) 2012-2013 - Mauro Carvalho Chehab
  *     The entire API were re-written, and ported to use struct device
  *
  */
index d5a98a45c062881009bc348f4621358d0a22492c..8399b4e16fe0916683ceb075ff3cb2b49e4baa5b 100644 (file)
@@ -4,7 +4,7 @@
  * This file may be distributed under the terms of the GNU General Public
  * License version 2.
  *
- * Copyright (c) 2013 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2013 by Mauro Carvalho Chehab
  *
  * Red Hat Inc. http://www.redhat.com
  */
index 5381e98d9c0cff20998a111dc492f74f2288947c..6ef6ad1ba16ef3351217074f2ba63316a07276e4 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 2008 by:
  *      Ben Woodard <woodard@redhat.com>
- *      Mauro Carvalho Chehab <mchehab@redhat.com>
+ *      Mauro Carvalho Chehab
  *
  * Red Hat Inc. http://www.redhat.com
  *
@@ -1469,7 +1469,7 @@ module_exit(i5400_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Woodard <woodard@redhat.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("MC Driver for Intel I5400 memory controllers - "
                   I5400_REVISION);
index 57e96a3350f0595ab002a5ff1285d85b44dd6e3f..dcac982fdc7a153fe89191f44c038b5a9da72151 100644 (file)
@@ -5,7 +5,7 @@
  * GNU General Public License version 2 only.
  *
  * Copyright (c) 2010 by:
- *      Mauro Carvalho Chehab <mchehab@redhat.com>
+ *      Mauro Carvalho Chehab
  *
  * Red Hat Inc. http://www.redhat.com
  *
@@ -1209,7 +1209,7 @@ module_init(i7300_init);
 module_exit(i7300_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("MC Driver for Intel I7300 memory controllers - "
                   I7300_REVISION);
index 8bc83b99974b946f170e44d70d8d0c00f9182be3..9cd0b301f81ba5a5a3fb52dfcc87ef337d7bcb41 100644 (file)
@@ -9,7 +9,7 @@
  * GNU General Public License version 2 only.
  *
  * Copyright (c) 2009-2010 by:
- *      Mauro Carvalho Chehab <mchehab@redhat.com>
+ *      Mauro Carvalho Chehab
  *
  * Red Hat Inc. http://www.redhat.com
  *
@@ -2457,7 +2457,7 @@ module_init(i7core_init);
 module_exit(i7core_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
                   I7CORE_REVISION);
index c460ba5d65a85fd7c68857834880771c9ff9700a..deea0dc9999bf1bb54d58fd2d43d4c98036d690e 100644 (file)
@@ -7,7 +7,7 @@
  * GNU General Public License version 2 only.
  *
  * Copyright (c) 2011 by:
- *      Mauro Carvalho Chehab <mchehab@redhat.com>
+ *      Mauro Carvalho Chehab
  */
 
 #include <linux/module.h>
@@ -2183,7 +2183,7 @@ module_param(edac_op_state, int, 0444);
 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("MC Driver for Intel Sandy Bridge and Ivy Bridge memory controllers - "
                   SBRIDGE_REVISION);
index 92d8e9a064b42d28224f027c94422d19ba3a817e..a86c49a605c63627b90d1def6fd8b038482ab005 100644 (file)
@@ -210,7 +210,7 @@ config GPIO_MSM_V1
 
 config GPIO_MSM_V2
        tristate "Qualcomm MSM GPIO v2"
-       depends on GPIOLIB && OF && ARCH_MSM
+       depends on GPIOLIB && OF && ARCH_QCOM
        help
          Say yes here to support the GPIO interface on ARM v7 based
          Qualcomm MSM chips.  Most of the pins on the MSM can be
index bfef20f8ab4810b918739905f10369c95d7128b3..e73c6755a5eb6b324d06f14f4a7cf574d025c8ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Intel ICH6-10, Series 5 and 6 GPIO driver
+ * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
  *
  * Copyright (C) 2010 Extreme Engineering Solutions.
  *
@@ -55,6 +55,16 @@ static const u8 ichx_reglen[3] = {
        0x30, 0x10, 0x10,
 };
 
+static const u8 avoton_regs[4][3] = {
+       {0x00, 0x80, 0x00},
+       {0x04, 0x84, 0x00},
+       {0x08, 0x88, 0x00},
+};
+
+static const u8 avoton_reglen[3] = {
+       0x10, 0x10, 0x00,
+};
+
 #define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
 #define ICHX_READ(reg, base_res)       inl((reg) + (base_res)->start)
 
@@ -353,6 +363,17 @@ static struct ichx_desc intel5_desc = {
        .reglen = ichx_reglen,
 };
 
+/* Avoton */
+static struct ichx_desc avoton_desc = {
+       /* Avoton has only 59 GPIOs, but we assume the first set of register
+        * (Core) has 32 instead of 31 to keep gpio-ich compliance
+        */
+       .ngpio = 60,
+       .regs = avoton_regs,
+       .reglen = avoton_reglen,
+       .use_outlvl_cache = true,
+};
+
 static int ichx_gpio_request_regions(struct resource *res_base,
                                                const char *name, u8 use_gpio)
 {
@@ -427,6 +448,9 @@ static int ichx_gpio_probe(struct platform_device *pdev)
        case ICH_V10CONS_GPIO:
                ichx_priv.desc = &ich10_cons_desc;
                break;
+       case AVOTON_GPIO:
+               ichx_priv.desc = &avoton_desc;
+               break;
        default:
                return -ENODEV;
        }
index c69d1e07a3a67b397ac798e312df7b31b62e3d20..b6984971ce0c9b928dca6251db2916cdc78c77e9 100644 (file)
@@ -3,7 +3,7 @@ config DRM_MSM
        tristate "MSM DRM"
        depends on DRM
        depends on MSM_IOMMU
-       depends on (ARCH_MSM && ARCH_MSM8960) || (ARM && COMPILE_TEST)
+       depends on ARCH_MSM8960 || (ARM && COMPILE_TEST)
        select DRM_KMS_HELPER
        select SHMEM
        select TMPFS
index 912759daf5625a88bb878f96a15f1ad39bd4c2a2..86f4ead0441d0d2b6e27f8441974f14dd68ed801 100644 (file)
@@ -37,7 +37,7 @@ struct omap_connector {
 void copy_timings_omap_to_drm(struct drm_display_mode *mode,
                struct omap_video_timings *timings)
 {
-       mode->clock = timings->pixel_clock;
+       mode->clock = timings->pixelclock / 1000;
 
        mode->hdisplay = timings->x_res;
        mode->hsync_start = mode->hdisplay + timings->hfp;
@@ -68,7 +68,7 @@ void copy_timings_omap_to_drm(struct drm_display_mode *mode,
 void copy_timings_drm_to_omap(struct omap_video_timings *timings,
                struct drm_display_mode *mode)
 {
-       timings->pixel_clock = mode->clock;
+       timings->pixelclock = mode->clock * 1000;
 
        timings->x_res = mode->hdisplay;
        timings->hfp = mode->hsync_start - mode->hdisplay;
@@ -220,7 +220,7 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
        if (!r) {
                /* check if vrefresh is still valid */
                new_mode = drm_mode_duplicate(dev, mode);
-               new_mode->clock = timings.pixel_clock;
+               new_mode->clock = timings.pixelclock / 1000;
                new_mode->vrefresh = 0;
                if (mode->vrefresh == drm_mode_vrefresh(new_mode))
                        ret = MODE_OK;
index 59d5eb1e742c98b8721f14a100528b587c25e3ef..cf1a9f1c12170542bca294c9706911532bb224f9 100644 (file)
@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
 
        rdev->priv             = data;
        rdev->driver_type      = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos   = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        rdev->open             = picolcd_cir_open;
        rdev->close            = picolcd_cir_close;
        rdev->input_name       = data->hdev->name;
index 29dd9f746dfa23efea7206277a60f950a2d6eddf..3eb4281689b565d3796a7ae82ee5ed4bd45b4773 100644 (file)
@@ -79,9 +79,11 @@ enum chips {
 
 /* Each client has this additional data */
 struct adm1021_data {
-       struct device *hwmon_dev;
+       struct i2c_client *client;
        enum chips type;
 
+       const struct attribute_group *groups[3];
+
        struct mutex update_lock;
        char valid;             /* !=0 if following fields are valid */
        char low_power;         /* !=0 if device in low power mode */
@@ -101,7 +103,6 @@ static int adm1021_probe(struct i2c_client *client,
 static int adm1021_detect(struct i2c_client *client,
                          struct i2c_board_info *info);
 static void adm1021_init_client(struct i2c_client *client);
-static int adm1021_remove(struct i2c_client *client);
 static struct adm1021_data *adm1021_update_device(struct device *dev);
 
 /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
@@ -128,7 +129,6 @@ static struct i2c_driver adm1021_driver = {
                .name   = "adm1021",
        },
        .probe          = adm1021_probe,
-       .remove         = adm1021_remove,
        .id_table       = adm1021_id,
        .detect         = adm1021_detect,
        .address_list   = normal_i2c,
@@ -182,8 +182,8 @@ static ssize_t set_temp_max(struct device *dev,
                            const char *buf, size_t count)
 {
        int index = to_sensor_dev_attr(devattr)->index;
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adm1021_data *data = i2c_get_clientdata(client);
+       struct adm1021_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long temp;
        int err;
 
@@ -207,8 +207,8 @@ static ssize_t set_temp_min(struct device *dev,
                            const char *buf, size_t count)
 {
        int index = to_sensor_dev_attr(devattr)->index;
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adm1021_data *data = i2c_get_clientdata(client);
+       struct adm1021_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long temp;
        int err;
 
@@ -238,8 +238,8 @@ static ssize_t set_low_power(struct device *dev,
                             struct device_attribute *devattr,
                             const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adm1021_data *data = i2c_get_clientdata(client);
+       struct adm1021_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        char low_power;
        unsigned long val;
        int err;
@@ -412,15 +412,15 @@ static int adm1021_detect(struct i2c_client *client,
 static int adm1021_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
+       struct device *dev = &client->dev;
        struct adm1021_data *data;
-       int err;
+       struct device *hwmon_dev;
 
-       data = devm_kzalloc(&client->dev, sizeof(struct adm1021_data),
-                           GFP_KERNEL);
+       data = devm_kzalloc(dev, sizeof(struct adm1021_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
-       i2c_set_clientdata(client, data);
+       data->client = client;
        data->type = id->driver_data;
        mutex_init(&data->update_lock);
 
@@ -428,29 +428,14 @@ static int adm1021_probe(struct i2c_client *client,
        if (data->type != lm84 && !read_only)
                adm1021_init_client(client);
 
-       /* Register sysfs hooks */
-       err = sysfs_create_group(&client->dev.kobj, &adm1021_group);
-       if (err)
-               return err;
-
-       if (data->type != lm84) {
-               err = sysfs_create_group(&client->dev.kobj, &adm1021_min_group);
-               if (err)
-                       goto error;
-       }
+       data->groups[0] = &adm1021_group;
+       if (data->type != lm84)
+               data->groups[1] = &adm1021_min_group;
 
-       data->hwmon_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto error;
-       }
+       hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+                                                          data, data->groups);
 
-       return 0;
-
-error:
-       sysfs_remove_group(&client->dev.kobj, &adm1021_min_group);
-       sysfs_remove_group(&client->dev.kobj, &adm1021_group);
-       return err;
+       return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
 static void adm1021_init_client(struct i2c_client *client)
@@ -462,21 +447,10 @@ static void adm1021_init_client(struct i2c_client *client)
        i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
 }
 
-static int adm1021_remove(struct i2c_client *client)
-{
-       struct adm1021_data *data = i2c_get_clientdata(client);
-
-       hwmon_device_unregister(data->hwmon_dev);
-       sysfs_remove_group(&client->dev.kobj, &adm1021_min_group);
-       sysfs_remove_group(&client->dev.kobj, &adm1021_group);
-
-       return 0;
-}
-
 static struct adm1021_data *adm1021_update_device(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adm1021_data *data = i2c_get_clientdata(client);
+       struct adm1021_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
 
        mutex_lock(&data->update_lock);
 
@@ -484,7 +458,7 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
            || !data->valid) {
                int i;
 
-               dev_dbg(&client->dev, "Starting adm1021 update\n");
+               dev_dbg(dev, "Starting adm1021 update\n");
 
                for (i = 0; i < 2; i++) {
                        data->temp[i] = 1000 *
index 8d9f2a0e8efea262aaef5311133af527f66a7315..71463689d163d794916f692595475a4332baface 100644 (file)
@@ -1115,7 +1115,6 @@ asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id)
                return -ENOMEM;
 
        i2c_set_clientdata(client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Initialize the asc7621 chip */
index ddff02e3e66f9ad464b13261eaf0a7d0b76b9218..6edce42c61d51188df6d5e3e652125197558da9b 100644 (file)
@@ -353,8 +353,6 @@ static int atxp1_probe(struct i2c_client *new_client,
        data->vrm = vid_which_vrm();
 
        i2c_set_clientdata(new_client, data);
-       data->valid = 0;
-
        mutex_init(&data->update_lock);
 
        /* Register sysfs hooks */
index f31bc4c4864411ae8bd3267d27575c5444ac71e1..6d02e3b063756f6225078df7e00f981478ef5f45 100644 (file)
@@ -810,20 +810,20 @@ static int __init coretemp_init(void)
        if (err)
                goto exit;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
        for_each_online_cpu(i)
                get_core_online(i);
 
 #ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
-               put_online_cpus();
+               cpu_notifier_register_done();
                err = -ENODEV;
                goto exit_driver_unreg;
        }
 #endif
 
-       register_hotcpu_notifier(&coretemp_cpu_notifier);
-       put_online_cpus();
+       __register_hotcpu_notifier(&coretemp_cpu_notifier);
+       cpu_notifier_register_done();
        return 0;
 
 #ifndef CONFIG_HOTPLUG_CPU
@@ -838,8 +838,8 @@ static void __exit coretemp_exit(void)
 {
        struct pdev_entry *p, *n;
 
-       get_online_cpus();
-       unregister_hotcpu_notifier(&coretemp_cpu_notifier);
+       cpu_notifier_register_begin();
+       __unregister_hotcpu_notifier(&coretemp_cpu_notifier);
        mutex_lock(&pdev_list_mutex);
        list_for_each_entry_safe(p, n, &pdev_list, list) {
                platform_device_unregister(p->pdev);
@@ -847,7 +847,7 @@ static void __exit coretemp_exit(void)
                kfree(p);
        }
        mutex_unlock(&pdev_list_mutex);
-       put_online_cpus();
+       cpu_notifier_register_done();
        platform_driver_unregister(&coretemp_driver);
 }
 
index 1a8aa1265262e392dd246a8aecfd39d9e997e75b..32f5132c4652d43b89037f9ec16934d5f4d685f4 100644 (file)
@@ -1648,7 +1648,7 @@ static void __exit f71805f_exit(void)
        platform_driver_unregister(&f71805f_driver);
 }
 
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
+MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("F71805F/F71872F hardware monitoring driver");
 
index 70749fc15a4f4fdf07155a995513b7872b3bc4e6..a327fd3402a7dd4c6c5d028b45291c8839492172 100644 (file)
@@ -11,6 +11,7 @@
  *  similar parts.  The other devices are supported by different drivers.
  *
  *  Supports: IT8603E  Super I/O chip w/LPC interface
+ *            IT8623E  Super I/O chip w/LPC interface
  *            IT8705F  Super I/O chip w/LPC interface
  *            IT8712F  Super I/O chip w/LPC interface
  *            IT8716F  Super I/O chip w/LPC interface
@@ -147,7 +148,8 @@ static inline void superio_exit(void)
 #define IT8772E_DEVID 0x8772
 #define IT8782F_DEVID 0x8782
 #define IT8783E_DEVID 0x8783
-#define IT8306E_DEVID 0x8603
+#define IT8603E_DEVID 0x8603
+#define IT8623E_DEVID 0x8623
 #define IT87_ACT_REG  0x30
 #define IT87_BASE_REG 0x60
 
@@ -1431,7 +1433,7 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
 static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
 static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
 static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
-/* special AVCC3 IT8306E in9 */
+/* special AVCC3 IT8603E in9 */
 static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 0);
 
 static ssize_t show_name(struct device *dev, struct device_attribute
@@ -1766,7 +1768,8 @@ static int __init it87_find(unsigned short *address,
        case IT8783E_DEVID:
                sio_data->type = it8783;
                break;
-       case IT8306E_DEVID:
+       case IT8603E_DEVID:
+       case IT8623E_DEVID:
                sio_data->type = it8603;
                break;
        case 0xffff:    /* No device at all */
index b4ad598feb6c8ee10b7eb3b05ddfef38cf75fc9a..848b9611151f9507c21c74d2de94220ab475d2e8 100644 (file)
@@ -155,8 +155,9 @@ enum chips { lm63, lm64, lm96163 };
  */
 
 struct lm63_data {
-       struct device *hwmon_dev;
+       struct i2c_client *client;
        struct mutex update_lock;
+       const struct attribute_group *groups[5];
        char valid; /* zero until following fields are valid */
        char lut_valid; /* zero until lut fields are valid */
        unsigned long last_updated; /* in jiffies */
@@ -218,9 +219,9 @@ static inline int lut_temp_to_reg(struct lm63_data *data, long val)
  * Update the lookup table register cache.
  * client->update_lock must be held when calling this function.
  */
-static void lm63_update_lut(struct i2c_client *client)
+static void lm63_update_lut(struct lm63_data *data)
 {
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct i2c_client *client = data->client;
        int i;
 
        if (time_after(jiffies, data->lut_last_updated + 5 * HZ) ||
@@ -241,8 +242,8 @@ static void lm63_update_lut(struct i2c_client *client)
 
 static struct lm63_data *lm63_update_device(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long next_update;
 
        mutex_lock(&data->update_lock);
@@ -310,7 +311,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
                data->valid = 1;
        }
 
-       lm63_update_lut(client);
+       lm63_update_lut(data);
 
        mutex_unlock(&data->update_lock);
 
@@ -321,18 +322,17 @@ static struct lm63_data *lm63_update_device(struct device *dev)
  * Trip points in the lookup table should be in ascending order for both
  * temperatures and PWM output values.
  */
-static int lm63_lut_looks_bad(struct i2c_client *client)
+static int lm63_lut_looks_bad(struct device *dev, struct lm63_data *data)
 {
-       struct lm63_data *data = i2c_get_clientdata(client);
        int i;
 
        mutex_lock(&data->update_lock);
-       lm63_update_lut(client);
+       lm63_update_lut(data);
 
        for (i = 1; i < data->lut_size; i++) {
                if (data->pwm1[1 + i - 1] > data->pwm1[1 + i]
                 || data->temp8[3 + i - 1] > data->temp8[3 + i]) {
-                       dev_warn(&client->dev,
+                       dev_warn(dev,
                                 "Lookup table doesn't look sane (check entries %d and %d)\n",
                                 i, i + 1);
                        break;
@@ -358,8 +358,8 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
                       const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long val;
        int err;
 
@@ -399,8 +399,8 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr,
                        const char *buf, size_t count)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int nr = attr->index;
        unsigned long val;
        int err;
@@ -435,8 +435,8 @@ static ssize_t set_pwm1_enable(struct device *dev,
                               struct device_attribute *dummy,
                               const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long val;
        int err;
 
@@ -450,7 +450,7 @@ static ssize_t set_pwm1_enable(struct device *dev,
         * Only let the user switch to automatic mode if the lookup table
         * looks sane.
         */
-       if (val == 2 && lm63_lut_looks_bad(client))
+       if (val == 2 && lm63_lut_looks_bad(dev, data))
                return -EPERM;
 
        mutex_lock(&data->update_lock);
@@ -461,7 +461,7 @@ static ssize_t set_pwm1_enable(struct device *dev,
        else
                data->config_fan &= ~0x20;
        i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN,
-       data->config_fan);
+                                 data->config_fan);
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -505,8 +505,8 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
                         const char *buf, size_t count)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int nr = attr->index;
        long val;
        int err;
@@ -579,8 +579,8 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
        };
 
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long val;
        int err;
        int nr = attr->index;
@@ -635,8 +635,8 @@ static ssize_t set_temp2_crit_hyst(struct device *dev,
                                   struct device_attribute *dummy,
                                   const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long val;
        int err;
        long hyst;
@@ -657,11 +657,11 @@ static ssize_t set_temp2_crit_hyst(struct device *dev,
  * Set conversion rate.
  * client->update_lock must be held when calling this function.
  */
-static void lm63_set_convrate(struct i2c_client *client, struct lm63_data *data,
-                             unsigned int interval)
+static void lm63_set_convrate(struct lm63_data *data, unsigned int interval)
 {
-       int i;
+       struct i2c_client *client = data->client;
        unsigned int update_interval;
+       int i;
 
        /* Shift calculations to avoid rounding errors */
        interval <<= 6;
@@ -689,8 +689,7 @@ static ssize_t set_update_interval(struct device *dev,
                                   struct device_attribute *attr,
                                   const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
        unsigned long val;
        int err;
 
@@ -699,7 +698,7 @@ static ssize_t set_update_interval(struct device *dev,
                return err;
 
        mutex_lock(&data->update_lock);
-       lm63_set_convrate(client, data, clamp_val(val, 0, 100000));
+       lm63_set_convrate(data, clamp_val(val, 0, 100000));
        mutex_unlock(&data->update_lock);
 
        return count;
@@ -708,8 +707,7 @@ static ssize_t set_update_interval(struct device *dev,
 static ssize_t show_type(struct device *dev, struct device_attribute *attr,
                         char *buf)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
 
        return sprintf(buf, data->trutherm ? "1\n" : "2\n");
 }
@@ -717,8 +715,8 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr,
 static ssize_t set_type(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long val;
        int ret;
        u8 reg;
@@ -915,6 +913,15 @@ static struct attribute *lm63_attributes[] = {
        NULL
 };
 
+static struct attribute *lm63_attributes_temp2_type[] = {
+       &dev_attr_temp2_type.attr,
+       NULL
+};
+
+static const struct attribute_group lm63_group_temp2_type = {
+       .attrs = lm63_attributes_temp2_type,
+};
+
 static struct attribute *lm63_attributes_extra_lut[] = {
        &sensor_dev_attr_pwm1_auto_point9_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point9_temp.dev_attr.attr,
@@ -946,8 +953,7 @@ static umode_t lm63_attribute_mode(struct kobject *kobj,
                                   struct attribute *attr, int index)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct lm63_data *data = dev_get_drvdata(dev);
 
        if (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr
            && (data->kind == lm64 ||
@@ -1026,9 +1032,10 @@ static int lm63_detect(struct i2c_client *client,
  * Ideally we shouldn't have to initialize anything, since the BIOS
  * should have taken care of everything
  */
-static void lm63_init_client(struct i2c_client *client)
+static void lm63_init_client(struct lm63_data *data)
 {
-       struct lm63_data *data = i2c_get_clientdata(client);
+       struct i2c_client *client = data->client;
+       struct device *dev = &client->dev;
        u8 convrate;
 
        data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
@@ -1037,7 +1044,7 @@ static void lm63_init_client(struct i2c_client *client)
 
        /* Start converting if needed */
        if (data->config & 0x40) { /* standby */
-               dev_dbg(&client->dev, "Switching to operational mode\n");
+               dev_dbg(dev, "Switching to operational mode\n");
                data->config &= 0xA7;
                i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
                                          data->config);
@@ -1090,13 +1097,13 @@ static void lm63_init_client(struct i2c_client *client)
 
        /* Show some debug info about the LM63 configuration */
        if (data->kind == lm63)
-               dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",
+               dev_dbg(dev, "Alert/tach pin configured for %s\n",
                        (data->config & 0x04) ? "tachometer input" :
                        "alert output");
-       dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
+       dev_dbg(dev, "PWM clock %s kHz, output frequency %u Hz\n",
                (data->config_fan & 0x08) ? "1.4" : "360",
                ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
-       dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
+       dev_dbg(dev, "PWM output active %s, %s mode\n",
                (data->config_fan & 0x10) ? "low" : "high",
                (data->config_fan & 0x20) ? "manual" : "auto");
 }
@@ -1104,15 +1111,16 @@ static void lm63_init_client(struct i2c_client *client)
 static int lm63_probe(struct i2c_client *client,
                      const struct i2c_device_id *id)
 {
+       struct device *dev = &client->dev;
+       struct device *hwmon_dev;
        struct lm63_data *data;
-       int err;
+       int groups = 0;
 
-       data = devm_kzalloc(&client->dev, sizeof(struct lm63_data), GFP_KERNEL);
+       data = devm_kzalloc(dev, sizeof(struct lm63_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
-       i2c_set_clientdata(client, data);
-       data->valid = 0;
+       data->client = client;
        mutex_init(&data->update_lock);
 
        /* Set the device type */
@@ -1121,59 +1129,21 @@ static int lm63_probe(struct i2c_client *client,
                data->temp2_offset = 16000;
 
        /* Initialize chip */
-       lm63_init_client(client);
+       lm63_init_client(data);
 
        /* Register sysfs hooks */
-       err = sysfs_create_group(&client->dev.kobj, &lm63_group);
-       if (err)
-               return err;
-       if (data->config & 0x04) { /* tachometer enabled */
-               err = sysfs_create_group(&client->dev.kobj, &lm63_group_fan1);
-               if (err)
-                       goto exit_remove_files;
-       }
-       if (data->kind == lm96163) {
-               err = device_create_file(&client->dev, &dev_attr_temp2_type);
-               if (err)
-                       goto exit_remove_files;
-
-               err = sysfs_create_group(&client->dev.kobj,
-                                        &lm63_group_extra_lut);
-               if (err)
-                       goto exit_remove_files;
-       }
-
-       data->hwmon_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto exit_remove_files;
-       }
+       data->groups[groups++] = &lm63_group;
+       if (data->config & 0x04)        /* tachometer enabled */
+               data->groups[groups++] = &lm63_group_fan1;
 
-       return 0;
-
-exit_remove_files:
-       sysfs_remove_group(&client->dev.kobj, &lm63_group);
-       sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
        if (data->kind == lm96163) {
-               device_remove_file(&client->dev, &dev_attr_temp2_type);
-               sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut);
+               data->groups[groups++] = &lm63_group_temp2_type;
+               data->groups[groups++] = &lm63_group_extra_lut;
        }
-       return err;
-}
-
-static int lm63_remove(struct i2c_client *client)
-{
-       struct lm63_data *data = i2c_get_clientdata(client);
 
-       hwmon_device_unregister(data->hwmon_dev);
-       sysfs_remove_group(&client->dev.kobj, &lm63_group);
-       sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
-       if (data->kind == lm96163) {
-               device_remove_file(&client->dev, &dev_attr_temp2_type);
-               sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut);
-       }
-
-       return 0;
+       hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+                                                          data, data->groups);
+       return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
 /*
@@ -1194,7 +1164,6 @@ static struct i2c_driver lm63_driver = {
                .name   = "lm63",
        },
        .probe          = lm63_probe,
-       .remove         = lm63_remove,
        .id_table       = lm63_id,
        .detect         = lm63_detect,
        .address_list   = normal_i2c,
index f17beb5e6dd63bd7055f35492546c452c2fedcb1..502771c06fd99e73ce6bc9b51e5d3413fdc6d95f 100644 (file)
@@ -348,7 +348,6 @@ static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id)
                return -ENOMEM;
 
        i2c_set_clientdata(client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Initialize the LM77 chip */
index eba89aac3ecefbce3783329a546e5a66682bda94..bd0a1ebbf867c31be2ce98b6c45e766370eca5fe 100644 (file)
@@ -112,7 +112,7 @@ static inline long TEMP_FROM_REG(u16 temp)
  */
 
 struct lm80_data {
-       struct device *hwmon_dev;
+       struct i2c_client *client;
        struct mutex update_lock;
        char error;             /* !=0 if error occurred during last update */
        char valid;             /* !=0 if following fields are valid */
@@ -140,7 +140,6 @@ static int lm80_probe(struct i2c_client *client,
                      const struct i2c_device_id *id);
 static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info);
 static void lm80_init_client(struct i2c_client *client);
-static int lm80_remove(struct i2c_client *client);
 static struct lm80_data *lm80_update_device(struct device *dev);
 static int lm80_read_value(struct i2c_client *client, u8 reg);
 static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
@@ -162,7 +161,6 @@ static struct i2c_driver lm80_driver = {
                .name   = "lm80",
        },
        .probe          = lm80_probe,
-       .remove         = lm80_remove,
        .id_table       = lm80_id,
        .detect         = lm80_detect,
        .address_list   = normal_i2c,
@@ -191,8 +189,8 @@ static ssize_t set_in_##suffix(struct device *dev, \
        struct device_attribute *attr, const char *buf, size_t count) \
 { \
        int nr = to_sensor_dev_attr(attr)->index; \
-       struct i2c_client *client = to_i2c_client(dev); \
-       struct lm80_data *data = i2c_get_clientdata(client); \
+       struct lm80_data *data = dev_get_drvdata(dev); \
+       struct i2c_client *client = data->client; \
        long val; \
        int err = kstrtol(buf, 10, &val); \
        if (err < 0) \
@@ -235,8 +233,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
        const char *buf, size_t count)
 {
        int nr = to_sensor_dev_attr(attr)->index;
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm80_data *data = i2c_get_clientdata(client);
+       struct lm80_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long val;
        int err = kstrtoul(buf, 10, &val);
        if (err < 0)
@@ -259,8 +257,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
        const char *buf, size_t count)
 {
        int nr = to_sensor_dev_attr(attr)->index;
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm80_data *data = i2c_get_clientdata(client);
+       struct lm80_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long min, val;
        u8 reg;
        int err = kstrtoul(buf, 10, &val);
@@ -286,7 +284,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
                data->fan_div[nr] = 3;
                break;
        default:
-               dev_err(&client->dev,
+               dev_err(dev,
                        "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n",
                        val);
                mutex_unlock(&data->update_lock);
@@ -332,8 +330,8 @@ show_temp(os_hyst, temp_os_hyst);
 static ssize_t set_temp_##suffix(struct device *dev, \
        struct device_attribute *attr, const char *buf, size_t count) \
 { \
-       struct i2c_client *client = to_i2c_client(dev); \
-       struct lm80_data *data = i2c_get_clientdata(client); \
+       struct lm80_data *data = dev_get_drvdata(dev); \
+       struct i2c_client *client = data->client; \
        long val; \
        int err = kstrtol(buf, 10, &val); \
        if (err < 0) \
@@ -440,7 +438,7 @@ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 13);
  * Real code
  */
 
-static struct attribute *lm80_attributes[] = {
+static struct attribute *lm80_attrs[] = {
        &sensor_dev_attr_in0_min.dev_attr.attr,
        &sensor_dev_attr_in1_min.dev_attr.attr,
        &sensor_dev_attr_in2_min.dev_attr.attr,
@@ -487,10 +485,7 @@ static struct attribute *lm80_attributes[] = {
        &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
        NULL
 };
-
-static const struct attribute_group lm80_group = {
-       .attrs = lm80_attributes,
-};
+ATTRIBUTE_GROUPS(lm80);
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
@@ -541,14 +536,15 @@ static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
 static int lm80_probe(struct i2c_client *client,
                      const struct i2c_device_id *id)
 {
+       struct device *dev = &client->dev;
+       struct device *hwmon_dev;
        struct lm80_data *data;
-       int err;
 
-       data = devm_kzalloc(&client->dev, sizeof(struct lm80_data), GFP_KERNEL);
+       data = devm_kzalloc(dev, sizeof(struct lm80_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
-       i2c_set_clientdata(client, data);
+       data->client = client;
        mutex_init(&data->update_lock);
 
        /* Initialize the LM80 chip */
@@ -558,32 +554,10 @@ static int lm80_probe(struct i2c_client *client,
        data->fan_min[0] = lm80_read_value(client, LM80_REG_FAN_MIN(1));
        data->fan_min[1] = lm80_read_value(client, LM80_REG_FAN_MIN(2));
 
-       /* Register sysfs hooks */
-       err = sysfs_create_group(&client->dev.kobj, &lm80_group);
-       if (err)
-               return err;
-
-       data->hwmon_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto error_remove;
-       }
+       hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+                                                          data, lm80_groups);
 
-       return 0;
-
-error_remove:
-       sysfs_remove_group(&client->dev.kobj, &lm80_group);
-       return err;
-}
-
-static int lm80_remove(struct i2c_client *client)
-{
-       struct lm80_data *data = i2c_get_clientdata(client);
-
-       hwmon_device_unregister(data->hwmon_dev);
-       sysfs_remove_group(&client->dev.kobj, &lm80_group);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
 static int lm80_read_value(struct i2c_client *client, u8 reg)
@@ -614,8 +588,8 @@ static void lm80_init_client(struct i2c_client *client)
 
 static struct lm80_data *lm80_update_device(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm80_data *data = i2c_get_clientdata(client);
+       struct lm80_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int i;
        int rv;
        int prev_rv;
@@ -627,7 +601,7 @@ static struct lm80_data *lm80_update_device(struct device *dev)
                lm80_init_client(client);
 
        if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
-               dev_dbg(&client->dev, "Starting lm80 update\n");
+               dev_dbg(dev, "Starting lm80 update\n");
                for (i = 0; i <= 6; i++) {
                        rv = lm80_read_value(client, LM80_REG_IN(i));
                        if (rv < 0)
index abd270243ba701d2332977eea1e79f485353a4c0..be02155788c3e12ea0ada37b103251c4330a8bf5 100644 (file)
@@ -349,7 +349,6 @@ static int lm83_probe(struct i2c_client *new_client,
                return -ENOMEM;
 
        i2c_set_clientdata(new_client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /*
index 4c5f20231c1a6a71e0daa66116340dfb701ff8b5..ba1d83d480563a14c8bafae0c38df8bb6edd2740 100644 (file)
@@ -903,7 +903,6 @@ static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id)
                return -ENOMEM;
 
        i2c_set_clientdata(client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Initialize the LM87 chip */
index 701e952ae52378477d34c84afd99ce4ebb0e1df1..c9ff08dbe10cefcf8731c1360370edd037307d43 100644 (file)
@@ -365,7 +365,9 @@ enum lm90_temp11_reg_index {
  */
 
 struct lm90_data {
+       struct i2c_client *client;
        struct device *hwmon_dev;
+       const struct attribute_group *groups[6];
        struct mutex update_lock;
        struct regulator *regulator;
        char valid; /* zero until following fields are valid */
@@ -513,8 +515,8 @@ static void lm90_set_convrate(struct i2c_client *client, struct lm90_data *data,
 
 static struct lm90_data *lm90_update_device(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm90_data *data = i2c_get_clientdata(client);
+       struct lm90_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long next_update;
 
        mutex_lock(&data->update_lock);
@@ -793,8 +795,8 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
        };
 
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm90_data *data = i2c_get_clientdata(client);
+       struct lm90_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int nr = attr->index;
        long val;
        int err;
@@ -860,8 +862,8 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
        };
 
        struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm90_data *data = i2c_get_clientdata(client);
+       struct lm90_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int nr = attr->nr;
        int index = attr->index;
        long val;
@@ -922,8 +924,8 @@ static ssize_t show_temphyst(struct device *dev,
 static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
                            const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm90_data *data = i2c_get_clientdata(client);
+       struct lm90_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long val;
        int err;
        int temp;
@@ -976,8 +978,8 @@ static ssize_t set_update_interval(struct device *dev,
                                   struct device_attribute *attr,
                                   const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm90_data *data = i2c_get_clientdata(client);
+       struct lm90_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long val;
        int err;
 
@@ -1057,6 +1059,15 @@ static const struct attribute_group lm90_group = {
        .attrs = lm90_attributes,
 };
 
+static struct attribute *lm90_temp2_offset_attributes[] = {
+       &sensor_dev_attr_temp2_offset.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group lm90_temp2_offset_group = {
+       .attrs = lm90_temp2_offset_attributes,
+};
+
 /*
  * Additional attributes for devices with emergency sensors
  */
@@ -1393,22 +1404,6 @@ static int lm90_detect(struct i2c_client *client,
        return 0;
 }
 
-static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data)
-{
-       struct device *dev = &client->dev;
-
-       if (data->flags & LM90_HAVE_TEMP3)
-               sysfs_remove_group(&dev->kobj, &lm90_temp3_group);
-       if (data->flags & LM90_HAVE_EMERGENCY_ALARM)
-               sysfs_remove_group(&dev->kobj, &lm90_emergency_alarm_group);
-       if (data->flags & LM90_HAVE_EMERGENCY)
-               sysfs_remove_group(&dev->kobj, &lm90_emergency_group);
-       if (data->flags & LM90_HAVE_OFFSET)
-               device_remove_file(dev, &sensor_dev_attr_temp2_offset.dev_attr);
-       device_remove_file(dev, &dev_attr_pec);
-       sysfs_remove_group(&dev->kobj, &lm90_group);
-}
-
 static void lm90_restore_conf(struct i2c_client *client, struct lm90_data *data)
 {
        /* Restore initial configuration */
@@ -1418,10 +1413,9 @@ static void lm90_restore_conf(struct i2c_client *client, struct lm90_data *data)
                                  data->config_orig);
 }
 
-static void lm90_init_client(struct i2c_client *client)
+static void lm90_init_client(struct i2c_client *client, struct lm90_data *data)
 {
        u8 config, convrate;
-       struct lm90_data *data = i2c_get_clientdata(client);
 
        if (lm90_read_reg(client, LM90_REG_R_CONVRATE, &convrate) < 0) {
                dev_warn(&client->dev, "Failed to read convrate register!\n");
@@ -1519,6 +1513,7 @@ static int lm90_probe(struct i2c_client *client,
        struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
        struct lm90_data *data;
        struct regulator *regulator;
+       int groups = 0;
        int err;
 
        regulator = devm_regulator_get(dev, "vcc");
@@ -1527,15 +1522,15 @@ static int lm90_probe(struct i2c_client *client,
 
        err = regulator_enable(regulator);
        if (err < 0) {
-               dev_err(&client->dev,
-                       "Failed to enable regulator: %d\n", err);
+               dev_err(dev, "Failed to enable regulator: %d\n", err);
                return err;
        }
 
-       data = devm_kzalloc(&client->dev, sizeof(struct lm90_data), GFP_KERNEL);
+       data = devm_kzalloc(dev, sizeof(struct lm90_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
+       data->client = client;
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
 
@@ -1562,44 +1557,34 @@ static int lm90_probe(struct i2c_client *client,
        data->max_convrate = lm90_params[data->kind].max_convrate;
 
        /* Initialize the LM90 chip */
-       lm90_init_client(client);
+       lm90_init_client(client, data);
 
        /* Register sysfs hooks */
-       err = sysfs_create_group(&dev->kobj, &lm90_group);
-       if (err)
-               goto exit_restore;
+       data->groups[groups++] = &lm90_group;
+
+       if (data->flags & LM90_HAVE_OFFSET)
+               data->groups[groups++] = &lm90_temp2_offset_group;
+
+       if (data->flags & LM90_HAVE_EMERGENCY)
+               data->groups[groups++] = &lm90_emergency_group;
+
+       if (data->flags & LM90_HAVE_EMERGENCY_ALARM)
+               data->groups[groups++] = &lm90_emergency_alarm_group;
+
+       if (data->flags & LM90_HAVE_TEMP3)
+               data->groups[groups++] = &lm90_temp3_group;
+
        if (client->flags & I2C_CLIENT_PEC) {
                err = device_create_file(dev, &dev_attr_pec);
                if (err)
-                       goto exit_remove_files;
-       }
-       if (data->flags & LM90_HAVE_OFFSET) {
-               err = device_create_file(dev,
-                                       &sensor_dev_attr_temp2_offset.dev_attr);
-               if (err)
-                       goto exit_remove_files;
-       }
-       if (data->flags & LM90_HAVE_EMERGENCY) {
-               err = sysfs_create_group(&dev->kobj, &lm90_emergency_group);
-               if (err)
-                       goto exit_remove_files;
-       }
-       if (data->flags & LM90_HAVE_EMERGENCY_ALARM) {
-               err = sysfs_create_group(&dev->kobj,
-                                        &lm90_emergency_alarm_group);
-               if (err)
-                       goto exit_remove_files;
-       }
-       if (data->flags & LM90_HAVE_TEMP3) {
-               err = sysfs_create_group(&dev->kobj, &lm90_temp3_group);
-               if (err)
-                       goto exit_remove_files;
+                       goto exit_restore;
        }
 
-       data->hwmon_dev = hwmon_device_register(dev);
+       data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
+                                                           data, data->groups);
        if (IS_ERR(data->hwmon_dev)) {
                err = PTR_ERR(data->hwmon_dev);
-               goto exit_remove_files;
+               goto exit_remove_pec;
        }
 
        if (client->irq) {
@@ -1618,8 +1603,8 @@ static int lm90_probe(struct i2c_client *client,
 
 exit_unregister:
        hwmon_device_unregister(data->hwmon_dev);
-exit_remove_files:
-       lm90_remove_files(client, data);
+exit_remove_pec:
+       device_remove_file(dev, &dev_attr_pec);
 exit_restore:
        lm90_restore_conf(client, data);
        regulator_disable(data->regulator);
@@ -1632,7 +1617,7 @@ static int lm90_remove(struct i2c_client *client)
        struct lm90_data *data = i2c_get_clientdata(client);
 
        hwmon_device_unregister(data->hwmon_dev);
-       lm90_remove_files(client, data);
+       device_remove_file(&client->dev, &dev_attr_pec);
        lm90_restore_conf(client, data);
        regulator_disable(data->regulator);
 
index 9d0e87a4f0cbc1226cbf8efa47d99cf62dbaa4b8..b9022db6511ae4cc8ee5851d89466725c5384d8b 100644 (file)
@@ -380,7 +380,6 @@ static int lm92_probe(struct i2c_client *new_client,
                return -ENOMEM;
 
        i2c_set_clientdata(new_client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Initialize the chipset */
index 6f1c6c0dbaf56c1d019375292dfbfeefb4aef25a..adf23165a6a709ca2785cad332b8626da2a73b80 100644 (file)
@@ -2754,7 +2754,6 @@ static int lm93_probe(struct i2c_client *client,
        i2c_set_clientdata(client, data);
 
        /* housekeeping */
-       data->valid = 0;
        data->update = update;
        mutex_init(&data->update_lock);
 
index 6638e997f83fbd165ebcf019aba2b2da930b715b..4c23afe113e2f71b6d9b9356e59122abfc3484c4 100644 (file)
@@ -273,7 +273,6 @@ static int max1619_probe(struct i2c_client *new_client,
                return -ENOMEM;
 
        i2c_set_clientdata(new_client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Initialize the MAX1619 chip */
index 330fe117e219ff1af15a59d5d2fc4ed11bd79cbc..988181e4cfcdc8ab7e40f02ab2977b38ee231120 100644 (file)
@@ -1225,7 +1225,7 @@ static int pc87360_probe(struct platform_device *pdev)
        int i;
        struct pc87360_data *data;
        int err = 0;
-       const char *name = "pc87360";
+       const char *name;
        int use_thermistors = 0;
        struct device *dev = &pdev->dev;
 
@@ -1233,13 +1233,14 @@ static int pc87360_probe(struct platform_device *pdev)
        if (!data)
                return -ENOMEM;
 
-       data->fannr = 2;
-       data->innr = 0;
-       data->tempnr = 0;
-
        switch (devid) {
+       default:
+               name = "pc87360";
+               data->fannr = 2;
+               break;
        case 0xe8:
                name = "pc87363";
+               data->fannr = 2;
                break;
        case 0xe4:
                name = "pc87364";
@@ -1260,7 +1261,6 @@ static int pc87360_probe(struct platform_device *pdev)
        }
 
        data->name = name;
-       data->valid = 0;
        mutex_init(&data->lock);
        mutex_init(&data->update_lock);
        platform_set_drvdata(pdev, data);
index 38944e94f65fbd27692100d4d78b2868f13a2982..8df43c51de2c2d14434533cff15bc371f3d3a245 100644 (file)
@@ -319,7 +319,7 @@ static int __init via_cputemp_init(void)
        if (err)
                goto exit;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
        for_each_online_cpu(i) {
                struct cpuinfo_x86 *c = &cpu_data(i);
 
@@ -339,14 +339,14 @@ static int __init via_cputemp_init(void)
 
 #ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
-               put_online_cpus();
+               cpu_notifier_register_done();
                err = -ENODEV;
                goto exit_driver_unreg;
        }
 #endif
 
-       register_hotcpu_notifier(&via_cputemp_cpu_notifier);
-       put_online_cpus();
+       __register_hotcpu_notifier(&via_cputemp_cpu_notifier);
+       cpu_notifier_register_done();
        return 0;
 
 #ifndef CONFIG_HOTPLUG_CPU
@@ -361,8 +361,8 @@ static void __exit via_cputemp_exit(void)
 {
        struct pdev_entry *p, *n;
 
-       get_online_cpus();
-       unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
+       cpu_notifier_register_begin();
+       __unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
        mutex_lock(&pdev_list_mutex);
        list_for_each_entry_safe(p, n, &pdev_list, list) {
                platform_device_unregister(p->pdev);
@@ -370,7 +370,7 @@ static void __exit via_cputemp_exit(void)
                kfree(p);
        }
        mutex_unlock(&pdev_list_mutex);
-       put_online_cpus();
+       cpu_notifier_register_done();
        platform_driver_unregister(&via_cputemp_driver);
 }
 
index df585808adb65feb2f53c458799010f68ca4bcc2..4068db4d9580b538c70ffccc7db71d29c5515967 100644 (file)
@@ -1376,7 +1376,6 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id)
                return -ENOMEM;
 
        i2c_set_clientdata(client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        err = w83792d_detect_subclients(client);
index 6384b268f59008406a3cd2789fd851978e35acd7..ac30431220115d9f5efff73288f4bb3baa1d5cf9 100644 (file)
@@ -188,12 +188,8 @@ static int w83l785ts_probe(struct i2c_client *client,
                return -ENOMEM;
 
        i2c_set_clientdata(client, data);
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
-       /* Default values in case the first read fails (unlikely). */
-       data->temp[1] = data->temp[0] = 0;
-
        /*
         * Initialize the W83L785TS chip
         * Nothing yet, assume it is already started.
index 8e1939f564f4ae16f44d1f1b06e80744d303fa0b..51493ed4643b019a1cd80e423485a75f363b8dbe 100644 (file)
@@ -681,14 +681,19 @@ static int __init intel_idle_init(void)
        if (intel_idle_cpuidle_devices == NULL)
                return -ENOMEM;
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(i) {
                retval = intel_idle_cpu_init(i);
                if (retval) {
+                       cpu_notifier_register_done();
                        cpuidle_unregister_driver(&intel_idle_driver);
                        return retval;
                }
        }
-       register_cpu_notifier(&cpu_hotplug_notifier);
+       __register_cpu_notifier(&cpu_hotplug_notifier);
+
+       cpu_notifier_register_done();
 
        return 0;
 }
@@ -698,10 +703,13 @@ static void __exit intel_idle_exit(void)
        intel_idle_cpuidle_devices_uninit();
        cpuidle_unregister_driver(&intel_idle_driver);
 
+       cpu_notifier_register_begin();
 
        if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE)
                on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
-       unregister_cpu_notifier(&cpu_hotplug_notifier);
+       __unregister_cpu_notifier(&cpu_hotplug_notifier);
+
+       cpu_notifier_register_done();
 
        return;
 }
index 4bf4c16de976be31f811ef8d367510c7dc530d8d..d86196cfe4b47091add5d756da6d3dbf7fded9eb 100644 (file)
@@ -193,6 +193,16 @@ config TI_AM335X_ADC
          Say yes here to build support for Texas Instruments ADC
          driver which is also a MFD client.
 
+config TWL4030_MADC
+       tristate "TWL4030 MADC (Monitoring A/D Converter)"
+       depends on TWL4030_CORE
+       help
+       This driver provides support for Triton TWL4030-MADC. The
+       driver supports both RT and SW conversion methods.
+
+       This driver can also be built as a module. If so, the module will be
+       called twl4030-madc.
+
 config TWL6030_GPADC
        tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
        depends on TWL4030_CORE
index bb252540664ae15a6f74730226415f838e0d0434..ab346d88c68874e2ac06dc6f2911ef1ec6cf0f25 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
+obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_VF610_ADC) += vf610_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
new file mode 100644 (file)
index 0000000..7de1c4c
--- /dev/null
@@ -0,0 +1,895 @@
+/*
+ *
+ * TWL4030 MADC module driver-This driver monitors the real time
+ * conversion of analog signals like battery temperature,
+ * battery type, battery level etc.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * J Keerthy <j-keerthy@ti.com>
+ *
+ * Based on twl4030-madc.c
+ * Copyright (C) 2008 Nokia Corporation
+ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
+ *
+ * Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/i2c/twl.h>
+#include <linux/i2c/twl4030-madc.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/mutex.h>
+#include <linux/bitops.h>
+#include <linux/jiffies.h>
+#include <linux/types.h>
+#include <linux/gfp.h>
+#include <linux/err.h>
+
+#include <linux/iio/iio.h>
+
+/**
+ * struct twl4030_madc_data - a container for madc info
+ * @dev:               Pointer to device structure for madc
+ * @lock:              Mutex protecting this data structure
+ * @requests:          Array of request struct corresponding to SW1, SW2 and RT
+ * @use_second_irq:    IRQ selection (main or co-processor)
+ * @imr:               Interrupt mask register of MADC
+ * @isr:               Interrupt status register of MADC
+ */
+struct twl4030_madc_data {
+       struct device *dev;
+       struct mutex lock;      /* mutex protecting this data structure */
+       struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
+       bool use_second_irq;
+       u8 imr;
+       u8 isr;
+};
+
+static int twl4030_madc_read(struct iio_dev *iio_dev,
+                            const struct iio_chan_spec *chan,
+                            int *val, int *val2, long mask)
+{
+       struct twl4030_madc_data *madc = iio_priv(iio_dev);
+       struct twl4030_madc_request req;
+       int ret;
+
+       req.method = madc->use_second_irq ? TWL4030_MADC_SW2 : TWL4030_MADC_SW1;
+
+       req.channels = BIT(chan->channel);
+       req.active = false;
+       req.func_cb = NULL;
+       req.type = TWL4030_MADC_WAIT;
+       req.raw = !(mask == IIO_CHAN_INFO_PROCESSED);
+       req.do_avg = (mask == IIO_CHAN_INFO_AVERAGE_RAW);
+
+       ret = twl4030_madc_conversion(&req);
+       if (ret < 0)
+               return ret;
+
+       *val = req.rbuf[chan->channel];
+
+       return IIO_VAL_INT;
+}
+
+static const struct iio_info twl4030_madc_iio_info = {
+       .read_raw = &twl4030_madc_read,
+       .driver_module = THIS_MODULE,
+};
+
+#define TWL4030_ADC_CHANNEL(_channel, _type, _name) {  \
+       .type = _type,                                  \
+       .channel = _channel,                            \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
+                             BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \
+                             BIT(IIO_CHAN_INFO_PROCESSED), \
+       .datasheet_name = _name,                        \
+       .indexed = 1,                                   \
+}
+
+static const struct iio_chan_spec twl4030_madc_iio_channels[] = {
+       TWL4030_ADC_CHANNEL(0, IIO_VOLTAGE, "ADCIN0"),
+       TWL4030_ADC_CHANNEL(1, IIO_TEMP, "ADCIN1"),
+       TWL4030_ADC_CHANNEL(2, IIO_VOLTAGE, "ADCIN2"),
+       TWL4030_ADC_CHANNEL(3, IIO_VOLTAGE, "ADCIN3"),
+       TWL4030_ADC_CHANNEL(4, IIO_VOLTAGE, "ADCIN4"),
+       TWL4030_ADC_CHANNEL(5, IIO_VOLTAGE, "ADCIN5"),
+       TWL4030_ADC_CHANNEL(6, IIO_VOLTAGE, "ADCIN6"),
+       TWL4030_ADC_CHANNEL(7, IIO_VOLTAGE, "ADCIN7"),
+       TWL4030_ADC_CHANNEL(8, IIO_VOLTAGE, "ADCIN8"),
+       TWL4030_ADC_CHANNEL(9, IIO_VOLTAGE, "ADCIN9"),
+       TWL4030_ADC_CHANNEL(10, IIO_CURRENT, "ADCIN10"),
+       TWL4030_ADC_CHANNEL(11, IIO_VOLTAGE, "ADCIN11"),
+       TWL4030_ADC_CHANNEL(12, IIO_VOLTAGE, "ADCIN12"),
+       TWL4030_ADC_CHANNEL(13, IIO_VOLTAGE, "ADCIN13"),
+       TWL4030_ADC_CHANNEL(14, IIO_VOLTAGE, "ADCIN14"),
+       TWL4030_ADC_CHANNEL(15, IIO_VOLTAGE, "ADCIN15"),
+};
+
+static struct twl4030_madc_data *twl4030_madc;
+
+struct twl4030_prescale_divider_ratios {
+       s16 numerator;
+       s16 denominator;
+};
+
+static const struct twl4030_prescale_divider_ratios
+twl4030_divider_ratios[16] = {
+       {1, 1},         /* CHANNEL 0 No Prescaler */
+       {1, 1},         /* CHANNEL 1 No Prescaler */
+       {6, 10},        /* CHANNEL 2 */
+       {6, 10},        /* CHANNEL 3 */
+       {6, 10},        /* CHANNEL 4 */
+       {6, 10},        /* CHANNEL 5 */
+       {6, 10},        /* CHANNEL 6 */
+       {6, 10},        /* CHANNEL 7 */
+       {3, 14},        /* CHANNEL 8 */
+       {1, 3},         /* CHANNEL 9 */
+       {1, 1},         /* CHANNEL 10 No Prescaler */
+       {15, 100},      /* CHANNEL 11 */
+       {1, 4},         /* CHANNEL 12 */
+       {1, 1},         /* CHANNEL 13 Reserved channels */
+       {1, 1},         /* CHANNEL 14 Reseved channels */
+       {5, 11},        /* CHANNEL 15 */
+};
+
+
+/* Conversion table from -3 to 55 degrees Celcius */
+static int twl4030_therm_tbl[] = {
+       30800,  29500,  28300,  27100,
+       26000,  24900,  23900,  22900,  22000,  21100,  20300,  19400,  18700,
+       17900,  17200,  16500,  15900,  15300,  14700,  14100,  13600,  13100,
+       12600,  12100,  11600,  11200,  10800,  10400,  10000,  9630,   9280,
+       8950,   8620,   8310,   8020,   7730,   7460,   7200,   6950,   6710,
+       6470,   6250,   6040,   5830,   5640,   5450,   5260,   5090,   4920,
+       4760,   4600,   4450,   4310,   4170,   4040,   3910,   3790,   3670,
+       3550
+};
+
+/*
+ * Structure containing the registers
+ * of different conversion methods supported by MADC.
+ * Hardware or RT real time conversion request initiated by external host
+ * processor for RT Signal conversions.
+ * External host processors can also request for non RT conversions
+ * SW1 and SW2 software conversions also called asynchronous or GPC request.
+ */
+static
+const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
+       [TWL4030_MADC_RT] = {
+                            .sel = TWL4030_MADC_RTSELECT_LSB,
+                            .avg = TWL4030_MADC_RTAVERAGE_LSB,
+                            .rbase = TWL4030_MADC_RTCH0_LSB,
+                            },
+       [TWL4030_MADC_SW1] = {
+                             .sel = TWL4030_MADC_SW1SELECT_LSB,
+                             .avg = TWL4030_MADC_SW1AVERAGE_LSB,
+                             .rbase = TWL4030_MADC_GPCH0_LSB,
+                             .ctrl = TWL4030_MADC_CTRL_SW1,
+                             },
+       [TWL4030_MADC_SW2] = {
+                             .sel = TWL4030_MADC_SW2SELECT_LSB,
+                             .avg = TWL4030_MADC_SW2AVERAGE_LSB,
+                             .rbase = TWL4030_MADC_GPCH0_LSB,
+                             .ctrl = TWL4030_MADC_CTRL_SW2,
+                             },
+};
+
+/**
+ * twl4030_madc_channel_raw_read() - Function to read a particular channel value
+ * @madc:      pointer to struct twl4030_madc_data
+ * @reg:       lsb of ADC Channel
+ *
+ * Return: 0 on success, an error code otherwise.
+ */
+static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
+{
+       u16 val;
+       int ret;
+       /*
+        * For each ADC channel, we have MSB and LSB register pair. MSB address
+        * is always LSB address+1. reg parameter is the address of LSB register
+        */
+       ret = twl_i2c_read_u16(TWL4030_MODULE_MADC, &val, reg);
+       if (ret) {
+               dev_err(madc->dev, "unable to read register 0x%X\n", reg);
+               return ret;
+       }
+
+       return (int)(val >> 6);
+}
+
+/*
+ * Return battery temperature in degrees Celsius
+ * Or < 0 on failure.
+ */
+static int twl4030battery_temperature(int raw_volt)
+{
+       u8 val;
+       int temp, curr, volt, res, ret;
+
+       volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
+       /* Getting and calculating the supply current in micro amperes */
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
+               REG_BCICTL2);
+       if (ret < 0)
+               return ret;
+
+       curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
+       /* Getting and calculating the thermistor resistance in ohms */
+       res = volt * 1000 / curr;
+       /* calculating temperature */
+       for (temp = 58; temp >= 0; temp--) {
+               int actual = twl4030_therm_tbl[temp];
+               if ((actual - res) >= 0)
+                       break;
+       }
+
+       return temp + 1;
+}
+
+static int twl4030battery_current(int raw_volt)
+{
+       int ret;
+       u8 val;
+
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
+               TWL4030_BCI_BCICTL1);
+       if (ret)
+               return ret;
+       if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
+               return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
+       else /* slope of 0.88 mV/mA */
+               return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
+}
+
+/*
+ * Function to read channel values
+ * @madc - pointer to twl4030_madc_data struct
+ * @reg_base - Base address of the first channel
+ * @Channels - 16 bit bitmap. If the bit is set, channel's value is read
+ * @buf - The channel values are stored here. if read fails error
+ * @raw - Return raw values without conversion
+ * value is stored
+ * Returns the number of successfully read channels.
+ */
+static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
+                                     u8 reg_base, unsigned
+                                     long channels, int *buf,
+                                     bool raw)
+{
+       int count = 0;
+       int i;
+       u8 reg;
+
+       for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
+               reg = reg_base + (2 * i);
+               buf[i] = twl4030_madc_channel_raw_read(madc, reg);
+               if (buf[i] < 0) {
+                       dev_err(madc->dev, "Unable to read register 0x%X\n",
+                               reg);
+                       return buf[i];
+               }
+               if (raw) {
+                       count++;
+                       continue;
+               }
+               switch (i) {
+               case 10:
+                       buf[i] = twl4030battery_current(buf[i]);
+                       if (buf[i] < 0) {
+                               dev_err(madc->dev, "err reading current\n");
+                               return buf[i];
+                       } else {
+                               count++;
+                               buf[i] = buf[i] - 750;
+                       }
+                       break;
+               case 1:
+                       buf[i] = twl4030battery_temperature(buf[i]);
+                       if (buf[i] < 0) {
+                               dev_err(madc->dev, "err reading temperature\n");
+                               return buf[i];
+                       } else {
+                               buf[i] -= 3;
+                               count++;
+                       }
+                       break;
+               default:
+                       count++;
+                       /* Analog Input (V) = conv_result * step_size / R
+                        * conv_result = decimal value of 10-bit conversion
+                        *               result
+                        * step size = 1.5 / (2 ^ 10 -1)
+                        * R = Prescaler ratio for input channels.
+                        * Result given in mV hence multiplied by 1000.
+                        */
+                       buf[i] = (buf[i] * 3 * 1000 *
+                                twl4030_divider_ratios[i].denominator)
+                               / (2 * 1023 *
+                               twl4030_divider_ratios[i].numerator);
+               }
+       }
+
+       return count;
+}
+
+/*
+ * Enables irq.
+ * @madc - pointer to twl4030_madc_data struct
+ * @id - irq number to be enabled
+ * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
+ * corresponding to RT, SW1, SW2 conversion requests.
+ * If the i2c read fails it returns an error else returns 0.
+ */
+static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
+{
+       u8 val;
+       int ret;
+
+       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
+       if (ret) {
+               dev_err(madc->dev, "unable to read imr register 0x%X\n",
+                       madc->imr);
+               return ret;
+       }
+
+       val &= ~(1 << id);
+       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
+       if (ret) {
+               dev_err(madc->dev,
+                       "unable to write imr register 0x%X\n", madc->imr);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Disables irq.
+ * @madc - pointer to twl4030_madc_data struct
+ * @id - irq number to be disabled
+ * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
+ * corresponding to RT, SW1, SW2 conversion requests.
+ * Returns error if i2c read/write fails.
+ */
+static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
+{
+       u8 val;
+       int ret;
+
+       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
+       if (ret) {
+               dev_err(madc->dev, "unable to read imr register 0x%X\n",
+                       madc->imr);
+               return ret;
+       }
+       val |= (1 << id);
+       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
+       if (ret) {
+               dev_err(madc->dev,
+                       "unable to write imr register 0x%X\n", madc->imr);
+               return ret;
+       }
+
+       return 0;
+}
+
+static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
+{
+       struct twl4030_madc_data *madc = _madc;
+       const struct twl4030_madc_conversion_method *method;
+       u8 isr_val, imr_val;
+       int i, len, ret;
+       struct twl4030_madc_request *r;
+
+       mutex_lock(&madc->lock);
+       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
+       if (ret) {
+               dev_err(madc->dev, "unable to read isr register 0x%X\n",
+                       madc->isr);
+               goto err_i2c;
+       }
+       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
+       if (ret) {
+               dev_err(madc->dev, "unable to read imr register 0x%X\n",
+                       madc->imr);
+               goto err_i2c;
+       }
+       isr_val &= ~imr_val;
+       for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
+               if (!(isr_val & (1 << i)))
+                       continue;
+               ret = twl4030_madc_disable_irq(madc, i);
+               if (ret < 0)
+                       dev_dbg(madc->dev, "Disable interrupt failed %d\n", i);
+               madc->requests[i].result_pending = 1;
+       }
+       for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
+               r = &madc->requests[i];
+               /* No pending results for this method, move to next one */
+               if (!r->result_pending)
+                       continue;
+               method = &twl4030_conversion_methods[r->method];
+               /* Read results */
+               len = twl4030_madc_read_channels(madc, method->rbase,
+                                                r->channels, r->rbuf, r->raw);
+               /* Return results to caller */
+               if (r->func_cb != NULL) {
+                       r->func_cb(len, r->channels, r->rbuf);
+                       r->func_cb = NULL;
+               }
+               /* Free request */
+               r->result_pending = 0;
+               r->active = 0;
+       }
+       mutex_unlock(&madc->lock);
+
+       return IRQ_HANDLED;
+
+err_i2c:
+       /*
+        * In case of error check whichever request is active
+        * and service the same.
+        */
+       for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
+               r = &madc->requests[i];
+               if (r->active == 0)
+                       continue;
+               method = &twl4030_conversion_methods[r->method];
+               /* Read results */
+               len = twl4030_madc_read_channels(madc, method->rbase,
+                                                r->channels, r->rbuf, r->raw);
+               /* Return results to caller */
+               if (r->func_cb != NULL) {
+                       r->func_cb(len, r->channels, r->rbuf);
+                       r->func_cb = NULL;
+               }
+               /* Free request */
+               r->result_pending = 0;
+               r->active = 0;
+       }
+       mutex_unlock(&madc->lock);
+
+       return IRQ_HANDLED;
+}
+
+static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
+                               struct twl4030_madc_request *req)
+{
+       struct twl4030_madc_request *p;
+       int ret;
+
+       p = &madc->requests[req->method];
+       memcpy(p, req, sizeof(*req));
+       ret = twl4030_madc_enable_irq(madc, req->method);
+       if (ret < 0) {
+               dev_err(madc->dev, "enable irq failed!!\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Function which enables the madc conversion
+ * by writing to the control register.
+ * @madc - pointer to twl4030_madc_data struct
+ * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
+ * corresponding to RT SW1 or SW2 conversion methods.
+ * Returns 0 if succeeds else a negative error value
+ */
+static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
+                                        int conv_method)
+{
+       const struct twl4030_madc_conversion_method *method;
+       int ret = 0;
+
+       if (conv_method != TWL4030_MADC_SW1 && conv_method != TWL4030_MADC_SW2)
+               return -ENOTSUPP;
+
+       method = &twl4030_conversion_methods[conv_method];
+       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, TWL4030_MADC_SW_START,
+                              method->ctrl);
+       if (ret) {
+               dev_err(madc->dev, "unable to write ctrl register 0x%X\n",
+                       method->ctrl);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Function that waits for conversion to be ready
+ * @madc - pointer to twl4030_madc_data struct
+ * @timeout_ms - timeout value in milliseconds
+ * @status_reg - ctrl register
+ * returns 0 if succeeds else a negative error value
+ */
+static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
+                                             unsigned int timeout_ms,
+                                             u8 status_reg)
+{
+       unsigned long timeout;
+       int ret;
+
+       timeout = jiffies + msecs_to_jiffies(timeout_ms);
+       do {
+               u8 reg;
+
+               ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
+               if (ret) {
+                       dev_err(madc->dev,
+                               "unable to read status register 0x%X\n",
+                               status_reg);
+                       return ret;
+               }
+               if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
+                       return 0;
+               usleep_range(500, 2000);
+       } while (!time_after(jiffies, timeout));
+       dev_err(madc->dev, "conversion timeout!\n");
+
+       return -EAGAIN;
+}
+
+/*
+ * An exported function which can be called from other kernel drivers.
+ * @req twl4030_madc_request structure
+ * req->rbuf will be filled with read values of channels based on the
+ * channel index. If a particular channel reading fails there will
+ * be a negative error value in the corresponding array element.
+ * returns 0 if succeeds else error value
+ */
+int twl4030_madc_conversion(struct twl4030_madc_request *req)
+{
+       const struct twl4030_madc_conversion_method *method;
+       int ret;
+
+       if (!req || !twl4030_madc)
+               return -EINVAL;
+
+       mutex_lock(&twl4030_madc->lock);
+       if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
+               ret = -EINVAL;
+               goto out;
+       }
+       /* Do we have a conversion request ongoing */
+       if (twl4030_madc->requests[req->method].active) {
+               ret = -EBUSY;
+               goto out;
+       }
+       method = &twl4030_conversion_methods[req->method];
+       /* Select channels to be converted */
+       ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels, method->sel);
+       if (ret) {
+               dev_err(twl4030_madc->dev,
+                       "unable to write sel register 0x%X\n", method->sel);
+               goto out;
+       }
+       /* Select averaging for all channels if do_avg is set */
+       if (req->do_avg) {
+               ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels,
+                                      method->avg);
+               if (ret) {
+                       dev_err(twl4030_madc->dev,
+                               "unable to write avg register 0x%X\n",
+                               method->avg);
+                       goto out;
+               }
+       }
+       if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
+               ret = twl4030_madc_set_irq(twl4030_madc, req);
+               if (ret < 0)
+                       goto out;
+               ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
+               if (ret < 0)
+                       goto out;
+               twl4030_madc->requests[req->method].active = 1;
+               ret = 0;
+               goto out;
+       }
+       /* With RT method we should not be here anymore */
+       if (req->method == TWL4030_MADC_RT) {
+               ret = -EINVAL;
+               goto out;
+       }
+       ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
+       if (ret < 0)
+               goto out;
+       twl4030_madc->requests[req->method].active = 1;
+       /* Wait until conversion is ready (ctrl register returns EOC) */
+       ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
+       if (ret) {
+               twl4030_madc->requests[req->method].active = 0;
+               goto out;
+       }
+       ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
+                                        req->channels, req->rbuf, req->raw);
+       twl4030_madc->requests[req->method].active = 0;
+
+out:
+       mutex_unlock(&twl4030_madc->lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
+
+int twl4030_get_madc_conversion(int channel_no)
+{
+       struct twl4030_madc_request req;
+       int temp = 0;
+       int ret;
+
+       req.channels = (1 << channel_no);
+       req.method = TWL4030_MADC_SW2;
+       req.active = 0;
+       req.func_cb = NULL;
+       ret = twl4030_madc_conversion(&req);
+       if (ret < 0)
+               return ret;
+       if (req.rbuf[channel_no] > 0)
+               temp = req.rbuf[channel_no];
+
+       return temp;
+}
+EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
+
+/**
+ * twl4030_madc_set_current_generator() - setup bias current
+ *
+ * @madc:      pointer to twl4030_madc_data struct
+ * @chan:      can be one of the two values:
+ *             TWL4030_BCI_ITHEN
+ *             Enables bias current for main battery type reading
+ *             TWL4030_BCI_TYPEN
+ *             Enables bias current for main battery temperature sensing
+ * @on:                enable or disable chan.
+ *
+ * Function to enable or disable bias current for
+ * main battery type reading or temperature sensing
+ */
+static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
+                                             int chan, int on)
+{
+       int ret;
+       int regmask;
+       u8 regval;
+
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
+                             &regval, TWL4030_BCI_BCICTL1);
+       if (ret) {
+               dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
+                       TWL4030_BCI_BCICTL1);
+               return ret;
+       }
+
+       regmask = chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
+       if (on)
+               regval |= regmask;
+       else
+               regval &= ~regmask;
+
+       ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
+                              regval, TWL4030_BCI_BCICTL1);
+       if (ret) {
+               dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
+                       TWL4030_BCI_BCICTL1);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Function that sets MADC software power on bit to enable MADC
+ * @madc - pointer to twl4030_madc_data struct
+ * @on - Enable or disable MADC software power on bit.
+ * returns error if i2c read/write fails else 0
+ */
+static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
+{
+       u8 regval;
+       int ret;
+
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
+                             &regval, TWL4030_MADC_CTRL1);
+       if (ret) {
+               dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
+                       TWL4030_MADC_CTRL1);
+               return ret;
+       }
+       if (on)
+               regval |= TWL4030_MADC_MADCON;
+       else
+               regval &= ~TWL4030_MADC_MADCON;
+       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
+       if (ret) {
+               dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
+                       TWL4030_MADC_CTRL1);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Initialize MADC and request for threaded irq
+ */
+static int twl4030_madc_probe(struct platform_device *pdev)
+{
+       struct twl4030_madc_data *madc;
+       struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       struct device_node *np = pdev->dev.of_node;
+       int irq, ret;
+       u8 regval;
+       struct iio_dev *iio_dev = NULL;
+
+       if (!pdata && !np) {
+               dev_err(&pdev->dev, "neither platform data nor Device Tree node available\n");
+               return -EINVAL;
+       }
+
+       iio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*madc));
+       if (!iio_dev) {
+               dev_err(&pdev->dev, "failed allocating iio device\n");
+               return -ENOMEM;
+       }
+
+       madc = iio_priv(iio_dev);
+       madc->dev = &pdev->dev;
+
+       iio_dev->name = dev_name(&pdev->dev);
+       iio_dev->dev.parent = &pdev->dev;
+       iio_dev->dev.of_node = pdev->dev.of_node;
+       iio_dev->info = &twl4030_madc_iio_info;
+       iio_dev->modes = INDIO_DIRECT_MODE;
+       iio_dev->channels = twl4030_madc_iio_channels;
+       iio_dev->num_channels = ARRAY_SIZE(twl4030_madc_iio_channels);
+
+       /*
+        * Phoenix provides 2 interrupt lines. The first one is connected to
+        * the OMAP. The other one can be connected to the other processor such
+        * as modem. Hence two separate ISR and IMR registers.
+        */
+       if (pdata)
+               madc->use_second_irq = (pdata->irq_line != 1);
+       else
+               madc->use_second_irq = of_property_read_bool(np,
+                                      "ti,system-uses-second-madc-irq");
+
+       madc->imr = madc->use_second_irq ? TWL4030_MADC_IMR2 :
+                                          TWL4030_MADC_IMR1;
+       madc->isr = madc->use_second_irq ? TWL4030_MADC_ISR2 :
+                                          TWL4030_MADC_ISR1;
+
+       ret = twl4030_madc_set_power(madc, 1);
+       if (ret < 0)
+               return ret;
+       ret = twl4030_madc_set_current_generator(madc, 0, 1);
+       if (ret < 0)
+               goto err_current_generator;
+
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
+                             &regval, TWL4030_BCI_BCICTL1);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
+                       TWL4030_BCI_BCICTL1);
+               goto err_i2c;
+       }
+       regval |= TWL4030_BCI_MESBAT;
+       ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
+                              regval, TWL4030_BCI_BCICTL1);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
+                       TWL4030_BCI_BCICTL1);
+               goto err_i2c;
+       }
+
+       /* Check that MADC clock is on */
+       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
+                               TWL4030_REG_GPBR1);
+               goto err_i2c;
+       }
+
+       /* If MADC clk is not on, turn it on */
+       if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
+               dev_info(&pdev->dev, "clk disabled, enabling\n");
+               regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
+               ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
+                                      TWL4030_REG_GPBR1);
+               if (ret) {
+                       dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
+                                       TWL4030_REG_GPBR1);
+                       goto err_i2c;
+               }
+       }
+
+       platform_set_drvdata(pdev, iio_dev);
+       mutex_init(&madc->lock);
+
+       irq = platform_get_irq(pdev, 0);
+       ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+                                  twl4030_madc_threaded_irq_handler,
+                                  IRQF_TRIGGER_RISING, "twl4030_madc", madc);
+       if (ret) {
+               dev_err(&pdev->dev, "could not request irq\n");
+               goto err_i2c;
+       }
+       twl4030_madc = madc;
+
+       ret = iio_device_register(iio_dev);
+       if (ret) {
+               dev_err(&pdev->dev, "could not register iio device\n");
+               goto err_i2c;
+       }
+
+       return 0;
+
+err_i2c:
+       twl4030_madc_set_current_generator(madc, 0, 0);
+err_current_generator:
+       twl4030_madc_set_power(madc, 0);
+       return ret;
+}
+
+static int twl4030_madc_remove(struct platform_device *pdev)
+{
+       struct iio_dev *iio_dev = platform_get_drvdata(pdev);
+       struct twl4030_madc_data *madc = iio_priv(iio_dev);
+
+       iio_device_unregister(iio_dev);
+
+       twl4030_madc_set_current_generator(madc, 0, 0);
+       twl4030_madc_set_power(madc, 0);
+
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id twl_madc_of_match[] = {
+       { .compatible = "ti,twl4030-madc", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, twl_madc_of_match);
+#endif
+
+static struct platform_driver twl4030_madc_driver = {
+       .probe = twl4030_madc_probe,
+       .remove = twl4030_madc_remove,
+       .driver = {
+                  .name = "twl4030_madc",
+                  .owner = THIS_MODULE,
+                  .of_match_table = of_match_ptr(twl_madc_of_match),
+       },
+};
+
+module_platform_driver(twl4030_madc_driver);
+
+MODULE_DESCRIPTION("TWL4030 ADC driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("J Keerthy");
+MODULE_ALIAS("platform:twl4030_madc");
index f772981bdcdbef5d46d14461eb2cc04fd223fae6..5928ea71dd696324807c7181e62eb96f93e2f65e 100644 (file)
@@ -156,7 +156,7 @@ config INPUT_MAX8925_ONKEY
 
 config INPUT_MAX8997_HAPTIC
        tristate "MAXIM MAX8997 haptic controller support"
-       depends on PWM && HAVE_PWM && MFD_MAX8997
+       depends on PWM && MFD_MAX8997
        select INPUT_FF_MEMLESS
        help
          This option enables device driver support for the haptic controller
@@ -470,7 +470,7 @@ config INPUT_PCF8574
 
 config INPUT_PWM_BEEPER
        tristate "PWM beeper support"
-       depends on PWM && HAVE_PWM
+       depends on PWM
        help
          Say Y here to get support for PWM based beeper devices.
 
index 17ccba88d636af381acd020a4d02b1f557babb64..ed8e5e8449d39a440d3c9390f33ec475a27bd7f8 100644 (file)
@@ -67,7 +67,7 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned
        }
 
        if (value > 20 && value < 32767)
-               count = (IXP4XX_TIMER_FREQ / (value * 4)) - 1;
+               count = (ixp4xx_timer_freq / (value * 4)) - 1;
 
        ixp4xx_spkr_control(pin, count);
 
index 79bbc21c1d01671b6c7d289c3c1ff44db449e4ec..df56e4c74a7e450aae8820d4b7d6837c897c781b 100644 (file)
@@ -207,7 +207,7 @@ config SHMOBILE_IOMMU
        bool "IOMMU for Renesas IPMMU/IPMMUI"
        default n
        depends on ARM
-       depends on SH_MOBILE || COMPILE_TEST
+       depends on ARCH_SHMOBILE || COMPILE_TEST
        select IOMMU_API
        select ARM_DMA_USE_IOMMU
        select SHMOBILE_IPMMU
index faf0da4bb3a2f84bfd69c911d8de100028b25b7e..c949520bd196ec47cf6e572e68cdd67c11b9f84f 100644 (file)
@@ -963,7 +963,7 @@ static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid,
 
        address &= ~(0xfffULL);
 
-       cmd->data[0]  = pasid & PASID_MASK;
+       cmd->data[0]  = pasid;
        cmd->data[1]  = domid;
        cmd->data[2]  = lower_32_bits(address);
        cmd->data[3]  = upper_32_bits(address);
@@ -982,10 +982,10 @@ static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid,
        address &= ~(0xfffULL);
 
        cmd->data[0]  = devid;
-       cmd->data[0] |= (pasid & 0xff) << 16;
+       cmd->data[0] |= ((pasid >> 8) & 0xff) << 16;
        cmd->data[0] |= (qdep  & 0xff) << 24;
        cmd->data[1]  = devid;
-       cmd->data[1] |= ((pasid >> 8) & 0xfff) << 16;
+       cmd->data[1] |= (pasid & 0xff) << 16;
        cmd->data[2]  = lower_32_bits(address);
        cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
        cmd->data[3]  = upper_32_bits(address);
@@ -1001,7 +1001,7 @@ static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid,
 
        cmd->data[0]  = devid;
        if (gn) {
-               cmd->data[1]  = pasid & PASID_MASK;
+               cmd->data[1]  = pasid;
                cmd->data[2]  = CMD_INV_IOMMU_PAGES_GN_MASK;
        }
        cmd->data[3]  = tag & 0x1ff;
index 28b4bea7c1094d79a483ee5256c21a91d3829396..b76c58dbe30ce5ac38c8422b66b5ed2ea4f0fb1e 100644 (file)
@@ -150,7 +150,7 @@ int amd_iommus_present;
 bool amd_iommu_np_cache __read_mostly;
 bool amd_iommu_iotlb_sup __read_mostly = true;
 
-u32 amd_iommu_max_pasids __read_mostly = ~0;
+u32 amd_iommu_max_pasid __read_mostly = ~0;
 
 bool amd_iommu_v2_present __read_mostly;
 bool amd_iommu_pc_present __read_mostly;
@@ -1231,14 +1231,16 @@ static int iommu_init_pci(struct amd_iommu *iommu)
 
        if (iommu_feature(iommu, FEATURE_GT)) {
                int glxval;
-               u32 pasids;
-               u64 shift;
+               u32 max_pasid;
+               u64 pasmax;
 
-               shift   = iommu->features & FEATURE_PASID_MASK;
-               shift >>= FEATURE_PASID_SHIFT;
-               pasids  = (1 << shift);
+               pasmax = iommu->features & FEATURE_PASID_MASK;
+               pasmax >>= FEATURE_PASID_SHIFT;
+               max_pasid  = (1 << (pasmax + 1)) - 1;
 
-               amd_iommu_max_pasids = min(amd_iommu_max_pasids, pasids);
+               amd_iommu_max_pasid = min(amd_iommu_max_pasid, max_pasid);
+
+               BUG_ON(amd_iommu_max_pasid & ~PASID_MASK);
 
                glxval   = iommu->features & FEATURE_GLXVAL_MASK;
                glxval >>= FEATURE_GLXVAL_SHIFT;
index cff039df056ee614ea578a2cf678c1a8b72c39e4..f1a5abf11acfd06beadd326bb0b6b1ee6c14edae 100644 (file)
 #define FEATURE_GLXVAL_SHIFT   14
 #define FEATURE_GLXVAL_MASK    (0x03ULL << FEATURE_GLXVAL_SHIFT)
 
-#define PASID_MASK             0x000fffff
+/* Note:
+ * The current driver only support 16-bit PASID.
+ * Currently, hardware only implement upto 16-bit PASID
+ * even though the spec says it could have upto 20 bits.
+ */
+#define PASID_MASK             0x0000ffff
 
 /* MMIO status bits */
 #define MMIO_STATUS_EVT_INT_MASK       (1 << 1)
@@ -697,8 +702,8 @@ extern unsigned long *amd_iommu_pd_alloc_bitmap;
  */
 extern u32 amd_iommu_unmap_flush;
 
-/* Smallest number of PASIDs supported by any IOMMU in the system */
-extern u32 amd_iommu_max_pasids;
+/* Smallest max PASID supported by any IOMMU in the system */
+extern u32 amd_iommu_max_pasid;
 
 extern bool amd_iommu_v2_present;
 
index 1d9ab39af29f7c5d6ab2504fd2403ff725358a5d..8b89e33a89fe99057d99e322ce2c287b41c0eb2f 100644 (file)
@@ -48,7 +48,7 @@
 #include <asm/pgalloc.h>
 
 /* Maximum number of stream IDs assigned to a single device */
-#define MAX_MASTER_STREAMIDS           8
+#define MAX_MASTER_STREAMIDS           MAX_PHANDLE_ARGS
 
 /* Maximum number of context banks per SMMU */
 #define ARM_SMMU_MAX_CBS               128
 #define ARM_SMMU_GR0(smmu)             ((smmu)->base)
 #define ARM_SMMU_GR1(smmu)             ((smmu)->base + (smmu)->pagesize)
 
+/*
+ * SMMU global address space with conditional offset to access secure
+ * aliases of non-secure registers (e.g. nsCR0: 0x400, nsGFSR: 0x448,
+ * nsGFSYNR0: 0x450)
+ */
+#define ARM_SMMU_GR0_NS(smmu)                                          \
+       ((smmu)->base +                                                 \
+               ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)       \
+                       ? 0x400 : 0))
+
 /* Page table bits */
 #define ARM_SMMU_PTE_XN                        (((pteval_t)3) << 53)
 #define ARM_SMMU_PTE_CONT              (((pteval_t)1) << 52)
@@ -351,6 +361,9 @@ struct arm_smmu_device {
 #define ARM_SMMU_FEAT_TRANS_S2         (1 << 3)
 #define ARM_SMMU_FEAT_TRANS_NESTED     (1 << 4)
        u32                             features;
+
+#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
+       u32                             options;
        int                             version;
 
        u32                             num_context_banks;
@@ -401,6 +414,29 @@ struct arm_smmu_domain {
 static DEFINE_SPINLOCK(arm_smmu_devices_lock);
 static LIST_HEAD(arm_smmu_devices);
 
+struct arm_smmu_option_prop {
+       u32 opt;
+       const char *prop;
+};
+
+static struct arm_smmu_option_prop arm_smmu_options [] = {
+       { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" },
+       { 0, NULL},
+};
+
+static void parse_driver_options(struct arm_smmu_device *smmu)
+{
+       int i = 0;
+       do {
+               if (of_property_read_bool(smmu->dev->of_node,
+                                               arm_smmu_options[i].prop)) {
+                       smmu->options |= arm_smmu_options[i].opt;
+                       dev_notice(smmu->dev, "option %s\n",
+                               arm_smmu_options[i].prop);
+               }
+       } while (arm_smmu_options[++i].opt);
+}
+
 static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
                                                struct device_node *dev_node)
 {
@@ -614,16 +650,16 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
 {
        u32 gfsr, gfsynr0, gfsynr1, gfsynr2;
        struct arm_smmu_device *smmu = dev;
-       void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+       void __iomem *gr0_base = ARM_SMMU_GR0_NS(smmu);
 
        gfsr = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
-       if (!gfsr)
-               return IRQ_NONE;
-
        gfsynr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR0);
        gfsynr1 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR1);
        gfsynr2 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR2);
 
+       if (!gfsr)
+               return IRQ_NONE;
+
        dev_err_ratelimited(smmu->dev,
                "Unexpected global fault, this could be serious\n");
        dev_err_ratelimited(smmu->dev,
@@ -642,7 +678,7 @@ static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
 
        /* Ensure new page tables are visible to the hardware walker */
        if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) {
-               dsb();
+               dsb(ishst);
        } else {
                /*
                 * If the SMMU can't walk tables in the CPU caches, treat them
@@ -990,9 +1026,8 @@ static void arm_smmu_free_pgtables(struct arm_smmu_domain *smmu_domain)
 
        /*
         * Recursively free the page tables for this domain. We don't
-        * care about speculative TLB filling, because the TLB will be
-        * nuked next time this context bank is re-allocated and no devices
-        * currently map to these tables.
+        * care about speculative TLB filling because the tables should
+        * not be active in any context bank at this point (SCTLR.M is 0).
         */
        pgd = pgd_base;
        for (i = 0; i < PTRS_PER_PGD; ++i) {
@@ -1218,7 +1253,7 @@ static bool arm_smmu_pte_is_contiguous_range(unsigned long addr,
 
 static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
                                   unsigned long addr, unsigned long end,
-                                  unsigned long pfn, int flags, int stage)
+                                  unsigned long pfn, int prot, int stage)
 {
        pte_t *pte, *start;
        pteval_t pteval = ARM_SMMU_PTE_PAGE | ARM_SMMU_PTE_AF | ARM_SMMU_PTE_XN;
@@ -1240,28 +1275,28 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
 
        if (stage == 1) {
                pteval |= ARM_SMMU_PTE_AP_UNPRIV | ARM_SMMU_PTE_nG;
-               if (!(flags & IOMMU_WRITE) && (flags & IOMMU_READ))
+               if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
                        pteval |= ARM_SMMU_PTE_AP_RDONLY;
 
-               if (flags & IOMMU_CACHE)
+               if (prot & IOMMU_CACHE)
                        pteval |= (MAIR_ATTR_IDX_CACHE <<
                                   ARM_SMMU_PTE_ATTRINDX_SHIFT);
        } else {
                pteval |= ARM_SMMU_PTE_HAP_FAULT;
-               if (flags & IOMMU_READ)
+               if (prot & IOMMU_READ)
                        pteval |= ARM_SMMU_PTE_HAP_READ;
-               if (flags & IOMMU_WRITE)
+               if (prot & IOMMU_WRITE)
                        pteval |= ARM_SMMU_PTE_HAP_WRITE;
-               if (flags & IOMMU_CACHE)
+               if (prot & IOMMU_CACHE)
                        pteval |= ARM_SMMU_PTE_MEMATTR_OIWB;
                else
                        pteval |= ARM_SMMU_PTE_MEMATTR_NC;
        }
 
        /* If no access, create a faulting entry to avoid TLB fills */
-       if (flags & IOMMU_EXEC)
+       if (prot & IOMMU_EXEC)
                pteval &= ~ARM_SMMU_PTE_XN;
-       else if (!(flags & (IOMMU_READ | IOMMU_WRITE)))
+       else if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
                pteval &= ~ARM_SMMU_PTE_PAGE;
 
        pteval |= ARM_SMMU_PTE_SH_IS;
@@ -1323,7 +1358,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
 
 static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud,
                                   unsigned long addr, unsigned long end,
-                                  phys_addr_t phys, int flags, int stage)
+                                  phys_addr_t phys, int prot, int stage)
 {
        int ret;
        pmd_t *pmd;
@@ -1347,7 +1382,7 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud,
        do {
                next = pmd_addr_end(addr, end);
                ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn,
-                                             flags, stage);
+                                             prot, stage);
                phys += next - addr;
        } while (pmd++, addr = next, addr < end);
 
@@ -1356,7 +1391,7 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud,
 
 static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd,
                                   unsigned long addr, unsigned long end,
-                                  phys_addr_t phys, int flags, int stage)
+                                  phys_addr_t phys, int prot, int stage)
 {
        int ret = 0;
        pud_t *pud;
@@ -1380,7 +1415,7 @@ static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd,
        do {
                next = pud_addr_end(addr, end);
                ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys,
-                                             flags, stage);
+                                             prot, stage);
                phys += next - addr;
        } while (pud++, addr = next, addr < end);
 
@@ -1389,7 +1424,7 @@ static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd,
 
 static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
                                   unsigned long iova, phys_addr_t paddr,
-                                  size_t size, int flags)
+                                  size_t size, int prot)
 {
        int ret, stage;
        unsigned long end;
@@ -1397,7 +1432,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
        struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
        pgd_t *pgd = root_cfg->pgd;
        struct arm_smmu_device *smmu = root_cfg->smmu;
-       unsigned long irqflags;
+       unsigned long flags;
 
        if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) {
                stage = 2;
@@ -1420,14 +1455,14 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
        if (paddr & ~output_mask)
                return -ERANGE;
 
-       spin_lock_irqsave(&smmu_domain->lock, irqflags);
+       spin_lock_irqsave(&smmu_domain->lock, flags);
        pgd += pgd_index(iova);
        end = iova + size;
        do {
                unsigned long next = pgd_addr_end(iova, end);
 
                ret = arm_smmu_alloc_init_pud(smmu, pgd, iova, next, paddr,
-                                             flags, stage);
+                                             prot, stage);
                if (ret)
                        goto out_unlock;
 
@@ -1436,13 +1471,13 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
        } while (pgd++, iova != end);
 
 out_unlock:
-       spin_unlock_irqrestore(&smmu_domain->lock, irqflags);
+       spin_unlock_irqrestore(&smmu_domain->lock, flags);
 
        return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
-                       phys_addr_t paddr, size_t size, int flags)
+                       phys_addr_t paddr, size_t size, int prot)
 {
        struct arm_smmu_domain *smmu_domain = domain->priv;
 
@@ -1453,7 +1488,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
        if ((phys_addr_t)iova & ~smmu_domain->output_mask)
                return -ERANGE;
 
-       return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, flags);
+       return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, prot);
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
@@ -1597,9 +1632,9 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
        int i = 0;
        u32 reg;
 
-       /* Clear Global FSR */
-       reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
-       writel(reg, gr0_base + ARM_SMMU_GR0_sGFSR);
+       /* clear global FSR */
+       reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
+       writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
 
        /* Mark all SMRn as invalid and all S2CRn as bypass */
        for (i = 0; i < smmu->num_mapping_groups; ++i) {
@@ -1619,7 +1654,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
        writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLH);
        writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLNSNH);
 
-       reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sCR0);
+       reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
 
        /* Enable fault reporting */
        reg |= (sCR0_GFRE | sCR0_GFIE | sCR0_GCFGFRE | sCR0_GCFGFIE);
@@ -1638,7 +1673,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
 
        /* Push the button */
        arm_smmu_tlb_sync(smmu);
-       writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sCR0);
+       writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
 }
 
 static int arm_smmu_id_size_to_bits(int size)
@@ -1885,6 +1920,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
        if (err)
                goto out_put_parent;
 
+       parse_driver_options(smmu);
+
        if (smmu->version > 1 &&
            smmu->num_context_banks != smmu->num_context_irqs) {
                dev_err(dev,
@@ -1969,7 +2006,7 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
                free_irq(smmu->irqs[i], smmu);
 
        /* Turn the thing off */
-       writel_relaxed(sCR0_CLIENTPD, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_sCR0);
+       writel(sCR0_CLIENTPD,ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
        return 0;
 }
 
index 1581565434106027dca83e1e7bae4c640b3febe9..f445c10df8dfd2beb53b8fb4628d7094d0e17b5a 100644 (file)
 
 #include "irq_remapping.h"
 
-/* No locks are needed as DMA remapping hardware unit
- * list is constructed at boot time and hotplug of
- * these units are not supported by the architecture.
+/*
+ * Assumptions:
+ * 1) The hotplug framework guarentees that DMAR unit will be hot-added
+ *    before IO devices managed by that unit.
+ * 2) The hotplug framework guarantees that DMAR unit will be hot-removed
+ *    after IO devices managed by that unit.
+ * 3) Hotplug events are rare.
+ *
+ * Locking rules for DMA and interrupt remapping related global data structures:
+ * 1) Use dmar_global_lock in process context
+ * 2) Use RCU in interrupt context
  */
+DECLARE_RWSEM(dmar_global_lock);
 LIST_HEAD(dmar_drhd_units);
 
 struct acpi_table_header * __initdata dmar_tbl;
 static acpi_size dmar_tbl_size;
+static int dmar_dev_scope_status = 1;
 
 static int alloc_iommu(struct dmar_drhd_unit *drhd);
 static void free_iommu(struct intel_iommu *iommu);
@@ -62,73 +72,20 @@ static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
         * the very end.
         */
        if (drhd->include_all)
-               list_add_tail(&drhd->list, &dmar_drhd_units);
+               list_add_tail_rcu(&drhd->list, &dmar_drhd_units);
        else
-               list_add(&drhd->list, &dmar_drhd_units);
+               list_add_rcu(&drhd->list, &dmar_drhd_units);
 }
 
-static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
-                                          struct pci_dev **dev, u16 segment)
-{
-       struct pci_bus *bus;
-       struct pci_dev *pdev = NULL;
-       struct acpi_dmar_pci_path *path;
-       int count;
-
-       bus = pci_find_bus(segment, scope->bus);
-       path = (struct acpi_dmar_pci_path *)(scope + 1);
-       count = (scope->length - sizeof(struct acpi_dmar_device_scope))
-               / sizeof(struct acpi_dmar_pci_path);
-
-       while (count) {
-               if (pdev)
-                       pci_dev_put(pdev);
-               /*
-                * Some BIOSes list non-exist devices in DMAR table, just
-                * ignore it
-                */
-               if (!bus) {
-                       pr_warn("Device scope bus [%d] not found\n", scope->bus);
-                       break;
-               }
-               pdev = pci_get_slot(bus, PCI_DEVFN(path->device, path->function));
-               if (!pdev) {
-                       /* warning will be printed below */
-                       break;
-               }
-               path ++;
-               count --;
-               bus = pdev->subordinate;
-       }
-       if (!pdev) {
-               pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n",
-                       segment, scope->bus, path->device, path->function);
-               return 0;
-       }
-       if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT && \
-                       pdev->subordinate) || (scope->entry_type == \
-                       ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) {
-               pci_dev_put(pdev);
-               pr_warn("Device scope type does not match for %s\n",
-                       pci_name(pdev));
-               return -EINVAL;
-       }
-       *dev = pdev;
-       return 0;
-}
-
-int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
-                               struct pci_dev ***devices, u16 segment)
+void *dmar_alloc_dev_scope(void *start, void *end, int *cnt)
 {
        struct acpi_dmar_device_scope *scope;
-       void * tmp = start;
-       int index;
-       int ret;
 
        *cnt = 0;
        while (start < end) {
                scope = start;
-               if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+               if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ACPI ||
+                   scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
                    scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
                        (*cnt)++;
                else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC &&
@@ -138,43 +95,236 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
                start += scope->length;
        }
        if (*cnt == 0)
-               return 0;
+               return NULL;
 
-       *devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL);
-       if (!*devices)
-               return -ENOMEM;
+       return kcalloc(*cnt, sizeof(struct dmar_dev_scope), GFP_KERNEL);
+}
 
-       start = tmp;
-       index = 0;
-       while (start < end) {
+void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt)
+{
+       int i;
+       struct device *tmp_dev;
+
+       if (*devices && *cnt) {
+               for_each_active_dev_scope(*devices, *cnt, i, tmp_dev)
+                       put_device(tmp_dev);
+               kfree(*devices);
+       }
+
+       *devices = NULL;
+       *cnt = 0;
+}
+
+/* Optimize out kzalloc()/kfree() for normal cases */
+static char dmar_pci_notify_info_buf[64];
+
+static struct dmar_pci_notify_info *
+dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
+{
+       int level = 0;
+       size_t size;
+       struct pci_dev *tmp;
+       struct dmar_pci_notify_info *info;
+
+       BUG_ON(dev->is_virtfn);
+
+       /* Only generate path[] for device addition event */
+       if (event == BUS_NOTIFY_ADD_DEVICE)
+               for (tmp = dev; tmp; tmp = tmp->bus->self)
+                       level++;
+
+       size = sizeof(*info) + level * sizeof(struct acpi_dmar_pci_path);
+       if (size <= sizeof(dmar_pci_notify_info_buf)) {
+               info = (struct dmar_pci_notify_info *)dmar_pci_notify_info_buf;
+       } else {
+               info = kzalloc(size, GFP_KERNEL);
+               if (!info) {
+                       pr_warn("Out of memory when allocating notify_info "
+                               "for %s.\n", pci_name(dev));
+                       if (dmar_dev_scope_status == 0)
+                               dmar_dev_scope_status = -ENOMEM;
+                       return NULL;
+               }
+       }
+
+       info->event = event;
+       info->dev = dev;
+       info->seg = pci_domain_nr(dev->bus);
+       info->level = level;
+       if (event == BUS_NOTIFY_ADD_DEVICE) {
+               for (tmp = dev, level--; tmp; tmp = tmp->bus->self) {
+                       info->path[level].device = PCI_SLOT(tmp->devfn);
+                       info->path[level].function = PCI_FUNC(tmp->devfn);
+                       if (pci_is_root_bus(tmp->bus))
+                               info->bus = tmp->bus->number;
+               }
+       }
+
+       return info;
+}
+
+static inline void dmar_free_pci_notify_info(struct dmar_pci_notify_info *info)
+{
+       if ((void *)info != dmar_pci_notify_info_buf)
+               kfree(info);
+}
+
+static bool dmar_match_pci_path(struct dmar_pci_notify_info *info, int bus,
+                               struct acpi_dmar_pci_path *path, int count)
+{
+       int i;
+
+       if (info->bus != bus)
+               return false;
+       if (info->level != count)
+               return false;
+
+       for (i = 0; i < count; i++) {
+               if (path[i].device != info->path[i].device ||
+                   path[i].function != info->path[i].function)
+                       return false;
+       }
+
+       return true;
+}
+
+/* Return: > 0 if match found, 0 if no match found, < 0 if error happens */
+int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
+                         void *start, void*end, u16 segment,
+                         struct dmar_dev_scope *devices,
+                         int devices_cnt)
+{
+       int i, level;
+       struct device *tmp, *dev = &info->dev->dev;
+       struct acpi_dmar_device_scope *scope;
+       struct acpi_dmar_pci_path *path;
+
+       if (segment != info->seg)
+               return 0;
+
+       for (; start < end; start += scope->length) {
                scope = start;
-               if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
-                   scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) {
-                       ret = dmar_parse_one_dev_scope(scope,
-                               &(*devices)[index], segment);
-                       if (ret) {
-                               dmar_free_dev_scope(devices, cnt);
-                               return ret;
-                       }
-                       index ++;
+               if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ENDPOINT &&
+                   scope->entry_type != ACPI_DMAR_SCOPE_TYPE_BRIDGE)
+                       continue;
+
+               path = (struct acpi_dmar_pci_path *)(scope + 1);
+               level = (scope->length - sizeof(*scope)) / sizeof(*path);
+               if (!dmar_match_pci_path(info, scope->bus, path, level))
+                       continue;
+
+               if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT) ^
+                   (info->dev->hdr_type == PCI_HEADER_TYPE_NORMAL)) {
+                       pr_warn("Device scope type does not match for %s\n",
+                               pci_name(info->dev));
+                       return -EINVAL;
                }
-               start += scope->length;
+
+               for_each_dev_scope(devices, devices_cnt, i, tmp)
+                       if (tmp == NULL) {
+                               devices[i].bus = info->dev->bus->number;
+                               devices[i].devfn = info->dev->devfn;
+                               rcu_assign_pointer(devices[i].dev,
+                                                  get_device(dev));
+                               return 1;
+                       }
+               BUG_ON(i >= devices_cnt);
        }
 
        return 0;
 }
 
-void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt)
+int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, u16 segment,
+                         struct dmar_dev_scope *devices, int count)
 {
-       if (*devices && *cnt) {
-               while (--*cnt >= 0)
-                       pci_dev_put((*devices)[*cnt]);
-               kfree(*devices);
-               *devices = NULL;
-               *cnt = 0;
+       int index;
+       struct device *tmp;
+
+       if (info->seg != segment)
+               return 0;
+
+       for_each_active_dev_scope(devices, count, index, tmp)
+               if (tmp == &info->dev->dev) {
+                       rcu_assign_pointer(devices[index].dev, NULL);
+                       synchronize_rcu();
+                       put_device(tmp);
+                       return 1;
+               }
+
+       return 0;
+}
+
+static int dmar_pci_bus_add_dev(struct dmar_pci_notify_info *info)
+{
+       int ret = 0;
+       struct dmar_drhd_unit *dmaru;
+       struct acpi_dmar_hardware_unit *drhd;
+
+       for_each_drhd_unit(dmaru) {
+               if (dmaru->include_all)
+                       continue;
+
+               drhd = container_of(dmaru->hdr,
+                                   struct acpi_dmar_hardware_unit, header);
+               ret = dmar_insert_dev_scope(info, (void *)(drhd + 1),
+                               ((void *)drhd) + drhd->header.length,
+                               dmaru->segment,
+                               dmaru->devices, dmaru->devices_cnt);
+               if (ret != 0)
+                       break;
        }
+       if (ret >= 0)
+               ret = dmar_iommu_notify_scope_dev(info);
+       if (ret < 0 && dmar_dev_scope_status == 0)
+               dmar_dev_scope_status = ret;
+
+       return ret;
 }
 
+static void  dmar_pci_bus_del_dev(struct dmar_pci_notify_info *info)
+{
+       struct dmar_drhd_unit *dmaru;
+
+       for_each_drhd_unit(dmaru)
+               if (dmar_remove_dev_scope(info, dmaru->segment,
+                       dmaru->devices, dmaru->devices_cnt))
+                       break;
+       dmar_iommu_notify_scope_dev(info);
+}
+
+static int dmar_pci_bus_notifier(struct notifier_block *nb,
+                                unsigned long action, void *data)
+{
+       struct pci_dev *pdev = to_pci_dev(data);
+       struct dmar_pci_notify_info *info;
+
+       /* Only care about add/remove events for physical functions */
+       if (pdev->is_virtfn)
+               return NOTIFY_DONE;
+       if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE)
+               return NOTIFY_DONE;
+
+       info = dmar_alloc_pci_notify_info(pdev, action);
+       if (!info)
+               return NOTIFY_DONE;
+
+       down_write(&dmar_global_lock);
+       if (action == BUS_NOTIFY_ADD_DEVICE)
+               dmar_pci_bus_add_dev(info);
+       else if (action == BUS_NOTIFY_DEL_DEVICE)
+               dmar_pci_bus_del_dev(info);
+       up_write(&dmar_global_lock);
+
+       dmar_free_pci_notify_info(info);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block dmar_pci_bus_nb = {
+       .notifier_call = dmar_pci_bus_notifier,
+       .priority = INT_MIN,
+};
+
 /**
  * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
  * structure which uniquely represent one DMA remapping hardware unit
@@ -196,9 +346,18 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
        dmaru->reg_base_addr = drhd->address;
        dmaru->segment = drhd->segment;
        dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
+       dmaru->devices = dmar_alloc_dev_scope((void *)(drhd + 1),
+                                             ((void *)drhd) + drhd->header.length,
+                                             &dmaru->devices_cnt);
+       if (dmaru->devices_cnt && dmaru->devices == NULL) {
+               kfree(dmaru);
+               return -ENOMEM;
+       }
 
        ret = alloc_iommu(dmaru);
        if (ret) {
+               dmar_free_dev_scope(&dmaru->devices,
+                                   &dmaru->devices_cnt);
                kfree(dmaru);
                return ret;
        }
@@ -215,19 +374,24 @@ static void dmar_free_drhd(struct dmar_drhd_unit *dmaru)
        kfree(dmaru);
 }
 
-static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru)
+static int __init dmar_parse_one_andd(struct acpi_dmar_header *header)
 {
-       struct acpi_dmar_hardware_unit *drhd;
-
-       drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;
-
-       if (dmaru->include_all)
-               return 0;
+       struct acpi_dmar_andd *andd = (void *)header;
+
+       /* Check for NUL termination within the designated length */
+       if (strnlen(andd->object_name, header->length - 8) == header->length - 8) {
+               WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
+                          "Your BIOS is broken; ANDD object name is not NUL-terminated\n"
+                          "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+                          dmi_get_system_info(DMI_BIOS_VENDOR),
+                          dmi_get_system_info(DMI_BIOS_VERSION),
+                          dmi_get_system_info(DMI_PRODUCT_VERSION));
+               return -EINVAL;
+       }
+       pr_info("ANDD device: %x name: %s\n", andd->device_number,
+               andd->object_name);
 
-       return dmar_parse_dev_scope((void *)(drhd + 1),
-                                   ((void *)drhd) + drhd->header.length,
-                                   &dmaru->devices_cnt, &dmaru->devices,
-                                   drhd->segment);
+       return 0;
 }
 
 #ifdef CONFIG_ACPI_NUMA
@@ -293,6 +457,10 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
                       (unsigned long long)rhsa->base_address,
                       rhsa->proximity_domain);
                break;
+       case ACPI_DMAR_TYPE_ANDD:
+               /* We don't print this here because we need to sanity-check
+                  it first. So print it in dmar_parse_one_andd() instead. */
+               break;
        }
 }
 
@@ -378,6 +546,9 @@ parse_dmar_table(void)
                        ret = dmar_parse_one_rhsa(entry_header);
 #endif
                        break;
+               case ACPI_DMAR_TYPE_ANDD:
+                       ret = dmar_parse_one_andd(entry_header);
+                       break;
                default:
                        pr_warn("Unknown DMAR structure type %d\n",
                                entry_header->type);
@@ -394,14 +565,15 @@ parse_dmar_table(void)
        return ret;
 }
 
-static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
-                         struct pci_dev *dev)
+static int dmar_pci_device_match(struct dmar_dev_scope devices[],
+                                int cnt, struct pci_dev *dev)
 {
        int index;
+       struct device *tmp;
 
        while (dev) {
-               for (index = 0; index < cnt; index++)
-                       if (dev == devices[index])
+               for_each_active_dev_scope(devices, cnt, index, tmp)
+                       if (dev_is_pci(tmp) && dev == to_pci_dev(tmp))
                                return 1;
 
                /* Check our parent */
@@ -414,11 +586,12 @@ static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
 struct dmar_drhd_unit *
 dmar_find_matched_drhd_unit(struct pci_dev *dev)
 {
-       struct dmar_drhd_unit *dmaru = NULL;
+       struct dmar_drhd_unit *dmaru;
        struct acpi_dmar_hardware_unit *drhd;
 
        dev = pci_physfn(dev);
 
+       rcu_read_lock();
        for_each_drhd_unit(dmaru) {
                drhd = container_of(dmaru->hdr,
                                    struct acpi_dmar_hardware_unit,
@@ -426,44 +599,128 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
 
                if (dmaru->include_all &&
                    drhd->segment == pci_domain_nr(dev->bus))
-                       return dmaru;
+                       goto out;
 
                if (dmar_pci_device_match(dmaru->devices,
                                          dmaru->devices_cnt, dev))
-                       return dmaru;
+                       goto out;
        }
+       dmaru = NULL;
+out:
+       rcu_read_unlock();
 
-       return NULL;
+       return dmaru;
 }
 
-int __init dmar_dev_scope_init(void)
+static void __init dmar_acpi_insert_dev_scope(u8 device_number,
+                                             struct acpi_device *adev)
 {
-       static int dmar_dev_scope_initialized;
-       struct dmar_drhd_unit *drhd;
-       int ret = -ENODEV;
-
-       if (dmar_dev_scope_initialized)
-               return dmar_dev_scope_initialized;
+       struct dmar_drhd_unit *dmaru;
+       struct acpi_dmar_hardware_unit *drhd;
+       struct acpi_dmar_device_scope *scope;
+       struct device *tmp;
+       int i;
+       struct acpi_dmar_pci_path *path;
 
-       if (list_empty(&dmar_drhd_units))
-               goto fail;
+       for_each_drhd_unit(dmaru) {
+               drhd = container_of(dmaru->hdr,
+                                   struct acpi_dmar_hardware_unit,
+                                   header);
 
-       list_for_each_entry(drhd, &dmar_drhd_units, list) {
-               ret = dmar_parse_dev(drhd);
-               if (ret)
-                       goto fail;
+               for (scope = (void *)(drhd + 1);
+                    (unsigned long)scope < ((unsigned long)drhd) + drhd->header.length;
+                    scope = ((void *)scope) + scope->length) {
+                       if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ACPI)
+                               continue;
+                       if (scope->enumeration_id != device_number)
+                               continue;
+
+                       path = (void *)(scope + 1);
+                       pr_info("ACPI device \"%s\" under DMAR at %llx as %02x:%02x.%d\n",
+                               dev_name(&adev->dev), dmaru->reg_base_addr,
+                               scope->bus, path->device, path->function);
+                       for_each_dev_scope(dmaru->devices, dmaru->devices_cnt, i, tmp)
+                               if (tmp == NULL) {
+                                       dmaru->devices[i].bus = scope->bus;
+                                       dmaru->devices[i].devfn = PCI_DEVFN(path->device,
+                                                                           path->function);
+                                       rcu_assign_pointer(dmaru->devices[i].dev,
+                                                          get_device(&adev->dev));
+                                       return;
+                               }
+                       BUG_ON(i >= dmaru->devices_cnt);
+               }
        }
+       pr_warn("No IOMMU scope found for ANDD enumeration ID %d (%s)\n",
+               device_number, dev_name(&adev->dev));
+}
 
-       ret = dmar_parse_rmrr_atsr_dev();
-       if (ret)
-               goto fail;
+static int __init dmar_acpi_dev_scope_init(void)
+{
+       struct acpi_dmar_andd *andd;
+
+       if (dmar_tbl == NULL)
+               return -ENODEV;
 
-       dmar_dev_scope_initialized = 1;
+       for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar);
+            ((unsigned long)andd) < ((unsigned long)dmar_tbl) + dmar_tbl->length;
+            andd = ((void *)andd) + andd->header.length) {
+               if (andd->header.type == ACPI_DMAR_TYPE_ANDD) {
+                       acpi_handle h;
+                       struct acpi_device *adev;
+
+                       if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
+                                                         andd->object_name,
+                                                         &h))) {
+                               pr_err("Failed to find handle for ACPI object %s\n",
+                                      andd->object_name);
+                               continue;
+                       }
+                       acpi_bus_get_device(h, &adev);
+                       if (!adev) {
+                               pr_err("Failed to get device for ACPI object %s\n",
+                                      andd->object_name);
+                               continue;
+                       }
+                       dmar_acpi_insert_dev_scope(andd->device_number, adev);
+               }
+       }
        return 0;
+}
 
-fail:
-       dmar_dev_scope_initialized = ret;
-       return ret;
+int __init dmar_dev_scope_init(void)
+{
+       struct pci_dev *dev = NULL;
+       struct dmar_pci_notify_info *info;
+
+       if (dmar_dev_scope_status != 1)
+               return dmar_dev_scope_status;
+
+       if (list_empty(&dmar_drhd_units)) {
+               dmar_dev_scope_status = -ENODEV;
+       } else {
+               dmar_dev_scope_status = 0;
+
+               dmar_acpi_dev_scope_init();
+
+               for_each_pci_dev(dev) {
+                       if (dev->is_virtfn)
+                               continue;
+
+                       info = dmar_alloc_pci_notify_info(dev,
+                                       BUS_NOTIFY_ADD_DEVICE);
+                       if (!info) {
+                               return dmar_dev_scope_status;
+                       } else {
+                               dmar_pci_bus_add_dev(info);
+                               dmar_free_pci_notify_info(info);
+                       }
+               }
+
+               bus_register_notifier(&pci_bus_type, &dmar_pci_bus_nb);
+       }
+
+       return dmar_dev_scope_status;
 }
 
 
@@ -557,6 +814,7 @@ int __init detect_intel_iommu(void)
 {
        int ret;
 
+       down_write(&dmar_global_lock);
        ret = dmar_table_detect();
        if (ret)
                ret = check_zero_address();
@@ -574,6 +832,7 @@ int __init detect_intel_iommu(void)
        }
        early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size);
        dmar_tbl = NULL;
+       up_write(&dmar_global_lock);
 
        return ret ? 1 : -ENODEV;
 }
@@ -696,6 +955,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
        }
        iommu->agaw = agaw;
        iommu->msagaw = msagaw;
+       iommu->segment = drhd->segment;
 
        iommu->node = -1;
 
@@ -1386,10 +1646,15 @@ static int __init dmar_free_unused_resources(void)
        if (irq_remapping_enabled || intel_iommu_enabled)
                return 0;
 
+       if (dmar_dev_scope_status != 1 && !list_empty(&dmar_drhd_units))
+               bus_unregister_notifier(&pci_bus_type, &dmar_pci_bus_nb);
+
+       down_write(&dmar_global_lock);
        list_for_each_entry_safe(dmaru, dmaru_n, &dmar_drhd_units, list) {
                list_del(&dmaru->list);
                dmar_free_drhd(dmaru);
        }
+       up_write(&dmar_global_lock);
 
        return 0;
 }
index a22c86c867faee78544b99b8528e1f4b9fc183c8..69fa7da5e48beba40a9595f67117505efc4e069b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Intel Corporation.
+ * Copyright Â© 2006-2014 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  * more details.
  *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Copyright (C) 2006-2008 Intel Corporation
- * Author: Ashok Raj <ashok.raj@intel.com>
- * Author: Shaohua Li <shaohua.li@intel.com>
- * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
- * Author: Fenghua Yu <fenghua.yu@intel.com>
+ * Authors: David Woodhouse <dwmw2@infradead.org>,
+ *          Ashok Raj <ashok.raj@intel.com>,
+ *          Shaohua Li <shaohua.li@intel.com>,
+ *          Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
+ *          Fenghua Yu <fenghua.yu@intel.com>
  */
 
 #include <linux/init.h>
@@ -33,6 +29,7 @@
 #include <linux/dmar.h>
 #include <linux/dma-mapping.h>
 #include <linux/mempool.h>
+#include <linux/memory.h>
 #include <linux/timer.h>
 #include <linux/iova.h>
 #include <linux/iommu.h>
@@ -372,14 +369,36 @@ struct dmar_domain {
 struct device_domain_info {
        struct list_head link;  /* link to domain siblings */
        struct list_head global; /* link to global list */
-       int segment;            /* PCI domain */
        u8 bus;                 /* PCI bus number */
        u8 devfn;               /* PCI devfn number */
-       struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */
+       struct device *dev; /* it's NULL for PCIe-to-PCI bridge */
        struct intel_iommu *iommu; /* IOMMU used by this device */
        struct dmar_domain *domain; /* pointer to domain */
 };
 
+struct dmar_rmrr_unit {
+       struct list_head list;          /* list of rmrr units   */
+       struct acpi_dmar_header *hdr;   /* ACPI header          */
+       u64     base_address;           /* reserved base address*/
+       u64     end_address;            /* reserved end address */
+       struct dmar_dev_scope *devices; /* target devices */
+       int     devices_cnt;            /* target device count */
+};
+
+struct dmar_atsr_unit {
+       struct list_head list;          /* list of ATSR units */
+       struct acpi_dmar_header *hdr;   /* ACPI header */
+       struct dmar_dev_scope *devices; /* target devices */
+       int devices_cnt;                /* target device count */
+       u8 include_all:1;               /* include all ports */
+};
+
+static LIST_HEAD(dmar_atsr_units);
+static LIST_HEAD(dmar_rmrr_units);
+
+#define for_each_rmrr_units(rmrr) \
+       list_for_each_entry(rmrr, &dmar_rmrr_units, list)
+
 static void flush_unmaps_timeout(unsigned long data);
 
 static DEFINE_TIMER(unmap_timer,  flush_unmaps_timeout, 0, 0);
@@ -389,6 +408,7 @@ struct deferred_flush_tables {
        int next;
        struct iova *iova[HIGH_WATER_MARK];
        struct dmar_domain *domain[HIGH_WATER_MARK];
+       struct page *freelist[HIGH_WATER_MARK];
 };
 
 static struct deferred_flush_tables *deferred_flush;
@@ -402,7 +422,12 @@ static LIST_HEAD(unmaps_to_do);
 static int timer_on;
 static long list_size;
 
+static void domain_exit(struct dmar_domain *domain);
 static void domain_remove_dev_info(struct dmar_domain *domain);
+static void domain_remove_one_dev_info(struct dmar_domain *domain,
+                                      struct device *dev);
+static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+                                          struct device *dev);
 
 #ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
 int dmar_disabled = 0;
@@ -566,18 +591,31 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
 
 static void domain_update_iommu_coherency(struct dmar_domain *domain)
 {
-       int i;
-
-       i = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
+       struct dmar_drhd_unit *drhd;
+       struct intel_iommu *iommu;
+       int i, found = 0;
 
-       domain->iommu_coherency = i < g_num_of_iommus ? 1 : 0;
+       domain->iommu_coherency = 1;
 
        for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
+               found = 1;
                if (!ecap_coherent(g_iommus[i]->ecap)) {
                        domain->iommu_coherency = 0;
                        break;
                }
        }
+       if (found)
+               return;
+
+       /* No hardware attached; use lowest common denominator */
+       rcu_read_lock();
+       for_each_active_iommu(iommu, drhd) {
+               if (!ecap_coherent(iommu->ecap)) {
+                       domain->iommu_coherency = 0;
+                       break;
+               }
+       }
+       rcu_read_unlock();
 }
 
 static void domain_update_iommu_snooping(struct dmar_domain *domain)
@@ -606,12 +644,15 @@ static void domain_update_iommu_superpage(struct dmar_domain *domain)
        }
 
        /* set iommu_superpage to the smallest common denominator */
+       rcu_read_lock();
        for_each_active_iommu(iommu, drhd) {
                mask &= cap_super_page_val(iommu->cap);
                if (!mask) {
                        break;
                }
        }
+       rcu_read_unlock();
+
        domain->iommu_superpage = fls(mask);
 }
 
@@ -623,32 +664,56 @@ static void domain_update_iommu_cap(struct dmar_domain *domain)
        domain_update_iommu_superpage(domain);
 }
 
-static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
+static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
 {
        struct dmar_drhd_unit *drhd = NULL;
+       struct intel_iommu *iommu;
+       struct device *tmp;
+       struct pci_dev *ptmp, *pdev = NULL;
+       u16 segment;
        int i;
 
-       for_each_active_drhd_unit(drhd) {
-               if (segment != drhd->segment)
+       if (dev_is_pci(dev)) {
+               pdev = to_pci_dev(dev);
+               segment = pci_domain_nr(pdev->bus);
+       } else if (ACPI_COMPANION(dev))
+               dev = &ACPI_COMPANION(dev)->dev;
+
+       rcu_read_lock();
+       for_each_active_iommu(iommu, drhd) {
+               if (pdev && segment != drhd->segment)
                        continue;
 
-               for (i = 0; i < drhd->devices_cnt; i++) {
-                       if (drhd->devices[i] &&
-                           drhd->devices[i]->bus->number == bus &&
-                           drhd->devices[i]->devfn == devfn)
-                               return drhd->iommu;
-                       if (drhd->devices[i] &&
-                           drhd->devices[i]->subordinate &&
-                           drhd->devices[i]->subordinate->number <= bus &&
-                           drhd->devices[i]->subordinate->busn_res.end >= bus)
-                               return drhd->iommu;
+               for_each_active_dev_scope(drhd->devices,
+                                         drhd->devices_cnt, i, tmp) {
+                       if (tmp == dev) {
+                               *bus = drhd->devices[i].bus;
+                               *devfn = drhd->devices[i].devfn;
+                               goto out;
+                       }
+
+                       if (!pdev || !dev_is_pci(tmp))
+                               continue;
+
+                       ptmp = to_pci_dev(tmp);
+                       if (ptmp->subordinate &&
+                           ptmp->subordinate->number <= pdev->bus->number &&
+                           ptmp->subordinate->busn_res.end >= pdev->bus->number)
+                               goto got_pdev;
                }
 
-               if (drhd->include_all)
-                       return drhd->iommu;
+               if (pdev && drhd->include_all) {
+               got_pdev:
+                       *bus = pdev->bus->number;
+                       *devfn = pdev->devfn;
+                       goto out;
+               }
        }
+       iommu = NULL;
+ out:
+       rcu_read_unlock();
 
-       return NULL;
+       return iommu;
 }
 
 static void domain_flush_cache(struct dmar_domain *domain,
@@ -748,7 +813,7 @@ out:
 }
 
 static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
-                                     unsigned long pfn, int target_level)
+                                     unsigned long pfn, int *target_level)
 {
        int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
        struct dma_pte *parent, *pte = NULL;
@@ -763,14 +828,14 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
 
        parent = domain->pgd;
 
-       while (level > 0) {
+       while (1) {
                void *tmp_page;
 
                offset = pfn_level_offset(pfn, level);
                pte = &parent[offset];
-               if (!target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
+               if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
                        break;
-               if (level == target_level)
+               if (level == *target_level)
                        break;
 
                if (!dma_pte_present(pte)) {
@@ -791,10 +856,16 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
                                domain_flush_cache(domain, pte, sizeof(*pte));
                        }
                }
+               if (level == 1)
+                       break;
+
                parent = phys_to_virt(dma_pte_addr(pte));
                level--;
        }
 
+       if (!*target_level)
+               *target_level = level;
+
        return pte;
 }
 
@@ -832,7 +903,7 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
 }
 
 /* clear last level pte, a tlb flush should be followed */
-static int dma_pte_clear_range(struct dmar_domain *domain,
+static void dma_pte_clear_range(struct dmar_domain *domain,
                                unsigned long start_pfn,
                                unsigned long last_pfn)
 {
@@ -862,8 +933,6 @@ static int dma_pte_clear_range(struct dmar_domain *domain,
                                   (void *)pte - (void *)first_pte);
 
        } while (start_pfn && start_pfn <= last_pfn);
-
-       return min_t(int, (large_page - 1) * 9, MAX_AGAW_PFN_WIDTH);
 }
 
 static void dma_pte_free_level(struct dmar_domain *domain, int level,
@@ -921,6 +990,123 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain,
        }
 }
 
+/* When a page at a given level is being unlinked from its parent, we don't
+   need to *modify* it at all. All we need to do is make a list of all the
+   pages which can be freed just as soon as we've flushed the IOTLB and we
+   know the hardware page-walk will no longer touch them.
+   The 'pte' argument is the *parent* PTE, pointing to the page that is to
+   be freed. */
+static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
+                                           int level, struct dma_pte *pte,
+                                           struct page *freelist)
+{
+       struct page *pg;
+
+       pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
+       pg->freelist = freelist;
+       freelist = pg;
+
+       if (level == 1)
+               return freelist;
+
+       for (pte = page_address(pg); !first_pte_in_page(pte); pte++) {
+               if (dma_pte_present(pte) && !dma_pte_superpage(pte))
+                       freelist = dma_pte_list_pagetables(domain, level - 1,
+                                                          pte, freelist);
+       }
+
+       return freelist;
+}
+
+static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
+                                       struct dma_pte *pte, unsigned long pfn,
+                                       unsigned long start_pfn,
+                                       unsigned long last_pfn,
+                                       struct page *freelist)
+{
+       struct dma_pte *first_pte = NULL, *last_pte = NULL;
+
+       pfn = max(start_pfn, pfn);
+       pte = &pte[pfn_level_offset(pfn, level)];
+
+       do {
+               unsigned long level_pfn;
+
+               if (!dma_pte_present(pte))
+                       goto next;
+
+               level_pfn = pfn & level_mask(level);
+
+               /* If range covers entire pagetable, free it */
+               if (start_pfn <= level_pfn &&
+                   last_pfn >= level_pfn + level_size(level) - 1) {
+                       /* These suborbinate page tables are going away entirely. Don't
+                          bother to clear them; we're just going to *free* them. */
+                       if (level > 1 && !dma_pte_superpage(pte))
+                               freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
+
+                       dma_clear_pte(pte);
+                       if (!first_pte)
+                               first_pte = pte;
+                       last_pte = pte;
+               } else if (level > 1) {
+                       /* Recurse down into a level that isn't *entirely* obsolete */
+                       freelist = dma_pte_clear_level(domain, level - 1,
+                                                      phys_to_virt(dma_pte_addr(pte)),
+                                                      level_pfn, start_pfn, last_pfn,
+                                                      freelist);
+               }
+next:
+               pfn += level_size(level);
+       } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
+
+       if (first_pte)
+               domain_flush_cache(domain, first_pte,
+                                  (void *)++last_pte - (void *)first_pte);
+
+       return freelist;
+}
+
+/* We can't just free the pages because the IOMMU may still be walking
+   the page tables, and may have cached the intermediate levels. The
+   pages can only be freed after the IOTLB flush has been done. */
+struct page *domain_unmap(struct dmar_domain *domain,
+                         unsigned long start_pfn,
+                         unsigned long last_pfn)
+{
+       int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
+       struct page *freelist = NULL;
+
+       BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
+       BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
+       BUG_ON(start_pfn > last_pfn);
+
+       /* we don't need lock here; nobody else touches the iova range */
+       freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
+                                      domain->pgd, 0, start_pfn, last_pfn, NULL);
+
+       /* free pgd */
+       if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
+               struct page *pgd_page = virt_to_page(domain->pgd);
+               pgd_page->freelist = freelist;
+               freelist = pgd_page;
+
+               domain->pgd = NULL;
+       }
+
+       return freelist;
+}
+
+void dma_free_pagelist(struct page *freelist)
+{
+       struct page *pg;
+
+       while ((pg = freelist)) {
+               freelist = pg->freelist;
+               free_pgtable_page(page_address(pg));
+       }
+}
+
 /* iommu handling */
 static int iommu_alloc_root_entry(struct intel_iommu *iommu)
 {
@@ -1030,7 +1216,7 @@ static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
                break;
        case DMA_TLB_PSI_FLUSH:
                val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
-               /* Note: always flush non-leaf currently */
+               /* IH bit is passed in as part of address */
                val_iva = size_order | addr;
                break;
        default:
@@ -1069,13 +1255,14 @@ static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
                        (unsigned long long)DMA_TLB_IAIG(val));
 }
 
-static struct device_domain_info *iommu_support_dev_iotlb(
-       struct dmar_domain *domain, int segment, u8 bus, u8 devfn)
+static struct device_domain_info *
+iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
+                        u8 bus, u8 devfn)
 {
        int found = 0;
        unsigned long flags;
        struct device_domain_info *info;
-       struct intel_iommu *iommu = device_to_iommu(segment, bus, devfn);
+       struct pci_dev *pdev;
 
        if (!ecap_dev_iotlb_support(iommu->ecap))
                return NULL;
@@ -1091,34 +1278,35 @@ static struct device_domain_info *iommu_support_dev_iotlb(
                }
        spin_unlock_irqrestore(&device_domain_lock, flags);
 
-       if (!found || !info->dev)
+       if (!found || !info->dev || !dev_is_pci(info->dev))
                return NULL;
 
-       if (!pci_find_ext_capability(info->dev, PCI_EXT_CAP_ID_ATS))
-               return NULL;
+       pdev = to_pci_dev(info->dev);
 
-       if (!dmar_find_matched_atsr_unit(info->dev))
+       if (!pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS))
                return NULL;
 
-       info->iommu = iommu;
+       if (!dmar_find_matched_atsr_unit(pdev))
+               return NULL;
 
        return info;
 }
 
 static void iommu_enable_dev_iotlb(struct device_domain_info *info)
 {
-       if (!info)
+       if (!info || !dev_is_pci(info->dev))
                return;
 
-       pci_enable_ats(info->dev, VTD_PAGE_SHIFT);
+       pci_enable_ats(to_pci_dev(info->dev), VTD_PAGE_SHIFT);
 }
 
 static void iommu_disable_dev_iotlb(struct device_domain_info *info)
 {
-       if (!info->dev || !pci_ats_enabled(info->dev))
+       if (!info->dev || !dev_is_pci(info->dev) ||
+           !pci_ats_enabled(to_pci_dev(info->dev)))
                return;
 
-       pci_disable_ats(info->dev);
+       pci_disable_ats(to_pci_dev(info->dev));
 }
 
 static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
@@ -1130,24 +1318,31 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
 
        spin_lock_irqsave(&device_domain_lock, flags);
        list_for_each_entry(info, &domain->devices, link) {
-               if (!info->dev || !pci_ats_enabled(info->dev))
+               struct pci_dev *pdev;
+               if (!info->dev || !dev_is_pci(info->dev))
+                       continue;
+
+               pdev = to_pci_dev(info->dev);
+               if (!pci_ats_enabled(pdev))
                        continue;
 
                sid = info->bus << 8 | info->devfn;
-               qdep = pci_ats_queue_depth(info->dev);
+               qdep = pci_ats_queue_depth(pdev);
                qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
        }
        spin_unlock_irqrestore(&device_domain_lock, flags);
 }
 
 static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
-                                 unsigned long pfn, unsigned int pages, int map)
+                                 unsigned long pfn, unsigned int pages, int ih, int map)
 {
        unsigned int mask = ilog2(__roundup_pow_of_two(pages));
        uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
 
        BUG_ON(pages == 0);
 
+       if (ih)
+               ih = 1 << 6;
        /*
         * Fallback to domain selective flush if no PSI support or the size is
         * too big.
@@ -1158,7 +1353,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
                iommu->flush.flush_iotlb(iommu, did, 0, 0,
                                                DMA_TLB_DSI_FLUSH);
        else
-               iommu->flush.flush_iotlb(iommu, did, addr, mask,
+               iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
                                                DMA_TLB_PSI_FLUSH);
 
        /*
@@ -1261,10 +1456,6 @@ static int iommu_init_domains(struct intel_iommu *iommu)
        return 0;
 }
 
-
-static void domain_exit(struct dmar_domain *domain);
-static void vm_domain_exit(struct dmar_domain *domain);
-
 static void free_dmar_iommu(struct intel_iommu *iommu)
 {
        struct dmar_domain *domain;
@@ -1273,18 +1464,21 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 
        if ((iommu->domains) && (iommu->domain_ids)) {
                for_each_set_bit(i, iommu->domain_ids, cap_ndoms(iommu->cap)) {
+                       /*
+                        * Domain id 0 is reserved for invalid translation
+                        * if hardware supports caching mode.
+                        */
+                       if (cap_caching_mode(iommu->cap) && i == 0)
+                               continue;
+
                        domain = iommu->domains[i];
                        clear_bit(i, iommu->domain_ids);
 
                        spin_lock_irqsave(&domain->iommu_lock, flags);
                        count = --domain->iommu_count;
                        spin_unlock_irqrestore(&domain->iommu_lock, flags);
-                       if (count == 0) {
-                               if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE)
-                                       vm_domain_exit(domain);
-                               else
-                                       domain_exit(domain);
-                       }
+                       if (count == 0)
+                               domain_exit(domain);
                }
        }
 
@@ -1298,21 +1492,14 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 
        g_iommus[iommu->seq_id] = NULL;
 
-       /* if all iommus are freed, free g_iommus */
-       for (i = 0; i < g_num_of_iommus; i++) {
-               if (g_iommus[i])
-                       break;
-       }
-
-       if (i == g_num_of_iommus)
-               kfree(g_iommus);
-
        /* free context mapping */
        free_context_table(iommu);
 }
 
-static struct dmar_domain *alloc_domain(void)
+static struct dmar_domain *alloc_domain(bool vm)
 {
+       /* domain id for virtual machine, it won't be set in context */
+       static atomic_t vm_domid = ATOMIC_INIT(0);
        struct dmar_domain *domain;
 
        domain = alloc_domain_mem();
@@ -1320,8 +1507,15 @@ static struct dmar_domain *alloc_domain(void)
                return NULL;
 
        domain->nid = -1;
+       domain->iommu_count = 0;
        memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
        domain->flags = 0;
+       spin_lock_init(&domain->iommu_lock);
+       INIT_LIST_HEAD(&domain->devices);
+       if (vm) {
+               domain->id = atomic_inc_return(&vm_domid);
+               domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
+       }
 
        return domain;
 }
@@ -1345,6 +1539,7 @@ static int iommu_attach_domain(struct dmar_domain *domain,
        }
 
        domain->id = num;
+       domain->iommu_count++;
        set_bit(num, iommu->domain_ids);
        set_bit(iommu->seq_id, domain->iommu_bmp);
        iommu->domains[num] = domain;
@@ -1358,22 +1553,16 @@ static void iommu_detach_domain(struct dmar_domain *domain,
 {
        unsigned long flags;
        int num, ndomains;
-       int found = 0;
 
        spin_lock_irqsave(&iommu->lock, flags);
        ndomains = cap_ndoms(iommu->cap);
        for_each_set_bit(num, iommu->domain_ids, ndomains) {
                if (iommu->domains[num] == domain) {
-                       found = 1;
+                       clear_bit(num, iommu->domain_ids);
+                       iommu->domains[num] = NULL;
                        break;
                }
        }
-
-       if (found) {
-               clear_bit(num, iommu->domain_ids);
-               clear_bit(iommu->seq_id, domain->iommu_bmp);
-               iommu->domains[num] = NULL;
-       }
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -1445,8 +1634,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
        unsigned long sagaw;
 
        init_iova_domain(&domain->iovad, DMA_32BIT_PFN);
-       spin_lock_init(&domain->iommu_lock);
-
        domain_reserve_special_ranges(domain);
 
        /* calculate AGAW */
@@ -1465,7 +1652,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
                        return -ENODEV;
        }
        domain->agaw = agaw;
-       INIT_LIST_HEAD(&domain->devices);
 
        if (ecap_coherent(iommu->ecap))
                domain->iommu_coherency = 1;
@@ -1477,8 +1663,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
        else
                domain->iommu_snooping = 0;
 
-       domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
-       domain->iommu_count = 1;
+       if (intel_iommu_superpage)
+               domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
+       else
+               domain->iommu_superpage = 0;
+
        domain->nid = iommu->node;
 
        /* always allocate the top pgd */
@@ -1493,6 +1682,7 @@ static void domain_exit(struct dmar_domain *domain)
 {
        struct dmar_drhd_unit *drhd;
        struct intel_iommu *iommu;
+       struct page *freelist = NULL;
 
        /* Domain 0 is reserved, so dont process it */
        if (!domain)
@@ -1502,29 +1692,33 @@ static void domain_exit(struct dmar_domain *domain)
        if (!intel_iommu_strict)
                flush_unmaps_timeout(0);
 
+       /* remove associated devices */
        domain_remove_dev_info(domain);
+
        /* destroy iovas */
        put_iova_domain(&domain->iovad);
 
-       /* clear ptes */
-       dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
-
-       /* free page tables */
-       dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
+       freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
 
+       /* clear attached or cached domains */
+       rcu_read_lock();
        for_each_active_iommu(iommu, drhd)
-               if (test_bit(iommu->seq_id, domain->iommu_bmp))
+               if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE ||
+                   test_bit(iommu->seq_id, domain->iommu_bmp))
                        iommu_detach_domain(domain, iommu);
+       rcu_read_unlock();
+
+       dma_free_pagelist(freelist);
 
        free_domain_mem(domain);
 }
 
-static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
-                                u8 bus, u8 devfn, int translation)
+static int domain_context_mapping_one(struct dmar_domain *domain,
+                                     struct intel_iommu *iommu,
+                                     u8 bus, u8 devfn, int translation)
 {
        struct context_entry *context;
        unsigned long flags;
-       struct intel_iommu *iommu;
        struct dma_pte *pgd;
        unsigned long num;
        unsigned long ndomains;
@@ -1539,10 +1733,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
        BUG_ON(translation != CONTEXT_TT_PASS_THROUGH &&
               translation != CONTEXT_TT_MULTI_LEVEL);
 
-       iommu = device_to_iommu(segment, bus, devfn);
-       if (!iommu)
-               return -ENODEV;
-
        context = device_to_context_entry(iommu, bus, devfn);
        if (!context)
                return -ENOMEM;
@@ -1600,7 +1790,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
        context_set_domain_id(context, id);
 
        if (translation != CONTEXT_TT_PASS_THROUGH) {
-               info = iommu_support_dev_iotlb(domain, segment, bus, devfn);
+               info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
                translation = info ? CONTEXT_TT_DEV_IOTLB :
                                     CONTEXT_TT_MULTI_LEVEL;
        }
@@ -1650,27 +1840,32 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
 }
 
 static int
-domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev,
-                       int translation)
+domain_context_mapping(struct dmar_domain *domain, struct device *dev,
+                      int translation)
 {
        int ret;
-       struct pci_dev *tmp, *parent;
+       struct pci_dev *pdev, *tmp, *parent;
+       struct intel_iommu *iommu;
+       u8 bus, devfn;
+
+       iommu = device_to_iommu(dev, &bus, &devfn);
+       if (!iommu)
+               return -ENODEV;
 
-       ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
-                                        pdev->bus->number, pdev->devfn,
+       ret = domain_context_mapping_one(domain, iommu, bus, devfn,
                                         translation);
-       if (ret)
+       if (ret || !dev_is_pci(dev))
                return ret;
 
        /* dependent device mapping */
+       pdev = to_pci_dev(dev);
        tmp = pci_find_upstream_pcie_bridge(pdev);
        if (!tmp)
                return 0;
        /* Secondary interface's bus number and devfn 0 */
        parent = pdev->bus->self;
        while (parent != tmp) {
-               ret = domain_context_mapping_one(domain,
-                                                pci_domain_nr(parent->bus),
+               ret = domain_context_mapping_one(domain, iommu,
                                                 parent->bus->number,
                                                 parent->devfn, translation);
                if (ret)
@@ -1678,33 +1873,33 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev,
                parent = parent->bus->self;
        }
        if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
-               return domain_context_mapping_one(domain,
-                                       pci_domain_nr(tmp->subordinate),
+               return domain_context_mapping_one(domain, iommu,
                                        tmp->subordinate->number, 0,
                                        translation);
        else /* this is a legacy PCI bridge */
-               return domain_context_mapping_one(domain,
-                                                 pci_domain_nr(tmp->bus),
+               return domain_context_mapping_one(domain, iommu,
                                                  tmp->bus->number,
                                                  tmp->devfn,
                                                  translation);
 }
 
-static int domain_context_mapped(struct pci_dev *pdev)
+static int domain_context_mapped(struct device *dev)
 {
        int ret;
-       struct pci_dev *tmp, *parent;
+       struct pci_dev *pdev, *tmp, *parent;
        struct intel_iommu *iommu;
+       u8 bus, devfn;
 
-       iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
-                               pdev->devfn);
+       iommu = device_to_iommu(dev, &bus, &devfn);
        if (!iommu)
                return -ENODEV;
 
-       ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn);
-       if (!ret)
+       ret = device_context_mapped(iommu, bus, devfn);
+       if (!ret || !dev_is_pci(dev))
                return ret;
+
        /* dependent device mapping */
+       pdev = to_pci_dev(dev);
        tmp = pci_find_upstream_pcie_bridge(pdev);
        if (!tmp)
                return ret;
@@ -1800,7 +1995,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                if (!pte) {
                        largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
 
-                       first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, largepage_lvl);
+                       first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
                        if (!pte)
                                return -ENOMEM;
                        /* It is large page*/
@@ -1899,14 +2094,13 @@ static inline void unlink_domain_info(struct device_domain_info *info)
        list_del(&info->link);
        list_del(&info->global);
        if (info->dev)
-               info->dev->dev.archdata.iommu = NULL;
+               info->dev->archdata.iommu = NULL;
 }
 
 static void domain_remove_dev_info(struct dmar_domain *domain)
 {
        struct device_domain_info *info;
-       unsigned long flags;
-       struct intel_iommu *iommu;
+       unsigned long flags, flags2;
 
        spin_lock_irqsave(&device_domain_lock, flags);
        while (!list_empty(&domain->devices)) {
@@ -1916,10 +2110,23 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
                spin_unlock_irqrestore(&device_domain_lock, flags);
 
                iommu_disable_dev_iotlb(info);
-               iommu = device_to_iommu(info->segment, info->bus, info->devfn);
-               iommu_detach_dev(iommu, info->bus, info->devfn);
-               free_devinfo_mem(info);
+               iommu_detach_dev(info->iommu, info->bus, info->devfn);
+
+               if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) {
+                       iommu_detach_dependent_devices(info->iommu, info->dev);
+                       /* clear this iommu in iommu_bmp, update iommu count
+                        * and capabilities
+                        */
+                       spin_lock_irqsave(&domain->iommu_lock, flags2);
+                       if (test_and_clear_bit(info->iommu->seq_id,
+                                              domain->iommu_bmp)) {
+                               domain->iommu_count--;
+                               domain_update_iommu_cap(domain);
+                       }
+                       spin_unlock_irqrestore(&domain->iommu_lock, flags2);
+               }
 
+               free_devinfo_mem(info);
                spin_lock_irqsave(&device_domain_lock, flags);
        }
        spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -1927,155 +2134,151 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
 
 /*
  * find_domain
- * Note: we use struct pci_dev->dev.archdata.iommu stores the info
+ * Note: we use struct device->archdata.iommu stores the info
  */
-static struct dmar_domain *
-find_domain(struct pci_dev *pdev)
+static struct dmar_domain *find_domain(struct device *dev)
 {
        struct device_domain_info *info;
 
        /* No lock here, assumes no domain exit in normal case */
-       info = pdev->dev.archdata.iommu;
+       info = dev->archdata.iommu;
        if (info)
                return info->domain;
        return NULL;
 }
 
+static inline struct device_domain_info *
+dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
+{
+       struct device_domain_info *info;
+
+       list_for_each_entry(info, &device_domain_list, global)
+               if (info->iommu->segment == segment && info->bus == bus &&
+                   info->devfn == devfn)
+                       return info;
+
+       return NULL;
+}
+
+static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
+                                               int bus, int devfn,
+                                               struct device *dev,
+                                               struct dmar_domain *domain)
+{
+       struct dmar_domain *found = NULL;
+       struct device_domain_info *info;
+       unsigned long flags;
+
+       info = alloc_devinfo_mem();
+       if (!info)
+               return NULL;
+
+       info->bus = bus;
+       info->devfn = devfn;
+       info->dev = dev;
+       info->domain = domain;
+       info->iommu = iommu;
+       if (!dev)
+               domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
+
+       spin_lock_irqsave(&device_domain_lock, flags);
+       if (dev)
+               found = find_domain(dev);
+       else {
+               struct device_domain_info *info2;
+               info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
+               if (info2)
+                       found = info2->domain;
+       }
+       if (found) {
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+               free_devinfo_mem(info);
+               /* Caller must free the original domain */
+               return found;
+       }
+
+       list_add(&info->link, &domain->devices);
+       list_add(&info->global, &device_domain_list);
+       if (dev)
+               dev->archdata.iommu = info;
+       spin_unlock_irqrestore(&device_domain_lock, flags);
+
+       return domain;
+}
+
 /* domain is initialized */
-static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
+static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
 {
-       struct dmar_domain *domain, *found = NULL;
-       struct intel_iommu *iommu;
-       struct dmar_drhd_unit *drhd;
-       struct device_domain_info *info, *tmp;
-       struct pci_dev *dev_tmp;
+       struct dmar_domain *domain, *free = NULL;
+       struct intel_iommu *iommu = NULL;
+       struct device_domain_info *info;
+       struct pci_dev *dev_tmp = NULL;
        unsigned long flags;
-       int bus = 0, devfn = 0;
-       int segment;
-       int ret;
+       u8 bus, devfn, bridge_bus, bridge_devfn;
 
-       domain = find_domain(pdev);
+       domain = find_domain(dev);
        if (domain)
                return domain;
 
-       segment = pci_domain_nr(pdev->bus);
+       if (dev_is_pci(dev)) {
+               struct pci_dev *pdev = to_pci_dev(dev);
+               u16 segment;
 
-       dev_tmp = pci_find_upstream_pcie_bridge(pdev);
-       if (dev_tmp) {
-               if (pci_is_pcie(dev_tmp)) {
-                       bus = dev_tmp->subordinate->number;
-                       devfn = 0;
-               } else {
-                       bus = dev_tmp->bus->number;
-                       devfn = dev_tmp->devfn;
-               }
-               spin_lock_irqsave(&device_domain_lock, flags);
-               list_for_each_entry(info, &device_domain_list, global) {
-                       if (info->segment == segment &&
-                           info->bus == bus && info->devfn == devfn) {
-                               found = info->domain;
-                               break;
+               segment = pci_domain_nr(pdev->bus);
+               dev_tmp = pci_find_upstream_pcie_bridge(pdev);
+               if (dev_tmp) {
+                       if (pci_is_pcie(dev_tmp)) {
+                               bridge_bus = dev_tmp->subordinate->number;
+                               bridge_devfn = 0;
+                       } else {
+                               bridge_bus = dev_tmp->bus->number;
+                               bridge_devfn = dev_tmp->devfn;
                        }
-               }
-               spin_unlock_irqrestore(&device_domain_lock, flags);
-               /* pcie-pci bridge already has a domain, uses it */
-               if (found) {
-                       domain = found;
-                       goto found_domain;
+                       spin_lock_irqsave(&device_domain_lock, flags);
+                       info = dmar_search_domain_by_dev_info(segment, bus, devfn);
+                       if (info) {
+                               iommu = info->iommu;
+                               domain = info->domain;
+                       }
+                       spin_unlock_irqrestore(&device_domain_lock, flags);
+                       /* pcie-pci bridge already has a domain, uses it */
+                       if (info)
+                               goto found_domain;
                }
        }
 
-       domain = alloc_domain();
-       if (!domain)
+       iommu = device_to_iommu(dev, &bus, &devfn);
+       if (!iommu)
                goto error;
 
-       /* Allocate new domain for the device */
-       drhd = dmar_find_matched_drhd_unit(pdev);
-       if (!drhd) {
-               printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
-                       pci_name(pdev));
-               free_domain_mem(domain);
-               return NULL;
-       }
-       iommu = drhd->iommu;
-
-       ret = iommu_attach_domain(domain, iommu);
-       if (ret) {
+       /* Allocate and initialize new domain for the device */
+       domain = alloc_domain(false);
+       if (!domain)
+               goto error;
+       if (iommu_attach_domain(domain, iommu)) {
                free_domain_mem(domain);
+               domain = NULL;
                goto error;
        }
-
-       if (domain_init(domain, gaw)) {
-               domain_exit(domain);
+       free = domain;
+       if (domain_init(domain, gaw))
                goto error;
-       }
 
        /* register pcie-to-pci device */
        if (dev_tmp) {
-               info = alloc_devinfo_mem();
-               if (!info) {
-                       domain_exit(domain);
+               domain = dmar_insert_dev_info(iommu, bridge_bus, bridge_devfn,
+                                             NULL, domain);
+               if (!domain)
                        goto error;
-               }
-               info->segment = segment;
-               info->bus = bus;
-               info->devfn = devfn;
-               info->dev = NULL;
-               info->domain = domain;
-               /* This domain is shared by devices under p2p bridge */
-               domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
-
-               /* pcie-to-pci bridge already has a domain, uses it */
-               found = NULL;
-               spin_lock_irqsave(&device_domain_lock, flags);
-               list_for_each_entry(tmp, &device_domain_list, global) {
-                       if (tmp->segment == segment &&
-                           tmp->bus == bus && tmp->devfn == devfn) {
-                               found = tmp->domain;
-                               break;
-                       }
-               }
-               if (found) {
-                       spin_unlock_irqrestore(&device_domain_lock, flags);
-                       free_devinfo_mem(info);
-                       domain_exit(domain);
-                       domain = found;
-               } else {
-                       list_add(&info->link, &domain->devices);
-                       list_add(&info->global, &device_domain_list);
-                       spin_unlock_irqrestore(&device_domain_lock, flags);
-               }
        }
 
 found_domain:
-       info = alloc_devinfo_mem();
-       if (!info)
-               goto error;
-       info->segment = segment;
-       info->bus = pdev->bus->number;
-       info->devfn = pdev->devfn;
-       info->dev = pdev;
-       info->domain = domain;
-       spin_lock_irqsave(&device_domain_lock, flags);
-       /* somebody is fast */
-       found = find_domain(pdev);
-       if (found != NULL) {
-               spin_unlock_irqrestore(&device_domain_lock, flags);
-               if (found != domain) {
-                       domain_exit(domain);
-                       domain = found;
-               }
-               free_devinfo_mem(info);
-               return domain;
-       }
-       list_add(&info->link, &domain->devices);
-       list_add(&info->global, &device_domain_list);
-       pdev->dev.archdata.iommu = info;
-       spin_unlock_irqrestore(&device_domain_lock, flags);
-       return domain;
+       domain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
 error:
-       /* recheck it here, maybe others set it */
-       return find_domain(pdev);
+       if (free != domain)
+               domain_exit(free);
+
+       return domain;
 }
 
 static int iommu_identity_mapping;
@@ -2109,14 +2312,14 @@ static int iommu_domain_identity_map(struct dmar_domain *domain,
                                  DMA_PTE_READ|DMA_PTE_WRITE);
 }
 
-static int iommu_prepare_identity_map(struct pci_dev *pdev,
+static int iommu_prepare_identity_map(struct device *dev,
                                      unsigned long long start,
                                      unsigned long long end)
 {
        struct dmar_domain *domain;
        int ret;
 
-       domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+       domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
        if (!domain)
                return -ENOMEM;
 
@@ -2126,13 +2329,13 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
           up to start with in si_domain */
        if (domain == si_domain && hw_pass_through) {
                printk("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
-                      pci_name(pdev), start, end);
+                      dev_name(dev), start, end);
                return 0;
        }
 
        printk(KERN_INFO
               "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
-              pci_name(pdev), start, end);
+              dev_name(dev), start, end);
        
        if (end < start) {
                WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
@@ -2160,7 +2363,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
                goto error;
 
        /* context entry init */
-       ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL);
+       ret = domain_context_mapping(domain, dev, CONTEXT_TT_MULTI_LEVEL);
        if (ret)
                goto error;
 
@@ -2172,12 +2375,12 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
 }
 
 static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
-       struct pci_dev *pdev)
+                                        struct device *dev)
 {
-       if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+       if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
                return 0;
-       return iommu_prepare_identity_map(pdev, rmrr->base_address,
-               rmrr->end_address);
+       return iommu_prepare_identity_map(dev, rmrr->base_address,
+                                         rmrr->end_address);
 }
 
 #ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
@@ -2191,7 +2394,7 @@ static inline void iommu_prepare_isa(void)
                return;
 
        printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
-       ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1);
+       ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
 
        if (ret)
                printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
@@ -2213,10 +2416,12 @@ static int __init si_domain_init(int hw)
        struct intel_iommu *iommu;
        int nid, ret = 0;
 
-       si_domain = alloc_domain();
+       si_domain = alloc_domain(false);
        if (!si_domain)
                return -EFAULT;
 
+       si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;
+
        for_each_active_iommu(iommu, drhd) {
                ret = iommu_attach_domain(si_domain, iommu);
                if (ret) {
@@ -2230,7 +2435,6 @@ static int __init si_domain_init(int hw)
                return -EFAULT;
        }
 
-       si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;
        pr_debug("IOMMU: identity mapping domain is domain %d\n",
                 si_domain->id);
 
@@ -2252,16 +2456,14 @@ static int __init si_domain_init(int hw)
        return 0;
 }
 
-static void domain_remove_one_dev_info(struct dmar_domain *domain,
-                                         struct pci_dev *pdev);
-static int identity_mapping(struct pci_dev *pdev)
+static int identity_mapping(struct device *dev)
 {
        struct device_domain_info *info;
 
        if (likely(!iommu_identity_mapping))
                return 0;
 
-       info = pdev->dev.archdata.iommu;
+       info = dev->archdata.iommu;
        if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
                return (info->domain == si_domain);
 
@@ -2269,111 +2471,112 @@ static int identity_mapping(struct pci_dev *pdev)
 }
 
 static int domain_add_dev_info(struct dmar_domain *domain,
-                              struct pci_dev *pdev,
-                              int translation)
+                              struct device *dev, int translation)
 {
-       struct device_domain_info *info;
-       unsigned long flags;
+       struct dmar_domain *ndomain;
+       struct intel_iommu *iommu;
+       u8 bus, devfn;
        int ret;
 
-       info = alloc_devinfo_mem();
-       if (!info)
-               return -ENOMEM;
+       iommu = device_to_iommu(dev, &bus, &devfn);
+       if (!iommu)
+               return -ENODEV;
 
-       info->segment = pci_domain_nr(pdev->bus);
-       info->bus = pdev->bus->number;
-       info->devfn = pdev->devfn;
-       info->dev = pdev;
-       info->domain = domain;
+       ndomain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
+       if (ndomain != domain)
+               return -EBUSY;
 
-       spin_lock_irqsave(&device_domain_lock, flags);
-       list_add(&info->link, &domain->devices);
-       list_add(&info->global, &device_domain_list);
-       pdev->dev.archdata.iommu = info;
-       spin_unlock_irqrestore(&device_domain_lock, flags);
-
-       ret = domain_context_mapping(domain, pdev, translation);
+       ret = domain_context_mapping(domain, dev, translation);
        if (ret) {
-               spin_lock_irqsave(&device_domain_lock, flags);
-               unlink_domain_info(info);
-               spin_unlock_irqrestore(&device_domain_lock, flags);
-               free_devinfo_mem(info);
+               domain_remove_one_dev_info(domain, dev);
                return ret;
        }
 
        return 0;
 }
 
-static bool device_has_rmrr(struct pci_dev *dev)
+static bool device_has_rmrr(struct device *dev)
 {
        struct dmar_rmrr_unit *rmrr;
+       struct device *tmp;
        int i;
 
+       rcu_read_lock();
        for_each_rmrr_units(rmrr) {
-               for (i = 0; i < rmrr->devices_cnt; i++) {
-                       /*
-                        * Return TRUE if this RMRR contains the device that
-                        * is passed in.
-                        */
-                       if (rmrr->devices[i] == dev)
+               /*
+                * Return TRUE if this RMRR contains the device that
+                * is passed in.
+                */
+               for_each_active_dev_scope(rmrr->devices,
+                                         rmrr->devices_cnt, i, tmp)
+                       if (tmp == dev) {
+                               rcu_read_unlock();
                                return true;
-               }
+                       }
        }
+       rcu_read_unlock();
        return false;
 }
 
-static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
+static int iommu_should_identity_map(struct device *dev, int startup)
 {
 
-       /*
-        * We want to prevent any device associated with an RMRR from
-        * getting placed into the SI Domain. This is done because
-        * problems exist when devices are moved in and out of domains
-        * and their respective RMRR info is lost. We exempt USB devices
-        * from this process due to their usage of RMRRs that are known
-        * to not be needed after BIOS hand-off to OS.
-        */
-       if (device_has_rmrr(pdev) &&
-           (pdev->class >> 8) != PCI_CLASS_SERIAL_USB)
-               return 0;
+       if (dev_is_pci(dev)) {
+               struct pci_dev *pdev = to_pci_dev(dev);
 
-       if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
-               return 1;
+               /*
+                * We want to prevent any device associated with an RMRR from
+                * getting placed into the SI Domain. This is done because
+                * problems exist when devices are moved in and out of domains
+                * and their respective RMRR info is lost. We exempt USB devices
+                * from this process due to their usage of RMRRs that are known
+                * to not be needed after BIOS hand-off to OS.
+                */
+               if (device_has_rmrr(dev) &&
+                   (pdev->class >> 8) != PCI_CLASS_SERIAL_USB)
+                       return 0;
 
-       if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
-               return 1;
+               if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
+                       return 1;
 
-       if (!(iommu_identity_mapping & IDENTMAP_ALL))
-               return 0;
+               if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
+                       return 1;
 
-       /*
-        * We want to start off with all devices in the 1:1 domain, and
-        * take them out later if we find they can't access all of memory.
-        *
-        * However, we can't do this for PCI devices behind bridges,
-        * because all PCI devices behind the same bridge will end up
-        * with the same source-id on their transactions.
-        *
-        * Practically speaking, we can't change things around for these
-        * devices at run-time, because we can't be sure there'll be no
-        * DMA transactions in flight for any of their siblings.
-        * 
-        * So PCI devices (unless they're on the root bus) as well as
-        * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
-        * the 1:1 domain, just in _case_ one of their siblings turns out
-        * not to be able to map all of memory.
-        */
-       if (!pci_is_pcie(pdev)) {
-               if (!pci_is_root_bus(pdev->bus))
+               if (!(iommu_identity_mapping & IDENTMAP_ALL))
                        return 0;
-               if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
+
+               /*
+                * We want to start off with all devices in the 1:1 domain, and
+                * take them out later if we find they can't access all of memory.
+                *
+                * However, we can't do this for PCI devices behind bridges,
+                * because all PCI devices behind the same bridge will end up
+                * with the same source-id on their transactions.
+                *
+                * Practically speaking, we can't change things around for these
+                * devices at run-time, because we can't be sure there'll be no
+                * DMA transactions in flight for any of their siblings.
+                *
+                * So PCI devices (unless they're on the root bus) as well as
+                * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
+                * the 1:1 domain, just in _case_ one of their siblings turns out
+                * not to be able to map all of memory.
+                */
+               if (!pci_is_pcie(pdev)) {
+                       if (!pci_is_root_bus(pdev->bus))
+                               return 0;
+                       if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
+                               return 0;
+               } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
                        return 0;
-       } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
-               return 0;
+       } else {
+               if (device_has_rmrr(dev))
+                       return 0;
+       }
 
-       /* 
+       /*
         * At boot time, we don't yet know if devices will be 64-bit capable.
-        * Assume that they will -- if they turn out not to be, then we can 
+        * Assume that they will â€” if they turn out not to be, then we can
         * take them out of the 1:1 domain later.
         */
        if (!startup) {
@@ -2381,42 +2584,77 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
                 * If the device's dma_mask is less than the system's memory
                 * size then this is not a candidate for identity mapping.
                 */
-               u64 dma_mask = pdev->dma_mask;
+               u64 dma_mask = *dev->dma_mask;
 
-               if (pdev->dev.coherent_dma_mask &&
-                   pdev->dev.coherent_dma_mask < dma_mask)
-                       dma_mask = pdev->dev.coherent_dma_mask;
+               if (dev->coherent_dma_mask &&
+                   dev->coherent_dma_mask < dma_mask)
+                       dma_mask = dev->coherent_dma_mask;
 
-               return dma_mask >= dma_get_required_mask(&pdev->dev);
+               return dma_mask >= dma_get_required_mask(dev);
        }
 
        return 1;
 }
 
+static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
+{
+       int ret;
+
+       if (!iommu_should_identity_map(dev, 1))
+               return 0;
+
+       ret = domain_add_dev_info(si_domain, dev,
+                                 hw ? CONTEXT_TT_PASS_THROUGH :
+                                      CONTEXT_TT_MULTI_LEVEL);
+       if (!ret)
+               pr_info("IOMMU: %s identity mapping for device %s\n",
+                       hw ? "hardware" : "software", dev_name(dev));
+       else if (ret == -ENODEV)
+               /* device not associated with an iommu */
+               ret = 0;
+
+       return ret;
+}
+
+
 static int __init iommu_prepare_static_identity_mapping(int hw)
 {
        struct pci_dev *pdev = NULL;
-       int ret;
+       struct dmar_drhd_unit *drhd;
+       struct intel_iommu *iommu;
+       struct device *dev;
+       int i;
+       int ret = 0;
 
        ret = si_domain_init(hw);
        if (ret)
                return -EFAULT;
 
        for_each_pci_dev(pdev) {
-               if (iommu_should_identity_map(pdev, 1)) {
-                       ret = domain_add_dev_info(si_domain, pdev,
-                                            hw ? CONTEXT_TT_PASS_THROUGH :
-                                                 CONTEXT_TT_MULTI_LEVEL);
-                       if (ret) {
-                               /* device not associated with an iommu */
-                               if (ret == -ENODEV)
-                                       continue;
-                               return ret;
+               ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
+               if (ret)
+                       return ret;
+       }
+
+       for_each_active_iommu(iommu, drhd)
+               for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
+                       struct acpi_device_physical_node *pn;
+                       struct acpi_device *adev;
+
+                       if (dev->bus != &acpi_bus_type)
+                               continue;
+                               
+                       adev= to_acpi_device(dev);
+                       mutex_lock(&adev->physical_node_lock);
+                       list_for_each_entry(pn, &adev->physical_node_list, node) {
+                               ret = dev_prepare_static_identity_mapping(pn->dev, hw);
+                               if (ret)
+                                       break;
                        }
-                       pr_info("IOMMU: %s identity mapping for device %s\n",
-                               hw ? "hardware" : "software", pci_name(pdev));
+                       mutex_unlock(&adev->physical_node_lock);
+                       if (ret)
+                               return ret;
                }
-       }
 
        return 0;
 }
@@ -2425,7 +2663,7 @@ static int __init init_dmars(void)
 {
        struct dmar_drhd_unit *drhd;
        struct dmar_rmrr_unit *rmrr;
-       struct pci_dev *pdev;
+       struct device *dev;
        struct intel_iommu *iommu;
        int i, ret;
 
@@ -2461,7 +2699,7 @@ static int __init init_dmars(void)
                sizeof(struct deferred_flush_tables), GFP_KERNEL);
        if (!deferred_flush) {
                ret = -ENOMEM;
-               goto error;
+               goto free_g_iommus;
        }
 
        for_each_active_iommu(iommu, drhd) {
@@ -2469,7 +2707,7 @@ static int __init init_dmars(void)
 
                ret = iommu_init_domains(iommu);
                if (ret)
-                       goto error;
+                       goto free_iommu;
 
                /*
                 * TBD:
@@ -2479,7 +2717,7 @@ static int __init init_dmars(void)
                ret = iommu_alloc_root_entry(iommu);
                if (ret) {
                        printk(KERN_ERR "IOMMU: allocate root entry failed\n");
-                       goto error;
+                       goto free_iommu;
                }
                if (!ecap_pass_through(iommu->ecap))
                        hw_pass_through = 0;
@@ -2548,7 +2786,7 @@ static int __init init_dmars(void)
                ret = iommu_prepare_static_identity_mapping(hw_pass_through);
                if (ret) {
                        printk(KERN_CRIT "Failed to setup IOMMU pass-through\n");
-                       goto error;
+                       goto free_iommu;
                }
        }
        /*
@@ -2567,15 +2805,10 @@ static int __init init_dmars(void)
         */
        printk(KERN_INFO "IOMMU: Setting RMRR:\n");
        for_each_rmrr_units(rmrr) {
-               for (i = 0; i < rmrr->devices_cnt; i++) {
-                       pdev = rmrr->devices[i];
-                       /*
-                        * some BIOS lists non-exist devices in DMAR
-                        * table.
-                        */
-                       if (!pdev)
-                               continue;
-                       ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+               /* some BIOS lists non-exist devices in DMAR table. */
+               for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
+                                         i, dev) {
+                       ret = iommu_prepare_rmrr_dev(rmrr, dev);
                        if (ret)
                                printk(KERN_ERR
                                       "IOMMU: mapping reserved region failed\n");
@@ -2606,7 +2839,7 @@ static int __init init_dmars(void)
 
                ret = dmar_set_interrupt(iommu);
                if (ret)
-                       goto error;
+                       goto free_iommu;
 
                iommu_set_root_entry(iommu);
 
@@ -2615,17 +2848,20 @@ static int __init init_dmars(void)
 
                ret = iommu_enable_translation(iommu);
                if (ret)
-                       goto error;
+                       goto free_iommu;
 
                iommu_disable_protect_mem_regions(iommu);
        }
 
        return 0;
-error:
+
+free_iommu:
        for_each_active_iommu(iommu, drhd)
                free_dmar_iommu(iommu);
        kfree(deferred_flush);
+free_g_iommus:
        kfree(g_iommus);
+error:
        return ret;
 }
 
@@ -2634,7 +2870,6 @@ static struct iova *intel_alloc_iova(struct device *dev,
                                     struct dmar_domain *domain,
                                     unsigned long nrpages, uint64_t dma_mask)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
        struct iova *iova = NULL;
 
        /* Restrict dma_mask to the width that the iommu can handle */
@@ -2654,34 +2889,31 @@ static struct iova *intel_alloc_iova(struct device *dev,
        iova = alloc_iova(&domain->iovad, nrpages, IOVA_PFN(dma_mask), 1);
        if (unlikely(!iova)) {
                printk(KERN_ERR "Allocating %ld-page iova for %s failed",
-                      nrpages, pci_name(pdev));
+                      nrpages, dev_name(dev));
                return NULL;
        }
 
        return iova;
 }
 
-static struct dmar_domain *__get_valid_domain_for_dev(struct pci_dev *pdev)
+static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev)
 {
        struct dmar_domain *domain;
        int ret;
 
-       domain = get_domain_for_dev(pdev,
-                       DEFAULT_DOMAIN_ADDRESS_WIDTH);
+       domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
        if (!domain) {
-               printk(KERN_ERR
-                       "Allocating domain for %s failed", pci_name(pdev));
+               printk(KERN_ERR "Allocating domain for %s failed",
+                      dev_name(dev));
                return NULL;
        }
 
        /* make sure context mapping is ok */
-       if (unlikely(!domain_context_mapped(pdev))) {
-               ret = domain_context_mapping(domain, pdev,
-                                            CONTEXT_TT_MULTI_LEVEL);
+       if (unlikely(!domain_context_mapped(dev))) {
+               ret = domain_context_mapping(domain, dev, CONTEXT_TT_MULTI_LEVEL);
                if (ret) {
-                       printk(KERN_ERR
-                               "Domain context map for %s failed",
-                               pci_name(pdev));
+                       printk(KERN_ERR "Domain context map for %s failed",
+                              dev_name(dev));
                        return NULL;
                }
        }
@@ -2689,51 +2921,46 @@ static struct dmar_domain *__get_valid_domain_for_dev(struct pci_dev *pdev)
        return domain;
 }
 
-static inline struct dmar_domain *get_valid_domain_for_dev(struct pci_dev *dev)
+static inline struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
 {
        struct device_domain_info *info;
 
        /* No lock here, assumes no domain exit in normal case */
-       info = dev->dev.archdata.iommu;
+       info = dev->archdata.iommu;
        if (likely(info))
                return info->domain;
 
        return __get_valid_domain_for_dev(dev);
 }
 
-static int iommu_dummy(struct pci_dev *pdev)
+static int iommu_dummy(struct device *dev)
 {
-       return pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
+       return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
 }
 
-/* Check if the pdev needs to go through non-identity map and unmap process.*/
+/* Check if the dev needs to go through non-identity map and unmap process.*/
 static int iommu_no_mapping(struct device *dev)
 {
-       struct pci_dev *pdev;
        int found;
 
-       if (unlikely(!dev_is_pci(dev)))
-               return 1;
-
-       pdev = to_pci_dev(dev);
-       if (iommu_dummy(pdev))
+       if (iommu_dummy(dev))
                return 1;
 
        if (!iommu_identity_mapping)
                return 0;
 
-       found = identity_mapping(pdev);
+       found = identity_mapping(dev);
        if (found) {
-               if (iommu_should_identity_map(pdev, 0))
+               if (iommu_should_identity_map(dev, 0))
                        return 1;
                else {
                        /*
                         * 32 bit DMA is removed from si_domain and fall back
                         * to non-identity mapping.
                         */
-                       domain_remove_one_dev_info(si_domain, pdev);
+                       domain_remove_one_dev_info(si_domain, dev);
                        printk(KERN_INFO "32bit %s uses non-identity mapping\n",
-                              pci_name(pdev));
+                              dev_name(dev));
                        return 0;
                }
        } else {
@@ -2741,15 +2968,15 @@ static int iommu_no_mapping(struct device *dev)
                 * In case of a detached 64 bit DMA device from vm, the device
                 * is put into si_domain for identity mapping.
                 */
-               if (iommu_should_identity_map(pdev, 0)) {
+               if (iommu_should_identity_map(dev, 0)) {
                        int ret;
-                       ret = domain_add_dev_info(si_domain, pdev,
+                       ret = domain_add_dev_info(si_domain, dev,
                                                  hw_pass_through ?
                                                  CONTEXT_TT_PASS_THROUGH :
                                                  CONTEXT_TT_MULTI_LEVEL);
                        if (!ret) {
                                printk(KERN_INFO "64bit %s uses identity mapping\n",
-                                      pci_name(pdev));
+                                      dev_name(dev));
                                return 1;
                        }
                }
@@ -2758,10 +2985,9 @@ static int iommu_no_mapping(struct device *dev)
        return 0;
 }
 
-static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
+static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
                                     size_t size, int dir, u64 dma_mask)
 {
-       struct pci_dev *pdev = to_pci_dev(hwdev);
        struct dmar_domain *domain;
        phys_addr_t start_paddr;
        struct iova *iova;
@@ -2772,17 +2998,17 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
 
        BUG_ON(dir == DMA_NONE);
 
-       if (iommu_no_mapping(hwdev))
+       if (iommu_no_mapping(dev))
                return paddr;
 
-       domain = get_valid_domain_for_dev(pdev);
+       domain = get_valid_domain_for_dev(dev);
        if (!domain)
                return 0;
 
        iommu = domain_get_iommu(domain);
        size = aligned_nrpages(paddr, size);
 
-       iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask);
+       iova = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
        if (!iova)
                goto error;
 
@@ -2808,7 +3034,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
 
        /* it's a non-present to present mapping. Only flush if caching mode */
        if (cap_caching_mode(iommu->cap))
-               iommu_flush_iotlb_psi(iommu, domain->id, mm_to_dma_pfn(iova->pfn_lo), size, 1);
+               iommu_flush_iotlb_psi(iommu, domain->id, mm_to_dma_pfn(iova->pfn_lo), size, 0, 1);
        else
                iommu_flush_write_buffer(iommu);
 
@@ -2820,7 +3046,7 @@ error:
        if (iova)
                __free_iova(&domain->iovad, iova);
        printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
-               pci_name(pdev), size, (unsigned long long)paddr, dir);
+               dev_name(dev), size, (unsigned long long)paddr, dir);
        return 0;
 }
 
@@ -2830,7 +3056,7 @@ static dma_addr_t intel_map_page(struct device *dev, struct page *page,
                                 struct dma_attrs *attrs)
 {
        return __intel_map_single(dev, page_to_phys(page) + offset, size,
-                                 dir, to_pci_dev(dev)->dma_mask);
+                                 dir, *dev->dma_mask);
 }
 
 static void flush_unmaps(void)
@@ -2860,13 +3086,16 @@ static void flush_unmaps(void)
                        /* On real hardware multiple invalidations are expensive */
                        if (cap_caching_mode(iommu->cap))
                                iommu_flush_iotlb_psi(iommu, domain->id,
-                               iova->pfn_lo, iova->pfn_hi - iova->pfn_lo + 1, 0);
+                                       iova->pfn_lo, iova->pfn_hi - iova->pfn_lo + 1,
+                                       !deferred_flush[i].freelist[j], 0);
                        else {
                                mask = ilog2(mm_to_dma_pfn(iova->pfn_hi - iova->pfn_lo + 1));
                                iommu_flush_dev_iotlb(deferred_flush[i].domain[j],
                                                (uint64_t)iova->pfn_lo << PAGE_SHIFT, mask);
                        }
                        __free_iova(&deferred_flush[i].domain[j]->iovad, iova);
+                       if (deferred_flush[i].freelist[j])
+                               dma_free_pagelist(deferred_flush[i].freelist[j]);
                }
                deferred_flush[i].next = 0;
        }
@@ -2883,7 +3112,7 @@ static void flush_unmaps_timeout(unsigned long data)
        spin_unlock_irqrestore(&async_umap_flush_lock, flags);
 }
 
-static void add_unmap(struct dmar_domain *dom, struct iova *iova)
+static void add_unmap(struct dmar_domain *dom, struct iova *iova, struct page *freelist)
 {
        unsigned long flags;
        int next, iommu_id;
@@ -2899,6 +3128,7 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
        next = deferred_flush[iommu_id].next;
        deferred_flush[iommu_id].domain[next] = dom;
        deferred_flush[iommu_id].iova[next] = iova;
+       deferred_flush[iommu_id].freelist[next] = freelist;
        deferred_flush[iommu_id].next++;
 
        if (!timer_on) {
@@ -2913,16 +3143,16 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
                             size_t size, enum dma_data_direction dir,
                             struct dma_attrs *attrs)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
        struct dmar_domain *domain;
        unsigned long start_pfn, last_pfn;
        struct iova *iova;
        struct intel_iommu *iommu;
+       struct page *freelist;
 
        if (iommu_no_mapping(dev))
                return;
 
-       domain = find_domain(pdev);
+       domain = find_domain(dev);
        BUG_ON(!domain);
 
        iommu = domain_get_iommu(domain);
@@ -2936,21 +3166,18 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
        last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1;
 
        pr_debug("Device %s unmapping: pfn %lx-%lx\n",
-                pci_name(pdev), start_pfn, last_pfn);
-
-       /*  clear the whole page */
-       dma_pte_clear_range(domain, start_pfn, last_pfn);
+                dev_name(dev), start_pfn, last_pfn);
 
-       /* free page tables */
-       dma_pte_free_pagetable(domain, start_pfn, last_pfn);
+       freelist = domain_unmap(domain, start_pfn, last_pfn);
 
        if (intel_iommu_strict) {
                iommu_flush_iotlb_psi(iommu, domain->id, start_pfn,
-                                     last_pfn - start_pfn + 1, 0);
+                                     last_pfn - start_pfn + 1, !freelist, 0);
                /* free iova */
                __free_iova(&domain->iovad, iova);
+               dma_free_pagelist(freelist);
        } else {
-               add_unmap(domain, iova);
+               add_unmap(domain, iova, freelist);
                /*
                 * queue up the release of the unmap to save the 1/6th of the
                 * cpu used up by the iotlb flush operation...
@@ -2958,7 +3185,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
        }
 }
 
-static void *intel_alloc_coherent(struct device *hwdev, size_t size,
+static void *intel_alloc_coherent(struct device *dev, size_t size,
                                  dma_addr_t *dma_handle, gfp_t flags,
                                  struct dma_attrs *attrs)
 {
@@ -2968,10 +3195,10 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
        size = PAGE_ALIGN(size);
        order = get_order(size);
 
-       if (!iommu_no_mapping(hwdev))
+       if (!iommu_no_mapping(dev))
                flags &= ~(GFP_DMA | GFP_DMA32);
-       else if (hwdev->coherent_dma_mask < dma_get_required_mask(hwdev)) {
-               if (hwdev->coherent_dma_mask < DMA_BIT_MASK(32))
+       else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
+               if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
                        flags |= GFP_DMA;
                else
                        flags |= GFP_DMA32;
@@ -2982,16 +3209,16 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
                return NULL;
        memset(vaddr, 0, size);
 
-       *dma_handle = __intel_map_single(hwdev, virt_to_bus(vaddr), size,
+       *dma_handle = __intel_map_single(dev, virt_to_bus(vaddr), size,
                                         DMA_BIDIRECTIONAL,
-                                        hwdev->coherent_dma_mask);
+                                        dev->coherent_dma_mask);
        if (*dma_handle)
                return vaddr;
        free_pages((unsigned long)vaddr, order);
        return NULL;
 }
 
-static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
                                dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
        int order;
@@ -2999,24 +3226,24 @@ static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
        size = PAGE_ALIGN(size);
        order = get_order(size);
 
-       intel_unmap_page(hwdev, dma_handle, size, DMA_BIDIRECTIONAL, NULL);
+       intel_unmap_page(dev, dma_handle, size, DMA_BIDIRECTIONAL, NULL);
        free_pages((unsigned long)vaddr, order);
 }
 
-static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
                           int nelems, enum dma_data_direction dir,
                           struct dma_attrs *attrs)
 {
-       struct pci_dev *pdev = to_pci_dev(hwdev);
        struct dmar_domain *domain;
        unsigned long start_pfn, last_pfn;
        struct iova *iova;
        struct intel_iommu *iommu;
+       struct page *freelist;
 
-       if (iommu_no_mapping(hwdev))
+       if (iommu_no_mapping(dev))
                return;
 
-       domain = find_domain(pdev);
+       domain = find_domain(dev);
        BUG_ON(!domain);
 
        iommu = domain_get_iommu(domain);
@@ -3029,19 +3256,16 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
        start_pfn = mm_to_dma_pfn(iova->pfn_lo);
        last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1;
 
-       /*  clear the whole page */
-       dma_pte_clear_range(domain, start_pfn, last_pfn);
-
-       /* free page tables */
-       dma_pte_free_pagetable(domain, start_pfn, last_pfn);
+       freelist = domain_unmap(domain, start_pfn, last_pfn);
 
        if (intel_iommu_strict) {
                iommu_flush_iotlb_psi(iommu, domain->id, start_pfn,
-                                     last_pfn - start_pfn + 1, 0);
+                                     last_pfn - start_pfn + 1, !freelist, 0);
                /* free iova */
                __free_iova(&domain->iovad, iova);
+               dma_free_pagelist(freelist);
        } else {
-               add_unmap(domain, iova);
+               add_unmap(domain, iova, freelist);
                /*
                 * queue up the release of the unmap to save the 1/6th of the
                 * cpu used up by the iotlb flush operation...
@@ -3063,11 +3287,10 @@ static int intel_nontranslate_map_sg(struct device *hddev,
        return nelems;
 }
 
-static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
+static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
                        enum dma_data_direction dir, struct dma_attrs *attrs)
 {
        int i;
-       struct pci_dev *pdev = to_pci_dev(hwdev);
        struct dmar_domain *domain;
        size_t size = 0;
        int prot = 0;
@@ -3078,10 +3301,10 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
        struct intel_iommu *iommu;
 
        BUG_ON(dir == DMA_NONE);
-       if (iommu_no_mapping(hwdev))
-               return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir);
+       if (iommu_no_mapping(dev))
+               return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
 
-       domain = get_valid_domain_for_dev(pdev);
+       domain = get_valid_domain_for_dev(dev);
        if (!domain)
                return 0;
 
@@ -3090,8 +3313,8 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
        for_each_sg(sglist, sg, nelems, i)
                size += aligned_nrpages(sg->offset, sg->length);
 
-       iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size),
-                               pdev->dma_mask);
+       iova = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
+                               *dev->dma_mask);
        if (!iova) {
                sglist->dma_length = 0;
                return 0;
@@ -3124,7 +3347,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
 
        /* it's a non-present to present mapping. Only flush if caching mode */
        if (cap_caching_mode(iommu->cap))
-               iommu_flush_iotlb_psi(iommu, domain->id, start_vpfn, size, 1);
+               iommu_flush_iotlb_psi(iommu, domain->id, start_vpfn, size, 0, 1);
        else
                iommu_flush_write_buffer(iommu);
 
@@ -3259,29 +3482,28 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quir
 static void __init init_no_remapping_devices(void)
 {
        struct dmar_drhd_unit *drhd;
+       struct device *dev;
+       int i;
 
        for_each_drhd_unit(drhd) {
                if (!drhd->include_all) {
-                       int i;
-                       for (i = 0; i < drhd->devices_cnt; i++)
-                               if (drhd->devices[i] != NULL)
-                                       break;
-                       /* ignore DMAR unit if no pci devices exist */
+                       for_each_active_dev_scope(drhd->devices,
+                                                 drhd->devices_cnt, i, dev)
+                               break;
+                       /* ignore DMAR unit if no devices exist */
                        if (i == drhd->devices_cnt)
                                drhd->ignored = 1;
                }
        }
 
        for_each_active_drhd_unit(drhd) {
-               int i;
                if (drhd->include_all)
                        continue;
 
-               for (i = 0; i < drhd->devices_cnt; i++)
-                       if (drhd->devices[i] &&
-                           !IS_GFX_DEVICE(drhd->devices[i]))
+               for_each_active_dev_scope(drhd->devices,
+                                         drhd->devices_cnt, i, dev)
+                       if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
                                break;
-
                if (i < drhd->devices_cnt)
                        continue;
 
@@ -3291,11 +3513,9 @@ static void __init init_no_remapping_devices(void)
                        intel_iommu_gfx_mapped = 1;
                } else {
                        drhd->ignored = 1;
-                       for (i = 0; i < drhd->devices_cnt; i++) {
-                               if (!drhd->devices[i])
-                                       continue;
-                               drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
-                       }
+                       for_each_active_dev_scope(drhd->devices,
+                                                 drhd->devices_cnt, i, dev)
+                               dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
                }
        }
 }
@@ -3438,13 +3658,6 @@ static void __init init_iommu_pm_ops(void)
 static inline void init_iommu_pm_ops(void) {}
 #endif /* CONFIG_PM */
 
-LIST_HEAD(dmar_rmrr_units);
-
-static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
-{
-       list_add(&rmrr->list, &dmar_rmrr_units);
-}
-
 
 int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header)
 {
@@ -3459,25 +3672,19 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header)
        rmrr = (struct acpi_dmar_reserved_memory *)header;
        rmrru->base_address = rmrr->base_address;
        rmrru->end_address = rmrr->end_address;
+       rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
+                               ((void *)rmrr) + rmrr->header.length,
+                               &rmrru->devices_cnt);
+       if (rmrru->devices_cnt && rmrru->devices == NULL) {
+               kfree(rmrru);
+               return -ENOMEM;
+       }
 
-       dmar_register_rmrr_unit(rmrru);
-       return 0;
-}
-
-static int __init
-rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
-{
-       struct acpi_dmar_reserved_memory *rmrr;
+       list_add(&rmrru->list, &dmar_rmrr_units);
 
-       rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
-       return dmar_parse_dev_scope((void *)(rmrr + 1),
-                                   ((void *)rmrr) + rmrr->header.length,
-                                   &rmrru->devices_cnt, &rmrru->devices,
-                                   rmrr->segment);
+       return 0;
 }
 
-static LIST_HEAD(dmar_atsr_units);
-
 int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
 {
        struct acpi_dmar_atsr *atsr;
@@ -3490,26 +3697,21 @@ int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr)
 
        atsru->hdr = hdr;
        atsru->include_all = atsr->flags & 0x1;
+       if (!atsru->include_all) {
+               atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
+                               (void *)atsr + atsr->header.length,
+                               &atsru->devices_cnt);
+               if (atsru->devices_cnt && atsru->devices == NULL) {
+                       kfree(atsru);
+                       return -ENOMEM;
+               }
+       }
 
-       list_add(&atsru->list, &dmar_atsr_units);
+       list_add_rcu(&atsru->list, &dmar_atsr_units);
 
        return 0;
 }
 
-static int __init atsr_parse_dev(struct dmar_atsr_unit *atsru)
-{
-       struct acpi_dmar_atsr *atsr;
-
-       if (atsru->include_all)
-               return 0;
-
-       atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
-       return dmar_parse_dev_scope((void *)(atsr + 1),
-                                   (void *)atsr + atsr->header.length,
-                                   &atsru->devices_cnt, &atsru->devices,
-                                   atsr->segment);
-}
-
 static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
 {
        dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
@@ -3535,62 +3737,97 @@ static void intel_iommu_free_dmars(void)
 
 int dmar_find_matched_atsr_unit(struct pci_dev *dev)
 {
-       int i;
+       int i, ret = 1;
        struct pci_bus *bus;
+       struct pci_dev *bridge = NULL;
+       struct device *tmp;
        struct acpi_dmar_atsr *atsr;
        struct dmar_atsr_unit *atsru;
 
        dev = pci_physfn(dev);
-
-       list_for_each_entry(atsru, &dmar_atsr_units, list) {
-               atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
-               if (atsr->segment == pci_domain_nr(dev->bus))
-                       goto found;
-       }
-
-       return 0;
-
-found:
        for (bus = dev->bus; bus; bus = bus->parent) {
-               struct pci_dev *bridge = bus->self;
-
+               bridge = bus->self;
                if (!bridge || !pci_is_pcie(bridge) ||
                    pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
                        return 0;
-
-               if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) {
-                       for (i = 0; i < atsru->devices_cnt; i++)
-                               if (atsru->devices[i] == bridge)
-                                       return 1;
+               if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
                        break;
-               }
        }
+       if (!bridge)
+               return 0;
 
-       if (atsru->include_all)
-               return 1;
+       rcu_read_lock();
+       list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
+               atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
+               if (atsr->segment != pci_domain_nr(dev->bus))
+                       continue;
 
-       return 0;
+               for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
+                       if (tmp == &bridge->dev)
+                               goto out;
+
+               if (atsru->include_all)
+                       goto out;
+       }
+       ret = 0;
+out:
+       rcu_read_unlock();
+
+       return ret;
 }
 
-int __init dmar_parse_rmrr_atsr_dev(void)
+int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
 {
-       struct dmar_rmrr_unit *rmrr;
-       struct dmar_atsr_unit *atsr;
        int ret = 0;
+       struct dmar_rmrr_unit *rmrru;
+       struct dmar_atsr_unit *atsru;
+       struct acpi_dmar_atsr *atsr;
+       struct acpi_dmar_reserved_memory *rmrr;
 
-       list_for_each_entry(rmrr, &dmar_rmrr_units, list) {
-               ret = rmrr_parse_dev(rmrr);
-               if (ret)
-                       return ret;
+       if (!intel_iommu_enabled && system_state != SYSTEM_BOOTING)
+               return 0;
+
+       list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
+               rmrr = container_of(rmrru->hdr,
+                                   struct acpi_dmar_reserved_memory, header);
+               if (info->event == BUS_NOTIFY_ADD_DEVICE) {
+                       ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
+                               ((void *)rmrr) + rmrr->header.length,
+                               rmrr->segment, rmrru->devices,
+                               rmrru->devices_cnt);
+                       if (ret > 0)
+                               break;
+                       else if(ret < 0)
+                               return ret;
+               } else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
+                       if (dmar_remove_dev_scope(info, rmrr->segment,
+                               rmrru->devices, rmrru->devices_cnt))
+                               break;
+               }
        }
 
-       list_for_each_entry(atsr, &dmar_atsr_units, list) {
-               ret = atsr_parse_dev(atsr);
-               if (ret)
-                       return ret;
+       list_for_each_entry(atsru, &dmar_atsr_units, list) {
+               if (atsru->include_all)
+                       continue;
+
+               atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
+               if (info->event == BUS_NOTIFY_ADD_DEVICE) {
+                       ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
+                                       (void *)atsr + atsr->header.length,
+                                       atsr->segment, atsru->devices,
+                                       atsru->devices_cnt);
+                       if (ret > 0)
+                               break;
+                       else if(ret < 0)
+                               return ret;
+               } else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
+                       if (dmar_remove_dev_scope(info, atsr->segment,
+                                       atsru->devices, atsru->devices_cnt))
+                               break;
+               }
        }
 
-       return ret;
+       return 0;
 }
 
 /*
@@ -3603,24 +3840,26 @@ static int device_notifier(struct notifier_block *nb,
                                  unsigned long action, void *data)
 {
        struct device *dev = data;
-       struct pci_dev *pdev = to_pci_dev(dev);
        struct dmar_domain *domain;
 
-       if (iommu_no_mapping(dev))
+       if (iommu_dummy(dev))
                return 0;
 
-       domain = find_domain(pdev);
-       if (!domain)
+       if (action != BUS_NOTIFY_UNBOUND_DRIVER &&
+           action != BUS_NOTIFY_DEL_DEVICE)
                return 0;
 
-       if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) {
-               domain_remove_one_dev_info(domain, pdev);
+       domain = find_domain(dev);
+       if (!domain)
+               return 0;
 
-               if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
-                   !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
-                   list_empty(&domain->devices))
-                       domain_exit(domain);
-       }
+       down_read(&dmar_global_lock);
+       domain_remove_one_dev_info(domain, dev);
+       if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
+           !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
+           list_empty(&domain->devices))
+               domain_exit(domain);
+       up_read(&dmar_global_lock);
 
        return 0;
 }
@@ -3629,6 +3868,75 @@ static struct notifier_block device_nb = {
        .notifier_call = device_notifier,
 };
 
+static int intel_iommu_memory_notifier(struct notifier_block *nb,
+                                      unsigned long val, void *v)
+{
+       struct memory_notify *mhp = v;
+       unsigned long long start, end;
+       unsigned long start_vpfn, last_vpfn;
+
+       switch (val) {
+       case MEM_GOING_ONLINE:
+               start = mhp->start_pfn << PAGE_SHIFT;
+               end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
+               if (iommu_domain_identity_map(si_domain, start, end)) {
+                       pr_warn("dmar: failed to build identity map for [%llx-%llx]\n",
+                               start, end);
+                       return NOTIFY_BAD;
+               }
+               break;
+
+       case MEM_OFFLINE:
+       case MEM_CANCEL_ONLINE:
+               start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
+               last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
+               while (start_vpfn <= last_vpfn) {
+                       struct iova *iova;
+                       struct dmar_drhd_unit *drhd;
+                       struct intel_iommu *iommu;
+                       struct page *freelist;
+
+                       iova = find_iova(&si_domain->iovad, start_vpfn);
+                       if (iova == NULL) {
+                               pr_debug("dmar: failed get IOVA for PFN %lx\n",
+                                        start_vpfn);
+                               break;
+                       }
+
+                       iova = split_and_remove_iova(&si_domain->iovad, iova,
+                                                    start_vpfn, last_vpfn);
+                       if (iova == NULL) {
+                               pr_warn("dmar: failed to split IOVA PFN [%lx-%lx]\n",
+                                       start_vpfn, last_vpfn);
+                               return NOTIFY_BAD;
+                       }
+
+                       freelist = domain_unmap(si_domain, iova->pfn_lo,
+                                              iova->pfn_hi);
+
+                       rcu_read_lock();
+                       for_each_active_iommu(iommu, drhd)
+                               iommu_flush_iotlb_psi(iommu, si_domain->id,
+                                       iova->pfn_lo,
+                                       iova->pfn_hi - iova->pfn_lo + 1,
+                                       !freelist, 0);
+                       rcu_read_unlock();
+                       dma_free_pagelist(freelist);
+
+                       start_vpfn = iova->pfn_hi + 1;
+                       free_iova_mem(iova);
+               }
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block intel_iommu_memory_nb = {
+       .notifier_call = intel_iommu_memory_notifier,
+       .priority = 0
+};
+
 int __init intel_iommu_init(void)
 {
        int ret = -ENODEV;
@@ -3638,6 +3946,13 @@ int __init intel_iommu_init(void)
        /* VT-d is required for a TXT/tboot launch, so enforce that */
        force_on = tboot_force_iommu();
 
+       if (iommu_init_mempool()) {
+               if (force_on)
+                       panic("tboot: Failed to initialize iommu memory\n");
+               return -ENOMEM;
+       }
+
+       down_write(&dmar_global_lock);
        if (dmar_table_init()) {
                if (force_on)
                        panic("tboot: Failed to initialize DMAR table\n");
@@ -3660,12 +3975,6 @@ int __init intel_iommu_init(void)
        if (no_iommu || dmar_disabled)
                goto out_free_dmar;
 
-       if (iommu_init_mempool()) {
-               if (force_on)
-                       panic("tboot: Failed to initialize iommu memory\n");
-               goto out_free_dmar;
-       }
-
        if (list_empty(&dmar_rmrr_units))
                printk(KERN_INFO "DMAR: No RMRR found\n");
 
@@ -3675,7 +3984,7 @@ int __init intel_iommu_init(void)
        if (dmar_init_reserved_ranges()) {
                if (force_on)
                        panic("tboot: Failed to reserve iommu ranges\n");
-               goto out_free_mempool;
+               goto out_free_reserved_range;
        }
 
        init_no_remapping_devices();
@@ -3687,6 +3996,7 @@ int __init intel_iommu_init(void)
                printk(KERN_ERR "IOMMU: dmar init failed\n");
                goto out_free_reserved_range;
        }
+       up_write(&dmar_global_lock);
        printk(KERN_INFO
        "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
 
@@ -3699,8 +4009,9 @@ int __init intel_iommu_init(void)
        init_iommu_pm_ops();
 
        bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
-
        bus_register_notifier(&pci_bus_type, &device_nb);
+       if (si_domain && !hw_pass_through)
+               register_memory_notifier(&intel_iommu_memory_nb);
 
        intel_iommu_enabled = 1;
 
@@ -3708,21 +4019,23 @@ int __init intel_iommu_init(void)
 
 out_free_reserved_range:
        put_iova_domain(&reserved_iova_list);
-out_free_mempool:
-       iommu_exit_mempool();
 out_free_dmar:
        intel_iommu_free_dmars();
+       up_write(&dmar_global_lock);
+       iommu_exit_mempool();
        return ret;
 }
 
 static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
-                                          struct pci_dev *pdev)
+                                          struct device *dev)
 {
-       struct pci_dev *tmp, *parent;
+       struct pci_dev *tmp, *parent, *pdev;
 
-       if (!iommu || !pdev)
+       if (!iommu || !dev || !dev_is_pci(dev))
                return;
 
+       pdev = to_pci_dev(dev);
+
        /* dependent device detach */
        tmp = pci_find_upstream_pcie_bridge(pdev);
        /* Secondary interface's bus number and devfn 0 */
@@ -3743,29 +4056,28 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
 }
 
 static void domain_remove_one_dev_info(struct dmar_domain *domain,
-                                         struct pci_dev *pdev)
+                                      struct device *dev)
 {
        struct device_domain_info *info, *tmp;
        struct intel_iommu *iommu;
        unsigned long flags;
        int found = 0;
+       u8 bus, devfn;
 
-       iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
-                               pdev->devfn);
+       iommu = device_to_iommu(dev, &bus, &devfn);
        if (!iommu)
                return;
 
        spin_lock_irqsave(&device_domain_lock, flags);
        list_for_each_entry_safe(info, tmp, &domain->devices, link) {
-               if (info->segment == pci_domain_nr(pdev->bus) &&
-                   info->bus == pdev->bus->number &&
-                   info->devfn == pdev->devfn) {
+               if (info->iommu == iommu && info->bus == bus &&
+                   info->devfn == devfn) {
                        unlink_domain_info(info);
                        spin_unlock_irqrestore(&device_domain_lock, flags);
 
                        iommu_disable_dev_iotlb(info);
                        iommu_detach_dev(iommu, info->bus, info->devfn);
-                       iommu_detach_dependent_devices(iommu, pdev);
+                       iommu_detach_dependent_devices(iommu, dev);
                        free_devinfo_mem(info);
 
                        spin_lock_irqsave(&device_domain_lock, flags);
@@ -3780,8 +4092,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
                 * owned by this domain, clear this iommu in iommu_bmp
                 * update iommu count and coherency
                 */
-               if (iommu == device_to_iommu(info->segment, info->bus,
-                                           info->devfn))
+               if (info->iommu == iommu)
                        found = 1;
        }
 
@@ -3805,67 +4116,11 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
        }
 }
 
-static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
-{
-       struct device_domain_info *info;
-       struct intel_iommu *iommu;
-       unsigned long flags1, flags2;
-
-       spin_lock_irqsave(&device_domain_lock, flags1);
-       while (!list_empty(&domain->devices)) {
-               info = list_entry(domain->devices.next,
-                       struct device_domain_info, link);
-               unlink_domain_info(info);
-               spin_unlock_irqrestore(&device_domain_lock, flags1);
-
-               iommu_disable_dev_iotlb(info);
-               iommu = device_to_iommu(info->segment, info->bus, info->devfn);
-               iommu_detach_dev(iommu, info->bus, info->devfn);
-               iommu_detach_dependent_devices(iommu, info->dev);
-
-               /* clear this iommu in iommu_bmp, update iommu count
-                * and capabilities
-                */
-               spin_lock_irqsave(&domain->iommu_lock, flags2);
-               if (test_and_clear_bit(iommu->seq_id,
-                                      domain->iommu_bmp)) {
-                       domain->iommu_count--;
-                       domain_update_iommu_cap(domain);
-               }
-               spin_unlock_irqrestore(&domain->iommu_lock, flags2);
-
-               free_devinfo_mem(info);
-               spin_lock_irqsave(&device_domain_lock, flags1);
-       }
-       spin_unlock_irqrestore(&device_domain_lock, flags1);
-}
-
-/* domain id for virtual machine, it won't be set in context */
-static atomic_t vm_domid = ATOMIC_INIT(0);
-
-static struct dmar_domain *iommu_alloc_vm_domain(void)
-{
-       struct dmar_domain *domain;
-
-       domain = alloc_domain_mem();
-       if (!domain)
-               return NULL;
-
-       domain->id = atomic_inc_return(&vm_domid);
-       domain->nid = -1;
-       memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
-       domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
-
-       return domain;
-}
-
 static int md_domain_init(struct dmar_domain *domain, int guest_width)
 {
        int adjust_width;
 
        init_iova_domain(&domain->iovad, DMA_32BIT_PFN);
-       spin_lock_init(&domain->iommu_lock);
-
        domain_reserve_special_ranges(domain);
 
        /* calculate AGAW */
@@ -3873,9 +4128,6 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
        adjust_width = guestwidth_to_adjustwidth(guest_width);
        domain->agaw = width_to_agaw(adjust_width);
 
-       INIT_LIST_HEAD(&domain->devices);
-
-       domain->iommu_count = 0;
        domain->iommu_coherency = 0;
        domain->iommu_snooping = 0;
        domain->iommu_superpage = 0;
@@ -3890,53 +4142,11 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
        return 0;
 }
 
-static void iommu_free_vm_domain(struct dmar_domain *domain)
-{
-       unsigned long flags;
-       struct dmar_drhd_unit *drhd;
-       struct intel_iommu *iommu;
-       unsigned long i;
-       unsigned long ndomains;
-
-       for_each_active_iommu(iommu, drhd) {
-               ndomains = cap_ndoms(iommu->cap);
-               for_each_set_bit(i, iommu->domain_ids, ndomains) {
-                       if (iommu->domains[i] == domain) {
-                               spin_lock_irqsave(&iommu->lock, flags);
-                               clear_bit(i, iommu->domain_ids);
-                               iommu->domains[i] = NULL;
-                               spin_unlock_irqrestore(&iommu->lock, flags);
-                               break;
-                       }
-               }
-       }
-}
-
-static void vm_domain_exit(struct dmar_domain *domain)
-{
-       /* Domain 0 is reserved, so dont process it */
-       if (!domain)
-               return;
-
-       vm_domain_remove_all_dev_info(domain);
-       /* destroy iovas */
-       put_iova_domain(&domain->iovad);
-
-       /* clear ptes */
-       dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
-
-       /* free page tables */
-       dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
-
-       iommu_free_vm_domain(domain);
-       free_domain_mem(domain);
-}
-
 static int intel_iommu_domain_init(struct iommu_domain *domain)
 {
        struct dmar_domain *dmar_domain;
 
-       dmar_domain = iommu_alloc_vm_domain();
+       dmar_domain = alloc_domain(true);
        if (!dmar_domain) {
                printk(KERN_ERR
                        "intel_iommu_domain_init: dmar_domain == NULL\n");
@@ -3945,7 +4155,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain)
        if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
                printk(KERN_ERR
                        "intel_iommu_domain_init() failed\n");
-               vm_domain_exit(dmar_domain);
+               domain_exit(dmar_domain);
                return -ENOMEM;
        }
        domain_update_iommu_cap(dmar_domain);
@@ -3963,33 +4173,32 @@ static void intel_iommu_domain_destroy(struct iommu_domain *domain)
        struct dmar_domain *dmar_domain = domain->priv;
 
        domain->priv = NULL;
-       vm_domain_exit(dmar_domain);
+       domain_exit(dmar_domain);
 }
 
 static int intel_iommu_attach_device(struct iommu_domain *domain,
                                     struct device *dev)
 {
        struct dmar_domain *dmar_domain = domain->priv;
-       struct pci_dev *pdev = to_pci_dev(dev);
        struct intel_iommu *iommu;
        int addr_width;
+       u8 bus, devfn;
 
-       /* normally pdev is not mapped */
-       if (unlikely(domain_context_mapped(pdev))) {
+       /* normally dev is not mapped */
+       if (unlikely(domain_context_mapped(dev))) {
                struct dmar_domain *old_domain;
 
-               old_domain = find_domain(pdev);
+               old_domain = find_domain(dev);
                if (old_domain) {
                        if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE ||
                            dmar_domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)
-                               domain_remove_one_dev_info(old_domain, pdev);
+                               domain_remove_one_dev_info(old_domain, dev);
                        else
                                domain_remove_dev_info(old_domain);
                }
        }
 
-       iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
-                               pdev->devfn);
+       iommu = device_to_iommu(dev, &bus, &devfn);
        if (!iommu)
                return -ENODEV;
 
@@ -4021,16 +4230,15 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
                dmar_domain->agaw--;
        }
 
-       return domain_add_dev_info(dmar_domain, pdev, CONTEXT_TT_MULTI_LEVEL);
+       return domain_add_dev_info(dmar_domain, dev, CONTEXT_TT_MULTI_LEVEL);
 }
 
 static void intel_iommu_detach_device(struct iommu_domain *domain,
                                      struct device *dev)
 {
        struct dmar_domain *dmar_domain = domain->priv;
-       struct pci_dev *pdev = to_pci_dev(dev);
 
-       domain_remove_one_dev_info(dmar_domain, pdev);
+       domain_remove_one_dev_info(dmar_domain, dev);
 }
 
 static int intel_iommu_map(struct iommu_domain *domain,
@@ -4072,18 +4280,51 @@ static int intel_iommu_map(struct iommu_domain *domain,
 }
 
 static size_t intel_iommu_unmap(struct iommu_domain *domain,
-                            unsigned long iova, size_t size)
+                               unsigned long iova, size_t size)
 {
        struct dmar_domain *dmar_domain = domain->priv;
-       int order;
+       struct page *freelist = NULL;
+       struct intel_iommu *iommu;
+       unsigned long start_pfn, last_pfn;
+       unsigned int npages;
+       int iommu_id, num, ndomains, level = 0;
+
+       /* Cope with horrid API which requires us to unmap more than the
+          size argument if it happens to be a large-page mapping. */
+       if (!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level))
+               BUG();
+
+       if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
+               size = VTD_PAGE_SIZE << level_to_offset_bits(level);
+
+       start_pfn = iova >> VTD_PAGE_SHIFT;
+       last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
+
+       freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
+
+       npages = last_pfn - start_pfn + 1;
+
+       for_each_set_bit(iommu_id, dmar_domain->iommu_bmp, g_num_of_iommus) {
+               iommu = g_iommus[iommu_id];
+
+               /*
+                * find bit position of dmar_domain
+                */
+               ndomains = cap_ndoms(iommu->cap);
+               for_each_set_bit(num, iommu->domain_ids, ndomains) {
+                       if (iommu->domains[num] == dmar_domain)
+                               iommu_flush_iotlb_psi(iommu, num, start_pfn,
+                                                    npages, !freelist, 0);
+              }
+
+       }
 
-       order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
-                           (iova + size - 1) >> VTD_PAGE_SHIFT);
+       dma_free_pagelist(freelist);
 
        if (dmar_domain->max_addr == iova + size)
                dmar_domain->max_addr = iova;
 
-       return PAGE_SIZE << order;
+       return size;
 }
 
 static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -4091,9 +4332,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
 {
        struct dmar_domain *dmar_domain = domain->priv;
        struct dma_pte *pte;
+       int level = 0;
        u64 phys = 0;
 
-       pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, 0);
+       pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
        if (pte)
                phys = dma_pte_addr(pte);
 
@@ -4121,9 +4363,9 @@ static int intel_iommu_add_device(struct device *dev)
        struct pci_dev *bridge, *dma_pdev = NULL;
        struct iommu_group *group;
        int ret;
+       u8 bus, devfn;
 
-       if (!device_to_iommu(pci_domain_nr(pdev->bus),
-                            pdev->bus->number, pdev->devfn))
+       if (!device_to_iommu(dev, &bus, &devfn))
                return -ENODEV;
 
        bridge = pci_find_upstream_pcie_bridge(pdev);
index ef5f65dbafe92d81c9d6fefa9990b76662347c50..9b174893f0f5bd7c19810dc2840b3fef2728e9ad 100644 (file)
@@ -38,6 +38,17 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static struct hpet_scope ir_hpet[MAX_HPET_TBS];
 static int ir_ioapic_num, ir_hpet_num;
 
+/*
+ * Lock ordering:
+ * ->dmar_global_lock
+ *     ->irq_2_ir_lock
+ *             ->qi->q_lock
+ *     ->iommu->register_lock
+ * Note:
+ * intel_irq_remap_ops.{supported,prepare,enable,disable,reenable} are called
+ * in single-threaded environment with interrupt disabled, so no need to tabke
+ * the dmar_global_lock.
+ */
 static DEFINE_RAW_SPINLOCK(irq_2_ir_lock);
 
 static int __init parse_ioapics_under_ir(void);
@@ -307,12 +318,14 @@ static int set_ioapic_sid(struct irte *irte, int apic)
        if (!irte)
                return -1;
 
+       down_read(&dmar_global_lock);
        for (i = 0; i < MAX_IO_APICS; i++) {
                if (ir_ioapic[i].id == apic) {
                        sid = (ir_ioapic[i].bus << 8) | ir_ioapic[i].devfn;
                        break;
                }
        }
+       up_read(&dmar_global_lock);
 
        if (sid == 0) {
                pr_warning("Failed to set source-id of IOAPIC (%d)\n", apic);
@@ -332,12 +345,14 @@ static int set_hpet_sid(struct irte *irte, u8 id)
        if (!irte)
                return -1;
 
+       down_read(&dmar_global_lock);
        for (i = 0; i < MAX_HPET_TBS; i++) {
                if (ir_hpet[i].id == id) {
                        sid = (ir_hpet[i].bus << 8) | ir_hpet[i].devfn;
                        break;
                }
        }
+       up_read(&dmar_global_lock);
 
        if (sid == 0) {
                pr_warning("Failed to set source-id of HPET block (%d)\n", id);
@@ -794,10 +809,16 @@ static int __init parse_ioapics_under_ir(void)
 
 static int __init ir_dev_scope_init(void)
 {
+       int ret;
+
        if (!irq_remapping_enabled)
                return 0;
 
-       return dmar_dev_scope_init();
+       down_write(&dmar_global_lock);
+       ret = dmar_dev_scope_init();
+       up_write(&dmar_global_lock);
+
+       return ret;
 }
 rootfs_initcall(ir_dev_scope_init);
 
@@ -878,23 +899,27 @@ static int intel_setup_ioapic_entry(int irq,
                                    struct io_apic_irq_attr *attr)
 {
        int ioapic_id = mpc_ioapic_id(attr->ioapic);
-       struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id);
+       struct intel_iommu *iommu;
        struct IR_IO_APIC_route_entry *entry;
        struct irte irte;
        int index;
 
+       down_read(&dmar_global_lock);
+       iommu = map_ioapic_to_ir(ioapic_id);
        if (!iommu) {
                pr_warn("No mapping iommu for ioapic %d\n", ioapic_id);
-               return -ENODEV;
-       }
-
-       entry = (struct IR_IO_APIC_route_entry *)route_entry;
-
-       index = alloc_irte(iommu, irq, 1);
-       if (index < 0) {
-               pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id);
-               return -ENOMEM;
+               index = -ENODEV;
+       } else {
+               index = alloc_irte(iommu, irq, 1);
+               if (index < 0) {
+                       pr_warn("Failed to allocate IRTE for ioapic %d\n",
+                               ioapic_id);
+                       index = -ENOMEM;
+               }
        }
+       up_read(&dmar_global_lock);
+       if (index < 0)
+               return index;
 
        prepare_irte(&irte, vector, destination);
 
@@ -913,6 +938,7 @@ static int intel_setup_ioapic_entry(int irq,
                irte.avail, irte.vector, irte.dest_id,
                irte.sid, irte.sq, irte.svt);
 
+       entry = (struct IR_IO_APIC_route_entry *)route_entry;
        memset(entry, 0, sizeof(*entry));
 
        entry->index2   = (index >> 15) & 0x1;
@@ -1043,20 +1069,23 @@ static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec)
        struct intel_iommu *iommu;
        int index;
 
+       down_read(&dmar_global_lock);
        iommu = map_dev_to_ir(dev);
        if (!iommu) {
                printk(KERN_ERR
                       "Unable to map PCI %s to iommu\n", pci_name(dev));
-               return -ENOENT;
+               index = -ENOENT;
+       } else {
+               index = alloc_irte(iommu, irq, nvec);
+               if (index < 0) {
+                       printk(KERN_ERR
+                              "Unable to allocate %d IRTE for PCI %s\n",
+                              nvec, pci_name(dev));
+                       index = -ENOSPC;
+               }
        }
+       up_read(&dmar_global_lock);
 
-       index = alloc_irte(iommu, irq, nvec);
-       if (index < 0) {
-               printk(KERN_ERR
-                      "Unable to allocate %d IRTE for PCI %s\n", nvec,
-                      pci_name(dev));
-               return -ENOSPC;
-       }
        return index;
 }
 
@@ -1064,33 +1093,40 @@ static int intel_msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
                               int index, int sub_handle)
 {
        struct intel_iommu *iommu;
+       int ret = -ENOENT;
 
+       down_read(&dmar_global_lock);
        iommu = map_dev_to_ir(pdev);
-       if (!iommu)
-               return -ENOENT;
-       /*
-        * setup the mapping between the irq and the IRTE
-        * base index, the sub_handle pointing to the
-        * appropriate interrupt remap table entry.
-        */
-       set_irte_irq(irq, iommu, index, sub_handle);
+       if (iommu) {
+               /*
+                * setup the mapping between the irq and the IRTE
+                * base index, the sub_handle pointing to the
+                * appropriate interrupt remap table entry.
+                */
+               set_irte_irq(irq, iommu, index, sub_handle);
+               ret = 0;
+       }
+       up_read(&dmar_global_lock);
 
-       return 0;
+       return ret;
 }
 
 static int intel_setup_hpet_msi(unsigned int irq, unsigned int id)
 {
-       struct intel_iommu *iommu = map_hpet_to_ir(id);
+       int ret = -1;
+       struct intel_iommu *iommu;
        int index;
 
-       if (!iommu)
-               return -1;
-
-       index = alloc_irte(iommu, irq, 1);
-       if (index < 0)
-               return -1;
+       down_read(&dmar_global_lock);
+       iommu = map_hpet_to_ir(id);
+       if (iommu) {
+               index = alloc_irte(iommu, irq, 1);
+               if (index >= 0)
+                       ret = 0;
+       }
+       up_read(&dmar_global_lock);
 
-       return 0;
+       return ret;
 }
 
 struct irq_remap_ops intel_irq_remap_ops = {
index 67da6cff74e8610cc04f5fa03b84fa8f612e9406..f6b17e6af2fb261f84eafd974d652a76716dcb95 100644 (file)
@@ -342,19 +342,30 @@ __is_range_overlap(struct rb_node *node,
        return 0;
 }
 
+static inline struct iova *
+alloc_and_init_iova(unsigned long pfn_lo, unsigned long pfn_hi)
+{
+       struct iova *iova;
+
+       iova = alloc_iova_mem();
+       if (iova) {
+               iova->pfn_lo = pfn_lo;
+               iova->pfn_hi = pfn_hi;
+       }
+
+       return iova;
+}
+
 static struct iova *
 __insert_new_range(struct iova_domain *iovad,
        unsigned long pfn_lo, unsigned long pfn_hi)
 {
        struct iova *iova;
 
-       iova = alloc_iova_mem();
-       if (!iova)
-               return iova;
+       iova = alloc_and_init_iova(pfn_lo, pfn_hi);
+       if (iova)
+               iova_insert_rbtree(&iovad->rbroot, iova);
 
-       iova->pfn_hi = pfn_hi;
-       iova->pfn_lo = pfn_lo;
-       iova_insert_rbtree(&iovad->rbroot, iova);
        return iova;
 }
 
@@ -433,3 +444,44 @@ copy_reserved_iova(struct iova_domain *from, struct iova_domain *to)
        }
        spin_unlock_irqrestore(&from->iova_rbtree_lock, flags);
 }
+
+struct iova *
+split_and_remove_iova(struct iova_domain *iovad, struct iova *iova,
+                     unsigned long pfn_lo, unsigned long pfn_hi)
+{
+       unsigned long flags;
+       struct iova *prev = NULL, *next = NULL;
+
+       spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+       if (iova->pfn_lo < pfn_lo) {
+               prev = alloc_and_init_iova(iova->pfn_lo, pfn_lo - 1);
+               if (prev == NULL)
+                       goto error;
+       }
+       if (iova->pfn_hi > pfn_hi) {
+               next = alloc_and_init_iova(pfn_hi + 1, iova->pfn_hi);
+               if (next == NULL)
+                       goto error;
+       }
+
+       __cached_rbnode_delete_update(iovad, iova);
+       rb_erase(&iova->node, &iovad->rbroot);
+
+       if (prev) {
+               iova_insert_rbtree(&iovad->rbroot, prev);
+               iova->pfn_lo = pfn_lo;
+       }
+       if (next) {
+               iova_insert_rbtree(&iovad->rbroot, next);
+               iova->pfn_hi = pfn_hi;
+       }
+       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+
+       return iova;
+
+error:
+       spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+       if (prev)
+               free_iova_mem(prev);
+       return NULL;
+}
index bcd78a720630782313f413d0db8a99adbd7e77da..7fcbfc498fa93c2527968191e6658be99eaa7b2d 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_iommu.h>
+#include <linux/of_irq.h>
 
 #include <asm/cacheflush.h>
 
@@ -146,13 +149,10 @@ static int iommu_enable(struct omap_iommu *obj)
        struct platform_device *pdev = to_platform_device(obj->dev);
        struct iommu_platform_data *pdata = pdev->dev.platform_data;
 
-       if (!pdata)
-               return -EINVAL;
-
        if (!arch_iommu)
                return -ENODEV;
 
-       if (pdata->deassert_reset) {
+       if (pdata && pdata->deassert_reset) {
                err = pdata->deassert_reset(pdev, pdata->reset_name);
                if (err) {
                        dev_err(obj->dev, "deassert_reset failed: %d\n", err);
@@ -172,14 +172,11 @@ static void iommu_disable(struct omap_iommu *obj)
        struct platform_device *pdev = to_platform_device(obj->dev);
        struct iommu_platform_data *pdata = pdev->dev.platform_data;
 
-       if (!pdata)
-               return;
-
        arch_iommu->disable(obj);
 
        pm_runtime_put_sync(obj->dev);
 
-       if (pdata->assert_reset)
+       if (pdata && pdata->assert_reset)
                pdata->assert_reset(pdev, pdata->reset_name);
 }
 
@@ -523,7 +520,8 @@ static void flush_iopte_range(u32 *first, u32 *last)
 static void iopte_free(u32 *iopte)
 {
        /* Note: freed iopte's must be clean ready for re-use */
-       kmem_cache_free(iopte_cachep, iopte);
+       if (iopte)
+               kmem_cache_free(iopte_cachep, iopte);
 }
 
 static u32 *iopte_alloc(struct omap_iommu *obj, u32 *iopgd, u32 da)
@@ -863,7 +861,7 @@ static int device_match_by_alias(struct device *dev, void *data)
  **/
 static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
 {
-       int err = -ENOMEM;
+       int err;
        struct device *dev;
        struct omap_iommu *obj;
 
@@ -871,7 +869,7 @@ static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
                                (void *)name,
                                device_match_by_alias);
        if (!dev)
-               return NULL;
+               return ERR_PTR(-ENODEV);
 
        obj = to_iommu(dev);
 
@@ -890,8 +888,10 @@ static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
                goto err_enable;
        flush_iotlb_all(obj);
 
-       if (!try_module_get(obj->owner))
+       if (!try_module_get(obj->owner)) {
+               err = -ENODEV;
                goto err_module;
+       }
 
        spin_unlock(&obj->iommu_lock);
 
@@ -940,17 +940,41 @@ static int omap_iommu_probe(struct platform_device *pdev)
        struct omap_iommu *obj;
        struct resource *res;
        struct iommu_platform_data *pdata = pdev->dev.platform_data;
+       struct device_node *of = pdev->dev.of_node;
 
-       obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
+       obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
        if (!obj)
                return -ENOMEM;
 
-       obj->nr_tlb_entries = pdata->nr_tlb_entries;
-       obj->name = pdata->name;
+       if (of) {
+               obj->name = dev_name(&pdev->dev);
+               obj->nr_tlb_entries = 32;
+               err = of_property_read_u32(of, "ti,#tlb-entries",
+                                          &obj->nr_tlb_entries);
+               if (err && err != -EINVAL)
+                       return err;
+               if (obj->nr_tlb_entries != 32 && obj->nr_tlb_entries != 8)
+                       return -EINVAL;
+               /*
+                * da_start and da_end are needed for omap-iovmm, so hardcode
+                * these values as used by OMAP3 ISP - the only user for
+                * omap-iovmm
+                */
+               obj->da_start = 0;
+               obj->da_end = 0xfffff000;
+               if (of_find_property(of, "ti,iommu-bus-err-back", NULL))
+                       obj->has_bus_err_back = MMU_GP_REG_BUS_ERR_BACK_EN;
+       } else {
+               obj->nr_tlb_entries = pdata->nr_tlb_entries;
+               obj->name = pdata->name;
+               obj->da_start = pdata->da_start;
+               obj->da_end = pdata->da_end;
+       }
+       if (obj->da_end <= obj->da_start)
+               return -EINVAL;
+
        obj->dev = &pdev->dev;
        obj->ctx = (void *)obj + sizeof(*obj);
-       obj->da_start = pdata->da_start;
-       obj->da_end = pdata->da_end;
 
        spin_lock_init(&obj->iommu_lock);
        mutex_init(&obj->mmap_lock);
@@ -958,33 +982,18 @@ static int omap_iommu_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&obj->mmap);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               err = -ENODEV;
-               goto err_mem;
-       }
-
-       res = request_mem_region(res->start, resource_size(res),
-                                dev_name(&pdev->dev));
-       if (!res) {
-               err = -EIO;
-               goto err_mem;
-       }
-
-       obj->regbase = ioremap(res->start, resource_size(res));
-       if (!obj->regbase) {
-               err = -ENOMEM;
-               goto err_ioremap;
-       }
+       obj->regbase = devm_ioremap_resource(obj->dev, res);
+       if (IS_ERR(obj->regbase))
+               return PTR_ERR(obj->regbase);
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               err = -ENODEV;
-               goto err_irq;
-       }
-       err = request_irq(irq, iommu_fault_handler, IRQF_SHARED,
-                         dev_name(&pdev->dev), obj);
+       if (irq < 0)
+               return -ENODEV;
+
+       err = devm_request_irq(obj->dev, irq, iommu_fault_handler, IRQF_SHARED,
+                              dev_name(obj->dev), obj);
        if (err < 0)
-               goto err_irq;
+               return err;
        platform_set_drvdata(pdev, obj);
 
        pm_runtime_irq_safe(obj->dev);
@@ -992,42 +1001,34 @@ static int omap_iommu_probe(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "%s registered\n", obj->name);
        return 0;
-
-err_irq:
-       iounmap(obj->regbase);
-err_ioremap:
-       release_mem_region(res->start, resource_size(res));
-err_mem:
-       kfree(obj);
-       return err;
 }
 
 static int omap_iommu_remove(struct platform_device *pdev)
 {
-       int irq;
-       struct resource *res;
        struct omap_iommu *obj = platform_get_drvdata(pdev);
 
        iopgtable_clear_entry_all(obj);
 
-       irq = platform_get_irq(pdev, 0);
-       free_irq(irq, obj);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, resource_size(res));
-       iounmap(obj->regbase);
-
        pm_runtime_disable(obj->dev);
 
        dev_info(&pdev->dev, "%s removed\n", obj->name);
-       kfree(obj);
        return 0;
 }
 
+static struct of_device_id omap_iommu_of_match[] = {
+       { .compatible = "ti,omap2-iommu" },
+       { .compatible = "ti,omap4-iommu" },
+       { .compatible = "ti,dra7-iommu" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, omap_iommu_of_match);
+
 static struct platform_driver omap_iommu_driver = {
        .probe  = omap_iommu_probe,
        .remove = omap_iommu_remove,
        .driver = {
                .name   = "omap-iommu",
+               .of_match_table = of_match_ptr(omap_iommu_of_match),
        },
 };
 
@@ -1253,6 +1254,49 @@ static int omap_iommu_domain_has_cap(struct iommu_domain *domain,
        return 0;
 }
 
+static int omap_iommu_add_device(struct device *dev)
+{
+       struct omap_iommu_arch_data *arch_data;
+       struct device_node *np;
+
+       /*
+        * Allocate the archdata iommu structure for DT-based devices.
+        *
+        * TODO: Simplify this when removing non-DT support completely from the
+        * IOMMU users.
+        */
+       if (!dev->of_node)
+               return 0;
+
+       np = of_parse_phandle(dev->of_node, "iommus", 0);
+       if (!np)
+               return 0;
+
+       arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL);
+       if (!arch_data) {
+               of_node_put(np);
+               return -ENOMEM;
+       }
+
+       arch_data->name = kstrdup(dev_name(dev), GFP_KERNEL);
+       dev->archdata.iommu = arch_data;
+
+       of_node_put(np);
+
+       return 0;
+}
+
+static void omap_iommu_remove_device(struct device *dev)
+{
+       struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
+
+       if (!dev->of_node || !arch_data)
+               return;
+
+       kfree(arch_data->name);
+       kfree(arch_data);
+}
+
 static struct iommu_ops omap_iommu_ops = {
        .domain_init    = omap_iommu_domain_init,
        .domain_destroy = omap_iommu_domain_destroy,
@@ -1262,6 +1306,8 @@ static struct iommu_ops omap_iommu_ops = {
        .unmap          = omap_iommu_unmap,
        .iova_to_phys   = omap_iommu_iova_to_phys,
        .domain_has_cap = omap_iommu_domain_has_cap,
+       .add_device     = omap_iommu_add_device,
+       .remove_device  = omap_iommu_remove_device,
        .pgsize_bitmap  = OMAP_IOMMU_PGSIZES,
 };
 
index 1200842066025dec7c6da98791ce64919b858fdd..ea920c3e94ff3497819fe26062fbca2f2128cbe4 100644 (file)
@@ -52,6 +52,8 @@ struct omap_iommu {
        void *ctx; /* iommu context: registres saved area */
        u32 da_start;
        u32 da_end;
+
+       int has_bus_err_back;
 };
 
 struct cr_regs {
@@ -130,6 +132,7 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
 #define MMU_READ_CAM           0x68
 #define MMU_READ_RAM           0x6c
 #define MMU_EMU_FAULT_AD       0x70
+#define MMU_GP_REG             0x88
 
 #define MMU_REG_SIZE           256
 
@@ -163,6 +166,8 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
 #define MMU_RAM_MIXED_MASK     (1 << MMU_RAM_MIXED_SHIFT)
 #define MMU_RAM_MIXED          MMU_RAM_MIXED_MASK
 
+#define MMU_GP_REG_BUS_ERR_BACK_EN     0x1
+
 /*
  * utilities for super page(16MB, 1MB, 64KB and 4KB)
  */
index d745094a69ddf180eeea86b4727a844008383682..5e1ea3b0bf16e0a8b917da634389c9bcb21f981b 100644 (file)
@@ -98,6 +98,9 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
 
        iommu_write_reg(obj, pa, MMU_TTB);
 
+       if (obj->has_bus_err_back)
+               iommu_write_reg(obj, MMU_GP_REG_BUS_ERR_BACK_EN, MMU_GP_REG);
+
        __iommu_set_twl(obj, true);
 
        return 0;
index 61ffdca96e253aa4794721be6c951163c28d0f61..d770f7406631298d2e400b9b1adee31adce76bad 100644 (file)
@@ -39,6 +39,14 @@ config IMGPDC_IRQ
        select GENERIC_IRQ_CHIP
        select IRQ_DOMAIN
 
+config CLPS711X_IRQCHIP
+       bool
+       depends on ARCH_CLPS711X
+       select IRQ_DOMAIN
+       select MULTI_IRQ_HANDLER
+       select SPARSE_IRQ
+       default y
+
 config ORION_IRQCHIP
        bool
        select IRQ_DOMAIN
@@ -69,3 +77,11 @@ config VERSATILE_FPGA_IRQ_NR
 config XTENSA_MX
        bool
        select IRQ_DOMAIN
+
+config IRQ_CROSSBAR
+       bool
+       help
+         Support for a CROSSBAR ip that preceeds the main interrupt controller.
+         The primary irqchip invokes the crossbar's callback which inturn allocates
+         a free irq and configures the IP. Thus the peripheral interrupts are
+         routed to one of the free irqchip interrupt lines.
index 1c0c151d108c2fe40d3cf8c4bda1d0b4c4d9112c..f180f8d5fb7b69011cb9860298e0422602ac3a53 100644 (file)
@@ -10,6 +10,7 @@ obj-$(CONFIG_DW_APB_ICTL)             += irq-dw-apb-ictl.o
 obj-$(CONFIG_METAG)                    += irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)   += irq-metag.o
 obj-$(CONFIG_ARCH_MOXART)              += irq-moxart.o
+obj-$(CONFIG_CLPS711X_IRQCHIP)         += irq-clps711x.o
 obj-$(CONFIG_ORION_IRQCHIP)            += irq-orion.o
 obj-$(CONFIG_ARCH_SUNXI)               += irq-sun4i.o
 obj-$(CONFIG_ARCH_SUNXI)               += irq-sunxi-nmi.o
@@ -27,3 +28,4 @@ obj-$(CONFIG_ARCH_VT8500)             += irq-vt8500.o
 obj-$(CONFIG_TB10X_IRQC)               += irq-tb10x.o
 obj-$(CONFIG_XTENSA)                   += irq-xtensa-pic.o
 obj-$(CONFIG_XTENSA_MX)                        += irq-xtensa-mx.o
+obj-$(CONFIG_IRQ_CROSSBAR)             += irq-crossbar.o
index 40e6440348ff5d9ace76ff17510bbf40ae648415..f8636a650cf6489a16d21b09df4e6c49127c5299 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/irqchip/chained_irq.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <asm/mach/irq.h>
 
 #include "irqchip.h"
 
@@ -81,7 +80,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
        cascade_irq = irq_find_mapping(combiner_irq_domain, combiner_irq);
 
        if (unlikely(!cascade_irq))
-               do_bad_IRQ(irq, desc);
+               handle_bad_irq(irq, desc);
        else
                generic_handle_irq(cascade_irq);
 
diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c
new file mode 100644 (file)
index 0000000..33340dc
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *  CLPS711X IRQ driver
+ *
+ *  Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#include "irqchip.h"
+
+#define CLPS711X_INTSR1        (0x0240)
+#define CLPS711X_INTMR1        (0x0280)
+#define CLPS711X_BLEOI (0x0600)
+#define CLPS711X_MCEOI (0x0640)
+#define CLPS711X_TEOI  (0x0680)
+#define CLPS711X_TC1EOI        (0x06c0)
+#define CLPS711X_TC2EOI        (0x0700)
+#define CLPS711X_RTCEOI        (0x0740)
+#define CLPS711X_UMSEOI        (0x0780)
+#define CLPS711X_COEOI (0x07c0)
+#define CLPS711X_INTSR2        (0x1240)
+#define CLPS711X_INTMR2        (0x1280)
+#define CLPS711X_SRXEOF        (0x1600)
+#define CLPS711X_KBDEOI        (0x1700)
+#define CLPS711X_INTSR3        (0x2240)
+#define CLPS711X_INTMR3        (0x2280)
+
+static const struct {
+#define CLPS711X_FLAG_EN       (1 << 0)
+#define CLPS711X_FLAG_FIQ      (1 << 1)
+       unsigned int    flags;
+       phys_addr_t     eoi;
+} clps711x_irqs[] = {
+       [1]     = { CLPS711X_FLAG_FIQ, CLPS711X_BLEOI, },
+       [3]     = { CLPS711X_FLAG_FIQ, CLPS711X_MCEOI, },
+       [4]     = { CLPS711X_FLAG_EN, CLPS711X_COEOI, },
+       [5]     = { CLPS711X_FLAG_EN, },
+       [6]     = { CLPS711X_FLAG_EN, },
+       [7]     = { CLPS711X_FLAG_EN, },
+       [8]     = { CLPS711X_FLAG_EN, CLPS711X_TC1EOI, },
+       [9]     = { CLPS711X_FLAG_EN, CLPS711X_TC2EOI, },
+       [10]    = { CLPS711X_FLAG_EN, CLPS711X_RTCEOI, },
+       [11]    = { CLPS711X_FLAG_EN, CLPS711X_TEOI, },
+       [12]    = { CLPS711X_FLAG_EN, },
+       [13]    = { CLPS711X_FLAG_EN, },
+       [14]    = { CLPS711X_FLAG_EN, CLPS711X_UMSEOI, },
+       [15]    = { CLPS711X_FLAG_EN, CLPS711X_SRXEOF, },
+       [16]    = { CLPS711X_FLAG_EN, CLPS711X_KBDEOI, },
+       [17]    = { CLPS711X_FLAG_EN, },
+       [18]    = { CLPS711X_FLAG_EN, },
+       [28]    = { CLPS711X_FLAG_EN, },
+       [29]    = { CLPS711X_FLAG_EN, },
+       [32]    = { CLPS711X_FLAG_FIQ, },
+};
+
+static struct {
+       void __iomem            *base;
+       void __iomem            *intmr[3];
+       void __iomem            *intsr[3];
+       struct irq_domain       *domain;
+       struct irq_domain_ops   ops;
+} *clps711x_intc;
+
+static asmlinkage void __exception_irq_entry clps711x_irqh(struct pt_regs *regs)
+{
+       u32 irqnr, irqstat;
+
+       do {
+               irqstat = readw_relaxed(clps711x_intc->intmr[0]) &
+                         readw_relaxed(clps711x_intc->intsr[0]);
+               if (irqstat) {
+                       irqnr = irq_find_mapping(clps711x_intc->domain,
+                                                fls(irqstat) - 1);
+                       handle_IRQ(irqnr, regs);
+               }
+
+               irqstat = readw_relaxed(clps711x_intc->intmr[1]) &
+                         readw_relaxed(clps711x_intc->intsr[1]);
+               if (irqstat) {
+                       irqnr = irq_find_mapping(clps711x_intc->domain,
+                                                fls(irqstat) - 1 + 16);
+                       handle_IRQ(irqnr, regs);
+               }
+       } while (irqstat);
+}
+
+static void clps711x_intc_eoi(struct irq_data *d)
+{
+       irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+       writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hwirq].eoi);
+}
+
+static void clps711x_intc_mask(struct irq_data *d)
+{
+       irq_hw_number_t hwirq = irqd_to_hwirq(d);
+       void __iomem *intmr = clps711x_intc->intmr[hwirq / 16];
+       u32 tmp;
+
+       tmp = readl_relaxed(intmr);
+       tmp &= ~(1 << (hwirq % 16));
+       writel_relaxed(tmp, intmr);
+}
+
+static void clps711x_intc_unmask(struct irq_data *d)
+{
+       irq_hw_number_t hwirq = irqd_to_hwirq(d);
+       void __iomem *intmr = clps711x_intc->intmr[hwirq / 16];
+       u32 tmp;
+
+       tmp = readl_relaxed(intmr);
+       tmp |= 1 << (hwirq % 16);
+       writel_relaxed(tmp, intmr);
+}
+
+static struct irq_chip clps711x_intc_chip = {
+       .name           = "clps711x-intc",
+       .irq_eoi        = clps711x_intc_eoi,
+       .irq_mask       = clps711x_intc_mask,
+       .irq_unmask     = clps711x_intc_unmask,
+};
+
+static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       irq_flow_handler_t handler = handle_level_irq;
+       unsigned int flags = IRQF_VALID | IRQF_PROBE;
+
+       if (!clps711x_irqs[hw].flags)
+               return 0;
+
+       if (clps711x_irqs[hw].flags & CLPS711X_FLAG_FIQ) {
+               handler = handle_bad_irq;
+               flags |= IRQF_NOAUTOEN;
+       } else if (clps711x_irqs[hw].eoi) {
+               handler = handle_fasteoi_irq;
+       }
+
+       /* Clear down pending interrupt */
+       if (clps711x_irqs[hw].eoi)
+               writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hw].eoi);
+
+       irq_set_chip_and_handler(virq, &clps711x_intc_chip, handler);
+       set_irq_flags(virq, flags);
+
+       return 0;
+}
+
+static int __init _clps711x_intc_init(struct device_node *np,
+                                     phys_addr_t base, resource_size_t size)
+{
+       int err;
+
+       clps711x_intc = kzalloc(sizeof(*clps711x_intc), GFP_KERNEL);
+       if (!clps711x_intc)
+               return -ENOMEM;
+
+       clps711x_intc->base = ioremap(base, size);
+       if (!clps711x_intc->base) {
+               err = -ENOMEM;
+               goto out_kfree;
+       }
+
+       clps711x_intc->intsr[0] = clps711x_intc->base + CLPS711X_INTSR1;
+       clps711x_intc->intmr[0] = clps711x_intc->base + CLPS711X_INTMR1;
+       clps711x_intc->intsr[1] = clps711x_intc->base + CLPS711X_INTSR2;
+       clps711x_intc->intmr[1] = clps711x_intc->base + CLPS711X_INTMR2;
+       clps711x_intc->intsr[2] = clps711x_intc->base + CLPS711X_INTSR3;
+       clps711x_intc->intmr[2] = clps711x_intc->base + CLPS711X_INTMR3;
+
+       /* Mask all interrupts */
+       writel_relaxed(0, clps711x_intc->intmr[0]);
+       writel_relaxed(0, clps711x_intc->intmr[1]);
+       writel_relaxed(0, clps711x_intc->intmr[2]);
+
+       err = irq_alloc_descs(-1, 0, ARRAY_SIZE(clps711x_irqs), numa_node_id());
+       if (IS_ERR_VALUE(err))
+               goto out_iounmap;
+
+       clps711x_intc->ops.map = clps711x_intc_irq_map;
+       clps711x_intc->ops.xlate = irq_domain_xlate_onecell;
+       clps711x_intc->domain =
+               irq_domain_add_legacy(np, ARRAY_SIZE(clps711x_irqs),
+                                     0, 0, &clps711x_intc->ops, NULL);
+       if (!clps711x_intc->domain) {
+               err = -ENOMEM;
+               goto out_irqfree;
+       }
+
+       irq_set_default_host(clps711x_intc->domain);
+       set_handle_irq(clps711x_irqh);
+
+#ifdef CONFIG_FIQ
+       init_FIQ(0);
+#endif
+
+       return 0;
+
+out_irqfree:
+       irq_free_descs(0, ARRAY_SIZE(clps711x_irqs));
+
+out_iounmap:
+       iounmap(clps711x_intc->base);
+
+out_kfree:
+       kfree(clps711x_intc);
+
+       return err;
+}
+
+void __init clps711x_intc_init(phys_addr_t base, resource_size_t size)
+{
+       BUG_ON(_clps711x_intc_init(NULL, base, size));
+}
+
+#ifdef CONFIG_IRQCHIP
+static int __init clps711x_intc_init_dt(struct device_node *np,
+                                       struct device_node *parent)
+{
+       struct resource res;
+       int err;
+
+       err = of_address_to_resource(np, 0, &res);
+       if (err)
+               return err;
+
+       return _clps711x_intc_init(np, res.start, resource_size(&res));
+}
+IRQCHIP_DECLARE(clps711x, "cirrus,clps711x-intc", clps711x_intc_init_dt);
+#endif
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
new file mode 100644 (file)
index 0000000..fc817d2
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ *  drivers/irqchip/irq-crossbar.c
+ *
+ *  Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Sricharan R <r.sricharan@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/err.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/irqchip/arm-gic.h>
+
+#define IRQ_FREE       -1
+#define GIC_IRQ_START  32
+
+/*
+ * @int_max: maximum number of supported interrupts
+ * @irq_map: array of interrupts to crossbar number mapping
+ * @crossbar_base: crossbar base address
+ * @register_offsets: offsets for each irq number
+ */
+struct crossbar_device {
+       uint int_max;
+       uint *irq_map;
+       void __iomem *crossbar_base;
+       int *register_offsets;
+       void (*write) (int, int);
+};
+
+static struct crossbar_device *cb;
+
+static inline void crossbar_writel(int irq_no, int cb_no)
+{
+       writel(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
+}
+
+static inline void crossbar_writew(int irq_no, int cb_no)
+{
+       writew(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
+}
+
+static inline void crossbar_writeb(int irq_no, int cb_no)
+{
+       writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
+}
+
+static inline int allocate_free_irq(int cb_no)
+{
+       int i;
+
+       for (i = 0; i < cb->int_max; i++) {
+               if (cb->irq_map[i] == IRQ_FREE) {
+                       cb->irq_map[i] = cb_no;
+                       return i;
+               }
+       }
+
+       return -ENODEV;
+}
+
+static int crossbar_domain_map(struct irq_domain *d, unsigned int irq,
+                              irq_hw_number_t hw)
+{
+       cb->write(hw - GIC_IRQ_START, cb->irq_map[hw - GIC_IRQ_START]);
+       return 0;
+}
+
+static void crossbar_domain_unmap(struct irq_domain *d, unsigned int irq)
+{
+       irq_hw_number_t hw = irq_get_irq_data(irq)->hwirq;
+
+       if (hw > GIC_IRQ_START)
+               cb->irq_map[hw - GIC_IRQ_START] = IRQ_FREE;
+}
+
+static int crossbar_domain_xlate(struct irq_domain *d,
+                                struct device_node *controller,
+                                const u32 *intspec, unsigned int intsize,
+                                unsigned long *out_hwirq,
+                                unsigned int *out_type)
+{
+       unsigned long ret;
+
+       ret = allocate_free_irq(intspec[1]);
+
+       if (IS_ERR_VALUE(ret))
+               return ret;
+
+       *out_hwirq = ret + GIC_IRQ_START;
+       return 0;
+}
+
+const struct irq_domain_ops routable_irq_domain_ops = {
+       .map = crossbar_domain_map,
+       .unmap = crossbar_domain_unmap,
+       .xlate = crossbar_domain_xlate
+};
+
+static int __init crossbar_of_init(struct device_node *node)
+{
+       int i, size, max, reserved = 0, entry;
+       const __be32 *irqsr;
+
+       cb = kzalloc(sizeof(struct cb_device *), GFP_KERNEL);
+
+       if (!cb)
+               return -ENOMEM;
+
+       cb->crossbar_base = of_iomap(node, 0);
+       if (!cb->crossbar_base)
+               goto err1;
+
+       of_property_read_u32(node, "ti,max-irqs", &max);
+       cb->irq_map = kzalloc(max * sizeof(int), GFP_KERNEL);
+       if (!cb->irq_map)
+               goto err2;
+
+       cb->int_max = max;
+
+       for (i = 0; i < max; i++)
+               cb->irq_map[i] = IRQ_FREE;
+
+       /* Get and mark reserved irqs */
+       irqsr = of_get_property(node, "ti,irqs-reserved", &size);
+       if (irqsr) {
+               size /= sizeof(__be32);
+
+               for (i = 0; i < size; i++) {
+                       of_property_read_u32_index(node,
+                                                  "ti,irqs-reserved",
+                                                  i, &entry);
+                       if (entry > max) {
+                               pr_err("Invalid reserved entry\n");
+                               goto err3;
+                       }
+                       cb->irq_map[entry] = 0;
+               }
+       }
+
+       cb->register_offsets = kzalloc(max * sizeof(int), GFP_KERNEL);
+       if (!cb->register_offsets)
+               goto err3;
+
+       of_property_read_u32(node, "ti,reg-size", &size);
+
+       switch (size) {
+       case 1:
+               cb->write = crossbar_writeb;
+               break;
+       case 2:
+               cb->write = crossbar_writew;
+               break;
+       case 4:
+               cb->write = crossbar_writel;
+               break;
+       default:
+               pr_err("Invalid reg-size property\n");
+               goto err4;
+               break;
+       }
+
+       /*
+        * Register offsets are not linear because of the
+        * reserved irqs. so find and store the offsets once.
+        */
+       for (i = 0; i < max; i++) {
+               if (!cb->irq_map[i])
+                       continue;
+
+               cb->register_offsets[i] = reserved;
+               reserved += size;
+       }
+
+       register_routable_domain_ops(&routable_irq_domain_ops);
+       return 0;
+
+err4:
+       kfree(cb->register_offsets);
+err3:
+       kfree(cb->irq_map);
+err2:
+       iounmap(cb->crossbar_base);
+err1:
+       kfree(cb);
+       return -ENOMEM;
+}
+
+static const struct of_device_id crossbar_match[] __initconst = {
+       { .compatible = "ti,irq-crossbar" },
+       {}
+};
+
+int __init irqcrossbar_init(void)
+{
+       struct device_node *np;
+       np = of_find_matching_node(NULL, crossbar_match);
+       if (!np)
+               return -ENODEV;
+
+       crossbar_of_init(np);
+       return 0;
+}
index 531769b2433a6dc3c305784e7836b11915f91ff2..4300b6606f5e3276c11656ff29506b665e9a2a87 100644 (file)
@@ -661,9 +661,9 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 
        /*
         * Ensure that stores to Normal memory are visible to the
-        * other CPUs before issuing the IPI.
+        * other CPUs before they observe us issuing the IPI.
         */
-       dsb();
+       dmb(ishst);
 
        /* this always happens on GIC0 */
        writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
@@ -824,16 +824,25 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
                irq_set_chip_and_handler(irq, &gic_chip,
                                         handle_fasteoi_irq);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+               gic_routable_irq_domain_ops->map(d, irq, hw);
        }
        irq_set_chip_data(irq, d->host_data);
        return 0;
 }
 
+static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
+{
+       gic_routable_irq_domain_ops->unmap(d, irq);
+}
+
 static int gic_irq_domain_xlate(struct irq_domain *d,
                                struct device_node *controller,
                                const u32 *intspec, unsigned int intsize,
                                unsigned long *out_hwirq, unsigned int *out_type)
 {
+       unsigned long ret = 0;
+
        if (d->of_node != controller)
                return -EINVAL;
        if (intsize < 3)
@@ -843,11 +852,20 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
        *out_hwirq = intspec[1] + 16;
 
        /* For SPIs, we need to add 16 more to get the GIC irq ID number */
-       if (!intspec[0])
-               *out_hwirq += 16;
+       if (!intspec[0]) {
+               ret = gic_routable_irq_domain_ops->xlate(d, controller,
+                                                        intspec,
+                                                        intsize,
+                                                        out_hwirq,
+                                                        out_type);
+
+               if (IS_ERR_VALUE(ret))
+                       return ret;
+       }
 
        *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
-       return 0;
+
+       return ret;
 }
 
 #ifdef CONFIG_SMP
@@ -871,9 +889,41 @@ static struct notifier_block gic_cpu_notifier = {
 
 static const struct irq_domain_ops gic_irq_domain_ops = {
        .map = gic_irq_domain_map,
+       .unmap = gic_irq_domain_unmap,
        .xlate = gic_irq_domain_xlate,
 };
 
+/* Default functions for routable irq domain */
+static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq,
+                             irq_hw_number_t hw)
+{
+       return 0;
+}
+
+static void gic_routable_irq_domain_unmap(struct irq_domain *d,
+                                         unsigned int irq)
+{
+}
+
+static int gic_routable_irq_domain_xlate(struct irq_domain *d,
+                               struct device_node *controller,
+                               const u32 *intspec, unsigned int intsize,
+                               unsigned long *out_hwirq,
+                               unsigned int *out_type)
+{
+       *out_hwirq += 16;
+       return 0;
+}
+
+const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
+       .map = gic_routable_irq_domain_map,
+       .unmap = gic_routable_irq_domain_unmap,
+       .xlate = gic_routable_irq_domain_xlate,
+};
+
+const struct irq_domain_ops *gic_routable_irq_domain_ops =
+                                       &gic_default_routable_irq_domain_ops;
+
 void __init gic_init_bases(unsigned int gic_nr, int irq_start,
                           void __iomem *dist_base, void __iomem *cpu_base,
                           u32 percpu_offset, struct device_node *node)
@@ -881,6 +931,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
        irq_hw_number_t hwirq_base;
        struct gic_chip_data *gic;
        int gic_irqs, irq_base, i;
+       int nr_routable_irqs;
 
        BUG_ON(gic_nr >= MAX_GIC_NR);
 
@@ -946,14 +997,25 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
        gic->gic_irqs = gic_irqs;
 
        gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
-       irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
-       if (IS_ERR_VALUE(irq_base)) {
-               WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
-                    irq_start);
-               irq_base = irq_start;
+
+       if (of_property_read_u32(node, "arm,routable-irqs",
+                                &nr_routable_irqs)) {
+               irq_base = irq_alloc_descs(irq_start, 16, gic_irqs,
+                                          numa_node_id());
+               if (IS_ERR_VALUE(irq_base)) {
+                       WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
+                            irq_start);
+                       irq_base = irq_start;
+               }
+
+               gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
+                                       hwirq_base, &gic_irq_domain_ops, gic);
+       } else {
+               gic->domain = irq_domain_add_linear(node, nr_routable_irqs,
+                                                   &gic_irq_domain_ops,
+                                                   gic);
        }
-       gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
-                                   hwirq_base, &gic_irq_domain_ops, gic);
+
        if (WARN_ON(!gic->domain))
                return;
 
index 3c8827fe83f37544a9a5b1e8a01ae1486c7c4440..1c3e2c9b46bae59c96e9f2851d988af4d13b33c6 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/of_irq.h>
 
 #include <asm/exception.h>
-#include <asm/mach/irq.h>
+#include <asm/hardirq.h>
 
 #include "irqchip.h"
 
index 473f09a74d4d4c53f80777f3173753e89d82b33e..37dab0b472cd8cc19f9fdba801ef69b41a36ddaa 100644 (file)
@@ -57,6 +57,7 @@
 
 /**
  * struct vic_device - VIC PM device
+ * @parent_irq: The parent IRQ number of the VIC if cascaded, or 0.
  * @irq: The IRQ number for the base of the VIC.
  * @base: The register base for the VIC.
  * @valid_sources: A bitmask of valid interrupts
@@ -224,6 +225,17 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
        return handled;
 }
 
+static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc)
+{
+       u32 stat, hwirq;
+       struct vic_device *vic = irq_desc_get_handler_data(desc);
+
+       while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
+               hwirq = ffs(stat) - 1;
+               generic_handle_irq(irq_find_mapping(vic->domain, hwirq));
+       }
+}
+
 /*
  * Keep iterating over all registered VIC's until there are no pending
  * interrupts.
@@ -246,6 +258,7 @@ static struct irq_domain_ops vic_irqdomain_ops = {
 /**
  * vic_register() - Register a VIC.
  * @base: The base address of the VIC.
+ * @parent_irq: The parent IRQ if cascaded, else 0.
  * @irq: The base IRQ for the VIC.
  * @valid_sources: bitmask of valid interrupts
  * @resume_sources: bitmask of interrupts allowed for resume sources.
@@ -257,7 +270,8 @@ static struct irq_domain_ops vic_irqdomain_ops = {
  *
  * This also configures the IRQ domain for the VIC.
  */
-static void __init vic_register(void __iomem *base, unsigned int irq,
+static void __init vic_register(void __iomem *base, unsigned int parent_irq,
+                               unsigned int irq,
                                u32 valid_sources, u32 resume_sources,
                                struct device_node *node)
 {
@@ -273,15 +287,25 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
        v->base = base;
        v->valid_sources = valid_sources;
        v->resume_sources = resume_sources;
-       v->irq = irq;
        set_handle_irq(vic_handle_irq);
        vic_id++;
+
+       if (parent_irq) {
+               irq_set_handler_data(parent_irq, v);
+               irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded);
+       }
+
        v->domain = irq_domain_add_simple(node, fls(valid_sources), irq,
                                          &vic_irqdomain_ops, v);
        /* create an IRQ mapping for each valid IRQ */
        for (i = 0; i < fls(valid_sources); i++)
                if (valid_sources & (1 << i))
                        irq_create_mapping(v->domain, i);
+       /* If no base IRQ was passed, figure out our allocated base */
+       if (irq)
+               v->irq = irq;
+       else
+               v->irq = irq_find_mapping(v->domain, 0);
 }
 
 static void vic_ack_irq(struct irq_data *d)
@@ -409,10 +433,10 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
                writel(32, base + VIC_PL190_DEF_VECT_ADDR);
        }
 
-       vic_register(base, irq_start, vic_sources, 0, node);
+       vic_register(base, 0, irq_start, vic_sources, 0, node);
 }
 
-void __init __vic_init(void __iomem *base, int irq_start,
+void __init __vic_init(void __iomem *base, int parent_irq, int irq_start,
                              u32 vic_sources, u32 resume_sources,
                              struct device_node *node)
 {
@@ -449,7 +473,7 @@ void __init __vic_init(void __iomem *base, int irq_start,
 
        vic_init2(base);
 
-       vic_register(base, irq_start, vic_sources, resume_sources, node);
+       vic_register(base, parent_irq, irq_start, vic_sources, resume_sources, node);
 }
 
 /**
@@ -462,8 +486,30 @@ void __init __vic_init(void __iomem *base, int irq_start,
 void __init vic_init(void __iomem *base, unsigned int irq_start,
                     u32 vic_sources, u32 resume_sources)
 {
-       __vic_init(base, irq_start, vic_sources, resume_sources, NULL);
+       __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL);
+}
+
+/**
+ * vic_init_cascaded() - initialise a cascaded vectored interrupt controller
+ * @base: iomem base address
+ * @parent_irq: the parent IRQ we're cascaded off
+ * @irq_start: starting interrupt number, must be muliple of 32
+ * @vic_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
+ *
+ * This returns the base for the new interrupts or negative on error.
+ */
+int __init vic_init_cascaded(void __iomem *base, unsigned int parent_irq,
+                             u32 vic_sources, u32 resume_sources)
+{
+       struct vic_device *v;
+
+       v = &vic_devices[vic_id];
+       __vic_init(base, parent_irq, 0, vic_sources, resume_sources, NULL);
+       /* Return out acquired base */
+       return v->irq;
 }
+EXPORT_SYMBOL_GPL(vic_init_cascaded);
 
 #ifdef CONFIG_OF
 int __init vic_of_init(struct device_node *node, struct device_node *parent)
@@ -485,7 +531,7 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
        /*
         * Passing 0 as first IRQ makes the simple domain allocate descriptors
         */
-       __vic_init(regs, 0, interrupt_mask, wakeup_mask, node);
+       __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, node);
 
        return 0;
 }
index 72156c123033342f566497155154d31eeef79baf..44c358ecf5a10ac4d681bbe0365d3b65784b884c 100644 (file)
@@ -421,7 +421,7 @@ config LEDS_MC13783
 config LEDS_NS2
        tristate "LED support for Network Space v2 GPIO LEDs"
        depends on LEDS_CLASS
-       depends on ARCH_KIRKWOOD
+       depends on ARCH_KIRKWOOD || MACH_KIRKWOOD
        default y
        help
          This option enable support for the dual-GPIO LED found on the
@@ -431,7 +431,7 @@ config LEDS_NS2
 config LEDS_NETXBIG
        tristate "LED support for Big Network series LEDs"
        depends on LEDS_CLASS
-       depends on ARCH_KIRKWOOD
+       depends on ARCH_KIRKWOOD || MACH_KIRKWOOD
        default y
        help
          This option enable support for LEDs found on the LaCie 2Big
index 95ad936e60482477c1f87c0aa654fded90d06ba5..5bdedf6df153cf25d54e91a2cca5d9e3b6b8b1cf 100644 (file)
@@ -285,6 +285,17 @@ config DM_CACHE_CLEANER
          A simple cache policy that writes back all data to the
          origin.  Used when decommissioning a dm-cache.
 
+config DM_ERA
+       tristate "Era target (EXPERIMENTAL)"
+       depends on BLK_DEV_DM
+       default n
+       select DM_PERSISTENT_DATA
+       select DM_BIO_PRISON
+       ---help---
+         dm-era tracks which parts of a block device are written to
+         over time.  Useful for maintaining cache coherency when using
+         vendor snapshots.
+
 config DM_MIRROR
        tristate "Mirror target"
        depends on BLK_DEV_DM
index f26d832925791e49f624d4b19649cfc5e8312f19..a2da532b1c2bda38d18a6324c2dfdcfcc7108df5 100644 (file)
@@ -14,6 +14,7 @@ dm-thin-pool-y        += dm-thin.o dm-thin-metadata.o
 dm-cache-y     += dm-cache-target.o dm-cache-metadata.o dm-cache-policy.o
 dm-cache-mq-y   += dm-cache-policy-mq.o
 dm-cache-cleaner-y += dm-cache-policy-cleaner.o
+dm-era-y       += dm-era-target.o
 md-mod-y       += md.o bitmap.o
 raid456-y      += raid5.o
 
@@ -53,6 +54,7 @@ obj-$(CONFIG_DM_VERITY)               += dm-verity.o
 obj-$(CONFIG_DM_CACHE)         += dm-cache.o
 obj-$(CONFIG_DM_CACHE_MQ)      += dm-cache-mq.o
 obj-$(CONFIG_DM_CACHE_CLEANER) += dm-cache-cleaner.o
+obj-$(CONFIG_DM_ERA)           += dm-era.o
 
 ifeq ($(CONFIG_DM_UEVENT),y)
 dm-mod-objs                    += dm-uevent.o
index bed4ad4e1b7c037c107813eabb87d6bb4650b9b1..aac0e2df06bec4c2412a8ff27787e0d89b6a6c4f 100644 (file)
@@ -19,7 +19,6 @@
 
 typedef dm_block_t __bitwise__ dm_oblock_t;
 typedef uint32_t __bitwise__ dm_cblock_t;
-typedef dm_block_t __bitwise__ dm_dblock_t;
 
 static inline dm_oblock_t to_oblock(dm_block_t b)
 {
@@ -41,14 +40,4 @@ static inline uint32_t from_cblock(dm_cblock_t b)
        return (__force uint32_t) b;
 }
 
-static inline dm_dblock_t to_dblock(dm_block_t b)
-{
-       return (__force dm_dblock_t) b;
-}
-
-static inline dm_block_t from_dblock(dm_dblock_t b)
-{
-       return (__force dm_block_t) b;
-}
-
 #endif /* DM_CACHE_BLOCK_TYPES_H */
index 9ef0752e8a08c4edb0ba422738da707270f60831..4ead4ba606562b0c33d750064660a4effe0594ea 100644 (file)
@@ -109,7 +109,7 @@ struct dm_cache_metadata {
        dm_block_t discard_root;
 
        sector_t discard_block_size;
-       dm_dblock_t discard_nr_blocks;
+       dm_oblock_t discard_nr_blocks;
 
        sector_t data_block_size;
        dm_cblock_t cache_blocks;
@@ -120,6 +120,12 @@ struct dm_cache_metadata {
        unsigned policy_version[CACHE_POLICY_VERSION_SIZE];
        size_t policy_hint_size;
        struct dm_cache_statistics stats;
+
+       /*
+        * Reading the space map root can fail, so we read it into this
+        * buffer before the superblock is locked and updated.
+        */
+       __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
 };
 
 /*-------------------------------------------------------------------
@@ -260,11 +266,31 @@ static void __setup_mapping_info(struct dm_cache_metadata *cmd)
        }
 }
 
+static int __save_sm_root(struct dm_cache_metadata *cmd)
+{
+       int r;
+       size_t metadata_len;
+
+       r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
+       if (r < 0)
+               return r;
+
+       return dm_sm_copy_root(cmd->metadata_sm, &cmd->metadata_space_map_root,
+                              metadata_len);
+}
+
+static void __copy_sm_root(struct dm_cache_metadata *cmd,
+                          struct cache_disk_superblock *disk_super)
+{
+       memcpy(&disk_super->metadata_space_map_root,
+              &cmd->metadata_space_map_root,
+              sizeof(cmd->metadata_space_map_root));
+}
+
 static int __write_initial_superblock(struct dm_cache_metadata *cmd)
 {
        int r;
        struct dm_block *sblock;
-       size_t metadata_len;
        struct cache_disk_superblock *disk_super;
        sector_t bdev_size = i_size_read(cmd->bdev->bd_inode) >> SECTOR_SHIFT;
 
@@ -272,12 +298,16 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
        if (bdev_size > DM_CACHE_METADATA_MAX_SECTORS)
                bdev_size = DM_CACHE_METADATA_MAX_SECTORS;
 
-       r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
+       r = dm_tm_pre_commit(cmd->tm);
        if (r < 0)
                return r;
 
-       r = dm_tm_pre_commit(cmd->tm);
-       if (r < 0)
+       /*
+        * dm_sm_copy_root() can fail.  So we need to do it before we start
+        * updating the superblock.
+        */
+       r = __save_sm_root(cmd);
+       if (r)
                return r;
 
        r = superblock_lock_zero(cmd, &sblock);
@@ -293,16 +323,13 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
        memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
        disk_super->policy_hint_size = 0;
 
-       r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
-                           metadata_len);
-       if (r < 0)
-               goto bad_locked;
+       __copy_sm_root(cmd, disk_super);
 
        disk_super->mapping_root = cpu_to_le64(cmd->root);
        disk_super->hint_root = cpu_to_le64(cmd->hint_root);
        disk_super->discard_root = cpu_to_le64(cmd->discard_root);
        disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
-       disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
+       disk_super->discard_nr_blocks = cpu_to_le64(from_oblock(cmd->discard_nr_blocks));
        disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
        disk_super->data_block_size = cpu_to_le32(cmd->data_block_size);
        disk_super->cache_blocks = cpu_to_le32(0);
@@ -313,10 +340,6 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
        disk_super->write_misses = cpu_to_le32(0);
 
        return dm_tm_commit(cmd->tm, sblock);
-
-bad_locked:
-       dm_bm_unlock(sblock);
-       return r;
 }
 
 static int __format_metadata(struct dm_cache_metadata *cmd)
@@ -496,7 +519,7 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd,
        cmd->hint_root = le64_to_cpu(disk_super->hint_root);
        cmd->discard_root = le64_to_cpu(disk_super->discard_root);
        cmd->discard_block_size = le64_to_cpu(disk_super->discard_block_size);
-       cmd->discard_nr_blocks = to_dblock(le64_to_cpu(disk_super->discard_nr_blocks));
+       cmd->discard_nr_blocks = to_oblock(le64_to_cpu(disk_super->discard_nr_blocks));
        cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
        cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
        strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
@@ -530,8 +553,9 @@ static int __begin_transaction_flags(struct dm_cache_metadata *cmd,
        disk_super = dm_block_data(sblock);
        update_flags(disk_super, mutator);
        read_superblock_fields(cmd, disk_super);
+       dm_bm_unlock(sblock);
 
-       return dm_bm_flush_and_unlock(cmd->bm, sblock);
+       return dm_bm_flush(cmd->bm);
 }
 
 static int __begin_transaction(struct dm_cache_metadata *cmd)
@@ -559,7 +583,6 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
                                flags_mutator mutator)
 {
        int r;
-       size_t metadata_len;
        struct cache_disk_superblock *disk_super;
        struct dm_block *sblock;
 
@@ -577,8 +600,8 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
        if (r < 0)
                return r;
 
-       r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
-       if (r < 0)
+       r = __save_sm_root(cmd);
+       if (r)
                return r;
 
        r = superblock_lock(cmd, &sblock);
@@ -594,7 +617,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
        disk_super->hint_root = cpu_to_le64(cmd->hint_root);
        disk_super->discard_root = cpu_to_le64(cmd->discard_root);
        disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
-       disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
+       disk_super->discard_nr_blocks = cpu_to_le64(from_oblock(cmd->discard_nr_blocks));
        disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
        strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
        disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
@@ -605,13 +628,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
        disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
        disk_super->write_hits = cpu_to_le32(cmd->stats.write_hits);
        disk_super->write_misses = cpu_to_le32(cmd->stats.write_misses);
-
-       r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
-                           metadata_len);
-       if (r < 0) {
-               dm_bm_unlock(sblock);
-               return r;
-       }
+       __copy_sm_root(cmd, disk_super);
 
        return dm_tm_commit(cmd->tm, sblock);
 }
@@ -771,15 +788,15 @@ out:
 
 int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
                                   sector_t discard_block_size,
-                                  dm_dblock_t new_nr_entries)
+                                  dm_oblock_t new_nr_entries)
 {
        int r;
 
        down_write(&cmd->root_lock);
        r = dm_bitset_resize(&cmd->discard_info,
                             cmd->discard_root,
-                            from_dblock(cmd->discard_nr_blocks),
-                            from_dblock(new_nr_entries),
+                            from_oblock(cmd->discard_nr_blocks),
+                            from_oblock(new_nr_entries),
                             false, &cmd->discard_root);
        if (!r) {
                cmd->discard_block_size = discard_block_size;
@@ -792,28 +809,28 @@ int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
        return r;
 }
 
-static int __set_discard(struct dm_cache_metadata *cmd, dm_dblock_t b)
+static int __set_discard(struct dm_cache_metadata *cmd, dm_oblock_t b)
 {
        return dm_bitset_set_bit(&cmd->discard_info, cmd->discard_root,
-                                from_dblock(b), &cmd->discard_root);
+                                from_oblock(b), &cmd->discard_root);
 }
 
-static int __clear_discard(struct dm_cache_metadata *cmd, dm_dblock_t b)
+static int __clear_discard(struct dm_cache_metadata *cmd, dm_oblock_t b)
 {
        return dm_bitset_clear_bit(&cmd->discard_info, cmd->discard_root,
-                                  from_dblock(b), &cmd->discard_root);
+                                  from_oblock(b), &cmd->discard_root);
 }
 
-static int __is_discarded(struct dm_cache_metadata *cmd, dm_dblock_t b,
+static int __is_discarded(struct dm_cache_metadata *cmd, dm_oblock_t b,
                          bool *is_discarded)
 {
        return dm_bitset_test_bit(&cmd->discard_info, cmd->discard_root,
-                                 from_dblock(b), &cmd->discard_root,
+                                 from_oblock(b), &cmd->discard_root,
                                  is_discarded);
 }
 
 static int __discard(struct dm_cache_metadata *cmd,
-                    dm_dblock_t dblock, bool discard)
+                    dm_oblock_t dblock, bool discard)
 {
        int r;
 
@@ -826,7 +843,7 @@ static int __discard(struct dm_cache_metadata *cmd,
 }
 
 int dm_cache_set_discard(struct dm_cache_metadata *cmd,
-                        dm_dblock_t dblock, bool discard)
+                        dm_oblock_t dblock, bool discard)
 {
        int r;
 
@@ -844,8 +861,8 @@ static int __load_discards(struct dm_cache_metadata *cmd,
        dm_block_t b;
        bool discard;
 
-       for (b = 0; b < from_dblock(cmd->discard_nr_blocks); b++) {
-               dm_dblock_t dblock = to_dblock(b);
+       for (b = 0; b < from_oblock(cmd->discard_nr_blocks); b++) {
+               dm_oblock_t dblock = to_oblock(b);
 
                if (cmd->clean_when_opened) {
                        r = __is_discarded(cmd, dblock, &discard);
@@ -1228,22 +1245,12 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
        return 0;
 }
 
-int dm_cache_begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
+static int save_hint(void *context, dm_cblock_t cblock, dm_oblock_t oblock, uint32_t hint)
 {
+       struct dm_cache_metadata *cmd = context;
+       __le32 value = cpu_to_le32(hint);
        int r;
 
-       down_write(&cmd->root_lock);
-       r = begin_hints(cmd, policy);
-       up_write(&cmd->root_lock);
-
-       return r;
-}
-
-static int save_hint(struct dm_cache_metadata *cmd, dm_cblock_t cblock,
-                    uint32_t hint)
-{
-       int r;
-       __le32 value = cpu_to_le32(hint);
        __dm_bless_for_disk(&value);
 
        r = dm_array_set_value(&cmd->hint_info, cmd->hint_root,
@@ -1253,16 +1260,25 @@ static int save_hint(struct dm_cache_metadata *cmd, dm_cblock_t cblock,
        return r;
 }
 
-int dm_cache_save_hint(struct dm_cache_metadata *cmd, dm_cblock_t cblock,
-                      uint32_t hint)
+static int write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
 {
        int r;
 
-       if (!hints_array_initialized(cmd))
-               return 0;
+       r = begin_hints(cmd, policy);
+       if (r) {
+               DMERR("begin_hints failed");
+               return r;
+       }
+
+       return policy_walk_mappings(policy, save_hint, cmd);
+}
+
+int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
+{
+       int r;
 
        down_write(&cmd->root_lock);
-       r = save_hint(cmd, cblock, hint);
+       r = write_hints(cmd, policy);
        up_write(&cmd->root_lock);
 
        return r;
index cd906f14f98d46ed2a0358e4760975c3c6573a40..cd70a78623a336956a6366a4de1b2a912821dd9a 100644 (file)
@@ -72,14 +72,14 @@ dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd);
 
 int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
                                   sector_t discard_block_size,
-                                  dm_dblock_t new_nr_entries);
+                                  dm_oblock_t new_nr_entries);
 
 typedef int (*load_discard_fn)(void *context, sector_t discard_block_size,
-                              dm_dblock_t dblock, bool discarded);
+                              dm_oblock_t dblock, bool discarded);
 int dm_cache_load_discards(struct dm_cache_metadata *cmd,
                           load_discard_fn fn, void *context);
 
-int dm_cache_set_discard(struct dm_cache_metadata *cmd, dm_dblock_t dblock, bool discard);
+int dm_cache_set_discard(struct dm_cache_metadata *cmd, dm_oblock_t dblock, bool discard);
 
 int dm_cache_remove_mapping(struct dm_cache_metadata *cmd, dm_cblock_t cblock);
 int dm_cache_insert_mapping(struct dm_cache_metadata *cmd, dm_cblock_t cblock, dm_oblock_t oblock);
@@ -128,14 +128,7 @@ void dm_cache_dump(struct dm_cache_metadata *cmd);
  * rather than querying the policy for each cblock, we let it walk its data
  * structures and fill in the hints in whatever order it wishes.
  */
-
-int dm_cache_begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *p);
-
-/*
- * requests hints for every cblock and stores in the metadata device.
- */
-int dm_cache_save_hint(struct dm_cache_metadata *cmd,
-                      dm_cblock_t cblock, uint32_t hint);
+int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *p);
 
 /*
  * Query method.  Are all the blocks in the cache clean?
index 074b9c8e4cf0840dd0d64014776dc297c2d82da6..1bf4a71919ec73957a00550dec49b3a3b3a1292c 100644 (file)
@@ -237,9 +237,8 @@ struct cache {
        /*
         * origin_blocks entries, discarded if set.
         */
-       dm_dblock_t discard_nr_blocks;
+       dm_oblock_t discard_nr_blocks;
        unsigned long *discard_bitset;
-       uint32_t discard_block_size; /* a power of 2 times sectors per block */
 
        /*
         * Rather than reconstructing the table line for the status we just
@@ -526,48 +525,33 @@ static dm_block_t block_div(dm_block_t b, uint32_t n)
        return b;
 }
 
-static dm_dblock_t oblock_to_dblock(struct cache *cache, dm_oblock_t oblock)
-{
-       uint32_t discard_blocks = cache->discard_block_size;
-       dm_block_t b = from_oblock(oblock);
-
-       if (!block_size_is_power_of_two(cache))
-               discard_blocks = discard_blocks / cache->sectors_per_block;
-       else
-               discard_blocks >>= cache->sectors_per_block_shift;
-
-       b = block_div(b, discard_blocks);
-
-       return to_dblock(b);
-}
-
-static void set_discard(struct cache *cache, dm_dblock_t b)
+static void set_discard(struct cache *cache, dm_oblock_t b)
 {
        unsigned long flags;
 
        atomic_inc(&cache->stats.discard_count);
 
        spin_lock_irqsave(&cache->lock, flags);
-       set_bit(from_dblock(b), cache->discard_bitset);
+       set_bit(from_oblock(b), cache->discard_bitset);
        spin_unlock_irqrestore(&cache->lock, flags);
 }
 
-static void clear_discard(struct cache *cache, dm_dblock_t b)
+static void clear_discard(struct cache *cache, dm_oblock_t b)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&cache->lock, flags);
-       clear_bit(from_dblock(b), cache->discard_bitset);
+       clear_bit(from_oblock(b), cache->discard_bitset);
        spin_unlock_irqrestore(&cache->lock, flags);
 }
 
-static bool is_discarded(struct cache *cache, dm_dblock_t b)
+static bool is_discarded(struct cache *cache, dm_oblock_t b)
 {
        int r;
        unsigned long flags;
 
        spin_lock_irqsave(&cache->lock, flags);
-       r = test_bit(from_dblock(b), cache->discard_bitset);
+       r = test_bit(from_oblock(b), cache->discard_bitset);
        spin_unlock_irqrestore(&cache->lock, flags);
 
        return r;
@@ -579,8 +563,7 @@ static bool is_discarded_oblock(struct cache *cache, dm_oblock_t b)
        unsigned long flags;
 
        spin_lock_irqsave(&cache->lock, flags);
-       r = test_bit(from_dblock(oblock_to_dblock(cache, b)),
-                    cache->discard_bitset);
+       r = test_bit(from_oblock(b), cache->discard_bitset);
        spin_unlock_irqrestore(&cache->lock, flags);
 
        return r;
@@ -705,7 +688,7 @@ static void remap_to_origin_clear_discard(struct cache *cache, struct bio *bio,
        check_if_tick_bio_needed(cache, bio);
        remap_to_origin(cache, bio);
        if (bio_data_dir(bio) == WRITE)
-               clear_discard(cache, oblock_to_dblock(cache, oblock));
+               clear_discard(cache, oblock);
 }
 
 static void remap_to_cache_dirty(struct cache *cache, struct bio *bio,
@@ -715,7 +698,7 @@ static void remap_to_cache_dirty(struct cache *cache, struct bio *bio,
        remap_to_cache(cache, bio, cblock);
        if (bio_data_dir(bio) == WRITE) {
                set_dirty(cache, oblock, cblock);
-               clear_discard(cache, oblock_to_dblock(cache, oblock));
+               clear_discard(cache, oblock);
        }
 }
 
@@ -1288,14 +1271,14 @@ static void process_flush_bio(struct cache *cache, struct bio *bio)
 static void process_discard_bio(struct cache *cache, struct bio *bio)
 {
        dm_block_t start_block = dm_sector_div_up(bio->bi_iter.bi_sector,
-                                                 cache->discard_block_size);
+                                                 cache->sectors_per_block);
        dm_block_t end_block = bio_end_sector(bio);
        dm_block_t b;
 
-       end_block = block_div(end_block, cache->discard_block_size);
+       end_block = block_div(end_block, cache->sectors_per_block);
 
        for (b = start_block; b < end_block; b++)
-               set_discard(cache, to_dblock(b));
+               set_discard(cache, to_oblock(b));
 
        bio_endio(bio, 0);
 }
@@ -2171,35 +2154,6 @@ static int create_cache_policy(struct cache *cache, struct cache_args *ca,
        return 0;
 }
 
-/*
- * We want the discard block size to be a power of two, at least the size
- * of the cache block size, and have no more than 2^14 discard blocks
- * across the origin.
- */
-#define MAX_DISCARD_BLOCKS (1 << 14)
-
-static bool too_many_discard_blocks(sector_t discard_block_size,
-                                   sector_t origin_size)
-{
-       (void) sector_div(origin_size, discard_block_size);
-
-       return origin_size > MAX_DISCARD_BLOCKS;
-}
-
-static sector_t calculate_discard_block_size(sector_t cache_block_size,
-                                            sector_t origin_size)
-{
-       sector_t discard_block_size;
-
-       discard_block_size = roundup_pow_of_two(cache_block_size);
-
-       if (origin_size)
-               while (too_many_discard_blocks(discard_block_size, origin_size))
-                       discard_block_size *= 2;
-
-       return discard_block_size;
-}
-
 #define DEFAULT_MIGRATION_THRESHOLD 2048
 
 static int cache_create(struct cache_args *ca, struct cache **result)
@@ -2321,16 +2275,13 @@ static int cache_create(struct cache_args *ca, struct cache **result)
        }
        clear_bitset(cache->dirty_bitset, from_cblock(cache->cache_size));
 
-       cache->discard_block_size =
-               calculate_discard_block_size(cache->sectors_per_block,
-                                            cache->origin_sectors);
-       cache->discard_nr_blocks = oblock_to_dblock(cache, cache->origin_blocks);
-       cache->discard_bitset = alloc_bitset(from_dblock(cache->discard_nr_blocks));
+       cache->discard_nr_blocks = cache->origin_blocks;
+       cache->discard_bitset = alloc_bitset(from_oblock(cache->discard_nr_blocks));
        if (!cache->discard_bitset) {
                *error = "could not allocate discard bitset";
                goto bad;
        }
-       clear_bitset(cache->discard_bitset, from_dblock(cache->discard_nr_blocks));
+       clear_bitset(cache->discard_bitset, from_oblock(cache->discard_nr_blocks));
 
        cache->copier = dm_kcopyd_client_create(&dm_kcopyd_throttle);
        if (IS_ERR(cache->copier)) {
@@ -2614,16 +2565,16 @@ static int write_discard_bitset(struct cache *cache)
 {
        unsigned i, r;
 
-       r = dm_cache_discard_bitset_resize(cache->cmd, cache->discard_block_size,
-                                          cache->discard_nr_blocks);
+       r = dm_cache_discard_bitset_resize(cache->cmd, cache->sectors_per_block,
+                                          cache->origin_blocks);
        if (r) {
                DMERR("could not resize on-disk discard bitset");
                return r;
        }
 
-       for (i = 0; i < from_dblock(cache->discard_nr_blocks); i++) {
-               r = dm_cache_set_discard(cache->cmd, to_dblock(i),
-                                        is_discarded(cache, to_dblock(i)));
+       for (i = 0; i < from_oblock(cache->discard_nr_blocks); i++) {
+               r = dm_cache_set_discard(cache->cmd, to_oblock(i),
+                                        is_discarded(cache, to_oblock(i)));
                if (r)
                        return r;
        }
@@ -2631,30 +2582,6 @@ static int write_discard_bitset(struct cache *cache)
        return 0;
 }
 
-static int save_hint(void *context, dm_cblock_t cblock, dm_oblock_t oblock,
-                    uint32_t hint)
-{
-       struct cache *cache = context;
-       return dm_cache_save_hint(cache->cmd, cblock, hint);
-}
-
-static int write_hints(struct cache *cache)
-{
-       int r;
-
-       r = dm_cache_begin_hints(cache->cmd, cache->policy);
-       if (r) {
-               DMERR("dm_cache_begin_hints failed");
-               return r;
-       }
-
-       r = policy_walk_mappings(cache->policy, save_hint, cache);
-       if (r)
-               DMERR("policy_walk_mappings failed");
-
-       return r;
-}
-
 /*
  * returns true on success
  */
@@ -2672,7 +2599,7 @@ static bool sync_metadata(struct cache *cache)
 
        save_stats(cache);
 
-       r3 = write_hints(cache);
+       r3 = dm_cache_write_hints(cache->cmd, cache->policy);
        if (r3)
                DMERR("could not write hints");
 
@@ -2720,16 +2647,14 @@ static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
 }
 
 static int load_discard(void *context, sector_t discard_block_size,
-                       dm_dblock_t dblock, bool discard)
+                       dm_oblock_t oblock, bool discard)
 {
        struct cache *cache = context;
 
-       /* FIXME: handle mis-matched block size */
-
        if (discard)
-               set_discard(cache, dblock);
+               set_discard(cache, oblock);
        else
-               clear_discard(cache, dblock);
+               clear_discard(cache, oblock);
 
        return 0;
 }
@@ -3120,8 +3045,8 @@ static void set_discard_limits(struct cache *cache, struct queue_limits *limits)
        /*
         * FIXME: these limits may be incompatible with the cache device
         */
-       limits->max_discard_sectors = cache->discard_block_size * 1024;
-       limits->discard_granularity = cache->discard_block_size << SECTOR_SHIFT;
+       limits->max_discard_sectors = cache->sectors_per_block;
+       limits->discard_granularity = cache->sectors_per_block << SECTOR_SHIFT;
 }
 
 static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
@@ -3145,7 +3070,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
 static struct target_type cache_target = {
        .name = "cache",
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module = THIS_MODULE,
        .ctr = cache_ctr,
        .dtr = cache_dtr,
diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c
new file mode 100644 (file)
index 0000000..414dad4
--- /dev/null
@@ -0,0 +1,1746 @@
+#include "dm.h"
+#include "persistent-data/dm-transaction-manager.h"
+#include "persistent-data/dm-bitset.h"
+#include "persistent-data/dm-space-map.h"
+
+#include <linux/dm-io.h>
+#include <linux/dm-kcopyd.h>
+#include <linux/init.h>
+#include <linux/mempool.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#define DM_MSG_PREFIX "era"
+
+#define SUPERBLOCK_LOCATION 0
+#define SUPERBLOCK_MAGIC 2126579579
+#define SUPERBLOCK_CSUM_XOR 146538381
+#define MIN_ERA_VERSION 1
+#define MAX_ERA_VERSION 1
+#define INVALID_WRITESET_ROOT SUPERBLOCK_LOCATION
+#define MIN_BLOCK_SIZE 8
+
+/*----------------------------------------------------------------
+ * Writeset
+ *--------------------------------------------------------------*/
+struct writeset_metadata {
+       uint32_t nr_bits;
+       dm_block_t root;
+};
+
+struct writeset {
+       struct writeset_metadata md;
+
+       /*
+        * An in core copy of the bits to save constantly doing look ups on
+        * disk.
+        */
+       unsigned long *bits;
+};
+
+/*
+ * This does not free off the on disk bitset as this will normally be done
+ * after digesting into the era array.
+ */
+static void writeset_free(struct writeset *ws)
+{
+       vfree(ws->bits);
+}
+
+static int setup_on_disk_bitset(struct dm_disk_bitset *info,
+                               unsigned nr_bits, dm_block_t *root)
+{
+       int r;
+
+       r = dm_bitset_empty(info, root);
+       if (r)
+               return r;
+
+       return dm_bitset_resize(info, *root, 0, nr_bits, false, root);
+}
+
+static size_t bitset_size(unsigned nr_bits)
+{
+       return sizeof(unsigned long) * dm_div_up(nr_bits, BITS_PER_LONG);
+}
+
+/*
+ * Allocates memory for the in core bitset.
+ */
+static int writeset_alloc(struct writeset *ws, dm_block_t nr_blocks)
+{
+       ws->md.nr_bits = nr_blocks;
+       ws->md.root = INVALID_WRITESET_ROOT;
+       ws->bits = vzalloc(bitset_size(nr_blocks));
+       if (!ws->bits) {
+               DMERR("%s: couldn't allocate in memory bitset", __func__);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Wipes the in-core bitset, and creates a new on disk bitset.
+ */
+static int writeset_init(struct dm_disk_bitset *info, struct writeset *ws)
+{
+       int r;
+
+       memset(ws->bits, 0, bitset_size(ws->md.nr_bits));
+
+       r = setup_on_disk_bitset(info, ws->md.nr_bits, &ws->md.root);
+       if (r) {
+               DMERR("%s: setup_on_disk_bitset failed", __func__);
+               return r;
+       }
+
+       return 0;
+}
+
+static bool writeset_marked(struct writeset *ws, dm_block_t block)
+{
+       return test_bit(block, ws->bits);
+}
+
+static int writeset_marked_on_disk(struct dm_disk_bitset *info,
+                                  struct writeset_metadata *m, dm_block_t block,
+                                  bool *result)
+{
+       dm_block_t old = m->root;
+
+       /*
+        * The bitset was flushed when it was archived, so we know there'll
+        * be no change to the root.
+        */
+       int r = dm_bitset_test_bit(info, m->root, block, &m->root, result);
+       if (r) {
+               DMERR("%s: dm_bitset_test_bit failed", __func__);
+               return r;
+       }
+
+       BUG_ON(m->root != old);
+
+       return r;
+}
+
+/*
+ * Returns < 0 on error, 0 if the bit wasn't previously set, 1 if it was.
+ */
+static int writeset_test_and_set(struct dm_disk_bitset *info,
+                                struct writeset *ws, uint32_t block)
+{
+       int r;
+
+       if (!test_and_set_bit(block, ws->bits)) {
+               r = dm_bitset_set_bit(info, ws->md.root, block, &ws->md.root);
+               if (r) {
+                       /* FIXME: fail mode */
+                       return r;
+               }
+
+               return 0;
+       }
+
+       return 1;
+}
+
+/*----------------------------------------------------------------
+ * On disk metadata layout
+ *--------------------------------------------------------------*/
+#define SPACE_MAP_ROOT_SIZE 128
+#define UUID_LEN 16
+
+struct writeset_disk {
+       __le32 nr_bits;
+       __le64 root;
+} __packed;
+
+struct superblock_disk {
+       __le32 csum;
+       __le32 flags;
+       __le64 blocknr;
+
+       __u8 uuid[UUID_LEN];
+       __le64 magic;
+       __le32 version;
+
+       __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
+
+       __le32 data_block_size;
+       __le32 metadata_block_size;
+       __le32 nr_blocks;
+
+       __le32 current_era;
+       struct writeset_disk current_writeset;
+
+       /*
+        * Only these two fields are valid within the metadata snapshot.
+        */
+       __le64 writeset_tree_root;
+       __le64 era_array_root;
+
+       __le64 metadata_snap;
+} __packed;
+
+/*----------------------------------------------------------------
+ * Superblock validation
+ *--------------------------------------------------------------*/
+static void sb_prepare_for_write(struct dm_block_validator *v,
+                                struct dm_block *b,
+                                size_t sb_block_size)
+{
+       struct superblock_disk *disk = dm_block_data(b);
+
+       disk->blocknr = cpu_to_le64(dm_block_location(b));
+       disk->csum = cpu_to_le32(dm_bm_checksum(&disk->flags,
+                                               sb_block_size - sizeof(__le32),
+                                               SUPERBLOCK_CSUM_XOR));
+}
+
+static int check_metadata_version(struct superblock_disk *disk)
+{
+       uint32_t metadata_version = le32_to_cpu(disk->version);
+       if (metadata_version < MIN_ERA_VERSION || metadata_version > MAX_ERA_VERSION) {
+               DMERR("Era metadata version %u found, but only versions between %u and %u supported.",
+                     metadata_version, MIN_ERA_VERSION, MAX_ERA_VERSION);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int sb_check(struct dm_block_validator *v,
+                   struct dm_block *b,
+                   size_t sb_block_size)
+{
+       struct superblock_disk *disk = dm_block_data(b);
+       __le32 csum_le;
+
+       if (dm_block_location(b) != le64_to_cpu(disk->blocknr)) {
+               DMERR("sb_check failed: blocknr %llu: wanted %llu",
+                     le64_to_cpu(disk->blocknr),
+                     (unsigned long long)dm_block_location(b));
+               return -ENOTBLK;
+       }
+
+       if (le64_to_cpu(disk->magic) != SUPERBLOCK_MAGIC) {
+               DMERR("sb_check failed: magic %llu: wanted %llu",
+                     le64_to_cpu(disk->magic),
+                     (unsigned long long) SUPERBLOCK_MAGIC);
+               return -EILSEQ;
+       }
+
+       csum_le = cpu_to_le32(dm_bm_checksum(&disk->flags,
+                                            sb_block_size - sizeof(__le32),
+                                            SUPERBLOCK_CSUM_XOR));
+       if (csum_le != disk->csum) {
+               DMERR("sb_check failed: csum %u: wanted %u",
+                     le32_to_cpu(csum_le), le32_to_cpu(disk->csum));
+               return -EILSEQ;
+       }
+
+       return check_metadata_version(disk);
+}
+
+static struct dm_block_validator sb_validator = {
+       .name = "superblock",
+       .prepare_for_write = sb_prepare_for_write,
+       .check = sb_check
+};
+
+/*----------------------------------------------------------------
+ * Low level metadata handling
+ *--------------------------------------------------------------*/
+#define DM_ERA_METADATA_BLOCK_SIZE 4096
+#define DM_ERA_METADATA_CACHE_SIZE 64
+#define ERA_MAX_CONCURRENT_LOCKS 5
+
+struct era_metadata {
+       struct block_device *bdev;
+       struct dm_block_manager *bm;
+       struct dm_space_map *sm;
+       struct dm_transaction_manager *tm;
+
+       dm_block_t block_size;
+       uint32_t nr_blocks;
+
+       uint32_t current_era;
+
+       /*
+        * We preallocate 2 writesets.  When an era rolls over we
+        * switch between them. This means the allocation is done at
+        * preresume time, rather than on the io path.
+        */
+       struct writeset writesets[2];
+       struct writeset *current_writeset;
+
+       dm_block_t writeset_tree_root;
+       dm_block_t era_array_root;
+
+       struct dm_disk_bitset bitset_info;
+       struct dm_btree_info writeset_tree_info;
+       struct dm_array_info era_array_info;
+
+       dm_block_t metadata_snap;
+
+       /*
+        * A flag that is set whenever a writeset has been archived.
+        */
+       bool archived_writesets;
+
+       /*
+        * Reading the space map root can fail, so we read it into this
+        * buffer before the superblock is locked and updated.
+        */
+       __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
+};
+
+static int superblock_read_lock(struct era_metadata *md,
+                               struct dm_block **sblock)
+{
+       return dm_bm_read_lock(md->bm, SUPERBLOCK_LOCATION,
+                              &sb_validator, sblock);
+}
+
+static int superblock_lock_zero(struct era_metadata *md,
+                               struct dm_block **sblock)
+{
+       return dm_bm_write_lock_zero(md->bm, SUPERBLOCK_LOCATION,
+                                    &sb_validator, sblock);
+}
+
+static int superblock_lock(struct era_metadata *md,
+                          struct dm_block **sblock)
+{
+       return dm_bm_write_lock(md->bm, SUPERBLOCK_LOCATION,
+                               &sb_validator, sblock);
+}
+
+/* FIXME: duplication with cache and thin */
+static int superblock_all_zeroes(struct dm_block_manager *bm, bool *result)
+{
+       int r;
+       unsigned i;
+       struct dm_block *b;
+       __le64 *data_le, zero = cpu_to_le64(0);
+       unsigned sb_block_size = dm_bm_block_size(bm) / sizeof(__le64);
+
+       /*
+        * We can't use a validator here - it may be all zeroes.
+        */
+       r = dm_bm_read_lock(bm, SUPERBLOCK_LOCATION, NULL, &b);
+       if (r)
+               return r;
+
+       data_le = dm_block_data(b);
+       *result = true;
+       for (i = 0; i < sb_block_size; i++) {
+               if (data_le[i] != zero) {
+                       *result = false;
+                       break;
+               }
+       }
+
+       return dm_bm_unlock(b);
+}
+
+/*----------------------------------------------------------------*/
+
+static void ws_pack(const struct writeset_metadata *core, struct writeset_disk *disk)
+{
+       disk->nr_bits = cpu_to_le32(core->nr_bits);
+       disk->root = cpu_to_le64(core->root);
+}
+
+static void ws_unpack(const struct writeset_disk *disk, struct writeset_metadata *core)
+{
+       core->nr_bits = le32_to_cpu(disk->nr_bits);
+       core->root = le64_to_cpu(disk->root);
+}
+
+static void ws_inc(void *context, const void *value)
+{
+       struct era_metadata *md = context;
+       struct writeset_disk ws_d;
+       dm_block_t b;
+
+       memcpy(&ws_d, value, sizeof(ws_d));
+       b = le64_to_cpu(ws_d.root);
+
+       dm_tm_inc(md->tm, b);
+}
+
+static void ws_dec(void *context, const void *value)
+{
+       struct era_metadata *md = context;
+       struct writeset_disk ws_d;
+       dm_block_t b;
+
+       memcpy(&ws_d, value, sizeof(ws_d));
+       b = le64_to_cpu(ws_d.root);
+
+       dm_bitset_del(&md->bitset_info, b);
+}
+
+static int ws_eq(void *context, const void *value1, const void *value2)
+{
+       return !memcmp(value1, value2, sizeof(struct writeset_metadata));
+}
+
+/*----------------------------------------------------------------*/
+
+static void setup_writeset_tree_info(struct era_metadata *md)
+{
+       struct dm_btree_value_type *vt = &md->writeset_tree_info.value_type;
+       md->writeset_tree_info.tm = md->tm;
+       md->writeset_tree_info.levels = 1;
+       vt->context = md;
+       vt->size = sizeof(struct writeset_disk);
+       vt->inc = ws_inc;
+       vt->dec = ws_dec;
+       vt->equal = ws_eq;
+}
+
+static void setup_era_array_info(struct era_metadata *md)
+
+{
+       struct dm_btree_value_type vt;
+       vt.context = NULL;
+       vt.size = sizeof(__le32);
+       vt.inc = NULL;
+       vt.dec = NULL;
+       vt.equal = NULL;
+
+       dm_array_info_init(&md->era_array_info, md->tm, &vt);
+}
+
+static void setup_infos(struct era_metadata *md)
+{
+       dm_disk_bitset_init(md->tm, &md->bitset_info);
+       setup_writeset_tree_info(md);
+       setup_era_array_info(md);
+}
+
+/*----------------------------------------------------------------*/
+
+static int create_fresh_metadata(struct era_metadata *md)
+{
+       int r;
+
+       r = dm_tm_create_with_sm(md->bm, SUPERBLOCK_LOCATION,
+                                &md->tm, &md->sm);
+       if (r < 0) {
+               DMERR("dm_tm_create_with_sm failed");
+               return r;
+       }
+
+       setup_infos(md);
+
+       r = dm_btree_empty(&md->writeset_tree_info, &md->writeset_tree_root);
+       if (r) {
+               DMERR("couldn't create new writeset tree");
+               goto bad;
+       }
+
+       r = dm_array_empty(&md->era_array_info, &md->era_array_root);
+       if (r) {
+               DMERR("couldn't create era array");
+               goto bad;
+       }
+
+       return 0;
+
+bad:
+       dm_sm_destroy(md->sm);
+       dm_tm_destroy(md->tm);
+
+       return r;
+}
+
+static int save_sm_root(struct era_metadata *md)
+{
+       int r;
+       size_t metadata_len;
+
+       r = dm_sm_root_size(md->sm, &metadata_len);
+       if (r < 0)
+               return r;
+
+       return dm_sm_copy_root(md->sm, &md->metadata_space_map_root,
+                              metadata_len);
+}
+
+static void copy_sm_root(struct era_metadata *md, struct superblock_disk *disk)
+{
+       memcpy(&disk->metadata_space_map_root,
+              &md->metadata_space_map_root,
+              sizeof(md->metadata_space_map_root));
+}
+
+/*
+ * Writes a superblock, including the static fields that don't get updated
+ * with every commit (possible optimisation here).  'md' should be fully
+ * constructed when this is called.
+ */
+static void prepare_superblock(struct era_metadata *md, struct superblock_disk *disk)
+{
+       disk->magic = cpu_to_le64(SUPERBLOCK_MAGIC);
+       disk->flags = cpu_to_le32(0ul);
+
+       /* FIXME: can't keep blanking the uuid (uuid is currently unused though) */
+       memset(disk->uuid, 0, sizeof(disk->uuid));
+       disk->version = cpu_to_le32(MAX_ERA_VERSION);
+
+       copy_sm_root(md, disk);
+
+       disk->data_block_size = cpu_to_le32(md->block_size);
+       disk->metadata_block_size = cpu_to_le32(DM_ERA_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
+       disk->nr_blocks = cpu_to_le32(md->nr_blocks);
+       disk->current_era = cpu_to_le32(md->current_era);
+
+       ws_pack(&md->current_writeset->md, &disk->current_writeset);
+       disk->writeset_tree_root = cpu_to_le64(md->writeset_tree_root);
+       disk->era_array_root = cpu_to_le64(md->era_array_root);
+       disk->metadata_snap = cpu_to_le64(md->metadata_snap);
+}
+
+static int write_superblock(struct era_metadata *md)
+{
+       int r;
+       struct dm_block *sblock;
+       struct superblock_disk *disk;
+
+       r = save_sm_root(md);
+       if (r) {
+               DMERR("%s: save_sm_root failed", __func__);
+               return r;
+       }
+
+       r = superblock_lock_zero(md, &sblock);
+       if (r)
+               return r;
+
+       disk = dm_block_data(sblock);
+       prepare_superblock(md, disk);
+
+       return dm_tm_commit(md->tm, sblock);
+}
+
+/*
+ * Assumes block_size and the infos are set.
+ */
+static int format_metadata(struct era_metadata *md)
+{
+       int r;
+
+       r = create_fresh_metadata(md);
+       if (r)
+               return r;
+
+       r = write_superblock(md);
+       if (r) {
+               dm_sm_destroy(md->sm);
+               dm_tm_destroy(md->tm);
+               return r;
+       }
+
+       return 0;
+}
+
+static int open_metadata(struct era_metadata *md)
+{
+       int r;
+       struct dm_block *sblock;
+       struct superblock_disk *disk;
+
+       r = superblock_read_lock(md, &sblock);
+       if (r) {
+               DMERR("couldn't read_lock superblock");
+               return r;
+       }
+
+       disk = dm_block_data(sblock);
+       r = dm_tm_open_with_sm(md->bm, SUPERBLOCK_LOCATION,
+                              disk->metadata_space_map_root,
+                              sizeof(disk->metadata_space_map_root),
+                              &md->tm, &md->sm);
+       if (r) {
+               DMERR("dm_tm_open_with_sm failed");
+               goto bad;
+       }
+
+       setup_infos(md);
+
+       md->block_size = le32_to_cpu(disk->data_block_size);
+       md->nr_blocks = le32_to_cpu(disk->nr_blocks);
+       md->current_era = le32_to_cpu(disk->current_era);
+
+       md->writeset_tree_root = le64_to_cpu(disk->writeset_tree_root);
+       md->era_array_root = le64_to_cpu(disk->era_array_root);
+       md->metadata_snap = le64_to_cpu(disk->metadata_snap);
+       md->archived_writesets = true;
+
+       return dm_bm_unlock(sblock);
+
+bad:
+       dm_bm_unlock(sblock);
+       return r;
+}
+
+static int open_or_format_metadata(struct era_metadata *md,
+                                  bool may_format)
+{
+       int r;
+       bool unformatted = false;
+
+       r = superblock_all_zeroes(md->bm, &unformatted);
+       if (r)
+               return r;
+
+       if (unformatted)
+               return may_format ? format_metadata(md) : -EPERM;
+
+       return open_metadata(md);
+}
+
+static int create_persistent_data_objects(struct era_metadata *md,
+                                         bool may_format)
+{
+       int r;
+
+       md->bm = dm_block_manager_create(md->bdev, DM_ERA_METADATA_BLOCK_SIZE,
+                                        DM_ERA_METADATA_CACHE_SIZE,
+                                        ERA_MAX_CONCURRENT_LOCKS);
+       if (IS_ERR(md->bm)) {
+               DMERR("could not create block manager");
+               return PTR_ERR(md->bm);
+       }
+
+       r = open_or_format_metadata(md, may_format);
+       if (r)
+               dm_block_manager_destroy(md->bm);
+
+       return r;
+}
+
+static void destroy_persistent_data_objects(struct era_metadata *md)
+{
+       dm_sm_destroy(md->sm);
+       dm_tm_destroy(md->tm);
+       dm_block_manager_destroy(md->bm);
+}
+
+/*
+ * This waits until all era_map threads have picked up the new filter.
+ */
+static void swap_writeset(struct era_metadata *md, struct writeset *new_writeset)
+{
+       rcu_assign_pointer(md->current_writeset, new_writeset);
+       synchronize_rcu();
+}
+
+/*----------------------------------------------------------------
+ * Writesets get 'digested' into the main era array.
+ *
+ * We're using a coroutine here so the worker thread can do the digestion,
+ * thus avoiding synchronisation of the metadata.  Digesting a whole
+ * writeset in one go would cause too much latency.
+ *--------------------------------------------------------------*/
+struct digest {
+       uint32_t era;
+       unsigned nr_bits, current_bit;
+       struct writeset_metadata writeset;
+       __le32 value;
+       struct dm_disk_bitset info;
+
+       int (*step)(struct era_metadata *, struct digest *);
+};
+
+static int metadata_digest_lookup_writeset(struct era_metadata *md,
+                                          struct digest *d);
+
+static int metadata_digest_remove_writeset(struct era_metadata *md,
+                                          struct digest *d)
+{
+       int r;
+       uint64_t key = d->era;
+
+       r = dm_btree_remove(&md->writeset_tree_info, md->writeset_tree_root,
+                           &key, &md->writeset_tree_root);
+       if (r) {
+               DMERR("%s: dm_btree_remove failed", __func__);
+               return r;
+       }
+
+       d->step = metadata_digest_lookup_writeset;
+       return 0;
+}
+
+#define INSERTS_PER_STEP 100
+
+static int metadata_digest_transcribe_writeset(struct era_metadata *md,
+                                              struct digest *d)
+{
+       int r;
+       bool marked;
+       unsigned b, e = min(d->current_bit + INSERTS_PER_STEP, d->nr_bits);
+
+       for (b = d->current_bit; b < e; b++) {
+               r = writeset_marked_on_disk(&d->info, &d->writeset, b, &marked);
+               if (r) {
+                       DMERR("%s: writeset_marked_on_disk failed", __func__);
+                       return r;
+               }
+
+               if (!marked)
+                       continue;
+
+               __dm_bless_for_disk(&d->value);
+               r = dm_array_set_value(&md->era_array_info, md->era_array_root,
+                                      b, &d->value, &md->era_array_root);
+               if (r) {
+                       DMERR("%s: dm_array_set_value failed", __func__);
+                       return r;
+               }
+       }
+
+       if (b == d->nr_bits)
+               d->step = metadata_digest_remove_writeset;
+       else
+               d->current_bit = b;
+
+       return 0;
+}
+
+static int metadata_digest_lookup_writeset(struct era_metadata *md,
+                                          struct digest *d)
+{
+       int r;
+       uint64_t key;
+       struct writeset_disk disk;
+
+       r = dm_btree_find_lowest_key(&md->writeset_tree_info,
+                                    md->writeset_tree_root, &key);
+       if (r < 0)
+               return r;
+
+       d->era = key;
+
+       r = dm_btree_lookup(&md->writeset_tree_info,
+                           md->writeset_tree_root, &key, &disk);
+       if (r) {
+               if (r == -ENODATA) {
+                       d->step = NULL;
+                       return 0;
+               }
+
+               DMERR("%s: dm_btree_lookup failed", __func__);
+               return r;
+       }
+
+       ws_unpack(&disk, &d->writeset);
+       d->value = cpu_to_le32(key);
+
+       d->nr_bits = min(d->writeset.nr_bits, md->nr_blocks);
+       d->current_bit = 0;
+       d->step = metadata_digest_transcribe_writeset;
+
+       return 0;
+}
+
+static int metadata_digest_start(struct era_metadata *md, struct digest *d)
+{
+       if (d->step)
+               return 0;
+
+       memset(d, 0, sizeof(*d));
+
+       /*
+        * We initialise another bitset info to avoid any caching side
+        * effects with the previous one.
+        */
+       dm_disk_bitset_init(md->tm, &d->info);
+       d->step = metadata_digest_lookup_writeset;
+
+       return 0;
+}
+
+/*----------------------------------------------------------------
+ * High level metadata interface.  Target methods should use these, and not
+ * the lower level ones.
+ *--------------------------------------------------------------*/
+static struct era_metadata *metadata_open(struct block_device *bdev,
+                                         sector_t block_size,
+                                         bool may_format)
+{
+       int r;
+       struct era_metadata *md = kzalloc(sizeof(*md), GFP_KERNEL);
+
+       if (!md)
+               return NULL;
+
+       md->bdev = bdev;
+       md->block_size = block_size;
+
+       md->writesets[0].md.root = INVALID_WRITESET_ROOT;
+       md->writesets[1].md.root = INVALID_WRITESET_ROOT;
+       md->current_writeset = &md->writesets[0];
+
+       r = create_persistent_data_objects(md, may_format);
+       if (r) {
+               kfree(md);
+               return ERR_PTR(r);
+       }
+
+       return md;
+}
+
+static void metadata_close(struct era_metadata *md)
+{
+       destroy_persistent_data_objects(md);
+       kfree(md);
+}
+
+static bool valid_nr_blocks(dm_block_t n)
+{
+       /*
+        * dm_bitset restricts us to 2^32.  test_bit & co. restrict us
+        * further to 2^31 - 1
+        */
+       return n < (1ull << 31);
+}
+
+static int metadata_resize(struct era_metadata *md, void *arg)
+{
+       int r;
+       dm_block_t *new_size = arg;
+       __le32 value;
+
+       if (!valid_nr_blocks(*new_size)) {
+               DMERR("Invalid number of origin blocks %llu",
+                     (unsigned long long) *new_size);
+               return -EINVAL;
+       }
+
+       writeset_free(&md->writesets[0]);
+       writeset_free(&md->writesets[1]);
+
+       r = writeset_alloc(&md->writesets[0], *new_size);
+       if (r) {
+               DMERR("%s: writeset_alloc failed for writeset 0", __func__);
+               return r;
+       }
+
+       r = writeset_alloc(&md->writesets[1], *new_size);
+       if (r) {
+               DMERR("%s: writeset_alloc failed for writeset 1", __func__);
+               return r;
+       }
+
+       value = cpu_to_le32(0u);
+       __dm_bless_for_disk(&value);
+       r = dm_array_resize(&md->era_array_info, md->era_array_root,
+                           md->nr_blocks, *new_size,
+                           &value, &md->era_array_root);
+       if (r) {
+               DMERR("%s: dm_array_resize failed", __func__);
+               return r;
+       }
+
+       md->nr_blocks = *new_size;
+       return 0;
+}
+
+static int metadata_era_archive(struct era_metadata *md)
+{
+       int r;
+       uint64_t keys[1];
+       struct writeset_disk value;
+
+       r = dm_bitset_flush(&md->bitset_info, md->current_writeset->md.root,
+                           &md->current_writeset->md.root);
+       if (r) {
+               DMERR("%s: dm_bitset_flush failed", __func__);
+               return r;
+       }
+
+       ws_pack(&md->current_writeset->md, &value);
+       md->current_writeset->md.root = INVALID_WRITESET_ROOT;
+
+       keys[0] = md->current_era;
+       __dm_bless_for_disk(&value);
+       r = dm_btree_insert(&md->writeset_tree_info, md->writeset_tree_root,
+                           keys, &value, &md->writeset_tree_root);
+       if (r) {
+               DMERR("%s: couldn't insert writeset into btree", __func__);
+               /* FIXME: fail mode */
+               return r;
+       }
+
+       md->archived_writesets = true;
+
+       return 0;
+}
+
+static struct writeset *next_writeset(struct era_metadata *md)
+{
+       return (md->current_writeset == &md->writesets[0]) ?
+               &md->writesets[1] : &md->writesets[0];
+}
+
+static int metadata_new_era(struct era_metadata *md)
+{
+       int r;
+       struct writeset *new_writeset = next_writeset(md);
+
+       r = writeset_init(&md->bitset_info, new_writeset);
+       if (r) {
+               DMERR("%s: writeset_init failed", __func__);
+               return r;
+       }
+
+       swap_writeset(md, new_writeset);
+       md->current_era++;
+
+       return 0;
+}
+
+static int metadata_era_rollover(struct era_metadata *md)
+{
+       int r;
+
+       if (md->current_writeset->md.root != INVALID_WRITESET_ROOT) {
+               r = metadata_era_archive(md);
+               if (r) {
+                       DMERR("%s: metadata_archive_era failed", __func__);
+                       /* FIXME: fail mode? */
+                       return r;
+               }
+       }
+
+       r = metadata_new_era(md);
+       if (r) {
+               DMERR("%s: new era failed", __func__);
+               /* FIXME: fail mode */
+               return r;
+       }
+
+       return 0;
+}
+
+static bool metadata_current_marked(struct era_metadata *md, dm_block_t block)
+{
+       bool r;
+       struct writeset *ws;
+
+       rcu_read_lock();
+       ws = rcu_dereference(md->current_writeset);
+       r = writeset_marked(ws, block);
+       rcu_read_unlock();
+
+       return r;
+}
+
+static int metadata_commit(struct era_metadata *md)
+{
+       int r;
+       struct dm_block *sblock;
+
+       if (md->current_writeset->md.root != SUPERBLOCK_LOCATION) {
+               r = dm_bitset_flush(&md->bitset_info, md->current_writeset->md.root,
+                                   &md->current_writeset->md.root);
+               if (r) {
+                       DMERR("%s: bitset flush failed", __func__);
+                       return r;
+               }
+       }
+
+       r = save_sm_root(md);
+       if (r) {
+               DMERR("%s: save_sm_root failed", __func__);
+               return r;
+       }
+
+       r = dm_tm_pre_commit(md->tm);
+       if (r) {
+               DMERR("%s: pre commit failed", __func__);
+               return r;
+       }
+
+       r = superblock_lock(md, &sblock);
+       if (r) {
+               DMERR("%s: superblock lock failed", __func__);
+               return r;
+       }
+
+       prepare_superblock(md, dm_block_data(sblock));
+
+       return dm_tm_commit(md->tm, sblock);
+}
+
+static int metadata_checkpoint(struct era_metadata *md)
+{
+       /*
+        * For now we just rollover, but later I want to put a check in to
+        * avoid this if the filter is still pretty fresh.
+        */
+       return metadata_era_rollover(md);
+}
+
+/*
+ * Metadata snapshots allow userland to access era data.
+ */
+static int metadata_take_snap(struct era_metadata *md)
+{
+       int r, inc;
+       struct dm_block *clone;
+
+       if (md->metadata_snap != SUPERBLOCK_LOCATION) {
+               DMERR("%s: metadata snapshot already exists", __func__);
+               return -EINVAL;
+       }
+
+       r = metadata_era_rollover(md);
+       if (r) {
+               DMERR("%s: era rollover failed", __func__);
+               return r;
+       }
+
+       r = metadata_commit(md);
+       if (r) {
+               DMERR("%s: pre commit failed", __func__);
+               return r;
+       }
+
+       r = dm_sm_inc_block(md->sm, SUPERBLOCK_LOCATION);
+       if (r) {
+               DMERR("%s: couldn't increment superblock", __func__);
+               return r;
+       }
+
+       r = dm_tm_shadow_block(md->tm, SUPERBLOCK_LOCATION,
+                              &sb_validator, &clone, &inc);
+       if (r) {
+               DMERR("%s: couldn't shadow superblock", __func__);
+               dm_sm_dec_block(md->sm, SUPERBLOCK_LOCATION);
+               return r;
+       }
+       BUG_ON(!inc);
+
+       r = dm_sm_inc_block(md->sm, md->writeset_tree_root);
+       if (r) {
+               DMERR("%s: couldn't inc writeset tree root", __func__);
+               dm_tm_unlock(md->tm, clone);
+               return r;
+       }
+
+       r = dm_sm_inc_block(md->sm, md->era_array_root);
+       if (r) {
+               DMERR("%s: couldn't inc era tree root", __func__);
+               dm_sm_dec_block(md->sm, md->writeset_tree_root);
+               dm_tm_unlock(md->tm, clone);
+               return r;
+       }
+
+       md->metadata_snap = dm_block_location(clone);
+
+       r = dm_tm_unlock(md->tm, clone);
+       if (r) {
+               DMERR("%s: couldn't unlock clone", __func__);
+               md->metadata_snap = SUPERBLOCK_LOCATION;
+               return r;
+       }
+
+       return 0;
+}
+
+static int metadata_drop_snap(struct era_metadata *md)
+{
+       int r;
+       dm_block_t location;
+       struct dm_block *clone;
+       struct superblock_disk *disk;
+
+       if (md->metadata_snap == SUPERBLOCK_LOCATION) {
+               DMERR("%s: no snap to drop", __func__);
+               return -EINVAL;
+       }
+
+       r = dm_tm_read_lock(md->tm, md->metadata_snap, &sb_validator, &clone);
+       if (r) {
+               DMERR("%s: couldn't read lock superblock clone", __func__);
+               return r;
+       }
+
+       /*
+        * Whatever happens now we'll commit with no record of the metadata
+        * snap.
+        */
+       md->metadata_snap = SUPERBLOCK_LOCATION;
+
+       disk = dm_block_data(clone);
+       r = dm_btree_del(&md->writeset_tree_info,
+                        le64_to_cpu(disk->writeset_tree_root));
+       if (r) {
+               DMERR("%s: error deleting writeset tree clone", __func__);
+               dm_tm_unlock(md->tm, clone);
+               return r;
+       }
+
+       r = dm_array_del(&md->era_array_info, le64_to_cpu(disk->era_array_root));
+       if (r) {
+               DMERR("%s: error deleting era array clone", __func__);
+               dm_tm_unlock(md->tm, clone);
+               return r;
+       }
+
+       location = dm_block_location(clone);
+       dm_tm_unlock(md->tm, clone);
+
+       return dm_sm_dec_block(md->sm, location);
+}
+
+struct metadata_stats {
+       dm_block_t used;
+       dm_block_t total;
+       dm_block_t snap;
+       uint32_t era;
+};
+
+static int metadata_get_stats(struct era_metadata *md, void *ptr)
+{
+       int r;
+       struct metadata_stats *s = ptr;
+       dm_block_t nr_free, nr_total;
+
+       r = dm_sm_get_nr_free(md->sm, &nr_free);
+       if (r) {
+               DMERR("dm_sm_get_nr_free returned %d", r);
+               return r;
+       }
+
+       r = dm_sm_get_nr_blocks(md->sm, &nr_total);
+       if (r) {
+               DMERR("dm_pool_get_metadata_dev_size returned %d", r);
+               return r;
+       }
+
+       s->used = nr_total - nr_free;
+       s->total = nr_total;
+       s->snap = md->metadata_snap;
+       s->era = md->current_era;
+
+       return 0;
+}
+
+/*----------------------------------------------------------------*/
+
+struct era {
+       struct dm_target *ti;
+       struct dm_target_callbacks callbacks;
+
+       struct dm_dev *metadata_dev;
+       struct dm_dev *origin_dev;
+
+       dm_block_t nr_blocks;
+       uint32_t sectors_per_block;
+       int sectors_per_block_shift;
+       struct era_metadata *md;
+
+       struct workqueue_struct *wq;
+       struct work_struct worker;
+
+       spinlock_t deferred_lock;
+       struct bio_list deferred_bios;
+
+       spinlock_t rpc_lock;
+       struct list_head rpc_calls;
+
+       struct digest digest;
+       atomic_t suspended;
+};
+
+struct rpc {
+       struct list_head list;
+
+       int (*fn0)(struct era_metadata *);
+       int (*fn1)(struct era_metadata *, void *);
+       void *arg;
+       int result;
+
+       struct completion complete;
+};
+
+/*----------------------------------------------------------------
+ * Remapping.
+ *---------------------------------------------------------------*/
+static bool block_size_is_power_of_two(struct era *era)
+{
+       return era->sectors_per_block_shift >= 0;
+}
+
+static dm_block_t get_block(struct era *era, struct bio *bio)
+{
+       sector_t block_nr = bio->bi_iter.bi_sector;
+
+       if (!block_size_is_power_of_two(era))
+               (void) sector_div(block_nr, era->sectors_per_block);
+       else
+               block_nr >>= era->sectors_per_block_shift;
+
+       return block_nr;
+}
+
+static void remap_to_origin(struct era *era, struct bio *bio)
+{
+       bio->bi_bdev = era->origin_dev->bdev;
+}
+
+/*----------------------------------------------------------------
+ * Worker thread
+ *--------------------------------------------------------------*/
+static void wake_worker(struct era *era)
+{
+       if (!atomic_read(&era->suspended))
+               queue_work(era->wq, &era->worker);
+}
+
+static void process_old_eras(struct era *era)
+{
+       int r;
+
+       if (!era->digest.step)
+               return;
+
+       r = era->digest.step(era->md, &era->digest);
+       if (r < 0) {
+               DMERR("%s: digest step failed, stopping digestion", __func__);
+               era->digest.step = NULL;
+
+       } else if (era->digest.step)
+               wake_worker(era);
+}
+
+static void process_deferred_bios(struct era *era)
+{
+       int r;
+       struct bio_list deferred_bios, marked_bios;
+       struct bio *bio;
+       bool commit_needed = false;
+       bool failed = false;
+
+       bio_list_init(&deferred_bios);
+       bio_list_init(&marked_bios);
+
+       spin_lock(&era->deferred_lock);
+       bio_list_merge(&deferred_bios, &era->deferred_bios);
+       bio_list_init(&era->deferred_bios);
+       spin_unlock(&era->deferred_lock);
+
+       while ((bio = bio_list_pop(&deferred_bios))) {
+               r = writeset_test_and_set(&era->md->bitset_info,
+                                         era->md->current_writeset,
+                                         get_block(era, bio));
+               if (r < 0) {
+                       /*
+                        * This is bad news, we need to rollback.
+                        * FIXME: finish.
+                        */
+                       failed = true;
+
+               } else if (r == 0)
+                       commit_needed = true;
+
+               bio_list_add(&marked_bios, bio);
+       }
+
+       if (commit_needed) {
+               r = metadata_commit(era->md);
+               if (r)
+                       failed = true;
+       }
+
+       if (failed)
+               while ((bio = bio_list_pop(&marked_bios)))
+                       bio_io_error(bio);
+       else
+               while ((bio = bio_list_pop(&marked_bios)))
+                       generic_make_request(bio);
+}
+
+static void process_rpc_calls(struct era *era)
+{
+       int r;
+       bool need_commit = false;
+       struct list_head calls;
+       struct rpc *rpc, *tmp;
+
+       INIT_LIST_HEAD(&calls);
+       spin_lock(&era->rpc_lock);
+       list_splice_init(&era->rpc_calls, &calls);
+       spin_unlock(&era->rpc_lock);
+
+       list_for_each_entry_safe(rpc, tmp, &calls, list) {
+               rpc->result = rpc->fn0 ? rpc->fn0(era->md) : rpc->fn1(era->md, rpc->arg);
+               need_commit = true;
+       }
+
+       if (need_commit) {
+               r = metadata_commit(era->md);
+               if (r)
+                       list_for_each_entry_safe(rpc, tmp, &calls, list)
+                               rpc->result = r;
+       }
+
+       list_for_each_entry_safe(rpc, tmp, &calls, list)
+               complete(&rpc->complete);
+}
+
+static void kick_off_digest(struct era *era)
+{
+       if (era->md->archived_writesets) {
+               era->md->archived_writesets = false;
+               metadata_digest_start(era->md, &era->digest);
+       }
+}
+
+static void do_work(struct work_struct *ws)
+{
+       struct era *era = container_of(ws, struct era, worker);
+
+       kick_off_digest(era);
+       process_old_eras(era);
+       process_deferred_bios(era);
+       process_rpc_calls(era);
+}
+
+static void defer_bio(struct era *era, struct bio *bio)
+{
+       spin_lock(&era->deferred_lock);
+       bio_list_add(&era->deferred_bios, bio);
+       spin_unlock(&era->deferred_lock);
+
+       wake_worker(era);
+}
+
+/*
+ * Make an rpc call to the worker to change the metadata.
+ */
+static int perform_rpc(struct era *era, struct rpc *rpc)
+{
+       rpc->result = 0;
+       init_completion(&rpc->complete);
+
+       spin_lock(&era->rpc_lock);
+       list_add(&rpc->list, &era->rpc_calls);
+       spin_unlock(&era->rpc_lock);
+
+       wake_worker(era);
+       wait_for_completion(&rpc->complete);
+
+       return rpc->result;
+}
+
+static int in_worker0(struct era *era, int (*fn)(struct era_metadata *))
+{
+       struct rpc rpc;
+       rpc.fn0 = fn;
+       rpc.fn1 = NULL;
+
+       return perform_rpc(era, &rpc);
+}
+
+static int in_worker1(struct era *era,
+                     int (*fn)(struct era_metadata *, void *), void *arg)
+{
+       struct rpc rpc;
+       rpc.fn0 = NULL;
+       rpc.fn1 = fn;
+       rpc.arg = arg;
+
+       return perform_rpc(era, &rpc);
+}
+
+static void start_worker(struct era *era)
+{
+       atomic_set(&era->suspended, 0);
+}
+
+static void stop_worker(struct era *era)
+{
+       atomic_set(&era->suspended, 1);
+       flush_workqueue(era->wq);
+}
+
+/*----------------------------------------------------------------
+ * Target methods
+ *--------------------------------------------------------------*/
+static int dev_is_congested(struct dm_dev *dev, int bdi_bits)
+{
+       struct request_queue *q = bdev_get_queue(dev->bdev);
+       return bdi_congested(&q->backing_dev_info, bdi_bits);
+}
+
+static int era_is_congested(struct dm_target_callbacks *cb, int bdi_bits)
+{
+       struct era *era = container_of(cb, struct era, callbacks);
+       return dev_is_congested(era->origin_dev, bdi_bits);
+}
+
+static void era_destroy(struct era *era)
+{
+       metadata_close(era->md);
+
+       if (era->wq)
+               destroy_workqueue(era->wq);
+
+       if (era->origin_dev)
+               dm_put_device(era->ti, era->origin_dev);
+
+       if (era->metadata_dev)
+               dm_put_device(era->ti, era->metadata_dev);
+
+       kfree(era);
+}
+
+static dm_block_t calc_nr_blocks(struct era *era)
+{
+       return dm_sector_div_up(era->ti->len, era->sectors_per_block);
+}
+
+static bool valid_block_size(dm_block_t block_size)
+{
+       bool greater_than_zero = block_size > 0;
+       bool multiple_of_min_block_size = (block_size & (MIN_BLOCK_SIZE - 1)) == 0;
+
+       return greater_than_zero && multiple_of_min_block_size;
+}
+
+/*
+ * <metadata dev> <data dev> <data block size (sectors)>
+ */
+static int era_ctr(struct dm_target *ti, unsigned argc, char **argv)
+{
+       int r;
+       char dummy;
+       struct era *era;
+       struct era_metadata *md;
+
+       if (argc != 3) {
+               ti->error = "Invalid argument count";
+               return -EINVAL;
+       }
+
+       era = kzalloc(sizeof(*era), GFP_KERNEL);
+       if (!era) {
+               ti->error = "Error allocating era structure";
+               return -ENOMEM;
+       }
+
+       era->ti = ti;
+
+       r = dm_get_device(ti, argv[0], FMODE_READ | FMODE_WRITE, &era->metadata_dev);
+       if (r) {
+               ti->error = "Error opening metadata device";
+               era_destroy(era);
+               return -EINVAL;
+       }
+
+       r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &era->origin_dev);
+       if (r) {
+               ti->error = "Error opening data device";
+               era_destroy(era);
+               return -EINVAL;
+       }
+
+       r = sscanf(argv[2], "%u%c", &era->sectors_per_block, &dummy);
+       if (r != 1) {
+               ti->error = "Error parsing block size";
+               era_destroy(era);
+               return -EINVAL;
+       }
+
+       r = dm_set_target_max_io_len(ti, era->sectors_per_block);
+       if (r) {
+               ti->error = "could not set max io len";
+               era_destroy(era);
+               return -EINVAL;
+       }
+
+       if (!valid_block_size(era->sectors_per_block)) {
+               ti->error = "Invalid block size";
+               era_destroy(era);
+               return -EINVAL;
+       }
+       if (era->sectors_per_block & (era->sectors_per_block - 1))
+               era->sectors_per_block_shift = -1;
+       else
+               era->sectors_per_block_shift = __ffs(era->sectors_per_block);
+
+       md = metadata_open(era->metadata_dev->bdev, era->sectors_per_block, true);
+       if (IS_ERR(md)) {
+               ti->error = "Error reading metadata";
+               era_destroy(era);
+               return PTR_ERR(md);
+       }
+       era->md = md;
+
+       era->nr_blocks = calc_nr_blocks(era);
+
+       r = metadata_resize(era->md, &era->nr_blocks);
+       if (r) {
+               ti->error = "couldn't resize metadata";
+               era_destroy(era);
+               return -ENOMEM;
+       }
+
+       era->wq = alloc_ordered_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM);
+       if (!era->wq) {
+               ti->error = "could not create workqueue for metadata object";
+               era_destroy(era);
+               return -ENOMEM;
+       }
+       INIT_WORK(&era->worker, do_work);
+
+       spin_lock_init(&era->deferred_lock);
+       bio_list_init(&era->deferred_bios);
+
+       spin_lock_init(&era->rpc_lock);
+       INIT_LIST_HEAD(&era->rpc_calls);
+
+       ti->private = era;
+       ti->num_flush_bios = 1;
+       ti->flush_supported = true;
+
+       ti->num_discard_bios = 1;
+       ti->discards_supported = true;
+       era->callbacks.congested_fn = era_is_congested;
+       dm_table_add_target_callbacks(ti->table, &era->callbacks);
+
+       return 0;
+}
+
+static void era_dtr(struct dm_target *ti)
+{
+       era_destroy(ti->private);
+}
+
+static int era_map(struct dm_target *ti, struct bio *bio)
+{
+       struct era *era = ti->private;
+       dm_block_t block = get_block(era, bio);
+
+       /*
+        * All bios get remapped to the origin device.  We do this now, but
+        * it may not get issued until later.  Depending on whether the
+        * block is marked in this era.
+        */
+       remap_to_origin(era, bio);
+
+       /*
+        * REQ_FLUSH bios carry no data, so we're not interested in them.
+        */
+       if (!(bio->bi_rw & REQ_FLUSH) &&
+           (bio_data_dir(bio) == WRITE) &&
+           !metadata_current_marked(era->md, block)) {
+               defer_bio(era, bio);
+               return DM_MAPIO_SUBMITTED;
+       }
+
+       return DM_MAPIO_REMAPPED;
+}
+
+static void era_postsuspend(struct dm_target *ti)
+{
+       int r;
+       struct era *era = ti->private;
+
+       r = in_worker0(era, metadata_era_archive);
+       if (r) {
+               DMERR("%s: couldn't archive current era", __func__);
+               /* FIXME: fail mode */
+       }
+
+       stop_worker(era);
+}
+
+static int era_preresume(struct dm_target *ti)
+{
+       int r;
+       struct era *era = ti->private;
+       dm_block_t new_size = calc_nr_blocks(era);
+
+       if (era->nr_blocks != new_size) {
+               r = in_worker1(era, metadata_resize, &new_size);
+               if (r)
+                       return r;
+
+               era->nr_blocks = new_size;
+       }
+
+       start_worker(era);
+
+       r = in_worker0(era, metadata_new_era);
+       if (r) {
+               DMERR("%s: metadata_era_rollover failed", __func__);
+               return r;
+       }
+
+       return 0;
+}
+
+/*
+ * Status format:
+ *
+ * <metadata block size> <#used metadata blocks>/<#total metadata blocks>
+ * <current era> <held metadata root | '-'>
+ */
+static void era_status(struct dm_target *ti, status_type_t type,
+                      unsigned status_flags, char *result, unsigned maxlen)
+{
+       int r;
+       struct era *era = ti->private;
+       ssize_t sz = 0;
+       struct metadata_stats stats;
+       char buf[BDEVNAME_SIZE];
+
+       switch (type) {
+       case STATUSTYPE_INFO:
+               r = in_worker1(era, metadata_get_stats, &stats);
+               if (r)
+                       goto err;
+
+               DMEMIT("%u %llu/%llu %u",
+                      (unsigned) (DM_ERA_METADATA_BLOCK_SIZE >> SECTOR_SHIFT),
+                      (unsigned long long) stats.used,
+                      (unsigned long long) stats.total,
+                      (unsigned) stats.era);
+
+               if (stats.snap != SUPERBLOCK_LOCATION)
+                       DMEMIT(" %llu", stats.snap);
+               else
+                       DMEMIT(" -");
+               break;
+
+       case STATUSTYPE_TABLE:
+               format_dev_t(buf, era->metadata_dev->bdev->bd_dev);
+               DMEMIT("%s ", buf);
+               format_dev_t(buf, era->origin_dev->bdev->bd_dev);
+               DMEMIT("%s %u", buf, era->sectors_per_block);
+               break;
+       }
+
+       return;
+
+err:
+       DMEMIT("Error");
+}
+
+static int era_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+       struct era *era = ti->private;
+
+       if (argc != 1) {
+               DMERR("incorrect number of message arguments");
+               return -EINVAL;
+       }
+
+       if (!strcasecmp(argv[0], "checkpoint"))
+               return in_worker0(era, metadata_checkpoint);
+
+       if (!strcasecmp(argv[0], "take_metadata_snap"))
+               return in_worker0(era, metadata_take_snap);
+
+       if (!strcasecmp(argv[0], "drop_metadata_snap"))
+               return in_worker0(era, metadata_drop_snap);
+
+       DMERR("unsupported message '%s'", argv[0]);
+       return -EINVAL;
+}
+
+static sector_t get_dev_size(struct dm_dev *dev)
+{
+       return i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT;
+}
+
+static int era_iterate_devices(struct dm_target *ti,
+                              iterate_devices_callout_fn fn, void *data)
+{
+       struct era *era = ti->private;
+       return fn(ti, era->origin_dev, 0, get_dev_size(era->origin_dev), data);
+}
+
+static int era_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+                    struct bio_vec *biovec, int max_size)
+{
+       struct era *era = ti->private;
+       struct request_queue *q = bdev_get_queue(era->origin_dev->bdev);
+
+       if (!q->merge_bvec_fn)
+               return max_size;
+
+       bvm->bi_bdev = era->origin_dev->bdev;
+
+       return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
+}
+
+static void era_io_hints(struct dm_target *ti, struct queue_limits *limits)
+{
+       struct era *era = ti->private;
+       uint64_t io_opt_sectors = limits->io_opt >> SECTOR_SHIFT;
+
+       /*
+        * If the system-determined stacked limits are compatible with the
+        * era device's blocksize (io_opt is a factor) do not override them.
+        */
+       if (io_opt_sectors < era->sectors_per_block ||
+           do_div(io_opt_sectors, era->sectors_per_block)) {
+               blk_limits_io_min(limits, 0);
+               blk_limits_io_opt(limits, era->sectors_per_block << SECTOR_SHIFT);
+       }
+}
+
+/*----------------------------------------------------------------*/
+
+static struct target_type era_target = {
+       .name = "era",
+       .version = {1, 0, 0},
+       .module = THIS_MODULE,
+       .ctr = era_ctr,
+       .dtr = era_dtr,
+       .map = era_map,
+       .postsuspend = era_postsuspend,
+       .preresume = era_preresume,
+       .status = era_status,
+       .message = era_message,
+       .iterate_devices = era_iterate_devices,
+       .merge = era_merge,
+       .io_hints = era_io_hints
+};
+
+static int __init dm_era_init(void)
+{
+       int r;
+
+       r = dm_register_target(&era_target);
+       if (r) {
+               DMERR("era target registration failed: %d", r);
+               return r;
+       }
+
+       return 0;
+}
+
+static void __exit dm_era_exit(void)
+{
+       dm_unregister_target(&era_target);
+}
+
+module_init(dm_era_init);
+module_exit(dm_era_exit);
+
+MODULE_DESCRIPTION(DM_NAME " era target");
+MODULE_AUTHOR("Joe Thornber <ejt@redhat.com>");
+MODULE_LICENSE("GPL");
index 422a9fdeb53e641d97acec4793ab00747dde9b1d..aa009e86587189a20a4ccf4734ad9d999cb5701f 100644 (file)
@@ -93,10 +93,6 @@ struct multipath {
        unsigned pg_init_count;         /* Number of times pg_init called */
        unsigned pg_init_delay_msecs;   /* Number of msecs before pg_init retry */
 
-       unsigned queue_size;
-       struct work_struct process_queued_ios;
-       struct list_head queued_ios;
-
        struct work_struct trigger_event;
 
        /*
@@ -121,9 +117,9 @@ typedef int (*action_fn) (struct pgpath *pgpath);
 static struct kmem_cache *_mpio_cache;
 
 static struct workqueue_struct *kmultipathd, *kmpath_handlerd;
-static void process_queued_ios(struct work_struct *work);
 static void trigger_event(struct work_struct *work);
 static void activate_path(struct work_struct *work);
+static int __pgpath_busy(struct pgpath *pgpath);
 
 
 /*-----------------------------------------------
@@ -195,11 +191,9 @@ static struct multipath *alloc_multipath(struct dm_target *ti)
        m = kzalloc(sizeof(*m), GFP_KERNEL);
        if (m) {
                INIT_LIST_HEAD(&m->priority_groups);
-               INIT_LIST_HEAD(&m->queued_ios);
                spin_lock_init(&m->lock);
                m->queue_io = 1;
                m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT;
-               INIT_WORK(&m->process_queued_ios, process_queued_ios);
                INIT_WORK(&m->trigger_event, trigger_event);
                init_waitqueue_head(&m->pg_init_wait);
                mutex_init(&m->work_mutex);
@@ -256,13 +250,21 @@ static void clear_mapinfo(struct multipath *m, union map_info *info)
  * Path selection
  *-----------------------------------------------*/
 
-static void __pg_init_all_paths(struct multipath *m)
+static int __pg_init_all_paths(struct multipath *m)
 {
        struct pgpath *pgpath;
        unsigned long pg_init_delay = 0;
 
+       if (m->pg_init_in_progress || m->pg_init_disabled)
+               return 0;
+
        m->pg_init_count++;
        m->pg_init_required = 0;
+
+       /* Check here to reset pg_init_required */
+       if (!m->current_pg)
+               return 0;
+
        if (m->pg_init_delay_retry)
                pg_init_delay = msecs_to_jiffies(m->pg_init_delay_msecs != DM_PG_INIT_DELAY_DEFAULT ?
                                                 m->pg_init_delay_msecs : DM_PG_INIT_DELAY_MSECS);
@@ -274,6 +276,7 @@ static void __pg_init_all_paths(struct multipath *m)
                                       pg_init_delay))
                        m->pg_init_in_progress++;
        }
+       return m->pg_init_in_progress;
 }
 
 static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
@@ -365,19 +368,26 @@ failed:
  */
 static int __must_push_back(struct multipath *m)
 {
-       return (m->queue_if_no_path != m->saved_queue_if_no_path &&
-               dm_noflush_suspending(m->ti));
+       return (m->queue_if_no_path ||
+               (m->queue_if_no_path != m->saved_queue_if_no_path &&
+                dm_noflush_suspending(m->ti)));
 }
 
-static int map_io(struct multipath *m, struct request *clone,
-                 union map_info *map_context, unsigned was_queued)
+#define pg_ready(m) (!(m)->queue_io && !(m)->pg_init_required)
+
+/*
+ * Map cloned requests
+ */
+static int multipath_map(struct dm_target *ti, struct request *clone,
+                        union map_info *map_context)
 {
-       int r = DM_MAPIO_REMAPPED;
+       struct multipath *m = (struct multipath *) ti->private;
+       int r = DM_MAPIO_REQUEUE;
        size_t nr_bytes = blk_rq_bytes(clone);
        unsigned long flags;
        struct pgpath *pgpath;
        struct block_device *bdev;
-       struct dm_mpath_io *mpio = map_context->ptr;
+       struct dm_mpath_io *mpio;
 
        spin_lock_irqsave(&m->lock, flags);
 
@@ -388,38 +398,33 @@ static int map_io(struct multipath *m, struct request *clone,
 
        pgpath = m->current_pgpath;
 
-       if (was_queued)
-               m->queue_size--;
-
-       if (m->pg_init_required) {
-               if (!m->pg_init_in_progress)
-                       queue_work(kmultipathd, &m->process_queued_ios);
-               r = DM_MAPIO_REQUEUE;
-       } else if ((pgpath && m->queue_io) ||
-                  (!pgpath && m->queue_if_no_path)) {
-               /* Queue for the daemon to resubmit */
-               list_add_tail(&clone->queuelist, &m->queued_ios);
-               m->queue_size++;
-               if (!m->queue_io)
-                       queue_work(kmultipathd, &m->process_queued_ios);
-               pgpath = NULL;
-               r = DM_MAPIO_SUBMITTED;
-       } else if (pgpath) {
-               bdev = pgpath->path.dev->bdev;
-               clone->q = bdev_get_queue(bdev);
-               clone->rq_disk = bdev->bd_disk;
-       } else if (__must_push_back(m))
-               r = DM_MAPIO_REQUEUE;
-       else
-               r = -EIO;       /* Failed */
+       if (!pgpath) {
+               if (!__must_push_back(m))
+                       r = -EIO;       /* Failed */
+               goto out_unlock;
+       }
+       if (!pg_ready(m)) {
+               __pg_init_all_paths(m);
+               goto out_unlock;
+       }
+       if (set_mapinfo(m, map_context) < 0)
+               /* ENOMEM, requeue */
+               goto out_unlock;
 
+       bdev = pgpath->path.dev->bdev;
+       clone->q = bdev_get_queue(bdev);
+       clone->rq_disk = bdev->bd_disk;
+       clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
+       mpio = map_context->ptr;
        mpio->pgpath = pgpath;
        mpio->nr_bytes = nr_bytes;
-
-       if (r == DM_MAPIO_REMAPPED && pgpath->pg->ps.type->start_io)
-               pgpath->pg->ps.type->start_io(&pgpath->pg->ps, &pgpath->path,
+       if (pgpath->pg->ps.type->start_io)
+               pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
+                                             &pgpath->path,
                                              nr_bytes);
+       r = DM_MAPIO_REMAPPED;
 
+out_unlock:
        spin_unlock_irqrestore(&m->lock, flags);
 
        return r;
@@ -440,76 +445,14 @@ static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path,
        else
                m->saved_queue_if_no_path = queue_if_no_path;
        m->queue_if_no_path = queue_if_no_path;
-       if (!m->queue_if_no_path && m->queue_size)
-               queue_work(kmultipathd, &m->process_queued_ios);
+       if (!m->queue_if_no_path)
+               dm_table_run_md_queue_async(m->ti->table);
 
        spin_unlock_irqrestore(&m->lock, flags);
 
        return 0;
 }
 
-/*-----------------------------------------------------------------
- * The multipath daemon is responsible for resubmitting queued ios.
- *---------------------------------------------------------------*/
-
-static void dispatch_queued_ios(struct multipath *m)
-{
-       int r;
-       unsigned long flags;
-       union map_info *info;
-       struct request *clone, *n;
-       LIST_HEAD(cl);
-
-       spin_lock_irqsave(&m->lock, flags);
-       list_splice_init(&m->queued_ios, &cl);
-       spin_unlock_irqrestore(&m->lock, flags);
-
-       list_for_each_entry_safe(clone, n, &cl, queuelist) {
-               list_del_init(&clone->queuelist);
-
-               info = dm_get_rq_mapinfo(clone);
-
-               r = map_io(m, clone, info, 1);
-               if (r < 0) {
-                       clear_mapinfo(m, info);
-                       dm_kill_unmapped_request(clone, r);
-               } else if (r == DM_MAPIO_REMAPPED)
-                       dm_dispatch_request(clone);
-               else if (r == DM_MAPIO_REQUEUE) {
-                       clear_mapinfo(m, info);
-                       dm_requeue_unmapped_request(clone);
-               }
-       }
-}
-
-static void process_queued_ios(struct work_struct *work)
-{
-       struct multipath *m =
-               container_of(work, struct multipath, process_queued_ios);
-       struct pgpath *pgpath = NULL;
-       unsigned must_queue = 1;
-       unsigned long flags;
-
-       spin_lock_irqsave(&m->lock, flags);
-
-       if (!m->current_pgpath)
-               __choose_pgpath(m, 0);
-
-       pgpath = m->current_pgpath;
-
-       if ((pgpath && !m->queue_io) ||
-           (!pgpath && !m->queue_if_no_path))
-               must_queue = 0;
-
-       if (m->pg_init_required && !m->pg_init_in_progress && pgpath &&
-           !m->pg_init_disabled)
-               __pg_init_all_paths(m);
-
-       spin_unlock_irqrestore(&m->lock, flags);
-       if (!must_queue)
-               dispatch_queued_ios(m);
-}
-
 /*
  * An event is triggered whenever a path is taken out of use.
  * Includes path failure and PG bypass.
@@ -971,27 +914,6 @@ static void multipath_dtr(struct dm_target *ti)
        free_multipath(m);
 }
 
-/*
- * Map cloned requests
- */
-static int multipath_map(struct dm_target *ti, struct request *clone,
-                        union map_info *map_context)
-{
-       int r;
-       struct multipath *m = (struct multipath *) ti->private;
-
-       if (set_mapinfo(m, map_context) < 0)
-               /* ENOMEM, requeue */
-               return DM_MAPIO_REQUEUE;
-
-       clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
-       r = map_io(m, clone, map_context, 0);
-       if (r < 0 || r == DM_MAPIO_REQUEUE)
-               clear_mapinfo(m, map_context);
-
-       return r;
-}
-
 /*
  * Take a path out of use.
  */
@@ -1054,9 +976,9 @@ static int reinstate_path(struct pgpath *pgpath)
 
        pgpath->is_active = 1;
 
-       if (!m->nr_valid_paths++ && m->queue_size) {
+       if (!m->nr_valid_paths++) {
                m->current_pgpath = NULL;
-               queue_work(kmultipathd, &m->process_queued_ios);
+               dm_table_run_md_queue_async(m->ti->table);
        } else if (m->hw_handler_name && (m->current_pg == pgpath->pg)) {
                if (queue_work(kmpath_handlerd, &pgpath->activate_path.work))
                        m->pg_init_in_progress++;
@@ -1252,11 +1174,12 @@ static void pg_init_done(void *data, int errors)
                /* Activations of other paths are still on going */
                goto out;
 
-       if (!m->pg_init_required)
-               m->queue_io = 0;
-
-       m->pg_init_delay_retry = delay_retry;
-       queue_work(kmultipathd, &m->process_queued_ios);
+       if (m->pg_init_required) {
+               m->pg_init_delay_retry = delay_retry;
+               if (__pg_init_all_paths(m))
+                       goto out;
+       }
+       m->queue_io = 0;
 
        /*
         * Wake up any thread waiting to suspend.
@@ -1272,8 +1195,11 @@ static void activate_path(struct work_struct *work)
        struct pgpath *pgpath =
                container_of(work, struct pgpath, activate_path.work);
 
-       scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
-                               pg_init_done, pgpath);
+       if (pgpath->is_active)
+               scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
+                                pg_init_done, pgpath);
+       else
+               pg_init_done(pgpath, SCSI_DH_DEV_OFFLINED);
 }
 
 static int noretry_error(int error)
@@ -1433,7 +1359,7 @@ static void multipath_status(struct dm_target *ti, status_type_t type,
 
        /* Features */
        if (type == STATUSTYPE_INFO)
-               DMEMIT("2 %u %u ", m->queue_size, m->pg_init_count);
+               DMEMIT("2 %u %u ", m->queue_io, m->pg_init_count);
        else {
                DMEMIT("%u ", m->queue_if_no_path +
                              (m->pg_init_retries > 0) * 2 +
@@ -1552,7 +1478,7 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
        }
 
        if (argc != 2) {
-               DMWARN("Unrecognised multipath message received.");
+               DMWARN("Invalid multipath message arguments. Expected 2 arguments, got %d.", argc);
                goto out;
        }
 
@@ -1570,7 +1496,7 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
        else if (!strcasecmp(argv[0], "fail_path"))
                action = fail_path;
        else {
-               DMWARN("Unrecognised multipath message received.");
+               DMWARN("Unrecognised multipath message received: %s", argv[0]);
                goto out;
        }
 
@@ -1632,8 +1558,17 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
                        r = err;
        }
 
-       if (r == -ENOTCONN && !fatal_signal_pending(current))
-               queue_work(kmultipathd, &m->process_queued_ios);
+       if (r == -ENOTCONN && !fatal_signal_pending(current)) {
+               spin_lock_irqsave(&m->lock, flags);
+               if (!m->current_pg) {
+                       /* Path status changed, redo selection */
+                       __choose_pgpath(m, 0);
+               }
+               if (m->pg_init_required)
+                       __pg_init_all_paths(m);
+               spin_unlock_irqrestore(&m->lock, flags);
+               dm_table_run_md_queue_async(m->ti->table);
+       }
 
        return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 }
@@ -1684,7 +1619,7 @@ static int multipath_busy(struct dm_target *ti)
        spin_lock_irqsave(&m->lock, flags);
 
        /* pg_init in progress, requeue until done */
-       if (m->pg_init_in_progress) {
+       if (!pg_ready(m)) {
                busy = 1;
                goto out;
        }
@@ -1737,7 +1672,7 @@ out:
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
        .name = "multipath",
-       .version = {1, 6, 0},
+       .version = {1, 7, 0},
        .module = THIS_MODULE,
        .ctr = multipath_ctr,
        .dtr = multipath_dtr,
index 6a7f2b83a1263f4c4ca6bc33b4a22fd5893bf445..50601ec7017acd3e310abedc9bb6c8ba45525344 100644 (file)
@@ -945,7 +945,7 @@ bool dm_table_request_based(struct dm_table *t)
        return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED;
 }
 
-int dm_table_alloc_md_mempools(struct dm_table *t)
+static int dm_table_alloc_md_mempools(struct dm_table *t)
 {
        unsigned type = dm_table_get_type(t);
        unsigned per_bio_data_size = 0;
@@ -1618,6 +1618,25 @@ struct mapped_device *dm_table_get_md(struct dm_table *t)
 }
 EXPORT_SYMBOL(dm_table_get_md);
 
+void dm_table_run_md_queue_async(struct dm_table *t)
+{
+       struct mapped_device *md;
+       struct request_queue *queue;
+       unsigned long flags;
+
+       if (!dm_table_request_based(t))
+               return;
+
+       md = dm_table_get_md(t);
+       queue = dm_get_md_queue(md);
+       if (queue) {
+               spin_lock_irqsave(queue->queue_lock, flags);
+               blk_run_queue_async(queue);
+               spin_unlock_irqrestore(queue->queue_lock, flags);
+       }
+}
+EXPORT_SYMBOL(dm_table_run_md_queue_async);
+
 static int device_discard_capable(struct dm_target *ti, struct dm_dev *dev,
                                  sector_t start, sector_t len, void *data)
 {
index fb9efc829182d4cce55c9c8cfac1e850e65abe79..b086a945edcbccc5106f267aa06109420c69cbd1 100644 (file)
@@ -192,6 +192,13 @@ struct dm_pool_metadata {
         * operation possible in this state is the closing of the device.
         */
        bool fail_io:1;
+
+       /*
+        * Reading the space map roots can fail, so we read it into these
+        * buffers before the superblock is locked and updated.
+        */
+       __u8 data_space_map_root[SPACE_MAP_ROOT_SIZE];
+       __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
 };
 
 struct dm_thin_device {
@@ -431,26 +438,53 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd)
        pmd->details_info.value_type.equal = NULL;
 }
 
+static int save_sm_roots(struct dm_pool_metadata *pmd)
+{
+       int r;
+       size_t len;
+
+       r = dm_sm_root_size(pmd->metadata_sm, &len);
+       if (r < 0)
+               return r;
+
+       r = dm_sm_copy_root(pmd->metadata_sm, &pmd->metadata_space_map_root, len);
+       if (r < 0)
+               return r;
+
+       r = dm_sm_root_size(pmd->data_sm, &len);
+       if (r < 0)
+               return r;
+
+       return dm_sm_copy_root(pmd->data_sm, &pmd->data_space_map_root, len);
+}
+
+static void copy_sm_roots(struct dm_pool_metadata *pmd,
+                         struct thin_disk_superblock *disk)
+{
+       memcpy(&disk->metadata_space_map_root,
+              &pmd->metadata_space_map_root,
+              sizeof(pmd->metadata_space_map_root));
+
+       memcpy(&disk->data_space_map_root,
+              &pmd->data_space_map_root,
+              sizeof(pmd->data_space_map_root));
+}
+
 static int __write_initial_superblock(struct dm_pool_metadata *pmd)
 {
        int r;
        struct dm_block *sblock;
-       size_t metadata_len, data_len;
        struct thin_disk_superblock *disk_super;
        sector_t bdev_size = i_size_read(pmd->bdev->bd_inode) >> SECTOR_SHIFT;
 
        if (bdev_size > THIN_METADATA_MAX_SECTORS)
                bdev_size = THIN_METADATA_MAX_SECTORS;
 
-       r = dm_sm_root_size(pmd->metadata_sm, &metadata_len);
-       if (r < 0)
-               return r;
-
-       r = dm_sm_root_size(pmd->data_sm, &data_len);
+       r = dm_sm_commit(pmd->data_sm);
        if (r < 0)
                return r;
 
-       r = dm_sm_commit(pmd->data_sm);
+       r = save_sm_roots(pmd);
        if (r < 0)
                return r;
 
@@ -471,15 +505,7 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
        disk_super->trans_id = 0;
        disk_super->held_root = 0;
 
-       r = dm_sm_copy_root(pmd->metadata_sm, &disk_super->metadata_space_map_root,
-                           metadata_len);
-       if (r < 0)
-               goto bad_locked;
-
-       r = dm_sm_copy_root(pmd->data_sm, &disk_super->data_space_map_root,
-                           data_len);
-       if (r < 0)
-               goto bad_locked;
+       copy_sm_roots(pmd, disk_super);
 
        disk_super->data_mapping_root = cpu_to_le64(pmd->root);
        disk_super->device_details_root = cpu_to_le64(pmd->details_root);
@@ -488,10 +514,6 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
        disk_super->data_block_size = cpu_to_le32(pmd->data_block_size);
 
        return dm_tm_commit(pmd->tm, sblock);
-
-bad_locked:
-       dm_bm_unlock(sblock);
-       return r;
 }
 
 static int __format_metadata(struct dm_pool_metadata *pmd)
@@ -769,6 +791,10 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
        if (r < 0)
                return r;
 
+       r = save_sm_roots(pmd);
+       if (r < 0)
+               return r;
+
        r = superblock_lock(pmd, &sblock);
        if (r)
                return r;
@@ -780,21 +806,9 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
        disk_super->trans_id = cpu_to_le64(pmd->trans_id);
        disk_super->flags = cpu_to_le32(pmd->flags);
 
-       r = dm_sm_copy_root(pmd->metadata_sm, &disk_super->metadata_space_map_root,
-                           metadata_len);
-       if (r < 0)
-               goto out_locked;
-
-       r = dm_sm_copy_root(pmd->data_sm, &disk_super->data_space_map_root,
-                           data_len);
-       if (r < 0)
-               goto out_locked;
+       copy_sm_roots(pmd, disk_super);
 
        return dm_tm_commit(pmd->tm, sblock);
-
-out_locked:
-       dm_bm_unlock(sblock);
-       return r;
 }
 
 struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
index be70d38745f7a7f5da51bd4ba83a29afe851b238..53728be84dee35ac8dfabbf48087919841049f1a 100644 (file)
 #include <linux/dm-io.h>
 #include <linux/dm-kcopyd.h>
 #include <linux/list.h>
+#include <linux/rculist.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/rbtree.h>
 
 #define        DM_MSG_PREFIX   "thin"
 
@@ -178,12 +180,10 @@ struct pool {
        unsigned ref_count;
 
        spinlock_t lock;
-       struct bio_list deferred_bios;
        struct bio_list deferred_flush_bios;
        struct list_head prepared_mappings;
        struct list_head prepared_discards;
-
-       struct bio_list retry_on_resume_list;
+       struct list_head active_thins;
 
        struct dm_deferred_set *shared_read_ds;
        struct dm_deferred_set *all_io_ds;
@@ -220,6 +220,7 @@ struct pool_c {
  * Target context for a thin.
  */
 struct thin_c {
+       struct list_head list;
        struct dm_dev *pool_dev;
        struct dm_dev *origin_dev;
        dm_thin_id dev_id;
@@ -227,6 +228,10 @@ struct thin_c {
        struct pool *pool;
        struct dm_thin_device *td;
        bool requeue_mode:1;
+       spinlock_t lock;
+       struct bio_list deferred_bio_list;
+       struct bio_list retry_on_resume_list;
+       struct rb_root sort_bio_list; /* sorted list of deferred bios */
 };
 
 /*----------------------------------------------------------------*/
@@ -287,9 +292,9 @@ static void cell_defer_no_holder_no_free(struct thin_c *tc,
        struct pool *pool = tc->pool;
        unsigned long flags;
 
-       spin_lock_irqsave(&pool->lock, flags);
-       dm_cell_release_no_holder(pool->prison, cell, &pool->deferred_bios);
-       spin_unlock_irqrestore(&pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
+       dm_cell_release_no_holder(pool->prison, cell, &tc->deferred_bio_list);
+       spin_unlock_irqrestore(&tc->lock, flags);
 
        wake_worker(pool);
 }
@@ -368,6 +373,7 @@ struct dm_thin_endio_hook {
        struct dm_deferred_entry *shared_read_entry;
        struct dm_deferred_entry *all_io_entry;
        struct dm_thin_new_mapping *overwrite_mapping;
+       struct rb_node rb_node;
 };
 
 static void requeue_bio_list(struct thin_c *tc, struct bio_list *master)
@@ -378,30 +384,22 @@ static void requeue_bio_list(struct thin_c *tc, struct bio_list *master)
 
        bio_list_init(&bios);
 
-       spin_lock_irqsave(&tc->pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
        bio_list_merge(&bios, master);
        bio_list_init(master);
-       spin_unlock_irqrestore(&tc->pool->lock, flags);
+       spin_unlock_irqrestore(&tc->lock, flags);
 
-       while ((bio = bio_list_pop(&bios))) {
-               struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
-
-               if (h->tc == tc)
-                       bio_endio(bio, DM_ENDIO_REQUEUE);
-               else
-                       bio_list_add(master, bio);
-       }
+       while ((bio = bio_list_pop(&bios)))
+               bio_endio(bio, DM_ENDIO_REQUEUE);
 }
 
 static void requeue_io(struct thin_c *tc)
 {
-       struct pool *pool = tc->pool;
-
-       requeue_bio_list(tc, &pool->deferred_bios);
-       requeue_bio_list(tc, &pool->retry_on_resume_list);
+       requeue_bio_list(tc, &tc->deferred_bio_list);
+       requeue_bio_list(tc, &tc->retry_on_resume_list);
 }
 
-static void error_retry_list(struct pool *pool)
+static void error_thin_retry_list(struct thin_c *tc)
 {
        struct bio *bio;
        unsigned long flags;
@@ -409,15 +407,25 @@ static void error_retry_list(struct pool *pool)
 
        bio_list_init(&bios);
 
-       spin_lock_irqsave(&pool->lock, flags);
-       bio_list_merge(&bios, &pool->retry_on_resume_list);
-       bio_list_init(&pool->retry_on_resume_list);
-       spin_unlock_irqrestore(&pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
+       bio_list_merge(&bios, &tc->retry_on_resume_list);
+       bio_list_init(&tc->retry_on_resume_list);
+       spin_unlock_irqrestore(&tc->lock, flags);
 
        while ((bio = bio_list_pop(&bios)))
                bio_io_error(bio);
 }
 
+static void error_retry_list(struct pool *pool)
+{
+       struct thin_c *tc;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(tc, &pool->active_thins, list)
+               error_thin_retry_list(tc);
+       rcu_read_unlock();
+}
+
 /*
  * This section of code contains the logic for processing a thin device's IO.
  * Much of the code depends on pool object resources (lists, workqueues, etc)
@@ -608,9 +616,9 @@ static void cell_defer(struct thin_c *tc, struct dm_bio_prison_cell *cell)
        struct pool *pool = tc->pool;
        unsigned long flags;
 
-       spin_lock_irqsave(&pool->lock, flags);
-       cell_release(pool, cell, &pool->deferred_bios);
-       spin_unlock_irqrestore(&tc->pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
+       cell_release(pool, cell, &tc->deferred_bio_list);
+       spin_unlock_irqrestore(&tc->lock, flags);
 
        wake_worker(pool);
 }
@@ -623,9 +631,9 @@ static void cell_defer_no_holder(struct thin_c *tc, struct dm_bio_prison_cell *c
        struct pool *pool = tc->pool;
        unsigned long flags;
 
-       spin_lock_irqsave(&pool->lock, flags);
-       cell_release_no_holder(pool, cell, &pool->deferred_bios);
-       spin_unlock_irqrestore(&pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
+       cell_release_no_holder(pool, cell, &tc->deferred_bio_list);
+       spin_unlock_irqrestore(&tc->lock, flags);
 
        wake_worker(pool);
 }
@@ -1001,12 +1009,11 @@ static void retry_on_resume(struct bio *bio)
 {
        struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
        struct thin_c *tc = h->tc;
-       struct pool *pool = tc->pool;
        unsigned long flags;
 
-       spin_lock_irqsave(&pool->lock, flags);
-       bio_list_add(&pool->retry_on_resume_list, bio);
-       spin_unlock_irqrestore(&pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
+       bio_list_add(&tc->retry_on_resume_list, bio);
+       spin_unlock_irqrestore(&tc->lock, flags);
 }
 
 static bool should_error_unserviceable_bio(struct pool *pool)
@@ -1363,38 +1370,111 @@ static int need_commit_due_to_time(struct pool *pool)
               jiffies > pool->last_commit_jiffies + COMMIT_PERIOD;
 }
 
-static void process_deferred_bios(struct pool *pool)
+#define thin_pbd(node) rb_entry((node), struct dm_thin_endio_hook, rb_node)
+#define thin_bio(pbd) dm_bio_from_per_bio_data((pbd), sizeof(struct dm_thin_endio_hook))
+
+static void __thin_bio_rb_add(struct thin_c *tc, struct bio *bio)
+{
+       struct rb_node **rbp, *parent;
+       struct dm_thin_endio_hook *pbd;
+       sector_t bi_sector = bio->bi_iter.bi_sector;
+
+       rbp = &tc->sort_bio_list.rb_node;
+       parent = NULL;
+       while (*rbp) {
+               parent = *rbp;
+               pbd = thin_pbd(parent);
+
+               if (bi_sector < thin_bio(pbd)->bi_iter.bi_sector)
+                       rbp = &(*rbp)->rb_left;
+               else
+                       rbp = &(*rbp)->rb_right;
+       }
+
+       pbd = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
+       rb_link_node(&pbd->rb_node, parent, rbp);
+       rb_insert_color(&pbd->rb_node, &tc->sort_bio_list);
+}
+
+static void __extract_sorted_bios(struct thin_c *tc)
+{
+       struct rb_node *node;
+       struct dm_thin_endio_hook *pbd;
+       struct bio *bio;
+
+       for (node = rb_first(&tc->sort_bio_list); node; node = rb_next(node)) {
+               pbd = thin_pbd(node);
+               bio = thin_bio(pbd);
+
+               bio_list_add(&tc->deferred_bio_list, bio);
+               rb_erase(&pbd->rb_node, &tc->sort_bio_list);
+       }
+
+       WARN_ON(!RB_EMPTY_ROOT(&tc->sort_bio_list));
+}
+
+static void __sort_thin_deferred_bios(struct thin_c *tc)
+{
+       struct bio *bio;
+       struct bio_list bios;
+
+       bio_list_init(&bios);
+       bio_list_merge(&bios, &tc->deferred_bio_list);
+       bio_list_init(&tc->deferred_bio_list);
+
+       /* Sort deferred_bio_list using rb-tree */
+       while ((bio = bio_list_pop(&bios)))
+               __thin_bio_rb_add(tc, bio);
+
+       /*
+        * Transfer the sorted bios in sort_bio_list back to
+        * deferred_bio_list to allow lockless submission of
+        * all bios.
+        */
+       __extract_sorted_bios(tc);
+}
+
+static void process_thin_deferred_bios(struct thin_c *tc)
 {
+       struct pool *pool = tc->pool;
        unsigned long flags;
        struct bio *bio;
        struct bio_list bios;
+       struct blk_plug plug;
+
+       if (tc->requeue_mode) {
+               requeue_bio_list(tc, &tc->deferred_bio_list);
+               return;
+       }
 
        bio_list_init(&bios);
 
-       spin_lock_irqsave(&pool->lock, flags);
-       bio_list_merge(&bios, &pool->deferred_bios);
-       bio_list_init(&pool->deferred_bios);
-       spin_unlock_irqrestore(&pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
 
-       while ((bio = bio_list_pop(&bios))) {
-               struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
-               struct thin_c *tc = h->tc;
+       if (bio_list_empty(&tc->deferred_bio_list)) {
+               spin_unlock_irqrestore(&tc->lock, flags);
+               return;
+       }
 
-               if (tc->requeue_mode) {
-                       bio_endio(bio, DM_ENDIO_REQUEUE);
-                       continue;
-               }
+       __sort_thin_deferred_bios(tc);
+
+       bio_list_merge(&bios, &tc->deferred_bio_list);
+       bio_list_init(&tc->deferred_bio_list);
 
+       spin_unlock_irqrestore(&tc->lock, flags);
+
+       blk_start_plug(&plug);
+       while ((bio = bio_list_pop(&bios))) {
                /*
                 * If we've got no free new_mapping structs, and processing
                 * this bio might require one, we pause until there are some
                 * prepared mappings to process.
                 */
                if (ensure_next_mapping(pool)) {
-                       spin_lock_irqsave(&pool->lock, flags);
-                       bio_list_merge(&pool->deferred_bios, &bios);
-                       spin_unlock_irqrestore(&pool->lock, flags);
-
+                       spin_lock_irqsave(&tc->lock, flags);
+                       bio_list_add(&tc->deferred_bio_list, bio);
+                       bio_list_merge(&tc->deferred_bio_list, &bios);
+                       spin_unlock_irqrestore(&tc->lock, flags);
                        break;
                }
 
@@ -1403,6 +1483,20 @@ static void process_deferred_bios(struct pool *pool)
                else
                        pool->process_bio(tc, bio);
        }
+       blk_finish_plug(&plug);
+}
+
+static void process_deferred_bios(struct pool *pool)
+{
+       unsigned long flags;
+       struct bio *bio;
+       struct bio_list bios;
+       struct thin_c *tc;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(tc, &pool->active_thins, list)
+               process_thin_deferred_bios(tc);
+       rcu_read_unlock();
 
        /*
         * If there are any deferred flush bios, we must commit
@@ -1634,9 +1728,9 @@ static void thin_defer_bio(struct thin_c *tc, struct bio *bio)
        unsigned long flags;
        struct pool *pool = tc->pool;
 
-       spin_lock_irqsave(&pool->lock, flags);
-       bio_list_add(&pool->deferred_bios, bio);
-       spin_unlock_irqrestore(&pool->lock, flags);
+       spin_lock_irqsave(&tc->lock, flags);
+       bio_list_add(&tc->deferred_bio_list, bio);
+       spin_unlock_irqrestore(&tc->lock, flags);
 
        wake_worker(pool);
 }
@@ -1757,26 +1851,29 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
 
 static int pool_is_congested(struct dm_target_callbacks *cb, int bdi_bits)
 {
-       int r;
-       unsigned long flags;
        struct pool_c *pt = container_of(cb, struct pool_c, callbacks);
+       struct request_queue *q;
 
-       spin_lock_irqsave(&pt->pool->lock, flags);
-       r = !bio_list_empty(&pt->pool->retry_on_resume_list);
-       spin_unlock_irqrestore(&pt->pool->lock, flags);
+       if (get_pool_mode(pt->pool) == PM_OUT_OF_DATA_SPACE)
+               return 1;
 
-       if (!r) {
-               struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
-               r = bdi_congested(&q->backing_dev_info, bdi_bits);
-       }
-
-       return r;
+       q = bdev_get_queue(pt->data_dev->bdev);
+       return bdi_congested(&q->backing_dev_info, bdi_bits);
 }
 
-static void __requeue_bios(struct pool *pool)
+static void requeue_bios(struct pool *pool)
 {
-       bio_list_merge(&pool->deferred_bios, &pool->retry_on_resume_list);
-       bio_list_init(&pool->retry_on_resume_list);
+       unsigned long flags;
+       struct thin_c *tc;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(tc, &pool->active_thins, list) {
+               spin_lock_irqsave(&tc->lock, flags);
+               bio_list_merge(&tc->deferred_bio_list, &tc->retry_on_resume_list);
+               bio_list_init(&tc->retry_on_resume_list);
+               spin_unlock_irqrestore(&tc->lock, flags);
+       }
+       rcu_read_unlock();
 }
 
 /*----------------------------------------------------------------
@@ -1957,12 +2054,11 @@ static struct pool *pool_create(struct mapped_device *pool_md,
        INIT_WORK(&pool->worker, do_worker);
        INIT_DELAYED_WORK(&pool->waker, do_waker);
        spin_lock_init(&pool->lock);
-       bio_list_init(&pool->deferred_bios);
        bio_list_init(&pool->deferred_flush_bios);
        INIT_LIST_HEAD(&pool->prepared_mappings);
        INIT_LIST_HEAD(&pool->prepared_discards);
+       INIT_LIST_HEAD(&pool->active_thins);
        pool->low_water_triggered = false;
-       bio_list_init(&pool->retry_on_resume_list);
 
        pool->shared_read_ds = dm_deferred_set_create();
        if (!pool->shared_read_ds) {
@@ -2507,8 +2603,8 @@ static void pool_resume(struct dm_target *ti)
 
        spin_lock_irqsave(&pool->lock, flags);
        pool->low_water_triggered = false;
-       __requeue_bios(pool);
        spin_unlock_irqrestore(&pool->lock, flags);
+       requeue_bios(pool);
 
        do_waker(&pool->waker.work);
 }
@@ -2947,7 +3043,7 @@ static struct target_type pool_target = {
        .name = "thin-pool",
        .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
                    DM_TARGET_IMMUTABLE,
-       .version = {1, 11, 0},
+       .version = {1, 12, 0},
        .module = THIS_MODULE,
        .ctr = pool_ctr,
        .dtr = pool_dtr,
@@ -2968,6 +3064,12 @@ static struct target_type pool_target = {
 static void thin_dtr(struct dm_target *ti)
 {
        struct thin_c *tc = ti->private;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tc->pool->lock, flags);
+       list_del_rcu(&tc->list);
+       spin_unlock_irqrestore(&tc->pool->lock, flags);
+       synchronize_rcu();
 
        mutex_lock(&dm_thin_pool_table.mutex);
 
@@ -3014,6 +3116,10 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
                r = -ENOMEM;
                goto out_unlock;
        }
+       spin_lock_init(&tc->lock);
+       bio_list_init(&tc->deferred_bio_list);
+       bio_list_init(&tc->retry_on_resume_list);
+       tc->sort_bio_list = RB_ROOT;
 
        if (argc == 3) {
                r = dm_get_device(ti, argv[2], FMODE_READ, &origin_dev);
@@ -3085,6 +3191,17 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        mutex_unlock(&dm_thin_pool_table.mutex);
 
+       spin_lock(&tc->pool->lock);
+       list_add_tail_rcu(&tc->list, &tc->pool->active_thins);
+       spin_unlock(&tc->pool->lock);
+       /*
+        * This synchronize_rcu() call is needed here otherwise we risk a
+        * wake_worker() call finding no bios to process (because the newly
+        * added tc isn't yet visible).  So this reduces latency since we
+        * aren't then dependent on the periodic commit to wake_worker().
+        */
+       synchronize_rcu();
+
        return 0;
 
 bad_target_max_io_len:
@@ -3250,7 +3367,7 @@ static int thin_iterate_devices(struct dm_target *ti,
 
 static struct target_type thin_target = {
        .name = "thin",
-       .version = {1, 11, 0},
+       .version = {1, 12, 0},
        .module = THIS_MODULE,
        .ctr = thin_ctr,
        .dtr = thin_dtr,
index 8c53b09b9a2c5a3050b22f4fba82af5563f1d59a..455e6491649889d1970cd8ef3425e93f2ea6a93c 100644 (file)
@@ -94,13 +94,6 @@ struct dm_rq_clone_bio_info {
        struct bio clone;
 };
 
-union map_info *dm_get_mapinfo(struct bio *bio)
-{
-       if (bio && bio->bi_private)
-               return &((struct dm_target_io *)bio->bi_private)->info;
-       return NULL;
-}
-
 union map_info *dm_get_rq_mapinfo(struct request *rq)
 {
        if (rq && rq->end_io_data)
@@ -475,6 +468,11 @@ sector_t dm_get_size(struct mapped_device *md)
        return get_capacity(md->disk);
 }
 
+struct request_queue *dm_get_md_queue(struct mapped_device *md)
+{
+       return md->queue;
+}
+
 struct dm_stats *dm_get_stats(struct mapped_device *md)
 {
        return &md->stats;
@@ -760,7 +758,7 @@ static void dec_pending(struct dm_io *io, int error)
 static void clone_endio(struct bio *bio, int error)
 {
        int r = 0;
-       struct dm_target_io *tio = bio->bi_private;
+       struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
        struct dm_io *io = tio->io;
        struct mapped_device *md = tio->io->md;
        dm_endio_fn endio = tio->ti->type->end_io;
@@ -794,7 +792,8 @@ static void clone_endio(struct bio *bio, int error)
  */
 static void end_clone_bio(struct bio *clone, int error)
 {
-       struct dm_rq_clone_bio_info *info = clone->bi_private;
+       struct dm_rq_clone_bio_info *info =
+               container_of(clone, struct dm_rq_clone_bio_info, clone);
        struct dm_rq_target_io *tio = info->tio;
        struct bio *bio = info->orig;
        unsigned int nr_bytes = info->orig->bi_iter.bi_size;
@@ -1120,7 +1119,6 @@ static void __map_bio(struct dm_target_io *tio)
        struct dm_target *ti = tio->ti;
 
        clone->bi_end_io = clone_endio;
-       clone->bi_private = tio;
 
        /*
         * Map the clone.  If r == 0 we don't need to do
@@ -1195,7 +1193,6 @@ static struct dm_target_io *alloc_tio(struct clone_info *ci,
 
        tio->io = ci->io;
        tio->ti = ti;
-       memset(&tio->info, 0, sizeof(tio->info));
        tio->target_bio_nr = target_bio_nr;
 
        return tio;
@@ -1530,7 +1527,6 @@ static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig,
        info->orig = bio_orig;
        info->tio = tio;
        bio->bi_end_io = end_clone_bio;
-       bio->bi_private = info;
 
        return 0;
 }
@@ -2172,7 +2168,7 @@ static struct dm_table *__unbind(struct mapped_device *md)
                return NULL;
 
        dm_table_event_callback(map, NULL, NULL);
-       rcu_assign_pointer(md->map, NULL);
+       RCU_INIT_POINTER(md->map, NULL);
        dm_sync_table(md);
 
        return map;
@@ -2873,8 +2869,6 @@ static const struct block_device_operations dm_blk_dops = {
        .owner = THIS_MODULE
 };
 
-EXPORT_SYMBOL(dm_get_mapinfo);
-
 /*
  * module hooks
  */
index c4569f02f50f1a181ed6f6f2bd797bd62c0c7f47..ed76126aac542e57d092a1d50a00135d8119c2ec 100644 (file)
@@ -73,7 +73,6 @@ unsigned dm_table_get_type(struct dm_table *t);
 struct target_type *dm_table_get_immutable_target_type(struct dm_table *t);
 bool dm_table_request_based(struct dm_table *t);
 bool dm_table_supports_discards(struct dm_table *t);
-int dm_table_alloc_md_mempools(struct dm_table *t);
 void dm_table_free_md_mempools(struct dm_table *t);
 struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t);
 
@@ -189,6 +188,7 @@ int dm_lock_for_deletion(struct mapped_device *md, bool mark_deferred, bool only
 int dm_cancel_deferred_remove(struct mapped_device *md);
 int dm_request_based(struct mapped_device *md);
 sector_t dm_get_size(struct mapped_device *md);
+struct request_queue *dm_get_md_queue(struct mapped_device *md);
 struct dm_stats *dm_get_stats(struct mapped_device *md);
 
 int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
index cd9a86d4cdf0f36878d5fa14b9bb2f24dc6e71c8..36f7cc2c7109b45b77a1ff27e1f7b1a146dbfcf1 100644 (file)
@@ -65,7 +65,7 @@ int dm_bitset_flush(struct dm_disk_bitset *info, dm_block_t root,
        int r;
        __le64 value;
 
-       if (!info->current_index_set)
+       if (!info->current_index_set || !info->dirty)
                return 0;
 
        value = cpu_to_le64(info->current_bits);
@@ -77,6 +77,8 @@ int dm_bitset_flush(struct dm_disk_bitset *info, dm_block_t root,
                return r;
 
        info->current_index_set = false;
+       info->dirty = false;
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(dm_bitset_flush);
@@ -94,6 +96,8 @@ static int read_bits(struct dm_disk_bitset *info, dm_block_t root,
        info->current_bits = le64_to_cpu(value);
        info->current_index_set = true;
        info->current_index = array_index;
+       info->dirty = false;
+
        return 0;
 }
 
@@ -126,6 +130,8 @@ int dm_bitset_set_bit(struct dm_disk_bitset *info, dm_block_t root,
                return r;
 
        set_bit(b, (unsigned long *) &info->current_bits);
+       info->dirty = true;
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(dm_bitset_set_bit);
@@ -141,6 +147,8 @@ int dm_bitset_clear_bit(struct dm_disk_bitset *info, dm_block_t root,
                return r;
 
        clear_bit(b, (unsigned long *) &info->current_bits);
+       info->dirty = true;
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(dm_bitset_clear_bit);
index e1b9bea14aa1f23e4ccd59f5bba2b3f2fa0cd99f..c2287d672ef5ed4735b91fe9fac3f708c9b7df64 100644 (file)
@@ -71,6 +71,7 @@ struct dm_disk_bitset {
        uint64_t current_bits;
 
        bool current_index_set:1;
+       bool dirty:1;
 };
 
 /*
index 455f79279a1653d4a18fd790129b848a4b4594bf..087411c95ffcb94805c4b3c860683615583244ab 100644 (file)
@@ -595,25 +595,14 @@ int dm_bm_unlock(struct dm_block *b)
 }
 EXPORT_SYMBOL_GPL(dm_bm_unlock);
 
-int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
-                          struct dm_block *superblock)
+int dm_bm_flush(struct dm_block_manager *bm)
 {
-       int r;
-
        if (bm->read_only)
                return -EPERM;
 
-       r = dm_bufio_write_dirty_buffers(bm->bufio);
-       if (unlikely(r)) {
-               dm_bm_unlock(superblock);
-               return r;
-       }
-
-       dm_bm_unlock(superblock);
-
        return dm_bufio_write_dirty_buffers(bm->bufio);
 }
-EXPORT_SYMBOL_GPL(dm_bm_flush_and_unlock);
+EXPORT_SYMBOL_GPL(dm_bm_flush);
 
 void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b)
 {
index 13cd58e1fe69ffb4ed477b10ee6bbbe6d58d9926..1b95dfc1778640efc74114b2ee382a36d11ad9f1 100644 (file)
@@ -105,8 +105,7 @@ int dm_bm_unlock(struct dm_block *b);
  *
  * This method always blocks.
  */
-int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
-                          struct dm_block *superblock);
+int dm_bm_flush(struct dm_block_manager *bm);
 
 /*
  * Request data is prefetched into the cache.
index 81da1a26042e5fae05d136a01353c8f7ec923052..3bc30a0ae3d6084a2e08b356ac40c9082c6d5c62 100644 (file)
@@ -154,7 +154,7 @@ int dm_tm_pre_commit(struct dm_transaction_manager *tm)
        if (r < 0)
                return r;
 
-       return 0;
+       return dm_bm_flush(tm->bm);
 }
 EXPORT_SYMBOL_GPL(dm_tm_pre_commit);
 
@@ -164,8 +164,9 @@ int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root)
                return -EWOULDBLOCK;
 
        wipe_shadow_table(tm);
+       dm_bm_unlock(root);
 
-       return dm_bm_flush_and_unlock(tm->bm, root);
+       return dm_bm_flush(tm->bm);
 }
 EXPORT_SYMBOL_GPL(dm_tm_commit);
 
index b5b139076ca58034b38e80f06c4e5ac9f177f47d..2772ed2a781a5de107e13d275f21b2ad1d98c7ea 100644 (file)
@@ -38,18 +38,17 @@ struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transac
 /*
  * We use a 2-phase commit here.
  *
- * i) In the first phase the block manager is told to start flushing, and
- * the changes to the space map are written to disk.  You should interrogate
- * your particular space map to get detail of its root node etc. to be
- * included in your superblock.
+ * i) Make all changes for the transaction *except* for the superblock.
+ * Then call dm_tm_pre_commit() to flush them to disk.
  *
- * ii) @root will be committed last.  You shouldn't use more than the
- * first 512 bytes of @root if you wish the transaction to survive a power
- * failure.  You *must* have a write lock held on @root for both stage (i)
- * and (ii).  The commit will drop the write lock.
+ * ii) Lock your superblock.  Update.  Then call dm_tm_commit() which will
+ * unlock the superblock and flush it.  No other blocks should be updated
+ * during this period.  Care should be taken to never unlock a partially
+ * updated superblock; perform any operations that could fail *before* you
+ * take the superblock lock.
  */
 int dm_tm_pre_commit(struct dm_transaction_manager *tm);
-int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root);
+int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *superblock);
 
 /*
  * These methods are the only way to get hold of a writeable block.
index 0bb4430535f91000856041e3ba821c2379f39b22..2408d7e9451eaea0608fdbb3ea9ef3b0ee0c36c2 100644 (file)
@@ -1,6 +1,6 @@
 /***********************************************************************
  *
- * Copyright(c) 2013 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright(c) 2013 Mauro Carvalho Chehab
  *
  * 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
index b8c5cad78537209b2409e687a4a5eb23b4c51b93..6d7c0c858bd04b708d5eae6dab636f814fd2f63a 100644 (file)
@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
 
        dev->priv = coredev;
        dev->driver_type = RC_DRIVER_IR_RAW;
-       dev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(dev, RC_BIT_ALL);
        dev->map_name = sms_get_board(board_id)->rc_codes;
        dev->driver_name = MODULE_NAME;
 
index f19a2ccd1e4b5e88c753200fc5177d88e7b1e8e9..1bdc0e7e8b79a90bfa754c71974c7e9c21ee419d 100644 (file)
 #define USB_PID_TERRATEC_T5                            0x10a1
 #define USB_PID_NOXON_DAB_STICK                                0x00b3
 #define USB_PID_NOXON_DAB_STICK_REV2                   0x00e0
+#define USB_PID_NOXON_DAB_STICK_REV3                   0x00b4
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX             0x022e
 #define USB_PID_PINNACLE_PCTV2000E                     0x022c
 #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH              0x0228
index 1f925e856974936914a7fdb5299bda2a4a84bd59..6ce435ac866f06d5689f3ee9f71a0d91c9ade143 100644 (file)
@@ -1279,7 +1279,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
        switch(tvp->cmd) {
        case DTV_ENUM_DELSYS:
                ncaps = 0;
-               while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+               while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
                        tvp->u.buffer.data[ncaps] = fe->ops.delsys[ncaps];
                        ncaps++;
                }
@@ -1596,7 +1596,7 @@ static int dvbv5_set_delivery_system(struct dvb_frontend *fe,
         * supported
         */
        ncaps = 0;
-       while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+       while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
                if (fe->ops.delsys[ncaps] == desired_system) {
                        c->delivery_system = desired_system;
                        dev_dbg(fe->dvb->device,
@@ -1628,7 +1628,7 @@ static int dvbv5_set_delivery_system(struct dvb_frontend *fe,
        * of the desired system
        */
        ncaps = 0;
-       while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+       while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
                if (dvbv3_type(fe->ops.delsys[ncaps]) == type)
                        delsys = fe->ops.delsys[ncaps];
                ncaps++;
@@ -1703,7 +1703,7 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
         * DVBv3 standard
         */
        ncaps = 0;
-       while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+       while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
                if (dvbv3_type(fe->ops.delsys[ncaps]) != DVBV3_UNKNOWN) {
                        delsys = fe->ops.delsys[ncaps];
                        break;
@@ -1882,6 +1882,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
                c->lna = tvp->u.data;
                if (fe->ops.set_lna)
                        r = fe->ops.set_lna(fe);
+               if (r < 0)
+                       c->lna = LNA_AUTO;
                break;
 
        default:
index dd12a1ebda823ffeadef699349fedcf2d2997a0a..025fc5496bfc602e1252bfc0be8093303fdbedfd 100644 (file)
@@ -441,7 +441,7 @@ config DVB_RTL2830
 
 config DVB_RTL2832
        tristate "Realtek RTL2832 DVB-T"
-       depends on DVB_CORE && I2C
+       depends on DVB_CORE && I2C && I2C_MUX
        default m if !MEDIA_SUBDRV_AUTOSELECT
        help
          Say Y when you want to support this frontend.
@@ -650,6 +650,8 @@ config DVB_TUNER_DIB0090
 comment "SEC control devices for DVB-S"
        depends on DVB_CORE
 
+source "drivers/media/dvb-frontends/drx39xyj/Kconfig"
+
 config DVB_LNBP21
        tristate "LNBP21/LNBH24 SEC controllers"
        depends on DVB_CORE && I2C
@@ -733,14 +735,6 @@ config DVB_IX2505V
        help
          A DVB-S tuner module. Say Y when you want to support this frontend.
 
-config DVB_IT913X_FE
-       tristate "it913x frontend and it9137 tuner"
-       depends on DVB_CORE && I2C
-       default m if !MEDIA_SUBDRV_AUTOSELECT
-       help
-         A DVB-T tuner module.
-         Say Y when you want to support this frontend.
-
 config DVB_M88RS2000
        tristate "M88RS2000 DVB-S demodulator and tuner"
        depends on DVB_CORE && I2C
index 0c75a6aafb9d7424e2393accd13e873f7037504d..282aba2fe8db039ad7f58af5f6780531583fe8fc 100644 (file)
@@ -92,13 +92,13 @@ obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
 obj-$(CONFIG_DVB_DS3000) += ds3000.o
 obj-$(CONFIG_DVB_TS2020) += ts2020.o
 obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
+obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj/
 obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
 obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
 obj-$(CONFIG_DVB_STV0367) += stv0367.o
 obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
 obj-$(CONFIG_DVB_DRXK) += drxk.o
 obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
-obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
 obj-$(CONFIG_DVB_A8293) += a8293.o
 obj-$(CONFIG_DVB_TDA10071) += tda10071.o
 obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
index 65728c25ea05adcd50bd658c96a6c54dd6fb569b..be4bec2a96408b896b9e3e6e62a4a8ac70c4d566 100644 (file)
@@ -989,10 +989,62 @@ err:
        return ret;
 }
 
+static int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+
+       dev_dbg(&state->i2c->dev, "%s: onoff=%d\n", __func__, onoff);
+
+       ret = af9033_wr_reg_mask(state, 0x80f993, onoff, 0x01);
+       if (ret < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid, int onoff)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+       u8 wbuf[2] = {(pid >> 0) & 0xff, (pid >> 8) & 0xff};
+
+       dev_dbg(&state->i2c->dev, "%s: index=%d pid=%04x onoff=%d\n",
+                       __func__, index, pid, onoff);
+
+       if (pid > 0x1fff)
+               return 0;
+
+       ret = af9033_wr_regs(state, 0x80f996, wbuf, 2);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg(state, 0x80f994, onoff);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg(state, 0x80f995, index);
+       if (ret < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
 static struct dvb_frontend_ops af9033_ops;
 
 struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-               struct i2c_adapter *i2c)
+                                  struct i2c_adapter *i2c,
+                                  struct af9033_ops *ops)
 {
        int ret;
        struct af9033_state *state;
@@ -1067,6 +1119,11 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
        memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
        state->fe.demodulator_priv = state;
 
+       if (ops) {
+               ops->pid_filter = af9033_pid_filter;
+               ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
+       }
+
        return &state->fe;
 
 err:
index c286e8f1ec02aab4a3da92f03780bcdd559ff7b1..539f4db678b87f0076093f8f85b9139e182dc31d 100644 (file)
@@ -78,16 +78,42 @@ struct af9033_config {
 };
 
 
+struct af9033_ops {
+       int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
+       int (*pid_filter)(struct dvb_frontend *fe, int index, u16 pid,
+                         int onoff);
+};
+
+
 #if IS_ENABLED(CONFIG_DVB_AF9033)
-extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-       struct i2c_adapter *i2c);
+extern
+struct dvb_frontend *af9033_attach(const struct af9033_config *config,
+                                  struct i2c_adapter *i2c,
+                                  struct af9033_ops *ops);
+
 #else
-static inline struct dvb_frontend *af9033_attach(
-       const struct af9033_config *config, struct i2c_adapter *i2c)
+static inline
+struct dvb_frontend *af9033_attach(const struct af9033_config *config,
+                                  struct i2c_adapter *i2c,
+                                  struct af9033_ops *ops)
 {
        pr_warn("%s: driver disabled by Kconfig\n", __func__);
        return NULL;
 }
+
+static inline int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       pr_warn("%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
+       int onoff)
+{
+       pr_warn("%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
 #endif
 
 #endif /* AF9033_H */
diff --git a/drivers/media/dvb-frontends/drx39xyj/Kconfig b/drivers/media/dvb-frontends/drx39xyj/Kconfig
new file mode 100644 (file)
index 0000000..15628eb
--- /dev/null
@@ -0,0 +1,7 @@
+config DVB_DRX39XYJ
+       tristate "Micronas DRX-J demodulator"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
diff --git a/drivers/media/dvb-frontends/drx39xyj/Makefile b/drivers/media/dvb-frontends/drx39xyj/Makefile
new file mode 100644 (file)
index 0000000..672e077
--- /dev/null
@@ -0,0 +1,6 @@
+drx39xyj-objs := drxj.o
+
+obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core/
+ccflags-y += -I$(srctree)/drivers/media/tuners/
diff --git a/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h b/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h
new file mode 100644 (file)
index 0000000..5b5421f
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+  I2C API, implementation depends on board specifics
+
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+  This module encapsulates I2C access.In some applications several devices
+  share one I2C bus. If these devices have the same I2C address some kind
+  off "switch" must be implemented to ensure error free communication with
+  one device.  In case such a "switch" is used, the device ID can be used
+  to implement control over this "switch".
+*/
+
+#ifndef __BSPI2C_H__
+#define __BSPI2C_H__
+
+#include "bsp_types.h"
+
+/*
+ * This structure contains the I2C address, the device ID and a user_data pointer.
+ * The user_data pointer can be used for application specific purposes.
+ */
+struct i2c_device_addr {
+       u16 i2c_addr;           /* The I2C address of the device. */
+       u16 i2c_dev_id;         /* The device identifier. */
+       void *user_data;                /* User data pointer */
+};
+
+
+/**
+* \def IS_I2C_10BIT( addr )
+* \brief Determine if I2C address 'addr' is a 10 bits address or not.
+* \param addr The I2C address.
+* \return int.
+* \retval 0 if address is not a 10 bits I2C address.
+* \retval 1 if address is a 10 bits I2C address.
+*/
+#define IS_I2C_10BIT(addr) \
+        (((addr) & 0xF8) == 0xF0)
+
+/*------------------------------------------------------------------------------
+Exported FUNCTIONS
+------------------------------------------------------------------------------*/
+
+/**
+* \fn drxbsp_i2c_init()
+* \brief Initialize I2C communication module.
+* \return drx_status_t Return status.
+* \retval 0 Initialization successful.
+* \retval -EIO Initialization failed.
+*/
+       drx_status_t drxbsp_i2c_init(void);
+
+/**
+* \fn drxbsp_i2c_term()
+* \brief Terminate I2C communication module.
+* \return drx_status_t Return status.
+* \retval 0 Termination successful.
+* \retval -EIO Termination failed.
+*/
+       drx_status_t drxbsp_i2c_term(void);
+
+/**
+* \fn drx_status_t drxbsp_i2c_write_read( struct i2c_device_addr *w_dev_addr,
+*                                       u16 w_count,
+*                                       u8 *wData,
+*                                       struct i2c_device_addr *r_dev_addr,
+*                                       u16 r_count,
+*                                       u8 *r_data)
+* \brief Read and/or write count bytes from I2C bus, store them in data[].
+* \param w_dev_addr The device i2c address and the device ID to write to
+* \param w_count   The number of bytes to write
+* \param wData    The array to write the data to
+* \param r_dev_addr The device i2c address and the device ID to read from
+* \param r_count   The number of bytes to read
+* \param r_data    The array to read the data from
+* \return drx_status_t Return status.
+* \retval 0 Succes.
+* \retval -EIO Failure.
+* \retval -EINVAL Parameter 'wcount' is not zero but parameter
+*                                       'wdata' contains NULL.
+*                                       Idem for 'rcount' and 'rdata'.
+*                                       Both w_dev_addr and r_dev_addr are NULL.
+*
+* This function must implement an atomic write and/or read action on the I2C bus
+* No other process may use the I2C bus when this function is executing.
+* The critical section of this function runs from and including the I2C
+* write, up to and including the I2C read action.
+*
+* The device ID can be useful if several devices share an I2C address.
+* It can be used to control a "switch" on the I2C bus to the correct device.
+*/
+       drx_status_t drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
+                                        u16 w_count,
+                                        u8 *w_data,
+                                        struct i2c_device_addr *r_dev_addr,
+                                        u16 r_count, u8 *r_data);
+
+/**
+* \fn drxbsp_i2c_error_text()
+* \brief Returns a human readable error.
+* Counter part of numerical drx_i2c_error_g.
+*
+* \return char* Pointer to human readable error text.
+*/
+       char *drxbsp_i2c_error_text(void);
+
+/**
+* \var drx_i2c_error_g;
+* \brief I2C specific error codes, platform dependent.
+*/
+       extern int drx_i2c_error_g;
+
+#endif                         /* __BSPI2C_H__ */
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
new file mode 100644 (file)
index 0000000..cfd0b96
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Driver for Micronas DRX39xx family (drx3933j)
+ *
+ *  Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef DRX39XXJ_H
+#define DRX39XXJ_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+#include "drx_driver.h"
+
+struct drx39xxj_state {
+       struct i2c_adapter *i2c;
+       struct drx_demod_instance *demod;
+       struct dvb_frontend frontend;
+       unsigned int i2c_gate_open:1;
+       const struct firmware *fw;
+};
+
+#if IS_ENABLED(CONFIG_DVB_DRX39XYJ)
+struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) {
+       return NULL;
+};
+#endif
+
+#endif /* DVB_DUMMY_FE_H */
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_dap_fasi.h b/drivers/media/dvb-frontends/drx39xyj/drx_dap_fasi.h
new file mode 100644 (file)
index 0000000..354ec07
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*******************************************************************************
+* FILENAME: $Id: drx_dap_fasi.h,v 1.5 2009/07/07 14:21:40 justin Exp $
+*
+* DESCRIPTION:
+* Part of DRX driver.
+* Data access protocol: Fast Access Sequential Interface (fasi)
+* Fast access, because of short addressing format (16 instead of 32 bits addr)
+* Sequential, because of I2C.
+*
+* USAGE:
+* Include.
+*
+* NOTES:
+*
+*
+*******************************************************************************/
+
+/*-------- compilation control switches --------------------------------------*/
+
+#ifndef __DRX_DAP_FASI_H__
+#define __DRX_DAP_FASI_H__
+
+/*-------- Required includes -------------------------------------------------*/
+
+#include "drx_driver.h"
+
+/*-------- Defines, configuring the API --------------------------------------*/
+
+/********************************************
+* Allowed address formats
+********************************************/
+
+/*
+* Comments about short/long addressing format:
+*
+* The DAP FASI offers long address format (4 bytes) and short address format
+* (2 bytes). The DAP can operate in 3 modes:
+* (1) only short
+* (2) only long
+* (3) both long and short but short preferred and long only when necesarry
+*
+* These modes must be selected compile time via compile switches.
+* Compile switch settings for the diffrent modes:
+* (1) DRXDAPFASI_LONG_ADDR_ALLOWED=0, DRXDAPFASI_SHORT_ADDR_ALLOWED=1
+* (2) DRXDAPFASI_LONG_ADDR_ALLOWED=1, DRXDAPFASI_SHORT_ADDR_ALLOWED=0
+* (3) DRXDAPFASI_LONG_ADDR_ALLOWED=1, DRXDAPFASI_SHORT_ADDR_ALLOWED=1
+*
+* The default setting will be (3) both long and short.
+* The default setting will need no compile switches.
+* The default setting must be overridden if compile switches are already
+* defined.
+*
+*/
+
+/* set default */
+#if !defined(DRXDAPFASI_LONG_ADDR_ALLOWED)
+#define  DRXDAPFASI_LONG_ADDR_ALLOWED 1
+#endif
+
+/* set default */
+#if !defined(DRXDAPFASI_SHORT_ADDR_ALLOWED)
+#define  DRXDAPFASI_SHORT_ADDR_ALLOWED 1
+#endif
+
+/* check */
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 0) && \
+      (DRXDAPFASI_SHORT_ADDR_ALLOWED == 0))
+#error  At least one of short- or long-addressing format must be allowed.
+*;                             /* illegal statement to force compiler error */
+#endif
+
+/********************************************
+* Single/master multi master setting
+********************************************/
+/*
+* Comments about SINGLE MASTER/MULTI MASTER  modes:
+*
+* Consider the two sides:1) the master and 2)the slave.
+*
+* Master:
+* Single/multimaster operation set via DRXDAP_SINGLE_MASTER compile switch
+*  + single master mode means no use of repeated starts
+*  + multi master mode means use of repeated starts
+*  Default is single master.
+*  Default can be overriden by setting the compile switch DRXDAP_SINGLE_MASTER.
+*
+* Slave:
+* Single/multi master selected via the flags in the FASI protocol.
+*  + single master means remember memory address between i2c packets
+*  + multimaster means flush memory address between i2c packets
+*  Default is single master, DAP FASI changes multi-master setting silently
+*  into single master setting. This cannot be overrriden.
+*
+*/
+/* set default */
+#ifndef DRXDAP_SINGLE_MASTER
+#define DRXDAP_SINGLE_MASTER 0
+#endif
+
+/********************************************
+* Chunk/mode checking
+********************************************/
+/*
+* Comments about DRXDAP_MAX_WCHUNKSIZE in single or multi master mode and
+* in combination with short and long addressing format. All text below
+* assumes long addressing format. The table also includes information
+* for short ADDRessing format.
+*
+* In single master mode, data can be written by sending the register address
+* first, then two or four bytes of data in the next packet.
+* Because the device address plus a register address equals five bytes,
+* the mimimum chunk size must be five.
+* If ten-bit I2C device addresses are used, the minimum chunk size must be six,
+* because the I2C device address will then occupy two bytes when writing.
+*
+* Data in single master mode is transferred as follows:
+* <S> <devW>  a0  a1  a2  a3  <P>
+* <S> <devW>  d0  d1 [d2  d3] <P>
+* ..
+* or
+* ..
+* <S> <devW>  a0  a1  a2  a3  <P>
+* <S> <devR> --- <P>
+*
+* In multi-master mode, the data must immediately follow the address (an I2C
+* stop resets the internal address), and hence the minimum chunk size is
+* 1 <I2C address> + 4 (register address) + 2 (data to send) = 7 bytes (8 if
+* 10-bit I2C device addresses are used).
+*
+* The 7-bit or 10-bit i2c address parameters is a runtime parameter.
+* The other parameters can be limited via compile time switches.
+*
+*-------------------------------------------------------------------------------
+*
+*  Minimum chunk size table (in bytes):
+*
+*       +----------------+----------------+
+*       | 7b i2c addr    | 10b i2c addr   |
+*       +----------------+----------------+
+*       | single | multi | single | multi |
+* ------+--------+-------+--------+-------+
+* short | 3      | 5     | 4      | 6     |
+* long  | 5      | 7     | 6      | 8     |
+* ------+--------+-------+--------+-------+
+*
+*/
+
+/* set default */
+#if !defined(DRXDAP_MAX_WCHUNKSIZE)
+#define  DRXDAP_MAX_WCHUNKSIZE 254
+#endif
+
+/* check */
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 0) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+#if DRXDAP_SINGLE_MASTER
+#define  DRXDAP_MAX_WCHUNKSIZE_MIN 3
+#else
+#define  DRXDAP_MAX_WCHUNKSIZE_MIN 5
+#endif
+#else
+#if DRXDAP_SINGLE_MASTER
+#define  DRXDAP_MAX_WCHUNKSIZE_MIN 5
+#else
+#define  DRXDAP_MAX_WCHUNKSIZE_MIN 7
+#endif
+#endif
+
+#if  DRXDAP_MAX_WCHUNKSIZE <  DRXDAP_MAX_WCHUNKSIZE_MIN
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 0) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+#if DRXDAP_SINGLE_MASTER
+#error  DRXDAP_MAX_WCHUNKSIZE must be at least 3 in single master mode
+*;                             /* illegal statement to force compiler error */
+#else
+#error  DRXDAP_MAX_WCHUNKSIZE must be at least 5 in multi master mode
+*;                             /* illegal statement to force compiler error */
+#endif
+#else
+#if DRXDAP_SINGLE_MASTER
+#error  DRXDAP_MAX_WCHUNKSIZE must be at least 5 in single master mode
+*;                             /* illegal statement to force compiler error */
+#else
+#error  DRXDAP_MAX_WCHUNKSIZE must be at least 7 in multi master mode
+*;                             /* illegal statement to force compiler error */
+#endif
+#endif
+#endif
+
+/* set default */
+#if !defined(DRXDAP_MAX_RCHUNKSIZE)
+#define  DRXDAP_MAX_RCHUNKSIZE 254
+#endif
+
+/* check */
+#if  DRXDAP_MAX_RCHUNKSIZE < 2
+#error  DRXDAP_MAX_RCHUNKSIZE must be at least 2
+*;                             /* illegal statement to force compiler error */
+#endif
+
+/* check */
+#if  DRXDAP_MAX_RCHUNKSIZE & 1
+#error  DRXDAP_MAX_RCHUNKSIZE must be even
+*;                             /* illegal statement to force compiler error */
+#endif
+
+/*-------- Public API functions ----------------------------------------------*/
+
+extern struct drx_access_func drx_dap_fasi_funct_g;
+
+#define DRXDAP_FASI_RMW           0x10000000
+#define DRXDAP_FASI_BROADCAST     0x20000000
+#define DRXDAP_FASI_CLEARCRC      0x80000000
+#define DRXDAP_FASI_SINGLE_MASTER 0xC0000000
+#define DRXDAP_FASI_MULTI_MASTER  0x40000000
+#define DRXDAP_FASI_SMM_SWITCH    0x40000000   /* single/multi master switch */
+#define DRXDAP_FASI_MODEFLAGS     0xC0000000
+#define DRXDAP_FASI_FLAGS         0xF0000000
+
+#define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr)>>22)&0x3F)
+#define DRXDAP_FASI_ADDR2BANK(addr)   (((addr)>>16)&0x3F)
+#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr)&0x7FFF)
+
+#define DRXDAP_FASI_SHORT_FORMAT(addr)     (((addr) & 0xFC30FF80) == 0)
+#define DRXDAP_FASI_LONG_FORMAT(addr)      (((addr) & 0xFC30FF80) != 0)
+#define DRXDAP_FASI_OFFSET_TOO_LARGE(addr) (((addr) & 0x00008000) != 0)
+
+#endif                         /* __DRX_DAP_FASI_H__ */
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
new file mode 100644 (file)
index 0000000..9076bf2
--- /dev/null
@@ -0,0 +1,2343 @@
+/*
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DRXDRIVER_H__
+#define __DRXDRIVER_H__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+
+/*
+ * This structure contains the I2C address, the device ID and a user_data pointer.
+ * The user_data pointer can be used for application specific purposes.
+ */
+struct i2c_device_addr {
+       u16 i2c_addr;           /* The I2C address of the device. */
+       u16 i2c_dev_id;         /* The device identifier. */
+       void *user_data;                /* User data pointer */
+};
+
+/**
+* \def IS_I2C_10BIT( addr )
+* \brief Determine if I2C address 'addr' is a 10 bits address or not.
+* \param addr The I2C address.
+* \return int.
+* \retval 0 if address is not a 10 bits I2C address.
+* \retval 1 if address is a 10 bits I2C address.
+*/
+#define IS_I2C_10BIT(addr) \
+        (((addr) & 0xF8) == 0xF0)
+
+/*------------------------------------------------------------------------------
+Exported FUNCTIONS
+------------------------------------------------------------------------------*/
+
+/**
+* \fn drxbsp_i2c_init()
+* \brief Initialize I2C communication module.
+* \return int Return status.
+* \retval 0 Initialization successful.
+* \retval -EIO Initialization failed.
+*/
+int drxbsp_i2c_init(void);
+
+/**
+* \fn drxbsp_i2c_term()
+* \brief Terminate I2C communication module.
+* \return int Return status.
+* \retval 0 Termination successful.
+* \retval -EIO Termination failed.
+*/
+int drxbsp_i2c_term(void);
+
+/**
+* \fn int drxbsp_i2c_write_read( struct i2c_device_addr *w_dev_addr,
+*                                       u16 w_count,
+*                                       u8 * wData,
+*                                       struct i2c_device_addr *r_dev_addr,
+*                                       u16 r_count,
+*                                       u8 * r_data)
+* \brief Read and/or write count bytes from I2C bus, store them in data[].
+* \param w_dev_addr The device i2c address and the device ID to write to
+* \param w_count   The number of bytes to write
+* \param wData    The array to write the data to
+* \param r_dev_addr The device i2c address and the device ID to read from
+* \param r_count   The number of bytes to read
+* \param r_data    The array to read the data from
+* \return int Return status.
+* \retval 0 Succes.
+* \retval -EIO Failure.
+* \retval -EINVAL Parameter 'wcount' is not zero but parameter
+*                                       'wdata' contains NULL.
+*                                       Idem for 'rcount' and 'rdata'.
+*                                       Both w_dev_addr and r_dev_addr are NULL.
+*
+* This function must implement an atomic write and/or read action on the I2C bus
+* No other process may use the I2C bus when this function is executing.
+* The critical section of this function runs from and including the I2C
+* write, up to and including the I2C read action.
+*
+* The device ID can be useful if several devices share an I2C address.
+* It can be used to control a "switch" on the I2C bus to the correct device.
+*/
+int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
+                                       u16 w_count,
+                                       u8 *wData,
+                                       struct i2c_device_addr *r_dev_addr,
+                                       u16 r_count, u8 *r_data);
+
+/**
+* \fn drxbsp_i2c_error_text()
+* \brief Returns a human readable error.
+* Counter part of numerical drx_i2c_error_g.
+*
+* \return char* Pointer to human readable error text.
+*/
+char *drxbsp_i2c_error_text(void);
+
+/**
+* \var drx_i2c_error_g;
+* \brief I2C specific error codes, platform dependent.
+*/
+extern int drx_i2c_error_g;
+
+#define TUNER_MODE_SUB0    0x0001      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB1    0x0002      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB2    0x0004      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB3    0x0008      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB4    0x0010      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB5    0x0020      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB6    0x0040      /* for sub-mode (e.g. RF-AGC setting) */
+#define TUNER_MODE_SUB7    0x0080      /* for sub-mode (e.g. RF-AGC setting) */
+
+#define TUNER_MODE_DIGITAL 0x0100      /* for digital channel (e.g. DVB-T)   */
+#define TUNER_MODE_ANALOG  0x0200      /* for analog channel  (e.g. PAL)     */
+#define TUNER_MODE_SWITCH  0x0400      /* during channel switch & scanning   */
+#define TUNER_MODE_LOCK    0x0800      /* after tuner has locked             */
+#define TUNER_MODE_6MHZ    0x1000      /* for 6MHz bandwidth channels        */
+#define TUNER_MODE_7MHZ    0x2000      /* for 7MHz bandwidth channels        */
+#define TUNER_MODE_8MHZ    0x4000      /* for 8MHz bandwidth channels        */
+
+#define TUNER_MODE_SUB_MAX 8
+#define TUNER_MODE_SUBALL  (TUNER_MODE_SUB0 | TUNER_MODE_SUB1 | \
+                             TUNER_MODE_SUB2 | TUNER_MODE_SUB3 | \
+                             TUNER_MODE_SUB4 | TUNER_MODE_SUB5 | \
+                             TUNER_MODE_SUB6 | TUNER_MODE_SUB7)
+
+
+enum tuner_lock_status {
+       TUNER_LOCKED,
+       TUNER_NOT_LOCKED
+};
+
+struct tuner_common {
+       char *name;     /* Tuner brand & type name */
+       s32 min_freq_rf;        /* Lowest  RF input frequency, in kHz */
+       s32 max_freq_rf;        /* Highest RF input frequency, in kHz */
+
+       u8 sub_mode;    /* Index to sub-mode in use */
+       char ***sub_mode_descriptions;  /* Pointer to description of sub-modes */
+       u8 sub_modes;   /* Number of available sub-modes      */
+
+       /* The following fields will be either 0, NULL or false and do not need
+               initialisation */
+       void *self_check;       /* gives proof of initialization  */
+       bool programmed;        /* only valid if self_check is OK  */
+       s32 r_ffrequency;       /* only valid if programmed       */
+       s32 i_ffrequency;       /* only valid if programmed       */
+
+       void *my_user_data;     /* pointer to associated demod instance */
+       u16 my_capabilities;    /* value for storing application flags  */
+};
+
+struct tuner_instance;
+
+typedef int(*tuner_open_func_t) (struct tuner_instance *tuner);
+typedef int(*tuner_close_func_t) (struct tuner_instance *tuner);
+
+typedef int(*tuner_set_frequency_func_t) (struct tuner_instance *tuner,
+                                               u32 mode,
+                                               s32
+                                               frequency);
+
+typedef int(*tuner_get_frequency_func_t) (struct tuner_instance *tuner,
+                                               u32 mode,
+                                               s32 *
+                                               r_ffrequency,
+                                               s32 *
+                                               i_ffrequency);
+
+typedef int(*tuner_lock_status_func_t) (struct tuner_instance *tuner,
+                                               enum tuner_lock_status *
+                                               lock_stat);
+
+typedef int(*tune_ri2c_write_read_func_t) (struct tuner_instance *tuner,
+                                               struct i2c_device_addr *
+                                               w_dev_addr, u16 w_count,
+                                               u8 *wData,
+                                               struct i2c_device_addr *
+                                               r_dev_addr, u16 r_count,
+                                               u8 *r_data);
+
+struct tuner_ops {
+       tuner_open_func_t open_func;
+       tuner_close_func_t close_func;
+       tuner_set_frequency_func_t set_frequency_func;
+       tuner_get_frequency_func_t get_frequency_func;
+       tuner_lock_status_func_t lock_status_func;
+       tune_ri2c_write_read_func_t i2c_write_read_func;
+
+};
+
+struct tuner_instance {
+       struct i2c_device_addr my_i2c_dev_addr;
+       struct tuner_common *my_common_attr;
+       void *my_ext_attr;
+       struct tuner_ops *my_funct;
+};
+
+int drxbsp_tuner_set_frequency(struct tuner_instance *tuner,
+                                       u32 mode,
+                                       s32 frequency);
+
+int drxbsp_tuner_get_frequency(struct tuner_instance *tuner,
+                                       u32 mode,
+                                       s32 *r_ffrequency,
+                                       s32 *i_ffrequency);
+
+int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
+                                               struct i2c_device_addr *w_dev_addr,
+                                               u16 w_count,
+                                               u8 *wData,
+                                               struct i2c_device_addr *r_dev_addr,
+                                               u16 r_count, u8 *r_data);
+
+/**************
+*
+* This section configures the DRX Data Access Protocols (DAPs).
+*
+**************/
+
+/**
+* \def DRXDAP_SINGLE_MASTER
+* \brief Enable I2C single or I2C multimaster mode on host.
+*
+* Set to 1 to enable single master mode
+* Set to 0 to enable multi master mode
+*
+* The actual DAP implementation may be restricted to only one of the modes.
+* A compiler warning or error will be generated if the DAP implementation
+* overides or cannot handle the mode defined below.
+*
+*/
+#ifndef DRXDAP_SINGLE_MASTER
+#define DRXDAP_SINGLE_MASTER 1
+#endif
+
+/**
+* \def DRXDAP_MAX_WCHUNKSIZE
+* \brief Defines maximum chunksize of an i2c write action by host.
+*
+* This indicates the maximum size of data the I2C device driver is able to
+* write at a time. This includes I2C device address and register addressing.
+*
+* This maximum size may be restricted by the actual DAP implementation.
+* A compiler warning or error will be generated if the DAP implementation
+* overides or cannot handle the chunksize defined below.
+*
+* Beware that the DAP uses  DRXDAP_MAX_WCHUNKSIZE to create a temporary data
+* buffer. Do not undefine or choose too large, unless your system is able to
+* handle a stack buffer of that size.
+*
+*/
+#ifndef DRXDAP_MAX_WCHUNKSIZE
+#define  DRXDAP_MAX_WCHUNKSIZE 60
+#endif
+
+/**
+* \def DRXDAP_MAX_RCHUNKSIZE
+* \brief Defines maximum chunksize of an i2c read action by host.
+*
+* This indicates the maximum size of data the I2C device driver is able to read
+* at a time. Minimum value is 2. Also, the read chunk size must be even.
+*
+* This maximum size may be restricted by the actual DAP implementation.
+* A compiler warning or error will be generated if the DAP implementation
+* overides or cannot handle the chunksize defined below.
+*
+*/
+#ifndef DRXDAP_MAX_RCHUNKSIZE
+#define  DRXDAP_MAX_RCHUNKSIZE 60
+#endif
+
+/**************
+*
+* This section describes drxdriver defines.
+*
+**************/
+
+/**
+* \def DRX_UNKNOWN
+* \brief Generic UNKNOWN value for DRX enumerated types.
+*
+* Used to indicate that the parameter value is unknown or not yet initalized.
+*/
+#ifndef DRX_UNKNOWN
+#define DRX_UNKNOWN (254)
+#endif
+
+/**
+* \def DRX_AUTO
+* \brief Generic AUTO value for DRX enumerated types.
+*
+* Used to instruct the driver to automatically determine the value of the
+* parameter.
+*/
+#ifndef DRX_AUTO
+#define DRX_AUTO    (255)
+#endif
+
+/**************
+*
+* This section describes flag definitions for the device capbilities.
+*
+**************/
+
+/**
+* \brief LNA capability flag
+*
+* Device has a Low Noise Amplifier
+*
+*/
+#define DRX_CAPABILITY_HAS_LNA           (1UL <<  0)
+/**
+* \brief OOB-RX capability flag
+*
+* Device has OOB-RX
+*
+*/
+#define DRX_CAPABILITY_HAS_OOBRX         (1UL <<  1)
+/**
+* \brief ATV capability flag
+*
+* Device has ATV
+*
+*/
+#define DRX_CAPABILITY_HAS_ATV           (1UL <<  2)
+/**
+* \brief DVB-T capability flag
+*
+* Device has DVB-T
+*
+*/
+#define DRX_CAPABILITY_HAS_DVBT          (1UL <<  3)
+/**
+* \brief  ITU-B capability flag
+*
+* Device has ITU-B
+*
+*/
+#define DRX_CAPABILITY_HAS_ITUB          (1UL <<  4)
+/**
+* \brief  Audio capability flag
+*
+* Device has Audio
+*
+*/
+#define DRX_CAPABILITY_HAS_AUD           (1UL <<  5)
+/**
+* \brief  SAW switch capability flag
+*
+* Device has SAW switch
+*
+*/
+#define DRX_CAPABILITY_HAS_SAWSW         (1UL <<  6)
+/**
+* \brief  GPIO1 capability flag
+*
+* Device has GPIO1
+*
+*/
+#define DRX_CAPABILITY_HAS_GPIO1         (1UL <<  7)
+/**
+* \brief  GPIO2 capability flag
+*
+* Device has GPIO2
+*
+*/
+#define DRX_CAPABILITY_HAS_GPIO2         (1UL <<  8)
+/**
+* \brief  IRQN capability flag
+*
+* Device has IRQN
+*
+*/
+#define DRX_CAPABILITY_HAS_IRQN          (1UL <<  9)
+/**
+* \brief  8VSB capability flag
+*
+* Device has 8VSB
+*
+*/
+#define DRX_CAPABILITY_HAS_8VSB          (1UL << 10)
+/**
+* \brief  SMA-TX capability flag
+*
+* Device has SMATX
+*
+*/
+#define DRX_CAPABILITY_HAS_SMATX         (1UL << 11)
+/**
+* \brief  SMA-RX capability flag
+*
+* Device has SMARX
+*
+*/
+#define DRX_CAPABILITY_HAS_SMARX         (1UL << 12)
+/**
+* \brief  ITU-A/C capability flag
+*
+* Device has ITU-A/C
+*
+*/
+#define DRX_CAPABILITY_HAS_ITUAC         (1UL << 13)
+
+/*-------------------------------------------------------------------------
+MACROS
+-------------------------------------------------------------------------*/
+/* Macros to stringify the version number */
+#define DRX_VERSIONSTRING(MAJOR, MINOR, PATCH) \
+        DRX_VERSIONSTRING_HELP(MAJOR)"." \
+        DRX_VERSIONSTRING_HELP(MINOR)"." \
+        DRX_VERSIONSTRING_HELP(PATCH)
+#define DRX_VERSIONSTRING_HELP(NUM) #NUM
+
+/**
+* \brief Macro to create byte array elements from 16 bit integers.
+* This macro is used to create byte arrays for block writes.
+* Block writes speed up I2C traffic between host and demod.
+* The macro takes care of the required byte order in a 16 bits word.
+* x->lowbyte(x), highbyte(x)
+*/
+#define DRX_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
+                       ((u8)((((u16)x)>>8)&0xFF))
+
+/**
+* \brief Macro to sign extend signed 9 bit value to signed  16 bit value
+*/
+#define DRX_S9TOS16(x) ((((u16)x)&0x100) ? ((s16)((u16)(x)|0xFF00)) : (x))
+
+/**
+* \brief Macro to sign extend signed 9 bit value to signed  16 bit value
+*/
+#define DRX_S24TODRXFREQ(x) ((((u32) x) & 0x00800000UL) ? \
+                                ((s32) \
+                                   (((u32) x) | 0xFF000000)) : \
+                                ((s32) x))
+
+/**
+* \brief Macro to convert 16 bit register value to a s32
+*/
+#define DRX_U16TODRXFREQ(x)   ((x & 0x8000) ? \
+                                ((s32) \
+                                   (((u32) x) | 0xFFFF0000)) : \
+                                ((s32) x))
+
+/*-------------------------------------------------------------------------
+ENUM
+-------------------------------------------------------------------------*/
+
+/**
+* \enum enum drx_standard
+* \brief Modulation standards.
+*/
+enum drx_standard {
+       DRX_STANDARD_DVBT = 0, /**< Terrestrial DVB-T.               */
+       DRX_STANDARD_8VSB,     /**< Terrestrial 8VSB.                */
+       DRX_STANDARD_NTSC,     /**< Terrestrial\Cable analog NTSC.   */
+       DRX_STANDARD_PAL_SECAM_BG,
+                               /**< Terrestrial analog PAL/SECAM B/G */
+       DRX_STANDARD_PAL_SECAM_DK,
+                               /**< Terrestrial analog PAL/SECAM D/K */
+       DRX_STANDARD_PAL_SECAM_I,
+                               /**< Terrestrial analog PAL/SECAM I   */
+       DRX_STANDARD_PAL_SECAM_L,
+                               /**< Terrestrial analog PAL/SECAM L
+                                       with negative modulation        */
+       DRX_STANDARD_PAL_SECAM_LP,
+                               /**< Terrestrial analog PAL/SECAM L
+                                       with positive modulation        */
+       DRX_STANDARD_ITU_A,    /**< Cable ITU ANNEX A.               */
+       DRX_STANDARD_ITU_B,    /**< Cable ITU ANNEX B.               */
+       DRX_STANDARD_ITU_C,    /**< Cable ITU ANNEX C.               */
+       DRX_STANDARD_ITU_D,    /**< Cable ITU ANNEX D.               */
+       DRX_STANDARD_FM,       /**< Terrestrial\Cable FM radio       */
+       DRX_STANDARD_DTMB,     /**< Terrestrial DTMB standard (China)*/
+       DRX_STANDARD_UNKNOWN = DRX_UNKNOWN,
+                               /**< Standard unknown.                */
+       DRX_STANDARD_AUTO = DRX_AUTO
+                               /**< Autodetect standard.             */
+};
+
+/**
+* \enum enum drx_standard
+* \brief Modulation sub-standards.
+*/
+enum drx_substandard {
+       DRX_SUBSTANDARD_MAIN = 0, /**< Main subvariant of standard   */
+       DRX_SUBSTANDARD_ATV_BG_SCANDINAVIA,
+       DRX_SUBSTANDARD_ATV_DK_POLAND,
+       DRX_SUBSTANDARD_ATV_DK_CHINA,
+       DRX_SUBSTANDARD_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Sub-standard unknown.         */
+       DRX_SUBSTANDARD_AUTO = DRX_AUTO
+                                       /**< Auto (default) sub-standard   */
+};
+
+/**
+* \enum enum drx_bandwidth
+* \brief Channel bandwidth or channel spacing.
+*/
+enum drx_bandwidth {
+       DRX_BANDWIDTH_8MHZ = 0,  /**< Bandwidth 8 MHz.   */
+       DRX_BANDWIDTH_7MHZ,      /**< Bandwidth 7 MHz.   */
+       DRX_BANDWIDTH_6MHZ,      /**< Bandwidth 6 MHz.   */
+       DRX_BANDWIDTH_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Bandwidth unknown. */
+       DRX_BANDWIDTH_AUTO = DRX_AUTO
+                                       /**< Auto Set Bandwidth */
+};
+
+/**
+* \enum enum drx_mirror
+* \brief Indicate if channel spectrum is mirrored or not.
+*/
+enum drx_mirror {
+       DRX_MIRROR_NO = 0,   /**< Spectrum is not mirrored.           */
+       DRX_MIRROR_YES,      /**< Spectrum is mirrored.               */
+       DRX_MIRROR_UNKNOWN = DRX_UNKNOWN,
+                               /**< Unknown if spectrum is mirrored.    */
+       DRX_MIRROR_AUTO = DRX_AUTO
+                               /**< Autodetect if spectrum is mirrored. */
+};
+
+/**
+* \enum enum drx_modulation
+* \brief Constellation type of the channel.
+*/
+enum drx_modulation {
+       DRX_CONSTELLATION_BPSK = 0,  /**< Modulation is BPSK.       */
+       DRX_CONSTELLATION_QPSK,      /**< Constellation is QPSK.    */
+       DRX_CONSTELLATION_PSK8,      /**< Constellation is PSK8.    */
+       DRX_CONSTELLATION_QAM16,     /**< Constellation is QAM16.   */
+       DRX_CONSTELLATION_QAM32,     /**< Constellation is QAM32.   */
+       DRX_CONSTELLATION_QAM64,     /**< Constellation is QAM64.   */
+       DRX_CONSTELLATION_QAM128,    /**< Constellation is QAM128.  */
+       DRX_CONSTELLATION_QAM256,    /**< Constellation is QAM256.  */
+       DRX_CONSTELLATION_QAM512,    /**< Constellation is QAM512.  */
+       DRX_CONSTELLATION_QAM1024,   /**< Constellation is QAM1024. */
+       DRX_CONSTELLATION_QPSK_NR,   /**< Constellation is QPSK_NR  */
+       DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Constellation unknown.    */
+       DRX_CONSTELLATION_AUTO = DRX_AUTO
+                                       /**< Autodetect constellation. */
+};
+
+/**
+* \enum enum drx_hierarchy
+* \brief Hierarchy of the channel.
+*/
+enum drx_hierarchy {
+       DRX_HIERARCHY_NONE = 0, /**< None hierarchical channel.     */
+       DRX_HIERARCHY_ALPHA1,   /**< Hierarchical channel, alpha=1. */
+       DRX_HIERARCHY_ALPHA2,   /**< Hierarchical channel, alpha=2. */
+       DRX_HIERARCHY_ALPHA4,   /**< Hierarchical channel, alpha=4. */
+       DRX_HIERARCHY_UNKNOWN = DRX_UNKNOWN,
+                               /**< Hierarchy unknown.             */
+       DRX_HIERARCHY_AUTO = DRX_AUTO
+                               /**< Autodetect hierarchy.          */
+};
+
+/**
+* \enum enum drx_priority
+* \brief Channel priority in case of hierarchical transmission.
+*/
+enum drx_priority {
+       DRX_PRIORITY_LOW = 0,  /**< Low priority channel.  */
+       DRX_PRIORITY_HIGH,     /**< High priority channel. */
+       DRX_PRIORITY_UNKNOWN = DRX_UNKNOWN
+                               /**< Priority unknown.      */
+};
+
+/**
+* \enum enum drx_coderate
+* \brief Channel priority in case of hierarchical transmission.
+*/
+enum drx_coderate {
+               DRX_CODERATE_1DIV2 = 0, /**< Code rate 1/2nd.      */
+               DRX_CODERATE_2DIV3,     /**< Code rate 2/3nd.      */
+               DRX_CODERATE_3DIV4,     /**< Code rate 3/4nd.      */
+               DRX_CODERATE_5DIV6,     /**< Code rate 5/6nd.      */
+               DRX_CODERATE_7DIV8,     /**< Code rate 7/8nd.      */
+               DRX_CODERATE_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Code rate unknown.    */
+               DRX_CODERATE_AUTO = DRX_AUTO
+                                       /**< Autodetect code rate. */
+};
+
+/**
+* \enum enum drx_guard
+* \brief Guard interval of a channel.
+*/
+enum drx_guard {
+       DRX_GUARD_1DIV32 = 0, /**< Guard interval 1/32nd.     */
+       DRX_GUARD_1DIV16,     /**< Guard interval 1/16th.     */
+       DRX_GUARD_1DIV8,      /**< Guard interval 1/8th.      */
+       DRX_GUARD_1DIV4,      /**< Guard interval 1/4th.      */
+       DRX_GUARD_UNKNOWN = DRX_UNKNOWN,
+                               /**< Guard interval unknown.    */
+       DRX_GUARD_AUTO = DRX_AUTO
+                               /**< Autodetect guard interval. */
+};
+
+/**
+* \enum enum drx_fft_mode
+* \brief FFT mode.
+*/
+enum drx_fft_mode {
+       DRX_FFTMODE_2K = 0,    /**< 2K FFT mode.         */
+       DRX_FFTMODE_4K,        /**< 4K FFT mode.         */
+       DRX_FFTMODE_8K,        /**< 8K FFT mode.         */
+       DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
+                               /**< FFT mode unknown.    */
+       DRX_FFTMODE_AUTO = DRX_AUTO
+                               /**< Autodetect FFT mode. */
+};
+
+/**
+* \enum enum drx_classification
+* \brief Channel classification.
+*/
+enum drx_classification {
+       DRX_CLASSIFICATION_GAUSS = 0, /**< Gaussion noise.            */
+       DRX_CLASSIFICATION_HVY_GAUSS, /**< Heavy Gaussion noise.      */
+       DRX_CLASSIFICATION_COCHANNEL, /**< Co-channel.                */
+       DRX_CLASSIFICATION_STATIC,    /**< Static echo.               */
+       DRX_CLASSIFICATION_MOVING,    /**< Moving echo.               */
+       DRX_CLASSIFICATION_ZERODB,    /**< Zero dB echo.              */
+       DRX_CLASSIFICATION_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Unknown classification     */
+       DRX_CLASSIFICATION_AUTO = DRX_AUTO
+                                       /**< Autodetect classification. */
+};
+
+/**
+* /enum enum drx_interleave_mode
+* /brief Interleave modes
+*/
+enum drx_interleave_mode {
+       DRX_INTERLEAVEMODE_I128_J1 = 0,
+       DRX_INTERLEAVEMODE_I128_J1_V2,
+       DRX_INTERLEAVEMODE_I128_J2,
+       DRX_INTERLEAVEMODE_I64_J2,
+       DRX_INTERLEAVEMODE_I128_J3,
+       DRX_INTERLEAVEMODE_I32_J4,
+       DRX_INTERLEAVEMODE_I128_J4,
+       DRX_INTERLEAVEMODE_I16_J8,
+       DRX_INTERLEAVEMODE_I128_J5,
+       DRX_INTERLEAVEMODE_I8_J16,
+       DRX_INTERLEAVEMODE_I128_J6,
+       DRX_INTERLEAVEMODE_RESERVED_11,
+       DRX_INTERLEAVEMODE_I128_J7,
+       DRX_INTERLEAVEMODE_RESERVED_13,
+       DRX_INTERLEAVEMODE_I128_J8,
+       DRX_INTERLEAVEMODE_RESERVED_15,
+       DRX_INTERLEAVEMODE_I12_J17,
+       DRX_INTERLEAVEMODE_I5_J4,
+       DRX_INTERLEAVEMODE_B52_M240,
+       DRX_INTERLEAVEMODE_B52_M720,
+       DRX_INTERLEAVEMODE_B52_M48,
+       DRX_INTERLEAVEMODE_B52_M0,
+       DRX_INTERLEAVEMODE_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Unknown interleave mode    */
+       DRX_INTERLEAVEMODE_AUTO = DRX_AUTO
+                                       /**< Autodetect interleave mode */
+};
+
+/**
+* \enum enum drx_carrier_mode
+* \brief Channel Carrier Mode.
+*/
+enum drx_carrier_mode {
+       DRX_CARRIER_MULTI = 0,          /**< Multi carrier mode       */
+       DRX_CARRIER_SINGLE,             /**< Single carrier mode      */
+       DRX_CARRIER_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Carrier mode unknown.    */
+       DRX_CARRIER_AUTO = DRX_AUTO     /**< Autodetect carrier mode  */
+};
+
+/**
+* \enum enum drx_frame_mode
+* \brief Channel Frame Mode.
+*/
+enum drx_frame_mode {
+       DRX_FRAMEMODE_420 = 0,   /**< 420 with variable PN  */
+       DRX_FRAMEMODE_595,       /**< 595                   */
+       DRX_FRAMEMODE_945,       /**< 945 with variable PN  */
+       DRX_FRAMEMODE_420_FIXED_PN,
+                                       /**< 420 with fixed PN     */
+       DRX_FRAMEMODE_945_FIXED_PN,
+                                       /**< 945 with fixed PN     */
+       DRX_FRAMEMODE_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Frame mode unknown.   */
+       DRX_FRAMEMODE_AUTO = DRX_AUTO
+                                       /**< Autodetect frame mode */
+};
+
+/**
+* \enum enum drx_tps_frame
+* \brief Frame number in current super-frame.
+*/
+enum drx_tps_frame {
+       DRX_TPS_FRAME1 = 0,       /**< TPS frame 1.       */
+       DRX_TPS_FRAME2,           /**< TPS frame 2.       */
+       DRX_TPS_FRAME3,           /**< TPS frame 3.       */
+       DRX_TPS_FRAME4,           /**< TPS frame 4.       */
+       DRX_TPS_FRAME_UNKNOWN = DRX_UNKNOWN
+                                       /**< TPS frame unknown. */
+};
+
+/**
+* \enum enum drx_ldpc
+* \brief TPS LDPC .
+*/
+enum drx_ldpc {
+       DRX_LDPC_0_4 = 0,         /**< LDPC 0.4           */
+       DRX_LDPC_0_6,             /**< LDPC 0.6           */
+       DRX_LDPC_0_8,             /**< LDPC 0.8           */
+       DRX_LDPC_UNKNOWN = DRX_UNKNOWN,
+                                       /**< LDPC unknown.      */
+       DRX_LDPC_AUTO = DRX_AUTO  /**< Autodetect LDPC    */
+};
+
+/**
+* \enum enum drx_pilot_mode
+* \brief Pilot modes in DTMB.
+*/
+enum drx_pilot_mode {
+       DRX_PILOT_ON = 0,         /**< Pilot On             */
+       DRX_PILOT_OFF,            /**< Pilot Off            */
+       DRX_PILOT_UNKNOWN = DRX_UNKNOWN,
+                                       /**< Pilot unknown.       */
+       DRX_PILOT_AUTO = DRX_AUTO /**< Autodetect Pilot     */
+};
+
+/**
+ * enum drxu_code_action - indicate if firmware has to be uploaded or verified.
+ * @UCODE_UPLOAD:      Upload the microcode image to device
+ * @UCODE_VERIFY:      Compare microcode image with code on device
+ */
+enum drxu_code_action {
+       UCODE_UPLOAD,
+       UCODE_VERIFY
+};
+
+/**
+* \enum enum drx_lock_status * \brief Used to reflect current lock status of demodulator.
+*
+* The generic lock states have device dependent semantics.
+
+               DRX_NEVER_LOCK = 0,
+                             **< Device will never lock on this signal *
+               DRX_NOT_LOCKED,
+                             **< Device has no lock at all             *
+               DRX_LOCK_STATE_1,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_2,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_3,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_4,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_5,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_6,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_7,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_8,
+                             **< Generic lock state                    *
+               DRX_LOCK_STATE_9,
+                             **< Generic lock state                    *
+               DRX_LOCKED    **< Device is in lock                     *
+*/
+
+enum drx_lock_status {
+       DRX_NEVER_LOCK = 0,
+       DRX_NOT_LOCKED,
+       DRX_LOCK_STATE_1,
+       DRX_LOCK_STATE_2,
+       DRX_LOCK_STATE_3,
+       DRX_LOCK_STATE_4,
+       DRX_LOCK_STATE_5,
+       DRX_LOCK_STATE_6,
+       DRX_LOCK_STATE_7,
+       DRX_LOCK_STATE_8,
+       DRX_LOCK_STATE_9,
+       DRX_LOCKED
+};
+
+/**
+* \enum enum drx_uio* \brief Used to address a User IO (UIO).
+*/
+enum drx_uio {
+       DRX_UIO1,
+       DRX_UIO2,
+       DRX_UIO3,
+       DRX_UIO4,
+       DRX_UIO5,
+       DRX_UIO6,
+       DRX_UIO7,
+       DRX_UIO8,
+       DRX_UIO9,
+       DRX_UIO10,
+       DRX_UIO11,
+       DRX_UIO12,
+       DRX_UIO13,
+       DRX_UIO14,
+       DRX_UIO15,
+       DRX_UIO16,
+       DRX_UIO17,
+       DRX_UIO18,
+       DRX_UIO19,
+       DRX_UIO20,
+       DRX_UIO21,
+       DRX_UIO22,
+       DRX_UIO23,
+       DRX_UIO24,
+       DRX_UIO25,
+       DRX_UIO26,
+       DRX_UIO27,
+       DRX_UIO28,
+       DRX_UIO29,
+       DRX_UIO30,
+       DRX_UIO31,
+       DRX_UIO32,
+       DRX_UIO_MAX = DRX_UIO32
+};
+
+/**
+* \enum enum drxuio_mode * \brief Used to configure the modus oprandi of a UIO.
+*
+* DRX_UIO_MODE_FIRMWARE is an old uio mode.
+* It is replaced by the modes DRX_UIO_MODE_FIRMWARE0 .. DRX_UIO_MODE_FIRMWARE9.
+* To be backward compatible DRX_UIO_MODE_FIRMWARE is equivalent to
+* DRX_UIO_MODE_FIRMWARE0.
+*/
+enum drxuio_mode {
+       DRX_UIO_MODE_DISABLE = 0x01,
+                           /**< not used, pin is configured as input */
+       DRX_UIO_MODE_READWRITE = 0x02,
+                           /**< used for read/write by application   */
+       DRX_UIO_MODE_FIRMWARE = 0x04,
+                           /**< controlled by firmware, function 0   */
+       DRX_UIO_MODE_FIRMWARE0 = DRX_UIO_MODE_FIRMWARE,
+                                           /**< same as above        */
+       DRX_UIO_MODE_FIRMWARE1 = 0x08,
+                           /**< controlled by firmware, function 1   */
+       DRX_UIO_MODE_FIRMWARE2 = 0x10,
+                           /**< controlled by firmware, function 2   */
+       DRX_UIO_MODE_FIRMWARE3 = 0x20,
+                           /**< controlled by firmware, function 3   */
+       DRX_UIO_MODE_FIRMWARE4 = 0x40,
+                           /**< controlled by firmware, function 4   */
+       DRX_UIO_MODE_FIRMWARE5 = 0x80
+                           /**< controlled by firmware, function 5   */
+};
+
+/**
+* \enum enum drxoob_downstream_standard * \brief Used to select OOB standard.
+*
+* Based on ANSI 55-1 and 55-2
+*/
+enum drxoob_downstream_standard {
+       DRX_OOB_MODE_A = 0,
+                      /**< ANSI 55-1   */
+       DRX_OOB_MODE_B_GRADE_A,
+                      /**< ANSI 55-2 A */
+       DRX_OOB_MODE_B_GRADE_B
+                      /**< ANSI 55-2 B */
+};
+
+/*-------------------------------------------------------------------------
+STRUCTS
+-------------------------------------------------------------------------*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*== CTRL CFG related data structures ========================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+#ifndef DRX_CFG_BASE
+#define DRX_CFG_BASE          0
+#endif
+
+#define DRX_CFG_MPEG_OUTPUT         (DRX_CFG_BASE +  0)        /* MPEG TS output    */
+#define DRX_CFG_PKTERR              (DRX_CFG_BASE +  1)        /* Packet Error      */
+#define DRX_CFG_SYMCLK_OFFS         (DRX_CFG_BASE +  2)        /* Symbol Clk Offset */
+#define DRX_CFG_SMA                 (DRX_CFG_BASE +  3)        /* Smart Antenna     */
+#define DRX_CFG_PINSAFE             (DRX_CFG_BASE +  4)        /* Pin safe mode     */
+#define DRX_CFG_SUBSTANDARD         (DRX_CFG_BASE +  5)        /* substandard       */
+#define DRX_CFG_AUD_VOLUME          (DRX_CFG_BASE +  6)        /* volume            */
+#define DRX_CFG_AUD_RDS             (DRX_CFG_BASE +  7)        /* rds               */
+#define DRX_CFG_AUD_AUTOSOUND       (DRX_CFG_BASE +  8)        /* ASS & ASC         */
+#define DRX_CFG_AUD_ASS_THRES       (DRX_CFG_BASE +  9)        /* ASS Thresholds    */
+#define DRX_CFG_AUD_DEVIATION       (DRX_CFG_BASE + 10)        /* Deviation         */
+#define DRX_CFG_AUD_PRESCALE        (DRX_CFG_BASE + 11)        /* Prescale          */
+#define DRX_CFG_AUD_MIXER           (DRX_CFG_BASE + 12)        /* Mixer             */
+#define DRX_CFG_AUD_AVSYNC          (DRX_CFG_BASE + 13)        /* AVSync            */
+#define DRX_CFG_AUD_CARRIER         (DRX_CFG_BASE + 14)        /* Audio carriers    */
+#define DRX_CFG_I2S_OUTPUT          (DRX_CFG_BASE + 15)        /* I2S output        */
+#define DRX_CFG_ATV_STANDARD        (DRX_CFG_BASE + 16)        /* ATV standard      */
+#define DRX_CFG_SQI_SPEED           (DRX_CFG_BASE + 17)        /* SQI speed         */
+#define DRX_CTRL_CFG_MAX            (DRX_CFG_BASE + 18)        /* never to be used  */
+
+#define DRX_CFG_PINS_SAFE_MODE      DRX_CFG_PINSAFE
+/*============================================================================*/
+/*============================================================================*/
+/*== CTRL related data structures ============================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+/**
+ * struct drxu_code_info       Parameters for microcode upload and verfiy.
+ *
+ * @mc_file:   microcode file name
+ *
+ * Used by DRX_CTRL_LOAD_UCODE and DRX_CTRL_VERIFY_UCODE
+ */
+struct drxu_code_info {
+       char                    *mc_file;
+};
+
+/**
+* \struct drx_mc_version_rec_t
+* \brief Microcode version record
+* Version numbers are stored in BCD format, as usual:
+*   o major number = bits 31-20 (first three nibbles of MSW)
+*   o minor number = bits 19-16 (fourth nibble of MSW)
+*   o patch number = bits 15-0  (remaining nibbles in LSW)
+*
+* The device type indicates for which the device is meant. It is based on the
+* JTAG ID, using everything except the bond ID and the metal fix.
+*
+* Special values:
+* - mc_dev_type == 0         => any device allowed
+* - mc_base_version == 0.0.0 => full microcode (mc_version is the version)
+* - mc_base_version != 0.0.0 => patch microcode, the base microcode version
+*                             (mc_version is the version)
+*/
+#define AUX_VER_RECORD 0x8000
+
+struct drx_mc_version_rec {
+       u16 aux_type;   /* type of aux data - 0x8000 for version record     */
+       u32 mc_dev_type;        /* device type, based on JTAG ID                    */
+       u32 mc_version; /* version of microcode                             */
+       u32 mc_base_version;    /* in case of patch: the original microcode version */
+};
+
+/*========================================*/
+
+/**
+* \struct drx_filter_info_t
+* \brief Parameters for loading filter coefficients
+*
+* Used by DRX_CTRL_LOAD_FILTER
+*/
+struct drx_filter_info {
+       u8 *data_re;
+             /**< pointer to coefficients for RE */
+       u8 *data_im;
+             /**< pointer to coefficients for IM */
+       u16 size_re;
+             /**< size of coefficients for RE    */
+       u16 size_im;
+             /**< size of coefficients for IM    */
+};
+
+/*========================================*/
+
+/**
+* \struct struct drx_channel * \brief The set of parameters describing a single channel.
+*
+* Used by DRX_CTRL_SET_CHANNEL and DRX_CTRL_GET_CHANNEL.
+* Only certain fields need to be used for a specfic standard.
+*
+*/
+struct drx_channel {
+       s32 frequency;
+                               /**< frequency in kHz                 */
+       enum drx_bandwidth bandwidth;
+                               /**< bandwidth                        */
+       enum drx_mirror mirror; /**< mirrored or not on RF            */
+       enum drx_modulation constellation;
+                               /**< constellation                    */
+       enum drx_hierarchy hierarchy;
+                               /**< hierarchy                        */
+       enum drx_priority priority;     /**< priority                         */
+       enum drx_coderate coderate;     /**< coderate                         */
+       enum drx_guard guard;   /**< guard interval                   */
+       enum drx_fft_mode fftmode;      /**< fftmode                          */
+       enum drx_classification classification;
+                               /**< classification                   */
+       u32 symbolrate;
+                               /**< symbolrate in symbols/sec        */
+       enum drx_interleave_mode interleavemode;
+                               /**< interleaveMode QAM               */
+       enum drx_ldpc ldpc;             /**< ldpc                             */
+       enum drx_carrier_mode carrier;  /**< carrier                          */
+       enum drx_frame_mode framemode;
+                               /**< frame mode                       */
+       enum drx_pilot_mode pilot;      /**< pilot mode                       */
+};
+
+/*========================================*/
+
+enum drx_cfg_sqi_speed {
+       DRX_SQI_SPEED_FAST = 0,
+       DRX_SQI_SPEED_MEDIUM,
+       DRX_SQI_SPEED_SLOW,
+       DRX_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
+};
+
+/*========================================*/
+
+/**
+* \struct struct drx_complex * A complex number.
+*
+* Used by DRX_CTRL_CONSTEL.
+*/
+struct drx_complex {
+       s16 im;
+     /**< Imaginary part. */
+       s16 re;
+     /**< Real part.      */
+};
+
+/*========================================*/
+
+/**
+* \struct struct drx_frequency_plan * Array element of a frequency plan.
+*
+* Used by DRX_CTRL_SCAN_INIT.
+*/
+struct drx_frequency_plan {
+       s32 first;
+                    /**< First centre frequency in this band        */
+       s32 last;
+                    /**< Last centre frequency in this band         */
+       s32 step;
+                    /**< Stepping frequency in this band            */
+       enum drx_bandwidth bandwidth;
+                    /**< Bandwidth within this frequency band       */
+       u16 ch_number;
+                    /**< First channel number in this band, or first
+                           index in ch_names                         */
+       char **ch_names;
+                    /**< Optional list of channel names in this
+                           band                                     */
+};
+
+/*========================================*/
+
+/**
+* \struct struct drx_scan_param * Parameters for channel scan.
+*
+* Used by DRX_CTRL_SCAN_INIT.
+*/
+struct drx_scan_param {
+       struct drx_frequency_plan *frequency_plan;
+                                 /**< Frequency plan (array)*/
+       u16 frequency_plan_size;  /**< Number of bands       */
+       u32 num_tries;            /**< Max channels tried    */
+       s32 skip;         /**< Minimum frequency step to take
+                                       after a channel is found */
+       void *ext_params;         /**< Standard specific params */
+};
+
+/*========================================*/
+
+/**
+* \brief Scan commands.
+* Used by scanning algorithms.
+*/
+enum drx_scan_command {
+               DRX_SCAN_COMMAND_INIT = 0,/**< Initialize scanning */
+               DRX_SCAN_COMMAND_NEXT,    /**< Next scan           */
+               DRX_SCAN_COMMAND_STOP     /**< Stop scanning       */
+};
+
+/*========================================*/
+
+/**
+* \brief Inner scan function prototype.
+*/
+typedef int(*drx_scan_func_t) (void *scan_context,
+                                    enum drx_scan_command scan_command,
+                                    struct drx_channel *scan_channel,
+                                    bool *get_next_channel);
+
+/*========================================*/
+
+/**
+* \struct struct drxtps_info * TPS information, DVB-T specific.
+*
+* Used by DRX_CTRL_TPS_INFO.
+*/
+       struct drxtps_info {
+               enum drx_fft_mode fftmode;      /**< Fft mode       */
+               enum drx_guard guard;   /**< Guard interval */
+               enum drx_modulation constellation;
+                                       /**< Constellation  */
+               enum drx_hierarchy hierarchy;
+                                       /**< Hierarchy      */
+               enum drx_coderate high_coderate;
+                                       /**< High code rate */
+               enum drx_coderate low_coderate;
+                                       /**< Low cod rate   */
+               enum drx_tps_frame frame;       /**< Tps frame      */
+               u8 length;              /**< Length         */
+               u16 cell_id;            /**< Cell id        */
+       };
+
+/*========================================*/
+
+/**
+* \brief Power mode of device.
+*
+* Used by DRX_CTRL_SET_POWER_MODE.
+*/
+       enum drx_power_mode {
+               DRX_POWER_UP = 0,
+                        /**< Generic         , Power Up Mode   */
+               DRX_POWER_MODE_1,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_2,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_3,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_4,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_5,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_6,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_7,
+                        /**< Device specific , Power Up Mode   */
+               DRX_POWER_MODE_8,
+                        /**< Device specific , Power Up Mode   */
+
+               DRX_POWER_MODE_9,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_10,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_11,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_12,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_13,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_14,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_15,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_MODE_16,
+                        /**< Device specific , Power Down Mode */
+               DRX_POWER_DOWN = 255
+                        /**< Generic         , Power Down Mode */
+       };
+
+/*========================================*/
+
+/**
+* \enum enum drx_module * \brief Software module identification.
+*
+* Used by DRX_CTRL_VERSION.
+*/
+       enum drx_module {
+               DRX_MODULE_DEVICE,
+               DRX_MODULE_MICROCODE,
+               DRX_MODULE_DRIVERCORE,
+               DRX_MODULE_DEVICEDRIVER,
+               DRX_MODULE_DAP,
+               DRX_MODULE_BSP_I2C,
+               DRX_MODULE_BSP_TUNER,
+               DRX_MODULE_BSP_HOST,
+               DRX_MODULE_UNKNOWN
+       };
+
+/**
+* \enum struct drx_version * \brief Version information of one software module.
+*
+* Used by DRX_CTRL_VERSION.
+*/
+       struct drx_version {
+               enum drx_module module_type;
+                              /**< Type identifier of the module */
+               char *module_name;
+                              /**< Name or description of module */
+               u16 v_major;  /**< Major version number          */
+               u16 v_minor;  /**< Minor version number          */
+               u16 v_patch;  /**< Patch version number          */
+               char *v_string; /**< Version as text string        */
+       };
+
+/**
+* \enum struct drx_version_list * \brief List element of NULL terminated, linked list for version information.
+*
+* Used by DRX_CTRL_VERSION.
+*/
+struct drx_version_list {
+       struct drx_version *version;/**< Version information */
+       struct drx_version_list *next;
+                             /**< Next list element   */
+};
+
+/*========================================*/
+
+/**
+* \brief Parameters needed to confiugure a UIO.
+*
+* Used by DRX_CTRL_UIO_CFG.
+*/
+       struct drxuio_cfg {
+               enum drx_uio uio;
+                      /**< UIO identifier       */
+               enum drxuio_mode mode;
+                      /**< UIO operational mode */
+       };
+
+/*========================================*/
+
+/**
+* \brief Parameters needed to read from or write to a UIO.
+*
+* Used by DRX_CTRL_UIO_READ and DRX_CTRL_UIO_WRITE.
+*/
+       struct drxuio_data {
+               enum drx_uio uio;
+                  /**< UIO identifier              */
+               bool value;
+                  /**< UIO value (true=1, false=0) */
+       };
+
+/*========================================*/
+
+/**
+* \brief Parameters needed to configure OOB.
+*
+* Used by DRX_CTRL_SET_OOB.
+*/
+       struct drxoob {
+               s32 frequency;     /**< Frequency in kHz      */
+               enum drxoob_downstream_standard standard;
+                                                  /**< OOB standard          */
+               bool spectrum_inverted;    /**< If true, then spectrum
+                                                        is inverted          */
+       };
+
+/*========================================*/
+
+/**
+* \brief Metrics from OOB.
+*
+* Used by DRX_CTRL_GET_OOB.
+*/
+       struct drxoob_status {
+               s32 frequency; /**< Frequency in Khz         */
+               enum drx_lock_status lock;        /**< Lock status              */
+               u32 mer;                  /**< MER                      */
+               s32 symbol_rate_offset;   /**< Symbolrate offset in ppm */
+       };
+
+/*========================================*/
+
+/**
+* \brief Device dependent configuration data.
+*
+* Used by DRX_CTRL_SET_CFG and DRX_CTRL_GET_CFG.
+* A sort of nested drx_ctrl() functionality for device specific controls.
+*/
+       struct drx_cfg {
+               u32 cfg_type;
+                         /**< Function identifier */
+               void *cfg_data;
+                         /**< Function data */
+       };
+
+/*========================================*/
+
+/**
+* /struct DRXMpegStartWidth_t
+* MStart width [nr MCLK cycles] for serial MPEG output.
+*/
+
+       enum drxmpeg_str_width {
+               DRX_MPEG_STR_WIDTH_1,
+               DRX_MPEG_STR_WIDTH_8
+       };
+
+/* CTRL CFG MPEG ouput */
+/**
+* \struct struct drx_cfg_mpeg_output * \brief Configuartion parameters for MPEG output control.
+*
+* Used by DRX_CFG_MPEG_OUTPUT, in combination with DRX_CTRL_SET_CFG and
+* DRX_CTRL_GET_CFG.
+*/
+
+       struct drx_cfg_mpeg_output {
+               bool enable_mpeg_output;/**< If true, enable MPEG output      */
+               bool insert_rs_byte;    /**< If true, insert RS byte          */
+               bool enable_parallel;   /**< If true, parallel out otherwise
+                                                                    serial   */
+               bool invert_data;       /**< If true, invert DATA signals     */
+               bool invert_err;        /**< If true, invert ERR signal       */
+               bool invert_str;        /**< If true, invert STR signals      */
+               bool invert_val;        /**< If true, invert VAL signals      */
+               bool invert_clk;        /**< If true, invert CLK signals      */
+               bool static_clk;        /**< If true, static MPEG clockrate
+                                            will be used, otherwise clockrate
+                                            will adapt to the bitrate of the
+                                            TS                               */
+               u32 bitrate;            /**< Maximum bitrate in b/s in case
+                                            static clockrate is selected     */
+               enum drxmpeg_str_width width_str;
+                                       /**< MPEG start width                 */
+       };
+
+
+/*========================================*/
+
+/**
+* \struct struct drxi2c_data * \brief Data for I2C via 2nd or 3rd or etc I2C port.
+*
+* Used by DRX_CTRL_I2C_READWRITE.
+* If port_nr is equal to primairy port_nr BSPI2C will be used.
+*
+*/
+       struct drxi2c_data {
+               u16 port_nr;    /**< I2C port number               */
+               struct i2c_device_addr *w_dev_addr;
+                               /**< Write device address          */
+               u16 w_count;    /**< Size of write data in bytes   */
+               u8 *wData;      /**< Pointer to write data         */
+               struct i2c_device_addr *r_dev_addr;
+                               /**< Read device address           */
+               u16 r_count;    /**< Size of data to read in bytes */
+               u8 *r_data;     /**< Pointer to read buffer        */
+       };
+
+/*========================================*/
+
+/**
+* \enum enum drx_aud_standard * \brief Audio standard identifier.
+*
+* Used by DRX_CTRL_SET_AUD.
+*/
+       enum drx_aud_standard {
+               DRX_AUD_STANDARD_BTSC,     /**< set BTSC standard (USA)       */
+               DRX_AUD_STANDARD_A2,       /**< set A2-Korea FM Stereo        */
+               DRX_AUD_STANDARD_EIAJ,     /**< set to Japanese FM Stereo     */
+               DRX_AUD_STANDARD_FM_STEREO,/**< set to FM-Stereo Radio        */
+               DRX_AUD_STANDARD_M_MONO,   /**< for 4.5 MHz mono detected     */
+               DRX_AUD_STANDARD_D_K_MONO, /**< for 6.5 MHz mono detected     */
+               DRX_AUD_STANDARD_BG_FM,    /**< set BG_FM standard            */
+               DRX_AUD_STANDARD_D_K1,     /**< set D_K1 standard             */
+               DRX_AUD_STANDARD_D_K2,     /**< set D_K2 standard             */
+               DRX_AUD_STANDARD_D_K3,     /**< set D_K3 standard             */
+               DRX_AUD_STANDARD_BG_NICAM_FM,
+                                          /**< set BG_NICAM_FM standard      */
+               DRX_AUD_STANDARD_L_NICAM_AM,
+                                          /**< set L_NICAM_AM standard       */
+               DRX_AUD_STANDARD_I_NICAM_FM,
+                                          /**< set I_NICAM_FM standard       */
+               DRX_AUD_STANDARD_D_K_NICAM_FM,
+                                          /**< set D_K_NICAM_FM standard     */
+               DRX_AUD_STANDARD_NOT_READY,/**< used to detect audio standard */
+               DRX_AUD_STANDARD_AUTO = DRX_AUTO,
+                                          /**< Automatic Standard Detection  */
+               DRX_AUD_STANDARD_UNKNOWN = DRX_UNKNOWN
+                                          /**< used as auto and for readback */
+       };
+
+/* CTRL_AUD_GET_STATUS    - struct drx_aud_status */
+/**
+* \enum enum drx_aud_nicam_status * \brief Status of NICAM carrier.
+*/
+       enum drx_aud_nicam_status {
+               DRX_AUD_NICAM_DETECTED = 0,
+                                         /**< NICAM carrier detected         */
+               DRX_AUD_NICAM_NOT_DETECTED,
+                                         /**< NICAM carrier not detected     */
+               DRX_AUD_NICAM_BAD         /**< NICAM carrier bad quality      */
+       };
+
+/**
+* \struct struct drx_aud_status * \brief Audio status characteristics.
+*/
+       struct drx_aud_status {
+               bool stereo;              /**< stereo detection               */
+               bool carrier_a;   /**< carrier A detected             */
+               bool carrier_b;   /**< carrier B detected             */
+               bool sap;                 /**< sap / bilingual detection      */
+               bool rds;                 /**< RDS data array present         */
+               enum drx_aud_nicam_status nicam_status;
+                                         /**< status of NICAM carrier        */
+               s8 fm_ident;              /**< FM Identification value        */
+       };
+
+/* CTRL_AUD_READ_RDS       - DRXRDSdata_t */
+
+/**
+* \struct DRXRDSdata_t
+* \brief Raw RDS data array.
+*/
+       struct drx_cfg_aud_rds {
+               bool valid;               /**< RDS data validation            */
+               u16 data[18];             /**< data from one RDS data array   */
+       };
+
+/* DRX_CFG_AUD_VOLUME      - struct drx_cfg_aud_volume - set/get */
+/**
+* \enum DRXAudAVCDecayTime_t
+* \brief Automatic volume control configuration.
+*/
+       enum drx_aud_avc_mode {
+               DRX_AUD_AVC_OFF,          /**< Automatic volume control off   */
+               DRX_AUD_AVC_DECAYTIME_8S, /**< level volume in  8 seconds     */
+               DRX_AUD_AVC_DECAYTIME_4S, /**< level volume in  4 seconds     */
+               DRX_AUD_AVC_DECAYTIME_2S, /**< level volume in  2 seconds     */
+               DRX_AUD_AVC_DECAYTIME_20MS/**< level volume in 20 millisec    */
+       };
+
+/**
+* /enum DRXAudMaxAVCGain_t
+* /brief Automatic volume control max gain in audio baseband.
+*/
+       enum drx_aud_avc_max_gain {
+               DRX_AUD_AVC_MAX_GAIN_0DB, /**< maximum AVC gain  0 dB         */
+               DRX_AUD_AVC_MAX_GAIN_6DB, /**< maximum AVC gain  6 dB         */
+               DRX_AUD_AVC_MAX_GAIN_12DB /**< maximum AVC gain 12 dB         */
+       };
+
+/**
+* /enum DRXAudMaxAVCAtten_t
+* /brief Automatic volume control max attenuation in audio baseband.
+*/
+       enum drx_aud_avc_max_atten {
+               DRX_AUD_AVC_MAX_ATTEN_12DB,
+                                         /**< maximum AVC attenuation 12 dB  */
+               DRX_AUD_AVC_MAX_ATTEN_18DB,
+                                         /**< maximum AVC attenuation 18 dB  */
+               DRX_AUD_AVC_MAX_ATTEN_24DB/**< maximum AVC attenuation 24 dB  */
+       };
+/**
+* \struct struct drx_cfg_aud_volume * \brief Audio volume configuration.
+*/
+       struct drx_cfg_aud_volume {
+               bool mute;                /**< mute overrides volume setting  */
+               s16 volume;               /**< volume, range -114 to 12 dB    */
+               enum drx_aud_avc_mode avc_mode;  /**< AVC auto volume control mode   */
+               u16 avc_ref_level;        /**< AVC reference level            */
+               enum drx_aud_avc_max_gain avc_max_gain;
+                                         /**< AVC max gain selection         */
+               enum drx_aud_avc_max_atten avc_max_atten;
+                                         /**< AVC max attenuation selection  */
+               s16 strength_left;        /**< quasi-peak, left speaker       */
+               s16 strength_right;       /**< quasi-peak, right speaker      */
+       };
+
+/* DRX_CFG_I2S_OUTPUT      - struct drx_cfg_i2s_output - set/get */
+/**
+* \enum enum drxi2s_mode * \brief I2S output mode.
+*/
+       enum drxi2s_mode {
+               DRX_I2S_MODE_MASTER,      /**< I2S is in master mode          */
+               DRX_I2S_MODE_SLAVE        /**< I2S is in slave mode           */
+       };
+
+/**
+* \enum enum drxi2s_word_length * \brief Width of I2S data.
+*/
+       enum drxi2s_word_length {
+               DRX_I2S_WORDLENGTH_32 = 0,/**< I2S data is 32 bit wide        */
+               DRX_I2S_WORDLENGTH_16 = 1 /**< I2S data is 16 bit wide        */
+       };
+
+/**
+* \enum enum drxi2s_format * \brief Data wordstrobe alignment for I2S.
+*/
+       enum drxi2s_format {
+               DRX_I2S_FORMAT_WS_WITH_DATA,
+                                   /**< I2S data and wordstrobe are aligned  */
+               DRX_I2S_FORMAT_WS_ADVANCED
+                                   /**< I2S data one cycle after wordstrobe  */
+       };
+
+/**
+* \enum enum drxi2s_polarity * \brief Polarity of I2S data.
+*/
+       enum drxi2s_polarity {
+               DRX_I2S_POLARITY_RIGHT,/**< wordstrobe - right high, left low */
+               DRX_I2S_POLARITY_LEFT  /**< wordstrobe - right low, left high */
+       };
+
+/**
+* \struct struct drx_cfg_i2s_output * \brief I2S output configuration.
+*/
+       struct drx_cfg_i2s_output {
+               bool output_enable;       /**< I2S output enable              */
+               u32 frequency;    /**< range from 8000-48000 Hz       */
+               enum drxi2s_mode mode;    /**< I2S mode, master or slave      */
+               enum drxi2s_word_length word_length;
+                                         /**< I2S wordlength, 16 or 32 bits  */
+               enum drxi2s_polarity polarity;/**< I2S wordstrobe polarity        */
+               enum drxi2s_format format;        /**< I2S wordstrobe delay to data   */
+       };
+
+/* ------------------------------expert interface-----------------------------*/
+/**
+* /enum enum drx_aud_fm_deemphasis * setting for FM-Deemphasis in audio demodulator.
+*
+*/
+       enum drx_aud_fm_deemphasis {
+               DRX_AUD_FM_DEEMPH_50US,
+               DRX_AUD_FM_DEEMPH_75US,
+               DRX_AUD_FM_DEEMPH_OFF
+       };
+
+/**
+* /enum DRXAudDeviation_t
+* setting for deviation mode in audio demodulator.
+*
+*/
+       enum drx_cfg_aud_deviation {
+               DRX_AUD_DEVIATION_NORMAL,
+               DRX_AUD_DEVIATION_HIGH
+       };
+
+/**
+* /enum enum drx_no_carrier_option * setting for carrier, mute/noise.
+*
+*/
+       enum drx_no_carrier_option {
+               DRX_NO_CARRIER_MUTE,
+               DRX_NO_CARRIER_NOISE
+       };
+
+/**
+* \enum DRXAudAutoSound_t
+* \brief Automatic Sound
+*/
+       enum drx_cfg_aud_auto_sound {
+               DRX_AUD_AUTO_SOUND_OFF = 0,
+               DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON,
+               DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF
+       };
+
+/**
+* \enum DRXAudASSThres_t
+* \brief Automatic Sound Select Thresholds
+*/
+       struct drx_cfg_aud_ass_thres {
+               u16 a2; /* A2 Threshold for ASS configuration */
+               u16 btsc;       /* BTSC Threshold for ASS configuration */
+               u16 nicam;      /* Nicam Threshold for ASS configuration */
+       };
+
+/**
+* \struct struct drx_aud_carrier * \brief Carrier detection related parameters
+*/
+       struct drx_aud_carrier {
+               u16 thres;      /* carrier detetcion threshold for primary carrier (A) */
+               enum drx_no_carrier_option opt; /* Mute or noise at no carrier detection (A) */
+               s32 shift;      /* DC level of incoming signal (A) */
+               s32 dco;        /* frequency adjustment (A) */
+       };
+
+/**
+* \struct struct drx_cfg_aud_carriers * \brief combining carrier A & B to one struct
+*/
+       struct drx_cfg_aud_carriers {
+               struct drx_aud_carrier a;
+               struct drx_aud_carrier b;
+       };
+
+/**
+* /enum enum drx_aud_i2s_src * Selection of audio source
+*/
+       enum drx_aud_i2s_src {
+               DRX_AUD_SRC_MONO,
+               DRX_AUD_SRC_STEREO_OR_AB,
+               DRX_AUD_SRC_STEREO_OR_A,
+               DRX_AUD_SRC_STEREO_OR_B};
+
+/**
+* \enum enum drx_aud_i2s_matrix * \brief Used for selecting I2S output.
+*/
+       enum drx_aud_i2s_matrix {
+               DRX_AUD_I2S_MATRIX_A_MONO,
+                                       /**< A sound only, stereo or mono     */
+               DRX_AUD_I2S_MATRIX_B_MONO,
+                                       /**< B sound only, stereo or mono     */
+               DRX_AUD_I2S_MATRIX_STEREO,
+                                       /**< A+B sound, transparant           */
+               DRX_AUD_I2S_MATRIX_MONO /**< A+B mixed to mono sum, (L+R)/2   */};
+
+/**
+* /enum enum drx_aud_fm_matrix * setting for FM-Matrix in audio demodulator.
+*
+*/
+       enum drx_aud_fm_matrix {
+               DRX_AUD_FM_MATRIX_NO_MATRIX,
+               DRX_AUD_FM_MATRIX_GERMAN,
+               DRX_AUD_FM_MATRIX_KOREAN,
+               DRX_AUD_FM_MATRIX_SOUND_A,
+               DRX_AUD_FM_MATRIX_SOUND_B};
+
+/**
+* \struct DRXAudMatrices_t
+* \brief Mixer settings
+*/
+struct drx_cfg_aud_mixer {
+       enum drx_aud_i2s_src source_i2s;
+       enum drx_aud_i2s_matrix matrix_i2s;
+       enum drx_aud_fm_matrix matrix_fm;
+};
+
+/**
+* \enum DRXI2SVidSync_t
+* \brief Audio/video synchronization, interacts with I2S mode.
+* AUTO_1 and AUTO_2 are for automatic video standard detection with preference
+* for NTSC or Monochrome, because the frequencies are too close (59.94 & 60 Hz)
+*/
+       enum drx_cfg_aud_av_sync {
+               DRX_AUD_AVSYNC_OFF,/**< audio/video synchronization is off   */
+               DRX_AUD_AVSYNC_NTSC,
+                                  /**< it is an NTSC system                 */
+               DRX_AUD_AVSYNC_MONOCHROME,
+                                  /**< it is a MONOCHROME system            */
+               DRX_AUD_AVSYNC_PAL_SECAM
+                                  /**< it is a PAL/SECAM system             */};
+
+/**
+* \struct struct drx_cfg_aud_prescale * \brief Prescalers
+*/
+struct drx_cfg_aud_prescale {
+       u16 fm_deviation;
+       s16 nicam_gain;
+};
+
+/**
+* \struct struct drx_aud_beep * \brief Beep
+*/
+struct drx_aud_beep {
+       s16 volume;     /* dB */
+       u16 frequency;  /* Hz */
+       bool mute;
+};
+
+/**
+* \enum enum drx_aud_btsc_detect * \brief BTSC detetcion mode
+*/
+       enum drx_aud_btsc_detect {
+               DRX_BTSC_STEREO,
+               DRX_BTSC_MONO_AND_SAP};
+
+/**
+* \struct struct drx_aud_data * \brief Audio data structure
+*/
+struct drx_aud_data {
+       /* audio storage */
+       bool audio_is_active;
+       enum drx_aud_standard audio_standard;
+       struct drx_cfg_i2s_output i2sdata;
+       struct drx_cfg_aud_volume volume;
+       enum drx_cfg_aud_auto_sound auto_sound;
+       struct drx_cfg_aud_ass_thres ass_thresholds;
+       struct drx_cfg_aud_carriers carriers;
+       struct drx_cfg_aud_mixer mixer;
+       enum drx_cfg_aud_deviation deviation;
+       enum drx_cfg_aud_av_sync av_sync;
+       struct drx_cfg_aud_prescale prescale;
+       enum drx_aud_fm_deemphasis deemph;
+       enum drx_aud_btsc_detect btsc_detect;
+       /* rds */
+       u16 rds_data_counter;
+       bool rds_data_present;
+};
+
+/**
+* \enum enum drx_qam_lock_range * \brief QAM lock range mode
+*/
+       enum drx_qam_lock_range {
+               DRX_QAM_LOCKRANGE_NORMAL,
+               DRX_QAM_LOCKRANGE_EXTENDED};
+
+/*============================================================================*/
+/*============================================================================*/
+/*== Data access structures ==================================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+/* Address on device */
+       typedef u32 dr_xaddr_t, *pdr_xaddr_t;
+
+/* Protocol specific flags */
+       typedef u32 dr_xflags_t, *pdr_xflags_t;
+
+/* Write block of data to device */
+       typedef int(*drx_write_block_func_t) (struct i2c_device_addr *dev_addr, /* address of I2C device        */
+                                                  u32 addr,    /* address of register/memory   */
+                                                  u16 datasize,        /* size of data in bytes        */
+                                                  u8 *data,    /* data to send                 */
+                                                  u32 flags);
+
+/* Read block of data from device */
+       typedef int(*drx_read_block_func_t) (struct i2c_device_addr *dev_addr,  /* address of I2C device        */
+                                                 u32 addr,     /* address of register/memory   */
+                                                 u16 datasize, /* size of data in bytes        */
+                                                 u8 *data,     /* receive buffer               */
+                                                 u32 flags);
+
+/* Write 8-bits value to device */
+       typedef int(*drx_write_reg8func_t) (struct i2c_device_addr *dev_addr,   /* address of I2C device        */
+                                                 u32 addr,     /* address of register/memory   */
+                                                 u8 data,      /* data to send                 */
+                                                 u32 flags);
+
+/* Read 8-bits value to device */
+       typedef int(*drx_read_reg8func_t) (struct i2c_device_addr *dev_addr,    /* address of I2C device        */
+                                                u32 addr,      /* address of register/memory   */
+                                                u8 *data,      /* receive buffer               */
+                                                u32 flags);
+
+/* Read modify write 8-bits value to device */
+       typedef int(*drx_read_modify_write_reg8func_t) (struct i2c_device_addr *dev_addr,       /* address of I2C device       */
+                                                           u32 waddr,  /* write address of register   */
+                                                           u32 raddr,  /* read  address of register   */
+                                                           u8 wdata,   /* data to write               */
+                                                           u8 *rdata); /* data to read                */
+
+/* Write 16-bits value to device */
+       typedef int(*drx_write_reg16func_t) (struct i2c_device_addr *dev_addr,  /* address of I2C device        */
+                                                  u32 addr,    /* address of register/memory   */
+                                                  u16 data,    /* data to send                 */
+                                                  u32 flags);
+
+/* Read 16-bits value to device */
+       typedef int(*drx_read_reg16func_t) (struct i2c_device_addr *dev_addr,   /* address of I2C device        */
+                                                 u32 addr,     /* address of register/memory   */
+                                                 u16 *data,    /* receive buffer               */
+                                                 u32 flags);
+
+/* Read modify write 16-bits value to device */
+       typedef int(*drx_read_modify_write_reg16func_t) (struct i2c_device_addr *dev_addr,      /* address of I2C device       */
+                                                            u32 waddr, /* write address of register   */
+                                                            u32 raddr, /* read  address of register   */
+                                                            u16 wdata, /* data to write               */
+                                                            u16 *rdata);       /* data to read                */
+
+/* Write 32-bits value to device */
+       typedef int(*drx_write_reg32func_t) (struct i2c_device_addr *dev_addr,  /* address of I2C device        */
+                                                  u32 addr,    /* address of register/memory   */
+                                                  u32 data,    /* data to send                 */
+                                                  u32 flags);
+
+/* Read 32-bits value to device */
+       typedef int(*drx_read_reg32func_t) (struct i2c_device_addr *dev_addr,   /* address of I2C device        */
+                                                 u32 addr,     /* address of register/memory   */
+                                                 u32 *data,    /* receive buffer               */
+                                                 u32 flags);
+
+/* Read modify write 32-bits value to device */
+       typedef int(*drx_read_modify_write_reg32func_t) (struct i2c_device_addr *dev_addr,      /* address of I2C device       */
+                                                            u32 waddr, /* write address of register   */
+                                                            u32 raddr, /* read  address of register   */
+                                                            u32 wdata, /* data to write               */
+                                                            u32 *rdata);       /* data to read                */
+
+/**
+* \struct struct drx_access_func * \brief Interface to an access protocol.
+*/
+struct drx_access_func {
+       drx_write_block_func_t write_block_func;
+       drx_read_block_func_t read_block_func;
+       drx_write_reg8func_t write_reg8func;
+       drx_read_reg8func_t read_reg8func;
+       drx_read_modify_write_reg8func_t read_modify_write_reg8func;
+       drx_write_reg16func_t write_reg16func;
+       drx_read_reg16func_t read_reg16func;
+       drx_read_modify_write_reg16func_t read_modify_write_reg16func;
+       drx_write_reg32func_t write_reg32func;
+       drx_read_reg32func_t read_reg32func;
+       drx_read_modify_write_reg32func_t read_modify_write_reg32func;
+};
+
+/* Register address and data for register dump function */
+struct drx_reg_dump {
+       u32 address;
+       u32 data;
+};
+
+/*============================================================================*/
+/*============================================================================*/
+/*== Demod instance data structures ==========================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+/**
+* \struct struct drx_common_attr * \brief Set of common attributes, shared by all DRX devices.
+*/
+       struct drx_common_attr {
+               /* Microcode (firmware) attributes */
+               char *microcode_file;   /**<  microcode filename           */
+               bool verify_microcode;
+                                  /**< Use microcode verify or not.          */
+               struct drx_mc_version_rec mcversion;
+                                  /**< Version record of microcode from file */
+
+               /* Clocks and tuner attributes */
+               s32 intermediate_freq;
+                                    /**< IF,if tuner instance not used. (kHz)*/
+               s32 sys_clock_freq;
+                                    /**< Systemclock frequency.  (kHz)       */
+               s32 osc_clock_freq;
+                                    /**< Oscillator clock frequency.  (kHz)  */
+               s16 osc_clock_deviation;
+                                    /**< Oscillator clock deviation.  (ppm)  */
+               bool mirror_freq_spect;
+                                    /**< Mirror IF frequency spectrum or not.*/
+
+               /* Initial MPEG output attributes */
+               struct drx_cfg_mpeg_output mpeg_cfg;
+                                    /**< MPEG configuration                  */
+
+               bool is_opened;     /**< if true instance is already opened. */
+
+               /* Channel scan */
+               struct drx_scan_param *scan_param;
+                                     /**< scan parameters                    */
+               u16 scan_freq_plan_index;
+                                     /**< next index in freq plan            */
+               s32 scan_next_frequency;
+                                     /**< next freq to scan                  */
+               bool scan_ready;     /**< scan ready flag                    */
+               u32 scan_max_channels;/**< number of channels in freqplan     */
+               u32 scan_channels_scanned;
+                                       /**< number of channels scanned       */
+               /* Channel scan - inner loop: demod related */
+               drx_scan_func_t scan_function;
+                                     /**< function to check channel          */
+               /* Channel scan - inner loop: SYSObj related */
+               void *scan_context;    /**< Context Pointer of SYSObj          */
+               /* Channel scan - parameters for default DTV scan function in core driver  */
+               u16 scan_demod_lock_timeout;
+                                        /**< millisecs to wait for lock      */
+               enum drx_lock_status scan_desired_lock;
+                                     /**< lock requirement for channel found */
+               /* scan_active can be used by SetChannel to decide how to program the tuner,
+                  fast or slow (but stable). Usually fast during scan. */
+               bool scan_active;    /**< true when scan routines are active */
+
+               /* Power management */
+               enum drx_power_mode current_power_mode;
+                                     /**< current power management mode      */
+
+               /* Tuner */
+               u8 tuner_port_nr;     /**< nr of I2C port to wich tuner is    */
+               s32 tuner_min_freq_rf;
+                                     /**< minimum RF input frequency, in kHz */
+               s32 tuner_max_freq_rf;
+                                     /**< maximum RF input frequency, in kHz */
+               bool tuner_rf_agc_pol; /**< if true invert RF AGC polarity     */
+               bool tuner_if_agc_pol; /**< if true invert IF AGC polarity     */
+               bool tuner_slow_mode; /**< if true invert IF AGC polarity     */
+
+               struct drx_channel current_channel;
+                                     /**< current channel parameters         */
+               enum drx_standard current_standard;
+                                     /**< current standard selection         */
+               enum drx_standard prev_standard;
+                                     /**< previous standard selection        */
+               enum drx_standard di_cache_standard;
+                                     /**< standard in DI cache if available  */
+               bool use_bootloader; /**< use bootloader in open             */
+               u32 capabilities;   /**< capabilities flags                 */
+               u32 product_id;      /**< product ID inc. metal fix number   */};
+
+/*
+* Generic functions for DRX devices.
+*/
+
+struct drx_demod_instance;
+
+/**
+* \struct struct drx_demod_instance * \brief Top structure of demodulator instance.
+*/
+struct drx_demod_instance {
+                               /**< data access protocol functions       */
+       struct i2c_device_addr *my_i2c_dev_addr;
+                               /**< i2c address and device identifier    */
+       struct drx_common_attr *my_common_attr;
+                               /**< common DRX attributes                */
+       void *my_ext_attr;    /**< device specific attributes           */
+       /* generic demodulator data */
+
+       struct i2c_adapter      *i2c;
+       const struct firmware   *firmware;
+};
+
+/*-------------------------------------------------------------------------
+MACROS
+Conversion from enum values to human readable form.
+-------------------------------------------------------------------------*/
+
+/* standard */
+
+#define DRX_STR_STANDARD(x) ( \
+       (x == DRX_STANDARD_DVBT)  ? "DVB-T"            : \
+       (x == DRX_STANDARD_8VSB)  ? "8VSB"             : \
+       (x == DRX_STANDARD_NTSC)  ? "NTSC"             : \
+       (x == DRX_STANDARD_PAL_SECAM_BG)  ? "PAL/SECAM B/G"    : \
+       (x == DRX_STANDARD_PAL_SECAM_DK)  ? "PAL/SECAM D/K"    : \
+       (x == DRX_STANDARD_PAL_SECAM_I)  ? "PAL/SECAM I"      : \
+       (x == DRX_STANDARD_PAL_SECAM_L)  ? "PAL/SECAM L"      : \
+       (x == DRX_STANDARD_PAL_SECAM_LP)  ? "PAL/SECAM LP"     : \
+       (x == DRX_STANDARD_ITU_A)  ? "ITU-A"            : \
+       (x == DRX_STANDARD_ITU_B)  ? "ITU-B"            : \
+       (x == DRX_STANDARD_ITU_C)  ? "ITU-C"            : \
+       (x == DRX_STANDARD_ITU_D)  ? "ITU-D"            : \
+       (x == DRX_STANDARD_FM)  ? "FM"               : \
+       (x == DRX_STANDARD_DTMB)  ? "DTMB"             : \
+       (x == DRX_STANDARD_AUTO)  ? "Auto"             : \
+       (x == DRX_STANDARD_UNKNOWN)  ? "Unknown"          : \
+       "(Invalid)")
+
+/* channel */
+
+#define DRX_STR_BANDWIDTH(x) ( \
+       (x == DRX_BANDWIDTH_8MHZ)  ?  "8 MHz"            : \
+       (x == DRX_BANDWIDTH_7MHZ)  ?  "7 MHz"            : \
+       (x == DRX_BANDWIDTH_6MHZ)  ?  "6 MHz"            : \
+       (x == DRX_BANDWIDTH_AUTO)  ?  "Auto"             : \
+       (x == DRX_BANDWIDTH_UNKNOWN)  ?  "Unknown"          : \
+       "(Invalid)")
+#define DRX_STR_FFTMODE(x) ( \
+       (x == DRX_FFTMODE_2K)  ?  "2k"               : \
+       (x == DRX_FFTMODE_4K)  ?  "4k"               : \
+       (x == DRX_FFTMODE_8K)  ?  "8k"               : \
+       (x == DRX_FFTMODE_AUTO)  ?  "Auto"             : \
+       (x == DRX_FFTMODE_UNKNOWN)  ?  "Unknown"          : \
+       "(Invalid)")
+#define DRX_STR_GUARD(x) ( \
+       (x == DRX_GUARD_1DIV32)  ?  "1/32nd"           : \
+       (x == DRX_GUARD_1DIV16)  ?  "1/16th"           : \
+       (x == DRX_GUARD_1DIV8)  ?  "1/8th"            : \
+       (x == DRX_GUARD_1DIV4)  ?  "1/4th"            : \
+       (x == DRX_GUARD_AUTO)  ?  "Auto"             : \
+       (x == DRX_GUARD_UNKNOWN)  ?  "Unknown"          : \
+       "(Invalid)")
+#define DRX_STR_CONSTELLATION(x) ( \
+       (x == DRX_CONSTELLATION_BPSK)  ?  "BPSK"            : \
+       (x == DRX_CONSTELLATION_QPSK)  ?  "QPSK"            : \
+       (x == DRX_CONSTELLATION_PSK8)  ?  "PSK8"            : \
+       (x == DRX_CONSTELLATION_QAM16)  ?  "QAM16"           : \
+       (x == DRX_CONSTELLATION_QAM32)  ?  "QAM32"           : \
+       (x == DRX_CONSTELLATION_QAM64)  ?  "QAM64"           : \
+       (x == DRX_CONSTELLATION_QAM128)  ?  "QAM128"          : \
+       (x == DRX_CONSTELLATION_QAM256)  ?  "QAM256"          : \
+       (x == DRX_CONSTELLATION_QAM512)  ?  "QAM512"          : \
+       (x == DRX_CONSTELLATION_QAM1024)  ?  "QAM1024"         : \
+       (x == DRX_CONSTELLATION_QPSK_NR)  ?  "QPSK_NR"            : \
+       (x == DRX_CONSTELLATION_AUTO)  ?  "Auto"            : \
+       (x == DRX_CONSTELLATION_UNKNOWN)  ?  "Unknown"         : \
+       "(Invalid)")
+#define DRX_STR_CODERATE(x) ( \
+       (x == DRX_CODERATE_1DIV2)  ?  "1/2nd"           : \
+       (x == DRX_CODERATE_2DIV3)  ?  "2/3rd"           : \
+       (x == DRX_CODERATE_3DIV4)  ?  "3/4th"           : \
+       (x == DRX_CODERATE_5DIV6)  ?  "5/6th"           : \
+       (x == DRX_CODERATE_7DIV8)  ?  "7/8th"           : \
+       (x == DRX_CODERATE_AUTO)  ?  "Auto"            : \
+       (x == DRX_CODERATE_UNKNOWN)  ?  "Unknown"         : \
+       "(Invalid)")
+#define DRX_STR_HIERARCHY(x) ( \
+       (x == DRX_HIERARCHY_NONE)  ?  "None"            : \
+       (x == DRX_HIERARCHY_ALPHA1)  ?  "Alpha=1"         : \
+       (x == DRX_HIERARCHY_ALPHA2)  ?  "Alpha=2"         : \
+       (x == DRX_HIERARCHY_ALPHA4)  ?  "Alpha=4"         : \
+       (x == DRX_HIERARCHY_AUTO)  ?  "Auto"            : \
+       (x == DRX_HIERARCHY_UNKNOWN)  ?  "Unknown"         : \
+       "(Invalid)")
+#define DRX_STR_PRIORITY(x) ( \
+       (x == DRX_PRIORITY_LOW)  ?  "Low"             : \
+       (x == DRX_PRIORITY_HIGH)  ?  "High"            : \
+       (x == DRX_PRIORITY_UNKNOWN)  ?  "Unknown"         : \
+       "(Invalid)")
+#define DRX_STR_MIRROR(x) ( \
+       (x == DRX_MIRROR_NO)  ?  "Normal"          : \
+       (x == DRX_MIRROR_YES)  ?  "Mirrored"        : \
+       (x == DRX_MIRROR_AUTO)  ?  "Auto"            : \
+       (x == DRX_MIRROR_UNKNOWN)  ?  "Unknown"         : \
+       "(Invalid)")
+#define DRX_STR_CLASSIFICATION(x) ( \
+       (x == DRX_CLASSIFICATION_GAUSS)  ?  "Gaussion"        : \
+       (x == DRX_CLASSIFICATION_HVY_GAUSS)  ?  "Heavy Gaussion"  : \
+       (x == DRX_CLASSIFICATION_COCHANNEL)  ?  "Co-channel"      : \
+       (x == DRX_CLASSIFICATION_STATIC)  ?  "Static echo"     : \
+       (x == DRX_CLASSIFICATION_MOVING)  ?  "Moving echo"     : \
+       (x == DRX_CLASSIFICATION_ZERODB)  ?  "Zero dB echo"    : \
+       (x == DRX_CLASSIFICATION_UNKNOWN)  ?  "Unknown"         : \
+       (x == DRX_CLASSIFICATION_AUTO)  ?  "Auto"            : \
+       "(Invalid)")
+
+#define DRX_STR_INTERLEAVEMODE(x) ( \
+       (x == DRX_INTERLEAVEMODE_I128_J1) ? "I128_J1"         : \
+       (x == DRX_INTERLEAVEMODE_I128_J1_V2) ? "I128_J1_V2"      : \
+       (x == DRX_INTERLEAVEMODE_I128_J2) ? "I128_J2"         : \
+       (x == DRX_INTERLEAVEMODE_I64_J2) ? "I64_J2"          : \
+       (x == DRX_INTERLEAVEMODE_I128_J3) ? "I128_J3"         : \
+       (x == DRX_INTERLEAVEMODE_I32_J4) ? "I32_J4"          : \
+       (x == DRX_INTERLEAVEMODE_I128_J4) ? "I128_J4"         : \
+       (x == DRX_INTERLEAVEMODE_I16_J8) ? "I16_J8"          : \
+       (x == DRX_INTERLEAVEMODE_I128_J5) ? "I128_J5"         : \
+       (x == DRX_INTERLEAVEMODE_I8_J16) ? "I8_J16"          : \
+       (x == DRX_INTERLEAVEMODE_I128_J6) ? "I128_J6"         : \
+       (x == DRX_INTERLEAVEMODE_RESERVED_11) ? "Reserved 11"     : \
+       (x == DRX_INTERLEAVEMODE_I128_J7) ? "I128_J7"         : \
+       (x == DRX_INTERLEAVEMODE_RESERVED_13) ? "Reserved 13"     : \
+       (x == DRX_INTERLEAVEMODE_I128_J8) ? "I128_J8"         : \
+       (x == DRX_INTERLEAVEMODE_RESERVED_15) ? "Reserved 15"     : \
+       (x == DRX_INTERLEAVEMODE_I12_J17) ? "I12_J17"         : \
+       (x == DRX_INTERLEAVEMODE_I5_J4) ? "I5_J4"           : \
+       (x == DRX_INTERLEAVEMODE_B52_M240) ? "B52_M240"        : \
+       (x == DRX_INTERLEAVEMODE_B52_M720) ? "B52_M720"        : \
+       (x == DRX_INTERLEAVEMODE_B52_M48) ? "B52_M48"         : \
+       (x == DRX_INTERLEAVEMODE_B52_M0) ? "B52_M0"          : \
+       (x == DRX_INTERLEAVEMODE_UNKNOWN) ? "Unknown"         : \
+       (x == DRX_INTERLEAVEMODE_AUTO) ? "Auto"            : \
+       "(Invalid)")
+
+#define DRX_STR_LDPC(x) ( \
+       (x == DRX_LDPC_0_4) ? "0.4"             : \
+       (x == DRX_LDPC_0_6) ? "0.6"             : \
+       (x == DRX_LDPC_0_8) ? "0.8"             : \
+       (x == DRX_LDPC_AUTO) ? "Auto"            : \
+       (x == DRX_LDPC_UNKNOWN) ? "Unknown"         : \
+       "(Invalid)")
+
+#define DRX_STR_CARRIER(x) ( \
+       (x == DRX_CARRIER_MULTI) ? "Multi"           : \
+       (x == DRX_CARRIER_SINGLE) ? "Single"          : \
+       (x == DRX_CARRIER_AUTO) ? "Auto"            : \
+       (x == DRX_CARRIER_UNKNOWN) ? "Unknown"         : \
+       "(Invalid)")
+
+#define DRX_STR_FRAMEMODE(x) ( \
+       (x == DRX_FRAMEMODE_420)  ? "420"                : \
+       (x == DRX_FRAMEMODE_595)  ? "595"                : \
+       (x == DRX_FRAMEMODE_945)  ? "945"                : \
+       (x == DRX_FRAMEMODE_420_FIXED_PN)  ? "420 with fixed PN"  : \
+       (x == DRX_FRAMEMODE_945_FIXED_PN)  ? "945 with fixed PN"  : \
+       (x == DRX_FRAMEMODE_AUTO)  ? "Auto"               : \
+       (x == DRX_FRAMEMODE_UNKNOWN)  ? "Unknown"            : \
+       "(Invalid)")
+
+#define DRX_STR_PILOT(x) ( \
+       (x == DRX_PILOT_ON) ?   "On"              : \
+       (x == DRX_PILOT_OFF) ?   "Off"             : \
+       (x == DRX_PILOT_AUTO) ?   "Auto"            : \
+       (x == DRX_PILOT_UNKNOWN) ?   "Unknown"         : \
+       "(Invalid)")
+/* TPS */
+
+#define DRX_STR_TPS_FRAME(x)  ( \
+       (x == DRX_TPS_FRAME1)  ?  "Frame1"          : \
+       (x == DRX_TPS_FRAME2)  ?  "Frame2"          : \
+       (x == DRX_TPS_FRAME3)  ?  "Frame3"          : \
+       (x == DRX_TPS_FRAME4)  ?  "Frame4"          : \
+       (x == DRX_TPS_FRAME_UNKNOWN)  ?  "Unknown"         : \
+       "(Invalid)")
+
+/* lock status */
+
+#define DRX_STR_LOCKSTATUS(x) ( \
+       (x == DRX_NEVER_LOCK)  ?  "Never"           : \
+       (x == DRX_NOT_LOCKED)  ?  "No"              : \
+       (x == DRX_LOCKED)  ?  "Locked"          : \
+       (x == DRX_LOCK_STATE_1)  ?  "Lock state 1"    : \
+       (x == DRX_LOCK_STATE_2)  ?  "Lock state 2"    : \
+       (x == DRX_LOCK_STATE_3)  ?  "Lock state 3"    : \
+       (x == DRX_LOCK_STATE_4)  ?  "Lock state 4"    : \
+       (x == DRX_LOCK_STATE_5)  ?  "Lock state 5"    : \
+       (x == DRX_LOCK_STATE_6)  ?  "Lock state 6"    : \
+       (x == DRX_LOCK_STATE_7)  ?  "Lock state 7"    : \
+       (x == DRX_LOCK_STATE_8)  ?  "Lock state 8"    : \
+       (x == DRX_LOCK_STATE_9)  ?  "Lock state 9"    : \
+       "(Invalid)")
+
+/* version information , modules */
+#define DRX_STR_MODULE(x) ( \
+       (x == DRX_MODULE_DEVICE)  ?  "Device"                : \
+       (x == DRX_MODULE_MICROCODE)  ?  "Microcode"             : \
+       (x == DRX_MODULE_DRIVERCORE)  ?  "CoreDriver"            : \
+       (x == DRX_MODULE_DEVICEDRIVER)  ?  "DeviceDriver"          : \
+       (x == DRX_MODULE_BSP_I2C)  ?  "BSP I2C"               : \
+       (x == DRX_MODULE_BSP_TUNER)  ?  "BSP Tuner"             : \
+       (x == DRX_MODULE_BSP_HOST)  ?  "BSP Host"              : \
+       (x == DRX_MODULE_DAP)  ?  "Data Access Protocol"  : \
+       (x == DRX_MODULE_UNKNOWN)  ?  "Unknown"               : \
+       "(Invalid)")
+
+#define DRX_STR_POWER_MODE(x) ( \
+       (x == DRX_POWER_UP)  ?  "DRX_POWER_UP    "  : \
+       (x == DRX_POWER_MODE_1)  ?  "DRX_POWER_MODE_1"  : \
+       (x == DRX_POWER_MODE_2)  ?  "DRX_POWER_MODE_2"  : \
+       (x == DRX_POWER_MODE_3)  ?  "DRX_POWER_MODE_3"  : \
+       (x == DRX_POWER_MODE_4)  ?  "DRX_POWER_MODE_4"  : \
+       (x == DRX_POWER_MODE_5)  ?  "DRX_POWER_MODE_5"  : \
+       (x == DRX_POWER_MODE_6)  ?  "DRX_POWER_MODE_6"  : \
+       (x == DRX_POWER_MODE_7)  ?  "DRX_POWER_MODE_7"  : \
+       (x == DRX_POWER_MODE_8)  ?  "DRX_POWER_MODE_8"  : \
+       (x == DRX_POWER_MODE_9)  ?  "DRX_POWER_MODE_9"  : \
+       (x == DRX_POWER_MODE_10)  ?  "DRX_POWER_MODE_10" : \
+       (x == DRX_POWER_MODE_11)  ?  "DRX_POWER_MODE_11" : \
+       (x == DRX_POWER_MODE_12)  ?  "DRX_POWER_MODE_12" : \
+       (x == DRX_POWER_MODE_13)  ?  "DRX_POWER_MODE_13" : \
+       (x == DRX_POWER_MODE_14)  ?  "DRX_POWER_MODE_14" : \
+       (x == DRX_POWER_MODE_15)  ?  "DRX_POWER_MODE_15" : \
+       (x == DRX_POWER_MODE_16)  ?  "DRX_POWER_MODE_16" : \
+       (x == DRX_POWER_DOWN)  ?  "DRX_POWER_DOWN  " : \
+       "(Invalid)")
+
+#define DRX_STR_OOB_STANDARD(x) ( \
+       (x == DRX_OOB_MODE_A)  ?  "ANSI 55-1  " : \
+       (x == DRX_OOB_MODE_B_GRADE_A)  ?  "ANSI 55-2 A" : \
+       (x == DRX_OOB_MODE_B_GRADE_B)  ?  "ANSI 55-2 B" : \
+       "(Invalid)")
+
+#define DRX_STR_AUD_STANDARD(x) ( \
+       (x == DRX_AUD_STANDARD_BTSC)  ? "BTSC"                     : \
+       (x == DRX_AUD_STANDARD_A2)  ? "A2"                       : \
+       (x == DRX_AUD_STANDARD_EIAJ)  ? "EIAJ"                     : \
+       (x == DRX_AUD_STANDARD_FM_STEREO)  ? "FM Stereo"                : \
+       (x == DRX_AUD_STANDARD_AUTO)  ? "Auto"                     : \
+       (x == DRX_AUD_STANDARD_M_MONO)  ? "M-Standard Mono"          : \
+       (x == DRX_AUD_STANDARD_D_K_MONO)  ? "D/K Mono FM"              : \
+       (x == DRX_AUD_STANDARD_BG_FM)  ? "B/G-Dual Carrier FM (A2)" : \
+       (x == DRX_AUD_STANDARD_D_K1)  ? "D/K1-Dual Carrier FM"     : \
+       (x == DRX_AUD_STANDARD_D_K2)  ? "D/K2-Dual Carrier FM"     : \
+       (x == DRX_AUD_STANDARD_D_K3)  ? "D/K3-Dual Carrier FM"     : \
+       (x == DRX_AUD_STANDARD_BG_NICAM_FM)  ? "B/G-NICAM-FM"             : \
+       (x == DRX_AUD_STANDARD_L_NICAM_AM)  ? "L-NICAM-AM"               : \
+       (x == DRX_AUD_STANDARD_I_NICAM_FM)  ? "I-NICAM-FM"               : \
+       (x == DRX_AUD_STANDARD_D_K_NICAM_FM)  ? "D/K-NICAM-FM"             : \
+       (x == DRX_AUD_STANDARD_UNKNOWN)  ? "Unknown"                  : \
+       "(Invalid)")
+#define DRX_STR_AUD_STEREO(x) ( \
+       (x == true)  ? "Stereo"           : \
+       (x == false)  ? "Mono"             : \
+       "(Invalid)")
+
+#define DRX_STR_AUD_SAP(x) ( \
+       (x == true)  ? "Present"          : \
+       (x == false)  ? "Not present"      : \
+       "(Invalid)")
+
+#define DRX_STR_AUD_CARRIER(x) ( \
+       (x == true)  ? "Present"          : \
+       (x == false)  ? "Not present"      : \
+       "(Invalid)")
+
+#define DRX_STR_AUD_RDS(x) ( \
+       (x == true)  ? "Available"        : \
+       (x == false)  ? "Not Available"    : \
+       "(Invalid)")
+
+#define DRX_STR_AUD_NICAM_STATUS(x) ( \
+       (x == DRX_AUD_NICAM_DETECTED)  ? "Detected"         : \
+       (x == DRX_AUD_NICAM_NOT_DETECTED)  ? "Not detected"     : \
+       (x == DRX_AUD_NICAM_BAD)  ? "Bad"              : \
+       "(Invalid)")
+
+#define DRX_STR_RDS_VALID(x) ( \
+       (x == true)  ? "Valid"            : \
+       (x == false)  ? "Not Valid"        : \
+       "(Invalid)")
+
+/*-------------------------------------------------------------------------
+Access macros
+-------------------------------------------------------------------------*/
+
+/**
+* \brief Create a compilable reference to the microcode attribute
+* \param d pointer to demod instance
+*
+* Used as main reference to an attribute field.
+* Used by both macro implementation and function implementation.
+* These macros are defined to avoid duplication of code in macro and function
+* definitions that handle access of demod common or extended attributes.
+*
+*/
+
+#define DRX_ATTR_MCRECORD(d)        ((d)->my_common_attr->mcversion)
+#define DRX_ATTR_MIRRORFREQSPECT(d) ((d)->my_common_attr->mirror_freq_spect)
+#define DRX_ATTR_CURRENTPOWERMODE(d)((d)->my_common_attr->current_power_mode)
+#define DRX_ATTR_ISOPENED(d)        ((d)->my_common_attr->is_opened)
+#define DRX_ATTR_USEBOOTLOADER(d)   ((d)->my_common_attr->use_bootloader)
+#define DRX_ATTR_CURRENTSTANDARD(d) ((d)->my_common_attr->current_standard)
+#define DRX_ATTR_PREVSTANDARD(d)    ((d)->my_common_attr->prev_standard)
+#define DRX_ATTR_CACHESTANDARD(d)   ((d)->my_common_attr->di_cache_standard)
+#define DRX_ATTR_CURRENTCHANNEL(d)  ((d)->my_common_attr->current_channel)
+#define DRX_ATTR_MICROCODE(d)       ((d)->my_common_attr->microcode)
+#define DRX_ATTR_VERIFYMICROCODE(d) ((d)->my_common_attr->verify_microcode)
+#define DRX_ATTR_CAPABILITIES(d)    ((d)->my_common_attr->capabilities)
+#define DRX_ATTR_PRODUCTID(d)       ((d)->my_common_attr->product_id)
+#define DRX_ATTR_INTERMEDIATEFREQ(d) ((d)->my_common_attr->intermediate_freq)
+#define DRX_ATTR_SYSCLOCKFREQ(d)     ((d)->my_common_attr->sys_clock_freq)
+#define DRX_ATTR_TUNERRFAGCPOL(d)   ((d)->my_common_attr->tuner_rf_agc_pol)
+#define DRX_ATTR_TUNERIFAGCPOL(d)    ((d)->my_common_attr->tuner_if_agc_pol)
+#define DRX_ATTR_TUNERSLOWMODE(d)    ((d)->my_common_attr->tuner_slow_mode)
+#define DRX_ATTR_TUNERSPORTNR(d)     ((d)->my_common_attr->tuner_port_nr)
+#define DRX_ATTR_I2CADDR(d)         ((d)->my_i2c_dev_addr->i2c_addr)
+#define DRX_ATTR_I2CDEVID(d)        ((d)->my_i2c_dev_addr->i2c_dev_id)
+#define DRX_ISMCVERTYPE(x) ((x) == AUX_VER_RECORD)
+
+/**************************/
+
+/* Macros with device-specific handling are converted to CFG functions */
+
+#define DRX_ACCESSMACRO_SET(demod, value, cfg_name, data_type)             \
+       do {                                                               \
+               struct drx_cfg config;                                     \
+               data_type cfg_data;                                        \
+               config.cfg_type = cfg_name;                                \
+               config.cfg_data = &cfg_data;                               \
+               cfg_data = value;                                          \
+               drx_ctrl(demod, DRX_CTRL_SET_CFG, &config);                \
+       } while (0)
+
+#define DRX_ACCESSMACRO_GET(demod, value, cfg_name, data_type, error_value) \
+       do {                                                                \
+               int cfg_status;                                             \
+               struct drx_cfg config;                                      \
+               data_type    cfg_data;                                      \
+               config.cfg_type = cfg_name;                                 \
+               config.cfg_data = &cfg_data;                                \
+               cfg_status = drx_ctrl(demod, DRX_CTRL_GET_CFG, &config);    \
+               if (cfg_status == 0) {                                      \
+                       value = cfg_data;                                   \
+               } else {                                                    \
+                       value = (data_type)error_value;                     \
+               }                                                           \
+       } while (0)
+
+/* Configuration functions for usage by Access (XS) Macros */
+
+#ifndef DRX_XS_CFG_BASE
+#define DRX_XS_CFG_BASE (500)
+#endif
+
+#define DRX_XS_CFG_PRESET          (DRX_XS_CFG_BASE + 0)
+#define DRX_XS_CFG_AUD_BTSC_DETECT (DRX_XS_CFG_BASE + 1)
+#define DRX_XS_CFG_QAM_LOCKRANGE   (DRX_XS_CFG_BASE + 2)
+
+/* Access Macros with device-specific handling */
+
+#define DRX_SET_PRESET(d, x) \
+       DRX_ACCESSMACRO_SET((d), (x), DRX_XS_CFG_PRESET, char*)
+#define DRX_GET_PRESET(d, x) \
+       DRX_ACCESSMACRO_GET((d), (x), DRX_XS_CFG_PRESET, char*, "ERROR")
+
+#define DRX_SET_AUD_BTSC_DETECT(d, x) DRX_ACCESSMACRO_SET((d), (x), \
+        DRX_XS_CFG_AUD_BTSC_DETECT, enum drx_aud_btsc_detect)
+#define DRX_GET_AUD_BTSC_DETECT(d, x) DRX_ACCESSMACRO_GET((d), (x), \
+        DRX_XS_CFG_AUD_BTSC_DETECT, enum drx_aud_btsc_detect, DRX_UNKNOWN)
+
+#define DRX_SET_QAM_LOCKRANGE(d, x) DRX_ACCESSMACRO_SET((d), (x), \
+        DRX_XS_CFG_QAM_LOCKRANGE, enum drx_qam_lock_range)
+#define DRX_GET_QAM_LOCKRANGE(d, x) DRX_ACCESSMACRO_GET((d), (x), \
+        DRX_XS_CFG_QAM_LOCKRANGE, enum drx_qam_lock_range, DRX_UNKNOWN)
+
+/**
+* \brief Macro to check if std is an ATV standard
+* \retval true std is an ATV standard
+* \retval false std is an ATV standard
+*/
+#define DRX_ISATVSTD(std) (((std) == DRX_STANDARD_PAL_SECAM_BG) || \
+                             ((std) == DRX_STANDARD_PAL_SECAM_DK) || \
+                             ((std) == DRX_STANDARD_PAL_SECAM_I) || \
+                             ((std) == DRX_STANDARD_PAL_SECAM_L) || \
+                             ((std) == DRX_STANDARD_PAL_SECAM_LP) || \
+                             ((std) == DRX_STANDARD_NTSC) || \
+                             ((std) == DRX_STANDARD_FM))
+
+/**
+* \brief Macro to check if std is an QAM standard
+* \retval true std is an QAM standards
+* \retval false std is an QAM standards
+*/
+#define DRX_ISQAMSTD(std) (((std) == DRX_STANDARD_ITU_A) || \
+                             ((std) == DRX_STANDARD_ITU_B) || \
+                             ((std) == DRX_STANDARD_ITU_C) || \
+                             ((std) == DRX_STANDARD_ITU_D))
+
+/**
+* \brief Macro to check if std is VSB standard
+* \retval true std is VSB standard
+* \retval false std is not VSB standard
+*/
+#define DRX_ISVSBSTD(std) ((std) == DRX_STANDARD_8VSB)
+
+/**
+* \brief Macro to check if std is DVBT standard
+* \retval true std is DVBT standard
+* \retval false std is not DVBT standard
+*/
+#define DRX_ISDVBTSTD(std) ((std) == DRX_STANDARD_DVBT)
+
+/*-------------------------------------------------------------------------
+THE END
+-------------------------------------------------------------------------*/
+#endif                         /* __DRXDRIVER_H__ */
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver_version.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver_version.h
new file mode 100644 (file)
index 0000000..ff05a4f
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *******************************************************************************
+ * WARNING - THIS FILE HAS BEEN GENERATED - DO NOT CHANGE
+ *
+ * Filename:        drx_driver_version.h
+ * Generated on:    Mon Jan 18 12:09:23 2010
+ * Generated by:    IDF:x 1.3.0
+ * Generated from:  ../../../device/drxj/version
+ * Output start:    [entry point]
+ *
+ * filename         last modified               re-use
+ *
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* -----------------------------------------------------
+ * version.idf      Mon Jan 18 11:56:10 2010    -
+ *
+ */
+
+#ifndef __DRX_DRIVER_VERSION__H__
+#define __DRX_DRIVER_VERSION__H__ INCLUDED
+
+#ifdef _REGISTERTABLE_
+#include <registertable.h>
+       extern register_table_t drx_driver_version[];
+       extern register_table_info_t drx_driver_version_info[];
+#endif                         /* _REGISTERTABLE_ */
+
+/*
+ *==============================================================================
+ * VERSION
+ * version@/var/cvs/projects/drxj.cvsroot/hostcode/drxdriver/device/drxj
+ *==============================================================================
+ */
+
+#define VERSION__A      0x0
+#define   VERSION_MAJOR 1
+#define   VERSION_MINOR 0
+#define   VERSION_PATCH 56
+
+#endif                         /* __DRX_DRIVER_VERSION__H__ */
+/*
+ * End of file (drx_driver_version.h)
+ *******************************************************************************
+ */
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
new file mode 100644 (file)
index 0000000..9482954
--- /dev/null
@@ -0,0 +1,12400 @@
+/*
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+  DRXJ specific implementation of DRX driver
+  authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
+
+  The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
+  written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*-----------------------------------------------------------------------------
+INCLUDE FILES
+----------------------------------------------------------------------------*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drx39xxj.h"
+
+#include "drxj.h"
+#include "drxj_map.h"
+
+/*============================================================================*/
+/*=== DEFINES ================================================================*/
+/*============================================================================*/
+
+#define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
+
+/**
+* \brief Maximum u32 value.
+*/
+#ifndef MAX_U32
+#define MAX_U32  ((u32) (0xFFFFFFFFL))
+#endif
+
+/* Customer configurable hardware settings, etc */
+#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
+#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
+#endif
+
+#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
+#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
+#endif
+
+#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
+#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
+#endif
+
+#ifndef OOB_CRX_DRIVE_STRENGTH
+#define OOB_CRX_DRIVE_STRENGTH 0x02
+#endif
+
+#ifndef OOB_DRX_DRIVE_STRENGTH
+#define OOB_DRX_DRIVE_STRENGTH 0x02
+#endif
+/**** START DJCOMBO patches to DRXJ registermap constants *********************/
+/**** registermap 200706071303 from drxj **************************************/
+#define   ATV_TOP_CR_AMP_TH_FM                                              0x0
+#define   ATV_TOP_CR_AMP_TH_L                                               0xA
+#define   ATV_TOP_CR_AMP_TH_LP                                              0xA
+#define   ATV_TOP_CR_AMP_TH_BG                                              0x8
+#define   ATV_TOP_CR_AMP_TH_DK                                              0x8
+#define   ATV_TOP_CR_AMP_TH_I                                               0x8
+#define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18
+#define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0
+#define     ATV_TOP_CR_CONT_CR_D_L                                          0x20
+#define     ATV_TOP_CR_CONT_CR_D_LP                                         0x20
+#define     ATV_TOP_CR_CONT_CR_D_BG                                         0x18
+#define     ATV_TOP_CR_CONT_CR_D_DK                                         0x18
+#define     ATV_TOP_CR_CONT_CR_D_I                                          0x18
+#define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80
+#define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0
+#define     ATV_TOP_CR_CONT_CR_I_L                                          0x80
+#define     ATV_TOP_CR_CONT_CR_I_LP                                         0x80
+#define     ATV_TOP_CR_CONT_CR_I_BG                                         0x80
+#define     ATV_TOP_CR_CONT_CR_I_DK                                         0x80
+#define     ATV_TOP_CR_CONT_CR_I_I                                          0x80
+#define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4
+#define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0
+#define     ATV_TOP_CR_CONT_CR_P_L                                          0x4
+#define     ATV_TOP_CR_CONT_CR_P_LP                                         0x4
+#define     ATV_TOP_CR_CONT_CR_P_BG                                         0x4
+#define     ATV_TOP_CR_CONT_CR_P_DK                                         0x4
+#define     ATV_TOP_CR_CONT_CR_P_I                                          0x4
+#define   ATV_TOP_CR_OVM_TH_MN                                              0xA0
+#define   ATV_TOP_CR_OVM_TH_FM                                              0x0
+#define   ATV_TOP_CR_OVM_TH_L                                               0xA0
+#define   ATV_TOP_CR_OVM_TH_LP                                              0xA0
+#define   ATV_TOP_CR_OVM_TH_BG                                              0xA0
+#define   ATV_TOP_CR_OVM_TH_DK                                              0xA0
+#define   ATV_TOP_CR_OVM_TH_I                                               0xA0
+#define     ATV_TOP_EQU0_EQU_C0_FM                                          0x0
+#define     ATV_TOP_EQU0_EQU_C0_L                                           0x3
+#define     ATV_TOP_EQU0_EQU_C0_LP                                          0x3
+#define     ATV_TOP_EQU0_EQU_C0_BG                                          0x7
+#define     ATV_TOP_EQU0_EQU_C0_DK                                          0x0
+#define     ATV_TOP_EQU0_EQU_C0_I                                           0x3
+#define     ATV_TOP_EQU1_EQU_C1_FM                                          0x0
+#define     ATV_TOP_EQU1_EQU_C1_L                                           0x1F6
+#define     ATV_TOP_EQU1_EQU_C1_LP                                          0x1F6
+#define     ATV_TOP_EQU1_EQU_C1_BG                                          0x197
+#define     ATV_TOP_EQU1_EQU_C1_DK                                          0x198
+#define     ATV_TOP_EQU1_EQU_C1_I                                           0x1F6
+#define     ATV_TOP_EQU2_EQU_C2_FM                                          0x0
+#define     ATV_TOP_EQU2_EQU_C2_L                                           0x28
+#define     ATV_TOP_EQU2_EQU_C2_LP                                          0x28
+#define     ATV_TOP_EQU2_EQU_C2_BG                                          0xC5
+#define     ATV_TOP_EQU2_EQU_C2_DK                                          0xB0
+#define     ATV_TOP_EQU2_EQU_C2_I                                           0x28
+#define     ATV_TOP_EQU3_EQU_C3_FM                                          0x0
+#define     ATV_TOP_EQU3_EQU_C3_L                                           0x192
+#define     ATV_TOP_EQU3_EQU_C3_LP                                          0x192
+#define     ATV_TOP_EQU3_EQU_C3_BG                                          0x12E
+#define     ATV_TOP_EQU3_EQU_C3_DK                                          0x18E
+#define     ATV_TOP_EQU3_EQU_C3_I                                           0x192
+#define     ATV_TOP_STD_MODE_MN                                             0x0
+#define     ATV_TOP_STD_MODE_FM                                             0x1
+#define     ATV_TOP_STD_MODE_L                                              0x0
+#define     ATV_TOP_STD_MODE_LP                                             0x0
+#define     ATV_TOP_STD_MODE_BG                                             0x0
+#define     ATV_TOP_STD_MODE_DK                                             0x0
+#define     ATV_TOP_STD_MODE_I                                              0x0
+#define     ATV_TOP_STD_VID_POL_MN                                          0x0
+#define     ATV_TOP_STD_VID_POL_FM                                          0x0
+#define     ATV_TOP_STD_VID_POL_L                                           0x2
+#define     ATV_TOP_STD_VID_POL_LP                                          0x2
+#define     ATV_TOP_STD_VID_POL_BG                                          0x0
+#define     ATV_TOP_STD_VID_POL_DK                                          0x0
+#define     ATV_TOP_STD_VID_POL_I                                           0x0
+#define   ATV_TOP_VID_AMP_MN                                                0x380
+#define   ATV_TOP_VID_AMP_FM                                                0x0
+#define   ATV_TOP_VID_AMP_L                                                 0xF50
+#define   ATV_TOP_VID_AMP_LP                                                0xF50
+#define   ATV_TOP_VID_AMP_BG                                                0x380
+#define   ATV_TOP_VID_AMP_DK                                                0x394
+#define   ATV_TOP_VID_AMP_I                                                 0x3D8
+#define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
+#define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
+#define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
+#define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
+#define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
+#define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
+#define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
+/**** END DJCOMBO patches to DRXJ registermap *********************************/
+
+#include "drx_driver_version.h"
+
+/* #define DRX_DEBUG */
+#ifdef DRX_DEBUG
+#include <stdio.h>
+#endif
+
+/*-----------------------------------------------------------------------------
+ENUMS
+----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+DEFINES
+----------------------------------------------------------------------------*/
+#ifndef DRXJ_WAKE_UP_KEY
+#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
+#endif
+
+/**
+* \def DRXJ_DEF_I2C_ADDR
+* \brief Default I2C addres of a demodulator instance.
+*/
+#define DRXJ_DEF_I2C_ADDR (0x52)
+
+/**
+* \def DRXJ_DEF_DEMOD_DEV_ID
+* \brief Default device identifier of a demodultor instance.
+*/
+#define DRXJ_DEF_DEMOD_DEV_ID      (1)
+
+/**
+* \def DRXJ_SCAN_TIMEOUT
+* \brief Timeout value for waiting on demod lock during channel scan (millisec).
+*/
+#define DRXJ_SCAN_TIMEOUT    1000
+
+/**
+* \def HI_I2C_DELAY
+* \brief HI timing delay for I2C timing (in nano seconds)
+*
+*  Used to compute HI_CFG_DIV
+*/
+#define HI_I2C_DELAY    42
+
+/**
+* \def HI_I2C_BRIDGE_DELAY
+* \brief HI timing delay for I2C timing (in nano seconds)
+*
+*  Used to compute HI_CFG_BDL
+*/
+#define HI_I2C_BRIDGE_DELAY   750
+
+/**
+* \brief Time Window for MER and SER Measurement in Units of Segment duration.
+*/
+#define VSB_TOP_MEASUREMENT_PERIOD  64
+#define SYMBOLS_PER_SEGMENT         832
+
+/**
+* \brief bit rate and segment rate constants used for SER and BER.
+*/
+/* values taken from the QAM microcode */
+#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
+#define DRXJ_QAM_SL_SIG_POWER_QPSK        32768
+#define DRXJ_QAM_SL_SIG_POWER_QAM8        24576
+#define DRXJ_QAM_SL_SIG_POWER_QAM16       40960
+#define DRXJ_QAM_SL_SIG_POWER_QAM32       20480
+#define DRXJ_QAM_SL_SIG_POWER_QAM64       43008
+#define DRXJ_QAM_SL_SIG_POWER_QAM128      20992
+#define DRXJ_QAM_SL_SIG_POWER_QAM256      43520
+/**
+* \brief Min supported symbolrates.
+*/
+#ifndef DRXJ_QAM_SYMBOLRATE_MIN
+#define DRXJ_QAM_SYMBOLRATE_MIN          (520000)
+#endif
+
+/**
+* \brief Max supported symbolrates.
+*/
+#ifndef DRXJ_QAM_SYMBOLRATE_MAX
+#define DRXJ_QAM_SYMBOLRATE_MAX         (7233000)
+#endif
+
+/**
+* \def DRXJ_QAM_MAX_WAITTIME
+* \brief Maximal wait time for QAM auto constellation in ms
+*/
+#ifndef DRXJ_QAM_MAX_WAITTIME
+#define DRXJ_QAM_MAX_WAITTIME 900
+#endif
+
+#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
+#define DRXJ_QAM_FEC_LOCK_WAITTIME 150
+#endif
+
+#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
+#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
+#endif
+
+/**
+* \def SCU status and results
+* \brief SCU
+*/
+#define DRX_SCU_READY               0
+#define DRXJ_MAX_WAITTIME           100        /* ms */
+#define FEC_RS_MEASUREMENT_PERIOD   12894      /* 1 sec */
+#define FEC_RS_MEASUREMENT_PRESCALE 1  /* n sec */
+
+/**
+* \def DRX_AUD_MAX_DEVIATION
+* \brief Needed for calculation of prescale feature in AUD
+*/
+#ifndef DRXJ_AUD_MAX_FM_DEVIATION
+#define DRXJ_AUD_MAX_FM_DEVIATION  100 /* kHz */
+#endif
+
+/**
+* \brief Needed for calculation of NICAM prescale feature in AUD
+*/
+#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
+#define DRXJ_AUD_MAX_NICAM_PRESCALE  (9)       /* dB */
+#endif
+
+/**
+* \brief Needed for calculation of NICAM prescale feature in AUD
+*/
+#ifndef DRXJ_AUD_MAX_WAITTIME
+#define DRXJ_AUD_MAX_WAITTIME  250     /* ms */
+#endif
+
+/* ATV config changed flags */
+#define DRXJ_ATV_CHANGED_COEF          (0x00000001UL)
+#define DRXJ_ATV_CHANGED_PEAK_FLT      (0x00000008UL)
+#define DRXJ_ATV_CHANGED_NOISE_FLT     (0x00000010UL)
+#define DRXJ_ATV_CHANGED_OUTPUT        (0x00000020UL)
+#define DRXJ_ATV_CHANGED_SIF_ATT       (0x00000040UL)
+
+/* UIO define */
+#define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
+#define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
+
+/*
+ * MICROCODE RELATED DEFINES
+ */
+
+/* Magic word for checking correct Endianess of microcode data */
+#define DRX_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))
+
+/* CRC flag in ucode header, flags field. */
+#define DRX_UCODE_CRC_FLAG           (0x0001)
+
+/*
+ * Maximum size of buffer used to verify the microcode.
+ * Must be an even number
+ */
+#define DRX_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)
+
+#if DRX_UCODE_MAX_BUF_SIZE & 1
+#error DRX_UCODE_MAX_BUF_SIZE must be an even number
+#endif
+
+/*
+ * Power mode macros
+ */
+
+#define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
+                                      (mode == DRX_POWER_MODE_10) || \
+                                      (mode == DRX_POWER_MODE_11) || \
+                                      (mode == DRX_POWER_MODE_12) || \
+                                      (mode == DRX_POWER_MODE_13) || \
+                                      (mode == DRX_POWER_MODE_14) || \
+                                      (mode == DRX_POWER_MODE_15) || \
+                                      (mode == DRX_POWER_MODE_16) || \
+                                      (mode == DRX_POWER_DOWN))
+
+/* Pin safe mode macro */
+#define DRXJ_PIN_SAFE_MODE 0x0000
+/*============================================================================*/
+/*=== GLOBAL VARIABLEs =======================================================*/
+/*============================================================================*/
+/**
+*/
+
+/**
+* \brief Temporary register definitions.
+*        (register definitions that are not yet available in register master)
+*/
+
+/******************************************************************************/
+/* Audio block 0x103 is write only. To avoid shadowing in driver accessing    */
+/* RAM adresses directly. This must be READ ONLY to avoid problems.           */
+/* Writing to the interface adresses is more than only writing the RAM        */
+/* locations                                                                  */
+/******************************************************************************/
+/**
+* \brief RAM location of MODUS registers
+*/
+#define AUD_DEM_RAM_MODUS_HI__A              0x10204A3
+#define AUD_DEM_RAM_MODUS_HI__M              0xF000
+
+#define AUD_DEM_RAM_MODUS_LO__A              0x10204A4
+#define AUD_DEM_RAM_MODUS_LO__M              0x0FFF
+
+/**
+* \brief RAM location of I2S config registers
+*/
+#define AUD_DEM_RAM_I2S_CONFIG1__A           0x10204B1
+#define AUD_DEM_RAM_I2S_CONFIG2__A           0x10204B2
+
+/**
+* \brief RAM location of DCO config registers
+*/
+#define AUD_DEM_RAM_DCO_B_HI__A              0x1020461
+#define AUD_DEM_RAM_DCO_B_LO__A              0x1020462
+#define AUD_DEM_RAM_DCO_A_HI__A              0x1020463
+#define AUD_DEM_RAM_DCO_A_LO__A              0x1020464
+
+/**
+* \brief RAM location of Threshold registers
+*/
+#define AUD_DEM_RAM_NICAM_THRSHLD__A         0x102045A
+#define AUD_DEM_RAM_A2_THRSHLD__A            0x10204BB
+#define AUD_DEM_RAM_BTSC_THRSHLD__A          0x10204A6
+
+/**
+* \brief RAM location of Carrier Threshold registers
+*/
+#define AUD_DEM_RAM_CM_A_THRSHLD__A          0x10204AF
+#define AUD_DEM_RAM_CM_B_THRSHLD__A          0x10204B0
+
+/**
+* \brief FM Matrix register fix
+*/
+#ifdef AUD_DEM_WR_FM_MATRIX__A
+#undef  AUD_DEM_WR_FM_MATRIX__A
+#endif
+#define AUD_DEM_WR_FM_MATRIX__A              0x105006F
+
+/*============================================================================*/
+/**
+* \brief Defines required for audio
+*/
+#define AUD_VOLUME_ZERO_DB                      115
+#define AUD_VOLUME_DB_MIN                       -60
+#define AUD_VOLUME_DB_MAX                       12
+#define AUD_CARRIER_STRENGTH_QP_0DB             0x4000
+#define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100   421
+#define AUD_MAX_AVC_REF_LEVEL                   15
+#define AUD_I2S_FREQUENCY_MAX                   48000UL
+#define AUD_I2S_FREQUENCY_MIN                   12000UL
+#define AUD_RDS_ARRAY_SIZE                      18
+
+/**
+* \brief Needed for calculation of prescale feature in AUD
+*/
+#ifndef DRX_AUD_MAX_FM_DEVIATION
+#define DRX_AUD_MAX_FM_DEVIATION  (100)        /* kHz */
+#endif
+
+/**
+* \brief Needed for calculation of NICAM prescale feature in AUD
+*/
+#ifndef DRX_AUD_MAX_NICAM_PRESCALE
+#define DRX_AUD_MAX_NICAM_PRESCALE  (9)        /* dB */
+#endif
+
+/*============================================================================*/
+/* Values for I2S Master/Slave pin configurations */
+#define SIO_PDR_I2S_CL_CFG_MODE__MASTER      0x0004
+#define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER     0x0008
+#define SIO_PDR_I2S_CL_CFG_MODE__SLAVE       0x0004
+#define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE      0x0000
+
+#define SIO_PDR_I2S_DA_CFG_MODE__MASTER      0x0003
+#define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER     0x0008
+#define SIO_PDR_I2S_DA_CFG_MODE__SLAVE       0x0003
+#define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE      0x0008
+
+#define SIO_PDR_I2S_WS_CFG_MODE__MASTER      0x0004
+#define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER     0x0008
+#define SIO_PDR_I2S_WS_CFG_MODE__SLAVE       0x0004
+#define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE      0x0000
+
+/*============================================================================*/
+/*=== REGISTER ACCESS MACROS =================================================*/
+/*============================================================================*/
+
+/**
+* This macro is used to create byte arrays for block writes.
+* Block writes speed up I2C traffic between host and demod.
+* The macro takes care of the required byte order in a 16 bits word.
+* x -> lowbyte(x), highbyte(x)
+*/
+#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
+                      ((u8)((((u16)x)>>8)&0xFF))
+/**
+* This macro is used to convert byte array to 16 bit register value for block read.
+* Block read speed up I2C traffic between host and demod.
+* The macro takes care of the required byte order in a 16 bits word.
+*/
+#define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
+
+/*============================================================================*/
+/*=== MISC DEFINES ===========================================================*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*=== HI COMMAND RELATED DEFINES =============================================*/
+/*============================================================================*/
+
+/**
+* \brief General maximum number of retries for ucode command interfaces
+*/
+#define DRXJ_MAX_RETRIES (100)
+
+/*============================================================================*/
+/*=== STANDARD RELATED MACROS ================================================*/
+/*============================================================================*/
+
+#define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
+                              (std == DRX_STANDARD_PAL_SECAM_DK) || \
+                              (std == DRX_STANDARD_PAL_SECAM_I) || \
+                              (std == DRX_STANDARD_PAL_SECAM_L) || \
+                              (std == DRX_STANDARD_PAL_SECAM_LP) || \
+                              (std == DRX_STANDARD_NTSC) || \
+                              (std == DRX_STANDARD_FM))
+
+#define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
+                              (std == DRX_STANDARD_ITU_B) || \
+                              (std == DRX_STANDARD_ITU_C) || \
+                              (std == DRX_STANDARD_ITU_D))
+
+/*-----------------------------------------------------------------------------
+GLOBAL VARIABLES
+----------------------------------------------------------------------------*/
+/*
+ * DRXJ DAP structures
+ */
+
+static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
+                                     u32 addr,
+                                     u16 datasize,
+                                     u8 *data, u32 flags);
+
+
+static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
+                                                u32 waddr,
+                                                u32 raddr,
+                                                u16 wdata, u16 *rdata);
+
+static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
+                                     u32 addr,
+                                     u16 *data, u32 flags);
+
+static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
+                                     u32 addr,
+                                     u32 *data, u32 flags);
+
+static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
+                                      u32 addr,
+                                      u16 datasize,
+                                      u8 *data, u32 flags);
+
+static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
+                                      u32 addr,
+                                      u16 data, u32 flags);
+
+static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
+                                      u32 addr,
+                                      u32 data, u32 flags);
+
+static struct drxj_data drxj_data_g = {
+       false,                  /* has_lna : true if LNA (aka PGA) present      */
+       false,                  /* has_oob : true if OOB supported              */
+       false,                  /* has_ntsc: true if NTSC supported             */
+       false,                  /* has_btsc: true if BTSC supported             */
+       false,                  /* has_smatx: true if SMA_TX pin is available   */
+       false,                  /* has_smarx: true if SMA_RX pin is available   */
+       false,                  /* has_gpio : true if GPIO pin is available     */
+       false,                  /* has_irqn : true if IRQN pin is available     */
+       0,                      /* mfx A1/A2/A... */
+
+       /* tuner settings */
+       false,                  /* tuner mirrors RF signal    */
+       /* standard/channel settings */
+       DRX_STANDARD_UNKNOWN,   /* current standard           */
+       DRX_CONSTELLATION_AUTO, /* constellation              */
+       0,                      /* frequency in KHz           */
+       DRX_BANDWIDTH_UNKNOWN,  /* curr_bandwidth              */
+       DRX_MIRROR_NO,          /* mirror                     */
+
+       /* signal quality information: */
+       /* default values taken from the QAM Programming guide */
+       /*   fec_bits_desired should not be less than 4000000    */
+       4000000,                /* fec_bits_desired    */
+       5,                      /* fec_vd_plen         */
+       4,                      /* qam_vd_prescale     */
+       0xFFFF,                 /* qamVDPeriod       */
+       204 * 8,                /* fec_rs_plen annex A */
+       1,                      /* fec_rs_prescale     */
+       FEC_RS_MEASUREMENT_PERIOD,      /* fec_rs_period     */
+       true,                   /* reset_pkt_err_acc    */
+       0,                      /* pkt_err_acc_start    */
+
+       /* HI configuration */
+       0,                      /* hi_cfg_timing_div    */
+       0,                      /* hi_cfg_bridge_delay  */
+       0,                      /* hi_cfg_wake_up_key    */
+       0,                      /* hi_cfg_ctrl         */
+       0,                      /* HICfgTimeout      */
+       /* UIO configuartion */
+       DRX_UIO_MODE_DISABLE,   /* uio_sma_rx_mode      */
+       DRX_UIO_MODE_DISABLE,   /* uio_sma_tx_mode      */
+       DRX_UIO_MODE_DISABLE,   /* uioASELMode       */
+       DRX_UIO_MODE_DISABLE,   /* uio_irqn_mode       */
+       /* FS setting */
+       0UL,                    /* iqm_fs_rate_ofs      */
+       false,                  /* pos_image          */
+       /* RC setting */
+       0UL,                    /* iqm_rc_rate_ofs      */
+       /* AUD information */
+/*   false,                  * flagSetAUDdone    */
+/*   false,                  * detectedRDS       */
+/*   true,                   * flagASDRequest    */
+/*   false,                  * flagHDevClear     */
+/*   false,                  * flagHDevSet       */
+/*   (u16) 0xFFF,          * rdsLastCount      */
+
+       /* ATV configuartion */
+       0UL,                    /* flags cfg changes */
+       /* shadow of ATV_TOP_EQU0__A */
+       {-5,
+        ATV_TOP_EQU0_EQU_C0_FM,
+        ATV_TOP_EQU0_EQU_C0_L,
+        ATV_TOP_EQU0_EQU_C0_LP,
+        ATV_TOP_EQU0_EQU_C0_BG,
+        ATV_TOP_EQU0_EQU_C0_DK,
+        ATV_TOP_EQU0_EQU_C0_I},
+       /* shadow of ATV_TOP_EQU1__A */
+       {-50,
+        ATV_TOP_EQU1_EQU_C1_FM,
+        ATV_TOP_EQU1_EQU_C1_L,
+        ATV_TOP_EQU1_EQU_C1_LP,
+        ATV_TOP_EQU1_EQU_C1_BG,
+        ATV_TOP_EQU1_EQU_C1_DK,
+        ATV_TOP_EQU1_EQU_C1_I},
+       /* shadow of ATV_TOP_EQU2__A */
+       {210,
+        ATV_TOP_EQU2_EQU_C2_FM,
+        ATV_TOP_EQU2_EQU_C2_L,
+        ATV_TOP_EQU2_EQU_C2_LP,
+        ATV_TOP_EQU2_EQU_C2_BG,
+        ATV_TOP_EQU2_EQU_C2_DK,
+        ATV_TOP_EQU2_EQU_C2_I},
+       /* shadow of ATV_TOP_EQU3__A */
+       {-160,
+        ATV_TOP_EQU3_EQU_C3_FM,
+        ATV_TOP_EQU3_EQU_C3_L,
+        ATV_TOP_EQU3_EQU_C3_LP,
+        ATV_TOP_EQU3_EQU_C3_BG,
+        ATV_TOP_EQU3_EQU_C3_DK,
+        ATV_TOP_EQU3_EQU_C3_I},
+       false,                  /* flag: true=bypass             */
+       ATV_TOP_VID_PEAK__PRE,  /* shadow of ATV_TOP_VID_PEAK__A */
+       ATV_TOP_NOISE_TH__PRE,  /* shadow of ATV_TOP_NOISE_TH__A */
+       true,                   /* flag CVBS ouput enable        */
+       false,                  /* flag SIF ouput enable         */
+       DRXJ_SIF_ATTENUATION_0DB,       /* current SIF att setting       */
+       {                       /* qam_rf_agc_cfg */
+        DRX_STANDARD_ITU_B,    /* standard            */
+        DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
+        0,                     /* output_level         */
+        0,                     /* min_output_level      */
+        0xFFFF,                /* max_output_level      */
+        0x0000,                /* speed               */
+        0x0000,                /* top                 */
+        0x0000                 /* c.o.c.              */
+        },
+       {                       /* qam_if_agc_cfg */
+        DRX_STANDARD_ITU_B,    /* standard            */
+        DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
+        0,                     /* output_level         */
+        0,                     /* min_output_level      */
+        0xFFFF,                /* max_output_level      */
+        0x0000,                /* speed               */
+        0x0000,                /* top    (don't care) */
+        0x0000                 /* c.o.c. (don't care) */
+        },
+       {                       /* vsb_rf_agc_cfg */
+        DRX_STANDARD_8VSB,     /* standard       */
+        DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
+        0,                     /* output_level    */
+        0,                     /* min_output_level */
+        0xFFFF,                /* max_output_level */
+        0x0000,                /* speed          */
+        0x0000,                /* top    (don't care) */
+        0x0000                 /* c.o.c. (don't care) */
+        },
+       {                       /* vsb_if_agc_cfg */
+        DRX_STANDARD_8VSB,     /* standard       */
+        DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
+        0,                     /* output_level    */
+        0,                     /* min_output_level */
+        0xFFFF,                /* max_output_level */
+        0x0000,                /* speed          */
+        0x0000,                /* top    (don't care) */
+        0x0000                 /* c.o.c. (don't care) */
+        },
+       0,                      /* qam_pga_cfg */
+       0,                      /* vsb_pga_cfg */
+       {                       /* qam_pre_saw_cfg */
+        DRX_STANDARD_ITU_B,    /* standard  */
+        0,                     /* reference */
+        false                  /* use_pre_saw */
+        },
+       {                       /* vsb_pre_saw_cfg */
+        DRX_STANDARD_8VSB,     /* standard  */
+        0,                     /* reference */
+        false                  /* use_pre_saw */
+        },
+
+       /* Version information */
+#ifndef _CH_
+       {
+        "01234567890",         /* human readable version microcode             */
+        "01234567890"          /* human readable version device specific code  */
+        },
+       {
+        {                      /* struct drx_version for microcode                   */
+         DRX_MODULE_UNKNOWN,
+         (char *)(NULL),
+         0,
+         0,
+         0,
+         (char *)(NULL)
+         },
+        {                      /* struct drx_version for device specific code */
+         DRX_MODULE_UNKNOWN,
+         (char *)(NULL),
+         0,
+         0,
+         0,
+         (char *)(NULL)
+         }
+        },
+       {
+        {                      /* struct drx_version_list for microcode */
+         (struct drx_version *) (NULL),
+         (struct drx_version_list *) (NULL)
+         },
+        {                      /* struct drx_version_list for device specific code */
+         (struct drx_version *) (NULL),
+         (struct drx_version_list *) (NULL)
+         }
+        },
+#endif
+       false,                  /* smart_ant_inverted */
+       /* Tracking filter setting for OOB  */
+       {
+        12000,
+        9300,
+        6600,
+        5280,
+        3700,
+        3000,
+        2000,
+        0},
+       false,                  /* oob_power_on           */
+       0,                      /* mpeg_ts_static_bitrate  */
+       false,                  /* disable_te_ihandling   */
+       false,                  /* bit_reverse_mpeg_outout */
+       DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,        /* mpeg_output_clock_rate */
+       DRXJ_MPEG_START_WIDTH_1CLKCYC,  /* mpeg_start_width */
+
+       /* Pre SAW & Agc configuration for ATV */
+       {
+        DRX_STANDARD_NTSC,     /* standard     */
+        7,                     /* reference    */
+        true                   /* use_pre_saw    */
+        },
+       {                       /* ATV RF-AGC */
+        DRX_STANDARD_NTSC,     /* standard              */
+        DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
+        0,                     /* output_level           */
+        0,                     /* min_output_level (d.c.) */
+        0,                     /* max_output_level (d.c.) */
+        3,                     /* speed                 */
+        9500,                  /* top                   */
+        4000                   /* cut-off current       */
+        },
+       {                       /* ATV IF-AGC */
+        DRX_STANDARD_NTSC,     /* standard              */
+        DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
+        0,                     /* output_level           */
+        0,                     /* min_output_level (d.c.) */
+        0,                     /* max_output_level (d.c.) */
+        3,                     /* speed                 */
+        2400,                  /* top                   */
+        0                      /* c.o.c.         (d.c.) */
+        },
+       140,                    /* ATV PGA config */
+       0,                      /* curr_symbol_rate */
+
+       false,                  /* pdr_safe_mode     */
+       SIO_PDR_GPIO_CFG__PRE,  /* pdr_safe_restore_val_gpio  */
+       SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
+       SIO_PDR_SMA_RX_CFG__PRE,        /* pdr_safe_restore_val_sma_rx */
+       SIO_PDR_SMA_TX_CFG__PRE,        /* pdr_safe_restore_val_sma_tx */
+
+       4,                      /* oob_pre_saw            */
+       DRXJ_OOB_LO_POW_MINUS10DB,      /* oob_lo_pow             */
+       {
+        false                  /* aud_data, only first member */
+        },
+};
+
+/**
+* \var drxj_default_addr_g
+* \brief Default I2C address and device identifier.
+*/
+static struct i2c_device_addr drxj_default_addr_g = {
+       DRXJ_DEF_I2C_ADDR,      /* i2c address */
+       DRXJ_DEF_DEMOD_DEV_ID   /* device id */
+};
+
+/**
+* \var drxj_default_comm_attr_g
+* \brief Default common attributes of a drxj demodulator instance.
+*/
+static struct drx_common_attr drxj_default_comm_attr_g = {
+       NULL,                   /* ucode file           */
+       true,                   /* ucode verify switch  */
+       {0},                    /* version record       */
+
+       44000,                  /* IF in kHz in case no tuner instance is used  */
+       (151875 - 0),           /* system clock frequency in kHz                */
+       0,                      /* oscillator frequency kHz                     */
+       0,                      /* oscillator deviation in ppm, signed          */
+       false,                  /* If true mirror frequency spectrum            */
+       {
+        /* MPEG output configuration */
+        true,                  /* If true, enable MPEG ouput    */
+        false,                 /* If true, insert RS byte       */
+        false,                 /* If true, parallel out otherwise serial */
+        false,                 /* If true, invert DATA signals  */
+        false,                 /* If true, invert ERR signal    */
+        false,                 /* If true, invert STR signals   */
+        false,                 /* If true, invert VAL signals   */
+        false,                 /* If true, invert CLK signals   */
+        true,                  /* If true, static MPEG clockrate will
+                                  be used, otherwise clockrate will
+                                  adapt to the bitrate of the TS */
+        19392658UL,            /* Maximum bitrate in b/s in case
+                                  static clockrate is selected */
+        DRX_MPEG_STR_WIDTH_1   /* MPEG Start width in clock cycles */
+        },
+       /* Initilisations below can be ommited, they require no user input and
+          are initialy 0, NULL or false. The compiler will initialize them to these
+          values when ommited.  */
+       false,                  /* is_opened */
+
+       /* SCAN */
+       NULL,                   /* no scan params yet               */
+       0,                      /* current scan index               */
+       0,                      /* next scan frequency              */
+       false,                  /* scan ready flag                  */
+       0,                      /* max channels to scan             */
+       0,                      /* nr of channels scanned           */
+       NULL,                   /* default scan function            */
+       NULL,                   /* default context pointer          */
+       0,                      /* millisec to wait for demod lock  */
+       DRXJ_DEMOD_LOCK,        /* desired lock               */
+       false,
+
+       /* Power management */
+       DRX_POWER_UP,
+
+       /* Tuner */
+       1,                      /* nr of I2C port to wich tuner is     */
+       0L,                     /* minimum RF input frequency, in kHz  */
+       0L,                     /* maximum RF input frequency, in kHz  */
+       false,                  /* Rf Agc Polarity                     */
+       false,                  /* If Agc Polarity                     */
+       false,                  /* tuner slow mode                     */
+
+       {                       /* current channel (all 0)             */
+        0UL                    /* channel.frequency */
+        },
+       DRX_STANDARD_UNKNOWN,   /* current standard */
+       DRX_STANDARD_UNKNOWN,   /* previous standard */
+       DRX_STANDARD_UNKNOWN,   /* di_cache_standard   */
+       false,                  /* use_bootloader */
+       0UL,                    /* capabilities */
+       0                       /* mfx */
+};
+
+/**
+* \var drxj_default_demod_g
+* \brief Default drxj demodulator instance.
+*/
+static struct drx_demod_instance drxj_default_demod_g = {
+       &drxj_default_addr_g,   /* i2c address & device id */
+       &drxj_default_comm_attr_g,      /* demod common attributes */
+       &drxj_data_g            /* demod device specific attributes */
+};
+
+/**
+* \brief Default audio data structure for DRK demodulator instance.
+*
+* This structure is DRXK specific.
+*
+*/
+static struct drx_aud_data drxj_default_aud_data_g = {
+       false,                  /* audio_is_active */
+       DRX_AUD_STANDARD_AUTO,  /* audio_standard  */
+
+       /* i2sdata */
+       {
+        false,                 /* output_enable   */
+        48000,                 /* frequency      */
+        DRX_I2S_MODE_MASTER,   /* mode           */
+        DRX_I2S_WORDLENGTH_32, /* word_length     */
+        DRX_I2S_POLARITY_RIGHT,        /* polarity       */
+        DRX_I2S_FORMAT_WS_WITH_DATA    /* format         */
+        },
+       /* volume            */
+       {
+        true,                  /* mute;          */
+        0,                     /* volume         */
+        DRX_AUD_AVC_OFF,       /* avc_mode        */
+        0,                     /* avc_ref_level    */
+        DRX_AUD_AVC_MAX_GAIN_12DB,     /* avc_max_gain     */
+        DRX_AUD_AVC_MAX_ATTEN_24DB,    /* avc_max_atten    */
+        0,                     /* strength_left   */
+        0                      /* strength_right  */
+        },
+       DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
+       /*  ass_thresholds */
+       {
+        440,                   /* A2    */
+        12,                    /* BTSC  */
+        700,                   /* NICAM */
+        },
+       /* carrier */
+       {
+        /* a */
+        {
+         42,                   /* thres */
+         DRX_NO_CARRIER_NOISE, /* opt   */
+         0,                    /* shift */
+         0                     /* dco   */
+         },
+        /* b */
+        {
+         42,                   /* thres */
+         DRX_NO_CARRIER_MUTE,  /* opt   */
+         0,                    /* shift */
+         0                     /* dco   */
+         },
+
+        },
+       /* mixer */
+       {
+        DRX_AUD_SRC_STEREO_OR_A,       /* source_i2s */
+        DRX_AUD_I2S_MATRIX_STEREO,     /* matrix_i2s */
+        DRX_AUD_FM_MATRIX_SOUND_A      /* matrix_fm  */
+        },
+       DRX_AUD_DEVIATION_NORMAL,       /* deviation */
+       DRX_AUD_AVSYNC_OFF,     /* av_sync */
+
+       /* prescale */
+       {
+        DRX_AUD_MAX_FM_DEVIATION,      /* fm_deviation */
+        DRX_AUD_MAX_NICAM_PRESCALE     /* nicam_gain */
+        },
+       DRX_AUD_FM_DEEMPH_75US, /* deemph */
+       DRX_BTSC_STEREO,        /* btsc_detect */
+       0,                      /* rds_data_counter */
+       false                   /* rds_data_present */
+};
+
+/*-----------------------------------------------------------------------------
+STRUCTURES
+----------------------------------------------------------------------------*/
+struct drxjeq_stat {
+       u16 eq_mse;
+       u8 eq_mode;
+       u8 eq_ctrl;
+       u8 eq_stat;
+};
+
+/* HI command */
+struct drxj_hi_cmd {
+       u16 cmd;
+       u16 param1;
+       u16 param2;
+       u16 param3;
+       u16 param4;
+       u16 param5;
+       u16 param6;
+};
+
+/*============================================================================*/
+/*=== MICROCODE RELATED STRUCTURES ===========================================*/
+/*============================================================================*/
+
+/**
+ * struct drxu_code_block_hdr - Structure of the microcode block headers
+ *
+ * @addr:      Destination address of the data in this block
+ * @size:      Size of the block data following this header counted in
+ *             16 bits words
+ * @CRC:       CRC value of the data block, only valid if CRC flag is
+ *             set.
+ */
+struct drxu_code_block_hdr {
+       u32 addr;
+       u16 size;
+       u16 flags;
+       u16 CRC;
+};
+
+/*-----------------------------------------------------------------------------
+FUNCTIONS
+----------------------------------------------------------------------------*/
+/* Some prototypes */
+static int
+hi_command(struct i2c_device_addr *dev_addr,
+          const struct drxj_hi_cmd *cmd, u16 *result);
+
+static int
+ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
+
+static int
+ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
+
+static int power_down_aud(struct drx_demod_instance *demod);
+
+static int
+ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
+
+static int
+ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                          HELPER FUNCTIONS                              ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*============================================================================*/
+
+/*
+* \fn u32 frac28(u32 N, u32 D)
+* \brief Compute: (1<<28)*N/D
+* \param N 32 bits
+* \param D 32 bits
+* \return (1<<28)*N/D
+* This function is used to avoid floating-point calculations as they may
+* not be present on the target platform.
+
+* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
+* fraction used for setting the Frequency Shifter registers.
+* N and D can hold numbers up to width: 28-bits.
+* The 4 bits integer part and the 28 bits fractional part are calculated.
+
+* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
+
+* N: 0...(1<<28)-1 = 268435454
+* D: 0...(1<<28)-1
+* Q: 0...(1<<32)-1
+*/
+static u32 frac28(u32 N, u32 D)
+{
+       int i = 0;
+       u32 Q1 = 0;
+       u32 R0 = 0;
+
+       R0 = (N % D) << 4;      /* 32-28 == 4 shifts possible at max */
+       Q1 = N / D;             /* integer part, only the 4 least significant bits
+                                  will be visible in the result */
+
+       /* division using radix 16, 7 nibbles in the result */
+       for (i = 0; i < 7; i++) {
+               Q1 = (Q1 << 4) | R0 / D;
+               R0 = (R0 % D) << 4;
+       }
+       /* rounding */
+       if ((R0 >> 3) >= D)
+               Q1++;
+
+       return Q1;
+}
+
+/**
+* \fn u32 log1_times100( u32 x)
+* \brief Compute: 100*log10(x)
+* \param x 32 bits
+* \return 100*log10(x)
+*
+* 100*log10(x)
+* = 100*(log2(x)/log2(10)))
+* = (100*(2^15)*log2(x))/((2^15)*log2(10))
+* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
+* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
+* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
+*
+* where y = 2^k and 1<= (x/y) < 2
+*/
+
+static u32 log1_times100(u32 x)
+{
+       static const u8 scale = 15;
+       static const u8 index_width = 5;
+       /*
+          log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
+          0 <= n < ((1<<INDEXWIDTH)+1)
+        */
+
+       static const u32 log2lut[] = {
+               0,              /* 0.000000 */
+               290941,         /* 290941.300628 */
+               573196,         /* 573196.476418 */
+               847269,         /* 847269.179851 */
+               1113620,        /* 1113620.489452 */
+               1372674,        /* 1372673.576986 */
+               1624818,        /* 1624817.752104 */
+               1870412,        /* 1870411.981536 */
+               2109788,        /* 2109787.962654 */
+               2343253,        /* 2343252.817465 */
+               2571091,        /* 2571091.461923 */
+               2793569,        /* 2793568.696416 */
+               3010931,        /* 3010931.055901 */
+               3223408,        /* 3223408.452106 */
+               3431216,        /* 3431215.635215 */
+               3634553,        /* 3634553.498355 */
+               3833610,        /* 3833610.244726 */
+               4028562,        /* 4028562.434393 */
+               4219576,        /* 4219575.925308 */
+               4406807,        /* 4406806.721144 */
+               4590402,        /* 4590401.736809 */
+               4770499,        /* 4770499.491025 */
+               4947231,        /* 4947230.734179 */
+               5120719,        /* 5120719.018555 */
+               5291081,        /* 5291081.217197 */
+               5458428,        /* 5458427.996830 */
+               5622864,        /* 5622864.249668 */
+               5784489,        /* 5784489.488298 */
+               5943398,        /* 5943398.207380 */
+               6099680,        /* 6099680.215452 */
+               6253421,        /* 6253420.939751 */
+               6404702,        /* 6404701.706649 */
+               6553600,        /* 6553600.000000 */
+       };
+
+       u8 i = 0;
+       u32 y = 0;
+       u32 d = 0;
+       u32 k = 0;
+       u32 r = 0;
+
+       if (x == 0)
+               return 0;
+
+       /* Scale x (normalize) */
+       /* computing y in log(x/y) = log(x) - log(y) */
+       if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
+               for (k = scale; k > 0; k--) {
+                       if (x & (((u32) 1) << scale))
+                               break;
+                       x <<= 1;
+               }
+       } else {
+               for (k = scale; k < 31; k++) {
+                       if ((x & (((u32) (-1)) << (scale + 1))) == 0)
+                               break;
+                       x >>= 1;
+               }
+       }
+       /*
+          Now x has binary point between bit[scale] and bit[scale-1]
+          and 1.0 <= x < 2.0 */
+
+       /* correction for divison: log(x) = log(x/y)+log(y) */
+       y = k * ((((u32) 1) << scale) * 200);
+
+       /* remove integer part */
+       x &= ((((u32) 1) << scale) - 1);
+       /* get index */
+       i = (u8) (x >> (scale - index_width));
+       /* compute delta (x-a) */
+       d = x & ((((u32) 1) << (scale - index_width)) - 1);
+       /* compute log, multiplication ( d* (.. )) must be within range ! */
+       y += log2lut[i] +
+           ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
+       /* Conver to log10() */
+       y /= 108853;            /* (log2(10) << scale) */
+       r = (y >> 1);
+       /* rounding */
+       if (y & ((u32)1))
+               r++;
+
+       return r;
+
+}
+
+/**
+* \fn u32 frac_times1e6( u16 N, u32 D)
+* \brief Compute: (N/D) * 1000000.
+* \param N nominator 16-bits.
+* \param D denominator 32-bits.
+* \return u32
+* \retval ((N/D) * 1000000), 32 bits
+*
+* No check on D=0!
+*/
+static u32 frac_times1e6(u32 N, u32 D)
+{
+       u32 remainder = 0;
+       u32 frac = 0;
+
+       /*
+          frac = (N * 1000000) / D
+          To let it fit in a 32 bits computation:
+          frac = (N * (1000000 >> 4)) / (D >> 4)
+          This would result in a problem in case D < 16 (div by 0).
+          So we do it more elaborate as shown below.
+        */
+       frac = (((u32) N) * (1000000 >> 4)) / D;
+       frac <<= 4;
+       remainder = (((u32) N) * (1000000 >> 4)) % D;
+       remainder <<= 4;
+       frac += remainder / D;
+       remainder = remainder % D;
+       if ((remainder * 2) > D)
+               frac++;
+
+       return frac;
+}
+
+/*============================================================================*/
+
+
+/**
+* \brief Values for NICAM prescaler gain. Computed from dB to integer
+*        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
+*
+*/
+static const u16 nicam_presc_table_val[43] = {
+       1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
+       5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
+       18, 20, 23, 25, 28, 32, 36, 40, 45,
+       51, 57, 64, 71, 80, 90, 101, 113, 127
+};
+
+/*============================================================================*/
+/*==                        END HELPER FUNCTIONS                            ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                      DRXJ DAP FUNCTIONS                                ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+/*
+   This layer takes care of some device specific register access protocols:
+   -conversion to short address format
+   -access to audio block
+   This layer is placed between the drx_dap_fasi and the rest of the drxj
+   specific implementation. This layer can use address map knowledge whereas
+   dap_fasi may not use memory map knowledge.
+
+   * For audio currently only 16 bits read and write register access is
+     supported. More is not needed. RMW and 32 or 8 bit access on audio
+     registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
+     single/multi master) will be ignored.
+
+   TODO: check ignoring single/multimaster is ok for AUD access ?
+*/
+
+#define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
+#define DRXJ_DAP_AUDTRIF_TIMEOUT 80    /* millisec */
+/*============================================================================*/
+
+/**
+* \fn bool is_handled_by_aud_tr_if( u32 addr )
+* \brief Check if this address is handled by the audio token ring interface.
+* \param addr
+* \return bool
+* \retval true  Yes, handled by audio token ring interface
+* \retval false No, not handled by audio token ring interface
+*
+*/
+static
+bool is_handled_by_aud_tr_if(u32 addr)
+{
+       bool retval = false;
+
+       if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
+           (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
+           (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
+               retval = true;
+       }
+
+       return retval;
+}
+
+/*============================================================================*/
+
+int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
+                                u16 w_count,
+                                u8 *wData,
+                                struct i2c_device_addr *r_dev_addr,
+                                u16 r_count, u8 *r_data)
+{
+       struct drx39xxj_state *state;
+       struct i2c_msg msg[2];
+       unsigned int num_msgs;
+
+       if (w_dev_addr == NULL) {
+               /* Read only */
+               state = r_dev_addr->user_data;
+               msg[0].addr = r_dev_addr->i2c_addr >> 1;
+               msg[0].flags = I2C_M_RD;
+               msg[0].buf = r_data;
+               msg[0].len = r_count;
+               num_msgs = 1;
+       } else if (r_dev_addr == NULL) {
+               /* Write only */
+               state = w_dev_addr->user_data;
+               msg[0].addr = w_dev_addr->i2c_addr >> 1;
+               msg[0].flags = 0;
+               msg[0].buf = wData;
+               msg[0].len = w_count;
+               num_msgs = 1;
+       } else {
+               /* Both write and read */
+               state = w_dev_addr->user_data;
+               msg[0].addr = w_dev_addr->i2c_addr >> 1;
+               msg[0].flags = 0;
+               msg[0].buf = wData;
+               msg[0].len = w_count;
+               msg[1].addr = r_dev_addr->i2c_addr >> 1;
+               msg[1].flags = I2C_M_RD;
+               msg[1].buf = r_data;
+               msg[1].len = r_count;
+               num_msgs = 2;
+       }
+
+       if (state->i2c == NULL) {
+               pr_err("i2c was zero, aborting\n");
+               return 0;
+       }
+       if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
+               pr_warn("drx3933: I2C write/read failed\n");
+               return -EREMOTEIO;
+       }
+
+#ifdef DJH_DEBUG
+       if (w_dev_addr == NULL || r_dev_addr == NULL)
+               return 0;
+
+       state = w_dev_addr->user_data;
+
+       if (state->i2c == NULL)
+               return 0;
+
+       msg[0].addr = w_dev_addr->i2c_addr;
+       msg[0].flags = 0;
+       msg[0].buf = wData;
+       msg[0].len = w_count;
+       msg[1].addr = r_dev_addr->i2c_addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].buf = r_data;
+       msg[1].len = r_count;
+       num_msgs = 2;
+
+       pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
+              w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
+
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               pr_warn("drx3933: I2C write/read failed\n");
+               return -EREMOTEIO;
+       }
+#endif
+       return 0;
+}
+
+/*============================================================================*/
+
+/******************************
+*
+* int drxdap_fasi_read_block (
+*      struct i2c_device_addr *dev_addr,      -- address of I2C device
+*      u32 addr,         -- address of chip register/memory
+*      u16            datasize,     -- number of bytes to read
+*      u8 *data,         -- data to receive
+*      u32 flags)        -- special device flags
+*
+* Read block data from chip address. Because the chip is word oriented,
+* the number of bytes to read must be even.
+*
+* Make sure that the buffer to receive the data is large enough.
+*
+* Although this function expects an even number of bytes, it is still byte
+* oriented, and the data read back is NOT translated to the endianness of
+* the target platform.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: data read is in *data.
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u16 datasize,
+                                        u8 *data, u32 flags)
+{
+       u8 buf[4];
+       u16 bufx;
+       int rc;
+       u16 overhead_size = 0;
+
+       /* Check parameters ******************************************************* */
+       if (dev_addr == NULL)
+               return -EINVAL;
+
+       overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
+           (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
+
+       if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
+           ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
+            DRXDAP_FASI_LONG_FORMAT(addr)) ||
+           (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
+           ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
+               return -EINVAL;
+       }
+
+       /* ReadModifyWrite & mode flag bits are not allowed */
+       flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
+#if DRXDAP_SINGLE_MASTER
+       flags |= DRXDAP_FASI_SINGLE_MASTER;
+#endif
+
+       /* Read block from I2C **************************************************** */
+       do {
+               u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
+                             datasize : DRXDAP_MAX_RCHUNKSIZE);
+
+               bufx = 0;
+
+               addr &= ~DRXDAP_FASI_FLAGS;
+               addr |= flags;
+
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+               /* short format address preferred but long format otherwise */
+               if (DRXDAP_FASI_LONG_FORMAT(addr)) {
+#endif
+#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
+                       buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
+                       buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
+#endif
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+               } else {
+#endif
+#if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
+                       buf[bufx++] = (u8) ((addr << 1) & 0xFF);
+                       buf[bufx++] =
+                           (u8) (((addr >> 16) & 0x0F) |
+                                   ((addr >> 18) & 0xF0));
+#endif
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
+               }
+#endif
+
+#if DRXDAP_SINGLE_MASTER
+               /*
+                * In single master mode, split the read and write actions.
+                * No special action is needed for write chunks here.
+                */
+               rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
+                                          NULL, 0, NULL);
+               if (rc == 0)
+                       rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);
+#else
+               /* In multi master mode, do everything in one RW action */
+               rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
+                                         data);
+#endif
+               data += todo;
+               addr += (todo >> 1);
+               datasize -= todo;
+       } while (datasize && rc == 0);
+
+       return rc;
+}
+
+
+/******************************
+*
+* int drxdap_fasi_read_reg16 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u16 *data,    -- data to receive
+*     u32 flags)   -- special device flags
+*
+* Read one 16-bit register or memory location. The data received back is
+* converted back to the target platform's endianness.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: read data is at *data
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u16 *data, u32 flags)
+{
+       u8 buf[sizeof(*data)];
+       int rc;
+
+       if (!data)
+               return -EINVAL;
+
+       rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
+       *data = buf[0] + (((u16) buf[1]) << 8);
+       return rc;
+}
+
+/******************************
+*
+* int drxdap_fasi_read_reg32 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u32 *data,    -- data to receive
+*     u32 flags)   -- special device flags
+*
+* Read one 32-bit register or memory location. The data received back is
+* converted back to the target platform's endianness.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: read data is at *data
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u32 *data, u32 flags)
+{
+       u8 buf[sizeof(*data)];
+       int rc;
+
+       if (!data)
+               return -EINVAL;
+
+       rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
+       *data = (((u32) buf[0]) << 0) +
+           (((u32) buf[1]) << 8) +
+           (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
+       return rc;
+}
+
+/******************************
+*
+* int drxdap_fasi_write_block (
+*      struct i2c_device_addr *dev_addr,    -- address of I2C device
+*      u32 addr,       -- address of chip register/memory
+*      u16            datasize,   -- number of bytes to read
+*      u8 *data,       -- data to receive
+*      u32 flags)      -- special device flags
+*
+* Write block data to chip address. Because the chip is word oriented,
+* the number of bytes to write must be even.
+*
+* Although this function expects an even number of bytes, it is still byte
+* oriented, and the data being written is NOT translated from the endianness of
+* the target platform.
+*
+* Output:
+* - 0     if writing was successful
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u16 datasize,
+                                         u8 *data, u32 flags)
+{
+       u8 buf[DRXDAP_MAX_WCHUNKSIZE];
+       int st = -EIO;
+       int first_err = 0;
+       u16 overhead_size = 0;
+       u16 block_size = 0;
+
+       /* Check parameters ******************************************************* */
+       if (dev_addr == NULL)
+               return -EINVAL;
+
+       overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
+           (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
+
+       if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
+           ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
+            DRXDAP_FASI_LONG_FORMAT(addr)) ||
+           (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
+           ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
+               return -EINVAL;
+
+       flags &= DRXDAP_FASI_FLAGS;
+       flags &= ~DRXDAP_FASI_MODEFLAGS;
+#if DRXDAP_SINGLE_MASTER
+       flags |= DRXDAP_FASI_SINGLE_MASTER;
+#endif
+
+       /* Write block to I2C ***************************************************** */
+       block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
+       do {
+               u16 todo = 0;
+               u16 bufx = 0;
+
+               /* Buffer device address */
+               addr &= ~DRXDAP_FASI_FLAGS;
+               addr |= flags;
+#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
+               /* short format address preferred but long format otherwise */
+               if (DRXDAP_FASI_LONG_FORMAT(addr)) {
+#endif
+#if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
+                       buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
+                       buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
+                       buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
+#endif
+#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
+               } else {
+#endif
+#if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
+                       buf[bufx++] = (u8) ((addr << 1) & 0xFF);
+                       buf[bufx++] =
+                           (u8) (((addr >> 16) & 0x0F) |
+                                   ((addr >> 18) & 0xF0));
+#endif
+#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
+               }
+#endif
+
+               /*
+                  In single master mode block_size can be 0. In such a case this I2C
+                  sequense will be visible: (1) write address {i2c addr,
+                  4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
+                  (3) write address (4) write data etc...
+                  Addres must be rewriten because HI is reset after data transport and
+                  expects an address.
+                */
+               todo = (block_size < datasize ? block_size : datasize);
+               if (todo == 0) {
+                       u16 overhead_size_i2c_addr = 0;
+                       u16 data_block_size = 0;
+
+                       overhead_size_i2c_addr =
+                           (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
+                       data_block_size =
+                           (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
+
+                       /* write device address */
+                       st = drxbsp_i2c_write_read(dev_addr,
+                                                 (u16) (bufx),
+                                                 buf,
+                                                 (struct i2c_device_addr *)(NULL),
+                                                 0, (u8 *)(NULL));
+
+                       if ((st != 0) && (first_err == 0)) {
+                               /* at the end, return the first error encountered */
+                               first_err = st;
+                       }
+                       bufx = 0;
+                       todo =
+                           (data_block_size <
+                            datasize ? data_block_size : datasize);
+               }
+               memcpy(&buf[bufx], data, todo);
+               /* write (address if can do and) data */
+               st = drxbsp_i2c_write_read(dev_addr,
+                                         (u16) (bufx + todo),
+                                         buf,
+                                         (struct i2c_device_addr *)(NULL),
+                                         0, (u8 *)(NULL));
+
+               if ((st != 0) && (first_err == 0)) {
+                       /* at the end, return the first error encountered */
+                       first_err = st;
+               }
+               datasize -= todo;
+               data += todo;
+               addr += (todo >> 1);
+       } while (datasize);
+
+       return first_err;
+}
+
+/******************************
+*
+* int drxdap_fasi_write_reg16 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u16            data,    -- data to send
+*     u32 flags)   -- special device flags
+*
+* Write one 16-bit register or memory location. The data being written is
+* converted from the target platform's endianness to little endian.
+*
+* Output:
+* - 0     if writing was successful
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u16 data, u32 flags)
+{
+       u8 buf[sizeof(data)];
+
+       buf[0] = (u8) ((data >> 0) & 0xFF);
+       buf[1] = (u8) ((data >> 8) & 0xFF);
+
+       return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
+}
+
+/******************************
+*
+* int drxdap_fasi_read_modify_write_reg16 (
+*      struct i2c_device_addr *dev_addr,   -- address of I2C device
+*      u32 waddr,     -- address of chip register/memory
+*      u32 raddr,     -- chip address to read back from
+*      u16            wdata,     -- data to send
+*      u16 *rdata)     -- data to receive back
+*
+* Write 16-bit data, then read back the original contents of that location.
+* Requires long addressing format to be allowed.
+*
+* Before sending data, the data is converted to little endian. The
+* data received back is converted back to the target platform's endianness.
+*
+* WARNING: This function is only guaranteed to work if there is one
+* master on the I2C bus.
+*
+* Output:
+* - 0     if reading was successful
+*                  in that case: read back data is at *rdata
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
+                                                   u32 waddr,
+                                                   u32 raddr,
+                                                   u16 wdata, u16 *rdata)
+{
+       int rc = -EIO;
+
+#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
+       if (rdata == NULL)
+               return -EINVAL;
+
+       rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
+       if (rc == 0)
+               rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
+#endif
+
+       return rc;
+}
+
+/******************************
+*
+* int drxdap_fasi_write_reg32 (
+*     struct i2c_device_addr *dev_addr, -- address of I2C device
+*     u32 addr,    -- address of chip register/memory
+*     u32            data,    -- data to send
+*     u32 flags)   -- special device flags
+*
+* Write one 32-bit register or memory location. The data being written is
+* converted from the target platform's endianness to little endian.
+*
+* Output:
+* - 0     if writing was successful
+* - -EIO  if anything went wrong
+*
+******************************/
+
+static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u32 data, u32 flags)
+{
+       u8 buf[sizeof(data)];
+
+       buf[0] = (u8) ((data >> 0) & 0xFF);
+       buf[1] = (u8) ((data >> 8) & 0xFF);
+       buf[2] = (u8) ((data >> 16) & 0xFF);
+       buf[3] = (u8) ((data >> 24) & 0xFF);
+
+       return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
+}
+
+/*============================================================================*/
+
+/**
+* \fn int drxj_dap_rm_write_reg16short
+* \brief Read modify write 16 bits audio register using short format only.
+* \param dev_addr
+* \param waddr    Address to write to
+* \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
+* \param wdata    Data to write
+* \param rdata    Buffer for data to read
+* \return int
+* \retval 0 Succes
+* \retval -EIO Timeout, I2C error, illegal bank
+*
+* 16 bits register read modify write access using short addressing format only.
+* Requires knowledge of the registermap, thus device dependent.
+* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
+*
+*/
+
+/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
+   See comments drxj_dap_read_modify_write_reg16 */
+#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
+static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
+                                             u32 waddr,
+                                             u32 raddr,
+                                             u16 wdata, u16 *rdata)
+{
+       int rc;
+
+       if (rdata == NULL)
+               return -EINVAL;
+
+       /* Set RMW flag */
+       rc = drxdap_fasi_write_reg16(dev_addr,
+                                             SIO_HI_RA_RAM_S0_FLG_ACC__A,
+                                             SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
+                                             0x0000);
+       if (rc == 0) {
+               /* Write new data: triggers RMW */
+               rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
+                                                     0x0000);
+       }
+       if (rc == 0) {
+               /* Read old data */
+               rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
+                                                    0x0000);
+       }
+       if (rc == 0) {
+               /* Reset RMW flag */
+               rc = drxdap_fasi_write_reg16(dev_addr,
+                                                     SIO_HI_RA_RAM_S0_FLG_ACC__A,
+                                                     0, 0x0000);
+       }
+
+       return rc;
+}
+#endif
+
+/*============================================================================*/
+
+static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
+                                                u32 waddr,
+                                                u32 raddr,
+                                                u16 wdata, u16 *rdata)
+{
+       /* TODO: correct short/long addressing format decision,
+          now long format has higher prio then short because short also
+          needs virt bnks (not impl yet) for certain audio registers */
+#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
+       return drxdap_fasi_read_modify_write_reg16(dev_addr,
+                                                         waddr,
+                                                         raddr, wdata, rdata);
+#else
+       return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
+#endif
+}
+
+
+/*============================================================================*/
+
+/**
+* \fn int drxj_dap_read_aud_reg16
+* \brief Read 16 bits audio register
+* \param dev_addr
+* \param addr
+* \param data
+* \return int
+* \retval 0 Succes
+* \retval -EIO Timeout, I2C error, illegal bank
+*
+* 16 bits register read access via audio token ring interface.
+*
+*/
+static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
+                                        u32 addr, u16 *data)
+{
+       u32 start_timer = 0;
+       u32 current_timer = 0;
+       u32 delta_timer = 0;
+       u16 tr_status = 0;
+       int stat = -EIO;
+
+       /* No read possible for bank 3, return with error */
+       if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
+               stat = -EINVAL;
+       } else {
+               const u32 write_bit = ((dr_xaddr_t) 1) << 16;
+
+               /* Force reset write bit */
+               addr &= (~write_bit);
+
+               /* Set up read */
+               start_timer = jiffies_to_msecs(jiffies);
+               do {
+                       /* RMW to aud TR IF until request is granted or timeout */
+                       stat = drxj_dap_read_modify_write_reg16(dev_addr,
+                                                            addr,
+                                                            SIO_HI_RA_RAM_S0_RMWBUF__A,
+                                                            0x0000, &tr_status);
+
+                       if (stat != 0)
+                               break;
+
+                       current_timer = jiffies_to_msecs(jiffies);
+                       delta_timer = current_timer - start_timer;
+                       if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
+                               stat = -EIO;
+                               break;
+                       }
+
+               } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
+                         AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
+                        ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
+                         AUD_TOP_TR_CTR_FIFO_FULL_FULL));
+       }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
+
+       /* Wait for read ready status or timeout */
+       if (stat == 0) {
+               start_timer = jiffies_to_msecs(jiffies);
+
+               while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
+                      AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
+                       stat = drxj_dap_read_reg16(dev_addr,
+                                                 AUD_TOP_TR_CTR__A,
+                                                 &tr_status, 0x0000);
+                       if (stat != 0)
+                               break;
+
+                       current_timer = jiffies_to_msecs(jiffies);
+                       delta_timer = current_timer - start_timer;
+                       if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
+                               stat = -EIO;
+                               break;
+                       }
+               }               /* while ( ... ) */
+       }
+
+       /* Read value */
+       if (stat == 0)
+               stat = drxj_dap_read_modify_write_reg16(dev_addr,
+                                                    AUD_TOP_TR_RD_REG__A,
+                                                    SIO_HI_RA_RAM_S0_RMWBUF__A,
+                                                    0x0000, data);
+       return stat;
+}
+
+/*============================================================================*/
+
+static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
+                                     u32 addr,
+                                     u16 *data, u32 flags)
+{
+       int stat = -EIO;
+
+       /* Check param */
+       if ((dev_addr == NULL) || (data == NULL))
+               return -EINVAL;
+
+       if (is_handled_by_aud_tr_if(addr))
+               stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
+       else
+               stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
+
+       return stat;
+}
+/*============================================================================*/
+
+/**
+* \fn int drxj_dap_write_aud_reg16
+* \brief Write 16 bits audio register
+* \param dev_addr
+* \param addr
+* \param data
+* \return int
+* \retval 0 Succes
+* \retval -EIO Timeout, I2C error, illegal bank
+*
+* 16 bits register write access via audio token ring interface.
+*
+*/
+static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
+                                         u32 addr, u16 data)
+{
+       int stat = -EIO;
+
+       /* No write possible for bank 2, return with error */
+       if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
+               stat = -EINVAL;
+       } else {
+               u32 start_timer = 0;
+               u32 current_timer = 0;
+               u32 delta_timer = 0;
+               u16 tr_status = 0;
+               const u32 write_bit = ((dr_xaddr_t) 1) << 16;
+
+               /* Force write bit */
+               addr |= write_bit;
+               start_timer = jiffies_to_msecs(jiffies);
+               do {
+                       /* RMW to aud TR IF until request is granted or timeout */
+                       stat = drxj_dap_read_modify_write_reg16(dev_addr,
+                                                            addr,
+                                                            SIO_HI_RA_RAM_S0_RMWBUF__A,
+                                                            data, &tr_status);
+                       if (stat != 0)
+                               break;
+
+                       current_timer = jiffies_to_msecs(jiffies);
+                       delta_timer = current_timer - start_timer;
+                       if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
+                               stat = -EIO;
+                               break;
+                       }
+
+               } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
+                         AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
+                        ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
+                         AUD_TOP_TR_CTR_FIFO_FULL_FULL));
+
+       }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
+
+       return stat;
+}
+
+/*============================================================================*/
+
+static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
+                                      u32 addr,
+                                      u16 data, u32 flags)
+{
+       int stat = -EIO;
+
+       /* Check param */
+       if (dev_addr == NULL)
+               return -EINVAL;
+
+       if (is_handled_by_aud_tr_if(addr))
+               stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
+       else
+               stat = drxdap_fasi_write_reg16(dev_addr,
+                                                           addr, data, flags);
+
+       return stat;
+}
+
+/*============================================================================*/
+
+/* Free data ram in SIO HI */
+#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
+#define SIO_HI_RA_RAM_USR_END__A   0x420060
+
+#define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
+#define DRXJ_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
+#define DRXJ_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
+#define DRXJ_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
+
+/**
+* \fn int drxj_dap_atomic_read_write_block()
+* \brief Basic access routine for atomic read or write access
+* \param dev_addr  pointer to i2c dev address
+* \param addr     destination/source address
+* \param datasize size of data buffer in bytes
+* \param data     pointer to data buffer
+* \return int
+* \retval 0 Succes
+* \retval -EIO Timeout, I2C error, illegal bank
+*
+*/
+static
+int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u16 datasize,
+                                         u8 *data, bool read_flag)
+{
+       struct drxj_hi_cmd hi_cmd;
+       int rc;
+       u16 word;
+       u16 dummy = 0;
+       u16 i = 0;
+
+       /* Parameter check */
+       if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
+               return -EINVAL;
+
+       /* Set up HI parameters to read or write n bytes */
+       hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
+       hi_cmd.param1 =
+           (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
+                    DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
+       hi_cmd.param2 =
+           (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
+       hi_cmd.param3 = (u16) ((datasize / 2) - 1);
+       if (!read_flag)
+               hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
+       else
+               hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
+       hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
+                               DRXDAP_FASI_ADDR2BANK(addr));
+       hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
+
+       if (!read_flag) {
+               /* write data to buffer */
+               for (i = 0; i < (datasize / 2); i++) {
+
+                       word = ((u16) data[2 * i]);
+                       word += (((u16) data[(2 * i) + 1]) << 8);
+                       drxj_dap_write_reg16(dev_addr,
+                                            (DRXJ_HI_ATOMIC_BUF_START + i),
+                                           word, 0);
+               }
+       }
+
+       rc = hi_command(dev_addr, &hi_cmd, &dummy);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       if (read_flag) {
+               /* read data from buffer */
+               for (i = 0; i < (datasize / 2); i++) {
+                       drxj_dap_read_reg16(dev_addr,
+                                           (DRXJ_HI_ATOMIC_BUF_START + i),
+                                          &word, 0);
+                       data[2 * i] = (u8) (word & 0xFF);
+                       data[(2 * i) + 1] = (u8) (word >> 8);
+               }
+       }
+
+       return 0;
+
+rw_error:
+       return -EIO;
+
+}
+
+/*============================================================================*/
+
+/**
+* \fn int drxj_dap_atomic_read_reg32()
+* \brief Atomic read of 32 bits words
+*/
+static
+int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
+                                    u32 addr,
+                                    u32 *data, u32 flags)
+{
+       u8 buf[sizeof(*data)];
+       int rc = -EIO;
+       u32 word = 0;
+
+       if (!data)
+               return -EINVAL;
+
+       rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
+                                             sizeof(*data), buf, true);
+
+       if (rc < 0)
+               return 0;
+
+       word = (u32) buf[3];
+       word <<= 8;
+       word |= (u32) buf[2];
+       word <<= 8;
+       word |= (u32) buf[1];
+       word <<= 8;
+       word |= (u32) buf[0];
+
+       *data = word;
+
+       return rc;
+}
+
+/*============================================================================*/
+
+/*============================================================================*/
+/*==                        END DRXJ DAP FUNCTIONS                          ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                      HOST INTERFACE FUNCTIONS                          ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+/**
+* \fn int hi_cfg_command()
+* \brief Configure HI with settings stored in the demod structure.
+* \param demod Demodulator.
+* \return int.
+*
+* This routine was created because to much orthogonal settings have
+* been put into one HI API function (configure). Especially the I2C bridge
+* enable/disable should not need re-configuration of the HI.
+*
+*/
+static int hi_cfg_command(const struct drx_demod_instance *demod)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       struct drxj_hi_cmd hi_cmd;
+       u16 result = 0;
+       int rc;
+
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
+       hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
+       hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
+       hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
+       hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
+       hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
+       hi_cmd.param6 = ext_attr->hi_cfg_transmit;
+
+       rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Reset power down flag (set one call only) */
+       ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
+
+       return 0;
+
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int hi_command()
+* \brief Configure HI with settings stored in the demod structure.
+* \param dev_addr I2C address.
+* \param cmd HI command.
+* \param result HI command result.
+* \return int.
+*
+* Sends command to HI
+*
+*/
+static int
+hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
+{
+       u16 wait_cmd = 0;
+       u16 nr_retries = 0;
+       bool powerdown_cmd = false;
+       int rc;
+
+       /* Write parameters */
+       switch (cmd->cmd) {
+
+       case SIO_HI_RA_RAM_CMD_CONFIG:
+       case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
+               rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /* fallthrough */
+       case SIO_HI_RA_RAM_CMD_BRDCTRL:
+               rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /* fallthrough */
+       case SIO_HI_RA_RAM_CMD_NULL:
+               /* No parameters */
+               break;
+
+       default:
+               return -EINVAL;
+               break;
+       }
+
+       /* Write command */
+       rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
+               msleep(1);
+
+       /* Detect power down to ommit reading result */
+       powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
+                                 (((cmd->
+                                    param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
+                                  == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
+       if (!powerdown_cmd) {
+               /* Wait until command rdy */
+               do {
+                       nr_retries++;
+                       if (nr_retries > DRXJ_MAX_RETRIES) {
+                               pr_err("timeout\n");
+                               goto rw_error;
+                       }
+
+                       rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               } while (wait_cmd != 0);
+
+               /* Read result */
+               rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+       }
+       /* if ( powerdown_cmd == true ) */
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int init_hi( const struct drx_demod_instance *demod )
+* \brief Initialise and configurate HI.
+* \param demod pointer to demod data.
+* \return int Return status.
+* \retval 0 Success.
+* \retval -EIO Failure.
+*
+* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
+* Need to store configuration in driver because of the way I2C
+* bridging is controlled.
+*
+*/
+static int init_hi(const struct drx_demod_instance *demod)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       int rc;
+
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       dev_addr = demod->my_i2c_dev_addr;
+
+       /* PATCH for bug 5003, HI ucode v3.1.0 */
+       rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Timing div, 250ns/Psys */
+       /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
+       ext_attr->hi_cfg_timing_div =
+           (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
+       /* Clipping */
+       if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
+               ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
+       /* Bridge delay, uses oscilator clock */
+       /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
+       /* SDA brdige delay */
+       ext_attr->hi_cfg_bridge_delay =
+           (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
+           1000;
+       /* Clipping */
+       if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
+               ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
+       /* SCL bridge delay, same as SDA for now */
+       ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
+                                     SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
+       /* Wakeup key, setting the read flag (as suggest in the documentation) does
+          not always result into a working solution (barebones worked VI2C failed).
+          Not setting the bit works in all cases . */
+       ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
+       /* port/bridge/power down ctrl */
+       ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
+       /* transit mode time out delay and watch dog divider */
+       ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
+
+       rc = hi_cfg_command(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+/*==                   END HOST INTERFACE FUNCTIONS                         ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                        AUXILIARY FUNCTIONS                             ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+/**
+* \fn int get_device_capabilities()
+* \brief Get and store device capabilities.
+* \param demod  Pointer to demodulator instance.
+* \return int.
+* \return 0    Success
+* \retval -EIO Failure
+*
+* Depending on pulldowns on MDx pins the following internals are set:
+*  * common_attr->osc_clock_freq
+*  * ext_attr->has_lna
+*  * ext_attr->has_ntsc
+*  * ext_attr->has_btsc
+*  * ext_attr->has_oob
+*
+*/
+static int get_device_capabilities(struct drx_demod_instance *demod)
+{
+       struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
+       struct drxj_data *ext_attr = (struct drxj_data *) NULL;
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       u16 sio_pdr_ohw_cfg = 0;
+       u32 sio_top_jtagid_lo = 0;
+       u16 bid = 0;
+       int rc;
+
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       dev_addr = demod->my_i2c_dev_addr;
+
+       rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
+       case 0:
+               /* ignore (bypass ?) */
+               break;
+       case 1:
+               /* 27 MHz */
+               common_attr->osc_clock_freq = 27000;
+               break;
+       case 2:
+               /* 20.25 MHz */
+               common_attr->osc_clock_freq = 20250;
+               break;
+       case 3:
+               /* 4 MHz */
+               common_attr->osc_clock_freq = 4000;
+               break;
+       default:
+               return -EIO;
+       }
+
+       /*
+          Determine device capabilities
+          Based on pinning v47
+        */
+       rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
+
+       switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
+       case 0x31:
+               rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               bid = (bid >> 10) & 0xf;
+               rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               ext_attr->has_lna = true;
+               ext_attr->has_ntsc = false;
+               ext_attr->has_btsc = false;
+               ext_attr->has_oob = false;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = false;
+               ext_attr->has_gpio = false;
+               ext_attr->has_irqn = false;
+               break;
+       case 0x33:
+               ext_attr->has_lna = false;
+               ext_attr->has_ntsc = false;
+               ext_attr->has_btsc = false;
+               ext_attr->has_oob = false;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = false;
+               ext_attr->has_gpio = false;
+               ext_attr->has_irqn = false;
+               break;
+       case 0x45:
+               ext_attr->has_lna = true;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = false;
+               ext_attr->has_oob = false;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = false;
+               break;
+       case 0x46:
+               ext_attr->has_lna = false;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = false;
+               ext_attr->has_oob = false;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = false;
+               break;
+       case 0x41:
+               ext_attr->has_lna = true;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = true;
+               ext_attr->has_oob = false;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = false;
+               break;
+       case 0x43:
+               ext_attr->has_lna = false;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = true;
+               ext_attr->has_oob = false;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = false;
+               break;
+       case 0x32:
+               ext_attr->has_lna = true;
+               ext_attr->has_ntsc = false;
+               ext_attr->has_btsc = false;
+               ext_attr->has_oob = true;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = true;
+               break;
+       case 0x34:
+               ext_attr->has_lna = false;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = true;
+               ext_attr->has_oob = true;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = true;
+               break;
+       case 0x42:
+               ext_attr->has_lna = true;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = true;
+               ext_attr->has_oob = true;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = true;
+               break;
+       case 0x44:
+               ext_attr->has_lna = false;
+               ext_attr->has_ntsc = true;
+               ext_attr->has_btsc = true;
+               ext_attr->has_oob = true;
+               ext_attr->has_smatx = true;
+               ext_attr->has_smarx = true;
+               ext_attr->has_gpio = true;
+               ext_attr->has_irqn = true;
+               break;
+       default:
+               /* Unknown device variant */
+               return -EIO;
+               break;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int power_up_device()
+* \brief Power up device.
+* \param demod  Pointer to demodulator instance.
+* \return int.
+* \return 0    Success
+* \retval -EIO Failure, I2C or max retries reached
+*
+*/
+
+#ifndef DRXJ_MAX_RETRIES_POWERUP
+#define DRXJ_MAX_RETRIES_POWERUP 10
+#endif
+
+static int power_up_device(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       u8 data = 0;
+       u16 retry_count = 0;
+       struct i2c_device_addr wake_up_addr;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
+       wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
+       wake_up_addr.user_data = dev_addr->user_data;
+       /*
+        * I2C access may fail in this case: no ack
+        * dummy write must be used to wake uop device, dummy read must be used to
+        * reset HI state machine (avoiding actual writes)
+        */
+       do {
+               data = 0;
+               drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
+                                     (struct i2c_device_addr *)(NULL), 0,
+                                    (u8 *)(NULL));
+               msleep(10);
+               retry_count++;
+       } while ((drxbsp_i2c_write_read
+                 ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
+                  &data)
+                 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
+
+       /* Need some recovery time .... */
+       msleep(10);
+
+       if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
+               return -EIO;
+
+       return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/* MPEG Output Configuration Functions - begin                                */
+/*----------------------------------------------------------------------------*/
+/**
+* \fn int ctrl_set_cfg_mpeg_output()
+* \brief Set MPEG output configuration of the device.
+* \param devmod  Pointer to demodulator instance.
+* \param cfg_data Pointer to mpeg output configuaration.
+* \return int.
+*
+*  Configure MPEG output parameters.
+*
+*/
+static int
+ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
+{
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
+       int rc;
+       u16 fec_oc_reg_mode = 0;
+       u16 fec_oc_reg_ipr_mode = 0;
+       u16 fec_oc_reg_ipr_invert = 0;
+       u32 max_bit_rate = 0;
+       u32 rcn_rate = 0;
+       u32 nr_bits = 0;
+       u16 sio_pdr_md_cfg = 0;
+       /* data mask for the output data byte */
+       u16 invert_data_mask =
+           FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
+           FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
+           FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
+           FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
+
+       /* check arguments */
+       if ((demod == NULL) || (cfg_data == NULL))
+               return -EINVAL;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+
+       if (cfg_data->enable_mpeg_output == true) {
+               /* quick and dirty patch to set MPEG incase current std is not
+                  producing MPEG */
+               switch (ext_attr->standard) {
+               case DRX_STANDARD_8VSB:
+               case DRX_STANDARD_ITU_A:
+               case DRX_STANDARD_ITU_B:
+               case DRX_STANDARD_ITU_C:
+                       break;
+               default:
+                       return 0;
+               }
+
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               switch (ext_attr->standard) {
+               case DRX_STANDARD_8VSB:
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* 2048 bytes fifo ram */
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       /* Low Water Mark for synchronization  */
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       /* High Water Mark for synchronization */
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_STANDARD_ITU_A:
+               case DRX_STANDARD_ITU_C:
+                       switch (ext_attr->constellation) {
+                       case DRX_CONSTELLATION_QAM256:
+                               nr_bits = 8;
+                               break;
+                       case DRX_CONSTELLATION_QAM128:
+                               nr_bits = 7;
+                               break;
+                       case DRX_CONSTELLATION_QAM64:
+                               nr_bits = 6;
+                               break;
+                       case DRX_CONSTELLATION_QAM32:
+                               nr_bits = 5;
+                               break;
+                       case DRX_CONSTELLATION_QAM16:
+                               nr_bits = 4;
+                               break;
+                       default:
+                               return -EIO;
+                       }       /* ext_attr->constellation */
+                       /* max_bit_rate = symbol_rate * nr_bits * coef */
+                       /* coef = 188/204                          */
+                       max_bit_rate =
+                           (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
+                       /* pass through b/c Annex A/c need following settings */
+               case DRX_STANDARD_ITU_B:
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       if (cfg_data->static_clk == true) {
+                               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                       } else {
+                               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       break;
+               }               /* swtich (standard) */
+
+               /* Check insertion of the Reed-Solomon parity bytes */
+               rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (cfg_data->insert_rs_byte == true) {
+                       /* enable parity symbol forward */
+                       fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
+                       /* MVAL disable during parity bytes */
+                       fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
+                       switch (ext_attr->standard) {
+                       case DRX_STANDARD_8VSB:
+                               rcn_rate = 0x004854D3;
+                               break;
+                       case DRX_STANDARD_ITU_B:
+                               fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
+                               switch (ext_attr->constellation) {
+                               case DRX_CONSTELLATION_QAM256:
+                                       rcn_rate = 0x008945E7;
+                                       break;
+                               case DRX_CONSTELLATION_QAM64:
+                                       rcn_rate = 0x005F64D4;
+                                       break;
+                               default:
+                                       return -EIO;
+                               }
+                               break;
+                       case DRX_STANDARD_ITU_A:
+                       case DRX_STANDARD_ITU_C:
+                               /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
+                               rcn_rate =
+                                   (frac28
+                                    (max_bit_rate,
+                                     (u32) (common_attr->sys_clock_freq / 8))) /
+                                   188;
+                               break;
+                       default:
+                               return -EIO;
+                       }       /* ext_attr->standard */
+               } else {        /* insert_rs_byte == false */
+
+                       /* disable parity symbol forward */
+                       fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
+                       /* MVAL enable during parity bytes */
+                       fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
+                       switch (ext_attr->standard) {
+                       case DRX_STANDARD_8VSB:
+                               rcn_rate = 0x0041605C;
+                               break;
+                       case DRX_STANDARD_ITU_B:
+                               fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
+                               switch (ext_attr->constellation) {
+                               case DRX_CONSTELLATION_QAM256:
+                                       rcn_rate = 0x0082D6A0;
+                                       break;
+                               case DRX_CONSTELLATION_QAM64:
+                                       rcn_rate = 0x005AEC1A;
+                                       break;
+                               default:
+                                       return -EIO;
+                               }
+                               break;
+                       case DRX_STANDARD_ITU_A:
+                       case DRX_STANDARD_ITU_C:
+                               /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
+                               rcn_rate =
+                                   (frac28
+                                    (max_bit_rate,
+                                     (u32) (common_attr->sys_clock_freq / 8))) /
+                                   204;
+                               break;
+                       default:
+                               return -EIO;
+                       }       /* ext_attr->standard */
+               }
+
+               if (cfg_data->enable_parallel == true) {        /* MPEG data output is paralel -> clear ipr_mode[0] */
+                       fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
+               } else {        /* MPEG data output is serial -> set ipr_mode[0] */
+                       fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
+               }
+
+               /* Control slective inversion of output bits */
+               if (cfg_data->invert_data == true)
+                       fec_oc_reg_ipr_invert |= invert_data_mask;
+               else
+                       fec_oc_reg_ipr_invert &= (~(invert_data_mask));
+
+               if (cfg_data->invert_err == true)
+                       fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
+               else
+                       fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
+
+               if (cfg_data->invert_str == true)
+                       fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
+               else
+                       fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
+
+               if (cfg_data->invert_val == true)
+                       fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
+               else
+                       fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
+
+               if (cfg_data->invert_clk == true)
+                       fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
+               else
+                       fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
+
+
+               if (cfg_data->static_clk == true) {     /* Static mode */
+                       u32 dto_rate = 0;
+                       u32 bit_rate = 0;
+                       u16 fec_oc_dto_burst_len = 0;
+                       u16 fec_oc_dto_period = 0;
+
+                       fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
+
+                       switch (ext_attr->standard) {
+                       case DRX_STANDARD_8VSB:
+                               fec_oc_dto_period = 4;
+                               if (cfg_data->insert_rs_byte == true)
+                                       fec_oc_dto_burst_len = 208;
+                               break;
+                       case DRX_STANDARD_ITU_A:
+                               {
+                                       u32 symbol_rate_th = 6400000;
+                                       if (cfg_data->insert_rs_byte == true) {
+                                               fec_oc_dto_burst_len = 204;
+                                               symbol_rate_th = 5900000;
+                                       }
+                                       if (ext_attr->curr_symbol_rate >=
+                                           symbol_rate_th) {
+                                               fec_oc_dto_period = 0;
+                                       } else {
+                                               fec_oc_dto_period = 1;
+                                       }
+                               }
+                               break;
+                       case DRX_STANDARD_ITU_B:
+                               fec_oc_dto_period = 1;
+                               if (cfg_data->insert_rs_byte == true)
+                                       fec_oc_dto_burst_len = 128;
+                               break;
+                       case DRX_STANDARD_ITU_C:
+                               fec_oc_dto_period = 1;
+                               if (cfg_data->insert_rs_byte == true)
+                                       fec_oc_dto_burst_len = 204;
+                               break;
+                       default:
+                               return -EIO;
+                       }
+                       bit_rate =
+                           common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
+                                                              2);
+                       dto_rate =
+                           frac28(bit_rate, common_attr->sys_clock_freq * 1000);
+                       dto_rate >>= 3;
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
+                               fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               } else {        /* Dynamic mode */
+
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+
+               rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* Write appropriate registers with requested configuration */
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* enabling for both parallel and serial now */
+               /*  Write magic word to enable pdr reg write */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /*  Set MPEG TS pads to outputmode */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               sio_pdr_md_cfg =
+                   MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
+                   SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (cfg_data->enable_parallel == true) {        /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
+                       sio_pdr_md_cfg =
+                           MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
+                           SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
+                           SIO_PDR_MD0_CFG_MODE__B;
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               } else {        /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+               /*  Enable Monitor Bus output over MPEG pads and ctl input */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /*  Write nomagic word to enable pdr reg write */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       } else {
+               /*  Write magic word to enable pdr reg write */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /*  Set MPEG TS pads to inputmode */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /* Enable Monitor Bus output over MPEG pads and ctl input */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /* Write nomagic word to enable pdr reg write */
+               rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* save values for restore after re-acquire */
+       common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------*/
+/* MPEG Output Configuration Functions - end                                  */
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* miscellaneous configuartions - begin                           */
+/*----------------------------------------------------------------------------*/
+
+/**
+* \fn int set_mpegtei_handling()
+* \brief Activate MPEG TEI handling settings.
+* \param devmod  Pointer to demodulator instance.
+* \return int.
+*
+* This routine should be called during a set channel of QAM/VSB
+*
+*/
+static int set_mpegtei_handling(struct drx_demod_instance *demod)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       int rc;
+       u16 fec_oc_dpr_mode = 0;
+       u16 fec_oc_snc_mode = 0;
+       u16 fec_oc_ems_mode = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* reset to default, allow TEI bit to be changed */
+       fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
+       fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
+                          FEC_OC_SNC_MODE_CORR_DISABLE__M));
+       fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
+
+       if (ext_attr->disable_te_ihandling) {
+               /* do not change TEI bit */
+               fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
+               fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
+                   ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
+               fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+* \fn int bit_reverse_mpeg_output()
+* \brief Set MPEG output bit-endian settings.
+* \param devmod  Pointer to demodulator instance.
+* \return int.
+*
+* This routine should be called during a set channel of QAM/VSB
+*
+*/
+static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       int rc;
+       u16 fec_oc_ipr_mode = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* reset to default (normal bit order) */
+       fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
+
+       if (ext_attr->bit_reverse_mpeg_outout)
+               fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
+
+       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+* \fn int set_mpeg_start_width()
+* \brief Set MPEG start width.
+* \param devmod  Pointer to demodulator instance.
+* \return int.
+*
+* This routine should be called during a set channel of QAM/VSB
+*
+*/
+static int set_mpeg_start_width(struct drx_demod_instance *demod)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
+       struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
+       int rc;
+       u16 fec_oc_comm_mb = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       common_attr = demod->my_common_attr;
+
+       if ((common_attr->mpeg_cfg.static_clk == true)
+           && (common_attr->mpeg_cfg.enable_parallel == false)) {
+               rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
+               if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
+                       fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*----------------------------------------------------------------------------*/
+/* miscellaneous configuartions - end                             */
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* UIO Configuration Functions - begin                                        */
+/*----------------------------------------------------------------------------*/
+/**
+* \fn int ctrl_set_uio_cfg()
+* \brief Configure modus oprandi UIO.
+* \param demod Pointer to demodulator instance.
+* \param uio_cfg Pointer to a configuration setting for a certain UIO.
+* \return int.
+*/
+static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       int rc;
+
+       if ((uio_cfg == NULL) || (demod == NULL))
+               return -EINVAL;
+
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       /*  Write magic word to enable pdr reg write               */
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       switch (uio_cfg->uio) {
+      /*====================================================================*/
+       case DRX_UIO1:
+               /* DRX_UIO1: SMA_TX UIO-1 */
+               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_READWRITE:
+                       ext_attr->uio_sma_tx_mode = uio_cfg->mode;
+                       break;
+               case DRX_UIO_MODE_DISABLE:
+                       ext_attr->uio_sma_tx_mode = uio_cfg->mode;
+                       /* pad configuration register is set 0 - input mode */
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }               /* switch ( uio_cfg->mode ) */
+               break;
+      /*====================================================================*/
+       case DRX_UIO2:
+               /* DRX_UIO2: SMA_RX UIO-2 */
+               if (!ext_attr->has_smarx)
+                       return -EIO;
+               switch (uio_cfg->mode) {
+               case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
+               case DRX_UIO_MODE_READWRITE:
+                       ext_attr->uio_sma_rx_mode = uio_cfg->mode;
+                       break;
+               case DRX_UIO_MODE_DISABLE:
+                       ext_attr->uio_sma_rx_mode = uio_cfg->mode;
+                       /* pad configuration register is set 0 - input mode */
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }               /* switch ( uio_cfg->mode ) */
+               break;
+      /*====================================================================*/
+       case DRX_UIO3:
+               /* DRX_UIO3: GPIO UIO-3 */
+               if (!ext_attr->has_gpio)
+                       return -EIO;
+               switch (uio_cfg->mode) {
+               case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
+               case DRX_UIO_MODE_READWRITE:
+                       ext_attr->uio_gpio_mode = uio_cfg->mode;
+                       break;
+               case DRX_UIO_MODE_DISABLE:
+                       ext_attr->uio_gpio_mode = uio_cfg->mode;
+                       /* pad configuration register is set 0 - input mode */
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }               /* switch ( uio_cfg->mode ) */
+               break;
+      /*====================================================================*/
+       case DRX_UIO4:
+               /* DRX_UIO4: IRQN UIO-4 */
+               if (!ext_attr->has_irqn)
+                       return -EIO;
+               switch (uio_cfg->mode) {
+               case DRX_UIO_MODE_READWRITE:
+                       ext_attr->uio_irqn_mode = uio_cfg->mode;
+                       break;
+               case DRX_UIO_MODE_DISABLE:
+                       /* pad configuration register is set 0 - input mode */
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       ext_attr->uio_irqn_mode = uio_cfg->mode;
+                       break;
+               case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
+               default:
+                       return -EINVAL;
+                       break;
+               }               /* switch ( uio_cfg->mode ) */
+               break;
+      /*====================================================================*/
+       default:
+               return -EINVAL;
+       }                       /* switch ( uio_cfg->uio ) */
+
+       /*  Write magic word to disable pdr reg write               */
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int ctrl_uio_write()
+* \brief Write to a UIO.
+* \param demod Pointer to demodulator instance.
+* \param uio_data Pointer to data container for a certain UIO.
+* \return int.
+*/
+static int
+ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
+{
+       struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
+       int rc;
+       u16 pin_cfg_value = 0;
+       u16 value = 0;
+
+       if ((uio_data == NULL) || (demod == NULL))
+               return -EINVAL;
+
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       /*  Write magic word to enable pdr reg write               */
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       switch (uio_data->uio) {
+      /*====================================================================*/
+       case DRX_UIO1:
+               /* DRX_UIO1: SMA_TX UIO-1 */
+               if (!ext_attr->has_smatx)
+                       return -EIO;
+               if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
+                   && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
+                       return -EIO;
+               }
+               pin_cfg_value = 0;
+               /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
+               pin_cfg_value |= 0x0113;
+               /* io_pad_cfg_mode output mode is drive always */
+               /* io_pad_cfg_drive is set to power 2 (23 mA) */
+
+               /* write to io pad configuration register - output mode */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* use corresponding bit in io data output registar */
+               rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (!uio_data->value)
+                       value &= 0x7FFF;        /* write zero to 15th bit - 1st UIO */
+               else
+                       value |= 0x8000;        /* write one to 15th bit - 1st UIO */
+
+               /* write back to io data output register */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+   /*======================================================================*/
+       case DRX_UIO2:
+               /* DRX_UIO2: SMA_RX UIO-2 */
+               if (!ext_attr->has_smarx)
+                       return -EIO;
+               if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
+                       return -EIO;
+
+               pin_cfg_value = 0;
+               /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
+               pin_cfg_value |= 0x0113;
+               /* io_pad_cfg_mode output mode is drive always */
+               /* io_pad_cfg_drive is set to power 2 (23 mA) */
+
+               /* write to io pad configuration register - output mode */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* use corresponding bit in io data output registar */
+               rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (!uio_data->value)
+                       value &= 0xBFFF;        /* write zero to 14th bit - 2nd UIO */
+               else
+                       value |= 0x4000;        /* write one to 14th bit - 2nd UIO */
+
+               /* write back to io data output register */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+   /*====================================================================*/
+       case DRX_UIO3:
+               /* DRX_UIO3: ASEL UIO-3 */
+               if (!ext_attr->has_gpio)
+                       return -EIO;
+               if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
+                       return -EIO;
+
+               pin_cfg_value = 0;
+               /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
+               pin_cfg_value |= 0x0113;
+               /* io_pad_cfg_mode output mode is drive always */
+               /* io_pad_cfg_drive is set to power 2 (23 mA) */
+
+               /* write to io pad configuration register - output mode */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* use corresponding bit in io data output registar */
+               rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (!uio_data->value)
+                       value &= 0xFFFB;        /* write zero to 2nd bit - 3rd UIO */
+               else
+                       value |= 0x0004;        /* write one to 2nd bit - 3rd UIO */
+
+               /* write back to io data output register */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+   /*=====================================================================*/
+       case DRX_UIO4:
+               /* DRX_UIO4: IRQN UIO-4 */
+               if (!ext_attr->has_irqn)
+                       return -EIO;
+
+               if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
+                       return -EIO;
+
+               pin_cfg_value = 0;
+               /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
+               pin_cfg_value |= 0x0113;
+               /* io_pad_cfg_mode output mode is drive always */
+               /* io_pad_cfg_drive is set to power 2 (23 mA) */
+
+               /* write to io pad configuration register - output mode */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* use corresponding bit in io data output registar */
+               rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (uio_data->value == false)
+                       value &= 0xEFFF;        /* write zero to 12th bit - 4th UIO */
+               else
+                       value |= 0x1000;        /* write one to 12th bit - 4th UIO */
+
+               /* write back to io data output register */
+               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+      /*=====================================================================*/
+       default:
+               return -EINVAL;
+       }                       /* switch ( uio_data->uio ) */
+
+       /*  Write magic word to disable pdr reg write               */
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*---------------------------------------------------------------------------*/
+/* UIO Configuration Functions - end                                         */
+/*---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* I2C Bridge Functions - begin                                               */
+/*----------------------------------------------------------------------------*/
+/**
+* \fn int ctrl_i2c_bridge()
+* \brief Open or close the I2C switch to tuner.
+* \param demod Pointer to demodulator instance.
+* \param bridge_closed Pointer to bool indication if bridge is closed not.
+* \return int.
+
+*/
+static int
+ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
+{
+       struct drxj_hi_cmd hi_cmd;
+       u16 result = 0;
+
+       /* check arguments */
+       if (bridge_closed == NULL)
+               return -EINVAL;
+
+       hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
+       hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
+       if (*bridge_closed)
+               hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
+       else
+               hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
+
+       return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
+}
+
+/*----------------------------------------------------------------------------*/
+/* I2C Bridge Functions - end                                                 */
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* Smart antenna Functions - begin                                            */
+/*----------------------------------------------------------------------------*/
+/**
+* \fn int smart_ant_init()
+* \brief Initialize Smart Antenna.
+* \param pointer to struct drx_demod_instance.
+* \return int.
+*
+*/
+static int smart_ant_init(struct drx_demod_instance *demod)
+{
+       struct drxj_data *ext_attr = NULL;
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
+       int rc;
+       u16 data = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       /*  Write magic word to enable pdr reg write               */
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* init smart antenna */
+       rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (ext_attr->smart_ant_inverted) {
+               rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       } else {
+               rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* config SMA_TX pin to smart antenna mode */
+       rc = ctrl_set_uio_cfg(demod, &uio_cfg);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /*  Write magic word to disable pdr reg write               */
+       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
+{
+       int rc;
+       u16 cur_cmd = 0;
+       unsigned long timeout;
+
+       /* Check param */
+       if (cmd == NULL)
+               return -EINVAL;
+
+       /* Wait until SCU command interface is ready to receive command */
+       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (cur_cmd != DRX_SCU_READY)
+               return -EIO;
+
+       switch (cmd->parameter_len) {
+       case 5:
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /* fallthrough */
+       case 4:
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /* fallthrough */
+       case 3:
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /* fallthrough */
+       case 2:
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /* fallthrough */
+       case 1:
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /* fallthrough */
+       case 0:
+               /* do nothing */
+               break;
+       default:
+               /* this number of parameters is not supported */
+               return -EIO;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Wait until SCU has processed command */
+       timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
+       while (time_is_after_jiffies(timeout)) {
+               rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               if (cur_cmd == DRX_SCU_READY)
+                       break;
+               usleep_range(1000, 2000);
+       }
+
+       if (cur_cmd != DRX_SCU_READY)
+               return -EIO;
+
+       /* read results */
+       if ((cmd->result_len > 0) && (cmd->result != NULL)) {
+               s16 err;
+
+               switch (cmd->result_len) {
+               case 4:
+                       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* fallthrough */
+               case 3:
+                       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* fallthrough */
+               case 2:
+                       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* fallthrough */
+               case 1:
+                       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* fallthrough */
+               case 0:
+                       /* do nothing */
+                       break;
+               default:
+                       /* this number of parameters is not supported */
+                       return -EIO;
+               }
+
+               /* Check if an error was reported by SCU */
+               err = cmd->result[0];
+
+               /* check a few fixed error codes */
+               if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
+                   || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
+                   || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
+                   || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
+                   ) {
+                       return -EINVAL;
+               }
+               /* here it is assumed that negative means error, and positive no error */
+               else if (err < 0)
+                       return -EIO;
+               else
+                       return 0;
+       }
+
+       return 0;
+
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
+* \brief Basic access routine for SCU atomic read or write access
+* \param dev_addr  pointer to i2c dev address
+* \param addr     destination/source address
+* \param datasize size of data buffer in bytes
+* \param data     pointer to data buffer
+* \return int
+* \retval 0 Succes
+* \retval -EIO Timeout, I2C error, illegal bank
+*
+*/
+#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
+static
+int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize,     /* max 30 bytes because the limit of SCU parameter */
+                                             u8 *data, bool read_flag)
+{
+       struct drxjscu_cmd scu_cmd;
+       int rc;
+       u16 set_param_parameters[15];
+       u16 cmd_result[15];
+
+       /* Parameter check */
+       if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
+               return -EINVAL;
+
+       set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
+       if (read_flag) {                /* read */
+               set_param_parameters[0] = ((~(0x0080)) & datasize);
+               scu_cmd.parameter_len = 2;
+               scu_cmd.result_len = datasize / 2 + 2;
+       } else {
+               int i = 0;
+
+               set_param_parameters[0] = 0x0080 | datasize;
+               for (i = 0; i < (datasize / 2); i++) {
+                       set_param_parameters[i + 2] =
+                           (data[2 * i] | (data[(2 * i) + 1] << 8));
+               }
+               scu_cmd.parameter_len = datasize / 2 + 2;
+               scu_cmd.result_len = 1;
+       }
+
+       scu_cmd.command =
+           SCU_RAM_COMMAND_STANDARD_TOP |
+           SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
+       scu_cmd.result = cmd_result;
+       scu_cmd.parameter = set_param_parameters;
+       rc = scu_command(dev_addr, &scu_cmd);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       if (read_flag) {
+               int i = 0;
+               /* read data from buffer */
+               for (i = 0; i < (datasize / 2); i++) {
+                       data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
+                       data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
+               }
+       }
+
+       return 0;
+
+rw_error:
+       return -EIO;
+
+}
+
+/*============================================================================*/
+
+/**
+* \fn int DRXJ_DAP_AtomicReadReg16()
+* \brief Atomic read of 16 bits words
+*/
+static
+int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
+                                        u32 addr,
+                                        u16 *data, u32 flags)
+{
+       u8 buf[2];
+       int rc = -EIO;
+       u16 word = 0;
+
+       if (!data)
+               return -EINVAL;
+
+       rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
+       if (rc < 0)
+               return rc;
+
+       word = (u16) (buf[0] + (buf[1] << 8));
+
+       *data = word;
+
+       return rc;
+}
+
+/*============================================================================*/
+/**
+* \fn int drxj_dap_scu_atomic_write_reg16()
+* \brief Atomic read of 16 bits words
+*/
+static
+int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
+                                         u32 addr,
+                                         u16 data, u32 flags)
+{
+       u8 buf[2];
+       int rc = -EIO;
+
+       buf[0] = (u8) (data & 0xff);
+       buf[1] = (u8) ((data >> 8) & 0xff);
+
+       rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
+
+       return rc;
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+* \brief Measure result of ADC synchronisation
+* \param demod demod instance
+* \param count (returned) count
+* \return int.
+* \retval 0    Success
+* \retval -EIO Failure: I2C error
+*
+*/
+static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       int rc;
+       u16 data = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+
+       /* Start measurement */
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
+       msleep(1);
+
+       *count = 0;
+       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (data == 127)
+               *count = *count + 1;
+       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (data == 127)
+               *count = *count + 1;
+       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (data == 127)
+               *count = *count + 1;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \brief Synchronize analog and digital clock domains
+* \param demod demod instance
+* \return int.
+* \retval 0    Success
+* \retval -EIO Failure: I2C error or failure to synchronize
+*
+* An IQM reset will also reset the results of this synchronization.
+* After an IQM reset this routine needs to be called again.
+*
+*/
+
+static int adc_synchronization(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       int rc;
+       u16 count = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+
+       rc = adc_sync_measurement(demod, &count);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       if (count == 1) {
+               /* Try sampling on a diffrent edge */
+               u16 clk_neg = 0;
+
+               rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               rc = adc_sync_measurement(demod, &count);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* TODO: implement fallback scenarios */
+       if (count < 2)
+               return -EIO;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+/*==                      END AUXILIARY FUNCTIONS                           ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/
+/*============================================================================*/
+/*============================================================================*/
+/**
+* \fn int init_agc ()
+* \brief Initialize AGC for all standards.
+* \param demod instance of demodulator.
+* \param channel pointer to channel data.
+* \return int.
+*/
+static int init_agc(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drx_common_attr *common_attr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       struct drxj_cfg_agc *p_agc_rf_settings = NULL;
+       struct drxj_cfg_agc *p_agc_if_settings = NULL;
+       int rc;
+       u16 ingain_tgt_max = 0;
+       u16 clp_dir_to = 0;
+       u16 sns_sum_max = 0;
+       u16 clp_sum_max = 0;
+       u16 sns_dir_to = 0;
+       u16 ki_innergain_min = 0;
+       u16 agc_ki = 0;
+       u16 ki_max = 0;
+       u16 if_iaccu_hi_tgt_min = 0;
+       u16 data = 0;
+       u16 agc_ki_dgain = 0;
+       u16 ki_min = 0;
+       u16 clp_ctrl_mode = 0;
+       u16 agc_rf = 0;
+       u16 agc_if = 0;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       switch (ext_attr->standard) {
+       case DRX_STANDARD_8VSB:
+               clp_sum_max = 1023;
+               clp_dir_to = (u16) (-9);
+               sns_sum_max = 1023;
+               sns_dir_to = (u16) (-9);
+               ki_innergain_min = (u16) (-32768);
+               ki_max = 0x032C;
+               agc_ki_dgain = 0xC;
+               if_iaccu_hi_tgt_min = 2047;
+               ki_min = 0x0117;
+               ingain_tgt_max = 16383;
+               clp_ctrl_mode = 0;
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
+               p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_C:
+       case DRX_STANDARD_ITU_B:
+               ingain_tgt_max = 5119;
+               clp_sum_max = 1023;
+               clp_dir_to = (u16) (-5);
+               sns_sum_max = 127;
+               sns_dir_to = (u16) (-3);
+               ki_innergain_min = 0;
+               ki_max = 0x0657;
+               if_iaccu_hi_tgt_min = 2047;
+               agc_ki_dgain = 0x7;
+               ki_min = 0x0117;
+               clp_ctrl_mode = 0;
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
+               p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               agc_ki &= 0xf000;
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+#endif
+       default:
+               return -EINVAL;
+       }
+
+       /* for new AGC interface */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* Gain fed from inner to outer AGC */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* set to p_agc_settings->top before */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
+       if (common_attr->tuner_rf_agc_pol == true)
+               agc_rf = 0x87ff - agc_rf;
+
+       agc_if = 0x800;
+       if (common_attr->tuner_if_agc_pol == true)
+               agc_rf = 0x87ff - agc_rf;
+
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Set/restore Ki DGAIN factor */
+       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       data &= ~SCU_RAM_AGC_KI_DGAIN__M;
+       data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_frequency ()
+* \brief Set frequency shift.
+* \param demod instance of demodulator.
+* \param channel pointer to channel data.
+* \param tuner_freq_offset residual frequency from tuner.
+* \return int.
+*/
+static int
+set_frequency(struct drx_demod_instance *demod,
+             struct drx_channel *channel, s32 tuner_freq_offset)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       int rc;
+       s32 sampling_frequency = 0;
+       s32 frequency_shift = 0;
+       s32 if_freq_actual = 0;
+       s32 rf_freq_residual = -1 * tuner_freq_offset;
+       s32 adc_freq = 0;
+       s32 intermediate_freq = 0;
+       u32 iqm_fs_rate_ofs = 0;
+       bool adc_flip = true;
+       bool select_pos_image = false;
+       bool rf_mirror;
+       bool tuner_mirror;
+       bool image_to_select = true;
+       s32 fm_frequency_shift = 0;
+
+       rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
+       tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
+       /*
+          Program frequency shifter
+          No need to account for mirroring on RF
+        */
+       switch (ext_attr->standard) {
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:        /* fallthrough */
+       case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
+       case DRX_STANDARD_8VSB:
+               select_pos_image = true;
+               break;
+       case DRX_STANDARD_FM:
+               /* After IQM FS sound carrier must appear at 4 Mhz in spect.
+                  Sound carrier is already 3Mhz above centre frequency due
+                  to tuner setting so now add an extra shift of 1MHz... */
+               fm_frequency_shift = 1000;
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_NTSC: /* fallthrough */
+       case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
+       case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
+       case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
+       case DRX_STANDARD_PAL_SECAM_L:
+               select_pos_image = false;
+               break;
+       default:
+               return -EINVAL;
+       }
+       intermediate_freq = demod->my_common_attr->intermediate_freq;
+       sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
+       if (tuner_mirror)
+               if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
+       else
+               if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
+       if (if_freq_actual > sampling_frequency / 2) {
+               /* adc mirrors */
+               adc_freq = sampling_frequency - if_freq_actual;
+               adc_flip = true;
+       } else {
+               /* adc doesn't mirror */
+               adc_freq = if_freq_actual;
+               adc_flip = false;
+       }
+
+       frequency_shift = adc_freq;
+       image_to_select =
+           (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
+       iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
+
+       if (image_to_select)
+               iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
+
+       /* Program frequency shifter with tuner offset compensation */
+       /* frequency_shift += tuner_freq_offset; TODO */
+       rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
+       ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int get_acc_pkt_err()
+* \brief Retrieve signal strength for VSB and QAM.
+* \param demod Pointer to demod instance
+* \param packet_err Pointer to packet error
+* \return int.
+* \retval 0 sig_strength contains valid data.
+* \retval -EINVAL sig_strength is NULL.
+* \retval -EIO Erroneous data, sig_strength contains invalid data.
+*/
+#ifdef DRXJ_SIGNAL_ACCUM_ERR
+static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
+{
+       int rc;
+       static u16 pkt_err;
+       static u16 last_pkt_err;
+       u16 data = 0;
+       struct drxj_data *ext_attr = NULL;
+       struct i2c_device_addr *dev_addr = NULL;
+
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       dev_addr = demod->my_i2c_dev_addr;
+
+       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (ext_attr->reset_pkt_err_acc) {
+               last_pkt_err = data;
+               pkt_err = 0;
+               ext_attr->reset_pkt_err_acc = false;
+       }
+
+       if (data < last_pkt_err) {
+               pkt_err += 0xffff - last_pkt_err;
+               pkt_err += data;
+       } else {
+               pkt_err += (data - last_pkt_err);
+       }
+       *packet_err = pkt_err;
+       last_pkt_err = data;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+#endif
+
+
+/*============================================================================*/
+
+/**
+* \fn int set_agc_rf ()
+* \brief Configure RF AGC
+* \param demod instance of demodulator.
+* \param agc_settings AGC configuration structure
+* \return int.
+*/
+static int
+set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       struct drxj_cfg_agc *p_agc_settings = NULL;
+       struct drx_common_attr *common_attr = NULL;
+       int rc;
+       drx_write_reg16func_t scu_wr16 = NULL;
+       drx_read_reg16func_t scu_rr16 = NULL;
+
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       if (atomic) {
+               scu_rr16 = drxj_dap_scu_atomic_read_reg16;
+               scu_wr16 = drxj_dap_scu_atomic_write_reg16;
+       } else {
+               scu_rr16 = drxj_dap_read_reg16;
+               scu_wr16 = drxj_dap_write_reg16;
+       }
+
+       /* Configure AGC only if standard is currently active */
+       if ((ext_attr->standard == agc_settings->standard) ||
+           (DRXJ_ISQAMSTD(ext_attr->standard) &&
+            DRXJ_ISQAMSTD(agc_settings->standard)) ||
+           (DRXJ_ISATVSTD(ext_attr->standard) &&
+            DRXJ_ISATVSTD(agc_settings->standard))) {
+               u16 data = 0;
+
+               switch (agc_settings->ctrl_mode) {
+               case DRX_AGC_CTRL_AUTO:
+
+                       /* Enable RF AGC DAC */
+                       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Enable SCU RF AGC loop */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_RF__M;
+                       if (ext_attr->standard == DRX_STANDARD_8VSB)
+                               data |= (2 << SCU_RAM_AGC_KI_RF__B);
+                       else if (DRXJ_ISQAMSTD(ext_attr->standard))
+                               data |= (5 << SCU_RAM_AGC_KI_RF__B);
+                       else
+                               data |= (4 << SCU_RAM_AGC_KI_RF__B);
+
+                       if (common_attr->tuner_rf_agc_pol)
+                               data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
+                       else
+                               data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Set speed ( using complementary reduction value ) */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B) & SCU_RAM_AGC_KI_RED_RAGC_RED__M) | data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       if (agc_settings->standard == DRX_STANDARD_8VSB)
+                               p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
+                       else if (DRXJ_ISQAMSTD(agc_settings->standard))
+                               p_agc_settings = &(ext_attr->qam_if_agc_cfg);
+                       else if (DRXJ_ISATVSTD(agc_settings->standard))
+                               p_agc_settings = &(ext_attr->atv_if_agc_cfg);
+                       else
+                               return -EINVAL;
+
+                       /* Set TOP, only if IF-AGC is in AUTO mode */
+                       if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
+                               rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                       }
+
+                       /* Cut-Off current */
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_AGC_CTRL_USER:
+
+                       /* Enable RF AGC DAC */
+                       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Disable SCU RF AGC loop */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_RF__M;
+                       if (common_attr->tuner_rf_agc_pol)
+                               data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
+                       else
+                               data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Write value to output pin */
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_AGC_CTRL_OFF:
+
+                       /* Disable RF AGC DAC */
+                       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Disable SCU RF AGC loop */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_RF__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }               /* switch ( agcsettings->ctrl_mode ) */
+       }
+
+       /* Store rf agc settings */
+       switch (agc_settings->standard) {
+       case DRX_STANDARD_8VSB:
+               ext_attr->vsb_rf_agc_cfg = *agc_settings;
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_B:
+       case DRX_STANDARD_ITU_C:
+               ext_attr->qam_rf_agc_cfg = *agc_settings;
+               break;
+#endif
+       default:
+               return -EIO;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_agc_if ()
+* \brief Configure If AGC
+* \param demod instance of demodulator.
+* \param agc_settings AGC configuration structure
+* \return int.
+*/
+static int
+set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       struct drxj_cfg_agc *p_agc_settings = NULL;
+       struct drx_common_attr *common_attr = NULL;
+       drx_write_reg16func_t scu_wr16 = NULL;
+       drx_read_reg16func_t scu_rr16 = NULL;
+       int rc;
+
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       if (atomic) {
+               scu_rr16 = drxj_dap_scu_atomic_read_reg16;
+               scu_wr16 = drxj_dap_scu_atomic_write_reg16;
+       } else {
+               scu_rr16 = drxj_dap_read_reg16;
+               scu_wr16 = drxj_dap_write_reg16;
+       }
+
+       /* Configure AGC only if standard is currently active */
+       if ((ext_attr->standard == agc_settings->standard) ||
+           (DRXJ_ISQAMSTD(ext_attr->standard) &&
+            DRXJ_ISQAMSTD(agc_settings->standard)) ||
+           (DRXJ_ISATVSTD(ext_attr->standard) &&
+            DRXJ_ISATVSTD(agc_settings->standard))) {
+               u16 data = 0;
+
+               switch (agc_settings->ctrl_mode) {
+               case DRX_AGC_CTRL_AUTO:
+                       /* Enable IF AGC DAC */
+                       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Enable SCU IF AGC loop */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
+                       data &= ~SCU_RAM_AGC_KI_IF__M;
+                       if (ext_attr->standard == DRX_STANDARD_8VSB)
+                               data |= (3 << SCU_RAM_AGC_KI_IF__B);
+                       else if (DRXJ_ISQAMSTD(ext_attr->standard))
+                               data |= (6 << SCU_RAM_AGC_KI_IF__B);
+                       else
+                               data |= (5 << SCU_RAM_AGC_KI_IF__B);
+
+                       if (common_attr->tuner_if_agc_pol)
+                               data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
+                       else
+                               data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Set speed (using complementary reduction value) */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
+                       rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B) & SCU_RAM_AGC_KI_RED_IAGC_RED__M) | data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       if (agc_settings->standard == DRX_STANDARD_8VSB)
+                               p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
+                       else if (DRXJ_ISQAMSTD(agc_settings->standard))
+                               p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
+                       else if (DRXJ_ISATVSTD(agc_settings->standard))
+                               p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
+                       else
+                               return -EINVAL;
+
+                       /* Restore TOP */
+                       if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
+                               rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                       } else {
+                               rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                       }
+                       break;
+
+               case DRX_AGC_CTRL_USER:
+
+                       /* Enable IF AGC DAC */
+                       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Disable SCU IF AGC loop */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
+                       data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
+                       if (common_attr->tuner_if_agc_pol)
+                               data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
+                       else
+                               data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Write value to output pin */
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+
+               case DRX_AGC_CTRL_OFF:
+
+                       /* Disable If AGC DAC */
+                       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       /* Disable SCU IF AGC loop */
+                       rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
+                       data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
+                       rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }               /* switch ( agcsettings->ctrl_mode ) */
+
+               /* always set the top to support configurations without if-loop */
+               rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* Store if agc settings */
+       switch (agc_settings->standard) {
+       case DRX_STANDARD_8VSB:
+               ext_attr->vsb_if_agc_cfg = *agc_settings;
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_B:
+       case DRX_STANDARD_ITU_C:
+               ext_attr->qam_if_agc_cfg = *agc_settings;
+               break;
+#endif
+       default:
+               return -EIO;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_iqm_af ()
+* \brief Configure IQM AF registers
+* \param demod instance of demodulator.
+* \param active
+* \return int.
+*/
+static int set_iqm_af(struct drx_demod_instance *demod, bool active)
+{
+       u16 data = 0;
+       struct i2c_device_addr *dev_addr = NULL;
+       int rc;
+
+       dev_addr = demod->my_i2c_dev_addr;
+
+       /* Configure IQM */
+       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (!active)
+               data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
+       else
+               data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+/*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                       8VSB DATAPATH FUNCTIONS                          ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+/**
+* \fn int power_down_vsb ()
+* \brief Powr down QAM related blocks.
+* \param demod instance of demodulator.
+* \param channel pointer to channel data.
+* \return int.
+*/
+static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drxjscu_cmd cmd_scu = { /* command     */ 0,
+               /* parameter_len */ 0,
+               /* result_len    */ 0,
+               /* *parameter   */ NULL,
+               /* *result      */ NULL
+       };
+       struct drx_cfg_mpeg_output cfg_mpeg_output;
+       int rc;
+       u16 cmd_result = 0;
+
+       /*
+          STOP demodulator
+          reset of FEC and VSB HW
+        */
+       cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
+           SCU_RAM_COMMAND_CMD_DEMOD_STOP;
+       cmd_scu.parameter_len = 0;
+       cmd_scu.result_len = 1;
+       cmd_scu.parameter = NULL;
+       cmd_scu.result = &cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* stop all comm_exec */
+       rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (primary) {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_iqm_af(demod, false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       } else {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       cfg_mpeg_output.enable_mpeg_output = false;
+       rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_vsb_leak_n_gain ()
+* \brief Set ATSC demod.
+* \param demod instance of demodulator.
+* \return int.
+*/
+static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       int rc;
+
+       const u8 vsb_ffe_leak_gain_ram0[] = {
+               DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO1  */
+               DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO2  */
+               DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO3  */
+               DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO4  */
+               DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO5  */
+               DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO6  */
+               DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO7  */
+               DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO8  */
+               DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO9  */
+               DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO10  */
+               DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO11 */
+               DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO12 */
+               DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO1 */
+               DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO2 */
+               DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO3 */
+               DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO4 */
+               DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO5 */
+               DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO6 */
+               DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO7 */
+               DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO8 */
+               DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO9 */
+               DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO10 */
+               DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO11 */
+               DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO12 */
+               DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO1 */
+               DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO2 */
+               DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO3 */
+               DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO4 */
+               DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO5 */
+               DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO6 */
+               DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO7 */
+               DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO8 */
+               DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO9 */
+               DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO10 */
+               DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO11 */
+               DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO12 */
+               DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO1 */
+               DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO2 */
+               DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO3 */
+               DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO4 */
+               DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO5 */
+               DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO6 */
+               DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO7 */
+               DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO8 */
+               DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO9 */
+               DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO10 */
+               DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO11 */
+               DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO12 */
+               DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO1 */
+               DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO2 */
+               DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO3 */
+               DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO4 */
+               DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO5 */
+               DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO6 */
+               DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO7 */
+               DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO8 */
+               DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO9 */
+               DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO10 */
+               DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO11 */
+               DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO12 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO1 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO2 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO3 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO4 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO5 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO6 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO7 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO8 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO9 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO10 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO11 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO12 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO1 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO2 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO3 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO4 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO5 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO6 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO7 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO8 */
+               DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO9 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO10 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO11 */
+               DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO12 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO1 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO2 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO3 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO4 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO5 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO6 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO7 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO8 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO9 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO10 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO11 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO12 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO1 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO2 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO3 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO4 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO5 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO6 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO7 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO8 */
+               DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO9 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO10 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO11 */
+               DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO12 */
+               DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN1 */
+               DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN2 */
+               DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN3 */
+               DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN4 */
+               DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN5 */
+               DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN6 */
+               DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN7 */
+               DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN8 */
+               DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN9 */
+               DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN10 */
+               DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN11 */
+               DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN12 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN1 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN2 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN3 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN4 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN5 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN6 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN7 */
+               DRXJ_16TO8(0x1010)      /* FIRRCA1GAIN8 */
+       };
+
+       const u8 vsb_ffe_leak_gain_ram1[] = {
+               DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN9 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN10 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN11 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN12 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN1 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN2 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN3 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN4 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN5 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN6 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN7 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN8 */
+               DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN9 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN10 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN11 */
+               DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN12 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN1 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN2 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN3 */
+               DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN4 */
+               DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN5 */
+               DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN6 */
+               DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN7 */
+               DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN8 */
+               DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN9 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN10 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN11 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN12 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN1 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN2 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN3 */
+               DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN4 */
+               DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN5 */
+               DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN6 */
+               DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN7 */
+               DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN8 */
+               DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN9 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN10 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN11 */
+               DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN12 */
+               DRXJ_16TO8(0x001f),     /* DFETRAINLKRATIO */
+               DRXJ_16TO8(0x01ff),     /* DFERCA1TRAINLKRATIO */
+               DRXJ_16TO8(0x01ff),     /* DFERCA1DATALKRATIO */
+               DRXJ_16TO8(0x004f),     /* DFERCA2TRAINLKRATIO */
+               DRXJ_16TO8(0x004f),     /* DFERCA2DATALKRATIO */
+               DRXJ_16TO8(0x01ff),     /* DFEDDM1TRAINLKRATIO */
+               DRXJ_16TO8(0x01ff),     /* DFEDDM1DATALKRATIO */
+               DRXJ_16TO8(0x0352),     /* DFEDDM2TRAINLKRATIO */
+               DRXJ_16TO8(0x0352),     /* DFEDDM2DATALKRATIO */
+               DRXJ_16TO8(0x0000),     /* DFETRAINGAIN */
+               DRXJ_16TO8(0x2020),     /* DFERCA1GAIN */
+               DRXJ_16TO8(0x1010),     /* DFERCA2GAIN */
+               DRXJ_16TO8(0x1818),     /* DFEDDM1GAIN */
+               DRXJ_16TO8(0x1212)      /* DFEDDM2GAIN */
+       };
+
+       dev_addr = demod->my_i2c_dev_addr;
+       rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_vsb()
+* \brief Set 8VSB demod.
+* \param demod instance of demodulator.
+* \return int.
+*
+*/
+static int set_vsb(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       int rc;
+       struct drx_common_attr *common_attr = NULL;
+       struct drxjscu_cmd cmd_scu;
+       struct drxj_data *ext_attr = NULL;
+       u16 cmd_result = 0;
+       u16 cmd_param = 0;
+       const u8 vsb_taps_re[] = {
+               DRXJ_16TO8(-2), /* re0  */
+               DRXJ_16TO8(4),  /* re1  */
+               DRXJ_16TO8(1),  /* re2  */
+               DRXJ_16TO8(-4), /* re3  */
+               DRXJ_16TO8(1),  /* re4  */
+               DRXJ_16TO8(4),  /* re5  */
+               DRXJ_16TO8(-3), /* re6  */
+               DRXJ_16TO8(-3), /* re7  */
+               DRXJ_16TO8(6),  /* re8  */
+               DRXJ_16TO8(1),  /* re9  */
+               DRXJ_16TO8(-9), /* re10 */
+               DRXJ_16TO8(3),  /* re11 */
+               DRXJ_16TO8(12), /* re12 */
+               DRXJ_16TO8(-9), /* re13 */
+               DRXJ_16TO8(-15),        /* re14 */
+               DRXJ_16TO8(17), /* re15 */
+               DRXJ_16TO8(19), /* re16 */
+               DRXJ_16TO8(-29),        /* re17 */
+               DRXJ_16TO8(-22),        /* re18 */
+               DRXJ_16TO8(45), /* re19 */
+               DRXJ_16TO8(25), /* re20 */
+               DRXJ_16TO8(-70),        /* re21 */
+               DRXJ_16TO8(-28),        /* re22 */
+               DRXJ_16TO8(111),        /* re23 */
+               DRXJ_16TO8(30), /* re24 */
+               DRXJ_16TO8(-201),       /* re25 */
+               DRXJ_16TO8(-31),        /* re26 */
+               DRXJ_16TO8(629) /* re27 */
+       };
+
+       dev_addr = demod->my_i2c_dev_addr;
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       /* stop all comm_exec */
+       rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* reset demodulator */
+       cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
+           | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
+       cmd_scu.parameter_len = 0;
+       cmd_scu.result_len = 1;
+       cmd_scu.parameter = NULL;
+       cmd_scu.result = &cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
+       rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* set higher threshold */
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* burst detection on   */
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* drop thresholds by 1 dB */
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* drop thresholds by 2 dB */
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* cma on               */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* GPIO               */
+
+       /* Initialize the FEC Subsystem */
+       rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       {
+               u16 fec_oc_snc_mode = 0;
+               rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /* output data even when not locked */
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* set clip */
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* no transparent, no A&C framing; parity is set in mpegoutput */
+       {
+               u16 fec_oc_reg_mode = 0;
+               rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* timeout counter for restarting */
+       rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /* bypass disabled */
+       /* initialize RS packet error measurement parameters */
+       rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* init measurement period of MER/SER */
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* B-Input to ADC, PGA+filter in standby */
+       if (!ext_attr->has_lna) {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* turn on IQMAF. It has to be in front of setAgc**() */
+       rc = set_iqm_af(demod, true);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = adc_synchronization(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = init_agc(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       {
+               /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
+                  of only the gain */
+               struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
+
+               vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
+               rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+       rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Mpeg output has to be in front of FEC active */
+       rc = set_mpegtei_handling(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = bit_reverse_mpeg_output(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = set_mpeg_start_width(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       {
+               /* TODO: move to set_standard after hardware reset value problem is solved */
+               /* Configure initial MPEG output */
+               struct drx_cfg_mpeg_output cfg_mpeg_output;
+
+               memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
+               cfg_mpeg_output.enable_mpeg_output = true;
+
+               rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* TBD: what parameters should be set */
+       cmd_param = 0x00;       /* Default mode AGC on, etc */
+       cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
+           | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
+       cmd_scu.parameter_len = 1;
+       cmd_scu.result_len = 1;
+       cmd_scu.parameter = &cmd_param;
+       cmd_scu.result = &cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* start demodulator */
+       cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
+           | SCU_RAM_COMMAND_CMD_DEMOD_START;
+       cmd_scu.parameter_len = 0;
+       cmd_scu.result_len = 1;
+       cmd_scu.parameter = NULL;
+       cmd_scu.result = &cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
+* \brief Get the values of packet error in 8VSB mode
+* \return Error code
+*/
+static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
+                                  u32 *pck_errs, u32 *pck_count)
+{
+       int rc;
+       u16 data = 0;
+       u16 period = 0;
+       u16 prescale = 0;
+       u16 packet_errors_mant = 0;
+       u16 packet_errors_exp = 0;
+
+       rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
+       packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
+           >> FEC_RS_NR_FAILURES_EXP__B;
+       period = FEC_RS_MEASUREMENT_PERIOD;
+       prescale = FEC_RS_MEASUREMENT_PRESCALE;
+       /* packet error rate = (error packet number) per second */
+       /* 77.3 us is time for per packet */
+       if (period * prescale == 0) {
+               pr_err("error: period and/or prescale is zero!\n");
+               return -EIO;
+       }
+       *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
+       *pck_count = period * prescale * 77;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
+* \brief Get the values of ber in VSB mode
+* \return Error code
+*/
+static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
+                                   u32 *ber, u32 *cnt)
+{
+       int rc;
+       u16 data = 0;
+       u16 period = 0;
+       u16 prescale = 0;
+       u16 bit_errors_mant = 0;
+       u16 bit_errors_exp = 0;
+
+       rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       period = FEC_RS_MEASUREMENT_PERIOD;
+       prescale = FEC_RS_MEASUREMENT_PRESCALE;
+
+       bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
+       bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
+           >> FEC_RS_NR_BIT_ERRORS_EXP__B;
+
+       *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
+
+       if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
+               *ber = (*cnt) * 26570;
+       else {
+               if (period * prescale == 0) {
+                       pr_err("error: period and/or prescale is zero!\n");
+                       return -EIO;
+               }
+               *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
+                       (bit_errors_exp - 3) : bit_errors_exp);
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
+* \brief Get the values of ber in VSB mode
+* \return Error code
+*/
+static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
+                                  u32 *ber, u32 *cnt)
+{
+       u16 data = 0;
+       int rc;
+
+       rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               return -EIO;
+       }
+       *ber = data;
+       *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
+
+       return 0;
+}
+
+/**
+* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
+* \brief Get the values of MER
+* \return Error code
+*/
+static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
+{
+       int rc;
+       u16 data_hi = 0;
+
+       rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       *mer =
+           (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+
+/*============================================================================*/
+/*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                       QAM DATAPATH FUNCTIONS                           ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+/**
+* \fn int power_down_qam ()
+* \brief Powr down QAM related blocks.
+* \param demod instance of demodulator.
+* \param channel pointer to channel data.
+* \return int.
+*/
+static int power_down_qam(struct drx_demod_instance *demod, bool primary)
+{
+       struct drxjscu_cmd cmd_scu = { /* command      */ 0,
+               /* parameter_len */ 0,
+               /* result_len    */ 0,
+               /* *parameter   */ NULL,
+               /* *result      */ NULL
+       };
+       int rc;
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drx_cfg_mpeg_output cfg_mpeg_output;
+       struct drx_common_attr *common_attr = demod->my_common_attr;
+       u16 cmd_result = 0;
+
+       /*
+          STOP demodulator
+          resets IQM, QAM and FEC HW blocks
+        */
+       /* stop all comm_exec */
+       rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
+           SCU_RAM_COMMAND_CMD_DEMOD_STOP;
+       cmd_scu.parameter_len = 0;
+       cmd_scu.result_len = 1;
+       cmd_scu.parameter = NULL;
+       cmd_scu.result = &cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       if (primary) {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_iqm_af(demod, false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       } else {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
+       cfg_mpeg_output.enable_mpeg_output = false;
+
+       rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int set_qam_measurement ()
+* \brief Setup of the QAM Measuremnt intervals for signal quality
+* \param demod instance of demod.
+* \param constellation current constellation.
+* \return int.
+*
+*  NOTE:
+*  Take into account that for certain settings the errorcounters can overflow.
+*  The implementation does not check this.
+*
+*  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
+*  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
+*  field ?
+*
+*/
+#ifndef DRXJ_VSB_ONLY
+static int
+set_qam_measurement(struct drx_demod_instance *demod,
+                   enum drx_modulation constellation, u32 symbol_rate)
+{
+       struct i2c_device_addr *dev_addr = NULL;        /* device address for I2C writes */
+       struct drxj_data *ext_attr = NULL;      /* Global data container for DRXJ specif data */
+       int rc;
+       u32 fec_bits_desired = 0;       /* BER accounting period */
+       u16 fec_rs_plen = 0;    /* defines RS BER measurement period */
+       u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
+       u32 fec_rs_period = 0;  /* Value for corresponding I2C register */
+       u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
+       u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
+       u32 qam_vd_period = 0;  /* Value for corresponding I2C register */
+       u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
+       u16 fec_vd_plen = 0;    /* no of trellis symbols: VD SER measur period */
+       u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       fec_bits_desired = ext_attr->fec_bits_desired;
+       fec_rs_prescale = ext_attr->fec_rs_prescale;
+
+       switch (constellation) {
+       case DRX_CONSTELLATION_QAM16:
+               fec_bits_desired = 4 * symbol_rate;
+               break;
+       case DRX_CONSTELLATION_QAM32:
+               fec_bits_desired = 5 * symbol_rate;
+               break;
+       case DRX_CONSTELLATION_QAM64:
+               fec_bits_desired = 6 * symbol_rate;
+               break;
+       case DRX_CONSTELLATION_QAM128:
+               fec_bits_desired = 7 * symbol_rate;
+               break;
+       case DRX_CONSTELLATION_QAM256:
+               fec_bits_desired = 8 * symbol_rate;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Parameters for Reed-Solomon Decoder */
+       /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
+       /* rs_bit_cnt   = fecrs_period*fecrs_prescale*plen                  */
+       /*     result is within 32 bit arithmetic ->                        */
+       /*     no need for mult or frac functions                           */
+
+       /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
+       switch (ext_attr->standard) {
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_C:
+               fec_rs_plen = 204 * 8;
+               break;
+       case DRX_STANDARD_ITU_B:
+               fec_rs_plen = 128 * 7;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ext_attr->fec_rs_plen = fec_rs_plen;    /* for getSigQual */
+       fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage   */
+       if (fec_rs_bit_cnt == 0) {
+               pr_err("error: fec_rs_bit_cnt is zero!\n");
+               return -EIO;
+       }
+       fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1;  /* ceil */
+       if (ext_attr->standard != DRX_STANDARD_ITU_B)
+               fec_oc_snc_fail_period = fec_rs_period;
+
+       /* limit to max 16 bit value (I2C register width) if needed */
+       if (fec_rs_period > 0xFFFF)
+               fec_rs_period = 0xFFFF;
+
+       /* write corresponding registers */
+       switch (ext_attr->standard) {
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_C:
+               break;
+       case DRX_STANDARD_ITU_B:
+               switch (constellation) {
+               case DRX_CONSTELLATION_QAM64:
+                       fec_rs_period = 31581;
+                       fec_oc_snc_fail_period = 17932;
+                       break;
+               case DRX_CONSTELLATION_QAM256:
+                       fec_rs_period = 45446;
+                       fec_oc_snc_fail_period = 25805;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       ext_attr->fec_rs_period = (u16) fec_rs_period;
+       ext_attr->fec_rs_prescale = fec_rs_prescale;
+       rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+               /* Parameters for Viterbi Decoder */
+               /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/                      */
+               /*                    (qamvd_prescale*plen*(qam_constellation+1))) */
+               /* vd_bit_cnt   = qamvd_period*qamvd_prescale*plen                 */
+               /*     result is within 32 bit arithmetic ->                       */
+               /*     no need for mult or frac functions                          */
+
+               /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
+               fec_vd_plen = ext_attr->fec_vd_plen;
+               qam_vd_prescale = ext_attr->qam_vd_prescale;
+               qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
+
+               switch (constellation) {
+               case DRX_CONSTELLATION_QAM64:
+                       /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
+                       qam_vd_period =
+                           qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
+                           * (QAM_TOP_CONSTELLATION_QAM64 + 1);
+                       break;
+               case DRX_CONSTELLATION_QAM256:
+                       /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
+                       qam_vd_period =
+                           qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
+                           * (QAM_TOP_CONSTELLATION_QAM256 + 1);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               if (qam_vd_period == 0) {
+                       pr_err("error: qam_vd_period is zero!\n");
+                       return -EIO;
+               }
+               qam_vd_period = fec_bits_desired / qam_vd_period;
+               /* limit to max 16 bit value (I2C register width) if needed */
+               if (qam_vd_period > 0xFFFF)
+                       qam_vd_period = 0xFFFF;
+
+               /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
+               qam_vd_bit_cnt *= qam_vd_period;
+
+               rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               ext_attr->qam_vd_period = (u16) qam_vd_period;
+               ext_attr->qam_vd_prescale = qam_vd_prescale;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int set_qam16 ()
+* \brief QAM16 specific setup
+* \param demod instance of demod.
+* \return int.
+*/
+static int set_qam16(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       const u8 qam_dq_qual_fun[] = {
+               DRXJ_16TO8(2),  /* fun0  */
+               DRXJ_16TO8(2),  /* fun1  */
+               DRXJ_16TO8(2),  /* fun2  */
+               DRXJ_16TO8(2),  /* fun3  */
+               DRXJ_16TO8(3),  /* fun4  */
+               DRXJ_16TO8(3),  /* fun5  */
+       };
+       const u8 qam_eq_cma_rad[] = {
+               DRXJ_16TO8(13517),      /* RAD0  */
+               DRXJ_16TO8(13517),      /* RAD1  */
+               DRXJ_16TO8(13517),      /* RAD2  */
+               DRXJ_16TO8(13517),      /* RAD3  */
+               DRXJ_16TO8(13517),      /* RAD4  */
+               DRXJ_16TO8(13517),      /* RAD5  */
+       };
+
+       rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int set_qam32 ()
+* \brief QAM32 specific setup
+* \param demod instance of demod.
+* \return int.
+*/
+static int set_qam32(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       const u8 qam_dq_qual_fun[] = {
+               DRXJ_16TO8(3),  /* fun0  */
+               DRXJ_16TO8(3),  /* fun1  */
+               DRXJ_16TO8(3),  /* fun2  */
+               DRXJ_16TO8(3),  /* fun3  */
+               DRXJ_16TO8(4),  /* fun4  */
+               DRXJ_16TO8(4),  /* fun5  */
+       };
+       const u8 qam_eq_cma_rad[] = {
+               DRXJ_16TO8(6707),       /* RAD0  */
+               DRXJ_16TO8(6707),       /* RAD1  */
+               DRXJ_16TO8(6707),       /* RAD2  */
+               DRXJ_16TO8(6707),       /* RAD3  */
+               DRXJ_16TO8(6707),       /* RAD4  */
+               DRXJ_16TO8(6707),       /* RAD5  */
+       };
+
+       rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int set_qam64 ()
+* \brief QAM64 specific setup
+* \param demod instance of demod.
+* \return int.
+*/
+static int set_qam64(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       const u8 qam_dq_qual_fun[] = {  /* this is hw reset value. no necessary to re-write */
+               DRXJ_16TO8(4),  /* fun0  */
+               DRXJ_16TO8(4),  /* fun1  */
+               DRXJ_16TO8(4),  /* fun2  */
+               DRXJ_16TO8(4),  /* fun3  */
+               DRXJ_16TO8(6),  /* fun4  */
+               DRXJ_16TO8(6),  /* fun5  */
+       };
+       const u8 qam_eq_cma_rad[] = {
+               DRXJ_16TO8(13336),      /* RAD0  */
+               DRXJ_16TO8(12618),      /* RAD1  */
+               DRXJ_16TO8(11988),      /* RAD2  */
+               DRXJ_16TO8(13809),      /* RAD3  */
+               DRXJ_16TO8(13809),      /* RAD4  */
+               DRXJ_16TO8(15609),      /* RAD5  */
+       };
+
+       rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int set_qam128 ()
+* \brief QAM128 specific setup
+* \param demod: instance of demod.
+* \return int.
+*/
+static int set_qam128(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       const u8 qam_dq_qual_fun[] = {
+               DRXJ_16TO8(6),  /* fun0  */
+               DRXJ_16TO8(6),  /* fun1  */
+               DRXJ_16TO8(6),  /* fun2  */
+               DRXJ_16TO8(6),  /* fun3  */
+               DRXJ_16TO8(9),  /* fun4  */
+               DRXJ_16TO8(9),  /* fun5  */
+       };
+       const u8 qam_eq_cma_rad[] = {
+               DRXJ_16TO8(6164),       /* RAD0  */
+               DRXJ_16TO8(6598),       /* RAD1  */
+               DRXJ_16TO8(6394),       /* RAD2  */
+               DRXJ_16TO8(6409),       /* RAD3  */
+               DRXJ_16TO8(6656),       /* RAD4  */
+               DRXJ_16TO8(7238),       /* RAD5  */
+       };
+
+       rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int set_qam256 ()
+* \brief QAM256 specific setup
+* \param demod: instance of demod.
+* \return int.
+*/
+static int set_qam256(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       const u8 qam_dq_qual_fun[] = {
+               DRXJ_16TO8(8),  /* fun0  */
+               DRXJ_16TO8(8),  /* fun1  */
+               DRXJ_16TO8(8),  /* fun2  */
+               DRXJ_16TO8(8),  /* fun3  */
+               DRXJ_16TO8(12), /* fun4  */
+               DRXJ_16TO8(12), /* fun5  */
+       };
+       const u8 qam_eq_cma_rad[] = {
+               DRXJ_16TO8(12345),      /* RAD0  */
+               DRXJ_16TO8(12345),      /* RAD1  */
+               DRXJ_16TO8(13626),      /* RAD2  */
+               DRXJ_16TO8(12931),      /* RAD3  */
+               DRXJ_16TO8(14719),      /* RAD4  */
+               DRXJ_16TO8(15356),      /* RAD5  */
+       };
+
+       rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+#define QAM_SET_OP_ALL 0x1
+#define QAM_SET_OP_CONSTELLATION 0x2
+#define QAM_SET_OP_SPECTRUM 0X4
+
+/**
+* \fn int set_qam ()
+* \brief Set QAM demod.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \return int.
+*/
+static int
+set_qam(struct drx_demod_instance *demod,
+       struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       struct drx_common_attr *common_attr = NULL;
+       int rc;
+       u32 adc_frequency = 0;
+       u32 iqm_rc_rate = 0;
+       u16 cmd_result = 0;
+       u16 lc_symbol_freq = 0;
+       u16 iqm_rc_stretch = 0;
+       u16 set_env_parameters = 0;
+       u16 set_param_parameters[2] = { 0 };
+       struct drxjscu_cmd cmd_scu = { /* command      */ 0,
+               /* parameter_len */ 0,
+               /* result_len    */ 0,
+               /* parameter    */ NULL,
+               /* result       */ NULL
+       };
+       const u8 qam_a_taps[] = {
+               DRXJ_16TO8(-1), /* re0  */
+               DRXJ_16TO8(1),  /* re1  */
+               DRXJ_16TO8(1),  /* re2  */
+               DRXJ_16TO8(-1), /* re3  */
+               DRXJ_16TO8(-1), /* re4  */
+               DRXJ_16TO8(2),  /* re5  */
+               DRXJ_16TO8(1),  /* re6  */
+               DRXJ_16TO8(-2), /* re7  */
+               DRXJ_16TO8(0),  /* re8  */
+               DRXJ_16TO8(3),  /* re9  */
+               DRXJ_16TO8(-1), /* re10 */
+               DRXJ_16TO8(-3), /* re11 */
+               DRXJ_16TO8(4),  /* re12 */
+               DRXJ_16TO8(1),  /* re13 */
+               DRXJ_16TO8(-8), /* re14 */
+               DRXJ_16TO8(4),  /* re15 */
+               DRXJ_16TO8(13), /* re16 */
+               DRXJ_16TO8(-13),        /* re17 */
+               DRXJ_16TO8(-19),        /* re18 */
+               DRXJ_16TO8(28), /* re19 */
+               DRXJ_16TO8(25), /* re20 */
+               DRXJ_16TO8(-53),        /* re21 */
+               DRXJ_16TO8(-31),        /* re22 */
+               DRXJ_16TO8(96), /* re23 */
+               DRXJ_16TO8(37), /* re24 */
+               DRXJ_16TO8(-190),       /* re25 */
+               DRXJ_16TO8(-40),        /* re26 */
+               DRXJ_16TO8(619) /* re27 */
+       };
+       const u8 qam_b64_taps[] = {
+               DRXJ_16TO8(0),  /* re0  */
+               DRXJ_16TO8(-2), /* re1  */
+               DRXJ_16TO8(1),  /* re2  */
+               DRXJ_16TO8(2),  /* re3  */
+               DRXJ_16TO8(-2), /* re4  */
+               DRXJ_16TO8(0),  /* re5  */
+               DRXJ_16TO8(4),  /* re6  */
+               DRXJ_16TO8(-2), /* re7  */
+               DRXJ_16TO8(-4), /* re8  */
+               DRXJ_16TO8(4),  /* re9  */
+               DRXJ_16TO8(3),  /* re10 */
+               DRXJ_16TO8(-6), /* re11 */
+               DRXJ_16TO8(0),  /* re12 */
+               DRXJ_16TO8(6),  /* re13 */
+               DRXJ_16TO8(-5), /* re14 */
+               DRXJ_16TO8(-3), /* re15 */
+               DRXJ_16TO8(11), /* re16 */
+               DRXJ_16TO8(-4), /* re17 */
+               DRXJ_16TO8(-19),        /* re18 */
+               DRXJ_16TO8(19), /* re19 */
+               DRXJ_16TO8(28), /* re20 */
+               DRXJ_16TO8(-45),        /* re21 */
+               DRXJ_16TO8(-36),        /* re22 */
+               DRXJ_16TO8(90), /* re23 */
+               DRXJ_16TO8(42), /* re24 */
+               DRXJ_16TO8(-185),       /* re25 */
+               DRXJ_16TO8(-46),        /* re26 */
+               DRXJ_16TO8(614) /* re27 */
+       };
+       const u8 qam_b256_taps[] = {
+               DRXJ_16TO8(-2), /* re0  */
+               DRXJ_16TO8(4),  /* re1  */
+               DRXJ_16TO8(1),  /* re2  */
+               DRXJ_16TO8(-4), /* re3  */
+               DRXJ_16TO8(0),  /* re4  */
+               DRXJ_16TO8(4),  /* re5  */
+               DRXJ_16TO8(-2), /* re6  */
+               DRXJ_16TO8(-4), /* re7  */
+               DRXJ_16TO8(5),  /* re8  */
+               DRXJ_16TO8(2),  /* re9  */
+               DRXJ_16TO8(-8), /* re10 */
+               DRXJ_16TO8(2),  /* re11 */
+               DRXJ_16TO8(11), /* re12 */
+               DRXJ_16TO8(-8), /* re13 */
+               DRXJ_16TO8(-15),        /* re14 */
+               DRXJ_16TO8(16), /* re15 */
+               DRXJ_16TO8(19), /* re16 */
+               DRXJ_16TO8(-27),        /* re17 */
+               DRXJ_16TO8(-22),        /* re18 */
+               DRXJ_16TO8(44), /* re19 */
+               DRXJ_16TO8(26), /* re20 */
+               DRXJ_16TO8(-69),        /* re21 */
+               DRXJ_16TO8(-28),        /* re22 */
+               DRXJ_16TO8(110),        /* re23 */
+               DRXJ_16TO8(31), /* re24 */
+               DRXJ_16TO8(-201),       /* re25 */
+               DRXJ_16TO8(-32),        /* re26 */
+               DRXJ_16TO8(628) /* re27 */
+       };
+       const u8 qam_c_taps[] = {
+               DRXJ_16TO8(-3), /* re0  */
+               DRXJ_16TO8(3),  /* re1  */
+               DRXJ_16TO8(2),  /* re2  */
+               DRXJ_16TO8(-4), /* re3  */
+               DRXJ_16TO8(0),  /* re4  */
+               DRXJ_16TO8(4),  /* re5  */
+               DRXJ_16TO8(-1), /* re6  */
+               DRXJ_16TO8(-4), /* re7  */
+               DRXJ_16TO8(3),  /* re8  */
+               DRXJ_16TO8(3),  /* re9  */
+               DRXJ_16TO8(-5), /* re10 */
+               DRXJ_16TO8(0),  /* re11 */
+               DRXJ_16TO8(9),  /* re12 */
+               DRXJ_16TO8(-4), /* re13 */
+               DRXJ_16TO8(-12),        /* re14 */
+               DRXJ_16TO8(10), /* re15 */
+               DRXJ_16TO8(16), /* re16 */
+               DRXJ_16TO8(-21),        /* re17 */
+               DRXJ_16TO8(-20),        /* re18 */
+               DRXJ_16TO8(37), /* re19 */
+               DRXJ_16TO8(25), /* re20 */
+               DRXJ_16TO8(-62),        /* re21 */
+               DRXJ_16TO8(-28),        /* re22 */
+               DRXJ_16TO8(105),        /* re23 */
+               DRXJ_16TO8(31), /* re24 */
+               DRXJ_16TO8(-197),       /* re25 */
+               DRXJ_16TO8(-33),        /* re26 */
+               DRXJ_16TO8(626) /* re27 */
+       };
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+
+       if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
+               if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+                       switch (channel->constellation) {
+                       case DRX_CONSTELLATION_QAM256:
+                               iqm_rc_rate = 0x00AE3562;
+                               lc_symbol_freq =
+                                   QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
+                               channel->symbolrate = 5360537;
+                               iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
+                               break;
+                       case DRX_CONSTELLATION_QAM64:
+                               iqm_rc_rate = 0x00C05A0E;
+                               lc_symbol_freq = 409;
+                               channel->symbolrate = 5056941;
+                               iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               } else {
+                       adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
+                       if (channel->symbolrate == 0) {
+                               pr_err("error: channel symbolrate is zero!\n");
+                               return -EIO;
+                       }
+                       iqm_rc_rate =
+                           (adc_frequency / channel->symbolrate) * (1 << 21) +
+                           (frac28
+                            ((adc_frequency % channel->symbolrate),
+                             channel->symbolrate) >> 7) - (1 << 23);
+                       lc_symbol_freq =
+                           (u16) (frac28
+                                    (channel->symbolrate +
+                                     (adc_frequency >> 13),
+                                     adc_frequency) >> 16);
+                       if (lc_symbol_freq > 511)
+                               lc_symbol_freq = 511;
+
+                       iqm_rc_stretch = 21;
+               }
+
+               if (ext_attr->standard == DRX_STANDARD_ITU_A) {
+                       set_env_parameters = QAM_TOP_ANNEX_A;   /* annex             */
+                       set_param_parameters[0] = channel->constellation;       /* constellation     */
+                       set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
+               } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+                       set_env_parameters = QAM_TOP_ANNEX_B;   /* annex             */
+                       set_param_parameters[0] = channel->constellation;       /* constellation     */
+                       set_param_parameters[1] = channel->interleavemode;      /* interleave mode   */
+               } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
+                       set_env_parameters = QAM_TOP_ANNEX_C;   /* annex             */
+                       set_param_parameters[0] = channel->constellation;       /* constellation     */
+                       set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
+               } else {
+                       return -EINVAL;
+               }
+       }
+
+       if (op & QAM_SET_OP_ALL) {
+               /*
+                  STEP 1: reset demodulator
+                  resets IQM, QAM and FEC HW blocks
+                  resets SCU variables
+                */
+               /* stop all comm_exec */
+               rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
+                   SCU_RAM_COMMAND_CMD_DEMOD_RESET;
+               cmd_scu.parameter_len = 0;
+               cmd_scu.result_len = 1;
+               cmd_scu.parameter = NULL;
+               cmd_scu.result = &cmd_result;
+               rc = scu_command(dev_addr, &cmd_scu);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
+               /*
+                  STEP 2: configure demodulator
+                  -set env
+                  -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
+                */
+               cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
+                   SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
+               cmd_scu.parameter_len = 1;
+               cmd_scu.result_len = 1;
+               cmd_scu.parameter = &set_env_parameters;
+               cmd_scu.result = &cmd_result;
+               rc = scu_command(dev_addr, &cmd_scu);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
+                   SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
+               cmd_scu.parameter_len = 2;
+               cmd_scu.result_len = 1;
+               cmd_scu.parameter = set_param_parameters;
+               cmd_scu.result = &cmd_result;
+               rc = scu_command(dev_addr, &cmd_scu);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               /* set symbol rate */
+               rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
+               rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+       /* STEP 3: enable the system in a mode where the ADC provides valid signal
+          setup constellation independent registers */
+       /* from qam_cmd.py script (qam_driver_b) */
+       /* TODO: remove re-writes of HW reset values */
+       if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
+               rc = set_frequency(demod, channel, tuner_freq_offset);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
+
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       if (op & QAM_SET_OP_ALL) {
+               if (!ext_attr->has_lna) {
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /* scu temporary shut down agc */
+
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /*! reset default val ! */
+
+               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /*! reset default val ! */
+               if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+                       rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /*! reset default val ! */
+                       rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /*! reset default val ! */
+                       rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /*! reset default val ! */
+               } else {
+                       switch (channel->constellation) {
+                       case DRX_CONSTELLATION_QAM16:
+                       case DRX_CONSTELLATION_QAM64:
+                       case DRX_CONSTELLATION_QAM256:
+                               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }       /*! reset default val ! */
+                               break;
+                       case DRX_CONSTELLATION_QAM32:
+                       case DRX_CONSTELLATION_QAM128:
+                               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               break;
+                       default:
+                               return -EIO;
+                       }       /* switch */
+               }
+
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }       /*! reset default val ! */
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* No more resets of the IQM, current standard correctly set =>
+                  now AGCs can be configured. */
+               /* turn on IQMAF. It has to be in front of setAgc**() */
+               rc = set_iqm_af(demod, true);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = adc_synchronization(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               rc = init_agc(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               {
+                       /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
+                          of only the gain */
+                       struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
+
+                       qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
+                       rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+               rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
+               if (ext_attr->standard == DRX_STANDARD_ITU_A) {
+                       rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+                       switch (channel->constellation) {
+                       case DRX_CONSTELLATION_QAM64:
+                               rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               break;
+                       case DRX_CONSTELLATION_QAM256:
+                               rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               break;
+                       default:
+                               return -EIO;
+                       }
+               } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
+                       rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+
+               /* SETP 4: constellation specific setup */
+               switch (channel->constellation) {
+               case DRX_CONSTELLATION_QAM16:
+                       rc = set_qam16(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_CONSTELLATION_QAM32:
+                       rc = set_qam32(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_CONSTELLATION_QAM64:
+                       rc = set_qam64(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_CONSTELLATION_QAM128:
+                       rc = set_qam128(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_CONSTELLATION_QAM256:
+                       rc = set_qam256(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               default:
+                       return -EIO;
+               }               /* switch */
+       }
+
+       if ((op & QAM_SET_OP_ALL)) {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               /* Mpeg output has to be in front of FEC active */
+               rc = set_mpegtei_handling(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = bit_reverse_mpeg_output(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_mpeg_start_width(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               {
+                       /* TODO: move to set_standard after hardware reset value problem is solved */
+                       /* Configure initial MPEG output */
+                       struct drx_cfg_mpeg_output cfg_mpeg_output;
+
+                       memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
+                       cfg_mpeg_output.enable_mpeg_output = true;
+
+                       rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+       }
+
+       if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
+
+               /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
+               cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
+                   SCU_RAM_COMMAND_CMD_DEMOD_START;
+               cmd_scu.parameter_len = 0;
+               cmd_scu.result_len = 1;
+               cmd_scu.parameter = NULL;
+               cmd_scu.result = &cmd_result;
+               rc = scu_command(dev_addr, &cmd_scu);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
+
+static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       int rc;
+       u32 iqm_fs_rate_ofs = 0;
+       u32 iqm_fs_rate_lo = 0;
+       u16 qam_ctl_ena = 0;
+       u16 data = 0;
+       u16 equ_mode = 0;
+       u16 fsm_state = 0;
+       int i = 0;
+       int ofsofs = 0;
+
+       /* Silence the controlling of lc, equ, and the acquisition state machine */
+       rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* freeze the frequency control loop */
+       rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
+       iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
+       iqm_fs_rate_ofs -= 2 * ofsofs;
+
+       /* freeze dq/fq updating */
+       rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       data = (data & 0xfff9);
+       rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* lc_cp / _ci / _ca */
+       rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* flip the spec */
+       rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
+       ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
+
+       /* freeze dq/fq updating */
+       rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       equ_mode = data;
+       data = (data & 0xfff9);
+       rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       for (i = 0; i < 28; i++) {
+               rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       for (i = 0; i < 24; i++) {
+               rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       data = equ_mode;
+       rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       i = 0;
+       while ((fsm_state != 4) && (i++ < 100)) {
+               rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+
+}
+
+#define  NO_LOCK        0x0
+#define  DEMOD_LOCKED   0x1
+#define  SYNC_FLIPPED   0x2
+#define  SPEC_MIRRORED  0x4
+/**
+* \fn int qam64auto ()
+* \brief auto do sync pattern switching and mirroring.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \param tuner_freq_offset: tuner frequency offset.
+* \param lock_status: pointer to lock status.
+* \return int.
+*/
+static int
+qam64auto(struct drx_demod_instance *demod,
+         struct drx_channel *channel,
+         s32 tuner_freq_offset, enum drx_lock_status *lock_status)
+{
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drx39xxj_state *state = dev_addr->user_data;
+       struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
+       int rc;
+       u32 lck_state = NO_LOCK;
+       u32 start_time = 0;
+       u32 d_locked_time = 0;
+       u32 timeout_ofs = 0;
+       u16 data = 0;
+
+       /* external attributes for storing aquired channel constellation */
+       *lock_status = DRX_NOT_LOCKED;
+       start_time = jiffies_to_msecs(jiffies);
+       lck_state = NO_LOCK;
+       do {
+               rc = ctrl_lock_status(demod, lock_status);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               switch (lck_state) {
+               case NO_LOCK:
+                       if (*lock_status == DRXJ_DEMOD_LOCK) {
+                               rc = ctrl_get_qam_sig_quality(demod);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               if (p->cnr.stat[0].svalue > 20800) {
+                                       lck_state = DEMOD_LOCKED;
+                                       /* some delay to see if fec_lock possible TODO find the right value */
+                                       timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, waiting longer */
+                                       d_locked_time = jiffies_to_msecs(jiffies);
+                               }
+                       }
+                       break;
+               case DEMOD_LOCKED:
+                       if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
+                           ((jiffies_to_msecs(jiffies) - d_locked_time) >
+                            DRXJ_QAM_FEC_LOCK_WAITTIME)) {
+                               rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               lck_state = SYNC_FLIPPED;
+                               msleep(10);
+                       }
+                       break;
+               case SYNC_FLIPPED:
+                       if (*lock_status == DRXJ_DEMOD_LOCK) {
+                               if (channel->mirror == DRX_MIRROR_AUTO) {
+                                       /* flip sync pattern back */
+                                       rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
+                                       if (rc != 0) {
+                                               pr_err("error %d\n", rc);
+                                               goto rw_error;
+                                       }
+                                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
+                                       if (rc != 0) {
+                                               pr_err("error %d\n", rc);
+                                               goto rw_error;
+                                       }
+                                       /* flip spectrum */
+                                       ext_attr->mirror = DRX_MIRROR_YES;
+                                       rc = qam_flip_spec(demod, channel);
+                                       if (rc != 0) {
+                                               pr_err("error %d\n", rc);
+                                               goto rw_error;
+                                       }
+                                       lck_state = SPEC_MIRRORED;
+                                       /* reset timer TODO: still need 500ms? */
+                                       start_time = d_locked_time =
+                                           jiffies_to_msecs(jiffies);
+                                       timeout_ofs = 0;
+                               } else {        /* no need to wait lock */
+
+                                       start_time =
+                                           jiffies_to_msecs(jiffies) -
+                                           DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
+                               }
+                       }
+                       break;
+               case SPEC_MIRRORED:
+                       if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
+                           ((jiffies_to_msecs(jiffies) - d_locked_time) >
+                            DRXJ_QAM_FEC_LOCK_WAITTIME)) {
+                               rc = ctrl_get_qam_sig_quality(demod);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               if (p->cnr.stat[0].svalue > 20800) {
+                                       rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
+                                       if (rc != 0) {
+                                               pr_err("error %d\n", rc);
+                                               goto rw_error;
+                                       }
+                                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
+                                       if (rc != 0) {
+                                               pr_err("error %d\n", rc);
+                                               goto rw_error;
+                                       }
+                                       /* no need to wait lock */
+                                       start_time =
+                                           jiffies_to_msecs(jiffies) -
+                                           DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
+                               }
+                       }
+                       break;
+               default:
+                       break;
+               }
+               msleep(10);
+       } while
+           ((*lock_status != DRX_LOCKED) &&
+            (*lock_status != DRX_NEVER_LOCK) &&
+            ((jiffies_to_msecs(jiffies) - start_time) <
+             (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
+           );
+       /* Returning control to apllication ... */
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int qam256auto ()
+* \brief auto do sync pattern switching and mirroring.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \param tuner_freq_offset: tuner frequency offset.
+* \param lock_status: pointer to lock status.
+* \return int.
+*/
+static int
+qam256auto(struct drx_demod_instance *demod,
+          struct drx_channel *channel,
+          s32 tuner_freq_offset, enum drx_lock_status *lock_status)
+{
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drx39xxj_state *state = dev_addr->user_data;
+       struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
+       int rc;
+       u32 lck_state = NO_LOCK;
+       u32 start_time = 0;
+       u32 d_locked_time = 0;
+       u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
+
+       /* external attributes for storing aquired channel constellation */
+       *lock_status = DRX_NOT_LOCKED;
+       start_time = jiffies_to_msecs(jiffies);
+       lck_state = NO_LOCK;
+       do {
+               rc = ctrl_lock_status(demod, lock_status);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               switch (lck_state) {
+               case NO_LOCK:
+                       if (*lock_status == DRXJ_DEMOD_LOCK) {
+                               rc = ctrl_get_qam_sig_quality(demod);
+                               if (rc != 0) {
+                                       pr_err("error %d\n", rc);
+                                       goto rw_error;
+                               }
+                               if (p->cnr.stat[0].svalue > 26800) {
+                                       lck_state = DEMOD_LOCKED;
+                                       timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, wait longer */
+                                       d_locked_time = jiffies_to_msecs(jiffies);
+                               }
+                       }
+                       break;
+               case DEMOD_LOCKED:
+                       if (*lock_status == DRXJ_DEMOD_LOCK) {
+                               if ((channel->mirror == DRX_MIRROR_AUTO) &&
+                                   ((jiffies_to_msecs(jiffies) - d_locked_time) >
+                                    DRXJ_QAM_FEC_LOCK_WAITTIME)) {
+                                       ext_attr->mirror = DRX_MIRROR_YES;
+                                       rc = qam_flip_spec(demod, channel);
+                                       if (rc != 0) {
+                                               pr_err("error %d\n", rc);
+                                               goto rw_error;
+                                       }
+                                       lck_state = SPEC_MIRRORED;
+                                       /* reset timer TODO: still need 300ms? */
+                                       start_time = jiffies_to_msecs(jiffies);
+                                       timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
+                               }
+                       }
+                       break;
+               case SPEC_MIRRORED:
+                       break;
+               default:
+                       break;
+               }
+               msleep(10);
+       } while
+           ((*lock_status < DRX_LOCKED) &&
+            (*lock_status != DRX_NEVER_LOCK) &&
+            ((jiffies_to_msecs(jiffies) - start_time) <
+             (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_qam_channel ()
+* \brief Set QAM channel according to the requested constellation.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \return int.
+*/
+static int
+set_qam_channel(struct drx_demod_instance *demod,
+              struct drx_channel *channel, s32 tuner_freq_offset)
+{
+       struct drxj_data *ext_attr = NULL;
+       int rc;
+       enum drx_lock_status lock_status = DRX_NOT_LOCKED;
+       bool auto_flag = false;
+
+       /* external attributes for storing aquired channel constellation */
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       /* set QAM channel constellation */
+       switch (channel->constellation) {
+       case DRX_CONSTELLATION_QAM16:
+       case DRX_CONSTELLATION_QAM32:
+       case DRX_CONSTELLATION_QAM128:
+               return -EINVAL;
+       case DRX_CONSTELLATION_QAM64:
+       case DRX_CONSTELLATION_QAM256:
+               if (ext_attr->standard != DRX_STANDARD_ITU_B)
+                       return -EINVAL;
+
+               ext_attr->constellation = channel->constellation;
+               if (channel->mirror == DRX_MIRROR_AUTO)
+                       ext_attr->mirror = DRX_MIRROR_NO;
+               else
+                       ext_attr->mirror = channel->mirror;
+
+               rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               if (channel->constellation == DRX_CONSTELLATION_QAM64)
+                       rc = qam64auto(demod, channel, tuner_freq_offset,
+                                      &lock_status);
+               else
+                       rc = qam256auto(demod, channel, tuner_freq_offset,
+                                       &lock_status);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+       case DRX_CONSTELLATION_AUTO:    /* for channel scan */
+               if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+                       u16 qam_ctl_ena = 0;
+
+                       auto_flag = true;
+
+                       /* try to lock default QAM constellation: QAM256 */
+                       channel->constellation = DRX_CONSTELLATION_QAM256;
+                       ext_attr->constellation = DRX_CONSTELLATION_QAM256;
+                       if (channel->mirror == DRX_MIRROR_AUTO)
+                               ext_attr->mirror = DRX_MIRROR_NO;
+                       else
+                               ext_attr->mirror = channel->mirror;
+                       rc = set_qam(demod, channel, tuner_freq_offset,
+                                    QAM_SET_OP_ALL);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = qam256auto(demod, channel, tuner_freq_offset,
+                                       &lock_status);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       if (lock_status >= DRX_LOCKED) {
+                               channel->constellation = DRX_CONSTELLATION_AUTO;
+                               break;
+                       }
+
+                       /* QAM254 not locked. Try QAM64 constellation */
+                       channel->constellation = DRX_CONSTELLATION_QAM64;
+                       ext_attr->constellation = DRX_CONSTELLATION_QAM64;
+                       if (channel->mirror == DRX_MIRROR_AUTO)
+                               ext_attr->mirror = DRX_MIRROR_NO;
+                       else
+                               ext_attr->mirror = channel->mirror;
+
+                       rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
+                                                    SCU_RAM_QAM_CTL_ENA__A,
+                                                    &qam_ctl_ena, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
+                                                     SCU_RAM_QAM_CTL_ENA__A,
+                                                     qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
+                                                     SCU_RAM_QAM_FSM_STATE_TGT__A,
+                                                     0x2, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* force to rate hunting */
+
+                       rc = set_qam(demod, channel, tuner_freq_offset,
+                                    QAM_SET_OP_CONSTELLATION);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
+                                                     SCU_RAM_QAM_CTL_ENA__A,
+                                                     qam_ctl_ena, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       rc = qam64auto(demod, channel, tuner_freq_offset,
+                                      &lock_status);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       channel->constellation = DRX_CONSTELLATION_AUTO;
+               } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
+                       u16 qam_ctl_ena = 0;
+
+                       channel->constellation = DRX_CONSTELLATION_QAM64;
+                       ext_attr->constellation = DRX_CONSTELLATION_QAM64;
+                       auto_flag = true;
+
+                       if (channel->mirror == DRX_MIRROR_AUTO)
+                               ext_attr->mirror = DRX_MIRROR_NO;
+                       else
+                               ext_attr->mirror = channel->mirror;
+                       rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
+                                                    SCU_RAM_QAM_CTL_ENA__A,
+                                                    &qam_ctl_ena, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
+                                                     SCU_RAM_QAM_CTL_ENA__A,
+                                                     qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
+                                                     SCU_RAM_QAM_FSM_STATE_TGT__A,
+                                                     0x2, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }       /* force to rate hunting */
+
+                       rc = set_qam(demod, channel, tuner_freq_offset,
+                                    QAM_SET_OP_CONSTELLATION);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
+                                                     SCU_RAM_QAM_CTL_ENA__A,
+                                                     qam_ctl_ena, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       rc = qam64auto(demod, channel, tuner_freq_offset,
+                                      &lock_status);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       channel->constellation = DRX_CONSTELLATION_AUTO;
+               } else {
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+rw_error:
+       /* restore starting value */
+       if (auto_flag)
+               channel->constellation = DRX_CONSTELLATION_AUTO;
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
+* \brief Get RS error count in QAM mode (used for post RS BER calculation)
+* \return Error code
+*
+* precondition: measurement period & measurement prescale must be set
+*
+*/
+static int
+get_qamrs_err_count(struct i2c_device_addr *dev_addr,
+                   struct drxjrs_errors *rs_errors)
+{
+       int rc;
+       u16 nr_bit_errors = 0,
+           nr_symbol_errors = 0,
+           nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
+
+       /* check arguments */
+       if (dev_addr == NULL)
+               return -EINVAL;
+
+       /* all reported errors are received in the  */
+       /* most recently finished measurment period */
+       /*   no of pre RS bit errors */
+       rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /*   no of symbol errors      */
+       rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /*   no of packet errors      */
+       rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /*   no of failures to decode */
+       rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /*   no of post RS bit erros  */
+       rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* TODO: NOTE */
+       /* These register values are fetched in non-atomic fashion           */
+       /* It is possible that the read values contain unrelated information */
+
+       rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
+       rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
+       rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
+       rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
+       rs_errors->nr_snc_par_fail_count =
+           nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+ * \fn int get_sig_strength()
+ * \brief Retrieve signal strength for VSB and QAM.
+ * \param demod Pointer to demod instance
+ * \param u16-t Pointer to signal strength data; range 0, .. , 100.
+ * \return int.
+ * \retval 0 sig_strength contains valid data.
+ * \retval -EINVAL sig_strength is NULL.
+ * \retval -EIO Erroneous data, sig_strength contains invalid data.
+ */
+#define DRXJ_AGC_TOP    0x2800
+#define DRXJ_AGC_SNS    0x1600
+#define DRXJ_RFAGC_MAX  0x3fff
+#define DRXJ_RFAGC_MIN  0x800
+
+static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       u16 rf_gain = 0;
+       u16 if_gain = 0;
+       u16 if_agc_sns = 0;
+       u16 if_agc_top = 0;
+       u16 rf_agc_max = 0;
+       u16 rf_agc_min = 0;
+
+       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if_gain &= IQM_AF_AGC_IF__M;
+       rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rf_gain &= IQM_AF_AGC_RF__M;
+
+       if_agc_sns = DRXJ_AGC_SNS;
+       if_agc_top = DRXJ_AGC_TOP;
+       rf_agc_max = DRXJ_RFAGC_MAX;
+       rf_agc_min = DRXJ_RFAGC_MIN;
+
+       if (if_gain > if_agc_top) {
+               if (rf_gain > rf_agc_max)
+                       *sig_strength = 100;
+               else if (rf_gain > rf_agc_min) {
+                       if (rf_agc_max == rf_agc_min) {
+                               pr_err("error: rf_agc_max == rf_agc_min\n");
+                               return -EIO;
+                       }
+                       *sig_strength =
+                       75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
+                                                               rf_agc_min);
+               } else
+                       *sig_strength = 75;
+       } else if (if_gain > if_agc_sns) {
+               if (if_agc_top == if_agc_sns) {
+                       pr_err("error: if_agc_top == if_agc_sns\n");
+                       return -EIO;
+               }
+               *sig_strength =
+               20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
+       } else {
+               if (!if_agc_sns) {
+                       pr_err("error: if_agc_sns is zero!\n");
+                       return -EIO;
+               }
+               *sig_strength = (20 * if_gain / if_agc_sns);
+       }
+
+       if (*sig_strength <= 7)
+               *sig_strength = 0;
+
+       return 0;
+       rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int ctrl_get_qam_sig_quality()
+* \brief Retreive QAM signal quality from device.
+* \param devmod Pointer to demodulator instance.
+* \param sig_quality Pointer to signal quality data.
+* \return int.
+* \retval 0 sig_quality contains valid data.
+* \retval -EINVAL sig_quality is NULL.
+* \retval -EIO Erroneous data, sig_quality contains invalid data.
+
+*  Pre-condition: Device must be started and in lock.
+*/
+static int
+ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       struct drx39xxj_state *state = dev_addr->user_data;
+       struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
+       struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
+       enum drx_modulation constellation = ext_attr->constellation;
+       int rc;
+
+       u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
+       u32 post_bit_err_rs = 0;        /* post RedSolomon Bit Error Rate */
+       u32 pkt_errs = 0;       /* no of packet errors in RS */
+       u16 qam_sl_err_power = 0;       /* accumulated error between raw and sliced symbols */
+       u16 qsym_err_vd = 0;    /* quadrature symbol errors in QAM_VD */
+       u16 fec_oc_period = 0;  /* SNC sync failure measurement period */
+       u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
+       u16 fec_rs_period = 0;  /* Value for corresponding I2C register */
+       /* calculation constants */
+       u32 rs_bit_cnt = 0;     /* RedSolomon Bit Count */
+       u32 qam_sl_sig_power = 0;       /* used for MER, depends of QAM constellation */
+       /* intermediate results */
+       u32 e = 0;              /* exponent value used for QAM BER/SER */
+       u32 m = 0;              /* mantisa value used for QAM BER/SER */
+       u32 ber_cnt = 0;        /* BER count */
+       /* signal quality info */
+       u32 qam_sl_mer = 0;     /* QAM MER */
+       u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
+       u32 qam_post_rs_ber = 0;        /* Post RedSolomon BER */
+       u32 qam_vd_ser = 0;     /* ViterbiDecoder SER */
+       u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
+       u16 qam_vd_period = 0;  /* Viterbi Measurement period */
+       u32 vd_bit_cnt = 0;     /* ViterbiDecoder Bit Count */
+
+       p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+       /* read the physical registers */
+       /*   Get the RS error data */
+       rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* get the register value needed for MER */
+       rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* get the register value needed for post RS BER */
+       rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* get constants needed for signal quality calculation */
+       fec_rs_period = ext_attr->fec_rs_period;
+       fec_rs_prescale = ext_attr->fec_rs_prescale;
+       rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
+       qam_vd_period = ext_attr->qam_vd_period;
+       qam_vd_prescale = ext_attr->qam_vd_prescale;
+       vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
+
+       /* DRXJ_QAM_SL_SIG_POWER_QAMxxx  * 4     */
+       switch (constellation) {
+       case DRX_CONSTELLATION_QAM16:
+               qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
+               break;
+       case DRX_CONSTELLATION_QAM32:
+               qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
+               break;
+       case DRX_CONSTELLATION_QAM64:
+               qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
+               break;
+       case DRX_CONSTELLATION_QAM128:
+               qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
+               break;
+       case DRX_CONSTELLATION_QAM256:
+               qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
+               break;
+       default:
+               return -EIO;
+       }
+
+       /* ------------------------------ */
+       /* MER Calculation                */
+       /* ------------------------------ */
+       /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
+
+       /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
+       if (qam_sl_err_power == 0)
+               qam_sl_mer = 0;
+       else
+               qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
+
+       /* ----------------------------------------- */
+       /* Pre Viterbi Symbol Error Rate Calculation */
+       /* ----------------------------------------- */
+       /* pre viterbi SER is good if it is bellow 0.025 */
+
+       /* get the register value */
+       /*   no of quadrature symbol errors */
+       rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* Extract the Exponent and the Mantisa  */
+       /* of number of quadrature symbol errors */
+       e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
+           QAM_VD_NR_QSYM_ERRORS_EXP__B;
+       m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
+           QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
+
+       if ((m << e) >> 3 > 549752)
+               qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
+       else
+               qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
+
+       /* --------------------------------------- */
+       /* pre and post RedSolomon BER Calculation */
+       /* --------------------------------------- */
+       /* pre RS BER is good if it is below 3.5e-4 */
+
+       /* get the register values */
+       pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
+       pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
+
+       /* Extract the Exponent and the Mantisa of the */
+       /* pre Reed-Solomon bit error count            */
+       e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
+           FEC_RS_NR_BIT_ERRORS_EXP__B;
+       m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
+           FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
+
+       ber_cnt = m << e;
+
+       /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
+       if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
+               qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
+       else
+               qam_pre_rs_ber = ber_cnt;
+
+       /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) /  */
+       /*               (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A)  */
+       /*
+          => c = (1000000*100*11.17)/1504 =
+          post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
+          (100 * FEC_OC_SNC_FAIL_PERIOD__A)
+          *100 and /100 is for more precision.
+          => (20 bits * 12 bits) /(16 bits * 7 bits)  => safe in 32 bits computation
+
+          Precision errors still possible.
+        */
+       e = post_bit_err_rs * 742686;
+       m = fec_oc_period * 100;
+       if (fec_oc_period == 0)
+               qam_post_rs_ber = 0xFFFFFFFF;
+       else
+               qam_post_rs_ber = e / m;
+
+       /* fill signal quality data structure */
+       p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+       p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+       p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+       p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+       p->block_error.stat[0].scale = FE_SCALE_COUNTER;
+       p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+
+       p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
+       if (ext_attr->standard == DRX_STANDARD_ITU_B) {
+               p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
+               p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
+       } else {
+               p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
+               p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
+       }
+
+       p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
+       p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
+
+       p->block_error.stat[0].uvalue += pkt_errs;
+
+#ifdef DRXJ_SIGNAL_ACCUM_ERR
+       rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+#endif
+
+       return 0;
+rw_error:
+       p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+       return -EIO;
+}
+
+#endif /* #ifndef DRXJ_VSB_ONLY */
+
+/*============================================================================*/
+/*==                     END QAM DATAPATH FUNCTIONS                         ==*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*==                       ATV DATAPATH FUNCTIONS                           ==*/
+/*============================================================================*/
+/*============================================================================*/
+
+/*
+   Implementation notes.
+
+   NTSC/FM AGCs
+
+      Four AGCs are used for NTSC:
+      (1) RF (used to attenuate the input signal in case of to much power)
+      (2) IF (used to attenuate the input signal in case of to much power)
+      (3) Video AGC (used to amplify the output signal in case input to low)
+      (4) SIF AGC (used to amplify the output signal in case input to low)
+
+      Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
+      that the coupling between Video AGC and the RF and IF AGCs also works in
+      favor of the SIF AGC.
+
+      Three AGCs are used for FM:
+      (1) RF (used to attenuate the input signal in case of to much power)
+      (2) IF (used to attenuate the input signal in case of to much power)
+      (3) SIF AGC (used to amplify the output signal in case input to low)
+
+      The SIF AGC is now coupled to the RF/IF AGCs.
+      The SIF AGC is needed for both SIF ouput and the internal SIF signal to
+      the AUD block.
+
+      RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
+      the ATV block. The AGC control algorithms are all implemented in
+      microcode.
+
+   ATV SETTINGS
+
+      (Shadow settings will not be used for now, they will be implemented
+       later on because of the schedule)
+
+      Several HW/SCU "settings" can be used for ATV. The standard selection
+      will reset most of these settings. To avoid that the end user apllication
+      has to perform these settings each time the ATV or FM standards is
+      selected the driver will shadow these settings. This enables the end user
+      to perform the settings only once after a drx_open(). The driver must
+      write the shadow settings to HW/SCU incase:
+        ( setstandard FM/ATV) ||
+        ( settings have changed && FM/ATV standard is active)
+      The shadow settings will be stored in the device specific data container.
+      A set of flags will be defined to flag changes in shadow settings.
+      A routine will be implemented to write all changed shadow settings to
+      HW/SCU.
+
+      The "settings" will consist of: AGC settings, filter settings etc.
+
+      Disadvantage of use of shadow settings:
+      Direct changes in HW/SCU registers will not be reflected in the
+      shadow settings and these changes will be overwritten during a next
+      update. This can happen during evaluation. This will not be a problem
+      for normal customer usage.
+*/
+/* -------------------------------------------------------------------------- */
+
+/**
+* \fn int power_down_atv ()
+* \brief Power down ATV.
+* \param demod instance of demodulator
+* \param standard either NTSC or FM (sub strandard for ATV )
+* \return int.
+*
+*  Stops and thus resets ATV and IQM block
+*  SIF and CVBS ADC are powered down
+*  Calls audio power down
+*/
+static int
+power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drxjscu_cmd cmd_scu = { /* command      */ 0,
+               /* parameter_len */ 0,
+               /* result_len    */ 0,
+               /* *parameter   */ NULL,
+               /* *result      */ NULL
+       };
+       int rc;
+       u16 cmd_result = 0;
+
+       /* ATV NTSC */
+
+       /* Stop ATV SCU (will reset ATV and IQM hardware */
+       cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
+           SCU_RAM_COMMAND_CMD_DEMOD_STOP;
+       cmd_scu.parameter_len = 0;
+       cmd_scu.result_len = 1;
+       cmd_scu.parameter = NULL;
+       cmd_scu.result = &cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
+       rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (primary) {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_iqm_af(demod, false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       } else {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+       rc = power_down_aud(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \brief Power up AUD.
+* \param demod instance of demodulator
+* \return int.
+*
+*/
+static int power_down_aud(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       int rc;
+
+       dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       ext_attr->aud_data.audio_is_active = false;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int set_orx_nsu_aox()
+* \brief Configure OrxNsuAox for OOB
+* \param demod instance of demodulator.
+* \param active
+* \return int.
+*/
+static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       u16 data = 0;
+
+       /* Configure NSU_AOX */
+       rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (!active)
+               data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
+       else
+               data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
+       rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/**
+* \fn int ctrl_set_oob()
+* \brief Set OOB channel to be used.
+* \param demod instance of demodulator
+* \param oob_param OOB parameters for channel setting.
+* \frequency should be in KHz
+* \return int.
+*
+* Accepts  only. Returns error otherwise.
+* Demapper value is written after scu_command START
+* because START command causes COMM_EXEC transition
+* from 0 to 1 which causes all registers to be
+* overwritten with initial value
+*
+*/
+
+/* Nyquist filter impulse response */
+#define IMPULSE_COSINE_ALPHA_0_3    {-3, -4, -1, 6, 10, 7, -5, -20, -25, -10, 29, 79, 123, 140}        /*sqrt raised-cosine filter with alpha=0.3 */
+#define IMPULSE_COSINE_ALPHA_0_5    { 2, 0, -2, -2, 2, 5, 2, -10, -20, -14, 20, 74, 125, 145}  /*sqrt raised-cosine filter with alpha=0.5 */
+#define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0, -7, -15, -16,  0, 34, 77, 114, 128}    /*full raised-cosine filter with alpha=0.5 (receiver only) */
+
+/* Coefficients for the nyquist fitler (total: 27 taps) */
+#define NYQFILTERLEN 27
+
+static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
+{
+       int rc;
+       s32 freq = 0;   /* KHz */
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       u16 i = 0;
+       bool mirror_freq_spect_oob = false;
+       u16 trk_filter_value = 0;
+       struct drxjscu_cmd scu_cmd;
+       u16 set_param_parameters[3];
+       u16 cmd_result[2] = { 0, 0 };
+       s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
+               IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 0 */
+               IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 1 */
+               IMPULSE_COSINE_ALPHA_0_5,       /* Target Mode 2 */
+               IMPULSE_COSINE_ALPHA_RO_0_5     /* Target Mode 3 */
+       };
+       u8 mode_val[4] = { 2, 2, 0, 1 };
+       u8 pfi_coeffs[4][6] = {
+               {DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)},   /* TARGET_MODE = 0:     PFI_A = -23/32; PFI_B = -54/32;  PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
+               {DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)},     /* TARGET_MODE = 1:     PFI_A = -16/32; PFI_B = -40/32;  PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
+               {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)},     /* TARGET_MODE = 2, 3:  PFI_A = -20/32; PFI_B = -49/32;  PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
+               {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}      /* TARGET_MODE = 2, 3:  PFI_A = -20/32; PFI_B = -49/32;  PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
+       };
+       u16 mode_index;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
+
+       /* Check parameters */
+       if (oob_param == NULL) {
+               /* power off oob module  */
+               scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
+                   | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
+               scu_cmd.parameter_len = 0;
+               scu_cmd.result_len = 1;
+               scu_cmd.result = cmd_result;
+               rc = scu_command(dev_addr, &scu_cmd);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_orx_nsu_aox(demod, false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               ext_attr->oob_power_on = false;
+               return 0;
+       }
+
+       freq = oob_param->frequency;
+       if ((freq < 70000) || (freq > 130000))
+               return -EIO;
+       freq = (freq - 50000) / 50;
+
+       {
+               u16 index = 0;
+               u16 remainder = 0;
+               u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
+
+               index = (u16) ((freq - 400) / 200);
+               remainder = (u16) ((freq - 400) % 200);
+               trk_filter_value =
+                   trk_filtercfg[index] - (trk_filtercfg[index] -
+                                          trk_filtercfg[index +
+                                                       1]) / 10 * remainder /
+                   20;
+       }
+
+   /*********/
+       /* Stop  */
+   /*********/
+       rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
+           | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
+       scu_cmd.parameter_len = 0;
+       scu_cmd.result_len = 1;
+       scu_cmd.result = cmd_result;
+       rc = scu_command(dev_addr, &scu_cmd);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+   /*********/
+       /* Reset */
+   /*********/
+       scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
+           | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
+       scu_cmd.parameter_len = 0;
+       scu_cmd.result_len = 1;
+       scu_cmd.result = cmd_result;
+       rc = scu_command(dev_addr, &scu_cmd);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+   /***********/
+       /* SET_ENV */
+   /***********/
+       /* set frequency, spectrum inversion and data rate */
+       scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
+           | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
+       scu_cmd.parameter_len = 3;
+       /* 1-data rate;2-frequency */
+       switch (oob_param->standard) {
+       case DRX_OOB_MODE_A:
+               if (
+                          /* signal is transmitted inverted */
+                          ((oob_param->spectrum_inverted == true) &&
+                           /* and tuner is not mirroring the signal */
+                           (!mirror_freq_spect_oob)) |
+                          /* or */
+                          /* signal is transmitted noninverted */
+                          ((oob_param->spectrum_inverted == false) &&
+                           /* and tuner is mirroring the signal */
+                           (mirror_freq_spect_oob))
+                   )
+                       set_param_parameters[0] =
+                           SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
+               else
+                       set_param_parameters[0] =
+                           SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
+               break;
+       case DRX_OOB_MODE_B_GRADE_A:
+               if (
+                          /* signal is transmitted inverted */
+                          ((oob_param->spectrum_inverted == true) &&
+                           /* and tuner is not mirroring the signal */
+                           (!mirror_freq_spect_oob)) |
+                          /* or */
+                          /* signal is transmitted noninverted */
+                          ((oob_param->spectrum_inverted == false) &&
+                           /* and tuner is mirroring the signal */
+                           (mirror_freq_spect_oob))
+                   )
+                       set_param_parameters[0] =
+                           SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
+               else
+                       set_param_parameters[0] =
+                           SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
+               break;
+       case DRX_OOB_MODE_B_GRADE_B:
+       default:
+               if (
+                          /* signal is transmitted inverted */
+                          ((oob_param->spectrum_inverted == true) &&
+                           /* and tuner is not mirroring the signal */
+                           (!mirror_freq_spect_oob)) |
+                          /* or */
+                          /* signal is transmitted noninverted */
+                          ((oob_param->spectrum_inverted == false) &&
+                           /* and tuner is mirroring the signal */
+                           (mirror_freq_spect_oob))
+                   )
+                       set_param_parameters[0] =
+                           SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
+               else
+                       set_param_parameters[0] =
+                           SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
+               break;
+       }
+       set_param_parameters[1] = (u16) (freq & 0xFFFF);
+       set_param_parameters[2] = trk_filter_value;
+       scu_cmd.parameter = set_param_parameters;
+       scu_cmd.result_len = 1;
+       scu_cmd.result = cmd_result;
+       mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
+       rc = scu_command(dev_addr, &scu_cmd);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /*  Write magic word to enable pdr reg write  */
+       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }       /*  Write magic word to disable pdr reg write */
+
+       rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* ddc */
+       rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* nsu */
+       rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* initialization for target mode */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Reset bits for timing and freq. recovery */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* TIM_LOCK = {300,      -2048, 8, -8, 0, 1<<4}; */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* EQU_LOCK = {20,      -2048, 8, -8, 0, 1<<5}; */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* PRE-Filter coefficients (PFI) */
+       rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* NYQUIST-Filter coefficients (NYQ) */
+       for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
+               rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+       rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /*********/
+       /* Start */
+       /*********/
+       scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
+           | SCU_RAM_COMMAND_CMD_DEMOD_START;
+       scu_cmd.parameter_len = 0;
+       scu_cmd.result_len = 1;
+       scu_cmd.result = cmd_result;
+       rc = scu_command(dev_addr, &scu_cmd);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = set_orx_nsu_aox(demod, true);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       ext_attr->oob_power_on = true;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+/*==                     END OOB DATAPATH FUNCTIONS                         ==*/
+/*============================================================================*/
+
+/*=============================================================================
+  ===== MC command related functions ==========================================
+  ===========================================================================*/
+
+/*=============================================================================
+  ===== ctrl_set_channel() ==========================================================
+  ===========================================================================*/
+/**
+* \fn int ctrl_set_channel()
+* \brief Select a new transmission channel.
+* \param demod instance of demod.
+* \param channel Pointer to channel data.
+* \return int.
+*
+* In case the tuner module is not used and in case of NTSC/FM the pogrammer
+* must tune the tuner to the centre frequency of the NTSC/FM channel.
+*
+*/
+static int
+ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
+{
+       int rc;
+       s32 tuner_freq_offset = 0;
+       struct drxj_data *ext_attr = NULL;
+       struct i2c_device_addr *dev_addr = NULL;
+       enum drx_standard standard = DRX_STANDARD_UNKNOWN;
+#ifndef DRXJ_VSB_ONLY
+       u32 min_symbol_rate = 0;
+       u32 max_symbol_rate = 0;
+       int bandwidth_temp = 0;
+       int bandwidth = 0;
+#endif
+   /*== check arguments ======================================================*/
+       if ((demod == NULL) || (channel == NULL))
+               return -EINVAL;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       standard = ext_attr->standard;
+
+       /* check valid standards */
+       switch (standard) {
+       case DRX_STANDARD_8VSB:
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_B:
+       case DRX_STANDARD_ITU_C:
+#endif /* DRXJ_VSB_ONLY */
+               break;
+       case DRX_STANDARD_UNKNOWN:
+       default:
+               return -EINVAL;
+       }
+
+       /* check bandwidth QAM annex B, NTSC and 8VSB */
+       if ((standard == DRX_STANDARD_ITU_B) ||
+           (standard == DRX_STANDARD_8VSB) ||
+           (standard == DRX_STANDARD_NTSC)) {
+               switch (channel->bandwidth) {
+               case DRX_BANDWIDTH_6MHZ:
+               case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
+                       channel->bandwidth = DRX_BANDWIDTH_6MHZ;
+                       break;
+               case DRX_BANDWIDTH_8MHZ:        /* fall through */
+               case DRX_BANDWIDTH_7MHZ:        /* fall through */
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /* For QAM annex A and annex C:
+          -check symbolrate and constellation
+          -derive bandwidth from symbolrate (input bandwidth is ignored)
+        */
+#ifndef DRXJ_VSB_ONLY
+       if ((standard == DRX_STANDARD_ITU_A) ||
+           (standard == DRX_STANDARD_ITU_C)) {
+               struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
+               int bw_rolloff_factor = 0;
+
+               bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
+               min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
+               max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
+               /* config SMA_TX pin to SAW switch mode */
+               rc = ctrl_set_uio_cfg(demod, &uio_cfg);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               if (channel->symbolrate < min_symbol_rate ||
+                   channel->symbolrate > max_symbol_rate) {
+                       return -EINVAL;
+               }
+
+               switch (channel->constellation) {
+               case DRX_CONSTELLATION_QAM16:   /* fall through */
+               case DRX_CONSTELLATION_QAM32:   /* fall through */
+               case DRX_CONSTELLATION_QAM64:   /* fall through */
+               case DRX_CONSTELLATION_QAM128:  /* fall through */
+               case DRX_CONSTELLATION_QAM256:
+                       bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
+                       bandwidth = bandwidth_temp / 100;
+
+                       if ((bandwidth_temp % 100) >= 50)
+                               bandwidth++;
+
+                       if (bandwidth <= 6100000) {
+                               channel->bandwidth = DRX_BANDWIDTH_6MHZ;
+                       } else if ((bandwidth > 6100000)
+                                  && (bandwidth <= 7100000)) {
+                               channel->bandwidth = DRX_BANDWIDTH_7MHZ;
+                       } else if (bandwidth > 7100000) {
+                               channel->bandwidth = DRX_BANDWIDTH_8MHZ;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /* For QAM annex B:
+          -check constellation
+        */
+       if (standard == DRX_STANDARD_ITU_B) {
+               switch (channel->constellation) {
+               case DRX_CONSTELLATION_AUTO:
+               case DRX_CONSTELLATION_QAM256:
+               case DRX_CONSTELLATION_QAM64:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               switch (channel->interleavemode) {
+               case DRX_INTERLEAVEMODE_I128_J1:
+               case DRX_INTERLEAVEMODE_I128_J1_V2:
+               case DRX_INTERLEAVEMODE_I128_J2:
+               case DRX_INTERLEAVEMODE_I64_J2:
+               case DRX_INTERLEAVEMODE_I128_J3:
+               case DRX_INTERLEAVEMODE_I32_J4:
+               case DRX_INTERLEAVEMODE_I128_J4:
+               case DRX_INTERLEAVEMODE_I16_J8:
+               case DRX_INTERLEAVEMODE_I128_J5:
+               case DRX_INTERLEAVEMODE_I8_J16:
+               case DRX_INTERLEAVEMODE_I128_J6:
+               case DRX_INTERLEAVEMODE_I128_J7:
+               case DRX_INTERLEAVEMODE_I128_J8:
+               case DRX_INTERLEAVEMODE_I12_J17:
+               case DRX_INTERLEAVEMODE_I5_J4:
+               case DRX_INTERLEAVEMODE_B52_M240:
+               case DRX_INTERLEAVEMODE_B52_M720:
+               case DRX_INTERLEAVEMODE_UNKNOWN:
+               case DRX_INTERLEAVEMODE_AUTO:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
+               /* SAW SW, user UIO is used for switchable SAW */
+               struct drxuio_data uio1 = { DRX_UIO1, false };
+
+               switch (channel->bandwidth) {
+               case DRX_BANDWIDTH_8MHZ:
+                       uio1.value = true;
+                       break;
+               case DRX_BANDWIDTH_7MHZ:
+                       uio1.value = false;
+                       break;
+               case DRX_BANDWIDTH_6MHZ:
+                       uio1.value = false;
+                       break;
+               case DRX_BANDWIDTH_UNKNOWN:
+               default:
+                       return -EINVAL;
+               }
+
+               rc = ctrl_uio_write(demod, &uio1);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+#endif /* DRXJ_VSB_ONLY */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       tuner_freq_offset = 0;
+
+   /*== Setup demod for specific standard ====================================*/
+       switch (standard) {
+       case DRX_STANDARD_8VSB:
+               if (channel->mirror == DRX_MIRROR_AUTO)
+                       ext_attr->mirror = DRX_MIRROR_NO;
+               else
+                       ext_attr->mirror = channel->mirror;
+               rc = set_vsb(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = set_frequency(demod, channel, tuner_freq_offset);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:
+               rc = set_qam_channel(demod, channel, tuner_freq_offset);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+#endif
+       case DRX_STANDARD_UNKNOWN:
+       default:
+               return -EIO;
+       }
+
+       /* flag the packet error counter reset */
+       ext_attr->reset_pkt_err_acc = true;
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*=============================================================================
+  ===== SigQuality() ==========================================================
+  ===========================================================================*/
+
+/**
+* \fn int ctrl_sig_quality()
+* \brief Retreive signal quality form device.
+* \param devmod Pointer to demodulator instance.
+* \param sig_quality Pointer to signal quality data.
+* \return int.
+* \retval 0 sig_quality contains valid data.
+* \retval -EINVAL sig_quality is NULL.
+* \retval -EIO Erroneous data, sig_quality contains invalid data.
+
+*/
+static int
+ctrl_sig_quality(struct drx_demod_instance *demod,
+                enum drx_lock_status lock_status)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       struct drx39xxj_state *state = dev_addr->user_data;
+       struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
+       enum drx_standard standard = ext_attr->standard;
+       int rc;
+       u32 ber, cnt, err, pkt;
+       u16 mer, strength;
+
+       rc = get_sig_strength(demod, &strength);
+       if (rc < 0) {
+               pr_err("error getting signal strength %d\n", rc);
+               p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       } else {
+               p->strength.stat[0].scale = FE_SCALE_RELATIVE;
+               p->strength.stat[0].uvalue = 65535UL *  strength/ 100;
+       }
+
+       switch (standard) {
+       case DRX_STANDARD_8VSB:
+#ifdef DRXJ_SIGNAL_ACCUM_ERR
+               rc = get_acc_pkt_err(demod, &pkt);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+#endif
+               if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
+                       p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+               } else {
+                       rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
+                       if (rc != 0) {
+                               pr_err("error %d getting UCB\n", rc);
+                               p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       } else {
+                               p->block_error.stat[0].scale = FE_SCALE_COUNTER;
+                               p->block_error.stat[0].uvalue += err;
+                               p->block_count.stat[0].scale = FE_SCALE_COUNTER;
+                               p->block_count.stat[0].uvalue += pkt;
+                       }
+
+                       /* PostViterbi is compute in steps of 10^(-6) */
+                       rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
+                       if (rc != 0) {
+                               pr_err("error %d getting pre-ber\n", rc);
+                               p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       } else {
+                               p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+                               p->pre_bit_error.stat[0].uvalue += ber;
+                               p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+                               p->pre_bit_count.stat[0].uvalue += cnt;
+                       }
+
+                       rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
+                       if (rc != 0) {
+                               pr_err("error %d getting post-ber\n", rc);
+                               p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       } else {
+                               p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+                               p->post_bit_error.stat[0].uvalue += ber;
+                               p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+                               p->post_bit_count.stat[0].uvalue += cnt;
+                       }
+                       rc = get_vsbmer(dev_addr, &mer);
+                       if (rc != 0) {
+                               pr_err("error %d getting MER\n", rc);
+                               p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+                       } else {
+                               p->cnr.stat[0].svalue = mer * 100;
+                               p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+                       }
+               }
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_B:
+       case DRX_STANDARD_ITU_C:
+               rc = ctrl_get_qam_sig_quality(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+#endif
+       default:
+               return -EIO;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int ctrl_lock_status()
+* \brief Retreive lock status .
+* \param dev_addr Pointer to demodulator device address.
+* \param lock_stat Pointer to lock status structure.
+* \return int.
+*
+*/
+static int
+ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
+{
+       enum drx_standard standard = DRX_STANDARD_UNKNOWN;
+       struct drxj_data *ext_attr = NULL;
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxjscu_cmd cmd_scu = { /* command      */ 0,
+               /* parameter_len */ 0,
+               /* result_len    */ 0,
+               /* *parameter   */ NULL,
+               /* *result      */ NULL
+       };
+       int rc;
+       u16 cmd_result[2] = { 0, 0 };
+       u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
+
+       /* check arguments */
+       if ((demod == NULL) || (lock_stat == NULL))
+               return -EINVAL;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       standard = ext_attr->standard;
+
+       *lock_stat = DRX_NOT_LOCKED;
+
+       /* define the SCU command code */
+       switch (standard) {
+       case DRX_STANDARD_8VSB:
+               cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
+                   SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
+               demod_lock |= 0x6;
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:
+       case DRX_STANDARD_ITU_B:
+       case DRX_STANDARD_ITU_C:
+               cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
+                   SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
+               break;
+#endif
+       case DRX_STANDARD_UNKNOWN:      /* fallthrough */
+       default:
+               return -EIO;
+       }
+
+       /* define the SCU command paramters and execute the command */
+       cmd_scu.parameter_len = 0;
+       cmd_scu.result_len = 2;
+       cmd_scu.parameter = NULL;
+       cmd_scu.result = cmd_result;
+       rc = scu_command(dev_addr, &cmd_scu);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* set the lock status */
+       if (cmd_scu.result[1] < demod_lock) {
+               /* 0x0000 NOT LOCKED */
+               *lock_stat = DRX_NOT_LOCKED;
+       } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
+               *lock_stat = DRXJ_DEMOD_LOCK;
+       } else if (cmd_scu.result[1] <
+                  SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
+               /* 0x8000 DEMOD + FEC LOCKED (system lock) */
+               *lock_stat = DRX_LOCKED;
+       } else {
+               /* 0xC000 NEVER LOCKED */
+               /* (system will never be able to lock to the signal) */
+               *lock_stat = DRX_NEVER_LOCK;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int ctrl_set_standard()
+* \brief Set modulation standard to be used.
+* \param standard Modulation standard.
+* \return int.
+*
+* Setup stuff for the desired demodulation standard.
+* Disable and power down the previous selected demodulation standard
+*
+*/
+static int
+ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
+{
+       struct drxj_data *ext_attr = NULL;
+       int rc;
+       enum drx_standard prev_standard;
+
+       /* check arguments */
+       if ((standard == NULL) || (demod == NULL))
+               return -EINVAL;
+
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       prev_standard = ext_attr->standard;
+
+       /*
+          Stop and power down previous standard
+        */
+       switch (prev_standard) {
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:
+               rc = power_down_qam(demod, false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+#endif
+       case DRX_STANDARD_8VSB:
+               rc = power_down_vsb(demod, false);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+       case DRX_STANDARD_UNKNOWN:
+               /* Do nothing */
+               break;
+       case DRX_STANDARD_AUTO: /* fallthrough */
+       default:
+               return -EINVAL;
+       }
+
+       /*
+          Initialize channel independent registers
+          Power up new standard
+        */
+       ext_attr->standard = *standard;
+
+       switch (*standard) {
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:
+               do {
+                       u16 dummy;
+                       rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               } while (0);
+               break;
+#endif
+       case DRX_STANDARD_8VSB:
+               rc = set_vsb_leak_n_gain(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               break;
+       default:
+               ext_attr->standard = DRX_STANDARD_UNKNOWN;
+               return -EINVAL;
+               break;
+       }
+
+       return 0;
+rw_error:
+       /* Don't know what the standard is now ... try again */
+       ext_attr->standard = DRX_STANDARD_UNKNOWN;
+       return -EIO;
+}
+
+/*============================================================================*/
+
+static void drxj_reset_mode(struct drxj_data *ext_attr)
+{
+       /* Initialize default AFE configuartion for QAM */
+       if (ext_attr->has_lna) {
+               /* IF AGC off, PGA active */
+#ifndef DRXJ_VSB_ONLY
+               ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
+               ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
+               ext_attr->qam_pga_cfg = 140 + (11 * 13);
+#endif
+               ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
+               ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
+               ext_attr->vsb_pga_cfg = 140 + (11 * 13);
+       } else {
+               /* IF AGC on, PGA not active */
+#ifndef DRXJ_VSB_ONLY
+               ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
+               ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
+               ext_attr->qam_if_agc_cfg.min_output_level = 0;
+               ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
+               ext_attr->qam_if_agc_cfg.speed = 3;
+               ext_attr->qam_if_agc_cfg.top = 1297;
+               ext_attr->qam_pga_cfg = 140;
+#endif
+               ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
+               ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
+               ext_attr->vsb_if_agc_cfg.min_output_level = 0;
+               ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
+               ext_attr->vsb_if_agc_cfg.speed = 3;
+               ext_attr->vsb_if_agc_cfg.top = 1024;
+               ext_attr->vsb_pga_cfg = 140;
+       }
+       /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
+       /* mc has not used them */
+#ifndef DRXJ_VSB_ONLY
+       ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
+       ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
+       ext_attr->qam_rf_agc_cfg.min_output_level = 0;
+       ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
+       ext_attr->qam_rf_agc_cfg.speed = 3;
+       ext_attr->qam_rf_agc_cfg.top = 9500;
+       ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
+       ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
+       ext_attr->qam_pre_saw_cfg.reference = 0x07;
+       ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
+#endif
+       /* Initialize default AFE configuartion for VSB */
+       ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
+       ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
+       ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
+       ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
+       ext_attr->vsb_rf_agc_cfg.speed = 3;
+       ext_attr->vsb_rf_agc_cfg.top = 9500;
+       ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
+       ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
+       ext_attr->vsb_pre_saw_cfg.reference = 0x07;
+       ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
+}
+
+/**
+* \fn int ctrl_power_mode()
+* \brief Set the power mode of the device to the specified power mode
+* \param demod Pointer to demodulator instance.
+* \param mode  Pointer to new power mode.
+* \return int.
+* \retval 0          Success
+* \retval -EIO       I2C error or other failure
+* \retval -EINVAL Invalid mode argument.
+*
+*
+*/
+static int
+ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
+{
+       struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
+       struct drxj_data *ext_attr = (struct drxj_data *) NULL;
+       struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
+       int rc;
+       u16 sio_cc_pwd_mode = 0;
+
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       dev_addr = demod->my_i2c_dev_addr;
+
+       /* Check arguments */
+       if (mode == NULL)
+               return -EINVAL;
+
+       /* If already in requested power mode, do nothing */
+       if (common_attr->current_power_mode == *mode)
+               return 0;
+
+       switch (*mode) {
+       case DRX_POWER_UP:
+       case DRXJ_POWER_DOWN_MAIN_PATH:
+               sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
+               break;
+       case DRXJ_POWER_DOWN_CORE:
+               sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
+               break;
+       case DRXJ_POWER_DOWN_PLL:
+               sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
+               break;
+       case DRX_POWER_DOWN:
+               sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
+               break;
+       default:
+               /* Unknow sleep mode */
+               return -EINVAL;
+               break;
+       }
+
+       /* Check if device needs to be powered up */
+       if ((common_attr->current_power_mode != DRX_POWER_UP)) {
+               rc = power_up_device(demod);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       if ((*mode == DRX_POWER_UP)) {
+               /* Restore analog & pin configuartion */
+
+               /* Initialize default AFE configuartion for VSB */
+               drxj_reset_mode(ext_attr);
+       } else {
+               /* Power down to requested mode */
+               /* Backup some register settings */
+               /* Set pins with possible pull-ups connected to them in input mode */
+               /* Analog power down */
+               /* ADC power down */
+               /* Power down device */
+               /* stop all comm_exec */
+               /*
+                  Stop and power down previous standard
+                */
+
+               switch (ext_attr->standard) {
+               case DRX_STANDARD_ITU_A:
+               case DRX_STANDARD_ITU_B:
+               case DRX_STANDARD_ITU_C:
+                       rc = power_down_qam(demod, true);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_STANDARD_8VSB:
+                       rc = power_down_vsb(demod, true);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
+               case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
+               case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
+               case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
+               case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
+               case DRX_STANDARD_NTSC: /* fallthrough */
+               case DRX_STANDARD_FM:
+                       rc = power_down_atv(demod, ext_attr->standard, true);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+                       break;
+               case DRX_STANDARD_UNKNOWN:
+                       /* Do nothing */
+                       break;
+               case DRX_STANDARD_AUTO: /* fallthrough */
+               default:
+                       return -EIO;
+               }
+               ext_attr->standard = DRX_STANDARD_UNKNOWN;
+       }
+
+       if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
+               rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+               rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+
+               if ((*mode != DRX_POWER_UP)) {
+                       /* Initialize HI, wakeup key especially before put IC to sleep */
+                       rc = init_hi(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+
+                       ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+                       rc = hi_cfg_command(demod);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+       }
+
+       common_attr->current_power_mode = *mode;
+
+       return 0;
+rw_error:
+       return rc;
+}
+
+/*============================================================================*/
+/*== CTRL Set/Get Config related functions ===================================*/
+/*============================================================================*/
+
+/**
+* \fn int ctrl_set_cfg_pre_saw()
+* \brief Set Pre-saw reference.
+* \param demod demod instance
+* \param u16 *
+* \return int.
+*
+* Check arguments
+* Dispatch handling to standard specific function.
+*
+*/
+static int
+ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       int rc;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       /* check arguments */
+       if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
+           ) {
+               return -EINVAL;
+       }
+
+       /* Only if standard is currently active */
+       if ((ext_attr->standard == pre_saw->standard) ||
+           (DRXJ_ISQAMSTD(ext_attr->standard) &&
+            DRXJ_ISQAMSTD(pre_saw->standard)) ||
+           (DRXJ_ISATVSTD(ext_attr->standard) &&
+            DRXJ_ISATVSTD(pre_saw->standard))) {
+               rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
+               if (rc != 0) {
+                       pr_err("error %d\n", rc);
+                       goto rw_error;
+               }
+       }
+
+       /* Store pre-saw settings */
+       switch (pre_saw->standard) {
+       case DRX_STANDARD_8VSB:
+               ext_attr->vsb_pre_saw_cfg = *pre_saw;
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:
+               ext_attr->qam_pre_saw_cfg = *pre_saw;
+               break;
+#endif
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+/**
+* \fn int ctrl_set_cfg_afe_gain()
+* \brief Set AFE Gain.
+* \param demod demod instance
+* \param u16 *
+* \return int.
+*
+* Check arguments
+* Dispatch handling to standard specific function.
+*
+*/
+static int
+ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       int rc;
+       u8 gain = 0;
+
+       /* check arguments */
+       if (afe_gain == NULL)
+               return -EINVAL;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+
+       switch (afe_gain->standard) {
+       case DRX_STANDARD_8VSB: /* fallthrough */
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:
+#endif
+               /* Do nothing */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
+          So I (PJ) think interface requires choice between auto, user mode */
+
+       if (afe_gain->gain >= 329)
+               gain = 15;
+       else if (afe_gain->gain <= 147)
+               gain = 0;
+       else
+               gain = (afe_gain->gain - 140 + 6) / 13;
+
+       /* Only if standard is currently active */
+       if (ext_attr->standard == afe_gain->standard) {
+                       rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
+                       if (rc != 0) {
+                               pr_err("error %d\n", rc);
+                               goto rw_error;
+                       }
+               }
+
+       /* Store AFE Gain settings */
+       switch (afe_gain->standard) {
+       case DRX_STANDARD_8VSB:
+               ext_attr->vsb_pga_cfg = gain * 13 + 140;
+               break;
+#ifndef DRXJ_VSB_ONLY
+       case DRX_STANDARD_ITU_A:        /* fallthrough */
+       case DRX_STANDARD_ITU_B:        /* fallthrough */
+       case DRX_STANDARD_ITU_C:
+               ext_attr->qam_pga_cfg = gain * 13 + 140;
+               break;
+#endif
+       default:
+               return -EIO;
+       }
+
+       return 0;
+rw_error:
+       return -EIO;
+}
+
+/*============================================================================*/
+
+
+/*=============================================================================
+===== EXPORTED FUNCTIONS ====================================================*/
+
+static int drx_ctrl_u_code(struct drx_demod_instance *demod,
+                      struct drxu_code_info *mc_info,
+                      enum drxu_code_action action);
+
+/**
+* \fn drxj_open()
+* \brief Open the demod instance, configure device, configure drxdriver
+* \return Status_t Return status.
+*
+* drxj_open() can be called with a NULL ucode image => no ucode upload.
+* This means that drxj_open() must NOT contain SCU commands or, in general,
+* rely on SCU or AUD ucode to be present.
+*
+*/
+
+static int drxj_open(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = NULL;
+       struct drxj_data *ext_attr = NULL;
+       struct drx_common_attr *common_attr = NULL;
+       u32 driver_version = 0;
+       struct drxu_code_info ucode_info;
+       struct drx_cfg_mpeg_output cfg_mpeg_output;
+       int rc;
+       enum drx_power_mode power_mode = DRX_POWER_UP;
+
+       if ((demod == NULL) ||
+           (demod->my_common_attr == NULL) ||
+           (demod->my_ext_attr == NULL) ||
+           (demod->my_i2c_dev_addr == NULL) ||
+           (demod->my_common_attr->is_opened)) {
+               return -EINVAL;
+       }
+
+       /* Check arguments */
+       if (demod->my_ext_attr == NULL)
+               return -EINVAL;
+
+       dev_addr = demod->my_i2c_dev_addr;
+       ext_attr = (struct drxj_data *) demod->my_ext_attr;
+       common_attr = (struct drx_common_attr *) demod->my_common_attr;
+
+       rc = ctrl_power_mode(demod, &power_mode);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       if (power_mode != DRX_POWER_UP) {
+               rc = -EINVAL;
+               pr_err("failed to powerup device\n");
+               goto rw_error;
+       }
+
+       /* has to be in front of setIqmAf and setOrxNsuAox */
+       rc = get_device_capabilities(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /*
+        * Soft reset of sys- and osc-clockdomain
+        *
+        * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
+        * As we didn't load the firmware here yet, we should do the same.
+        * Btw, this is coherent with DRX-K, where we send reset codes
+        * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
+        */
+       rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       msleep(1);
+
+       /* TODO first make sure that everything keeps working before enabling this */
+       /* PowerDownAnalogBlocks() */
+       rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = set_iqm_af(demod, false);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = set_orx_nsu_aox(demod, false);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = init_hi(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* disable mpegoutput pins */
+       memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
+       cfg_mpeg_output.enable_mpeg_output = false;
+
+       rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* Stop AUD Inform SetAudio it will need to do all setting */
+       rc = power_down_aud(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       /* Stop SCU */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Upload microcode */
+       if (common_attr->microcode_file != NULL) {
+               /* Dirty trick to use common ucode upload & verify,
+                  pretend device is already open */
+               common_attr->is_opened = true;
+               ucode_info.mc_file = common_attr->microcode_file;
+
+               if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
+                       pr_err("Should powerup before loading the firmware.");
+                       return -EINVAL;
+               }
+
+               rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
+               if (rc != 0) {
+                       pr_err("error %d while uploading the firmware\n", rc);
+                       goto rw_error;
+               }
+               if (common_attr->verify_microcode == true) {
+                       rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
+                       if (rc != 0) {
+                               pr_err("error %d while verifying the firmware\n",
+                                      rc);
+                               goto rw_error;
+                       }
+               }
+               common_attr->is_opened = false;
+       }
+
+       /* Run SCU for a little while to initialize microcode version numbers */
+       rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Initialize scan timeout */
+       common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
+       common_attr->scan_desired_lock = DRX_LOCKED;
+
+       drxj_reset_mode(ext_attr);
+       ext_attr->standard = DRX_STANDARD_UNKNOWN;
+
+       rc = smart_ant_init(demod);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* Stamp driver version number in SCU data RAM in BCD code
+          Done to enable field application engineers to retreive drxdriver version
+          via I2C from SCU RAM
+        */
+       driver_version = (VERSION_MAJOR / 100) % 10;
+       driver_version <<= 4;
+       driver_version += (VERSION_MAJOR / 10) % 10;
+       driver_version <<= 4;
+       driver_version += (VERSION_MAJOR % 10);
+       driver_version <<= 4;
+       driver_version += (VERSION_MINOR % 10);
+       driver_version <<= 4;
+       driver_version += (VERSION_PATCH / 1000) % 10;
+       driver_version <<= 4;
+       driver_version += (VERSION_PATCH / 100) % 10;
+       driver_version <<= 4;
+       driver_version += (VERSION_PATCH / 10) % 10;
+       driver_version <<= 4;
+       driver_version += (VERSION_PATCH % 10);
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = ctrl_set_oob(demod, NULL);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       /* refresh the audio data structure with default */
+       ext_attr->aud_data = drxj_default_aud_data_g;
+
+       demod->my_common_attr->is_opened = true;
+       return 0;
+rw_error:
+       common_attr->is_opened = false;
+       return -EIO;
+}
+
+/*============================================================================*/
+/**
+* \fn drxj_close()
+* \brief Close the demod instance, power down the device
+* \return Status_t Return status.
+*
+*/
+static int drxj_close(struct drx_demod_instance *demod)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       enum drx_power_mode power_mode = DRX_POWER_UP;
+
+       if ((demod->my_common_attr == NULL) ||
+           (demod->my_ext_attr == NULL) ||
+           (demod->my_i2c_dev_addr == NULL) ||
+           (!demod->my_common_attr->is_opened)) {
+               return -EINVAL;
+       }
+
+       /* power up */
+       rc = ctrl_power_mode(demod, &power_mode);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+       power_mode = DRX_POWER_DOWN;
+       rc = ctrl_power_mode(demod, &power_mode);
+       if (rc != 0) {
+               pr_err("error %d\n", rc);
+               goto rw_error;
+       }
+
+       DRX_ATTR_ISOPENED(demod) = false;
+
+       return 0;
+rw_error:
+       DRX_ATTR_ISOPENED(demod) = false;
+
+       return -EIO;
+}
+
+/*
+ * Microcode related functions
+ */
+
+/**
+ * drx_u_code_compute_crc      - Compute CRC of block of microcode data.
+ * @block_data: Pointer to microcode data.
+ * @nr_words:   Size of microcode block (number of 16 bits words).
+ *
+ * returns The computed CRC residue.
+ */
+static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
+{
+       u16 i = 0;
+       u16 j = 0;
+       u32 crc_word = 0;
+       u32 carry = 0;
+
+       while (i < nr_words) {
+               crc_word |= (u32)be16_to_cpu(*(u32 *)(block_data));
+               for (j = 0; j < 16; j++) {
+                       crc_word <<= 1;
+                       if (carry != 0)
+                               crc_word ^= 0x80050000UL;
+                       carry = crc_word & 0x80000000UL;
+               }
+               i++;
+               block_data += (sizeof(u16));
+       }
+       return (u16)(crc_word >> 16);
+}
+
+/**
+ * drx_check_firmware - checks if the loaded firmware is valid
+ *
+ * @demod:     demod structure
+ * @mc_data:   pointer to the start of the firmware
+ * @size:      firmware size
+ */
+static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
+                         unsigned size)
+{
+       struct drxu_code_block_hdr block_hdr;
+       int i;
+       unsigned count = 2 * sizeof(u16);
+       u32 mc_dev_type, mc_version, mc_base_version;
+       u16 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data + sizeof(u16)));
+
+       /*
+        * Scan microcode blocks first for version info
+        * and firmware check
+        */
+
+       /* Clear version block */
+       DRX_ATTR_MCRECORD(demod).aux_type = 0;
+       DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
+       DRX_ATTR_MCRECORD(demod).mc_version = 0;
+       DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
+
+       for (i = 0; i < mc_nr_of_blks; i++) {
+               if (count + 3 * sizeof(u16) + sizeof(u32) > size)
+                       goto eof;
+
+               /* Process block header */
+               block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data + count));
+               count += sizeof(u32);
+               block_hdr.size = be16_to_cpu(*(u32 *)(mc_data + count));
+               count += sizeof(u16);
+               block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data + count));
+               count += sizeof(u16);
+               block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data + count));
+               count += sizeof(u16);
+
+               pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
+                       count, block_hdr.addr, block_hdr.size, block_hdr.flags,
+                       block_hdr.CRC);
+
+               if (block_hdr.flags & 0x8) {
+                       u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
+                       u16 auxtype;
+
+                       if (block_hdr.addr + sizeof(u16) > size)
+                               goto eof;
+
+                       auxtype = be16_to_cpu(*(u32 *)(auxblk));
+
+                       /* Aux block. Check type */
+                       if (DRX_ISMCVERTYPE(auxtype)) {
+                               if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
+                                       goto eof;
+
+                               auxblk += sizeof(u16);
+                               mc_dev_type = be32_to_cpu(*(u32 *)(auxblk));
+                               auxblk += sizeof(u32);
+                               mc_version = be32_to_cpu(*(u32 *)(auxblk));
+                               auxblk += sizeof(u32);
+                               mc_base_version = be32_to_cpu(*(u32 *)(auxblk));
+
+                               DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
+                               DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
+                               DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
+                               DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
+
+                               pr_info("Firmware dev %x, ver %x, base ver %x\n",
+                                       mc_dev_type, mc_version, mc_base_version);
+
+                       }
+               } else if (count + block_hdr.size * sizeof(u16) > size)
+                       goto eof;
+
+               count += block_hdr.size * sizeof(u16);
+       }
+       return 0;
+eof:
+       pr_err("Firmware is truncated at pos %u/%u\n", count, size);
+       return -EINVAL;
+}
+
+/**
+ * drx_ctrl_u_code - Handle microcode upload or verify.
+ * @dev_addr: Address of device.
+ * @mc_info:  Pointer to information about microcode data.
+ * @action:  Either UCODE_UPLOAD or UCODE_VERIFY
+ *
+ * This function returns:
+ *     0:
+ *             - In case of UCODE_UPLOAD: code is successfully uploaded.
+ *               - In case of UCODE_VERIFY: image on device is equal to
+ *               image provided to this control function.
+ *     -EIO:
+ *             - In case of UCODE_UPLOAD: I2C error.
+ *             - In case of UCODE_VERIFY: I2C error or image on device
+ *               is not equal to image provided to this control function.
+ *     -EINVAL:
+ *             - Invalid arguments.
+ *             - Provided image is corrupt
+ */
+static int drx_ctrl_u_code(struct drx_demod_instance *demod,
+                      struct drxu_code_info *mc_info,
+                      enum drxu_code_action action)
+{
+       struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
+       int rc;
+       u16 i = 0;
+       u16 mc_nr_of_blks = 0;
+       u16 mc_magic_word = 0;
+       const u8 *mc_data_init = NULL;
+       u8 *mc_data = NULL;
+       unsigned size;
+       char *mc_file;
+
+       /* Check arguments */
+       if (!mc_info || !mc_info->mc_file)
+               return -EINVAL;
+
+       mc_file = mc_info->mc_file;
+
+       if (!demod->firmware) {
+               const struct firmware *fw = NULL;
+
+               rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
+               if (rc < 0) {
+                       pr_err("Couldn't read firmware %s\n", mc_file);
+                       return rc;
+               }
+               demod->firmware = fw;
+
+               if (demod->firmware->size < 2 * sizeof(u16)) {
+                       rc = -EINVAL;
+                       pr_err("Firmware is too short!\n");
+                       goto release;
+               }
+
+               pr_info("Firmware %s, size %zu\n",
+                       mc_file, demod->firmware->size);
+       }
+
+       mc_data_init = demod->firmware->data;
+       size = demod->firmware->size;
+
+       mc_data = (void *)mc_data_init;
+       /* Check data */
+       mc_magic_word = be16_to_cpu(*(u32 *)(mc_data));
+       mc_data += sizeof(u16);
+       mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data));
+       mc_data += sizeof(u16);
+
+       if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
+               rc = -EINVAL;
+               pr_err("Firmware magic word doesn't match\n");
+               goto release;
+       }
+
+       if (action == UCODE_UPLOAD) {
+               rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
+               if (rc)
+                       goto release;
+               pr_info("Uploading firmware %s\n", mc_file);
+       } else {
+               pr_info("Verifying if firmware upload was ok.\n");
+       }
+
+       /* Process microcode blocks */
+       for (i = 0; i < mc_nr_of_blks; i++) {
+               struct drxu_code_block_hdr block_hdr;
+               u16 mc_block_nr_bytes = 0;
+
+               /* Process block header */
+               block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data));
+               mc_data += sizeof(u32);
+               block_hdr.size = be16_to_cpu(*(u32 *)(mc_data));
+               mc_data += sizeof(u16);
+               block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data));
+               mc_data += sizeof(u16);
+               block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data));
+               mc_data += sizeof(u16);
+
+               pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
+                       (unsigned)(mc_data - mc_data_init), block_hdr.addr,
+                        block_hdr.size, block_hdr.flags, block_hdr.CRC);
+
+               /* Check block header on:
+                  - data larger than 64Kb
+                  - if CRC enabled check CRC
+                */
+               if ((block_hdr.size > 0x7FFF) ||
+                   (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
+                    (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
+                   ) {
+                       /* Wrong data ! */
+                       rc = -EINVAL;
+                       pr_err("firmware CRC is wrong\n");
+                       goto release;
+               }
+
+               if (!block_hdr.size)
+                       continue;
+
+               mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
+
+               /* Perform the desired action */
+               switch (action) {
+               case UCODE_UPLOAD:      /* Upload microcode */
+                       if (drxdap_fasi_write_block(dev_addr,
+                                                       block_hdr.addr,
+                                                       mc_block_nr_bytes,
+                                                       mc_data, 0x0000)) {
+                               rc = -EIO;
+                               pr_err("error writing firmware at pos %u\n",
+                                      (unsigned)(mc_data - mc_data_init));
+                               goto release;
+                       }
+                       break;
+               case UCODE_VERIFY: {    /* Verify uploaded microcode */
+                       int result = 0;
+                       u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
+                       u32 bytes_to_comp = 0;
+                       u32 bytes_left = mc_block_nr_bytes;
+                       u32 curr_addr = block_hdr.addr;
+                       u8 *curr_ptr = mc_data;
+
+                       while (bytes_left != 0) {
+                               if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
+                                       bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
+                               else
+                                       bytes_to_comp = bytes_left;
+
+                               if (drxdap_fasi_read_block(dev_addr,
+                                                   curr_addr,
+                                                   (u16)bytes_to_comp,
+                                                   (u8 *)mc_data_buffer,
+                                                   0x0000)) {
+                                       pr_err("error reading firmware at pos %u\n",
+                                              (unsigned)(mc_data - mc_data_init));
+                                       return -EIO;
+                               }
+
+                               result = memcmp(curr_ptr, mc_data_buffer,
+                                               bytes_to_comp);
+
+                               if (result) {
+                                       pr_err("error verifying firmware at pos %u\n",
+                                              (unsigned)(mc_data - mc_data_init));
+                                       return -EIO;
+                               }
+
+                               curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
+                               curr_ptr =&(curr_ptr[bytes_to_comp]);
+                               bytes_left -=((u32) bytes_to_comp);
+                       }
+                       break;
+               }
+               default:
+                       return -EINVAL;
+                       break;
+
+               }
+               mc_data += mc_block_nr_bytes;
+       }
+
+       return 0;
+
+release:
+       release_firmware(demod->firmware);
+       demod->firmware = NULL;
+
+       return rc;
+}
+
+/*
+ * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
+ *
+ * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
+ */
+
+static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
+{
+       struct drx39xxj_state *state = fe->demodulator_priv;
+       struct drx_demod_instance *demod = state->demod;
+       int result;
+       enum drx_power_mode power_mode;
+
+       if (enable)
+               power_mode = DRX_POWER_UP;
+       else
+               power_mode = DRX_POWER_DOWN;
+
+       result = ctrl_power_mode(demod, &power_mode);
+       if (result != 0) {
+               pr_err("Power state change failed\n");
+               return 0;
+       }
+
+       return 0;
+}
+
+static int drx39xxj_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct drx39xxj_state *state = fe->demodulator_priv;
+       struct drx_demod_instance *demod = state->demod;
+       int result;
+       enum drx_lock_status lock_status;
+
+       *status = 0;
+
+       result = ctrl_lock_status(demod, &lock_status);
+       if (result != 0) {
+               pr_err("drx39xxj: could not get lock status!\n");
+               *status = 0;
+       }
+
+       switch (lock_status) {
+       case DRX_NEVER_LOCK:
+               *status = 0;
+               pr_err("drx says NEVER_LOCK\n");
+               break;
+       case DRX_NOT_LOCKED:
+               *status = 0;
+               break;
+       case DRX_LOCK_STATE_1:
+       case DRX_LOCK_STATE_2:
+       case DRX_LOCK_STATE_3:
+       case DRX_LOCK_STATE_4:
+       case DRX_LOCK_STATE_5:
+       case DRX_LOCK_STATE_6:
+       case DRX_LOCK_STATE_7:
+       case DRX_LOCK_STATE_8:
+       case DRX_LOCK_STATE_9:
+               *status = FE_HAS_SIGNAL
+                   | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
+               break;
+       case DRX_LOCKED:
+               *status = FE_HAS_SIGNAL
+                   | FE_HAS_CARRIER
+                   | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+               break;
+       default:
+               pr_err("Lock state unknown %d\n", lock_status);
+       }
+       ctrl_sig_quality(demod, lock_status);
+
+       return 0;
+}
+
+static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+               *ber = 0;
+               return 0;
+       }
+
+       if (!p->pre_bit_count.stat[0].uvalue) {
+               if (!p->pre_bit_error.stat[0].uvalue)
+                       *ber = 0;
+               else
+                       *ber = 1000000;
+       } else {
+               *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
+                                    p->pre_bit_count.stat[0].uvalue);
+       }
+       return 0;
+}
+
+static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
+                                        u16 *strength)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+               *strength = 0;
+               return 0;
+       }
+
+       *strength = p->strength.stat[0].uvalue;
+       return 0;
+}
+
+static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u64 tmp64;
+
+       if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+               *snr = 0;
+               return 0;
+       }
+
+       tmp64 = p->cnr.stat[0].svalue;
+       do_div(tmp64, 10);
+       *snr = tmp64;
+       return 0;
+}
+
+static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+               *ucb = 0;
+               return 0;
+       }
+
+       *ucb = p->block_error.stat[0].uvalue;
+       return 0;
+}
+
+static int drx39xxj_set_frontend(struct dvb_frontend *fe)
+{
+#ifdef DJH_DEBUG
+       int i;
+#endif
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct drx39xxj_state *state = fe->demodulator_priv;
+       struct drx_demod_instance *demod = state->demod;
+       enum drx_standard standard = DRX_STANDARD_8VSB;
+       struct drx_channel channel;
+       int result;
+       struct drxuio_data uio_data;
+       static const struct drx_channel def_channel = {
+               /* frequency      */ 0,
+               /* bandwidth      */ DRX_BANDWIDTH_6MHZ,
+               /* mirror         */ DRX_MIRROR_NO,
+               /* constellation  */ DRX_CONSTELLATION_AUTO,
+               /* hierarchy      */ DRX_HIERARCHY_UNKNOWN,
+               /* priority       */ DRX_PRIORITY_UNKNOWN,
+               /* coderate       */ DRX_CODERATE_UNKNOWN,
+               /* guard          */ DRX_GUARD_UNKNOWN,
+               /* fftmode        */ DRX_FFTMODE_UNKNOWN,
+               /* classification */ DRX_CLASSIFICATION_AUTO,
+               /* symbolrate     */ 5057000,
+               /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
+               /* ldpc           */ DRX_LDPC_UNKNOWN,
+               /* carrier        */ DRX_CARRIER_UNKNOWN,
+               /* frame mode     */ DRX_FRAMEMODE_UNKNOWN
+       };
+       u32 constellation = DRX_CONSTELLATION_AUTO;
+
+       /* Bring the demod out of sleep */
+       drx39xxj_set_powerstate(fe, 1);
+
+       if (fe->ops.tuner_ops.set_params) {
+               u32 int_freq;
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               /* Set tuner to desired frequency and standard */
+               fe->ops.tuner_ops.set_params(fe);
+
+               /* Use the tuner's IF */
+               if (fe->ops.tuner_ops.get_if_frequency) {
+                       fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
+                       demod->my_common_attr->intermediate_freq = int_freq / 1000;
+               }
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       switch (p->delivery_system) {
+       case SYS_ATSC:
+               standard = DRX_STANDARD_8VSB;
+               break;
+       case SYS_DVBC_ANNEX_B:
+               standard = DRX_STANDARD_ITU_B;
+
+               switch (p->modulation) {
+               case QAM_64:
+                       constellation = DRX_CONSTELLATION_QAM64;
+                       break;
+               case QAM_256:
+                       constellation = DRX_CONSTELLATION_QAM256;
+                       break;
+               default:
+                       constellation = DRX_CONSTELLATION_AUTO;
+                       break;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+       /* Set the standard (will be powered up if necessary */
+       result = ctrl_set_standard(demod, &standard);
+       if (result != 0) {
+               pr_err("Failed to set standard! result=%02x\n",
+                       result);
+               return -EINVAL;
+       }
+
+       /* set channel parameters */
+       channel = def_channel;
+       channel.frequency = p->frequency / 1000;
+       channel.bandwidth = DRX_BANDWIDTH_6MHZ;
+       channel.constellation = constellation;
+
+       /* program channel */
+       result = ctrl_set_channel(demod, &channel);
+       if (result != 0) {
+               pr_err("Failed to set channel!\n");
+               return -EINVAL;
+       }
+       /* Just for giggles, let's shut off the LNA again.... */
+       uio_data.uio = DRX_UIO1;
+       uio_data.value = false;
+       result = ctrl_uio_write(demod, &uio_data);
+       if (result != 0) {
+               pr_err("Failed to disable LNA!\n");
+               return 0;
+       }
+
+       /* After set_frontend, except for strength, stats aren't available */
+       p->strength.stat[0].scale = FE_SCALE_RELATIVE;
+
+       return 0;
+}
+
+static int drx39xxj_sleep(struct dvb_frontend *fe)
+{
+       /* power-down the demodulator */
+       return drx39xxj_set_powerstate(fe, 0);
+}
+
+static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct drx39xxj_state *state = fe->demodulator_priv;
+       struct drx_demod_instance *demod = state->demod;
+       bool i2c_gate_state;
+       int result;
+
+#ifdef DJH_DEBUG
+       pr_debug("i2c gate call: enable=%d state=%d\n", enable,
+              state->i2c_gate_open);
+#endif
+
+       if (enable)
+               i2c_gate_state = true;
+       else
+               i2c_gate_state = false;
+
+       if (state->i2c_gate_open == enable) {
+               /* We're already in the desired state */
+               return 0;
+       }
+
+       result = ctrl_i2c_bridge(demod, &i2c_gate_state);
+       if (result != 0) {
+               pr_err("drx39xxj: could not open i2c gate [%d]\n",
+                      result);
+               dump_stack();
+       } else {
+               state->i2c_gate_open = enable;
+       }
+       return 0;
+}
+
+static int drx39xxj_init(struct dvb_frontend *fe)
+{
+       /* Bring the demod out of sleep */
+       drx39xxj_set_powerstate(fe, 1);
+
+       return 0;
+}
+
+static int drx39xxj_set_lna(struct dvb_frontend *fe)
+{
+       int result;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct drx39xxj_state *state = fe->demodulator_priv;
+       struct drx_demod_instance *demod = state->demod;
+       struct drxj_data *ext_attr = demod->my_ext_attr;
+       struct drxuio_cfg uio_cfg;
+       struct drxuio_data uio_data;
+
+       if (c->lna) {
+               if (!ext_attr->has_lna) {
+                       pr_err("LNA is not supported on this device!\n");
+                       return -EINVAL;
+
+               }
+       }
+
+       /* Turn off the LNA */
+       uio_cfg.uio = DRX_UIO1;
+       uio_cfg.mode = DRX_UIO_MODE_READWRITE;
+       /* Configure user-I/O #3: enable read/write */
+       result = ctrl_set_uio_cfg(demod, &uio_cfg);
+       if (result) {
+               pr_err("Failed to setup LNA GPIO!\n");
+               return result;
+       }
+
+       uio_data.uio = DRX_UIO1;
+       uio_data.value = c->lna;
+       result = ctrl_uio_write(demod, &uio_data);
+       if (result != 0) {
+               pr_err("Failed to %sable LNA!\n",
+                      c->lna ? "en" : "dis");
+               return result;
+       }
+
+       return 0;
+}
+
+static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
+                                     struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void drx39xxj_release(struct dvb_frontend *fe)
+{
+       struct drx39xxj_state *state = fe->demodulator_priv;
+       struct drx_demod_instance *demod = state->demod;
+
+       drxj_close(demod);
+
+       kfree(demod->my_ext_attr);
+       kfree(demod->my_common_attr);
+       kfree(demod->my_i2c_dev_addr);
+       if (demod->firmware)
+               release_firmware(demod->firmware);
+       kfree(demod);
+       kfree(state);
+}
+
+static struct dvb_frontend_ops drx39xxj_ops;
+
+struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
+{
+       struct drx39xxj_state *state = NULL;
+       struct i2c_device_addr *demod_addr = NULL;
+       struct drx_common_attr *demod_comm_attr = NULL;
+       struct drxj_data *demod_ext_attr = NULL;
+       struct drx_demod_instance *demod = NULL;
+       struct dtv_frontend_properties *p;
+       struct drxuio_cfg uio_cfg;
+       struct drxuio_data uio_data;
+       int result;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       demod = kmalloc(sizeof(struct drx_demod_instance), GFP_KERNEL);
+       if (demod == NULL)
+               goto error;
+
+       demod_addr = kmalloc(sizeof(struct i2c_device_addr), GFP_KERNEL);
+       if (demod_addr == NULL)
+               goto error;
+       memcpy(demod_addr, &drxj_default_addr_g,
+              sizeof(struct i2c_device_addr));
+
+       demod_comm_attr = kmalloc(sizeof(struct drx_common_attr), GFP_KERNEL);
+       if (demod_comm_attr == NULL)
+               goto error;
+       memcpy(demod_comm_attr, &drxj_default_comm_attr_g,
+              sizeof(struct drx_common_attr));
+
+       demod_ext_attr = kmalloc(sizeof(struct drxj_data), GFP_KERNEL);
+       if (demod_ext_attr == NULL)
+               goto error;
+       memcpy(demod_ext_attr, &drxj_data_g, sizeof(struct drxj_data));
+
+       /* setup the state */
+       state->i2c = i2c;
+       state->demod = demod;
+
+       /* setup the demod data */
+       memcpy(demod, &drxj_default_demod_g, sizeof(struct drx_demod_instance));
+
+       demod->my_i2c_dev_addr = demod_addr;
+       demod->my_common_attr = demod_comm_attr;
+       demod->my_i2c_dev_addr->user_data = state;
+       demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
+       demod->my_common_attr->verify_microcode = true;
+       demod->my_common_attr->intermediate_freq = 5000;
+       demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
+       demod->my_ext_attr = demod_ext_attr;
+       ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
+       demod->i2c = i2c;
+
+       result = drxj_open(demod);
+       if (result != 0) {
+               pr_err("DRX open failed!  Aborting\n");
+               goto error;
+       }
+
+       /* Turn off the LNA */
+       uio_cfg.uio = DRX_UIO1;
+       uio_cfg.mode = DRX_UIO_MODE_READWRITE;
+       /* Configure user-I/O #3: enable read/write */
+       result = ctrl_set_uio_cfg(demod, &uio_cfg);
+       if (result) {
+               pr_err("Failed to setup LNA GPIO!\n");
+               goto error;
+       }
+
+       uio_data.uio = DRX_UIO1;
+       uio_data.value = false;
+       result = ctrl_uio_write(demod, &uio_data);
+       if (result != 0) {
+               pr_err("Failed to disable LNA!\n");
+               goto error;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &drx39xxj_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       state->frontend.demodulator_priv = state;
+
+       /* Initialize stats - needed for DVBv5 stats to work */
+       p = &state->frontend.dtv_property_cache;
+       p->strength.len = 1;
+       p->pre_bit_count.len = 1;
+       p->pre_bit_error.len = 1;
+       p->post_bit_count.len = 1;
+       p->post_bit_error.len = 1;
+       p->block_count.len = 1;
+       p->block_error.len = 1;
+       p->cnr.len = 1;
+
+       p->strength.stat[0].scale = FE_SCALE_RELATIVE;
+       p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+       return &state->frontend;
+
+error:
+       kfree(demod_ext_attr);
+       kfree(demod_comm_attr);
+       kfree(demod_addr);
+       kfree(demod);
+       kfree(state);
+
+       return NULL;
+}
+EXPORT_SYMBOL(drx39xxj_attach);
+
+static struct dvb_frontend_ops drx39xxj_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+                .name = "Micronas DRX39xxj family Frontend",
+                .frequency_stepsize = 62500,
+                .frequency_min = 51000000,
+                .frequency_max = 858000000,
+                .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+
+       .init = drx39xxj_init,
+       .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
+       .sleep = drx39xxj_sleep,
+       .set_frontend = drx39xxj_set_frontend,
+       .get_tune_settings = drx39xxj_get_tune_settings,
+       .read_status = drx39xxj_read_status,
+       .read_ber = drx39xxj_read_ber,
+       .read_signal_strength = drx39xxj_read_signal_strength,
+       .read_snr = drx39xxj_read_snr,
+       .read_ucblocks = drx39xxj_read_ucblocks,
+       .release = drx39xxj_release,
+       .set_lna = drx39xxj_set_lna,
+};
+
+MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.h b/drivers/media/dvb-frontends/drx39xyj/drxj.h
new file mode 100644 (file)
index 0000000..55ad535
--- /dev/null
@@ -0,0 +1,650 @@
+
+/*
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+ DRXJ specific header file
+
+ Authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
+*/
+
+#ifndef __DRXJ_H__
+#define __DRXJ_H__
+/*-------------------------------------------------------------------------
+INCLUDES
+-------------------------------------------------------------------------*/
+
+#include "drx_driver.h"
+#include "drx_dap_fasi.h"
+
+/* Check DRX-J specific dap condition */
+/* Multi master mode and short addr format only will not work.
+   RMW, CRC reset, broadcast and switching back to single master mode
+   cannot be done with short addr only in multi master mode. */
+#if ((DRXDAP_SINGLE_MASTER == 0) && (DRXDAPFASI_LONG_ADDR_ALLOWED == 0))
+#error "Multi master mode and short addressing only is an illegal combination"
+       *;                      /* Generate a fatal compiler error to make sure it stops here,
+                                  this is necesarry because not all compilers stop after a #error. */
+#endif
+
+/*-------------------------------------------------------------------------
+TYPEDEFS
+-------------------------------------------------------------------------*/
+/*============================================================================*/
+/*============================================================================*/
+/*== code support ============================================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+/*============================================================================*/
+/*============================================================================*/
+/*== SCU cmd if  =============================================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+       struct drxjscu_cmd {
+               u16 command;
+                       /**< Command number */
+               u16 parameter_len;
+                       /**< Data length in byte */
+               u16 result_len;
+                       /**< result length in byte */
+               u16 *parameter;
+                       /**< General purpous param */
+               u16 *result;
+                       /**< General purpous param */};
+
+/*============================================================================*/
+/*============================================================================*/
+/*== CTRL CFG related data structures ========================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+/* extra intermediate lock state for VSB,QAM,NTSC */
+#define DRXJ_DEMOD_LOCK       (DRX_LOCK_STATE_1)
+
+/* OOB lock states */
+#define DRXJ_OOB_AGC_LOCK     (DRX_LOCK_STATE_1)       /* analog gain control lock */
+#define DRXJ_OOB_SYNC_LOCK    (DRX_LOCK_STATE_2)       /* digital gain control lock */
+
+/* Intermediate powermodes for DRXJ */
+#define DRXJ_POWER_DOWN_MAIN_PATH   DRX_POWER_MODE_8
+#define DRXJ_POWER_DOWN_CORE        DRX_POWER_MODE_9
+#define DRXJ_POWER_DOWN_PLL         DRX_POWER_MODE_10
+
+/* supstition for GPIO FNC mux */
+#define APP_O                 (0x0000)
+
+/*#define DRX_CTRL_BASE         (0x0000)*/
+
+#define DRXJ_CTRL_CFG_BASE    (0x1000)
+       enum drxj_cfg_type {
+               DRXJ_CFG_AGC_RF = DRXJ_CTRL_CFG_BASE,
+               DRXJ_CFG_AGC_IF,
+               DRXJ_CFG_AGC_INTERNAL,
+               DRXJ_CFG_PRE_SAW,
+               DRXJ_CFG_AFE_GAIN,
+               DRXJ_CFG_SYMBOL_CLK_OFFSET,
+               DRXJ_CFG_ACCUM_CR_RS_CW_ERR,
+               DRXJ_CFG_FEC_MERS_SEQ_COUNT,
+               DRXJ_CFG_OOB_MISC,
+               DRXJ_CFG_SMART_ANT,
+               DRXJ_CFG_OOB_PRE_SAW,
+               DRXJ_CFG_VSB_MISC,
+               DRXJ_CFG_RESET_PACKET_ERR,
+
+               /* ATV (FM) */
+               DRXJ_CFG_ATV_OUTPUT,    /* also for FM (SIF control) but not likely */
+               DRXJ_CFG_ATV_MISC,
+               DRXJ_CFG_ATV_EQU_COEF,
+               DRXJ_CFG_ATV_AGC_STATUS,        /* also for FM ( IF,RF, audioAGC ) */
+
+               DRXJ_CFG_MPEG_OUTPUT_MISC,
+               DRXJ_CFG_HW_CFG,
+               DRXJ_CFG_OOB_LO_POW,
+
+               DRXJ_CFG_MAX    /* dummy, never to be used */};
+
+/**
+* /struct enum drxj_cfg_smart_ant_io * smart antenna i/o.
+*/
+enum drxj_cfg_smart_ant_io {
+       DRXJ_SMT_ANT_OUTPUT = 0,
+       DRXJ_SMT_ANT_INPUT
+};
+
+/**
+* /struct struct drxj_cfg_smart_ant * Set smart antenna.
+*/
+       struct drxj_cfg_smart_ant {
+               enum drxj_cfg_smart_ant_io io;
+               u16 ctrl_data;
+       };
+
+/**
+* /struct DRXJAGCSTATUS_t
+* AGC status information from the DRXJ-IQM-AF.
+*/
+struct drxj_agc_status {
+       u16 IFAGC;
+       u16 RFAGC;
+       u16 digital_agc;
+};
+
+/* DRXJ_CFG_AGC_RF, DRXJ_CFG_AGC_IF */
+
+/**
+* /struct enum drxj_agc_ctrl_mode * Available AGCs modes in the DRXJ.
+*/
+       enum drxj_agc_ctrl_mode {
+               DRX_AGC_CTRL_AUTO = 0,
+               DRX_AGC_CTRL_USER,
+               DRX_AGC_CTRL_OFF};
+
+/**
+* /struct struct drxj_cfg_agc * Generic interface for all AGCs present on the DRXJ.
+*/
+       struct drxj_cfg_agc {
+               enum drx_standard standard;     /* standard for which these settings apply */
+               enum drxj_agc_ctrl_mode ctrl_mode;      /* off, user, auto          */
+               u16 output_level;       /* range dependent on AGC   */
+               u16 min_output_level;   /* range dependent on AGC   */
+               u16 max_output_level;   /* range dependent on AGC   */
+               u16 speed;      /* range dependent on AGC   */
+               u16 top;        /* rf-agc take over point   */
+               u16 cut_off_current;    /* rf-agc is accelerated if output current
+                                          is below cut-off current                */};
+
+/* DRXJ_CFG_PRE_SAW */
+
+/**
+* /struct struct drxj_cfg_pre_saw * Interface to configure pre SAW sense.
+*/
+       struct drxj_cfg_pre_saw {
+               enum drx_standard standard;     /* standard to which these settings apply */
+               u16 reference;  /* pre SAW reference value, range 0 .. 31 */
+               bool use_pre_saw;       /* true algorithms must use pre SAW sense */};
+
+/* DRXJ_CFG_AFE_GAIN */
+
+/**
+* /struct struct drxj_cfg_afe_gain * Interface to configure gain of AFE (LNA + PGA).
+*/
+       struct drxj_cfg_afe_gain {
+               enum drx_standard standard;     /* standard to which these settings apply */
+               u16 gain;       /* gain in 0.1 dB steps, DRXJ range 140 .. 335 */};
+
+/**
+* /struct drxjrs_errors
+* Available failure information in DRXJ_FEC_RS.
+*
+* Container for errors that are received in the most recently finished measurment period
+*
+*/
+       struct drxjrs_errors {
+               u16 nr_bit_errors;
+                               /**< no of pre RS bit errors          */
+               u16 nr_symbol_errors;
+                               /**< no of pre RS symbol errors       */
+               u16 nr_packet_errors;
+                               /**< no of pre RS packet errors       */
+               u16 nr_failures;
+                               /**< no of post RS failures to decode */
+               u16 nr_snc_par_fail_count;
+                               /**< no of post RS bit erros          */
+       };
+
+/**
+* /struct struct drxj_cfg_vsb_misc * symbol error rate
+*/
+       struct drxj_cfg_vsb_misc {
+               u32 symb_error;
+                             /**< symbol error rate sps */};
+
+/**
+* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate.
+*
+*/
+       enum drxj_mpeg_start_width {
+               DRXJ_MPEG_START_WIDTH_1CLKCYC,
+               DRXJ_MPEG_START_WIDTH_8CLKCYC};
+
+/**
+* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate.
+*
+*/
+       enum drxj_mpeg_output_clock_rate {
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_75973K,
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_50625K,
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_37968K,
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_30375K,
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_25313K,
+               DRXJ_MPEGOUTPUT_CLOCK_RATE_21696K};
+
+/**
+* /struct DRXJCfgMisc_t
+* Change TEI bit of MPEG output
+* reverse MPEG output bit order
+* set MPEG output clock rate
+*/
+       struct drxj_cfg_mpeg_output_misc {
+               bool disable_tei_handling;            /**< if true pass (not change) TEI bit */
+               bool bit_reverse_mpeg_outout;         /**< if true, parallel: msb on MD0; serial: lsb out first */
+               enum drxj_mpeg_output_clock_rate mpeg_output_clock_rate;
+                                                     /**< set MPEG output clock rate that overwirtes the derived one from symbol rate */
+               enum drxj_mpeg_start_width mpeg_start_width;  /**< set MPEG output start width */};
+
+/**
+* /enum enum drxj_xtal_freq * Supported external crystal reference frequency.
+*/
+       enum drxj_xtal_freq {
+               DRXJ_XTAL_FREQ_RSVD,
+               DRXJ_XTAL_FREQ_27MHZ,
+               DRXJ_XTAL_FREQ_20P25MHZ,
+               DRXJ_XTAL_FREQ_4MHZ};
+
+/**
+* /enum enum drxj_xtal_freq * Supported external crystal reference frequency.
+*/
+       enum drxji2c_speed {
+               DRXJ_I2C_SPEED_400KBPS,
+               DRXJ_I2C_SPEED_100KBPS};
+
+/**
+* /struct struct drxj_cfg_hw_cfg * Get hw configuration, such as crystal reference frequency, I2C speed, etc...
+*/
+       struct drxj_cfg_hw_cfg {
+               enum drxj_xtal_freq xtal_freq;
+                                  /**< crystal reference frequency */
+               enum drxji2c_speed i2c_speed;
+                                  /**< 100 or 400 kbps */};
+
+/*
+ *  DRXJ_CFG_ATV_MISC
+ */
+       struct drxj_cfg_atv_misc {
+               s16 peak_filter;        /* -8 .. 15 */
+               u16 noise_filter;       /* 0 .. 15 */};
+
+/*
+ *  struct drxj_cfg_oob_misc */
+#define   DRXJ_OOB_STATE_RESET                                        0x0
+#define   DRXJ_OOB_STATE_AGN_HUNT                                     0x1
+#define   DRXJ_OOB_STATE_DGN_HUNT                                     0x2
+#define   DRXJ_OOB_STATE_AGC_HUNT                                     0x3
+#define   DRXJ_OOB_STATE_FRQ_HUNT                                     0x4
+#define   DRXJ_OOB_STATE_PHA_HUNT                                     0x8
+#define   DRXJ_OOB_STATE_TIM_HUNT                                     0x10
+#define   DRXJ_OOB_STATE_EQU_HUNT                                     0x20
+#define   DRXJ_OOB_STATE_EQT_HUNT                                     0x30
+#define   DRXJ_OOB_STATE_SYNC                                         0x40
+
+struct drxj_cfg_oob_misc {
+       struct drxj_agc_status agc;
+       bool eq_lock;
+       bool sym_timing_lock;
+       bool phase_lock;
+       bool freq_lock;
+       bool dig_gain_lock;
+       bool ana_gain_lock;
+       u8 state;
+};
+
+/*
+ *  Index of in array of coef
+ */
+       enum drxj_cfg_oob_lo_power {
+               DRXJ_OOB_LO_POW_MINUS0DB = 0,
+               DRXJ_OOB_LO_POW_MINUS5DB,
+               DRXJ_OOB_LO_POW_MINUS10DB,
+               DRXJ_OOB_LO_POW_MINUS15DB,
+               DRXJ_OOB_LO_POW_MAX};
+
+/*
+ *  DRXJ_CFG_ATV_EQU_COEF
+ */
+       struct drxj_cfg_atv_equ_coef {
+               s16 coef0;      /* -256 .. 255 */
+               s16 coef1;      /* -256 .. 255 */
+               s16 coef2;      /* -256 .. 255 */
+               s16 coef3;      /* -256 .. 255 */};
+
+/*
+ *  Index of in array of coef
+ */
+       enum drxj_coef_array_index {
+               DRXJ_COEF_IDX_MN = 0,
+               DRXJ_COEF_IDX_FM,
+               DRXJ_COEF_IDX_L,
+               DRXJ_COEF_IDX_LP,
+               DRXJ_COEF_IDX_BG,
+               DRXJ_COEF_IDX_DK,
+               DRXJ_COEF_IDX_I,
+               DRXJ_COEF_IDX_MAX};
+
+/*
+ *  DRXJ_CFG_ATV_OUTPUT
+ */
+
+/**
+* /enum DRXJAttenuation_t
+* Attenuation setting for SIF AGC.
+*
+*/
+       enum drxjsif_attenuation {
+               DRXJ_SIF_ATTENUATION_0DB,
+               DRXJ_SIF_ATTENUATION_3DB,
+               DRXJ_SIF_ATTENUATION_6DB,
+               DRXJ_SIF_ATTENUATION_9DB};
+
+/**
+* /struct struct drxj_cfg_atv_output * SIF attenuation setting.
+*
+*/
+struct drxj_cfg_atv_output {
+       bool enable_cvbs_output;        /* true= enabled */
+       bool enable_sif_output; /* true= enabled */
+       enum drxjsif_attenuation sif_attenuation;
+};
+
+/*
+   DRXJ_CFG_ATV_AGC_STATUS (get only)
+*/
+/* TODO : AFE interface not yet finished, subject to change */
+       struct drxj_cfg_atv_agc_status {
+               u16 rf_agc_gain;        /* 0 .. 877 uA */
+               u16 if_agc_gain;        /* 0 .. 877  uA */
+               s16 video_agc_gain;     /* -75 .. 1972 in 0.1 dB steps */
+               s16 audio_agc_gain;     /* -4 .. 1020 in 0.1 dB steps */
+               u16 rf_agc_loop_gain;   /* 0 .. 7 */
+               u16 if_agc_loop_gain;   /* 0 .. 7 */
+               u16 video_agc_loop_gain;        /* 0 .. 7 */};
+
+/*============================================================================*/
+/*============================================================================*/
+/*== CTRL related data structures ============================================*/
+/*============================================================================*/
+/*============================================================================*/
+
+/* NONE */
+
+/*============================================================================*/
+/*============================================================================*/
+
+/*========================================*/
+/**
+* /struct struct drxj_data * DRXJ specific attributes.
+*
+* Global data container for DRXJ specific data.
+*
+*/
+       struct drxj_data {
+               /* device capabilties (determined during drx_open()) */
+               bool has_lna;             /**< true if LNA (aka PGA) present */
+               bool has_oob;             /**< true if OOB supported */
+               bool has_ntsc;            /**< true if NTSC supported */
+               bool has_btsc;            /**< true if BTSC supported */
+               bool has_smatx;   /**< true if mat_tx is available */
+               bool has_smarx;   /**< true if mat_rx is available */
+               bool has_gpio;            /**< true if GPIO is available */
+               bool has_irqn;            /**< true if IRQN is available */
+               /* A1/A2/A... */
+               u8 mfx;           /**< metal fix */
+
+               /* tuner settings */
+               bool mirror_freq_spect_oob;/**< tuner inversion (true = tuner mirrors the signal */
+
+               /* standard/channel settings */
+               enum drx_standard standard;       /**< current standard information                     */
+               enum drx_modulation constellation;
+                                         /**< current constellation                            */
+               s32 frequency; /**< center signal frequency in KHz                   */
+               enum drx_bandwidth curr_bandwidth;
+                                         /**< current channel bandwidth                        */
+               enum drx_mirror mirror;   /**< current channel mirror                           */
+
+               /* signal quality information */
+               u32 fec_bits_desired;     /**< BER accounting period                            */
+               u16 fec_vd_plen;          /**< no of trellis symbols: VD SER measurement period */
+               u16 qam_vd_prescale;      /**< Viterbi Measurement Prescale                     */
+               u16 qam_vd_period;        /**< Viterbi Measurement period                       */
+               u16 fec_rs_plen;          /**< defines RS BER measurement period                */
+               u16 fec_rs_prescale;      /**< ReedSolomon Measurement Prescale                 */
+               u16 fec_rs_period;        /**< ReedSolomon Measurement period                   */
+               bool reset_pkt_err_acc;   /**< Set a flag to reset accumulated packet error     */
+               u16 pkt_err_acc_start;    /**< Set a flag to reset accumulated packet error     */
+
+               /* HI configuration */
+               u16 hi_cfg_timing_div;    /**< HI Configure() parameter 2                       */
+               u16 hi_cfg_bridge_delay;          /**< HI Configure() parameter 3                       */
+               u16 hi_cfg_wake_up_key;   /**< HI Configure() parameter 4                       */
+               u16 hi_cfg_ctrl;          /**< HI Configure() parameter 5                       */
+               u16 hi_cfg_transmit;      /**< HI Configure() parameter 6                       */
+
+               /* UIO configuartion */
+               enum drxuio_mode uio_sma_rx_mode;/**< current mode of SmaRx pin                        */
+               enum drxuio_mode uio_sma_tx_mode;/**< current mode of SmaTx pin                        */
+               enum drxuio_mode uio_gpio_mode; /**< current mode of ASEL pin                         */
+               enum drxuio_mode uio_irqn_mode; /**< current mode of IRQN pin                         */
+
+               /* IQM fs frequecy shift and inversion */
+               u32 iqm_fs_rate_ofs;       /**< frequency shifter setting after setchannel      */
+               bool pos_image;    /**< Ture: positive image                            */
+               /* IQM RC frequecy shift */
+               u32 iqm_rc_rate_ofs;       /**< frequency shifter setting after setchannel      */
+
+               /* ATV configuartion */
+               u32 atv_cfg_changed_flags; /**< flag: flags cfg changes */
+               s16 atv_top_equ0[DRXJ_COEF_IDX_MAX];         /**< shadow of ATV_TOP_EQU0__A */
+               s16 atv_top_equ1[DRXJ_COEF_IDX_MAX];         /**< shadow of ATV_TOP_EQU1__A */
+               s16 atv_top_equ2[DRXJ_COEF_IDX_MAX];         /**< shadow of ATV_TOP_EQU2__A */
+               s16 atv_top_equ3[DRXJ_COEF_IDX_MAX];         /**< shadow of ATV_TOP_EQU3__A */
+               bool phase_correction_bypass;/**< flag: true=bypass */
+               s16 atv_top_vid_peak;     /**< shadow of ATV_TOP_VID_PEAK__A */
+               u16 atv_top_noise_th;     /**< shadow of ATV_TOP_NOISE_TH__A */
+               bool enable_cvbs_output;  /**< flag CVBS ouput enable */
+               bool enable_sif_output;   /**< flag SIF ouput enable */
+                enum drxjsif_attenuation sif_attenuation;
+                                         /**< current SIF att setting */
+               /* Agc configuration for QAM and VSB */
+               struct drxj_cfg_agc qam_rf_agc_cfg; /**< qam RF AGC config */
+               struct drxj_cfg_agc qam_if_agc_cfg; /**< qam IF AGC config */
+               struct drxj_cfg_agc vsb_rf_agc_cfg; /**< vsb RF AGC config */
+               struct drxj_cfg_agc vsb_if_agc_cfg; /**< vsb IF AGC config */
+
+               /* PGA gain configuration for QAM and VSB */
+               u16 qam_pga_cfg;          /**< qam PGA config */
+               u16 vsb_pga_cfg;          /**< vsb PGA config */
+
+               /* Pre SAW configuration for QAM and VSB */
+               struct drxj_cfg_pre_saw qam_pre_saw_cfg;
+                                         /**< qam pre SAW config */
+               struct drxj_cfg_pre_saw vsb_pre_saw_cfg;
+                                         /**< qam pre SAW config */
+
+               /* Version information */
+               char v_text[2][12];       /**< allocated text versions */
+               struct drx_version v_version[2]; /**< allocated versions structs */
+               struct drx_version_list v_list_elements[2];
+                                         /**< allocated version list */
+
+               /* smart antenna configuration */
+               bool smart_ant_inverted;
+
+               /* Tracking filter setting for OOB */
+               u16 oob_trk_filter_cfg[8];
+               bool oob_power_on;
+
+               /* MPEG static bitrate setting */
+               u32 mpeg_ts_static_bitrate;  /**< bitrate static MPEG output */
+               bool disable_te_ihandling;  /**< MPEG TS TEI handling */
+               bool bit_reverse_mpeg_outout;/**< MPEG output bit order */
+                enum drxj_mpeg_output_clock_rate mpeg_output_clock_rate;
+                                           /**< MPEG output clock rate */
+                enum drxj_mpeg_start_width mpeg_start_width;
+                                           /**< MPEG Start width */
+
+               /* Pre SAW & Agc configuration for ATV */
+               struct drxj_cfg_pre_saw atv_pre_saw_cfg;
+                                         /**< atv pre SAW config */
+               struct drxj_cfg_agc atv_rf_agc_cfg; /**< atv RF AGC config */
+               struct drxj_cfg_agc atv_if_agc_cfg; /**< atv IF AGC config */
+               u16 atv_pga_cfg;          /**< atv pga config    */
+
+               u32 curr_symbol_rate;
+
+               /* pin-safe mode */
+               bool pdr_safe_mode;         /**< PDR safe mode activated      */
+               u16 pdr_safe_restore_val_gpio;
+               u16 pdr_safe_restore_val_v_sync;
+               u16 pdr_safe_restore_val_sma_rx;
+               u16 pdr_safe_restore_val_sma_tx;
+
+               /* OOB pre-saw value */
+               u16 oob_pre_saw;
+               enum drxj_cfg_oob_lo_power oob_lo_pow;
+
+               struct drx_aud_data aud_data;
+                                   /**< audio storage                  */};
+
+/*-------------------------------------------------------------------------
+Access MACROS
+-------------------------------------------------------------------------*/
+/**
+* \brief Compilable references to attributes
+* \param d pointer to demod instance
+*
+* Used as main reference to an attribute field.
+* Can be used by both macro implementation and function implementation.
+* These macros are defined to avoid duplication of code in macro and function
+* definitions that handle access of demod common or extended attributes.
+*
+*/
+
+#define DRXJ_ATTR_BTSC_DETECT(d)                       \
+                       (((struct drxj_data *)(d)->my_ext_attr)->aud_data.btsc_detect)
+
+/*-------------------------------------------------------------------------
+DEFINES
+-------------------------------------------------------------------------*/
+
+/**
+* \def DRXJ_NTSC_CARRIER_FREQ_OFFSET
+* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
+*
+* For NTSC standard.
+* NTSC channels are listed by their picture carrier frequency (Fpc).
+* The function DRX_CTRL_SET_CHANNEL requires the centre frequency as input.
+* In case the tuner module is not used the DRX-J requires that the tuner is
+* tuned to the centre frequency of the channel:
+*
+* Fcentre = Fpc + DRXJ_NTSC_CARRIER_FREQ_OFFSET
+*
+*/
+#define DRXJ_NTSC_CARRIER_FREQ_OFFSET           ((s32)(1750))
+
+/**
+* \def DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET
+* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
+*
+* For PAL/SECAM - BG standard. This define is needed in case the tuner module
+* is NOT used. PAL/SECAM channels are listed by their picture carrier frequency (Fpc).
+* The DRX-J requires that the tuner is tuned to:
+* Fpc + DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET
+*
+* In case the tuner module is used the drxdriver takes care of this.
+* In case the tuner module is NOT used the application programmer must take
+* care of this.
+*
+*/
+#define DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET   ((s32)(2375))
+
+/**
+* \def DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET
+* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
+*
+* For PAL/SECAM - DK, I, L standards. This define is needed in case the tuner module
+* is NOT used. PAL/SECAM channels are listed by their picture carrier frequency (Fpc).
+* The DRX-J requires that the tuner is tuned to:
+* Fpc + DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET
+*
+* In case the tuner module is used the drxdriver takes care of this.
+* In case the tuner module is NOT used the application programmer must take
+* care of this.
+*
+*/
+#define DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET ((s32)(2775))
+
+/**
+* \def DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET
+* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
+*
+* For PAL/SECAM - LP standard. This define is needed in case the tuner module
+* is NOT used. PAL/SECAM channels are listed by their picture carrier frequency (Fpc).
+* The DRX-J requires that the tuner is tuned to:
+* Fpc + DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET
+*
+* In case the tuner module is used the drxdriver takes care of this.
+* In case the tuner module is NOT used the application programmer must take
+* care of this.
+*/
+#define DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET   ((s32)(-3255))
+
+/**
+* \def DRXJ_FM_CARRIER_FREQ_OFFSET
+* \brief Offset from sound carrier to centre frequency in kHz, in RF domain
+*
+* For FM standard.
+* FM channels are listed by their sound carrier frequency (Fsc).
+* The function DRX_CTRL_SET_CHANNEL requires the Ffm frequency (see below) as
+* input.
+* In case the tuner module is not used the DRX-J requires that the tuner is
+* tuned to the Ffm frequency of the channel.
+*
+* Ffm = Fsc + DRXJ_FM_CARRIER_FREQ_OFFSET
+*
+*/
+#define DRXJ_FM_CARRIER_FREQ_OFFSET             ((s32)(-3000))
+
+/* Revision types -------------------------------------------------------*/
+
+#define DRXJ_TYPE_ID (0x3946000DUL)
+
+/* Macros ---------------------------------------------------------------*/
+
+/* Convert OOB lock status to string */
+#define DRXJ_STR_OOB_LOCKSTATUS(x) ( \
+       (x == DRX_NEVER_LOCK) ? "Never" : \
+       (x == DRX_NOT_LOCKED) ? "No" : \
+       (x == DRX_LOCKED) ? "Locked" : \
+       (x == DRX_LOCK_STATE_1) ? "AGC lock" : \
+       (x == DRX_LOCK_STATE_2) ? "sync lock" : \
+       "(Invalid)")
+
+#endif                         /* __DRXJ_H__ */
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj_map.h b/drivers/media/dvb-frontends/drx39xyj/drxj_map.h
new file mode 100644 (file)
index 0000000..0bbd4ae
--- /dev/null
@@ -0,0 +1,15055 @@
+/*
+  Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+       and/or other materials provided with the distribution.
+  * Neither the name of Trident Microsystems nor Hauppauge Computer Works
+    nor the names of its contributors may be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ ***********************************************************************************************************************
+ * WARNING - THIS FILE HAS BEEN GENERATED - DO NOT CHANGE
+ *
+ * Filename:        drxj_map.h
+ * Generated on:    Mon Jan 18 12:09:24 2010
+ * Generated by:    IDF:x 1.3.0
+ * Generated from:  reg_map
+ * Output start:    [entry point]
+ *
+ * filename         last modified               re-use
+ * -----------------------------------------------------
+ * reg_map.1.tmp    Mon Jan 18 12:09:24 2010    -
+ *
+ */
+
+#ifndef __DRXJ_MAP__H__
+#define __DRXJ_MAP__H__ INCLUDED
+
+#ifdef _REGISTERTABLE_
+#include <registertable.h>
+       extern register_table_t drxj_map[];
+       extern register_table_info_t drxj_map_info[];
+#endif
+
+#define ATV_COMM_EXEC__A                                                    0xC00000
+#define ATV_COMM_EXEC__W                                                    2
+#define ATV_COMM_EXEC__M                                                    0x3
+#define ATV_COMM_EXEC__PRE                                                  0x0
+#define   ATV_COMM_EXEC_STOP                                                0x0
+#define   ATV_COMM_EXEC_ACTIVE                                              0x1
+#define   ATV_COMM_EXEC_HOLD                                                0x2
+
+#define ATV_COMM_STATE__A                                                   0xC00001
+#define ATV_COMM_STATE__W                                                   16
+#define ATV_COMM_STATE__M                                                   0xFFFF
+#define ATV_COMM_STATE__PRE                                                 0x0
+#define ATV_COMM_MB__A                                                      0xC00002
+#define ATV_COMM_MB__W                                                      16
+#define ATV_COMM_MB__M                                                      0xFFFF
+#define ATV_COMM_MB__PRE                                                    0x0
+#define ATV_COMM_INT_REQ__A                                                 0xC00003
+#define ATV_COMM_INT_REQ__W                                                 16
+#define ATV_COMM_INT_REQ__M                                                 0xFFFF
+#define ATV_COMM_INT_REQ__PRE                                               0x0
+#define   ATV_COMM_INT_REQ_COMM_INT_REQ__B                                  0
+#define   ATV_COMM_INT_REQ_COMM_INT_REQ__W                                  1
+#define   ATV_COMM_INT_REQ_COMM_INT_REQ__M                                  0x1
+#define   ATV_COMM_INT_REQ_COMM_INT_REQ__PRE                                0x0
+
+#define ATV_COMM_INT_STA__A                                                 0xC00005
+#define ATV_COMM_INT_STA__W                                                 16
+#define ATV_COMM_INT_STA__M                                                 0xFFFF
+#define ATV_COMM_INT_STA__PRE                                               0x0
+#define ATV_COMM_INT_MSK__A                                                 0xC00006
+#define ATV_COMM_INT_MSK__W                                                 16
+#define ATV_COMM_INT_MSK__M                                                 0xFFFF
+#define ATV_COMM_INT_MSK__PRE                                               0x0
+#define ATV_COMM_INT_STM__A                                                 0xC00007
+#define ATV_COMM_INT_STM__W                                                 16
+#define ATV_COMM_INT_STM__M                                                 0xFFFF
+#define ATV_COMM_INT_STM__PRE                                               0x0
+
+#define ATV_COMM_KEY__A                                                     0xC0000F
+#define ATV_COMM_KEY__W                                                     16
+#define ATV_COMM_KEY__M                                                     0xFFFF
+#define ATV_COMM_KEY__PRE                                                   0x0
+#define   ATV_COMM_KEY_KEY                                                  0xFABA
+#define   ATV_COMM_KEY_MIN                                                  0x0
+#define   ATV_COMM_KEY_MAX                                                  0xFFFF
+
+#define ATV_TOP_COMM_EXEC__A                                                0xC10000
+#define ATV_TOP_COMM_EXEC__W                                                2
+#define ATV_TOP_COMM_EXEC__M                                                0x3
+#define ATV_TOP_COMM_EXEC__PRE                                              0x0
+#define   ATV_TOP_COMM_EXEC_STOP                                            0x0
+#define   ATV_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   ATV_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define ATV_TOP_COMM_STATE__A                                               0xC10001
+#define ATV_TOP_COMM_STATE__W                                               16
+#define ATV_TOP_COMM_STATE__M                                               0xFFFF
+#define ATV_TOP_COMM_STATE__PRE                                             0x0
+#define   ATV_TOP_COMM_STATE_STATE__B                                       0
+#define   ATV_TOP_COMM_STATE_STATE__W                                       16
+#define   ATV_TOP_COMM_STATE_STATE__M                                       0xFFFF
+#define   ATV_TOP_COMM_STATE_STATE__PRE                                     0x0
+
+#define ATV_TOP_COMM_MB__A                                                  0xC10002
+#define ATV_TOP_COMM_MB__W                                                  16
+#define ATV_TOP_COMM_MB__M                                                  0xFFFF
+#define ATV_TOP_COMM_MB__PRE                                                0x0
+#define   ATV_TOP_COMM_MB_CTL__B                                            0
+#define   ATV_TOP_COMM_MB_CTL__W                                            1
+#define   ATV_TOP_COMM_MB_CTL__M                                            0x1
+#define   ATV_TOP_COMM_MB_CTL__PRE                                          0x0
+#define   ATV_TOP_COMM_MB_OBS__B                                            1
+#define   ATV_TOP_COMM_MB_OBS__W                                            1
+#define   ATV_TOP_COMM_MB_OBS__M                                            0x2
+#define   ATV_TOP_COMM_MB_OBS__PRE                                          0x0
+
+#define   ATV_TOP_COMM_MB_MUX_CTRL__B                                       2
+#define   ATV_TOP_COMM_MB_MUX_CTRL__W                                       4
+#define   ATV_TOP_COMM_MB_MUX_CTRL__M                                       0x3C
+#define   ATV_TOP_COMM_MB_MUX_CTRL__PRE                                     0x0
+#define     ATV_TOP_COMM_MB_MUX_CTRL_PEAK_S                                 0x0
+#define     ATV_TOP_COMM_MB_MUX_CTRL_VID_GAIN                               0x4
+#define     ATV_TOP_COMM_MB_MUX_CTRL_CORR_O                                 0x8
+#define     ATV_TOP_COMM_MB_MUX_CTRL_CR_ROT_O                               0xC
+#define     ATV_TOP_COMM_MB_MUX_CTRL_CR_IIR_IQ                              0x10
+#define     ATV_TOP_COMM_MB_MUX_CTRL_VIDEO_O                                0x14
+#define     ATV_TOP_COMM_MB_MUX_CTRL_SIF_O                                  0x18
+#define     ATV_TOP_COMM_MB_MUX_CTRL_SIF2025_O                              0x1C
+#define     ATV_TOP_COMM_MB_MUX_CTRL_POST_S                                 0x20
+
+#define   ATV_TOP_COMM_MB_MUX_OBS__B                                        6
+#define   ATV_TOP_COMM_MB_MUX_OBS__W                                        4
+#define   ATV_TOP_COMM_MB_MUX_OBS__M                                        0x3C0
+#define   ATV_TOP_COMM_MB_MUX_OBS__PRE                                      0x0
+#define     ATV_TOP_COMM_MB_MUX_OBS_PEAK_S                                  0x0
+#define     ATV_TOP_COMM_MB_MUX_OBS_VID_GAIN                                0x40
+#define     ATV_TOP_COMM_MB_MUX_OBS_CORR_O                                  0x80
+#define     ATV_TOP_COMM_MB_MUX_OBS_CR_ROT_O                                0xC0
+#define     ATV_TOP_COMM_MB_MUX_OBS_CR_IIR_IQ                               0x100
+#define     ATV_TOP_COMM_MB_MUX_OBS_VIDEO_O                                 0x140
+#define     ATV_TOP_COMM_MB_MUX_OBS_SIF_O                                   0x180
+#define     ATV_TOP_COMM_MB_MUX_OBS_SIF2025_O                               0x1C0
+#define     ATV_TOP_COMM_MB_MUX_OBS_POST_S                                  0x200
+
+#define ATV_TOP_COMM_INT_REQ__A                                             0xC10003
+#define ATV_TOP_COMM_INT_REQ__W                                             16
+#define ATV_TOP_COMM_INT_REQ__M                                             0xFFFF
+#define ATV_TOP_COMM_INT_REQ__PRE                                           0x0
+#define ATV_TOP_COMM_INT_STA__A                                             0xC10005
+#define ATV_TOP_COMM_INT_STA__W                                             16
+#define ATV_TOP_COMM_INT_STA__M                                             0xFFFF
+#define ATV_TOP_COMM_INT_STA__PRE                                           0x0
+
+#define   ATV_TOP_COMM_INT_STA_FAGC_STA__B                                  0
+#define   ATV_TOP_COMM_INT_STA_FAGC_STA__W                                  1
+#define   ATV_TOP_COMM_INT_STA_FAGC_STA__M                                  0x1
+#define   ATV_TOP_COMM_INT_STA_FAGC_STA__PRE                                0x0
+
+#define   ATV_TOP_COMM_INT_STA_OVM_STA__B                                   1
+#define   ATV_TOP_COMM_INT_STA_OVM_STA__W                                   1
+#define   ATV_TOP_COMM_INT_STA_OVM_STA__M                                   0x2
+#define   ATV_TOP_COMM_INT_STA_OVM_STA__PRE                                 0x0
+
+#define   ATV_TOP_COMM_INT_STA_AMPTH_STA__B                                 2
+#define   ATV_TOP_COMM_INT_STA_AMPTH_STA__W                                 1
+#define   ATV_TOP_COMM_INT_STA_AMPTH_STA__M                                 0x4
+#define   ATV_TOP_COMM_INT_STA_AMPTH_STA__PRE                               0x0
+
+#define ATV_TOP_COMM_INT_MSK__A                                             0xC10006
+#define ATV_TOP_COMM_INT_MSK__W                                             16
+#define ATV_TOP_COMM_INT_MSK__M                                             0xFFFF
+#define ATV_TOP_COMM_INT_MSK__PRE                                           0x0
+
+#define   ATV_TOP_COMM_INT_MSK_FAGC_MSK__B                                  0
+#define   ATV_TOP_COMM_INT_MSK_FAGC_MSK__W                                  1
+#define   ATV_TOP_COMM_INT_MSK_FAGC_MSK__M                                  0x1
+#define   ATV_TOP_COMM_INT_MSK_FAGC_MSK__PRE                                0x0
+
+#define   ATV_TOP_COMM_INT_MSK_OVM_MSK__B                                   1
+#define   ATV_TOP_COMM_INT_MSK_OVM_MSK__W                                   1
+#define   ATV_TOP_COMM_INT_MSK_OVM_MSK__M                                   0x2
+#define   ATV_TOP_COMM_INT_MSK_OVM_MSK__PRE                                 0x0
+
+#define   ATV_TOP_COMM_INT_MSK_AMPTH_MSK__B                                 2
+#define   ATV_TOP_COMM_INT_MSK_AMPTH_MSK__W                                 1
+#define   ATV_TOP_COMM_INT_MSK_AMPTH_MSK__M                                 0x4
+#define   ATV_TOP_COMM_INT_MSK_AMPTH_MSK__PRE                               0x0
+
+#define ATV_TOP_COMM_INT_STM__A                                             0xC10007
+#define ATV_TOP_COMM_INT_STM__W                                             16
+#define ATV_TOP_COMM_INT_STM__M                                             0xFFFF
+#define ATV_TOP_COMM_INT_STM__PRE                                           0x0
+
+#define   ATV_TOP_COMM_INT_STM_FAGC_STM__B                                  0
+#define   ATV_TOP_COMM_INT_STM_FAGC_STM__W                                  1
+#define   ATV_TOP_COMM_INT_STM_FAGC_STM__M                                  0x1
+#define   ATV_TOP_COMM_INT_STM_FAGC_STM__PRE                                0x0
+
+#define   ATV_TOP_COMM_INT_STM_OVM_STM__B                                   1
+#define   ATV_TOP_COMM_INT_STM_OVM_STM__W                                   1
+#define   ATV_TOP_COMM_INT_STM_OVM_STM__M                                   0x2
+#define   ATV_TOP_COMM_INT_STM_OVM_STM__PRE                                 0x0
+
+#define   ATV_TOP_COMM_INT_STM_AMPTH_STM__B                                 2
+#define   ATV_TOP_COMM_INT_STM_AMPTH_STM__W                                 1
+#define   ATV_TOP_COMM_INT_STM_AMPTH_STM__M                                 0x4
+#define   ATV_TOP_COMM_INT_STM_AMPTH_STM__PRE                               0x0
+
+#define ATV_TOP_COMM_KEY__A                                                 0xC1000F
+#define ATV_TOP_COMM_KEY__W                                                 16
+#define ATV_TOP_COMM_KEY__M                                                 0xFFFF
+#define ATV_TOP_COMM_KEY__PRE                                               0x0
+
+#define   ATV_TOP_COMM_KEY_KEY__B                                           0
+#define   ATV_TOP_COMM_KEY_KEY__W                                           16
+#define   ATV_TOP_COMM_KEY_KEY__M                                           0xFFFF
+#define   ATV_TOP_COMM_KEY_KEY__PRE                                         0x0
+#define     ATV_TOP_COMM_KEY_KEY_KEY                                        0xFABA
+#define     ATV_TOP_COMM_KEY_KEY_MIN                                        0x0
+#define     ATV_TOP_COMM_KEY_KEY_MAX                                        0xFFFF
+
+#define ATV_TOP_CR_AMP_TH__A                                                0xC10010
+#define ATV_TOP_CR_AMP_TH__W                                                8
+#define ATV_TOP_CR_AMP_TH__M                                                0xFF
+#define ATV_TOP_CR_AMP_TH__PRE                                              0x8
+#define   ATV_TOP_CR_AMP_TH_MN                                              0x8
+
+#define ATV_TOP_CR_CONT__A                                                  0xC10011
+#define ATV_TOP_CR_CONT__W                                                  9
+#define ATV_TOP_CR_CONT__M                                                  0x1FF
+#define ATV_TOP_CR_CONT__PRE                                                0x9C
+
+#define   ATV_TOP_CR_CONT_CR_P__B                                           0
+#define   ATV_TOP_CR_CONT_CR_P__W                                           3
+#define   ATV_TOP_CR_CONT_CR_P__M                                           0x7
+#define   ATV_TOP_CR_CONT_CR_P__PRE                                         0x4
+#define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4
+#define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0
+
+#define   ATV_TOP_CR_CONT_CR_D__B                                           3
+#define   ATV_TOP_CR_CONT_CR_D__W                                           3
+#define   ATV_TOP_CR_CONT_CR_D__M                                           0x38
+#define   ATV_TOP_CR_CONT_CR_D__PRE                                         0x18
+#define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18
+#define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0
+
+#define   ATV_TOP_CR_CONT_CR_I__B                                           6
+#define   ATV_TOP_CR_CONT_CR_I__W                                           3
+#define   ATV_TOP_CR_CONT_CR_I__M                                           0x1C0
+#define   ATV_TOP_CR_CONT_CR_I__PRE                                         0x80
+#define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80
+#define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0
+
+#define ATV_TOP_CR_OVM_TH__A                                                0xC10012
+#define ATV_TOP_CR_OVM_TH__W                                                8
+#define ATV_TOP_CR_OVM_TH__M                                                0xFF
+#define ATV_TOP_CR_OVM_TH__PRE                                              0xA0
+#define   ATV_TOP_CR_OVM_TH_MN                                              0xA0
+#define   ATV_TOP_CR_OVM_TH_FM                                              0x0
+
+#define ATV_TOP_NOISE_TH__A                                                 0xC10013
+#define ATV_TOP_NOISE_TH__W                                                 4
+#define ATV_TOP_NOISE_TH__M                                                 0xF
+#define ATV_TOP_NOISE_TH__PRE                                               0x8
+#define   ATV_TOP_NOISE_TH_MN                                               0x8
+
+#define ATV_TOP_EQU0__A                                                     0xC10014
+#define ATV_TOP_EQU0__W                                                     9
+#define ATV_TOP_EQU0__M                                                     0x1FF
+#define ATV_TOP_EQU0__PRE                                                   0x1FB
+
+#define   ATV_TOP_EQU0_EQU_C0__B                                            0
+#define   ATV_TOP_EQU0_EQU_C0__W                                            9
+#define   ATV_TOP_EQU0_EQU_C0__M                                            0x1FF
+#define   ATV_TOP_EQU0_EQU_C0__PRE                                          0x1FB
+#define     ATV_TOP_EQU0_EQU_C0_MN                                          0xFB
+
+#define ATV_TOP_EQU1__A                                                     0xC10015
+#define ATV_TOP_EQU1__W                                                     9
+#define ATV_TOP_EQU1__M                                                     0x1FF
+#define ATV_TOP_EQU1__PRE                                                   0x1CE
+
+#define   ATV_TOP_EQU1_EQU_C1__B                                            0
+#define   ATV_TOP_EQU1_EQU_C1__W                                            9
+#define   ATV_TOP_EQU1_EQU_C1__M                                            0x1FF
+#define   ATV_TOP_EQU1_EQU_C1__PRE                                          0x1CE
+#define     ATV_TOP_EQU1_EQU_C1_MN                                          0xCE
+
+#define ATV_TOP_EQU2__A                                                     0xC10016
+#define ATV_TOP_EQU2__W                                                     9
+#define ATV_TOP_EQU2__M                                                     0x1FF
+#define ATV_TOP_EQU2__PRE                                                   0xD2
+
+#define   ATV_TOP_EQU2_EQU_C2__B                                            0
+#define   ATV_TOP_EQU2_EQU_C2__W                                            9
+#define   ATV_TOP_EQU2_EQU_C2__M                                            0x1FF
+#define   ATV_TOP_EQU2_EQU_C2__PRE                                          0xD2
+#define     ATV_TOP_EQU2_EQU_C2_MN                                          0xD2
+
+#define ATV_TOP_EQU3__A                                                     0xC10017
+#define ATV_TOP_EQU3__W                                                     9
+#define ATV_TOP_EQU3__M                                                     0x1FF
+#define ATV_TOP_EQU3__PRE                                                   0x160
+
+#define   ATV_TOP_EQU3_EQU_C3__B                                            0
+#define   ATV_TOP_EQU3_EQU_C3__W                                            9
+#define   ATV_TOP_EQU3_EQU_C3__M                                            0x1FF
+#define   ATV_TOP_EQU3_EQU_C3__PRE                                          0x160
+#define     ATV_TOP_EQU3_EQU_C3_MN                                          0x60
+
+#define ATV_TOP_ROT_MODE__A                                                 0xC10018
+#define ATV_TOP_ROT_MODE__W                                                 1
+#define ATV_TOP_ROT_MODE__M                                                 0x1
+#define ATV_TOP_ROT_MODE__PRE                                               0x0
+#define   ATV_TOP_ROT_MODE_AMPTH_DEPEND                                     0x0
+#define   ATV_TOP_ROT_MODE_ALWAYS                                           0x1
+
+#define ATV_TOP_MOD_CONTROL__A                                              0xC10019
+#define ATV_TOP_MOD_CONTROL__W                                              12
+#define ATV_TOP_MOD_CONTROL__M                                              0xFFF
+#define ATV_TOP_MOD_CONTROL__PRE                                            0x5B1
+
+#define   ATV_TOP_MOD_CONTROL_MOD_IR__B                                     0
+#define   ATV_TOP_MOD_CONTROL_MOD_IR__W                                     3
+#define   ATV_TOP_MOD_CONTROL_MOD_IR__M                                     0x7
+#define   ATV_TOP_MOD_CONTROL_MOD_IR__PRE                                   0x1
+#define     ATV_TOP_MOD_CONTROL_MOD_IR_MN                                   0x1
+#define     ATV_TOP_MOD_CONTROL_MOD_IR_FM                                   0x0
+
+#define   ATV_TOP_MOD_CONTROL_MOD_IF__B                                     3
+#define   ATV_TOP_MOD_CONTROL_MOD_IF__W                                     4
+#define   ATV_TOP_MOD_CONTROL_MOD_IF__M                                     0x78
+#define   ATV_TOP_MOD_CONTROL_MOD_IF__PRE                                   0x30
+#define     ATV_TOP_MOD_CONTROL_MOD_IF_MN                                   0x30
+#define     ATV_TOP_MOD_CONTROL_MOD_IF_FM                                   0x0
+
+#define   ATV_TOP_MOD_CONTROL_MOD_MODE__B                                   7
+#define   ATV_TOP_MOD_CONTROL_MOD_MODE__W                                   1
+#define   ATV_TOP_MOD_CONTROL_MOD_MODE__M                                   0x80
+#define   ATV_TOP_MOD_CONTROL_MOD_MODE__PRE                                 0x80
+#define     ATV_TOP_MOD_CONTROL_MOD_MODE_RISE                               0x0
+#define     ATV_TOP_MOD_CONTROL_MOD_MODE_RISE_FALL                          0x80
+
+#define   ATV_TOP_MOD_CONTROL_MOD_TH__B                                     8
+#define   ATV_TOP_MOD_CONTROL_MOD_TH__W                                     4
+#define   ATV_TOP_MOD_CONTROL_MOD_TH__M                                     0xF00
+#define   ATV_TOP_MOD_CONTROL_MOD_TH__PRE                                   0x500
+#define     ATV_TOP_MOD_CONTROL_MOD_TH_MN                                   0x500
+#define     ATV_TOP_MOD_CONTROL_MOD_TH_FM                                   0x0
+
+#define ATV_TOP_STD__A                                                      0xC1001A
+#define ATV_TOP_STD__W                                                      2
+#define ATV_TOP_STD__M                                                      0x3
+#define ATV_TOP_STD__PRE                                                    0x0
+
+#define   ATV_TOP_STD_MODE__B                                               0
+#define   ATV_TOP_STD_MODE__W                                               1
+#define   ATV_TOP_STD_MODE__M                                               0x1
+#define   ATV_TOP_STD_MODE__PRE                                             0x0
+#define     ATV_TOP_STD_MODE_MN                                             0x0
+#define     ATV_TOP_STD_MODE_FM                                             0x1
+
+#define   ATV_TOP_STD_VID_POL__B                                            1
+#define   ATV_TOP_STD_VID_POL__W                                            1
+#define   ATV_TOP_STD_VID_POL__M                                            0x2
+#define   ATV_TOP_STD_VID_POL__PRE                                          0x0
+#define     ATV_TOP_STD_VID_POL_NEG                                         0x0
+#define     ATV_TOP_STD_VID_POL_POS                                         0x2
+
+#define ATV_TOP_VID_AMP__A                                                  0xC1001B
+#define ATV_TOP_VID_AMP__W                                                  12
+#define ATV_TOP_VID_AMP__M                                                  0xFFF
+#define ATV_TOP_VID_AMP__PRE                                                0x380
+#define   ATV_TOP_VID_AMP_MN                                                0x380
+#define   ATV_TOP_VID_AMP_FM                                                0x0
+
+#define ATV_TOP_VID_PEAK__A                                                 0xC1001C
+#define ATV_TOP_VID_PEAK__W                                                 5
+#define ATV_TOP_VID_PEAK__M                                                 0x1F
+#define ATV_TOP_VID_PEAK__PRE                                               0x1
+
+#define ATV_TOP_FAGC_TH__A                                                  0xC1001D
+#define ATV_TOP_FAGC_TH__W                                                  11
+#define ATV_TOP_FAGC_TH__M                                                  0x7FF
+#define ATV_TOP_FAGC_TH__PRE                                                0x2B2
+#define   ATV_TOP_FAGC_TH_MN                                                0x2B2
+
+#define ATV_TOP_SYNC_SLICE__A                                               0xC1001E
+#define ATV_TOP_SYNC_SLICE__W                                               11
+#define ATV_TOP_SYNC_SLICE__M                                               0x7FF
+#define ATV_TOP_SYNC_SLICE__PRE                                             0x243
+#define   ATV_TOP_SYNC_SLICE_MN                                             0x243
+
+#define ATV_TOP_SIF_GAIN__A                                                 0xC1001F
+#define ATV_TOP_SIF_GAIN__W                                                 11
+#define ATV_TOP_SIF_GAIN__M                                                 0x7FF
+#define ATV_TOP_SIF_GAIN__PRE                                               0x0
+
+#define ATV_TOP_SIF_TP__A                                                   0xC10020
+#define ATV_TOP_SIF_TP__W                                                   6
+#define ATV_TOP_SIF_TP__M                                                   0x3F
+#define ATV_TOP_SIF_TP__PRE                                                 0x0
+
+#define ATV_TOP_MOD_ACCU__A                                                 0xC10021
+#define ATV_TOP_MOD_ACCU__W                                                 10
+#define ATV_TOP_MOD_ACCU__M                                                 0x3FF
+#define ATV_TOP_MOD_ACCU__PRE                                               0x0
+
+#define ATV_TOP_CR_FREQ__A                                                  0xC10022
+#define ATV_TOP_CR_FREQ__W                                                  8
+#define ATV_TOP_CR_FREQ__M                                                  0xFF
+#define ATV_TOP_CR_FREQ__PRE                                                0x0
+
+#define ATV_TOP_CR_PHAD__A                                                  0xC10023
+#define ATV_TOP_CR_PHAD__W                                                  12
+#define ATV_TOP_CR_PHAD__M                                                  0xFFF
+#define ATV_TOP_CR_PHAD__PRE                                                0x0
+
+#define ATV_TOP_AF_SIF_ATT__A                                               0xC10024
+#define ATV_TOP_AF_SIF_ATT__W                                               2
+#define ATV_TOP_AF_SIF_ATT__M                                               0x3
+#define ATV_TOP_AF_SIF_ATT__PRE                                             0x0
+#define   ATV_TOP_AF_SIF_ATT_0DB                                            0x0
+#define   ATV_TOP_AF_SIF_ATT_M3DB                                           0x1
+#define   ATV_TOP_AF_SIF_ATT_M6DB                                           0x2
+#define   ATV_TOP_AF_SIF_ATT_M9DB                                           0x3
+
+#define ATV_TOP_STDBY__A                                                    0xC10025
+#define ATV_TOP_STDBY__W                                                    2
+#define ATV_TOP_STDBY__M                                                    0x3
+#define ATV_TOP_STDBY__PRE                                                  0x1
+
+#define   ATV_TOP_STDBY_SIF_STDBY__B                                        0
+#define   ATV_TOP_STDBY_SIF_STDBY__W                                        1
+#define   ATV_TOP_STDBY_SIF_STDBY__M                                        0x1
+#define   ATV_TOP_STDBY_SIF_STDBY__PRE                                      0x1
+#define     ATV_TOP_STDBY_SIF_STDBY_ACTIVE                                  0x0
+#define     ATV_TOP_STDBY_SIF_STDBY_STANDBY                                 0x1
+
+#define   ATV_TOP_STDBY_CVBS_STDBY__B                                       1
+#define   ATV_TOP_STDBY_CVBS_STDBY__W                                       1
+#define   ATV_TOP_STDBY_CVBS_STDBY__M                                       0x2
+#define   ATV_TOP_STDBY_CVBS_STDBY__PRE                                     0x0
+#define     ATV_TOP_STDBY_CVBS_STDBY_A1_ACTIVE                              0x0
+#define     ATV_TOP_STDBY_CVBS_STDBY_A1_STANDBY                             0x2
+#define     ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE                              0x2
+#define     ATV_TOP_STDBY_CVBS_STDBY_A2_STANDBY                             0x0
+
+#define ATV_TOP_OVERRIDE_SFR__A                                             0xC10026
+#define ATV_TOP_OVERRIDE_SFR__W                                             1
+#define ATV_TOP_OVERRIDE_SFR__M                                             0x1
+#define ATV_TOP_OVERRIDE_SFR__PRE                                           0x0
+#define   ATV_TOP_OVERRIDE_SFR_ACTIVE                                       0x0
+#define   ATV_TOP_OVERRIDE_SFR_OVERRIDE                                     0x1
+
+#define ATV_TOP_SFR_VID_GAIN__A                                             0xC10027
+#define ATV_TOP_SFR_VID_GAIN__W                                             16
+#define ATV_TOP_SFR_VID_GAIN__M                                             0xFFFF
+#define ATV_TOP_SFR_VID_GAIN__PRE                                           0x0
+
+#define ATV_TOP_SFR_AGC_RES__A                                              0xC10028
+#define ATV_TOP_SFR_AGC_RES__W                                              5
+#define ATV_TOP_SFR_AGC_RES__M                                              0x1F
+#define ATV_TOP_SFR_AGC_RES__PRE                                            0x0
+
+#define ATV_TOP_OVM_COMP__A                                                 0xC10029
+#define ATV_TOP_OVM_COMP__W                                                 12
+#define ATV_TOP_OVM_COMP__M                                                 0xFFF
+#define ATV_TOP_OVM_COMP__PRE                                               0x0
+#define ATV_TOP_OUT_CONF__A                                                 0xC1002A
+#define ATV_TOP_OUT_CONF__W                                                 5
+#define ATV_TOP_OUT_CONF__M                                                 0x1F
+#define ATV_TOP_OUT_CONF__PRE                                               0x0
+
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_SIGN__B                                 0
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_SIGN__W                                 1
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_SIGN__M                                 0x1
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_SIGN__PRE                               0x0
+#define     ATV_TOP_OUT_CONF_CVBS_DAC_SIGN_UNSIGNED                         0x0
+#define     ATV_TOP_OUT_CONF_CVBS_DAC_SIGN_SIGNED                           0x1
+
+#define   ATV_TOP_OUT_CONF_SIF_DAC_SIGN__B                                  1
+#define   ATV_TOP_OUT_CONF_SIF_DAC_SIGN__W                                  1
+#define   ATV_TOP_OUT_CONF_SIF_DAC_SIGN__M                                  0x2
+#define   ATV_TOP_OUT_CONF_SIF_DAC_SIGN__PRE                                0x0
+#define     ATV_TOP_OUT_CONF_SIF_DAC_SIGN_UNSIGNED                          0x0
+#define     ATV_TOP_OUT_CONF_SIF_DAC_SIGN_SIGNED                            0x2
+
+#define   ATV_TOP_OUT_CONF_SIF20_SIGN__B                                    2
+#define   ATV_TOP_OUT_CONF_SIF20_SIGN__W                                    1
+#define   ATV_TOP_OUT_CONF_SIF20_SIGN__M                                    0x4
+#define   ATV_TOP_OUT_CONF_SIF20_SIGN__PRE                                  0x0
+#define     ATV_TOP_OUT_CONF_SIF20_SIGN_UNSIGNED                            0x0
+#define     ATV_TOP_OUT_CONF_SIF20_SIGN_SIGNED                              0x4
+
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_BR__B                                   3
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_BR__W                                   1
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_BR__M                                   0x8
+#define   ATV_TOP_OUT_CONF_CVBS_DAC_BR__PRE                                 0x0
+#define     ATV_TOP_OUT_CONF_CVBS_DAC_BR_NORMAL                             0x0
+#define     ATV_TOP_OUT_CONF_CVBS_DAC_BR_BITREVERSED                        0x8
+
+#define   ATV_TOP_OUT_CONF_SIF_DAC_BR__B                                    4
+#define   ATV_TOP_OUT_CONF_SIF_DAC_BR__W                                    1
+#define   ATV_TOP_OUT_CONF_SIF_DAC_BR__M                                    0x10
+#define   ATV_TOP_OUT_CONF_SIF_DAC_BR__PRE                                  0x0
+#define     ATV_TOP_OUT_CONF_SIF_DAC_BR_NORMAL                              0x0
+#define     ATV_TOP_OUT_CONF_SIF_DAC_BR_BITREVERSED                         0x10
+
+#define ATV_AFT_COMM_EXEC__A                                                0xFF0000
+#define ATV_AFT_COMM_EXEC__W                                                2
+#define ATV_AFT_COMM_EXEC__M                                                0x3
+#define ATV_AFT_COMM_EXEC__PRE                                              0x0
+#define   ATV_AFT_COMM_EXEC_STOP                                            0x0
+#define   ATV_AFT_COMM_EXEC_ACTIVE                                          0x1
+#define   ATV_AFT_COMM_EXEC_HOLD                                            0x2
+
+#define ATV_AFT_TST__A                                                      0xFF0010
+#define ATV_AFT_TST__W                                                      4
+#define ATV_AFT_TST__M                                                      0xF
+#define ATV_AFT_TST__PRE                                                    0x0
+
+#define AUD_COMM_EXEC__A                                                    0x1000000
+#define AUD_COMM_EXEC__W                                                    2
+#define AUD_COMM_EXEC__M                                                    0x3
+#define AUD_COMM_EXEC__PRE                                                  0x0
+#define   AUD_COMM_EXEC_STOP                                                0x0
+#define   AUD_COMM_EXEC_ACTIVE                                              0x1
+
+#define AUD_COMM_MB__A                                                      0x1000002
+#define AUD_COMM_MB__W                                                      16
+#define AUD_COMM_MB__M                                                      0xFFFF
+#define AUD_COMM_MB__PRE                                                    0x0
+
+#define AUD_TOP_COMM_EXEC__A                                                0x1010000
+#define AUD_TOP_COMM_EXEC__W                                                2
+#define AUD_TOP_COMM_EXEC__M                                                0x3
+#define AUD_TOP_COMM_EXEC__PRE                                              0x0
+#define   AUD_TOP_COMM_EXEC_STOP                                            0x0
+#define   AUD_TOP_COMM_EXEC_ACTIVE                                          0x1
+
+#define AUD_TOP_COMM_MB__A                                                  0x1010002
+#define AUD_TOP_COMM_MB__W                                                  16
+#define AUD_TOP_COMM_MB__M                                                  0xFFFF
+#define AUD_TOP_COMM_MB__PRE                                                0x0
+
+#define   AUD_TOP_COMM_MB_CTL__B                                            0
+#define   AUD_TOP_COMM_MB_CTL__W                                            1
+#define   AUD_TOP_COMM_MB_CTL__M                                            0x1
+#define   AUD_TOP_COMM_MB_CTL__PRE                                          0x0
+#define     AUD_TOP_COMM_MB_CTL_CTR_OFF                                     0x0
+#define     AUD_TOP_COMM_MB_CTL_CTR_ON                                      0x1
+
+#define   AUD_TOP_COMM_MB_OBS__B                                            1
+#define   AUD_TOP_COMM_MB_OBS__W                                            1
+#define   AUD_TOP_COMM_MB_OBS__M                                            0x2
+#define   AUD_TOP_COMM_MB_OBS__PRE                                          0x0
+#define     AUD_TOP_COMM_MB_OBS_OBS_OFF                                     0x0
+#define     AUD_TOP_COMM_MB_OBS_OBS_ON                                      0x2
+
+#define   AUD_TOP_COMM_MB_MUX_CTRL__B                                       2
+#define   AUD_TOP_COMM_MB_MUX_CTRL__W                                       4
+#define   AUD_TOP_COMM_MB_MUX_CTRL__M                                       0x3C
+#define   AUD_TOP_COMM_MB_MUX_CTRL__PRE                                     0x0
+#define     AUD_TOP_COMM_MB_MUX_CTRL_DEMOD_TBO                              0x0
+#define     AUD_TOP_COMM_MB_MUX_CTRL_XDFP_IRQS                              0x4
+#define     AUD_TOP_COMM_MB_MUX_CTRL_OBSERVEPC                              0x8
+#define     AUD_TOP_COMM_MB_MUX_CTRL_SAOUT                                  0xC
+#define     AUD_TOP_COMM_MB_MUX_CTRL_XDFP_SCHEQ                             0x10
+
+#define   AUD_TOP_COMM_MB_MUX_OBS__B                                        6
+#define   AUD_TOP_COMM_MB_MUX_OBS__W                                        4
+#define   AUD_TOP_COMM_MB_MUX_OBS__M                                        0x3C0
+#define   AUD_TOP_COMM_MB_MUX_OBS__PRE                                      0x0
+#define     AUD_TOP_COMM_MB_MUX_OBS_DEMOD_TBO                               0x0
+#define     AUD_TOP_COMM_MB_MUX_OBS_XDFP_IRQS                               0x40
+#define     AUD_TOP_COMM_MB_MUX_OBS_OBSERVEPC                               0x80
+#define     AUD_TOP_COMM_MB_MUX_OBS_SAOUT                                   0xC0
+#define     AUD_TOP_COMM_MB_MUX_OBS_XDFP_SCHEQ                              0x100
+
+#define AUD_TOP_TR_MDE__A                                                   0x1010010
+#define AUD_TOP_TR_MDE__W                                                   5
+#define AUD_TOP_TR_MDE__M                                                   0x1F
+#define AUD_TOP_TR_MDE__PRE                                                 0x18
+
+#define   AUD_TOP_TR_MDE_FIFO_SIZE__B                                       0
+#define   AUD_TOP_TR_MDE_FIFO_SIZE__W                                       4
+#define   AUD_TOP_TR_MDE_FIFO_SIZE__M                                       0xF
+#define   AUD_TOP_TR_MDE_FIFO_SIZE__PRE                                     0x8
+
+#define   AUD_TOP_TR_MDE_RD_LOCK__B                                         4
+#define   AUD_TOP_TR_MDE_RD_LOCK__W                                         1
+#define   AUD_TOP_TR_MDE_RD_LOCK__M                                         0x10
+#define   AUD_TOP_TR_MDE_RD_LOCK__PRE                                       0x10
+#define     AUD_TOP_TR_MDE_RD_LOCK_NORMAL                                   0x0
+#define     AUD_TOP_TR_MDE_RD_LOCK_LOCK                                     0x10
+
+#define AUD_TOP_TR_CTR__A                                                   0x1010011
+#define AUD_TOP_TR_CTR__W                                                   4
+#define AUD_TOP_TR_CTR__M                                                   0xF
+#define AUD_TOP_TR_CTR__PRE                                                 0x0
+
+#define   AUD_TOP_TR_CTR_FIFO_RD_RDY__B                                     0
+#define   AUD_TOP_TR_CTR_FIFO_RD_RDY__W                                     1
+#define   AUD_TOP_TR_CTR_FIFO_RD_RDY__M                                     0x1
+#define   AUD_TOP_TR_CTR_FIFO_RD_RDY__PRE                                   0x0
+#define     AUD_TOP_TR_CTR_FIFO_RD_RDY_NOT_READY                            0x0
+#define     AUD_TOP_TR_CTR_FIFO_RD_RDY_READY                                0x1
+
+#define   AUD_TOP_TR_CTR_FIFO_EMPTY__B                                      1
+#define   AUD_TOP_TR_CTR_FIFO_EMPTY__W                                      1
+#define   AUD_TOP_TR_CTR_FIFO_EMPTY__M                                      0x2
+#define   AUD_TOP_TR_CTR_FIFO_EMPTY__PRE                                    0x0
+#define     AUD_TOP_TR_CTR_FIFO_EMPTY_NOT_EMPTY                             0x0
+#define     AUD_TOP_TR_CTR_FIFO_EMPTY_EMPTY                                 0x2
+
+#define   AUD_TOP_TR_CTR_FIFO_LOCK__B                                       2
+#define   AUD_TOP_TR_CTR_FIFO_LOCK__W                                       1
+#define   AUD_TOP_TR_CTR_FIFO_LOCK__M                                       0x4
+#define   AUD_TOP_TR_CTR_FIFO_LOCK__PRE                                     0x0
+#define     AUD_TOP_TR_CTR_FIFO_LOCK_UNLOCKED                               0x0
+#define     AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED                                 0x4
+
+#define   AUD_TOP_TR_CTR_FIFO_FULL__B                                       3
+#define   AUD_TOP_TR_CTR_FIFO_FULL__W                                       1
+#define   AUD_TOP_TR_CTR_FIFO_FULL__M                                       0x8
+#define   AUD_TOP_TR_CTR_FIFO_FULL__PRE                                     0x0
+#define     AUD_TOP_TR_CTR_FIFO_FULL_EMPTY                                  0x0
+#define     AUD_TOP_TR_CTR_FIFO_FULL_FULL                                   0x8
+
+#define AUD_TOP_TR_RD_REG__A                                                0x1010012
+#define AUD_TOP_TR_RD_REG__W                                                16
+#define AUD_TOP_TR_RD_REG__M                                                0xFFFF
+#define AUD_TOP_TR_RD_REG__PRE                                              0x0
+
+#define   AUD_TOP_TR_RD_REG_RESULT__B                                       0
+#define   AUD_TOP_TR_RD_REG_RESULT__W                                       16
+#define   AUD_TOP_TR_RD_REG_RESULT__M                                       0xFFFF
+#define   AUD_TOP_TR_RD_REG_RESULT__PRE                                     0x0
+
+#define AUD_TOP_TR_TIMER__A                                                 0x1010013
+#define AUD_TOP_TR_TIMER__W                                                 16
+#define AUD_TOP_TR_TIMER__M                                                 0xFFFF
+#define AUD_TOP_TR_TIMER__PRE                                               0x0
+
+#define   AUD_TOP_TR_TIMER_CYCLES__B                                        0
+#define   AUD_TOP_TR_TIMER_CYCLES__W                                        16
+#define   AUD_TOP_TR_TIMER_CYCLES__M                                        0xFFFF
+#define   AUD_TOP_TR_TIMER_CYCLES__PRE                                      0x0
+
+#define AUD_TOP_DEMOD_TBO_SEL__A                                            0x1010014
+#define AUD_TOP_DEMOD_TBO_SEL__W                                            5
+#define AUD_TOP_DEMOD_TBO_SEL__M                                            0x1F
+#define AUD_TOP_DEMOD_TBO_SEL__PRE                                          0x0
+
+#define AUD_DEM_WR_MODUS__A                                                 0x1030030
+#define AUD_DEM_WR_MODUS__W                                                 16
+#define AUD_DEM_WR_MODUS__M                                                 0xFFFF
+#define AUD_DEM_WR_MODUS__PRE                                               0x0
+
+#define   AUD_DEM_WR_MODUS_MOD_ASS__B                                       0
+#define   AUD_DEM_WR_MODUS_MOD_ASS__W                                       1
+#define   AUD_DEM_WR_MODUS_MOD_ASS__M                                       0x1
+#define   AUD_DEM_WR_MODUS_MOD_ASS__PRE                                     0x0
+#define     AUD_DEM_WR_MODUS_MOD_ASS_OFF                                    0x0
+#define     AUD_DEM_WR_MODUS_MOD_ASS_ON                                     0x1
+
+#define   AUD_DEM_WR_MODUS_MOD_STATINTERR__B                                1
+#define   AUD_DEM_WR_MODUS_MOD_STATINTERR__W                                1
+#define   AUD_DEM_WR_MODUS_MOD_STATINTERR__M                                0x2
+#define   AUD_DEM_WR_MODUS_MOD_STATINTERR__PRE                              0x0
+#define     AUD_DEM_WR_MODUS_MOD_STATINTERR_DISABLE                         0x0
+#define     AUD_DEM_WR_MODUS_MOD_STATINTERR_ENABLE                          0x2
+
+#define   AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__B                               2
+#define   AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__W                               1
+#define   AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M                               0x4
+#define   AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__PRE                             0x0
+#define     AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED                        0x0
+#define     AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED                       0x4
+
+#define   AUD_DEM_WR_MODUS_MOD_HDEV_A__B                                    8
+#define   AUD_DEM_WR_MODUS_MOD_HDEV_A__W                                    1
+#define   AUD_DEM_WR_MODUS_MOD_HDEV_A__M                                    0x100
+#define   AUD_DEM_WR_MODUS_MOD_HDEV_A__PRE                                  0x0
+#define     AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL                              0x0
+#define     AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION                      0x100
+
+#define   AUD_DEM_WR_MODUS_MOD_CM_A__B                                      9
+#define   AUD_DEM_WR_MODUS_MOD_CM_A__W                                      1
+#define   AUD_DEM_WR_MODUS_MOD_CM_A__M                                      0x200
+#define   AUD_DEM_WR_MODUS_MOD_CM_A__PRE                                    0x0
+#define     AUD_DEM_WR_MODUS_MOD_CM_A_MUTE                                  0x0
+#define     AUD_DEM_WR_MODUS_MOD_CM_A_NOISE                                 0x200
+
+#define   AUD_DEM_WR_MODUS_MOD_CM_B__B                                      10
+#define   AUD_DEM_WR_MODUS_MOD_CM_B__W                                      1
+#define   AUD_DEM_WR_MODUS_MOD_CM_B__M                                      0x400
+#define   AUD_DEM_WR_MODUS_MOD_CM_B__PRE                                    0x0
+#define     AUD_DEM_WR_MODUS_MOD_CM_B_MUTE                                  0x0
+#define     AUD_DEM_WR_MODUS_MOD_CM_B_NOISE                                 0x400
+
+#define   AUD_DEM_WR_MODUS_MOD_FMRADIO__B                                   11
+#define   AUD_DEM_WR_MODUS_MOD_FMRADIO__W                                   1
+#define   AUD_DEM_WR_MODUS_MOD_FMRADIO__M                                   0x800
+#define   AUD_DEM_WR_MODUS_MOD_FMRADIO__PRE                                 0x0
+#define     AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U                             0x0
+#define     AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U                             0x800
+
+#define   AUD_DEM_WR_MODUS_MOD_6_5MHZ__B                                    12
+#define   AUD_DEM_WR_MODUS_MOD_6_5MHZ__W                                    1
+#define   AUD_DEM_WR_MODUS_MOD_6_5MHZ__M                                    0x1000
+#define   AUD_DEM_WR_MODUS_MOD_6_5MHZ__PRE                                  0x0
+#define     AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM                               0x0
+#define     AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K                                 0x1000
+
+#define   AUD_DEM_WR_MODUS_MOD_4_5MHZ__B                                    13
+#define   AUD_DEM_WR_MODUS_MOD_4_5MHZ__W                                    2
+#define   AUD_DEM_WR_MODUS_MOD_4_5MHZ__M                                    0x6000
+#define   AUD_DEM_WR_MODUS_MOD_4_5MHZ__PRE                                  0x0
+#define     AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_KOREA                             0x0
+#define     AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC                              0x2000
+#define     AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_EIAJ                              0x4000
+#define     AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA                              0x6000
+
+#define   AUD_DEM_WR_MODUS_MOD_BTSC__B                                      15
+#define   AUD_DEM_WR_MODUS_MOD_BTSC__W                                      1
+#define   AUD_DEM_WR_MODUS_MOD_BTSC__M                                      0x8000
+#define   AUD_DEM_WR_MODUS_MOD_BTSC__PRE                                    0x0
+#define     AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO                           0x0
+#define     AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP                              0x8000
+
+#define AUD_DEM_WR_STANDARD_SEL__A                                          0x1030020
+#define AUD_DEM_WR_STANDARD_SEL__W                                          16
+#define AUD_DEM_WR_STANDARD_SEL__M                                          0xFFFF
+#define AUD_DEM_WR_STANDARD_SEL__PRE                                        0x0
+
+#define   AUD_DEM_WR_STANDARD_SEL_STD_SEL__B                                0
+#define   AUD_DEM_WR_STANDARD_SEL_STD_SEL__W                                12
+#define   AUD_DEM_WR_STANDARD_SEL_STD_SEL__M                                0xFFF
+#define   AUD_DEM_WR_STANDARD_SEL_STD_SEL__PRE                              0x0
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO                            0x1
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA                         0x2
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM                           0x3
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1                            0x4
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2                            0x5
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3                            0x7
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM                     0x8
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM                      0x9
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM                      0xA
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM                    0xB
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO                     0x20
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP                        0x21
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J                           0x30
+#define     AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO                        0x40
+
+#define AUD_DEM_RD_STANDARD_RES__A                                          0x102007E
+#define AUD_DEM_RD_STANDARD_RES__W                                          16
+#define AUD_DEM_RD_STANDARD_RES__M                                          0xFFFF
+#define AUD_DEM_RD_STANDARD_RES__PRE                                        0x0
+
+#define   AUD_DEM_RD_STANDARD_RES_STD_RESULT__B                             0
+#define   AUD_DEM_RD_STANDARD_RES_STD_RESULT__W                             16
+#define   AUD_DEM_RD_STANDARD_RES_STD_RESULT__M                             0xFFFF
+#define   AUD_DEM_RD_STANDARD_RES_STD_RESULT__PRE                           0x0
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD            0x0
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM       0x2
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM          0x3
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM         0x4
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM         0x5
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM         0x7
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM                 0x8
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM                   0x9
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM                   0xA
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM                 0xB
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO                  0x20
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP                0x21
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J                   0x30
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO                     0x40
+#define     AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE       0x7FF
+
+#define AUD_DEM_RD_STATUS__A                                                0x1020200
+#define AUD_DEM_RD_STATUS__W                                                16
+#define AUD_DEM_RD_STATUS__M                                                0xFFFF
+#define AUD_DEM_RD_STATUS__PRE                                              0x0
+
+#define   AUD_DEM_RD_STATUS_STAT_NEW_RDS__B                                 0
+#define   AUD_DEM_RD_STATUS_STAT_NEW_RDS__W                                 1
+#define   AUD_DEM_RD_STATUS_STAT_NEW_RDS__M                                 0x1
+#define   AUD_DEM_RD_STATUS_STAT_NEW_RDS__PRE                               0x0
+#define     AUD_DEM_RD_STATUS_STAT_NEW_RDS_NO_RDS_DATA                      0x0
+#define     AUD_DEM_RD_STATUS_STAT_NEW_RDS_NEW_RDS_DATA                     0x1
+
+#define   AUD_DEM_RD_STATUS_STAT_CARR_A__B                                  1
+#define   AUD_DEM_RD_STATUS_STAT_CARR_A__W                                  1
+#define   AUD_DEM_RD_STATUS_STAT_CARR_A__M                                  0x2
+#define   AUD_DEM_RD_STATUS_STAT_CARR_A__PRE                                0x0
+#define     AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED                          0x0
+#define     AUD_DEM_RD_STATUS_STAT_CARR_A_NOT_DETECTED                      0x2
+
+#define   AUD_DEM_RD_STATUS_STAT_CARR_B__B                                  2
+#define   AUD_DEM_RD_STATUS_STAT_CARR_B__W                                  1
+#define   AUD_DEM_RD_STATUS_STAT_CARR_B__M                                  0x4
+#define   AUD_DEM_RD_STATUS_STAT_CARR_B__PRE                                0x0
+#define     AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED                          0x0
+#define     AUD_DEM_RD_STATUS_STAT_CARR_B_NOT_DETECTED                      0x4
+
+#define   AUD_DEM_RD_STATUS_STAT_NICAM__B                                   5
+#define   AUD_DEM_RD_STATUS_STAT_NICAM__W                                   1
+#define   AUD_DEM_RD_STATUS_STAT_NICAM__M                                   0x20
+#define   AUD_DEM_RD_STATUS_STAT_NICAM__PRE                                 0x0
+#define     AUD_DEM_RD_STATUS_STAT_NICAM_NO_NICAM                           0x0
+#define     AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED                     0x20
+
+#define   AUD_DEM_RD_STATUS_STAT_STEREO__B                                  6
+#define   AUD_DEM_RD_STATUS_STAT_STEREO__W                                  1
+#define   AUD_DEM_RD_STATUS_STAT_STEREO__M                                  0x40
+#define   AUD_DEM_RD_STATUS_STAT_STEREO__PRE                                0x0
+#define     AUD_DEM_RD_STATUS_STAT_STEREO_NO_STEREO                         0x0
+#define     AUD_DEM_RD_STATUS_STAT_STEREO_STEREO                            0x40
+
+#define   AUD_DEM_RD_STATUS_STAT_INDEP_MONO__B                              7
+#define   AUD_DEM_RD_STATUS_STAT_INDEP_MONO__W                              1
+#define   AUD_DEM_RD_STATUS_STAT_INDEP_MONO__M                              0x80
+#define   AUD_DEM_RD_STATUS_STAT_INDEP_MONO__PRE                            0x0
+#define     AUD_DEM_RD_STATUS_STAT_INDEP_MONO_DEPENDENT_FM_MONO_PROGRAM     0x0
+#define     AUD_DEM_RD_STATUS_STAT_INDEP_MONO_INDEPENDENT_FM_MONO_PROGRAM   0x80
+
+#define   AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__B                              8
+#define   AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__W                              1
+#define   AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M                              0x100
+#define   AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__PRE                            0x0
+#define     AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_NO_SAP                        0x0
+#define     AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP                           0x100
+
+#define   AUD_DEM_RD_STATUS_BAD_NICAM__B                                    9
+#define   AUD_DEM_RD_STATUS_BAD_NICAM__W                                    1
+#define   AUD_DEM_RD_STATUS_BAD_NICAM__M                                    0x200
+#define   AUD_DEM_RD_STATUS_BAD_NICAM__PRE                                  0x0
+#define     AUD_DEM_RD_STATUS_BAD_NICAM_OK                                  0x0
+#define     AUD_DEM_RD_STATUS_BAD_NICAM_BAD                                 0x200
+
+#define AUD_DEM_RD_RDS_ARRAY_CNT__A                                         0x102020F
+#define AUD_DEM_RD_RDS_ARRAY_CNT__W                                         12
+#define AUD_DEM_RD_RDS_ARRAY_CNT__M                                         0xFFF
+#define AUD_DEM_RD_RDS_ARRAY_CNT__PRE                                       0x0
+
+#define   AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT__B                          0
+#define   AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT__W                          12
+#define   AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT__M                          0xFFF
+#define   AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT__PRE                        0x0
+#define     AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID        0xFFF
+
+#define AUD_DEM_RD_RDS_DATA__A                                              0x1020210
+#define AUD_DEM_RD_RDS_DATA__W                                              12
+#define AUD_DEM_RD_RDS_DATA__M                                              0xFFF
+#define AUD_DEM_RD_RDS_DATA__PRE                                            0x0
+
+#define AUD_DSP_WR_FM_PRESC__A                                              0x105000E
+#define AUD_DSP_WR_FM_PRESC__W                                              16
+#define AUD_DSP_WR_FM_PRESC__M                                              0xFFFF
+#define AUD_DSP_WR_FM_PRESC__PRE                                            0x0
+
+#define   AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B                                8
+#define   AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__W                                8
+#define   AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__M                                0xFF00
+#define   AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__PRE                              0x0
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION             0x7F00
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_50_KHZ_FM_DEVIATION             0x4800
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_75_KHZ_FM_DEVIATION             0x3000
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_100_KHZ_FM_DEVIATION            0x2400
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_150_KHZ_FM_DEVIATION            0x1800
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_180_KHZ_FM_DEVIATION            0x1300
+#define     AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_380_KHZ_FM_DEVIATION            0x900
+
+#define AUD_DSP_WR_NICAM_PRESC__A                                           0x1050010
+#define AUD_DSP_WR_NICAM_PRESC__W                                           16
+#define AUD_DSP_WR_NICAM_PRESC__M                                           0xFFFF
+#define AUD_DSP_WR_NICAM_PRESC__PRE                                         0x0
+#define AUD_DSP_WR_VOLUME__A                                                0x1050000
+#define AUD_DSP_WR_VOLUME__W                                                16
+#define AUD_DSP_WR_VOLUME__M                                                0xFFFF
+#define AUD_DSP_WR_VOLUME__PRE                                              0x0
+
+#define   AUD_DSP_WR_VOLUME_VOL_MAIN__B                                     8
+#define   AUD_DSP_WR_VOLUME_VOL_MAIN__W                                     8
+#define   AUD_DSP_WR_VOLUME_VOL_MAIN__M                                     0xFF00
+#define   AUD_DSP_WR_VOLUME_VOL_MAIN__PRE                                   0x0
+
+#define AUD_DSP_WR_SRC_I2S_MATR__A                                          0x1050038
+#define AUD_DSP_WR_SRC_I2S_MATR__W                                          16
+#define AUD_DSP_WR_SRC_I2S_MATR__M                                          0xFFFF
+#define AUD_DSP_WR_SRC_I2S_MATR__PRE                                        0x0
+
+#define   AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__B                                8
+#define   AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__W                                8
+#define   AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M                                0xFF00
+#define   AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__PRE                              0x0
+#define     AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO                            0x0
+#define     AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB                       0x100
+#define     AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A                        0x300
+#define     AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B                        0x400
+
+#define   AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__B                                0
+#define   AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__W                                8
+#define   AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M                                0xFF
+#define   AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__PRE                              0x0
+#define     AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A                         0x0
+#define     AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B                         0x10
+#define     AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO                          0x20
+#define     AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO                            0x30
+
+#define AUD_DSP_WR_AVC__A                                                   0x1050029
+#define AUD_DSP_WR_AVC__W                                                   16
+#define AUD_DSP_WR_AVC__M                                                   0xFFFF
+#define AUD_DSP_WR_AVC__PRE                                                 0x0
+
+#define   AUD_DSP_WR_AVC_AVC_ON__B                                          14
+#define   AUD_DSP_WR_AVC_AVC_ON__W                                          2
+#define   AUD_DSP_WR_AVC_AVC_ON__M                                          0xC000
+#define   AUD_DSP_WR_AVC_AVC_ON__PRE                                        0x0
+#define     AUD_DSP_WR_AVC_AVC_ON_OFF                                       0x0
+#define     AUD_DSP_WR_AVC_AVC_ON_ON                                        0xC000
+
+#define   AUD_DSP_WR_AVC_AVC_DECAY__B                                       8
+#define   AUD_DSP_WR_AVC_AVC_DECAY__W                                       4
+#define   AUD_DSP_WR_AVC_AVC_DECAY__M                                       0xF00
+#define   AUD_DSP_WR_AVC_AVC_DECAY__PRE                                     0x0
+#define     AUD_DSP_WR_AVC_AVC_DECAY_8_SEC                                  0x800
+#define     AUD_DSP_WR_AVC_AVC_DECAY_4_SEC                                  0x400
+#define     AUD_DSP_WR_AVC_AVC_DECAY_2_SEC                                  0x200
+#define     AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC                                0x100
+
+#define   AUD_DSP_WR_AVC_AVC_REF_LEV__B                                     4
+#define   AUD_DSP_WR_AVC_AVC_REF_LEV__W                                     4
+#define   AUD_DSP_WR_AVC_AVC_REF_LEV__M                                     0xF0
+#define   AUD_DSP_WR_AVC_AVC_REF_LEV__PRE                                   0x0
+
+#define   AUD_DSP_WR_AVC_AVC_MAX_ATT__B                                     2
+#define   AUD_DSP_WR_AVC_AVC_MAX_ATT__W                                     2
+#define   AUD_DSP_WR_AVC_AVC_MAX_ATT__M                                     0xC
+#define   AUD_DSP_WR_AVC_AVC_MAX_ATT__PRE                                   0x0
+#define     AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB                                 0x0
+#define     AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB                                 0x4
+#define     AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB                                 0x8
+
+#define   AUD_DSP_WR_AVC_AVC_MAX_GAIN__B                                    0
+#define   AUD_DSP_WR_AVC_AVC_MAX_GAIN__W                                    2
+#define   AUD_DSP_WR_AVC_AVC_MAX_GAIN__M                                    0x3
+#define   AUD_DSP_WR_AVC_AVC_MAX_GAIN__PRE                                  0x0
+#define     AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB                                 0x0
+#define     AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB                                0x1
+#define     AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB                                 0x3
+
+#define AUD_DSP_WR_QPEAK__A                                                 0x105000C
+#define AUD_DSP_WR_QPEAK__W                                                 16
+#define AUD_DSP_WR_QPEAK__M                                                 0xFFFF
+#define AUD_DSP_WR_QPEAK__PRE                                               0x0
+
+#define   AUD_DSP_WR_QPEAK_SRC_QP__B                                        8
+#define   AUD_DSP_WR_QPEAK_SRC_QP__W                                        8
+#define   AUD_DSP_WR_QPEAK_SRC_QP__M                                        0xFF00
+#define   AUD_DSP_WR_QPEAK_SRC_QP__PRE                                      0x0
+#define     AUD_DSP_WR_QPEAK_SRC_QP_MONO                                    0x0
+#define     AUD_DSP_WR_QPEAK_SRC_QP_STEREO_AB                               0x100
+#define     AUD_DSP_WR_QPEAK_SRC_QP_STEREO_A                                0x300
+#define     AUD_DSP_WR_QPEAK_SRC_QP_STEREO_B                                0x400
+
+#define   AUD_DSP_WR_QPEAK_MAT_QP__B                                        0
+#define   AUD_DSP_WR_QPEAK_MAT_QP__W                                        8
+#define   AUD_DSP_WR_QPEAK_MAT_QP__M                                        0xFF
+#define   AUD_DSP_WR_QPEAK_MAT_QP__PRE                                      0x0
+#define     AUD_DSP_WR_QPEAK_MAT_QP_SOUND_A                                 0x0
+#define     AUD_DSP_WR_QPEAK_MAT_QP_SOUND_B                                 0x10
+#define     AUD_DSP_WR_QPEAK_MAT_QP_STEREO                                  0x20
+#define     AUD_DSP_WR_QPEAK_MAT_QP_MONO                                    0x30
+
+#define AUD_DSP_RD_QPEAK_L__A                                               0x1040019
+#define AUD_DSP_RD_QPEAK_L__W                                               16
+#define AUD_DSP_RD_QPEAK_L__M                                               0xFFFF
+#define AUD_DSP_RD_QPEAK_L__PRE                                             0x0
+
+#define AUD_DSP_RD_QPEAK_R__A                                               0x104001A
+#define AUD_DSP_RD_QPEAK_R__W                                               16
+#define AUD_DSP_RD_QPEAK_R__M                                               0xFFFF
+#define AUD_DSP_RD_QPEAK_R__PRE                                             0x0
+
+#define AUD_DSP_WR_BEEPER__A                                                0x1050014
+#define AUD_DSP_WR_BEEPER__W                                                16
+#define AUD_DSP_WR_BEEPER__M                                                0xFFFF
+#define AUD_DSP_WR_BEEPER__PRE                                              0x0
+
+#define   AUD_DSP_WR_BEEPER_BEEP_VOLUME__B                                  8
+#define   AUD_DSP_WR_BEEPER_BEEP_VOLUME__W                                  7
+#define   AUD_DSP_WR_BEEPER_BEEP_VOLUME__M                                  0x7F00
+#define   AUD_DSP_WR_BEEPER_BEEP_VOLUME__PRE                                0x0
+
+#define   AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__B                               0
+#define   AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__W                               7
+#define   AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M                               0x7F
+#define   AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__PRE                             0x0
+
+#define AUD_DEM_WR_I2S_CONFIG2__A                                           0x1030050
+#define AUD_DEM_WR_I2S_CONFIG2__W                                           16
+#define AUD_DEM_WR_I2S_CONFIG2__M                                           0xFFFF
+#define AUD_DEM_WR_I2S_CONFIG2__PRE                                         0x0
+
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_CL_POL__B                              6
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_CL_POL__W                              1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_CL_POL__M                              0x40
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_CL_POL__PRE                            0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_CL_POL_NORMAL                        0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_CL_POL_INVERTED                      0x40
+
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__B                              4
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__W                              1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M                              0x10
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__PRE                            0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE                       0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE                        0x10
+
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__B                             3
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__W                             1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M                             0x8
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__PRE                           0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER                       0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE                        0x8
+
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__B                              2
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__W                              1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M                              0x4
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__PRE                            0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW                      0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH                     0x4
+
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__B                             1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__W                             1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M                             0x2
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__PRE                           0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY                     0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY                        0x2
+
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__B                            0
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__W                            1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M                            0x1
+#define   AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__PRE                          0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32                      0x0
+#define     AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16                      0x1
+
+#define AUD_DSP_WR_I2S_OUT_FS__A                                            0x105002A
+#define AUD_DSP_WR_I2S_OUT_FS__W                                            16
+#define AUD_DSP_WR_I2S_OUT_FS__M                                            0xFFFF
+#define AUD_DSP_WR_I2S_OUT_FS__PRE                                          0x0
+
+#define   AUD_DSP_WR_I2S_OUT_FS_FS_OUT__B                                   0
+#define   AUD_DSP_WR_I2S_OUT_FS_FS_OUT__W                                   16
+#define   AUD_DSP_WR_I2S_OUT_FS_FS_OUT__M                                   0xFFFF
+#define   AUD_DSP_WR_I2S_OUT_FS_FS_OUT__PRE                                 0x0
+
+#define AUD_DSP_WR_AV_SYNC__A                                               0x105002B
+#define AUD_DSP_WR_AV_SYNC__W                                               16
+#define AUD_DSP_WR_AV_SYNC__M                                               0xFFFF
+#define AUD_DSP_WR_AV_SYNC__PRE                                             0x0
+
+#define   AUD_DSP_WR_AV_SYNC_AV_ON__B                                       15
+#define   AUD_DSP_WR_AV_SYNC_AV_ON__W                                       1
+#define   AUD_DSP_WR_AV_SYNC_AV_ON__M                                       0x8000
+#define   AUD_DSP_WR_AV_SYNC_AV_ON__PRE                                     0x0
+#define     AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE                                0x0
+#define     AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE                                 0x8000
+
+#define   AUD_DSP_WR_AV_SYNC_AV_AUTO_FREQ__B                                14
+#define   AUD_DSP_WR_AV_SYNC_AV_AUTO_FREQ__W                                1
+#define   AUD_DSP_WR_AV_SYNC_AV_AUTO_FREQ__M                                0x4000
+#define   AUD_DSP_WR_AV_SYNC_AV_AUTO_FREQ__PRE                              0x0
+#define     AUD_DSP_WR_AV_SYNC_AV_AUTO_FREQ_MONOCHROME                      0x0
+#define     AUD_DSP_WR_AV_SYNC_AV_AUTO_FREQ_NTSC                            0x4000
+
+#define   AUD_DSP_WR_AV_SYNC_AV_STD_SEL__B                                  0
+#define   AUD_DSP_WR_AV_SYNC_AV_STD_SEL__W                                  2
+#define   AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M                                  0x3
+#define   AUD_DSP_WR_AV_SYNC_AV_STD_SEL__PRE                                0x0
+#define     AUD_DSP_WR_AV_SYNC_AV_STD_SEL_AUTO                              0x0
+#define     AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM                         0x1
+#define     AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC                              0x2
+#define     AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME                        0x3
+
+#define AUD_DSP_RD_STATUS2__A                                               0x104007B
+#define AUD_DSP_RD_STATUS2__W                                               16
+#define AUD_DSP_RD_STATUS2__M                                               0xFFFF
+#define AUD_DSP_RD_STATUS2__PRE                                             0x0
+
+#define   AUD_DSP_RD_STATUS2_AV_ACTIVE__B                                   15
+#define   AUD_DSP_RD_STATUS2_AV_ACTIVE__W                                   1
+#define   AUD_DSP_RD_STATUS2_AV_ACTIVE__M                                   0x8000
+#define   AUD_DSP_RD_STATUS2_AV_ACTIVE__PRE                                 0x0
+#define     AUD_DSP_RD_STATUS2_AV_ACTIVE_NO_SYNC                            0x0
+#define     AUD_DSP_RD_STATUS2_AV_ACTIVE_SYNC_ACTIVE                        0x8000
+
+#define AUD_DSP_RD_XDFP_FW__A                                               0x104001D
+#define AUD_DSP_RD_XDFP_FW__W                                               16
+#define AUD_DSP_RD_XDFP_FW__M                                               0xFFFF
+#define AUD_DSP_RD_XDFP_FW__PRE                                             0x344
+
+#define   AUD_DSP_RD_XDFP_FW_DSP_FW_REV__B                                  0
+#define   AUD_DSP_RD_XDFP_FW_DSP_FW_REV__W                                  16
+#define   AUD_DSP_RD_XDFP_FW_DSP_FW_REV__M                                  0xFFFF
+#define   AUD_DSP_RD_XDFP_FW_DSP_FW_REV__PRE                                0x344
+
+#define AUD_DSP_RD_XFP_FW__A                                                0x10404B8
+#define AUD_DSP_RD_XFP_FW__W                                                16
+#define AUD_DSP_RD_XFP_FW__M                                                0xFFFF
+#define AUD_DSP_RD_XFP_FW__PRE                                              0x42
+
+#define   AUD_DSP_RD_XFP_FW_FP_FW_REV__B                                    0
+#define   AUD_DSP_RD_XFP_FW_FP_FW_REV__W                                    16
+#define   AUD_DSP_RD_XFP_FW_FP_FW_REV__M                                    0xFFFF
+#define   AUD_DSP_RD_XFP_FW_FP_FW_REV__PRE                                  0x42
+
+#define AUD_DEM_WR_DCO_B_HI__A                                              0x103009B
+#define AUD_DEM_WR_DCO_B_HI__W                                              16
+#define AUD_DEM_WR_DCO_B_HI__M                                              0xFFFF
+#define AUD_DEM_WR_DCO_B_HI__PRE                                            0x0
+
+#define AUD_DEM_WR_DCO_B_LO__A                                              0x1030093
+#define AUD_DEM_WR_DCO_B_LO__W                                              16
+#define AUD_DEM_WR_DCO_B_LO__M                                              0xFFFF
+#define AUD_DEM_WR_DCO_B_LO__PRE                                            0x0
+
+#define AUD_DEM_WR_DCO_A_HI__A                                              0x10300AB
+#define AUD_DEM_WR_DCO_A_HI__W                                              16
+#define AUD_DEM_WR_DCO_A_HI__M                                              0xFFFF
+#define AUD_DEM_WR_DCO_A_HI__PRE                                            0x0
+
+#define AUD_DEM_WR_DCO_A_LO__A                                              0x10300A3
+#define AUD_DEM_WR_DCO_A_LO__W                                              16
+#define AUD_DEM_WR_DCO_A_LO__M                                              0xFFFF
+#define AUD_DEM_WR_DCO_A_LO__PRE                                            0x0
+#define AUD_DEM_WR_NICAM_THRSHLD__A                                         0x1030021
+#define AUD_DEM_WR_NICAM_THRSHLD__W                                         16
+#define AUD_DEM_WR_NICAM_THRSHLD__M                                         0xFFFF
+#define AUD_DEM_WR_NICAM_THRSHLD__PRE                                       0x2BC
+
+#define   AUD_DEM_WR_NICAM_THRSHLD_NICAM_THLD__B                            0
+#define   AUD_DEM_WR_NICAM_THRSHLD_NICAM_THLD__W                            12
+#define   AUD_DEM_WR_NICAM_THRSHLD_NICAM_THLD__M                            0xFFF
+#define   AUD_DEM_WR_NICAM_THRSHLD_NICAM_THLD__PRE                          0x2BC
+
+#define AUD_DEM_WR_A2_THRSHLD__A                                            0x1030022
+#define AUD_DEM_WR_A2_THRSHLD__W                                            16
+#define AUD_DEM_WR_A2_THRSHLD__M                                            0xFFFF
+#define AUD_DEM_WR_A2_THRSHLD__PRE                                          0x190
+
+#define   AUD_DEM_WR_A2_THRSHLD_A2_THLD__B                                  0
+#define   AUD_DEM_WR_A2_THRSHLD_A2_THLD__W                                  12
+#define   AUD_DEM_WR_A2_THRSHLD_A2_THLD__M                                  0xFFF
+#define   AUD_DEM_WR_A2_THRSHLD_A2_THLD__PRE                                0x190
+
+#define AUD_DEM_WR_BTSC_THRSHLD__A                                          0x1030023
+#define AUD_DEM_WR_BTSC_THRSHLD__W                                          16
+#define AUD_DEM_WR_BTSC_THRSHLD__M                                          0xFFFF
+#define AUD_DEM_WR_BTSC_THRSHLD__PRE                                        0xC
+
+#define   AUD_DEM_WR_BTSC_THRSHLD_BTSC_THLD__B                              0
+#define   AUD_DEM_WR_BTSC_THRSHLD_BTSC_THLD__W                              12
+#define   AUD_DEM_WR_BTSC_THRSHLD_BTSC_THLD__M                              0xFFF
+#define   AUD_DEM_WR_BTSC_THRSHLD_BTSC_THLD__PRE                            0xC
+
+#define AUD_DEM_WR_CM_A_THRSHLD__A                                          0x1030024
+#define AUD_DEM_WR_CM_A_THRSHLD__W                                          16
+#define AUD_DEM_WR_CM_A_THRSHLD__M                                          0xFFFF
+#define AUD_DEM_WR_CM_A_THRSHLD__PRE                                        0x2A
+
+#define   AUD_DEM_WR_CM_A_THRSHLD_CM_A_THLD__B                              0
+#define   AUD_DEM_WR_CM_A_THRSHLD_CM_A_THLD__W                              12
+#define   AUD_DEM_WR_CM_A_THRSHLD_CM_A_THLD__M                              0xFFF
+#define   AUD_DEM_WR_CM_A_THRSHLD_CM_A_THLD__PRE                            0x2A
+
+#define AUD_DEM_WR_CM_B_THRSHLD__A                                          0x1030025
+#define AUD_DEM_WR_CM_B_THRSHLD__W                                          16
+#define AUD_DEM_WR_CM_B_THRSHLD__M                                          0xFFFF
+#define AUD_DEM_WR_CM_B_THRSHLD__PRE                                        0x2A
+
+#define   AUD_DEM_WR_CM_B_THRSHLD_CM_B_THLD__B                              0
+#define   AUD_DEM_WR_CM_B_THRSHLD_CM_B_THLD__W                              12
+#define   AUD_DEM_WR_CM_B_THRSHLD_CM_B_THLD__M                              0xFFF
+#define   AUD_DEM_WR_CM_B_THRSHLD_CM_B_THLD__PRE                            0x2A
+
+#define AUD_DEM_RD_NIC_C_AD_BITS__A                                         0x1020023
+#define AUD_DEM_RD_NIC_C_AD_BITS__W                                         16
+#define AUD_DEM_RD_NIC_C_AD_BITS__M                                         0xFFFF
+#define AUD_DEM_RD_NIC_C_AD_BITS__PRE                                       0x0
+
+#define   AUD_DEM_RD_NIC_C_AD_BITS_NICAM_SYNC__B                            0
+#define   AUD_DEM_RD_NIC_C_AD_BITS_NICAM_SYNC__W                            1
+#define   AUD_DEM_RD_NIC_C_AD_BITS_NICAM_SYNC__M                            0x1
+#define   AUD_DEM_RD_NIC_C_AD_BITS_NICAM_SYNC__PRE                          0x0
+#define     AUD_DEM_RD_NIC_C_AD_BITS_NICAM_SYNC_NOT_SYNCED                  0x0
+#define     AUD_DEM_RD_NIC_C_AD_BITS_NICAM_SYNC_SYNCED                      0x1
+
+#define   AUD_DEM_RD_NIC_C_AD_BITS_C__B                                     1
+#define   AUD_DEM_RD_NIC_C_AD_BITS_C__W                                     4
+#define   AUD_DEM_RD_NIC_C_AD_BITS_C__M                                     0x1E
+#define   AUD_DEM_RD_NIC_C_AD_BITS_C__PRE                                   0x0
+
+#define   AUD_DEM_RD_NIC_C_AD_BITS_ADD_BIT_LO__B                            5
+#define   AUD_DEM_RD_NIC_C_AD_BITS_ADD_BIT_LO__W                            3
+#define   AUD_DEM_RD_NIC_C_AD_BITS_ADD_BIT_LO__M                            0xE0
+#define   AUD_DEM_RD_NIC_C_AD_BITS_ADD_BIT_LO__PRE                          0x0
+
+#define AUD_DEM_RD_NIC_ADD_BITS_HI__A                                       0x1020038
+#define AUD_DEM_RD_NIC_ADD_BITS_HI__W                                       16
+#define AUD_DEM_RD_NIC_ADD_BITS_HI__M                                       0xFFFF
+#define AUD_DEM_RD_NIC_ADD_BITS_HI__PRE                                     0x0
+
+#define   AUD_DEM_RD_NIC_ADD_BITS_HI_ADD_BIT_HI__B                          0
+#define   AUD_DEM_RD_NIC_ADD_BITS_HI_ADD_BIT_HI__W                          8
+#define   AUD_DEM_RD_NIC_ADD_BITS_HI_ADD_BIT_HI__M                          0xFF
+#define   AUD_DEM_RD_NIC_ADD_BITS_HI_ADD_BIT_HI__PRE                        0x0
+
+#define AUD_DEM_RD_NIC_CIB__A                                               0x1020038
+#define AUD_DEM_RD_NIC_CIB__W                                               16
+#define AUD_DEM_RD_NIC_CIB__M                                               0xFFFF
+#define AUD_DEM_RD_NIC_CIB__PRE                                             0x0
+
+#define   AUD_DEM_RD_NIC_CIB_CIB2__B                                        0
+#define   AUD_DEM_RD_NIC_CIB_CIB2__W                                        1
+#define   AUD_DEM_RD_NIC_CIB_CIB2__M                                        0x1
+#define   AUD_DEM_RD_NIC_CIB_CIB2__PRE                                      0x0
+
+#define   AUD_DEM_RD_NIC_CIB_CIB1__B                                        1
+#define   AUD_DEM_RD_NIC_CIB_CIB1__W                                        1
+#define   AUD_DEM_RD_NIC_CIB_CIB1__M                                        0x2
+#define   AUD_DEM_RD_NIC_CIB_CIB1__PRE                                      0x0
+
+#define AUD_DEM_RD_NIC_ERROR_RATE__A                                        0x1020057
+#define AUD_DEM_RD_NIC_ERROR_RATE__W                                        16
+#define AUD_DEM_RD_NIC_ERROR_RATE__M                                        0xFFFF
+#define AUD_DEM_RD_NIC_ERROR_RATE__PRE                                      0x0
+
+#define   AUD_DEM_RD_NIC_ERROR_RATE_ERROR_RATE__B                           0
+#define   AUD_DEM_RD_NIC_ERROR_RATE_ERROR_RATE__W                           12
+#define   AUD_DEM_RD_NIC_ERROR_RATE_ERROR_RATE__M                           0xFFF
+#define   AUD_DEM_RD_NIC_ERROR_RATE_ERROR_RATE__PRE                         0x0
+
+#define AUD_DEM_WR_FM_DEEMPH__A                                             0x103000F
+#define AUD_DEM_WR_FM_DEEMPH__W                                             16
+#define AUD_DEM_WR_FM_DEEMPH__M                                             0xFFFF
+#define AUD_DEM_WR_FM_DEEMPH__PRE                                           0x0
+#define   AUD_DEM_WR_FM_DEEMPH_50US                                         0x0
+#define   AUD_DEM_WR_FM_DEEMPH_75US                                         0x1
+#define   AUD_DEM_WR_FM_DEEMPH_OFF                                          0x3F
+
+#define AUD_DEM_WR_FM_MATRIX__A                                             0x103006F
+#define AUD_DEM_WR_FM_MATRIX__W                                             16
+#define AUD_DEM_WR_FM_MATRIX__M                                             0xFFFF
+#define AUD_DEM_WR_FM_MATRIX__PRE                                           0x0
+#define   AUD_DEM_WR_FM_MATRIX_NO_MATRIX                                    0x0
+#define   AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX                                0x1
+#define   AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX                                0x2
+#define   AUD_DEM_WR_FM_MATRIX_SOUND_A                                      0x3
+#define   AUD_DEM_WR_FM_MATRIX_SOUND_B                                      0x4
+
+#define AUD_DSP_RD_FM_IDENT_VALUE__A                                        0x1040018
+#define AUD_DSP_RD_FM_IDENT_VALUE__W                                        16
+#define AUD_DSP_RD_FM_IDENT_VALUE__M                                        0xFFFF
+#define AUD_DSP_RD_FM_IDENT_VALUE__PRE                                      0x0
+
+#define   AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B                             8
+#define   AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__W                             8
+#define   AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__M                             0xFF00
+#define   AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__PRE                           0x0
+
+#define AUD_DSP_RD_FM_DC_LEVEL_A__A                                         0x104001B
+#define AUD_DSP_RD_FM_DC_LEVEL_A__W                                         16
+#define AUD_DSP_RD_FM_DC_LEVEL_A__M                                         0xFFFF
+#define AUD_DSP_RD_FM_DC_LEVEL_A__PRE                                       0x0
+
+#define   AUD_DSP_RD_FM_DC_LEVEL_A_FM_DC_LEV_A__B                           0
+#define   AUD_DSP_RD_FM_DC_LEVEL_A_FM_DC_LEV_A__W                           16
+#define   AUD_DSP_RD_FM_DC_LEVEL_A_FM_DC_LEV_A__M                           0xFFFF
+#define   AUD_DSP_RD_FM_DC_LEVEL_A_FM_DC_LEV_A__PRE                         0x0
+
+#define AUD_DSP_RD_FM_DC_LEVEL_B__A                                         0x104001C
+#define AUD_DSP_RD_FM_DC_LEVEL_B__W                                         16
+#define AUD_DSP_RD_FM_DC_LEVEL_B__M                                         0xFFFF
+#define AUD_DSP_RD_FM_DC_LEVEL_B__PRE                                       0x0
+
+#define   AUD_DSP_RD_FM_DC_LEVEL_B_FM_DC_LEV_B__B                           0
+#define   AUD_DSP_RD_FM_DC_LEVEL_B_FM_DC_LEV_B__W                           16
+#define   AUD_DSP_RD_FM_DC_LEVEL_B_FM_DC_LEV_B__M                           0xFFFF
+#define   AUD_DSP_RD_FM_DC_LEVEL_B_FM_DC_LEV_B__PRE                         0x0
+
+#define AUD_DEM_WR_FM_DC_NOTCH_SW__A                                        0x1030017
+#define AUD_DEM_WR_FM_DC_NOTCH_SW__W                                        16
+#define AUD_DEM_WR_FM_DC_NOTCH_SW__M                                        0xFFFF
+#define AUD_DEM_WR_FM_DC_NOTCH_SW__PRE                                      0x0
+
+#define   AUD_DEM_WR_FM_DC_NOTCH_SW_FM_DC_NO_SW__B                          0
+#define   AUD_DEM_WR_FM_DC_NOTCH_SW_FM_DC_NO_SW__W                          16
+#define   AUD_DEM_WR_FM_DC_NOTCH_SW_FM_DC_NO_SW__M                          0xFFFF
+#define   AUD_DEM_WR_FM_DC_NOTCH_SW_FM_DC_NO_SW__PRE                        0x0
+#define     AUD_DEM_WR_FM_DC_NOTCH_SW_FM_DC_NO_SW_ON                        0x0
+#define     AUD_DEM_WR_FM_DC_NOTCH_SW_FM_DC_NO_SW_OFF                       0x3F
+
+#define AUD_DSP_WR_SYNC_OUT__A                                              0x1050026
+#define AUD_DSP_WR_SYNC_OUT__W                                              16
+#define AUD_DSP_WR_SYNC_OUT__M                                              0xFFFF
+#define AUD_DSP_WR_SYNC_OUT__PRE                                            0x0
+#define   AUD_DSP_WR_SYNC_OUT_OFF                                           0x0
+#define   AUD_DSP_WR_SYNC_OUT_SYNCHRONOUS                                   0x1
+
+#define AUD_XFP_DRAM_1K__A                                                  0x1060000
+#define AUD_XFP_DRAM_1K__W                                                  16
+#define AUD_XFP_DRAM_1K__M                                                  0xFFFF
+#define AUD_XFP_DRAM_1K__PRE                                                0x0
+#define   AUD_XFP_DRAM_1K_D__B                                              0
+#define   AUD_XFP_DRAM_1K_D__W                                              16
+#define   AUD_XFP_DRAM_1K_D__M                                              0xFFFF
+#define   AUD_XFP_DRAM_1K_D__PRE                                            0x0
+
+#define AUD_XFP_PRAM_4K__A                                                  0x1070000
+#define AUD_XFP_PRAM_4K__W                                                  16
+#define AUD_XFP_PRAM_4K__M                                                  0xFFFF
+#define AUD_XFP_PRAM_4K__PRE                                                0x0
+#define   AUD_XFP_PRAM_4K_D__B                                              0
+#define   AUD_XFP_PRAM_4K_D__W                                              16
+#define   AUD_XFP_PRAM_4K_D__M                                              0xFFFF
+#define   AUD_XFP_PRAM_4K_D__PRE                                            0x0
+
+#define AUD_XDFP_DRAM_1K__A                                                 0x1080000
+#define AUD_XDFP_DRAM_1K__W                                                 16
+#define AUD_XDFP_DRAM_1K__M                                                 0xFFFF
+#define AUD_XDFP_DRAM_1K__PRE                                               0x0
+#define   AUD_XDFP_DRAM_1K_D__B                                             0
+#define   AUD_XDFP_DRAM_1K_D__W                                             16
+#define   AUD_XDFP_DRAM_1K_D__M                                             0xFFFF
+#define   AUD_XDFP_DRAM_1K_D__PRE                                           0x0
+
+#define AUD_XDFP_PRAM_4K__A                                                 0x1090000
+#define AUD_XDFP_PRAM_4K__W                                                 16
+#define AUD_XDFP_PRAM_4K__M                                                 0xFFFF
+#define AUD_XDFP_PRAM_4K__PRE                                               0x0
+#define   AUD_XDFP_PRAM_4K_D__B                                             0
+#define   AUD_XDFP_PRAM_4K_D__W                                             16
+#define   AUD_XDFP_PRAM_4K_D__M                                             0xFFFF
+#define   AUD_XDFP_PRAM_4K_D__PRE                                           0x0
+
+#define FEC_COMM_EXEC__A                                                    0x2400000
+#define FEC_COMM_EXEC__W                                                    2
+#define FEC_COMM_EXEC__M                                                    0x3
+#define FEC_COMM_EXEC__PRE                                                  0x0
+#define   FEC_COMM_EXEC_STOP                                                0x0
+#define   FEC_COMM_EXEC_ACTIVE                                              0x1
+#define   FEC_COMM_EXEC_HOLD                                                0x2
+
+#define FEC_COMM_MB__A                                                      0x2400002
+#define FEC_COMM_MB__W                                                      16
+#define FEC_COMM_MB__M                                                      0xFFFF
+#define FEC_COMM_MB__PRE                                                    0x0
+#define FEC_COMM_INT_REQ__A                                                 0x2400003
+#define FEC_COMM_INT_REQ__W                                                 16
+#define FEC_COMM_INT_REQ__M                                                 0xFFFF
+#define FEC_COMM_INT_REQ__PRE                                               0x0
+#define   FEC_COMM_INT_REQ_OC_REQ__B                                        0
+#define   FEC_COMM_INT_REQ_OC_REQ__W                                        1
+#define   FEC_COMM_INT_REQ_OC_REQ__M                                        0x1
+#define   FEC_COMM_INT_REQ_OC_REQ__PRE                                      0x0
+#define   FEC_COMM_INT_REQ_RS_REQ__B                                        1
+#define   FEC_COMM_INT_REQ_RS_REQ__W                                        1
+#define   FEC_COMM_INT_REQ_RS_REQ__M                                        0x2
+#define   FEC_COMM_INT_REQ_RS_REQ__PRE                                      0x0
+#define   FEC_COMM_INT_REQ_DI_REQ__B                                        2
+#define   FEC_COMM_INT_REQ_DI_REQ__W                                        1
+#define   FEC_COMM_INT_REQ_DI_REQ__M                                        0x4
+#define   FEC_COMM_INT_REQ_DI_REQ__PRE                                      0x0
+
+#define FEC_COMM_INT_STA__A                                                 0x2400005
+#define FEC_COMM_INT_STA__W                                                 16
+#define FEC_COMM_INT_STA__M                                                 0xFFFF
+#define FEC_COMM_INT_STA__PRE                                               0x0
+#define FEC_COMM_INT_MSK__A                                                 0x2400006
+#define FEC_COMM_INT_MSK__W                                                 16
+#define FEC_COMM_INT_MSK__M                                                 0xFFFF
+#define FEC_COMM_INT_MSK__PRE                                               0x0
+#define FEC_COMM_INT_STM__A                                                 0x2400007
+#define FEC_COMM_INT_STM__W                                                 16
+#define FEC_COMM_INT_STM__M                                                 0xFFFF
+#define FEC_COMM_INT_STM__PRE                                               0x0
+
+#define FEC_TOP_COMM_EXEC__A                                                0x2410000
+#define FEC_TOP_COMM_EXEC__W                                                2
+#define FEC_TOP_COMM_EXEC__M                                                0x3
+#define FEC_TOP_COMM_EXEC__PRE                                              0x0
+#define   FEC_TOP_COMM_EXEC_STOP                                            0x0
+#define   FEC_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   FEC_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define FEC_TOP_ANNEX__A                                                    0x2410010
+#define FEC_TOP_ANNEX__W                                                    2
+#define FEC_TOP_ANNEX__M                                                    0x3
+#define FEC_TOP_ANNEX__PRE                                                  0x0
+#define   FEC_TOP_ANNEX_A                                                   0x0
+#define   FEC_TOP_ANNEX_B                                                   0x1
+#define   FEC_TOP_ANNEX_C                                                   0x2
+#define   FEC_TOP_ANNEX_D                                                   0x3
+
+#define FEC_DI_COMM_EXEC__A                                                 0x2420000
+#define FEC_DI_COMM_EXEC__W                                                 2
+#define FEC_DI_COMM_EXEC__M                                                 0x3
+#define FEC_DI_COMM_EXEC__PRE                                               0x0
+#define   FEC_DI_COMM_EXEC_STOP                                             0x0
+#define   FEC_DI_COMM_EXEC_ACTIVE                                           0x1
+#define   FEC_DI_COMM_EXEC_HOLD                                             0x2
+
+#define FEC_DI_COMM_MB__A                                                   0x2420002
+#define FEC_DI_COMM_MB__W                                                   2
+#define FEC_DI_COMM_MB__M                                                   0x3
+#define FEC_DI_COMM_MB__PRE                                                 0x0
+#define   FEC_DI_COMM_MB_CTL__B                                             0
+#define   FEC_DI_COMM_MB_CTL__W                                             1
+#define   FEC_DI_COMM_MB_CTL__M                                             0x1
+#define   FEC_DI_COMM_MB_CTL__PRE                                           0x0
+#define     FEC_DI_COMM_MB_CTL_OFF                                          0x0
+#define     FEC_DI_COMM_MB_CTL_ON                                           0x1
+#define   FEC_DI_COMM_MB_OBS__B                                             1
+#define   FEC_DI_COMM_MB_OBS__W                                             1
+#define   FEC_DI_COMM_MB_OBS__M                                             0x2
+#define   FEC_DI_COMM_MB_OBS__PRE                                           0x0
+#define     FEC_DI_COMM_MB_OBS_OFF                                          0x0
+#define     FEC_DI_COMM_MB_OBS_ON                                           0x2
+
+#define FEC_DI_COMM_INT_REQ__A                                              0x2420003
+#define FEC_DI_COMM_INT_REQ__W                                              1
+#define FEC_DI_COMM_INT_REQ__M                                              0x1
+#define FEC_DI_COMM_INT_REQ__PRE                                            0x0
+#define FEC_DI_COMM_INT_STA__A                                              0x2420005
+#define FEC_DI_COMM_INT_STA__W                                              2
+#define FEC_DI_COMM_INT_STA__M                                              0x3
+#define FEC_DI_COMM_INT_STA__PRE                                            0x0
+
+#define   FEC_DI_COMM_INT_STA_STAT_INT__B                                   0
+#define   FEC_DI_COMM_INT_STA_STAT_INT__W                                   1
+#define   FEC_DI_COMM_INT_STA_STAT_INT__M                                   0x1
+#define   FEC_DI_COMM_INT_STA_STAT_INT__PRE                                 0x0
+
+#define   FEC_DI_COMM_INT_STA_TIMEOUT_INT__B                                1
+#define   FEC_DI_COMM_INT_STA_TIMEOUT_INT__W                                1
+#define   FEC_DI_COMM_INT_STA_TIMEOUT_INT__M                                0x2
+#define   FEC_DI_COMM_INT_STA_TIMEOUT_INT__PRE                              0x0
+
+#define FEC_DI_COMM_INT_MSK__A                                              0x2420006
+#define FEC_DI_COMM_INT_MSK__W                                              2
+#define FEC_DI_COMM_INT_MSK__M                                              0x3
+#define FEC_DI_COMM_INT_MSK__PRE                                            0x0
+#define   FEC_DI_COMM_INT_MSK_STAT_INT__B                                   0
+#define   FEC_DI_COMM_INT_MSK_STAT_INT__W                                   1
+#define   FEC_DI_COMM_INT_MSK_STAT_INT__M                                   0x1
+#define   FEC_DI_COMM_INT_MSK_STAT_INT__PRE                                 0x0
+#define   FEC_DI_COMM_INT_MSK_TIMEOUT_INT__B                                1
+#define   FEC_DI_COMM_INT_MSK_TIMEOUT_INT__W                                1
+#define   FEC_DI_COMM_INT_MSK_TIMEOUT_INT__M                                0x2
+#define   FEC_DI_COMM_INT_MSK_TIMEOUT_INT__PRE                              0x0
+
+#define FEC_DI_COMM_INT_STM__A                                              0x2420007
+#define FEC_DI_COMM_INT_STM__W                                              2
+#define FEC_DI_COMM_INT_STM__M                                              0x3
+#define FEC_DI_COMM_INT_STM__PRE                                            0x0
+#define   FEC_DI_COMM_INT_STM_STAT_INT__B                                   0
+#define   FEC_DI_COMM_INT_STM_STAT_INT__W                                   1
+#define   FEC_DI_COMM_INT_STM_STAT_INT__M                                   0x1
+#define   FEC_DI_COMM_INT_STM_STAT_INT__PRE                                 0x0
+#define   FEC_DI_COMM_INT_STM_TIMEOUT_INT__B                                1
+#define   FEC_DI_COMM_INT_STM_TIMEOUT_INT__W                                1
+#define   FEC_DI_COMM_INT_STM_TIMEOUT_INT__M                                0x2
+#define   FEC_DI_COMM_INT_STM_TIMEOUT_INT__PRE                              0x0
+
+#define FEC_DI_STATUS__A                                                    0x2420010
+#define FEC_DI_STATUS__W                                                    1
+#define FEC_DI_STATUS__M                                                    0x1
+#define FEC_DI_STATUS__PRE                                                  0x0
+#define FEC_DI_MODE__A                                                      0x2420011
+#define FEC_DI_MODE__W                                                      3
+#define FEC_DI_MODE__M                                                      0x7
+#define FEC_DI_MODE__PRE                                                    0x0
+
+#define   FEC_DI_MODE_NO_SYNC__B                                            0
+#define   FEC_DI_MODE_NO_SYNC__W                                            1
+#define   FEC_DI_MODE_NO_SYNC__M                                            0x1
+#define   FEC_DI_MODE_NO_SYNC__PRE                                          0x0
+
+#define   FEC_DI_MODE_IGNORE_LOST_SYNC__B                                   1
+#define   FEC_DI_MODE_IGNORE_LOST_SYNC__W                                   1
+#define   FEC_DI_MODE_IGNORE_LOST_SYNC__M                                   0x2
+#define   FEC_DI_MODE_IGNORE_LOST_SYNC__PRE                                 0x0
+
+#define   FEC_DI_MODE_IGNORE_TIMEOUT__B                                     2
+#define   FEC_DI_MODE_IGNORE_TIMEOUT__W                                     1
+#define   FEC_DI_MODE_IGNORE_TIMEOUT__M                                     0x4
+#define   FEC_DI_MODE_IGNORE_TIMEOUT__PRE                                   0x0
+
+#define FEC_DI_CONTROL_WORD__A                                              0x2420012
+#define FEC_DI_CONTROL_WORD__W                                              4
+#define FEC_DI_CONTROL_WORD__M                                              0xF
+#define FEC_DI_CONTROL_WORD__PRE                                            0x0
+
+#define FEC_DI_RESTART__A                                                   0x2420013
+#define FEC_DI_RESTART__W                                                   1
+#define FEC_DI_RESTART__M                                                   0x1
+#define FEC_DI_RESTART__PRE                                                 0x0
+
+#define FEC_DI_TIMEOUT_LO__A                                                0x2420014
+#define FEC_DI_TIMEOUT_LO__W                                                16
+#define FEC_DI_TIMEOUT_LO__M                                                0xFFFF
+#define FEC_DI_TIMEOUT_LO__PRE                                              0x0
+
+#define FEC_DI_TIMEOUT_HI__A                                                0x2420015
+#define FEC_DI_TIMEOUT_HI__W                                                8
+#define FEC_DI_TIMEOUT_HI__M                                                0xFF
+#define FEC_DI_TIMEOUT_HI__PRE                                              0xA
+
+#define FEC_RS_COMM_EXEC__A                                                 0x2430000
+#define FEC_RS_COMM_EXEC__W                                                 2
+#define FEC_RS_COMM_EXEC__M                                                 0x3
+#define FEC_RS_COMM_EXEC__PRE                                               0x0
+#define   FEC_RS_COMM_EXEC_STOP                                             0x0
+#define   FEC_RS_COMM_EXEC_ACTIVE                                           0x1
+#define   FEC_RS_COMM_EXEC_HOLD                                             0x2
+
+#define FEC_RS_COMM_MB__A                                                   0x2430002
+#define FEC_RS_COMM_MB__W                                                   2
+#define FEC_RS_COMM_MB__M                                                   0x3
+#define FEC_RS_COMM_MB__PRE                                                 0x0
+#define   FEC_RS_COMM_MB_CTL__B                                             0
+#define   FEC_RS_COMM_MB_CTL__W                                             1
+#define   FEC_RS_COMM_MB_CTL__M                                             0x1
+#define   FEC_RS_COMM_MB_CTL__PRE                                           0x0
+#define     FEC_RS_COMM_MB_CTL_OFF                                          0x0
+#define     FEC_RS_COMM_MB_CTL_ON                                           0x1
+#define   FEC_RS_COMM_MB_OBS__B                                             1
+#define   FEC_RS_COMM_MB_OBS__W                                             1
+#define   FEC_RS_COMM_MB_OBS__M                                             0x2
+#define   FEC_RS_COMM_MB_OBS__PRE                                           0x0
+#define     FEC_RS_COMM_MB_OBS_OFF                                          0x0
+#define     FEC_RS_COMM_MB_OBS_ON                                           0x2
+
+#define FEC_RS_COMM_INT_REQ__A                                              0x2430003
+#define FEC_RS_COMM_INT_REQ__W                                              1
+#define FEC_RS_COMM_INT_REQ__M                                              0x1
+#define FEC_RS_COMM_INT_REQ__PRE                                            0x0
+#define FEC_RS_COMM_INT_STA__A                                              0x2430005
+#define FEC_RS_COMM_INT_STA__W                                              2
+#define FEC_RS_COMM_INT_STA__M                                              0x3
+#define FEC_RS_COMM_INT_STA__PRE                                            0x0
+
+#define   FEC_RS_COMM_INT_STA_FAILURE_INT__B                                0
+#define   FEC_RS_COMM_INT_STA_FAILURE_INT__W                                1
+#define   FEC_RS_COMM_INT_STA_FAILURE_INT__M                                0x1
+#define   FEC_RS_COMM_INT_STA_FAILURE_INT__PRE                              0x0
+
+#define   FEC_RS_COMM_INT_STA_MEASUREMENT_INT__B                            1
+#define   FEC_RS_COMM_INT_STA_MEASUREMENT_INT__W                            1
+#define   FEC_RS_COMM_INT_STA_MEASUREMENT_INT__M                            0x2
+#define   FEC_RS_COMM_INT_STA_MEASUREMENT_INT__PRE                          0x0
+
+#define FEC_RS_COMM_INT_MSK__A                                              0x2430006
+#define FEC_RS_COMM_INT_MSK__W                                              2
+#define FEC_RS_COMM_INT_MSK__M                                              0x3
+#define FEC_RS_COMM_INT_MSK__PRE                                            0x0
+#define   FEC_RS_COMM_INT_MSK_FAILURE_MSK__B                                0
+#define   FEC_RS_COMM_INT_MSK_FAILURE_MSK__W                                1
+#define   FEC_RS_COMM_INT_MSK_FAILURE_MSK__M                                0x1
+#define   FEC_RS_COMM_INT_MSK_FAILURE_MSK__PRE                              0x0
+#define   FEC_RS_COMM_INT_MSK_MEASUREMENT_MSK__B                            1
+#define   FEC_RS_COMM_INT_MSK_MEASUREMENT_MSK__W                            1
+#define   FEC_RS_COMM_INT_MSK_MEASUREMENT_MSK__M                            0x2
+#define   FEC_RS_COMM_INT_MSK_MEASUREMENT_MSK__PRE                          0x0
+
+#define FEC_RS_COMM_INT_STM__A                                              0x2430007
+#define FEC_RS_COMM_INT_STM__W                                              2
+#define FEC_RS_COMM_INT_STM__M                                              0x3
+#define FEC_RS_COMM_INT_STM__PRE                                            0x0
+#define   FEC_RS_COMM_INT_STM_FAILURE_MSK__B                                0
+#define   FEC_RS_COMM_INT_STM_FAILURE_MSK__W                                1
+#define   FEC_RS_COMM_INT_STM_FAILURE_MSK__M                                0x1
+#define   FEC_RS_COMM_INT_STM_FAILURE_MSK__PRE                              0x0
+#define   FEC_RS_COMM_INT_STM_MEASUREMENT_MSK__B                            1
+#define   FEC_RS_COMM_INT_STM_MEASUREMENT_MSK__W                            1
+#define   FEC_RS_COMM_INT_STM_MEASUREMENT_MSK__M                            0x2
+#define   FEC_RS_COMM_INT_STM_MEASUREMENT_MSK__PRE                          0x0
+
+#define FEC_RS_STATUS__A                                                    0x2430010
+#define FEC_RS_STATUS__W                                                    1
+#define FEC_RS_STATUS__M                                                    0x1
+#define FEC_RS_STATUS__PRE                                                  0x0
+#define FEC_RS_MODE__A                                                      0x2430011
+#define FEC_RS_MODE__W                                                      1
+#define FEC_RS_MODE__M                                                      0x1
+#define FEC_RS_MODE__PRE                                                    0x0
+
+#define   FEC_RS_MODE_BYPASS__B                                             0
+#define   FEC_RS_MODE_BYPASS__W                                             1
+#define   FEC_RS_MODE_BYPASS__M                                             0x1
+#define   FEC_RS_MODE_BYPASS__PRE                                           0x0
+
+#define FEC_RS_MEASUREMENT_PERIOD__A                                        0x2430012
+#define FEC_RS_MEASUREMENT_PERIOD__W                                        16
+#define FEC_RS_MEASUREMENT_PERIOD__M                                        0xFFFF
+#define FEC_RS_MEASUREMENT_PERIOD__PRE                                      0x1171
+
+#define   FEC_RS_MEASUREMENT_PERIOD_PERIOD__B                               0
+#define   FEC_RS_MEASUREMENT_PERIOD_PERIOD__W                               16
+#define   FEC_RS_MEASUREMENT_PERIOD_PERIOD__M                               0xFFFF
+#define   FEC_RS_MEASUREMENT_PERIOD_PERIOD__PRE                             0x1171
+
+#define FEC_RS_MEASUREMENT_PRESCALE__A                                      0x2430013
+#define FEC_RS_MEASUREMENT_PRESCALE__W                                      16
+#define FEC_RS_MEASUREMENT_PRESCALE__M                                      0xFFFF
+#define FEC_RS_MEASUREMENT_PRESCALE__PRE                                    0x1
+
+#define   FEC_RS_MEASUREMENT_PRESCALE_PRESCALE__B                           0
+#define   FEC_RS_MEASUREMENT_PRESCALE_PRESCALE__W                           16
+#define   FEC_RS_MEASUREMENT_PRESCALE_PRESCALE__M                           0xFFFF
+#define   FEC_RS_MEASUREMENT_PRESCALE_PRESCALE__PRE                         0x1
+
+#define FEC_RS_NR_BIT_ERRORS__A                                             0x2430014
+#define FEC_RS_NR_BIT_ERRORS__W                                             16
+#define FEC_RS_NR_BIT_ERRORS__M                                             0xFFFF
+#define FEC_RS_NR_BIT_ERRORS__PRE                                           0xFFFF
+
+#define   FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B                                0
+#define   FEC_RS_NR_BIT_ERRORS_FIXED_MANT__W                                12
+#define   FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M                                0xFFF
+#define   FEC_RS_NR_BIT_ERRORS_FIXED_MANT__PRE                              0xFFF
+
+#define   FEC_RS_NR_BIT_ERRORS_EXP__B                                       12
+#define   FEC_RS_NR_BIT_ERRORS_EXP__W                                       4
+#define   FEC_RS_NR_BIT_ERRORS_EXP__M                                       0xF000
+#define   FEC_RS_NR_BIT_ERRORS_EXP__PRE                                     0xF000
+
+#define FEC_RS_NR_SYMBOL_ERRORS__A                                          0x2430015
+#define FEC_RS_NR_SYMBOL_ERRORS__W                                          16
+#define FEC_RS_NR_SYMBOL_ERRORS__M                                          0xFFFF
+#define FEC_RS_NR_SYMBOL_ERRORS__PRE                                        0xFFFF
+
+#define   FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__B                             0
+#define   FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__W                             12
+#define   FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M                             0xFFF
+#define   FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__PRE                           0xFFF
+
+#define   FEC_RS_NR_SYMBOL_ERRORS_EXP__B                                    12
+#define   FEC_RS_NR_SYMBOL_ERRORS_EXP__W                                    4
+#define   FEC_RS_NR_SYMBOL_ERRORS_EXP__M                                    0xF000
+#define   FEC_RS_NR_SYMBOL_ERRORS_EXP__PRE                                  0xF000
+
+#define FEC_RS_NR_PACKET_ERRORS__A                                          0x2430016
+#define FEC_RS_NR_PACKET_ERRORS__W                                          16
+#define FEC_RS_NR_PACKET_ERRORS__M                                          0xFFFF
+#define FEC_RS_NR_PACKET_ERRORS__PRE                                        0xFFFF
+
+#define   FEC_RS_NR_PACKET_ERRORS_FIXED_MANT__B                             0
+#define   FEC_RS_NR_PACKET_ERRORS_FIXED_MANT__W                             12
+#define   FEC_RS_NR_PACKET_ERRORS_FIXED_MANT__M                             0xFFF
+#define   FEC_RS_NR_PACKET_ERRORS_FIXED_MANT__PRE                           0xFFF
+
+#define   FEC_RS_NR_PACKET_ERRORS_EXP__B                                    12
+#define   FEC_RS_NR_PACKET_ERRORS_EXP__W                                    4
+#define   FEC_RS_NR_PACKET_ERRORS_EXP__M                                    0xF000
+#define   FEC_RS_NR_PACKET_ERRORS_EXP__PRE                                  0xF000
+
+#define FEC_RS_NR_FAILURES__A                                               0x2430017
+#define FEC_RS_NR_FAILURES__W                                               16
+#define FEC_RS_NR_FAILURES__M                                               0xFFFF
+#define FEC_RS_NR_FAILURES__PRE                                             0x0
+
+#define   FEC_RS_NR_FAILURES_FIXED_MANT__B                                  0
+#define   FEC_RS_NR_FAILURES_FIXED_MANT__W                                  12
+#define   FEC_RS_NR_FAILURES_FIXED_MANT__M                                  0xFFF
+#define   FEC_RS_NR_FAILURES_FIXED_MANT__PRE                                0x0
+
+#define   FEC_RS_NR_FAILURES_EXP__B                                         12
+#define   FEC_RS_NR_FAILURES_EXP__W                                         4
+#define   FEC_RS_NR_FAILURES_EXP__M                                         0xF000
+#define   FEC_RS_NR_FAILURES_EXP__PRE                                       0x0
+
+#define FEC_OC_COMM_EXEC__A                                                 0x2440000
+#define FEC_OC_COMM_EXEC__W                                                 2
+#define FEC_OC_COMM_EXEC__M                                                 0x3
+#define FEC_OC_COMM_EXEC__PRE                                               0x0
+#define   FEC_OC_COMM_EXEC_STOP                                             0x0
+#define   FEC_OC_COMM_EXEC_ACTIVE                                           0x1
+#define   FEC_OC_COMM_EXEC_HOLD                                             0x2
+
+#define FEC_OC_COMM_MB__A                                                   0x2440002
+#define FEC_OC_COMM_MB__W                                                   2
+#define FEC_OC_COMM_MB__M                                                   0x3
+#define FEC_OC_COMM_MB__PRE                                                 0x0
+#define   FEC_OC_COMM_MB_CTL__B                                             0
+#define   FEC_OC_COMM_MB_CTL__W                                             1
+#define   FEC_OC_COMM_MB_CTL__M                                             0x1
+#define   FEC_OC_COMM_MB_CTL__PRE                                           0x0
+#define     FEC_OC_COMM_MB_CTL_OFF                                          0x0
+#define     FEC_OC_COMM_MB_CTL_ON                                           0x1
+#define   FEC_OC_COMM_MB_OBS__B                                             1
+#define   FEC_OC_COMM_MB_OBS__W                                             1
+#define   FEC_OC_COMM_MB_OBS__M                                             0x2
+#define   FEC_OC_COMM_MB_OBS__PRE                                           0x0
+#define     FEC_OC_COMM_MB_OBS_OFF                                          0x0
+#define     FEC_OC_COMM_MB_OBS_ON                                           0x2
+
+#define FEC_OC_COMM_INT_REQ__A                                              0x2440003
+#define FEC_OC_COMM_INT_REQ__W                                              1
+#define FEC_OC_COMM_INT_REQ__M                                              0x1
+#define FEC_OC_COMM_INT_REQ__PRE                                            0x0
+#define FEC_OC_COMM_INT_STA__A                                              0x2440005
+#define FEC_OC_COMM_INT_STA__W                                              8
+#define FEC_OC_COMM_INT_STA__M                                              0xFF
+#define FEC_OC_COMM_INT_STA__PRE                                            0x0
+
+#define   FEC_OC_COMM_INT_STA_DPR_LOCK_INT__B                               0
+#define   FEC_OC_COMM_INT_STA_DPR_LOCK_INT__W                               1
+#define   FEC_OC_COMM_INT_STA_DPR_LOCK_INT__M                               0x1
+#define   FEC_OC_COMM_INT_STA_DPR_LOCK_INT__PRE                             0x0
+
+#define   FEC_OC_COMM_INT_STA_SNC_LOCK_INT__B                               1
+#define   FEC_OC_COMM_INT_STA_SNC_LOCK_INT__W                               1
+#define   FEC_OC_COMM_INT_STA_SNC_LOCK_INT__M                               0x2
+#define   FEC_OC_COMM_INT_STA_SNC_LOCK_INT__PRE                             0x0
+
+#define   FEC_OC_COMM_INT_STA_SNC_LOST_INT__B                               2
+#define   FEC_OC_COMM_INT_STA_SNC_LOST_INT__W                               1
+#define   FEC_OC_COMM_INT_STA_SNC_LOST_INT__M                               0x4
+#define   FEC_OC_COMM_INT_STA_SNC_LOST_INT__PRE                             0x0
+
+#define   FEC_OC_COMM_INT_STA_SNC_PAR_INT__B                                3
+#define   FEC_OC_COMM_INT_STA_SNC_PAR_INT__W                                1
+#define   FEC_OC_COMM_INT_STA_SNC_PAR_INT__M                                0x8
+#define   FEC_OC_COMM_INT_STA_SNC_PAR_INT__PRE                              0x0
+
+#define   FEC_OC_COMM_INT_STA_FIFO_FULL_INT__B                              4
+#define   FEC_OC_COMM_INT_STA_FIFO_FULL_INT__W                              1
+#define   FEC_OC_COMM_INT_STA_FIFO_FULL_INT__M                              0x10
+#define   FEC_OC_COMM_INT_STA_FIFO_FULL_INT__PRE                            0x0
+
+#define   FEC_OC_COMM_INT_STA_FIFO_EMPTY_INT__B                             5
+#define   FEC_OC_COMM_INT_STA_FIFO_EMPTY_INT__W                             1
+#define   FEC_OC_COMM_INT_STA_FIFO_EMPTY_INT__M                             0x20
+#define   FEC_OC_COMM_INT_STA_FIFO_EMPTY_INT__PRE                           0x0
+
+#define   FEC_OC_COMM_INT_STA_OCR_ACQ_INT__B                                6
+#define   FEC_OC_COMM_INT_STA_OCR_ACQ_INT__W                                1
+#define   FEC_OC_COMM_INT_STA_OCR_ACQ_INT__M                                0x40
+#define   FEC_OC_COMM_INT_STA_OCR_ACQ_INT__PRE                              0x0
+
+#define   FEC_OC_COMM_INT_STA_STAT_CHG_INT__B                               7
+#define   FEC_OC_COMM_INT_STA_STAT_CHG_INT__W                               1
+#define   FEC_OC_COMM_INT_STA_STAT_CHG_INT__M                               0x80
+#define   FEC_OC_COMM_INT_STA_STAT_CHG_INT__PRE                             0x0
+
+#define FEC_OC_COMM_INT_MSK__A                                              0x2440006
+#define FEC_OC_COMM_INT_MSK__W                                              8
+#define FEC_OC_COMM_INT_MSK__M                                              0xFF
+#define FEC_OC_COMM_INT_MSK__PRE                                            0x0
+#define   FEC_OC_COMM_INT_MSK_DPR_LOCK_MSK__B                               0
+#define   FEC_OC_COMM_INT_MSK_DPR_LOCK_MSK__W                               1
+#define   FEC_OC_COMM_INT_MSK_DPR_LOCK_MSK__M                               0x1
+#define   FEC_OC_COMM_INT_MSK_DPR_LOCK_MSK__PRE                             0x0
+#define   FEC_OC_COMM_INT_MSK_SNC_LOCK_MSK__B                               1
+#define   FEC_OC_COMM_INT_MSK_SNC_LOCK_MSK__W                               1
+#define   FEC_OC_COMM_INT_MSK_SNC_LOCK_MSK__M                               0x2
+#define   FEC_OC_COMM_INT_MSK_SNC_LOCK_MSK__PRE                             0x0
+#define   FEC_OC_COMM_INT_MSK_SNC_LOST_MSK__B                               2
+#define   FEC_OC_COMM_INT_MSK_SNC_LOST_MSK__W                               1
+#define   FEC_OC_COMM_INT_MSK_SNC_LOST_MSK__M                               0x4
+#define   FEC_OC_COMM_INT_MSK_SNC_LOST_MSK__PRE                             0x0
+#define   FEC_OC_COMM_INT_MSK_SNC_PAR_MSK__B                                3
+#define   FEC_OC_COMM_INT_MSK_SNC_PAR_MSK__W                                1
+#define   FEC_OC_COMM_INT_MSK_SNC_PAR_MSK__M                                0x8
+#define   FEC_OC_COMM_INT_MSK_SNC_PAR_MSK__PRE                              0x0
+#define   FEC_OC_COMM_INT_MSK_FIFO_FULL_MSK__B                              4
+#define   FEC_OC_COMM_INT_MSK_FIFO_FULL_MSK__W                              1
+#define   FEC_OC_COMM_INT_MSK_FIFO_FULL_MSK__M                              0x10
+#define   FEC_OC_COMM_INT_MSK_FIFO_FULL_MSK__PRE                            0x0
+#define   FEC_OC_COMM_INT_MSK_FIFO_EMPTY_MSK__B                             5
+#define   FEC_OC_COMM_INT_MSK_FIFO_EMPTY_MSK__W                             1
+#define   FEC_OC_COMM_INT_MSK_FIFO_EMPTY_MSK__M                             0x20
+#define   FEC_OC_COMM_INT_MSK_FIFO_EMPTY_MSK__PRE                           0x0
+#define   FEC_OC_COMM_INT_MSK_OCR_ACQ_MSK__B                                6
+#define   FEC_OC_COMM_INT_MSK_OCR_ACQ_MSK__W                                1
+#define   FEC_OC_COMM_INT_MSK_OCR_ACQ_MSK__M                                0x40
+#define   FEC_OC_COMM_INT_MSK_OCR_ACQ_MSK__PRE                              0x0
+#define   FEC_OC_COMM_INT_MSK_STAT_CHG_MSK__B                               7
+#define   FEC_OC_COMM_INT_MSK_STAT_CHG_MSK__W                               1
+#define   FEC_OC_COMM_INT_MSK_STAT_CHG_MSK__M                               0x80
+#define   FEC_OC_COMM_INT_MSK_STAT_CHG_MSK__PRE                             0x0
+
+#define FEC_OC_COMM_INT_STM__A                                              0x2440007
+#define FEC_OC_COMM_INT_STM__W                                              8
+#define FEC_OC_COMM_INT_STM__M                                              0xFF
+#define FEC_OC_COMM_INT_STM__PRE                                            0x0
+#define   FEC_OC_COMM_INT_STM_DPR_LOCK_MSK__B                               0
+#define   FEC_OC_COMM_INT_STM_DPR_LOCK_MSK__W                               1
+#define   FEC_OC_COMM_INT_STM_DPR_LOCK_MSK__M                               0x1
+#define   FEC_OC_COMM_INT_STM_DPR_LOCK_MSK__PRE                             0x0
+#define   FEC_OC_COMM_INT_STM_SNC_LOCK_MSK__B                               1
+#define   FEC_OC_COMM_INT_STM_SNC_LOCK_MSK__W                               1
+#define   FEC_OC_COMM_INT_STM_SNC_LOCK_MSK__M                               0x2
+#define   FEC_OC_COMM_INT_STM_SNC_LOCK_MSK__PRE                             0x0
+#define   FEC_OC_COMM_INT_STM_SNC_LOST_MSK__B                               2
+#define   FEC_OC_COMM_INT_STM_SNC_LOST_MSK__W                               1
+#define   FEC_OC_COMM_INT_STM_SNC_LOST_MSK__M                               0x4
+#define   FEC_OC_COMM_INT_STM_SNC_LOST_MSK__PRE                             0x0
+#define   FEC_OC_COMM_INT_STM_SNC_PAR_MSK__B                                3
+#define   FEC_OC_COMM_INT_STM_SNC_PAR_MSK__W                                1
+#define   FEC_OC_COMM_INT_STM_SNC_PAR_MSK__M                                0x8
+#define   FEC_OC_COMM_INT_STM_SNC_PAR_MSK__PRE                              0x0
+#define   FEC_OC_COMM_INT_STM_FIFO_FULL_MSK__B                              4
+#define   FEC_OC_COMM_INT_STM_FIFO_FULL_MSK__W                              1
+#define   FEC_OC_COMM_INT_STM_FIFO_FULL_MSK__M                              0x10
+#define   FEC_OC_COMM_INT_STM_FIFO_FULL_MSK__PRE                            0x0
+#define   FEC_OC_COMM_INT_STM_FIFO_EMPTY_MSK__B                             5
+#define   FEC_OC_COMM_INT_STM_FIFO_EMPTY_MSK__W                             1
+#define   FEC_OC_COMM_INT_STM_FIFO_EMPTY_MSK__M                             0x20
+#define   FEC_OC_COMM_INT_STM_FIFO_EMPTY_MSK__PRE                           0x0
+#define   FEC_OC_COMM_INT_STM_OCR_ACQ_MSK__B                                6
+#define   FEC_OC_COMM_INT_STM_OCR_ACQ_MSK__W                                1
+#define   FEC_OC_COMM_INT_STM_OCR_ACQ_MSK__M                                0x40
+#define   FEC_OC_COMM_INT_STM_OCR_ACQ_MSK__PRE                              0x0
+#define   FEC_OC_COMM_INT_STM_STAT_CHG_MSK__B                               7
+#define   FEC_OC_COMM_INT_STM_STAT_CHG_MSK__W                               1
+#define   FEC_OC_COMM_INT_STM_STAT_CHG_MSK__M                               0x80
+#define   FEC_OC_COMM_INT_STM_STAT_CHG_MSK__PRE                             0x0
+
+#define FEC_OC_STATUS__A                                                    0x2440010
+#define FEC_OC_STATUS__W                                                    5
+#define FEC_OC_STATUS__M                                                    0x1F
+#define FEC_OC_STATUS__PRE                                                  0x0
+
+#define   FEC_OC_STATUS_DPR_STATUS__B                                       0
+#define   FEC_OC_STATUS_DPR_STATUS__W                                       1
+#define   FEC_OC_STATUS_DPR_STATUS__M                                       0x1
+#define   FEC_OC_STATUS_DPR_STATUS__PRE                                     0x0
+
+#define   FEC_OC_STATUS_SNC_STATUS__B                                       1
+#define   FEC_OC_STATUS_SNC_STATUS__W                                       2
+#define   FEC_OC_STATUS_SNC_STATUS__M                                       0x6
+#define   FEC_OC_STATUS_SNC_STATUS__PRE                                     0x0
+
+#define   FEC_OC_STATUS_FIFO_FULL__B                                        3
+#define   FEC_OC_STATUS_FIFO_FULL__W                                        1
+#define   FEC_OC_STATUS_FIFO_FULL__M                                        0x8
+#define   FEC_OC_STATUS_FIFO_FULL__PRE                                      0x0
+
+#define   FEC_OC_STATUS_FIFO_EMPTY__B                                       4
+#define   FEC_OC_STATUS_FIFO_EMPTY__W                                       1
+#define   FEC_OC_STATUS_FIFO_EMPTY__M                                       0x10
+#define   FEC_OC_STATUS_FIFO_EMPTY__PRE                                     0x0
+
+#define FEC_OC_MODE__A                                                      0x2440011
+#define FEC_OC_MODE__W                                                      4
+#define FEC_OC_MODE__M                                                      0xF
+#define FEC_OC_MODE__PRE                                                    0x0
+
+#define   FEC_OC_MODE_PARITY__B                                             0
+#define   FEC_OC_MODE_PARITY__W                                             1
+#define   FEC_OC_MODE_PARITY__M                                             0x1
+#define   FEC_OC_MODE_PARITY__PRE                                           0x0
+
+#define   FEC_OC_MODE_TRANSPARENT__B                                        1
+#define   FEC_OC_MODE_TRANSPARENT__W                                        1
+#define   FEC_OC_MODE_TRANSPARENT__M                                        0x2
+#define   FEC_OC_MODE_TRANSPARENT__PRE                                      0x0
+
+#define   FEC_OC_MODE_CLEAR__B                                              2
+#define   FEC_OC_MODE_CLEAR__W                                              1
+#define   FEC_OC_MODE_CLEAR__M                                              0x4
+#define   FEC_OC_MODE_CLEAR__PRE                                            0x0
+
+#define   FEC_OC_MODE_RETAIN_FRAMING__B                                     3
+#define   FEC_OC_MODE_RETAIN_FRAMING__W                                     1
+#define   FEC_OC_MODE_RETAIN_FRAMING__M                                     0x8
+#define   FEC_OC_MODE_RETAIN_FRAMING__PRE                                   0x0
+
+#define FEC_OC_DPR_MODE__A                                                  0x2440012
+#define FEC_OC_DPR_MODE__W                                                  2
+#define FEC_OC_DPR_MODE__M                                                  0x3
+#define FEC_OC_DPR_MODE__PRE                                                0x0
+
+#define   FEC_OC_DPR_MODE_ERR_DISABLE__B                                    0
+#define   FEC_OC_DPR_MODE_ERR_DISABLE__W                                    1
+#define   FEC_OC_DPR_MODE_ERR_DISABLE__M                                    0x1
+#define   FEC_OC_DPR_MODE_ERR_DISABLE__PRE                                  0x0
+
+#define   FEC_OC_DPR_MODE_NOSYNC_ENABLE__B                                  1
+#define   FEC_OC_DPR_MODE_NOSYNC_ENABLE__W                                  1
+#define   FEC_OC_DPR_MODE_NOSYNC_ENABLE__M                                  0x2
+#define   FEC_OC_DPR_MODE_NOSYNC_ENABLE__PRE                                0x0
+
+#define FEC_OC_DPR_UNLOCK__A                                                0x2440013
+#define FEC_OC_DPR_UNLOCK__W                                                1
+#define FEC_OC_DPR_UNLOCK__M                                                0x1
+#define FEC_OC_DPR_UNLOCK__PRE                                              0x0
+#define FEC_OC_DTO_MODE__A                                                  0x2440014
+#define FEC_OC_DTO_MODE__W                                                  3
+#define FEC_OC_DTO_MODE__M                                                  0x7
+#define FEC_OC_DTO_MODE__PRE                                                0x0
+
+#define   FEC_OC_DTO_MODE_DYNAMIC__B                                        0
+#define   FEC_OC_DTO_MODE_DYNAMIC__W                                        1
+#define   FEC_OC_DTO_MODE_DYNAMIC__M                                        0x1
+#define   FEC_OC_DTO_MODE_DYNAMIC__PRE                                      0x0
+
+#define   FEC_OC_DTO_MODE_DUTY_CYCLE__B                                     1
+#define   FEC_OC_DTO_MODE_DUTY_CYCLE__W                                     1
+#define   FEC_OC_DTO_MODE_DUTY_CYCLE__M                                     0x2
+#define   FEC_OC_DTO_MODE_DUTY_CYCLE__PRE                                   0x0
+
+#define   FEC_OC_DTO_MODE_OFFSET_ENABLE__B                                  2
+#define   FEC_OC_DTO_MODE_OFFSET_ENABLE__W                                  1
+#define   FEC_OC_DTO_MODE_OFFSET_ENABLE__M                                  0x4
+#define   FEC_OC_DTO_MODE_OFFSET_ENABLE__PRE                                0x0
+
+#define FEC_OC_DTO_PERIOD__A                                                0x2440015
+#define FEC_OC_DTO_PERIOD__W                                                8
+#define FEC_OC_DTO_PERIOD__M                                                0xFF
+#define FEC_OC_DTO_PERIOD__PRE                                              0x0
+#define FEC_OC_DTO_RATE_LO__A                                               0x2440016
+#define FEC_OC_DTO_RATE_LO__W                                               16
+#define FEC_OC_DTO_RATE_LO__M                                               0xFFFF
+#define FEC_OC_DTO_RATE_LO__PRE                                             0x0
+
+#define   FEC_OC_DTO_RATE_LO_RATE_LO__B                                     0
+#define   FEC_OC_DTO_RATE_LO_RATE_LO__W                                     16
+#define   FEC_OC_DTO_RATE_LO_RATE_LO__M                                     0xFFFF
+#define   FEC_OC_DTO_RATE_LO_RATE_LO__PRE                                   0x0
+
+#define FEC_OC_DTO_RATE_HI__A                                               0x2440017
+#define FEC_OC_DTO_RATE_HI__W                                               10
+#define FEC_OC_DTO_RATE_HI__M                                               0x3FF
+#define FEC_OC_DTO_RATE_HI__PRE                                             0xC0
+
+#define   FEC_OC_DTO_RATE_HI_RATE_HI__B                                     0
+#define   FEC_OC_DTO_RATE_HI_RATE_HI__W                                     10
+#define   FEC_OC_DTO_RATE_HI_RATE_HI__M                                     0x3FF
+#define   FEC_OC_DTO_RATE_HI_RATE_HI__PRE                                   0xC0
+
+#define FEC_OC_DTO_BURST_LEN__A                                             0x2440018
+#define FEC_OC_DTO_BURST_LEN__W                                             8
+#define FEC_OC_DTO_BURST_LEN__M                                             0xFF
+#define FEC_OC_DTO_BURST_LEN__PRE                                           0xBC
+
+#define   FEC_OC_DTO_BURST_LEN_BURST_LEN__B                                 0
+#define   FEC_OC_DTO_BURST_LEN_BURST_LEN__W                                 8
+#define   FEC_OC_DTO_BURST_LEN_BURST_LEN__M                                 0xFF
+#define   FEC_OC_DTO_BURST_LEN_BURST_LEN__PRE                               0xBC
+
+#define FEC_OC_FCT_MODE__A                                                  0x244001A
+#define FEC_OC_FCT_MODE__W                                                  2
+#define FEC_OC_FCT_MODE__M                                                  0x3
+#define FEC_OC_FCT_MODE__PRE                                                0x0
+
+#define   FEC_OC_FCT_MODE_RAT_ENA__B                                        0
+#define   FEC_OC_FCT_MODE_RAT_ENA__W                                        1
+#define   FEC_OC_FCT_MODE_RAT_ENA__M                                        0x1
+#define   FEC_OC_FCT_MODE_RAT_ENA__PRE                                      0x0
+
+#define   FEC_OC_FCT_MODE_VIRT_ENA__B                                       1
+#define   FEC_OC_FCT_MODE_VIRT_ENA__W                                       1
+#define   FEC_OC_FCT_MODE_VIRT_ENA__M                                       0x2
+#define   FEC_OC_FCT_MODE_VIRT_ENA__PRE                                     0x0
+
+#define FEC_OC_FCT_USAGE__A                                                 0x244001B
+#define FEC_OC_FCT_USAGE__W                                                 3
+#define FEC_OC_FCT_USAGE__M                                                 0x7
+#define FEC_OC_FCT_USAGE__PRE                                               0x2
+
+#define   FEC_OC_FCT_USAGE_USAGE__B                                         0
+#define   FEC_OC_FCT_USAGE_USAGE__W                                         3
+#define   FEC_OC_FCT_USAGE_USAGE__M                                         0x7
+#define   FEC_OC_FCT_USAGE_USAGE__PRE                                       0x2
+
+#define FEC_OC_FCT_OCCUPATION__A                                            0x244001C
+#define FEC_OC_FCT_OCCUPATION__W                                            12
+#define FEC_OC_FCT_OCCUPATION__M                                            0xFFF
+#define FEC_OC_FCT_OCCUPATION__PRE                                          0x0
+
+#define   FEC_OC_FCT_OCCUPATION_OCCUPATION__B                               0
+#define   FEC_OC_FCT_OCCUPATION_OCCUPATION__W                               12
+#define   FEC_OC_FCT_OCCUPATION_OCCUPATION__M                               0xFFF
+#define   FEC_OC_FCT_OCCUPATION_OCCUPATION__PRE                             0x0
+
+#define FEC_OC_TMD_MODE__A                                                  0x244001E
+#define FEC_OC_TMD_MODE__W                                                  3
+#define FEC_OC_TMD_MODE__M                                                  0x7
+#define FEC_OC_TMD_MODE__PRE                                                0x4
+
+#define   FEC_OC_TMD_MODE_MODE__B                                           0
+#define   FEC_OC_TMD_MODE_MODE__W                                           3
+#define   FEC_OC_TMD_MODE_MODE__M                                           0x7
+#define   FEC_OC_TMD_MODE_MODE__PRE                                         0x4
+
+#define FEC_OC_TMD_COUNT__A                                                 0x244001F
+#define FEC_OC_TMD_COUNT__W                                                 10
+#define FEC_OC_TMD_COUNT__M                                                 0x3FF
+#define FEC_OC_TMD_COUNT__PRE                                               0x1F4
+
+#define   FEC_OC_TMD_COUNT_COUNT__B                                         0
+#define   FEC_OC_TMD_COUNT_COUNT__W                                         10
+#define   FEC_OC_TMD_COUNT_COUNT__M                                         0x3FF
+#define   FEC_OC_TMD_COUNT_COUNT__PRE                                       0x1F4
+
+#define FEC_OC_TMD_HI_MARGIN__A                                             0x2440020
+#define FEC_OC_TMD_HI_MARGIN__W                                             11
+#define FEC_OC_TMD_HI_MARGIN__M                                             0x7FF
+#define FEC_OC_TMD_HI_MARGIN__PRE                                           0x200
+
+#define   FEC_OC_TMD_HI_MARGIN_HI_MARGIN__B                                 0
+#define   FEC_OC_TMD_HI_MARGIN_HI_MARGIN__W                                 11
+#define   FEC_OC_TMD_HI_MARGIN_HI_MARGIN__M                                 0x7FF
+#define   FEC_OC_TMD_HI_MARGIN_HI_MARGIN__PRE                               0x200
+
+#define FEC_OC_TMD_LO_MARGIN__A                                             0x2440021
+#define FEC_OC_TMD_LO_MARGIN__W                                             11
+#define FEC_OC_TMD_LO_MARGIN__M                                             0x7FF
+#define FEC_OC_TMD_LO_MARGIN__PRE                                           0x100
+
+#define   FEC_OC_TMD_LO_MARGIN_LO_MARGIN__B                                 0
+#define   FEC_OC_TMD_LO_MARGIN_LO_MARGIN__W                                 11
+#define   FEC_OC_TMD_LO_MARGIN_LO_MARGIN__M                                 0x7FF
+#define   FEC_OC_TMD_LO_MARGIN_LO_MARGIN__PRE                               0x100
+
+#define FEC_OC_TMD_CTL_UPD_RATE__A                                          0x2440022
+#define FEC_OC_TMD_CTL_UPD_RATE__W                                          4
+#define FEC_OC_TMD_CTL_UPD_RATE__M                                          0xF
+#define FEC_OC_TMD_CTL_UPD_RATE__PRE                                        0x1
+
+#define   FEC_OC_TMD_CTL_UPD_RATE_RATE__B                                   0
+#define   FEC_OC_TMD_CTL_UPD_RATE_RATE__W                                   4
+#define   FEC_OC_TMD_CTL_UPD_RATE_RATE__M                                   0xF
+#define   FEC_OC_TMD_CTL_UPD_RATE_RATE__PRE                                 0x1
+
+#define FEC_OC_TMD_INT_UPD_RATE__A                                          0x2440023
+#define FEC_OC_TMD_INT_UPD_RATE__W                                          4
+#define FEC_OC_TMD_INT_UPD_RATE__M                                          0xF
+#define FEC_OC_TMD_INT_UPD_RATE__PRE                                        0x4
+
+#define   FEC_OC_TMD_INT_UPD_RATE_RATE__B                                   0
+#define   FEC_OC_TMD_INT_UPD_RATE_RATE__W                                   4
+#define   FEC_OC_TMD_INT_UPD_RATE_RATE__M                                   0xF
+#define   FEC_OC_TMD_INT_UPD_RATE_RATE__PRE                                 0x4
+
+#define FEC_OC_AVR_PARM_A__A                                                0x2440026
+#define FEC_OC_AVR_PARM_A__W                                                4
+#define FEC_OC_AVR_PARM_A__M                                                0xF
+#define FEC_OC_AVR_PARM_A__PRE                                              0x6
+
+#define   FEC_OC_AVR_PARM_A_PARM__B                                         0
+#define   FEC_OC_AVR_PARM_A_PARM__W                                         4
+#define   FEC_OC_AVR_PARM_A_PARM__M                                         0xF
+#define   FEC_OC_AVR_PARM_A_PARM__PRE                                       0x6
+
+#define FEC_OC_AVR_PARM_B__A                                                0x2440027
+#define FEC_OC_AVR_PARM_B__W                                                4
+#define FEC_OC_AVR_PARM_B__M                                                0xF
+#define FEC_OC_AVR_PARM_B__PRE                                              0x4
+
+#define   FEC_OC_AVR_PARM_B_PARM__B                                         0
+#define   FEC_OC_AVR_PARM_B_PARM__W                                         4
+#define   FEC_OC_AVR_PARM_B_PARM__M                                         0xF
+#define   FEC_OC_AVR_PARM_B_PARM__PRE                                       0x4
+
+#define FEC_OC_AVR_AVG_LO__A                                                0x2440028
+#define FEC_OC_AVR_AVG_LO__W                                                16
+#define FEC_OC_AVR_AVG_LO__M                                                0xFFFF
+#define FEC_OC_AVR_AVG_LO__PRE                                              0x0
+
+#define   FEC_OC_AVR_AVG_LO_AVG_LO__B                                       0
+#define   FEC_OC_AVR_AVG_LO_AVG_LO__W                                       16
+#define   FEC_OC_AVR_AVG_LO_AVG_LO__M                                       0xFFFF
+#define   FEC_OC_AVR_AVG_LO_AVG_LO__PRE                                     0x0
+
+#define FEC_OC_AVR_AVG_HI__A                                                0x2440029
+#define FEC_OC_AVR_AVG_HI__W                                                6
+#define FEC_OC_AVR_AVG_HI__M                                                0x3F
+#define FEC_OC_AVR_AVG_HI__PRE                                              0x0
+
+#define   FEC_OC_AVR_AVG_HI_AVG_HI__B                                       0
+#define   FEC_OC_AVR_AVG_HI_AVG_HI__W                                       6
+#define   FEC_OC_AVR_AVG_HI_AVG_HI__M                                       0x3F
+#define   FEC_OC_AVR_AVG_HI_AVG_HI__PRE                                     0x0
+
+#define FEC_OC_RCN_MODE__A                                                  0x244002C
+#define FEC_OC_RCN_MODE__W                                                  5
+#define FEC_OC_RCN_MODE__M                                                  0x1F
+#define FEC_OC_RCN_MODE__PRE                                                0x1F
+
+#define   FEC_OC_RCN_MODE_MODE__B                                           0
+#define   FEC_OC_RCN_MODE_MODE__W                                           5
+#define   FEC_OC_RCN_MODE_MODE__M                                           0x1F
+#define   FEC_OC_RCN_MODE_MODE__PRE                                         0x1F
+
+#define FEC_OC_RCN_OCC_SETTLE__A                                            0x244002D
+#define FEC_OC_RCN_OCC_SETTLE__W                                            11
+#define FEC_OC_RCN_OCC_SETTLE__M                                            0x7FF
+#define FEC_OC_RCN_OCC_SETTLE__PRE                                          0x180
+
+#define   FEC_OC_RCN_OCC_SETTLE_LEVEL__B                                    0
+#define   FEC_OC_RCN_OCC_SETTLE_LEVEL__W                                    11
+#define   FEC_OC_RCN_OCC_SETTLE_LEVEL__M                                    0x7FF
+#define   FEC_OC_RCN_OCC_SETTLE_LEVEL__PRE                                  0x180
+
+#define FEC_OC_RCN_GAIN__A                                                  0x244002E
+#define FEC_OC_RCN_GAIN__W                                                  4
+#define FEC_OC_RCN_GAIN__M                                                  0xF
+#define FEC_OC_RCN_GAIN__PRE                                                0xC
+
+#define   FEC_OC_RCN_GAIN_GAIN__B                                           0
+#define   FEC_OC_RCN_GAIN_GAIN__W                                           4
+#define   FEC_OC_RCN_GAIN_GAIN__M                                           0xF
+#define   FEC_OC_RCN_GAIN_GAIN__PRE                                         0xC
+
+#define FEC_OC_RCN_CTL_RATE_LO__A                                           0x2440030
+#define FEC_OC_RCN_CTL_RATE_LO__W                                           16
+#define FEC_OC_RCN_CTL_RATE_LO__M                                           0xFFFF
+#define FEC_OC_RCN_CTL_RATE_LO__PRE                                         0x0
+
+#define   FEC_OC_RCN_CTL_RATE_LO_CTL_LO__B                                  0
+#define   FEC_OC_RCN_CTL_RATE_LO_CTL_LO__W                                  16
+#define   FEC_OC_RCN_CTL_RATE_LO_CTL_LO__M                                  0xFFFF
+#define   FEC_OC_RCN_CTL_RATE_LO_CTL_LO__PRE                                0x0
+
+#define FEC_OC_RCN_CTL_RATE_HI__A                                           0x2440031
+#define FEC_OC_RCN_CTL_RATE_HI__W                                           8
+#define FEC_OC_RCN_CTL_RATE_HI__M                                           0xFF
+#define FEC_OC_RCN_CTL_RATE_HI__PRE                                         0xC0
+
+#define   FEC_OC_RCN_CTL_RATE_HI_CTL_HI__B                                  0
+#define   FEC_OC_RCN_CTL_RATE_HI_CTL_HI__W                                  8
+#define   FEC_OC_RCN_CTL_RATE_HI_CTL_HI__M                                  0xFF
+#define   FEC_OC_RCN_CTL_RATE_HI_CTL_HI__PRE                                0xC0
+
+#define FEC_OC_RCN_CTL_STEP_LO__A                                           0x2440032
+#define FEC_OC_RCN_CTL_STEP_LO__W                                           16
+#define FEC_OC_RCN_CTL_STEP_LO__M                                           0xFFFF
+#define FEC_OC_RCN_CTL_STEP_LO__PRE                                         0x0
+
+#define   FEC_OC_RCN_CTL_STEP_LO_CTL_LO__B                                  0
+#define   FEC_OC_RCN_CTL_STEP_LO_CTL_LO__W                                  16
+#define   FEC_OC_RCN_CTL_STEP_LO_CTL_LO__M                                  0xFFFF
+#define   FEC_OC_RCN_CTL_STEP_LO_CTL_LO__PRE                                0x0
+
+#define FEC_OC_RCN_CTL_STEP_HI__A                                           0x2440033
+#define FEC_OC_RCN_CTL_STEP_HI__W                                           8
+#define FEC_OC_RCN_CTL_STEP_HI__M                                           0xFF
+#define FEC_OC_RCN_CTL_STEP_HI__PRE                                         0x8
+
+#define   FEC_OC_RCN_CTL_STEP_HI_CTL_HI__B                                  0
+#define   FEC_OC_RCN_CTL_STEP_HI_CTL_HI__W                                  8
+#define   FEC_OC_RCN_CTL_STEP_HI_CTL_HI__M                                  0xFF
+#define   FEC_OC_RCN_CTL_STEP_HI_CTL_HI__PRE                                0x8
+
+#define FEC_OC_RCN_DTO_OFS_LO__A                                            0x2440034
+#define FEC_OC_RCN_DTO_OFS_LO__W                                            16
+#define FEC_OC_RCN_DTO_OFS_LO__M                                            0xFFFF
+#define FEC_OC_RCN_DTO_OFS_LO__PRE                                          0x0
+
+#define   FEC_OC_RCN_DTO_OFS_LO_OFS_LO__B                                   0
+#define   FEC_OC_RCN_DTO_OFS_LO_OFS_LO__W                                   16
+#define   FEC_OC_RCN_DTO_OFS_LO_OFS_LO__M                                   0xFFFF
+#define   FEC_OC_RCN_DTO_OFS_LO_OFS_LO__PRE                                 0x0
+
+#define FEC_OC_RCN_DTO_OFS_HI__A                                            0x2440035
+#define FEC_OC_RCN_DTO_OFS_HI__W                                            8
+#define FEC_OC_RCN_DTO_OFS_HI__M                                            0xFF
+#define FEC_OC_RCN_DTO_OFS_HI__PRE                                          0x0
+
+#define   FEC_OC_RCN_DTO_OFS_HI_OFS_HI__B                                   0
+#define   FEC_OC_RCN_DTO_OFS_HI_OFS_HI__W                                   8
+#define   FEC_OC_RCN_DTO_OFS_HI_OFS_HI__M                                   0xFF
+#define   FEC_OC_RCN_DTO_OFS_HI_OFS_HI__PRE                                 0x0
+
+#define FEC_OC_RCN_DTO_RATE_LO__A                                           0x2440036
+#define FEC_OC_RCN_DTO_RATE_LO__W                                           16
+#define FEC_OC_RCN_DTO_RATE_LO__M                                           0xFFFF
+#define FEC_OC_RCN_DTO_RATE_LO__PRE                                         0x0
+
+#define   FEC_OC_RCN_DTO_RATE_LO_OFS_LO__B                                  0
+#define   FEC_OC_RCN_DTO_RATE_LO_OFS_LO__W                                  16
+#define   FEC_OC_RCN_DTO_RATE_LO_OFS_LO__M                                  0xFFFF
+#define   FEC_OC_RCN_DTO_RATE_LO_OFS_LO__PRE                                0x0
+
+#define FEC_OC_RCN_DTO_RATE_HI__A                                           0x2440037
+#define FEC_OC_RCN_DTO_RATE_HI__W                                           8
+#define FEC_OC_RCN_DTO_RATE_HI__M                                           0xFF
+#define FEC_OC_RCN_DTO_RATE_HI__PRE                                         0x0
+
+#define   FEC_OC_RCN_DTO_RATE_HI_OFS_HI__B                                  0
+#define   FEC_OC_RCN_DTO_RATE_HI_OFS_HI__W                                  8
+#define   FEC_OC_RCN_DTO_RATE_HI_OFS_HI__M                                  0xFF
+#define   FEC_OC_RCN_DTO_RATE_HI_OFS_HI__PRE                                0x0
+
+#define FEC_OC_RCN_RATE_CLIP_LO__A                                          0x2440038
+#define FEC_OC_RCN_RATE_CLIP_LO__W                                          16
+#define FEC_OC_RCN_RATE_CLIP_LO__M                                          0xFFFF
+#define FEC_OC_RCN_RATE_CLIP_LO__PRE                                        0x0
+
+#define   FEC_OC_RCN_RATE_CLIP_LO_CLIP_LO__B                                0
+#define   FEC_OC_RCN_RATE_CLIP_LO_CLIP_LO__W                                16
+#define   FEC_OC_RCN_RATE_CLIP_LO_CLIP_LO__M                                0xFFFF
+#define   FEC_OC_RCN_RATE_CLIP_LO_CLIP_LO__PRE                              0x0
+
+#define FEC_OC_RCN_RATE_CLIP_HI__A                                          0x2440039
+#define FEC_OC_RCN_RATE_CLIP_HI__W                                          8
+#define FEC_OC_RCN_RATE_CLIP_HI__M                                          0xFF
+#define FEC_OC_RCN_RATE_CLIP_HI__PRE                                        0xF0
+
+#define   FEC_OC_RCN_RATE_CLIP_HI_CLIP_HI__B                                0
+#define   FEC_OC_RCN_RATE_CLIP_HI_CLIP_HI__W                                8
+#define   FEC_OC_RCN_RATE_CLIP_HI_CLIP_HI__M                                0xFF
+#define   FEC_OC_RCN_RATE_CLIP_HI_CLIP_HI__PRE                              0xF0
+
+#define FEC_OC_RCN_DYN_RATE_LO__A                                           0x244003A
+#define FEC_OC_RCN_DYN_RATE_LO__W                                           16
+#define FEC_OC_RCN_DYN_RATE_LO__M                                           0xFFFF
+#define FEC_OC_RCN_DYN_RATE_LO__PRE                                         0x0
+
+#define   FEC_OC_RCN_DYN_RATE_LO_RATE_LO__B                                 0
+#define   FEC_OC_RCN_DYN_RATE_LO_RATE_LO__W                                 16
+#define   FEC_OC_RCN_DYN_RATE_LO_RATE_LO__M                                 0xFFFF
+#define   FEC_OC_RCN_DYN_RATE_LO_RATE_LO__PRE                               0x0
+
+#define FEC_OC_RCN_DYN_RATE_HI__A                                           0x244003B
+#define FEC_OC_RCN_DYN_RATE_HI__W                                           8
+#define FEC_OC_RCN_DYN_RATE_HI__M                                           0xFF
+#define FEC_OC_RCN_DYN_RATE_HI__PRE                                         0x0
+
+#define   FEC_OC_RCN_DYN_RATE_HI_RATE_HI__B                                 0
+#define   FEC_OC_RCN_DYN_RATE_HI_RATE_HI__W                                 8
+#define   FEC_OC_RCN_DYN_RATE_HI_RATE_HI__M                                 0xFF
+#define   FEC_OC_RCN_DYN_RATE_HI_RATE_HI__PRE                               0x0
+
+#define FEC_OC_SNC_MODE__A                                                  0x2440040
+#define FEC_OC_SNC_MODE__W                                                  4
+#define FEC_OC_SNC_MODE__M                                                  0xF
+#define FEC_OC_SNC_MODE__PRE                                                0x0
+
+#define   FEC_OC_SNC_MODE_UNLOCK_ENABLE__B                                  0
+#define   FEC_OC_SNC_MODE_UNLOCK_ENABLE__W                                  1
+#define   FEC_OC_SNC_MODE_UNLOCK_ENABLE__M                                  0x1
+#define   FEC_OC_SNC_MODE_UNLOCK_ENABLE__PRE                                0x0
+
+#define   FEC_OC_SNC_MODE_ERROR_CTL__B                                      1
+#define   FEC_OC_SNC_MODE_ERROR_CTL__W                                      2
+#define   FEC_OC_SNC_MODE_ERROR_CTL__M                                      0x6
+#define   FEC_OC_SNC_MODE_ERROR_CTL__PRE                                    0x0
+
+#define   FEC_OC_SNC_MODE_CORR_DISABLE__B                                   3
+#define   FEC_OC_SNC_MODE_CORR_DISABLE__W                                   1
+#define   FEC_OC_SNC_MODE_CORR_DISABLE__M                                   0x8
+#define   FEC_OC_SNC_MODE_CORR_DISABLE__PRE                                 0x0
+
+#define FEC_OC_SNC_LWM__A                                                   0x2440041
+#define FEC_OC_SNC_LWM__W                                                   4
+#define FEC_OC_SNC_LWM__M                                                   0xF
+#define FEC_OC_SNC_LWM__PRE                                                 0x3
+
+#define   FEC_OC_SNC_LWM_MARK__B                                            0
+#define   FEC_OC_SNC_LWM_MARK__W                                            4
+#define   FEC_OC_SNC_LWM_MARK__M                                            0xF
+#define   FEC_OC_SNC_LWM_MARK__PRE                                          0x3
+
+#define FEC_OC_SNC_HWM__A                                                   0x2440042
+#define FEC_OC_SNC_HWM__W                                                   4
+#define FEC_OC_SNC_HWM__M                                                   0xF
+#define FEC_OC_SNC_HWM__PRE                                                 0x5
+
+#define   FEC_OC_SNC_HWM_MARK__B                                            0
+#define   FEC_OC_SNC_HWM_MARK__W                                            4
+#define   FEC_OC_SNC_HWM_MARK__M                                            0xF
+#define   FEC_OC_SNC_HWM_MARK__PRE                                          0x5
+
+#define FEC_OC_SNC_UNLOCK__A                                                0x2440043
+#define FEC_OC_SNC_UNLOCK__W                                                1
+#define FEC_OC_SNC_UNLOCK__M                                                0x1
+#define FEC_OC_SNC_UNLOCK__PRE                                              0x0
+
+#define   FEC_OC_SNC_UNLOCK_RESTART__B                                      0
+#define   FEC_OC_SNC_UNLOCK_RESTART__W                                      1
+#define   FEC_OC_SNC_UNLOCK_RESTART__M                                      0x1
+#define   FEC_OC_SNC_UNLOCK_RESTART__PRE                                    0x0
+
+#define FEC_OC_SNC_LOCK_COUNT__A                                            0x2440044
+#define FEC_OC_SNC_LOCK_COUNT__W                                            12
+#define FEC_OC_SNC_LOCK_COUNT__M                                            0xFFF
+#define FEC_OC_SNC_LOCK_COUNT__PRE                                          0x0
+
+#define   FEC_OC_SNC_LOCK_COUNT_COUNT__B                                    0
+#define   FEC_OC_SNC_LOCK_COUNT_COUNT__W                                    12
+#define   FEC_OC_SNC_LOCK_COUNT_COUNT__M                                    0xFFF
+#define   FEC_OC_SNC_LOCK_COUNT_COUNT__PRE                                  0x0
+
+#define FEC_OC_SNC_FAIL_COUNT__A                                            0x2440045
+#define FEC_OC_SNC_FAIL_COUNT__W                                            12
+#define FEC_OC_SNC_FAIL_COUNT__M                                            0xFFF
+#define FEC_OC_SNC_FAIL_COUNT__PRE                                          0x0
+
+#define   FEC_OC_SNC_FAIL_COUNT_COUNT__B                                    0
+#define   FEC_OC_SNC_FAIL_COUNT_COUNT__W                                    12
+#define   FEC_OC_SNC_FAIL_COUNT_COUNT__M                                    0xFFF
+#define   FEC_OC_SNC_FAIL_COUNT_COUNT__PRE                                  0x0
+
+#define FEC_OC_SNC_FAIL_PERIOD__A                                           0x2440046
+#define FEC_OC_SNC_FAIL_PERIOD__W                                           16
+#define FEC_OC_SNC_FAIL_PERIOD__M                                           0xFFFF
+#define FEC_OC_SNC_FAIL_PERIOD__PRE                                         0x1171
+
+#define   FEC_OC_SNC_FAIL_PERIOD_PERIOD__B                                  0
+#define   FEC_OC_SNC_FAIL_PERIOD_PERIOD__W                                  16
+#define   FEC_OC_SNC_FAIL_PERIOD_PERIOD__M                                  0xFFFF
+#define   FEC_OC_SNC_FAIL_PERIOD_PERIOD__PRE                                0x1171
+
+#define FEC_OC_EMS_MODE__A                                                  0x2440047
+#define FEC_OC_EMS_MODE__W                                                  2
+#define FEC_OC_EMS_MODE__M                                                  0x3
+#define FEC_OC_EMS_MODE__PRE                                                0x0
+
+#define   FEC_OC_EMS_MODE_MODE__B                                           0
+#define   FEC_OC_EMS_MODE_MODE__W                                           2
+#define   FEC_OC_EMS_MODE_MODE__M                                           0x3
+#define   FEC_OC_EMS_MODE_MODE__PRE                                         0x0
+
+#define FEC_OC_IPR_MODE__A                                                  0x2440048
+#define FEC_OC_IPR_MODE__W                                                  12
+#define FEC_OC_IPR_MODE__M                                                  0xFFF
+#define FEC_OC_IPR_MODE__PRE                                                0x0
+
+#define   FEC_OC_IPR_MODE_SERIAL__B                                         0
+#define   FEC_OC_IPR_MODE_SERIAL__W                                         1
+#define   FEC_OC_IPR_MODE_SERIAL__M                                         0x1
+#define   FEC_OC_IPR_MODE_SERIAL__PRE                                       0x0
+
+#define   FEC_OC_IPR_MODE_REVERSE_ORDER__B                                  1
+#define   FEC_OC_IPR_MODE_REVERSE_ORDER__W                                  1
+#define   FEC_OC_IPR_MODE_REVERSE_ORDER__M                                  0x2
+#define   FEC_OC_IPR_MODE_REVERSE_ORDER__PRE                                0x0
+
+#define   FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__B                               2
+#define   FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__W                               1
+#define   FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M                               0x4
+#define   FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__PRE                             0x0
+
+#define   FEC_OC_IPR_MODE_MCLK_DIS_PAR__B                                   3
+#define   FEC_OC_IPR_MODE_MCLK_DIS_PAR__W                                   1
+#define   FEC_OC_IPR_MODE_MCLK_DIS_PAR__M                                   0x8
+#define   FEC_OC_IPR_MODE_MCLK_DIS_PAR__PRE                                 0x0
+
+#define   FEC_OC_IPR_MODE_MVAL_DIS_PAR__B                                   4
+#define   FEC_OC_IPR_MODE_MVAL_DIS_PAR__W                                   1
+#define   FEC_OC_IPR_MODE_MVAL_DIS_PAR__M                                   0x10
+#define   FEC_OC_IPR_MODE_MVAL_DIS_PAR__PRE                                 0x0
+
+#define   FEC_OC_IPR_MODE_MERR_DIS_PAR__B                                   5
+#define   FEC_OC_IPR_MODE_MERR_DIS_PAR__W                                   1
+#define   FEC_OC_IPR_MODE_MERR_DIS_PAR__M                                   0x20
+#define   FEC_OC_IPR_MODE_MERR_DIS_PAR__PRE                                 0x0
+
+#define   FEC_OC_IPR_MODE_MD_DIS_PAR__B                                     6
+#define   FEC_OC_IPR_MODE_MD_DIS_PAR__W                                     1
+#define   FEC_OC_IPR_MODE_MD_DIS_PAR__M                                     0x40
+#define   FEC_OC_IPR_MODE_MD_DIS_PAR__PRE                                   0x0
+
+#define   FEC_OC_IPR_MODE_MCLK_DIS_ERR__B                                   7
+#define   FEC_OC_IPR_MODE_MCLK_DIS_ERR__W                                   1
+#define   FEC_OC_IPR_MODE_MCLK_DIS_ERR__M                                   0x80
+#define   FEC_OC_IPR_MODE_MCLK_DIS_ERR__PRE                                 0x0
+
+#define   FEC_OC_IPR_MODE_MVAL_DIS_ERR__B                                   8
+#define   FEC_OC_IPR_MODE_MVAL_DIS_ERR__W                                   1
+#define   FEC_OC_IPR_MODE_MVAL_DIS_ERR__M                                   0x100
+#define   FEC_OC_IPR_MODE_MVAL_DIS_ERR__PRE                                 0x0
+
+#define   FEC_OC_IPR_MODE_MERR_DIS_ERR__B                                   9
+#define   FEC_OC_IPR_MODE_MERR_DIS_ERR__W                                   1
+#define   FEC_OC_IPR_MODE_MERR_DIS_ERR__M                                   0x200
+#define   FEC_OC_IPR_MODE_MERR_DIS_ERR__PRE                                 0x0
+
+#define   FEC_OC_IPR_MODE_MD_DIS_ERR__B                                     10
+#define   FEC_OC_IPR_MODE_MD_DIS_ERR__W                                     1
+#define   FEC_OC_IPR_MODE_MD_DIS_ERR__M                                     0x400
+#define   FEC_OC_IPR_MODE_MD_DIS_ERR__PRE                                   0x0
+
+#define   FEC_OC_IPR_MODE_MSTRT_DIS_ERR__B                                  11
+#define   FEC_OC_IPR_MODE_MSTRT_DIS_ERR__W                                  1
+#define   FEC_OC_IPR_MODE_MSTRT_DIS_ERR__M                                  0x800
+#define   FEC_OC_IPR_MODE_MSTRT_DIS_ERR__PRE                                0x0
+
+#define FEC_OC_IPR_INVERT__A                                                0x2440049
+#define FEC_OC_IPR_INVERT__W                                                12
+#define FEC_OC_IPR_INVERT__M                                                0xFFF
+#define FEC_OC_IPR_INVERT__PRE                                              0x0
+
+#define   FEC_OC_IPR_INVERT_MD0__B                                          0
+#define   FEC_OC_IPR_INVERT_MD0__W                                          1
+#define   FEC_OC_IPR_INVERT_MD0__M                                          0x1
+#define   FEC_OC_IPR_INVERT_MD0__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD1__B                                          1
+#define   FEC_OC_IPR_INVERT_MD1__W                                          1
+#define   FEC_OC_IPR_INVERT_MD1__M                                          0x2
+#define   FEC_OC_IPR_INVERT_MD1__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD2__B                                          2
+#define   FEC_OC_IPR_INVERT_MD2__W                                          1
+#define   FEC_OC_IPR_INVERT_MD2__M                                          0x4
+#define   FEC_OC_IPR_INVERT_MD2__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD3__B                                          3
+#define   FEC_OC_IPR_INVERT_MD3__W                                          1
+#define   FEC_OC_IPR_INVERT_MD3__M                                          0x8
+#define   FEC_OC_IPR_INVERT_MD3__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD4__B                                          4
+#define   FEC_OC_IPR_INVERT_MD4__W                                          1
+#define   FEC_OC_IPR_INVERT_MD4__M                                          0x10
+#define   FEC_OC_IPR_INVERT_MD4__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD5__B                                          5
+#define   FEC_OC_IPR_INVERT_MD5__W                                          1
+#define   FEC_OC_IPR_INVERT_MD5__M                                          0x20
+#define   FEC_OC_IPR_INVERT_MD5__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD6__B                                          6
+#define   FEC_OC_IPR_INVERT_MD6__W                                          1
+#define   FEC_OC_IPR_INVERT_MD6__M                                          0x40
+#define   FEC_OC_IPR_INVERT_MD6__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MD7__B                                          7
+#define   FEC_OC_IPR_INVERT_MD7__W                                          1
+#define   FEC_OC_IPR_INVERT_MD7__M                                          0x80
+#define   FEC_OC_IPR_INVERT_MD7__PRE                                        0x0
+
+#define   FEC_OC_IPR_INVERT_MERR__B                                         8
+#define   FEC_OC_IPR_INVERT_MERR__W                                         1
+#define   FEC_OC_IPR_INVERT_MERR__M                                         0x100
+#define   FEC_OC_IPR_INVERT_MERR__PRE                                       0x0
+
+#define   FEC_OC_IPR_INVERT_MSTRT__B                                        9
+#define   FEC_OC_IPR_INVERT_MSTRT__W                                        1
+#define   FEC_OC_IPR_INVERT_MSTRT__M                                        0x200
+#define   FEC_OC_IPR_INVERT_MSTRT__PRE                                      0x0
+
+#define   FEC_OC_IPR_INVERT_MVAL__B                                         10
+#define   FEC_OC_IPR_INVERT_MVAL__W                                         1
+#define   FEC_OC_IPR_INVERT_MVAL__M                                         0x400
+#define   FEC_OC_IPR_INVERT_MVAL__PRE                                       0x0
+
+#define   FEC_OC_IPR_INVERT_MCLK__B                                         11
+#define   FEC_OC_IPR_INVERT_MCLK__W                                         1
+#define   FEC_OC_IPR_INVERT_MCLK__M                                         0x800
+#define   FEC_OC_IPR_INVERT_MCLK__PRE                                       0x0
+
+#define FEC_OC_OCR_MODE__A                                                  0x2440050
+#define FEC_OC_OCR_MODE__W                                                  4
+#define FEC_OC_OCR_MODE__M                                                  0xF
+#define FEC_OC_OCR_MODE__PRE                                                0x0
+
+#define   FEC_OC_OCR_MODE_MB_SELECT__B                                      0
+#define   FEC_OC_OCR_MODE_MB_SELECT__W                                      1
+#define   FEC_OC_OCR_MODE_MB_SELECT__M                                      0x1
+#define   FEC_OC_OCR_MODE_MB_SELECT__PRE                                    0x0
+
+#define   FEC_OC_OCR_MODE_GRAB_ENABLE__B                                    1
+#define   FEC_OC_OCR_MODE_GRAB_ENABLE__W                                    1
+#define   FEC_OC_OCR_MODE_GRAB_ENABLE__M                                    0x2
+#define   FEC_OC_OCR_MODE_GRAB_ENABLE__PRE                                  0x0
+
+#define   FEC_OC_OCR_MODE_GRAB_SELECT__B                                    2
+#define   FEC_OC_OCR_MODE_GRAB_SELECT__W                                    1
+#define   FEC_OC_OCR_MODE_GRAB_SELECT__M                                    0x4
+#define   FEC_OC_OCR_MODE_GRAB_SELECT__PRE                                  0x0
+
+#define   FEC_OC_OCR_MODE_GRAB_COUNTED__B                                   3
+#define   FEC_OC_OCR_MODE_GRAB_COUNTED__W                                   1
+#define   FEC_OC_OCR_MODE_GRAB_COUNTED__M                                   0x8
+#define   FEC_OC_OCR_MODE_GRAB_COUNTED__PRE                                 0x0
+
+#define FEC_OC_OCR_RATE__A                                                  0x2440051
+#define FEC_OC_OCR_RATE__W                                                  4
+#define FEC_OC_OCR_RATE__M                                                  0xF
+#define FEC_OC_OCR_RATE__PRE                                                0x0
+
+#define   FEC_OC_OCR_RATE_RATE__B                                           0
+#define   FEC_OC_OCR_RATE_RATE__W                                           4
+#define   FEC_OC_OCR_RATE_RATE__M                                           0xF
+#define   FEC_OC_OCR_RATE_RATE__PRE                                         0x0
+
+#define FEC_OC_OCR_INVERT__A                                                0x2440052
+#define FEC_OC_OCR_INVERT__W                                                12
+#define FEC_OC_OCR_INVERT__M                                                0xFFF
+#define FEC_OC_OCR_INVERT__PRE                                              0x800
+
+#define   FEC_OC_OCR_INVERT_INVERT__B                                       0
+#define   FEC_OC_OCR_INVERT_INVERT__W                                       12
+#define   FEC_OC_OCR_INVERT_INVERT__M                                       0xFFF
+#define   FEC_OC_OCR_INVERT_INVERT__PRE                                     0x800
+
+#define FEC_OC_OCR_GRAB_COUNT__A                                            0x2440053
+#define FEC_OC_OCR_GRAB_COUNT__W                                            16
+#define FEC_OC_OCR_GRAB_COUNT__M                                            0xFFFF
+#define FEC_OC_OCR_GRAB_COUNT__PRE                                          0x0
+
+#define   FEC_OC_OCR_GRAB_COUNT_COUNT__B                                    0
+#define   FEC_OC_OCR_GRAB_COUNT_COUNT__W                                    16
+#define   FEC_OC_OCR_GRAB_COUNT_COUNT__M                                    0xFFFF
+#define   FEC_OC_OCR_GRAB_COUNT_COUNT__PRE                                  0x0
+
+#define FEC_OC_OCR_GRAB_SYNC__A                                             0x2440054
+#define FEC_OC_OCR_GRAB_SYNC__W                                             8
+#define FEC_OC_OCR_GRAB_SYNC__M                                             0xFF
+#define FEC_OC_OCR_GRAB_SYNC__PRE                                           0x0
+
+#define   FEC_OC_OCR_GRAB_SYNC_BYTE_SEL__B                                  0
+#define   FEC_OC_OCR_GRAB_SYNC_BYTE_SEL__W                                  3
+#define   FEC_OC_OCR_GRAB_SYNC_BYTE_SEL__M                                  0x7
+#define   FEC_OC_OCR_GRAB_SYNC_BYTE_SEL__PRE                                0x0
+
+#define   FEC_OC_OCR_GRAB_SYNC_BIT_SEL__B                                   3
+#define   FEC_OC_OCR_GRAB_SYNC_BIT_SEL__W                                   4
+#define   FEC_OC_OCR_GRAB_SYNC_BIT_SEL__M                                   0x78
+#define   FEC_OC_OCR_GRAB_SYNC_BIT_SEL__PRE                                 0x0
+
+#define   FEC_OC_OCR_GRAB_SYNC_VALUE_SEL__B                                 7
+#define   FEC_OC_OCR_GRAB_SYNC_VALUE_SEL__W                                 1
+#define   FEC_OC_OCR_GRAB_SYNC_VALUE_SEL__M                                 0x80
+#define   FEC_OC_OCR_GRAB_SYNC_VALUE_SEL__PRE                               0x0
+
+#define FEC_OC_OCR_GRAB_RD0__A                                              0x2440055
+#define FEC_OC_OCR_GRAB_RD0__W                                              10
+#define FEC_OC_OCR_GRAB_RD0__M                                              0x3FF
+#define FEC_OC_OCR_GRAB_RD0__PRE                                            0x0
+
+#define   FEC_OC_OCR_GRAB_RD0_DATA__B                                       0
+#define   FEC_OC_OCR_GRAB_RD0_DATA__W                                       10
+#define   FEC_OC_OCR_GRAB_RD0_DATA__M                                       0x3FF
+#define   FEC_OC_OCR_GRAB_RD0_DATA__PRE                                     0x0
+
+#define FEC_OC_OCR_GRAB_RD1__A                                              0x2440056
+#define FEC_OC_OCR_GRAB_RD1__W                                              10
+#define FEC_OC_OCR_GRAB_RD1__M                                              0x3FF
+#define FEC_OC_OCR_GRAB_RD1__PRE                                            0x0
+
+#define   FEC_OC_OCR_GRAB_RD1_DATA__B                                       0
+#define   FEC_OC_OCR_GRAB_RD1_DATA__W                                       10
+#define   FEC_OC_OCR_GRAB_RD1_DATA__M                                       0x3FF
+#define   FEC_OC_OCR_GRAB_RD1_DATA__PRE                                     0x0
+
+#define FEC_OC_OCR_GRAB_RD2__A                                              0x2440057
+#define FEC_OC_OCR_GRAB_RD2__W                                              10
+#define FEC_OC_OCR_GRAB_RD2__M                                              0x3FF
+#define FEC_OC_OCR_GRAB_RD2__PRE                                            0x0
+
+#define   FEC_OC_OCR_GRAB_RD2_DATA__B                                       0
+#define   FEC_OC_OCR_GRAB_RD2_DATA__W                                       10
+#define   FEC_OC_OCR_GRAB_RD2_DATA__M                                       0x3FF
+#define   FEC_OC_OCR_GRAB_RD2_DATA__PRE                                     0x0
+
+#define FEC_OC_OCR_GRAB_RD3__A                                              0x2440058
+#define FEC_OC_OCR_GRAB_RD3__W                                              10
+#define FEC_OC_OCR_GRAB_RD3__M                                              0x3FF
+#define FEC_OC_OCR_GRAB_RD3__PRE                                            0x0
+
+#define   FEC_OC_OCR_GRAB_RD3_DATA__B                                       0
+#define   FEC_OC_OCR_GRAB_RD3_DATA__W                                       10
+#define   FEC_OC_OCR_GRAB_RD3_DATA__M                                       0x3FF
+#define   FEC_OC_OCR_GRAB_RD3_DATA__PRE                                     0x0
+
+#define FEC_OC_OCR_GRAB_RD4__A                                              0x2440059
+#define FEC_OC_OCR_GRAB_RD4__W                                              10
+#define FEC_OC_OCR_GRAB_RD4__M                                              0x3FF
+#define FEC_OC_OCR_GRAB_RD4__PRE                                            0x0
+
+#define   FEC_OC_OCR_GRAB_RD4_DATA__B                                       0
+#define   FEC_OC_OCR_GRAB_RD4_DATA__W                                       10
+#define   FEC_OC_OCR_GRAB_RD4_DATA__M                                       0x3FF
+#define   FEC_OC_OCR_GRAB_RD4_DATA__PRE                                     0x0
+
+#define FEC_OC_OCR_GRAB_RD5__A                                              0x244005A
+#define FEC_OC_OCR_GRAB_RD5__W                                              10
+#define FEC_OC_OCR_GRAB_RD5__M                                              0x3FF
+#define FEC_OC_OCR_GRAB_RD5__PRE                                            0x0
+
+#define   FEC_OC_OCR_GRAB_RD5_DATA__B                                       0
+#define   FEC_OC_OCR_GRAB_RD5_DATA__W                                       10
+#define   FEC_OC_OCR_GRAB_RD5_DATA__M                                       0x3FF
+#define   FEC_OC_OCR_GRAB_RD5_DATA__PRE                                     0x0
+
+#define FEC_DI_RAM__A                                                       0x2450000
+
+#define FEC_RS_RAM__A                                                       0x2460000
+
+#define FEC_OC_RAM__A                                                       0x2470000
+
+#define IQM_COMM_EXEC__A                                                    0x1800000
+#define IQM_COMM_EXEC__W                                                    2
+#define IQM_COMM_EXEC__M                                                    0x3
+#define IQM_COMM_EXEC__PRE                                                  0x0
+#define   IQM_COMM_EXEC_STOP                                                0x0
+#define   IQM_COMM_EXEC_ACTIVE                                              0x1
+#define   IQM_COMM_EXEC_HOLD                                                0x2
+
+#define IQM_COMM_MB__A                                                      0x1800002
+#define IQM_COMM_MB__W                                                      16
+#define IQM_COMM_MB__M                                                      0xFFFF
+#define IQM_COMM_MB__PRE                                                    0x0
+#define IQM_COMM_INT_REQ__A                                                 0x1800003
+#define IQM_COMM_INT_REQ__W                                                 2
+#define IQM_COMM_INT_REQ__M                                                 0x3
+#define IQM_COMM_INT_REQ__PRE                                               0x0
+
+#define   IQM_COMM_INT_REQ_AF_REQ__B                                        0
+#define   IQM_COMM_INT_REQ_AF_REQ__W                                        1
+#define   IQM_COMM_INT_REQ_AF_REQ__M                                        0x1
+#define   IQM_COMM_INT_REQ_AF_REQ__PRE                                      0x0
+
+#define   IQM_COMM_INT_REQ_CF_REQ__B                                        1
+#define   IQM_COMM_INT_REQ_CF_REQ__W                                        1
+#define   IQM_COMM_INT_REQ_CF_REQ__M                                        0x2
+#define   IQM_COMM_INT_REQ_CF_REQ__PRE                                      0x0
+
+#define IQM_COMM_INT_STA__A                                                 0x1800005
+#define IQM_COMM_INT_STA__W                                                 16
+#define IQM_COMM_INT_STA__M                                                 0xFFFF
+#define IQM_COMM_INT_STA__PRE                                               0x0
+#define IQM_COMM_INT_MSK__A                                                 0x1800006
+#define IQM_COMM_INT_MSK__W                                                 16
+#define IQM_COMM_INT_MSK__M                                                 0xFFFF
+#define IQM_COMM_INT_MSK__PRE                                               0x0
+#define IQM_COMM_INT_STM__A                                                 0x1800007
+#define IQM_COMM_INT_STM__W                                                 16
+#define IQM_COMM_INT_STM__M                                                 0xFFFF
+#define IQM_COMM_INT_STM__PRE                                               0x0
+
+#define IQM_FS_COMM_EXEC__A                                                 0x1820000
+#define IQM_FS_COMM_EXEC__W                                                 2
+#define IQM_FS_COMM_EXEC__M                                                 0x3
+#define IQM_FS_COMM_EXEC__PRE                                               0x0
+#define   IQM_FS_COMM_EXEC_STOP                                             0x0
+#define   IQM_FS_COMM_EXEC_ACTIVE                                           0x1
+#define   IQM_FS_COMM_EXEC_HOLD                                             0x2
+
+#define IQM_FS_COMM_MB__A                                                   0x1820002
+#define IQM_FS_COMM_MB__W                                                   2
+#define IQM_FS_COMM_MB__M                                                   0x3
+#define IQM_FS_COMM_MB__PRE                                                 0x0
+#define   IQM_FS_COMM_MB_CTL__B                                             0
+#define   IQM_FS_COMM_MB_CTL__W                                             1
+#define   IQM_FS_COMM_MB_CTL__M                                             0x1
+#define   IQM_FS_COMM_MB_CTL__PRE                                           0x0
+#define     IQM_FS_COMM_MB_CTL_CTL_OFF                                      0x0
+#define     IQM_FS_COMM_MB_CTL_CTL_ON                                       0x1
+#define   IQM_FS_COMM_MB_OBS__B                                             1
+#define   IQM_FS_COMM_MB_OBS__W                                             1
+#define   IQM_FS_COMM_MB_OBS__M                                             0x2
+#define   IQM_FS_COMM_MB_OBS__PRE                                           0x0
+#define     IQM_FS_COMM_MB_OBS_OBS_OFF                                      0x0
+#define     IQM_FS_COMM_MB_OBS_OBS_ON                                       0x2
+
+#define IQM_FS_RATE_OFS_LO__A                                               0x1820010
+#define IQM_FS_RATE_OFS_LO__W                                               16
+#define IQM_FS_RATE_OFS_LO__M                                               0xFFFF
+#define IQM_FS_RATE_OFS_LO__PRE                                             0x0
+#define IQM_FS_RATE_OFS_HI__A                                               0x1820011
+#define IQM_FS_RATE_OFS_HI__W                                               12
+#define IQM_FS_RATE_OFS_HI__M                                               0xFFF
+#define IQM_FS_RATE_OFS_HI__PRE                                             0x0
+#define IQM_FS_RATE_LO__A                                                   0x1820012
+#define IQM_FS_RATE_LO__W                                                   16
+#define IQM_FS_RATE_LO__M                                                   0xFFFF
+#define IQM_FS_RATE_LO__PRE                                                 0x0
+#define IQM_FS_RATE_HI__A                                                   0x1820013
+#define IQM_FS_RATE_HI__W                                                   12
+#define IQM_FS_RATE_HI__M                                                   0xFFF
+#define IQM_FS_RATE_HI__PRE                                                 0x0
+
+#define IQM_FS_ADJ_SEL__A                                                   0x1820014
+#define IQM_FS_ADJ_SEL__W                                                   2
+#define IQM_FS_ADJ_SEL__M                                                   0x3
+#define IQM_FS_ADJ_SEL__PRE                                                 0x0
+#define   IQM_FS_ADJ_SEL_OFF                                                0x0
+#define   IQM_FS_ADJ_SEL_QAM                                                0x1
+#define   IQM_FS_ADJ_SEL_VSB                                                0x2
+
+#define IQM_FD_COMM_EXEC__A                                                 0x1830000
+#define IQM_FD_COMM_EXEC__W                                                 2
+#define IQM_FD_COMM_EXEC__M                                                 0x3
+#define IQM_FD_COMM_EXEC__PRE                                               0x0
+#define   IQM_FD_COMM_EXEC_STOP                                             0x0
+#define   IQM_FD_COMM_EXEC_ACTIVE                                           0x1
+#define   IQM_FD_COMM_EXEC_HOLD                                             0x2
+
+#define IQM_FD_COMM_MB__A                                                   0x1830002
+#define IQM_FD_COMM_MB__W                                                   2
+#define IQM_FD_COMM_MB__M                                                   0x3
+#define IQM_FD_COMM_MB__PRE                                                 0x0
+#define   IQM_FD_COMM_MB_CTL__B                                             0
+#define   IQM_FD_COMM_MB_CTL__W                                             1
+#define   IQM_FD_COMM_MB_CTL__M                                             0x1
+#define   IQM_FD_COMM_MB_CTL__PRE                                           0x0
+#define     IQM_FD_COMM_MB_CTL_CTL_OFF                                      0x0
+#define     IQM_FD_COMM_MB_CTL_CTL_ON                                       0x1
+#define   IQM_FD_COMM_MB_OBS__B                                             1
+#define   IQM_FD_COMM_MB_OBS__W                                             1
+#define   IQM_FD_COMM_MB_OBS__M                                             0x2
+#define   IQM_FD_COMM_MB_OBS__PRE                                           0x0
+#define     IQM_FD_COMM_MB_OBS_OBS_OFF                                      0x0
+#define     IQM_FD_COMM_MB_OBS_OBS_ON                                       0x2
+
+#define IQM_RC_COMM_EXEC__A                                                 0x1840000
+#define IQM_RC_COMM_EXEC__W                                                 2
+#define IQM_RC_COMM_EXEC__M                                                 0x3
+#define IQM_RC_COMM_EXEC__PRE                                               0x0
+#define   IQM_RC_COMM_EXEC_STOP                                             0x0
+#define   IQM_RC_COMM_EXEC_ACTIVE                                           0x1
+#define   IQM_RC_COMM_EXEC_HOLD                                             0x2
+
+#define IQM_RC_COMM_MB__A                                                   0x1840002
+#define IQM_RC_COMM_MB__W                                                   2
+#define IQM_RC_COMM_MB__M                                                   0x3
+#define IQM_RC_COMM_MB__PRE                                                 0x0
+#define   IQM_RC_COMM_MB_CTL__B                                             0
+#define   IQM_RC_COMM_MB_CTL__W                                             1
+#define   IQM_RC_COMM_MB_CTL__M                                             0x1
+#define   IQM_RC_COMM_MB_CTL__PRE                                           0x0
+#define     IQM_RC_COMM_MB_CTL_CTL_OFF                                      0x0
+#define     IQM_RC_COMM_MB_CTL_CTL_ON                                       0x1
+#define   IQM_RC_COMM_MB_OBS__B                                             1
+#define   IQM_RC_COMM_MB_OBS__W                                             1
+#define   IQM_RC_COMM_MB_OBS__M                                             0x2
+#define   IQM_RC_COMM_MB_OBS__PRE                                           0x0
+#define     IQM_RC_COMM_MB_OBS_OBS_OFF                                      0x0
+#define     IQM_RC_COMM_MB_OBS_OBS_ON                                       0x2
+
+#define IQM_RC_RATE_OFS_LO__A                                               0x1840010
+#define IQM_RC_RATE_OFS_LO__W                                               16
+#define IQM_RC_RATE_OFS_LO__M                                               0xFFFF
+#define IQM_RC_RATE_OFS_LO__PRE                                             0x0
+#define IQM_RC_RATE_OFS_HI__A                                               0x1840011
+#define IQM_RC_RATE_OFS_HI__W                                               8
+#define IQM_RC_RATE_OFS_HI__M                                               0xFF
+#define IQM_RC_RATE_OFS_HI__PRE                                             0x0
+#define IQM_RC_RATE_LO__A                                                   0x1840012
+#define IQM_RC_RATE_LO__W                                                   16
+#define IQM_RC_RATE_LO__M                                                   0xFFFF
+#define IQM_RC_RATE_LO__PRE                                                 0x0
+#define IQM_RC_RATE_HI__A                                                   0x1840013
+#define IQM_RC_RATE_HI__W                                                   8
+#define IQM_RC_RATE_HI__M                                                   0xFF
+#define IQM_RC_RATE_HI__PRE                                                 0x0
+
+#define IQM_RC_ADJ_SEL__A                                                   0x1840014
+#define IQM_RC_ADJ_SEL__W                                                   2
+#define IQM_RC_ADJ_SEL__M                                                   0x3
+#define IQM_RC_ADJ_SEL__PRE                                                 0x0
+#define   IQM_RC_ADJ_SEL_OFF                                                0x0
+#define   IQM_RC_ADJ_SEL_QAM                                                0x1
+#define   IQM_RC_ADJ_SEL_VSB                                                0x2
+
+#define IQM_RC_CROUT_ENA__A                                                 0x1840015
+#define IQM_RC_CROUT_ENA__W                                                 1
+#define IQM_RC_CROUT_ENA__M                                                 0x1
+#define IQM_RC_CROUT_ENA__PRE                                               0x0
+
+#define   IQM_RC_CROUT_ENA_ENA__B                                           0
+#define   IQM_RC_CROUT_ENA_ENA__W                                           1
+#define   IQM_RC_CROUT_ENA_ENA__M                                           0x1
+#define   IQM_RC_CROUT_ENA_ENA__PRE                                         0x0
+
+#define IQM_RC_STRETCH__A                                                   0x1840016
+#define IQM_RC_STRETCH__W                                                   5
+#define IQM_RC_STRETCH__M                                                   0x1F
+#define IQM_RC_STRETCH__PRE                                                 0x0
+#define   IQM_RC_STRETCH_QAM_B_64                                           0x1E
+#define   IQM_RC_STRETCH_QAM_B_256                                          0x1C
+#define   IQM_RC_STRETCH_ATV                                                0xF
+
+#define IQM_RT_COMM_EXEC__A                                                 0x1850000
+#define IQM_RT_COMM_EXEC__W                                                 2
+#define IQM_RT_COMM_EXEC__M                                                 0x3
+#define IQM_RT_COMM_EXEC__PRE                                               0x0
+#define   IQM_RT_COMM_EXEC_STOP                                             0x0
+#define   IQM_RT_COMM_EXEC_ACTIVE                                           0x1
+#define   IQM_RT_COMM_EXEC_HOLD                                             0x2
+
+#define IQM_RT_COMM_MB__A                                                   0x1850002
+#define IQM_RT_COMM_MB__W                                                   2
+#define IQM_RT_COMM_MB__M                                                   0x3
+#define IQM_RT_COMM_MB__PRE                                                 0x0
+#define   IQM_RT_COMM_MB_CTL__B                                             0
+#define   IQM_RT_COMM_MB_CTL__W                                             1
+#define   IQM_RT_COMM_MB_CTL__M                                             0x1
+#define   IQM_RT_COMM_MB_CTL__PRE                                           0x0
+#define     IQM_RT_COMM_MB_CTL_CTL_OFF                                      0x0
+#define     IQM_RT_COMM_MB_CTL_CTL_ON                                       0x1
+#define   IQM_RT_COMM_MB_OBS__B                                             1
+#define   IQM_RT_COMM_MB_OBS__W                                             1
+#define   IQM_RT_COMM_MB_OBS__M                                             0x2
+#define   IQM_RT_COMM_MB_OBS__PRE                                           0x0
+#define     IQM_RT_COMM_MB_OBS_OBS_OFF                                      0x0
+#define     IQM_RT_COMM_MB_OBS_OBS_ON                                       0x2
+
+#define IQM_RT_ACTIVE__A                                                    0x1850010
+#define IQM_RT_ACTIVE__W                                                    2
+#define IQM_RT_ACTIVE__M                                                    0x3
+#define IQM_RT_ACTIVE__PRE                                                  0x0
+
+#define   IQM_RT_ACTIVE_ACTIVE_RT__B                                        0
+#define   IQM_RT_ACTIVE_ACTIVE_RT__W                                        1
+#define   IQM_RT_ACTIVE_ACTIVE_RT__M                                        0x1
+#define   IQM_RT_ACTIVE_ACTIVE_RT__PRE                                      0x0
+#define     IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_OFF                             0x0
+#define     IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON                              0x1
+
+#define   IQM_RT_ACTIVE_ACTIVE_CR__B                                        1
+#define   IQM_RT_ACTIVE_ACTIVE_CR__W                                        1
+#define   IQM_RT_ACTIVE_ACTIVE_CR__M                                        0x2
+#define   IQM_RT_ACTIVE_ACTIVE_CR__PRE                                      0x0
+#define     IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_OFF                              0x0
+#define     IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON                               0x2
+
+#define IQM_RT_LO_INCR__A                                                   0x1850011
+#define IQM_RT_LO_INCR__W                                                   12
+#define IQM_RT_LO_INCR__M                                                   0xFFF
+#define IQM_RT_LO_INCR__PRE                                                 0x588
+#define   IQM_RT_LO_INCR_FM                                                 0x0
+#define   IQM_RT_LO_INCR_MN                                                 0x588
+
+#define IQM_RT_ROT_BP__A                                                    0x1850012
+#define IQM_RT_ROT_BP__W                                                    2
+#define IQM_RT_ROT_BP__M                                                    0x3
+#define IQM_RT_ROT_BP__PRE                                                  0x0
+
+#define   IQM_RT_ROT_BP_ROT_OFF__B                                          0
+#define   IQM_RT_ROT_BP_ROT_OFF__W                                          1
+#define   IQM_RT_ROT_BP_ROT_OFF__M                                          0x1
+#define   IQM_RT_ROT_BP_ROT_OFF__PRE                                        0x0
+#define     IQM_RT_ROT_BP_ROT_OFF_ACTIVE                                    0x0
+#define     IQM_RT_ROT_BP_ROT_OFF_OFF                                       0x1
+
+#define   IQM_RT_ROT_BP_ROT_BPF__B                                          1
+#define   IQM_RT_ROT_BP_ROT_BPF__W                                          1
+#define   IQM_RT_ROT_BP_ROT_BPF__M                                          0x2
+#define   IQM_RT_ROT_BP_ROT_BPF__PRE                                        0x0
+
+#define IQM_RT_LP_BP__A                                                     0x1850013
+#define IQM_RT_LP_BP__W                                                     1
+#define IQM_RT_LP_BP__M                                                     0x1
+#define IQM_RT_LP_BP__PRE                                                   0x0
+
+#define IQM_RT_DELAY__A                                                     0x1850014
+#define IQM_RT_DELAY__W                                                     7
+#define IQM_RT_DELAY__M                                                     0x7F
+#define IQM_RT_DELAY__PRE                                                   0x45
+
+#define IQM_CF_COMM_EXEC__A                                                 0x1860000
+#define IQM_CF_COMM_EXEC__W                                                 2
+#define IQM_CF_COMM_EXEC__M                                                 0x3
+#define IQM_CF_COMM_EXEC__PRE                                               0x0
+#define   IQM_CF_COMM_EXEC_STOP                                             0x0
+#define   IQM_CF_COMM_EXEC_ACTIVE                                           0x1
+#define   IQM_CF_COMM_EXEC_HOLD                                             0x2
+
+#define IQM_CF_COMM_MB__A                                                   0x1860002
+#define IQM_CF_COMM_MB__W                                                   2
+#define IQM_CF_COMM_MB__M                                                   0x3
+#define IQM_CF_COMM_MB__PRE                                                 0x0
+#define   IQM_CF_COMM_MB_CTL__B                                             0
+#define   IQM_CF_COMM_MB_CTL__W                                             1
+#define   IQM_CF_COMM_MB_CTL__M                                             0x1
+#define   IQM_CF_COMM_MB_CTL__PRE                                           0x0
+#define     IQM_CF_COMM_MB_CTL_CTL_OFF                                      0x0
+#define     IQM_CF_COMM_MB_CTL_CTL_ON                                       0x1
+#define   IQM_CF_COMM_MB_OBS__B                                             1
+#define   IQM_CF_COMM_MB_OBS__W                                             1
+#define   IQM_CF_COMM_MB_OBS__M                                             0x2
+#define   IQM_CF_COMM_MB_OBS__PRE                                           0x0
+#define     IQM_CF_COMM_MB_OBS_OBS_OFF                                      0x0
+#define     IQM_CF_COMM_MB_OBS_OBS_ON                                       0x2
+
+#define IQM_CF_COMM_INT_REQ__A                                              0x1860003
+#define IQM_CF_COMM_INT_REQ__W                                              1
+#define IQM_CF_COMM_INT_REQ__M                                              0x1
+#define IQM_CF_COMM_INT_REQ__PRE                                            0x0
+#define IQM_CF_COMM_INT_STA__A                                              0x1860005
+#define IQM_CF_COMM_INT_STA__W                                              1
+#define IQM_CF_COMM_INT_STA__M                                              0x1
+#define IQM_CF_COMM_INT_STA__PRE                                            0x0
+#define   IQM_CF_COMM_INT_STA_PM__B                                         0
+#define   IQM_CF_COMM_INT_STA_PM__W                                         1
+#define   IQM_CF_COMM_INT_STA_PM__M                                         0x1
+#define   IQM_CF_COMM_INT_STA_PM__PRE                                       0x0
+
+#define IQM_CF_COMM_INT_MSK__A                                              0x1860006
+#define IQM_CF_COMM_INT_MSK__W                                              1
+#define IQM_CF_COMM_INT_MSK__M                                              0x1
+#define IQM_CF_COMM_INT_MSK__PRE                                            0x0
+#define   IQM_CF_COMM_INT_MSK_PM__B                                         0
+#define   IQM_CF_COMM_INT_MSK_PM__W                                         1
+#define   IQM_CF_COMM_INT_MSK_PM__M                                         0x1
+#define   IQM_CF_COMM_INT_MSK_PM__PRE                                       0x0
+
+#define IQM_CF_COMM_INT_STM__A                                              0x1860007
+#define IQM_CF_COMM_INT_STM__W                                              1
+#define IQM_CF_COMM_INT_STM__M                                              0x1
+#define IQM_CF_COMM_INT_STM__PRE                                            0x0
+#define   IQM_CF_COMM_INT_STM_PM__B                                         0
+#define   IQM_CF_COMM_INT_STM_PM__W                                         1
+#define   IQM_CF_COMM_INT_STM_PM__M                                         0x1
+#define   IQM_CF_COMM_INT_STM_PM__PRE                                       0x0
+
+#define IQM_CF_SYMMETRIC__A                                                 0x1860010
+#define IQM_CF_SYMMETRIC__W                                                 2
+#define IQM_CF_SYMMETRIC__M                                                 0x3
+#define IQM_CF_SYMMETRIC__PRE                                               0x0
+
+#define   IQM_CF_SYMMETRIC_RE__B                                            0
+#define   IQM_CF_SYMMETRIC_RE__W                                            1
+#define   IQM_CF_SYMMETRIC_RE__M                                            0x1
+#define   IQM_CF_SYMMETRIC_RE__PRE                                          0x0
+
+#define   IQM_CF_SYMMETRIC_IM__B                                            1
+#define   IQM_CF_SYMMETRIC_IM__W                                            1
+#define   IQM_CF_SYMMETRIC_IM__M                                            0x2
+#define   IQM_CF_SYMMETRIC_IM__PRE                                          0x0
+
+#define IQM_CF_MIDTAP__A                                                    0x1860011
+#define IQM_CF_MIDTAP__W                                                    2
+#define IQM_CF_MIDTAP__M                                                    0x3
+#define IQM_CF_MIDTAP__PRE                                                  0x3
+
+#define   IQM_CF_MIDTAP_RE__B                                               0
+#define   IQM_CF_MIDTAP_RE__W                                               1
+#define   IQM_CF_MIDTAP_RE__M                                               0x1
+#define   IQM_CF_MIDTAP_RE__PRE                                             0x1
+
+#define   IQM_CF_MIDTAP_IM__B                                               1
+#define   IQM_CF_MIDTAP_IM__W                                               1
+#define   IQM_CF_MIDTAP_IM__M                                               0x2
+#define   IQM_CF_MIDTAP_IM__PRE                                             0x2
+
+#define IQM_CF_OUT_ENA__A                                                   0x1860012
+#define IQM_CF_OUT_ENA__W                                                   3
+#define IQM_CF_OUT_ENA__M                                                   0x7
+#define IQM_CF_OUT_ENA__PRE                                                 0x0
+
+#define   IQM_CF_OUT_ENA_ATV__B                                             0
+#define   IQM_CF_OUT_ENA_ATV__W                                             1
+#define   IQM_CF_OUT_ENA_ATV__M                                             0x1
+#define   IQM_CF_OUT_ENA_ATV__PRE                                           0x0
+
+#define   IQM_CF_OUT_ENA_QAM__B                                             1
+#define   IQM_CF_OUT_ENA_QAM__W                                             1
+#define   IQM_CF_OUT_ENA_QAM__M                                             0x2
+#define   IQM_CF_OUT_ENA_QAM__PRE                                           0x0
+
+#define   IQM_CF_OUT_ENA_VSB__B                                             2
+#define   IQM_CF_OUT_ENA_VSB__W                                             1
+#define   IQM_CF_OUT_ENA_VSB__M                                             0x4
+#define   IQM_CF_OUT_ENA_VSB__PRE                                           0x0
+
+#define IQM_CF_ADJ_SEL__A                                                   0x1860013
+#define IQM_CF_ADJ_SEL__W                                                   2
+#define IQM_CF_ADJ_SEL__M                                                   0x3
+#define IQM_CF_ADJ_SEL__PRE                                                 0x0
+#define IQM_CF_SCALE__A                                                     0x1860014
+#define IQM_CF_SCALE__W                                                     14
+#define IQM_CF_SCALE__M                                                     0x3FFF
+#define IQM_CF_SCALE__PRE                                                   0x400
+
+#define IQM_CF_SCALE_SH__A                                                  0x1860015
+#define IQM_CF_SCALE_SH__W                                                  2
+#define IQM_CF_SCALE_SH__M                                                  0x3
+#define IQM_CF_SCALE_SH__PRE                                                0x0
+
+#define IQM_CF_AMP__A                                                       0x1860016
+#define IQM_CF_AMP__W                                                       14
+#define IQM_CF_AMP__M                                                       0x3FFF
+#define IQM_CF_AMP__PRE                                                     0x0
+
+#define IQM_CF_POW_MEAS_LEN__A                                              0x1860017
+#define IQM_CF_POW_MEAS_LEN__W                                              3
+#define IQM_CF_POW_MEAS_LEN__M                                              0x7
+#define IQM_CF_POW_MEAS_LEN__PRE                                            0x2
+#define   IQM_CF_POW_MEAS_LEN_QAM_B_64                                      0x1
+#define   IQM_CF_POW_MEAS_LEN_QAM_B_256                                     0x1
+
+#define IQM_CF_POW__A                                                       0x1860018
+#define IQM_CF_POW__W                                                       16
+#define IQM_CF_POW__M                                                       0xFFFF
+#define IQM_CF_POW__PRE                                                     0x2
+#define IQM_CF_TAP_RE0__A                                                   0x1860020
+#define IQM_CF_TAP_RE0__W                                                   7
+#define IQM_CF_TAP_RE0__M                                                   0x7F
+#define IQM_CF_TAP_RE0__PRE                                                 0x2
+#define IQM_CF_TAP_RE1__A                                                   0x1860021
+#define IQM_CF_TAP_RE1__W                                                   7
+#define IQM_CF_TAP_RE1__M                                                   0x7F
+#define IQM_CF_TAP_RE1__PRE                                                 0x2
+#define IQM_CF_TAP_RE2__A                                                   0x1860022
+#define IQM_CF_TAP_RE2__W                                                   7
+#define IQM_CF_TAP_RE2__M                                                   0x7F
+#define IQM_CF_TAP_RE2__PRE                                                 0x2
+#define IQM_CF_TAP_RE3__A                                                   0x1860023
+#define IQM_CF_TAP_RE3__W                                                   7
+#define IQM_CF_TAP_RE3__M                                                   0x7F
+#define IQM_CF_TAP_RE3__PRE                                                 0x2
+#define IQM_CF_TAP_RE4__A                                                   0x1860024
+#define IQM_CF_TAP_RE4__W                                                   7
+#define IQM_CF_TAP_RE4__M                                                   0x7F
+#define IQM_CF_TAP_RE4__PRE                                                 0x2
+#define IQM_CF_TAP_RE5__A                                                   0x1860025
+#define IQM_CF_TAP_RE5__W                                                   7
+#define IQM_CF_TAP_RE5__M                                                   0x7F
+#define IQM_CF_TAP_RE5__PRE                                                 0x2
+#define IQM_CF_TAP_RE6__A                                                   0x1860026
+#define IQM_CF_TAP_RE6__W                                                   7
+#define IQM_CF_TAP_RE6__M                                                   0x7F
+#define IQM_CF_TAP_RE6__PRE                                                 0x2
+#define IQM_CF_TAP_RE7__A                                                   0x1860027
+#define IQM_CF_TAP_RE7__W                                                   9
+#define IQM_CF_TAP_RE7__M                                                   0x1FF
+#define IQM_CF_TAP_RE7__PRE                                                 0x2
+#define IQM_CF_TAP_RE8__A                                                   0x1860028
+#define IQM_CF_TAP_RE8__W                                                   9
+#define IQM_CF_TAP_RE8__M                                                   0x1FF
+#define IQM_CF_TAP_RE8__PRE                                                 0x2
+#define IQM_CF_TAP_RE9__A                                                   0x1860029
+#define IQM_CF_TAP_RE9__W                                                   9
+#define IQM_CF_TAP_RE9__M                                                   0x1FF
+#define IQM_CF_TAP_RE9__PRE                                                 0x2
+#define IQM_CF_TAP_RE10__A                                                  0x186002A
+#define IQM_CF_TAP_RE10__W                                                  9
+#define IQM_CF_TAP_RE10__M                                                  0x1FF
+#define IQM_CF_TAP_RE10__PRE                                                0x2
+#define IQM_CF_TAP_RE11__A                                                  0x186002B
+#define IQM_CF_TAP_RE11__W                                                  9
+#define IQM_CF_TAP_RE11__M                                                  0x1FF
+#define IQM_CF_TAP_RE11__PRE                                                0x2
+#define IQM_CF_TAP_RE12__A                                                  0x186002C
+#define IQM_CF_TAP_RE12__W                                                  9
+#define IQM_CF_TAP_RE12__M                                                  0x1FF
+#define IQM_CF_TAP_RE12__PRE                                                0x2
+#define IQM_CF_TAP_RE13__A                                                  0x186002D
+#define IQM_CF_TAP_RE13__W                                                  9
+#define IQM_CF_TAP_RE13__M                                                  0x1FF
+#define IQM_CF_TAP_RE13__PRE                                                0x2
+#define IQM_CF_TAP_RE14__A                                                  0x186002E
+#define IQM_CF_TAP_RE14__W                                                  9
+#define IQM_CF_TAP_RE14__M                                                  0x1FF
+#define IQM_CF_TAP_RE14__PRE                                                0x2
+#define IQM_CF_TAP_RE15__A                                                  0x186002F
+#define IQM_CF_TAP_RE15__W                                                  9
+#define IQM_CF_TAP_RE15__M                                                  0x1FF
+#define IQM_CF_TAP_RE15__PRE                                                0x2
+#define IQM_CF_TAP_RE16__A                                                  0x1860030
+#define IQM_CF_TAP_RE16__W                                                  9
+#define IQM_CF_TAP_RE16__M                                                  0x1FF
+#define IQM_CF_TAP_RE16__PRE                                                0x2
+#define IQM_CF_TAP_RE17__A                                                  0x1860031
+#define IQM_CF_TAP_RE17__W                                                  9
+#define IQM_CF_TAP_RE17__M                                                  0x1FF
+#define IQM_CF_TAP_RE17__PRE                                                0x2
+#define IQM_CF_TAP_RE18__A                                                  0x1860032
+#define IQM_CF_TAP_RE18__W                                                  9
+#define IQM_CF_TAP_RE18__M                                                  0x1FF
+#define IQM_CF_TAP_RE18__PRE                                                0x2
+#define IQM_CF_TAP_RE19__A                                                  0x1860033
+#define IQM_CF_TAP_RE19__W                                                  9
+#define IQM_CF_TAP_RE19__M                                                  0x1FF
+#define IQM_CF_TAP_RE19__PRE                                                0x2
+#define IQM_CF_TAP_RE20__A                                                  0x1860034
+#define IQM_CF_TAP_RE20__W                                                  9
+#define IQM_CF_TAP_RE20__M                                                  0x1FF
+#define IQM_CF_TAP_RE20__PRE                                                0x2
+#define IQM_CF_TAP_RE21__A                                                  0x1860035
+#define IQM_CF_TAP_RE21__W                                                  11
+#define IQM_CF_TAP_RE21__M                                                  0x7FF
+#define IQM_CF_TAP_RE21__PRE                                                0x2
+#define IQM_CF_TAP_RE22__A                                                  0x1860036
+#define IQM_CF_TAP_RE22__W                                                  11
+#define IQM_CF_TAP_RE22__M                                                  0x7FF
+#define IQM_CF_TAP_RE22__PRE                                                0x2
+#define IQM_CF_TAP_RE23__A                                                  0x1860037
+#define IQM_CF_TAP_RE23__W                                                  11
+#define IQM_CF_TAP_RE23__M                                                  0x7FF
+#define IQM_CF_TAP_RE23__PRE                                                0x2
+#define IQM_CF_TAP_RE24__A                                                  0x1860038
+#define IQM_CF_TAP_RE24__W                                                  11
+#define IQM_CF_TAP_RE24__M                                                  0x7FF
+#define IQM_CF_TAP_RE24__PRE                                                0x2
+#define IQM_CF_TAP_RE25__A                                                  0x1860039
+#define IQM_CF_TAP_RE25__W                                                  11
+#define IQM_CF_TAP_RE25__M                                                  0x7FF
+#define IQM_CF_TAP_RE25__PRE                                                0x2
+#define IQM_CF_TAP_RE26__A                                                  0x186003A
+#define IQM_CF_TAP_RE26__W                                                  11
+#define IQM_CF_TAP_RE26__M                                                  0x7FF
+#define IQM_CF_TAP_RE26__PRE                                                0x2
+#define IQM_CF_TAP_RE27__A                                                  0x186003B
+#define IQM_CF_TAP_RE27__W                                                  11
+#define IQM_CF_TAP_RE27__M                                                  0x7FF
+#define IQM_CF_TAP_RE27__PRE                                                0x2
+#define IQM_CF_TAP_IM0__A                                                   0x1860040
+#define IQM_CF_TAP_IM0__W                                                   7
+#define IQM_CF_TAP_IM0__M                                                   0x7F
+#define IQM_CF_TAP_IM0__PRE                                                 0x2
+#define IQM_CF_TAP_IM1__A                                                   0x1860041
+#define IQM_CF_TAP_IM1__W                                                   7
+#define IQM_CF_TAP_IM1__M                                                   0x7F
+#define IQM_CF_TAP_IM1__PRE                                                 0x2
+#define IQM_CF_TAP_IM2__A                                                   0x1860042
+#define IQM_CF_TAP_IM2__W                                                   7
+#define IQM_CF_TAP_IM2__M                                                   0x7F
+#define IQM_CF_TAP_IM2__PRE                                                 0x2
+#define IQM_CF_TAP_IM3__A                                                   0x1860043
+#define IQM_CF_TAP_IM3__W                                                   7
+#define IQM_CF_TAP_IM3__M                                                   0x7F
+#define IQM_CF_TAP_IM3__PRE                                                 0x2
+#define IQM_CF_TAP_IM4__A                                                   0x1860044
+#define IQM_CF_TAP_IM4__W                                                   7
+#define IQM_CF_TAP_IM4__M                                                   0x7F
+#define IQM_CF_TAP_IM4__PRE                                                 0x2
+#define IQM_CF_TAP_IM5__A                                                   0x1860045
+#define IQM_CF_TAP_IM5__W                                                   7
+#define IQM_CF_TAP_IM5__M                                                   0x7F
+#define IQM_CF_TAP_IM5__PRE                                                 0x2
+#define IQM_CF_TAP_IM6__A                                                   0x1860046
+#define IQM_CF_TAP_IM6__W                                                   7
+#define IQM_CF_TAP_IM6__M                                                   0x7F
+#define IQM_CF_TAP_IM6__PRE                                                 0x2
+#define IQM_CF_TAP_IM7__A                                                   0x1860047
+#define IQM_CF_TAP_IM7__W                                                   9
+#define IQM_CF_TAP_IM7__M                                                   0x1FF
+#define IQM_CF_TAP_IM7__PRE                                                 0x2
+#define IQM_CF_TAP_IM8__A                                                   0x1860048
+#define IQM_CF_TAP_IM8__W                                                   9
+#define IQM_CF_TAP_IM8__M                                                   0x1FF
+#define IQM_CF_TAP_IM8__PRE                                                 0x2
+#define IQM_CF_TAP_IM9__A                                                   0x1860049
+#define IQM_CF_TAP_IM9__W                                                   9
+#define IQM_CF_TAP_IM9__M                                                   0x1FF
+#define IQM_CF_TAP_IM9__PRE                                                 0x2
+#define IQM_CF_TAP_IM10__A                                                  0x186004A
+#define IQM_CF_TAP_IM10__W                                                  9
+#define IQM_CF_TAP_IM10__M                                                  0x1FF
+#define IQM_CF_TAP_IM10__PRE                                                0x2
+#define IQM_CF_TAP_IM11__A                                                  0x186004B
+#define IQM_CF_TAP_IM11__W                                                  9
+#define IQM_CF_TAP_IM11__M                                                  0x1FF
+#define IQM_CF_TAP_IM11__PRE                                                0x2
+#define IQM_CF_TAP_IM12__A                                                  0x186004C
+#define IQM_CF_TAP_IM12__W                                                  9
+#define IQM_CF_TAP_IM12__M                                                  0x1FF
+#define IQM_CF_TAP_IM12__PRE                                                0x2
+#define IQM_CF_TAP_IM13__A                                                  0x186004D
+#define IQM_CF_TAP_IM13__W                                                  9
+#define IQM_CF_TAP_IM13__M                                                  0x1FF
+#define IQM_CF_TAP_IM13__PRE                                                0x2
+#define IQM_CF_TAP_IM14__A                                                  0x186004E
+#define IQM_CF_TAP_IM14__W                                                  9
+#define IQM_CF_TAP_IM14__M                                                  0x1FF
+#define IQM_CF_TAP_IM14__PRE                                                0x2
+#define IQM_CF_TAP_IM15__A                                                  0x186004F
+#define IQM_CF_TAP_IM15__W                                                  9
+#define IQM_CF_TAP_IM15__M                                                  0x1FF
+#define IQM_CF_TAP_IM15__PRE                                                0x2
+#define IQM_CF_TAP_IM16__A                                                  0x1860050
+#define IQM_CF_TAP_IM16__W                                                  9
+#define IQM_CF_TAP_IM16__M                                                  0x1FF
+#define IQM_CF_TAP_IM16__PRE                                                0x2
+#define IQM_CF_TAP_IM17__A                                                  0x1860051
+#define IQM_CF_TAP_IM17__W                                                  9
+#define IQM_CF_TAP_IM17__M                                                  0x1FF
+#define IQM_CF_TAP_IM17__PRE                                                0x2
+#define IQM_CF_TAP_IM18__A                                                  0x1860052
+#define IQM_CF_TAP_IM18__W                                                  9
+#define IQM_CF_TAP_IM18__M                                                  0x1FF
+#define IQM_CF_TAP_IM18__PRE                                                0x2
+#define IQM_CF_TAP_IM19__A                                                  0x1860053
+#define IQM_CF_TAP_IM19__W                                                  9
+#define IQM_CF_TAP_IM19__M                                                  0x1FF
+#define IQM_CF_TAP_IM19__PRE                                                0x2
+#define IQM_CF_TAP_IM20__A                                                  0x1860054
+#define IQM_CF_TAP_IM20__W                                                  9
+#define IQM_CF_TAP_IM20__M                                                  0x1FF
+#define IQM_CF_TAP_IM20__PRE                                                0x2
+#define IQM_CF_TAP_IM21__A                                                  0x1860055
+#define IQM_CF_TAP_IM21__W                                                  11
+#define IQM_CF_TAP_IM21__M                                                  0x7FF
+#define IQM_CF_TAP_IM21__PRE                                                0x2
+#define IQM_CF_TAP_IM22__A                                                  0x1860056
+#define IQM_CF_TAP_IM22__W                                                  11
+#define IQM_CF_TAP_IM22__M                                                  0x7FF
+#define IQM_CF_TAP_IM22__PRE                                                0x2
+#define IQM_CF_TAP_IM23__A                                                  0x1860057
+#define IQM_CF_TAP_IM23__W                                                  11
+#define IQM_CF_TAP_IM23__M                                                  0x7FF
+#define IQM_CF_TAP_IM23__PRE                                                0x2
+#define IQM_CF_TAP_IM24__A                                                  0x1860058
+#define IQM_CF_TAP_IM24__W                                                  11
+#define IQM_CF_TAP_IM24__M                                                  0x7FF
+#define IQM_CF_TAP_IM24__PRE                                                0x2
+#define IQM_CF_TAP_IM25__A                                                  0x1860059
+#define IQM_CF_TAP_IM25__W                                                  11
+#define IQM_CF_TAP_IM25__M                                                  0x7FF
+#define IQM_CF_TAP_IM25__PRE                                                0x2
+#define IQM_CF_TAP_IM26__A                                                  0x186005A
+#define IQM_CF_TAP_IM26__W                                                  11
+#define IQM_CF_TAP_IM26__M                                                  0x7FF
+#define IQM_CF_TAP_IM26__PRE                                                0x2
+#define IQM_CF_TAP_IM27__A                                                  0x186005B
+#define IQM_CF_TAP_IM27__W                                                  11
+#define IQM_CF_TAP_IM27__M                                                  0x7FF
+#define IQM_CF_TAP_IM27__PRE                                                0x2
+
+#define IQM_AF_COMM_EXEC__A                                                 0x1870000
+#define IQM_AF_COMM_EXEC__W                                                 2
+#define IQM_AF_COMM_EXEC__M                                                 0x3
+#define IQM_AF_COMM_EXEC__PRE                                               0x0
+#define   IQM_AF_COMM_EXEC_STOP                                             0x0
+#define   IQM_AF_COMM_EXEC_ACTIVE                                           0x1
+#define   IQM_AF_COMM_EXEC_HOLD                                             0x2
+
+#define IQM_AF_COMM_MB__A                                                   0x1870002
+#define IQM_AF_COMM_MB__W                                                   8
+#define IQM_AF_COMM_MB__M                                                   0xFF
+#define IQM_AF_COMM_MB__PRE                                                 0x0
+#define   IQM_AF_COMM_MB_CTL__B                                             0
+#define   IQM_AF_COMM_MB_CTL__W                                             1
+#define   IQM_AF_COMM_MB_CTL__M                                             0x1
+#define   IQM_AF_COMM_MB_CTL__PRE                                           0x0
+#define     IQM_AF_COMM_MB_CTL_CTL_OFF                                      0x0
+#define     IQM_AF_COMM_MB_CTL_CTL_ON                                       0x1
+#define   IQM_AF_COMM_MB_OBS__B                                             1
+#define   IQM_AF_COMM_MB_OBS__W                                             1
+#define   IQM_AF_COMM_MB_OBS__M                                             0x2
+#define   IQM_AF_COMM_MB_OBS__PRE                                           0x0
+#define     IQM_AF_COMM_MB_OBS_OBS_OFF                                      0x0
+#define     IQM_AF_COMM_MB_OBS_OBS_ON                                       0x2
+#define   IQM_AF_COMM_MB_MUX_CTRL__B                                        2
+#define   IQM_AF_COMM_MB_MUX_CTRL__W                                        3
+#define   IQM_AF_COMM_MB_MUX_CTRL__M                                        0x1C
+#define   IQM_AF_COMM_MB_MUX_CTRL__PRE                                      0x0
+#define     IQM_AF_COMM_MB_MUX_CTRL_AF_DATA_INPUT                           0x0
+#define     IQM_AF_COMM_MB_MUX_CTRL_SENSE_INPUT                             0x4
+#define     IQM_AF_COMM_MB_MUX_CTRL_AF_DATA_OUTPUT                          0x8
+#define     IQM_AF_COMM_MB_MUX_CTRL_IF_AGC_OUTPUT                           0xC
+#define     IQM_AF_COMM_MB_MUX_CTRL_RF_AGC_OUTPUT                           0x10
+#define   IQM_AF_COMM_MB_MUX_OBS__B                                         5
+#define   IQM_AF_COMM_MB_MUX_OBS__W                                         3
+#define   IQM_AF_COMM_MB_MUX_OBS__M                                         0xE0
+#define   IQM_AF_COMM_MB_MUX_OBS__PRE                                       0x0
+#define     IQM_AF_COMM_MB_MUX_OBS_AF_DATA_INPUT                            0x0
+#define     IQM_AF_COMM_MB_MUX_OBS_SENSE_INPUT                              0x20
+#define     IQM_AF_COMM_MB_MUX_OBS_AF_DATA_OUTPUT                           0x40
+#define     IQM_AF_COMM_MB_MUX_OBS_IF_AGC_OUTPUT                            0x60
+#define     IQM_AF_COMM_MB_MUX_OBS_RF_AGC_OUTPUT                            0x80
+
+#define IQM_AF_COMM_INT_REQ__A                                              0x1870003
+#define IQM_AF_COMM_INT_REQ__W                                              1
+#define IQM_AF_COMM_INT_REQ__M                                              0x1
+#define IQM_AF_COMM_INT_REQ__PRE                                            0x0
+#define IQM_AF_COMM_INT_STA__A                                              0x1870005
+#define IQM_AF_COMM_INT_STA__W                                              2
+#define IQM_AF_COMM_INT_STA__M                                              0x3
+#define IQM_AF_COMM_INT_STA__PRE                                            0x0
+#define   IQM_AF_COMM_INT_STA_CLP_INT_STA__B                                0
+#define   IQM_AF_COMM_INT_STA_CLP_INT_STA__W                                1
+#define   IQM_AF_COMM_INT_STA_CLP_INT_STA__M                                0x1
+#define   IQM_AF_COMM_INT_STA_CLP_INT_STA__PRE                              0x0
+#define   IQM_AF_COMM_INT_STA_SNS_INT_STA__B                                1
+#define   IQM_AF_COMM_INT_STA_SNS_INT_STA__W                                1
+#define   IQM_AF_COMM_INT_STA_SNS_INT_STA__M                                0x2
+#define   IQM_AF_COMM_INT_STA_SNS_INT_STA__PRE                              0x0
+
+#define IQM_AF_COMM_INT_MSK__A                                              0x1870006
+#define IQM_AF_COMM_INT_MSK__W                                              2
+#define IQM_AF_COMM_INT_MSK__M                                              0x3
+#define IQM_AF_COMM_INT_MSK__PRE                                            0x0
+#define   IQM_AF_COMM_INT_MSK_CLP_INT_MSK__B                                0
+#define   IQM_AF_COMM_INT_MSK_CLP_INT_MSK__W                                1
+#define   IQM_AF_COMM_INT_MSK_CLP_INT_MSK__M                                0x1
+#define   IQM_AF_COMM_INT_MSK_CLP_INT_MSK__PRE                              0x0
+#define   IQM_AF_COMM_INT_MSK_SNS_INT_MSK__B                                1
+#define   IQM_AF_COMM_INT_MSK_SNS_INT_MSK__W                                1
+#define   IQM_AF_COMM_INT_MSK_SNS_INT_MSK__M                                0x2
+#define   IQM_AF_COMM_INT_MSK_SNS_INT_MSK__PRE                              0x0
+
+#define IQM_AF_COMM_INT_STM__A                                              0x1870007
+#define IQM_AF_COMM_INT_STM__W                                              2
+#define IQM_AF_COMM_INT_STM__M                                              0x3
+#define IQM_AF_COMM_INT_STM__PRE                                            0x0
+#define   IQM_AF_COMM_INT_STM_CLP_INT_STA__B                                0
+#define   IQM_AF_COMM_INT_STM_CLP_INT_STA__W                                1
+#define   IQM_AF_COMM_INT_STM_CLP_INT_STA__M                                0x1
+#define   IQM_AF_COMM_INT_STM_CLP_INT_STA__PRE                              0x0
+#define   IQM_AF_COMM_INT_STM_SNS_INT_STA__B                                1
+#define   IQM_AF_COMM_INT_STM_SNS_INT_STA__W                                1
+#define   IQM_AF_COMM_INT_STM_SNS_INT_STA__M                                0x2
+#define   IQM_AF_COMM_INT_STM_SNS_INT_STA__PRE                              0x0
+
+#define IQM_AF_FDB_SEL__A                                                   0x1870010
+#define IQM_AF_FDB_SEL__W                                                   1
+#define IQM_AF_FDB_SEL__M                                                   0x1
+#define IQM_AF_FDB_SEL__PRE                                                 0x0
+
+#define IQM_AF_INVEXT__A                                                    0x1870011
+#define IQM_AF_INVEXT__W                                                    1
+#define IQM_AF_INVEXT__M                                                    0x1
+#define IQM_AF_INVEXT__PRE                                                  0x0
+#define IQM_AF_CLKNEG__A                                                    0x1870012
+#define IQM_AF_CLKNEG__W                                                    2
+#define IQM_AF_CLKNEG__M                                                    0x3
+#define IQM_AF_CLKNEG__PRE                                                  0x0
+
+#define   IQM_AF_CLKNEG_CLKNEGPEAK__B                                       0
+#define   IQM_AF_CLKNEG_CLKNEGPEAK__W                                       1
+#define   IQM_AF_CLKNEG_CLKNEGPEAK__M                                       0x1
+#define   IQM_AF_CLKNEG_CLKNEGPEAK__PRE                                     0x0
+#define     IQM_AF_CLKNEG_CLKNEGPEAK_CLK_ADC_PEAK_POS                       0x0
+#define     IQM_AF_CLKNEG_CLKNEGPEAK_CLK_ADC_PEAK_NEG                       0x1
+
+#define   IQM_AF_CLKNEG_CLKNEGDATA__B                                       1
+#define   IQM_AF_CLKNEG_CLKNEGDATA__W                                       1
+#define   IQM_AF_CLKNEG_CLKNEGDATA__M                                       0x2
+#define   IQM_AF_CLKNEG_CLKNEGDATA__PRE                                     0x0
+#define     IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS                       0x0
+#define     IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG                       0x2
+
+#define IQM_AF_MON_IN_MUX__A                                                0x1870013
+#define IQM_AF_MON_IN_MUX__W                                                2
+#define IQM_AF_MON_IN_MUX__M                                                0x3
+#define IQM_AF_MON_IN_MUX__PRE                                              0x0
+
+#define IQM_AF_MON_IN5__A                                                   0x1870014
+#define IQM_AF_MON_IN5__W                                                   10
+#define IQM_AF_MON_IN5__M                                                   0x3FF
+#define IQM_AF_MON_IN5__PRE                                                 0x0
+
+#define IQM_AF_MON_IN4__A                                                   0x1870015
+#define IQM_AF_MON_IN4__W                                                   10
+#define IQM_AF_MON_IN4__M                                                   0x3FF
+#define IQM_AF_MON_IN4__PRE                                                 0x0
+
+#define IQM_AF_MON_IN3__A                                                   0x1870016
+#define IQM_AF_MON_IN3__W                                                   10
+#define IQM_AF_MON_IN3__M                                                   0x3FF
+#define IQM_AF_MON_IN3__PRE                                                 0x0
+
+#define IQM_AF_MON_IN2__A                                                   0x1870017
+#define IQM_AF_MON_IN2__W                                                   10
+#define IQM_AF_MON_IN2__M                                                   0x3FF
+#define IQM_AF_MON_IN2__PRE                                                 0x0
+
+#define IQM_AF_MON_IN1__A                                                   0x1870018
+#define IQM_AF_MON_IN1__W                                                   10
+#define IQM_AF_MON_IN1__M                                                   0x3FF
+#define IQM_AF_MON_IN1__PRE                                                 0x0
+
+#define IQM_AF_MON_IN0__A                                                   0x1870019
+#define IQM_AF_MON_IN0__W                                                   10
+#define IQM_AF_MON_IN0__M                                                   0x3FF
+#define IQM_AF_MON_IN0__PRE                                                 0x0
+
+#define IQM_AF_MON_IN_VAL__A                                                0x187001A
+#define IQM_AF_MON_IN_VAL__W                                                1
+#define IQM_AF_MON_IN_VAL__M                                                0x1
+#define IQM_AF_MON_IN_VAL__PRE                                              0x0
+
+#define IQM_AF_START_LOCK__A                                                0x187001B
+#define IQM_AF_START_LOCK__W                                                1
+#define IQM_AF_START_LOCK__M                                                0x1
+#define IQM_AF_START_LOCK__PRE                                              0x0
+
+#define IQM_AF_PHASE0__A                                                    0x187001C
+#define IQM_AF_PHASE0__W                                                    7
+#define IQM_AF_PHASE0__M                                                    0x7F
+#define IQM_AF_PHASE0__PRE                                                  0x0
+
+#define IQM_AF_PHASE1__A                                                    0x187001D
+#define IQM_AF_PHASE1__W                                                    7
+#define IQM_AF_PHASE1__M                                                    0x7F
+#define IQM_AF_PHASE1__PRE                                                  0x0
+
+#define IQM_AF_PHASE2__A                                                    0x187001E
+#define IQM_AF_PHASE2__W                                                    7
+#define IQM_AF_PHASE2__M                                                    0x7F
+#define IQM_AF_PHASE2__PRE                                                  0x0
+
+#define IQM_AF_SCU_PHASE__A                                                 0x187001F
+#define IQM_AF_SCU_PHASE__W                                                 2
+#define IQM_AF_SCU_PHASE__M                                                 0x3
+#define IQM_AF_SCU_PHASE__PRE                                               0x0
+
+#define IQM_AF_SYNC_SEL__A                                                  0x1870020
+#define IQM_AF_SYNC_SEL__W                                                  2
+#define IQM_AF_SYNC_SEL__M                                                  0x3
+#define IQM_AF_SYNC_SEL__PRE                                                0x0
+#define IQM_AF_ADC_CONF__A                                                  0x1870021
+#define IQM_AF_ADC_CONF__W                                                  4
+#define IQM_AF_ADC_CONF__M                                                  0xF
+#define IQM_AF_ADC_CONF__PRE                                                0x0
+
+#define   IQM_AF_ADC_CONF_ADC_SIGN__B                                       0
+#define   IQM_AF_ADC_CONF_ADC_SIGN__W                                       1
+#define   IQM_AF_ADC_CONF_ADC_SIGN__M                                       0x1
+#define   IQM_AF_ADC_CONF_ADC_SIGN__PRE                                     0x0
+#define     IQM_AF_ADC_CONF_ADC_SIGN_ADC_SIGNED                             0x0
+#define     IQM_AF_ADC_CONF_ADC_SIGN_ADC_UNSIGNED                           0x1
+
+#define   IQM_AF_ADC_CONF_BITREVERSE_ADC__B                                 1
+#define   IQM_AF_ADC_CONF_BITREVERSE_ADC__W                                 1
+#define   IQM_AF_ADC_CONF_BITREVERSE_ADC__M                                 0x2
+#define   IQM_AF_ADC_CONF_BITREVERSE_ADC__PRE                               0x0
+#define     IQM_AF_ADC_CONF_BITREVERSE_ADC_ADC_NORMAL                       0x0
+#define     IQM_AF_ADC_CONF_BITREVERSE_ADC_ADC_BITREVERSED                  0x2
+
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSI__B                                2
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSI__W                                1
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSI__M                                0x4
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSI__PRE                              0x0
+#define     IQM_AF_ADC_CONF_BITREVERSE_NSSI_IFAGC_DAC_NORMAL                0x0
+#define     IQM_AF_ADC_CONF_BITREVERSE_NSSI_IFAGC_DAC_BITREVERSED           0x4
+
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSR__B                                3
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSR__W                                1
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSR__M                                0x8
+#define   IQM_AF_ADC_CONF_BITREVERSE_NSSR__PRE                              0x0
+#define     IQM_AF_ADC_CONF_BITREVERSE_NSSR_RFAGC_DAC_NORMAL                0x0
+#define     IQM_AF_ADC_CONF_BITREVERSE_NSSR_RFAGC_DAC_BITREVERSED           0x8
+
+#define IQM_AF_CLP_CLIP__A                                                  0x1870022
+#define IQM_AF_CLP_CLIP__W                                                  16
+#define IQM_AF_CLP_CLIP__M                                                  0xFFFF
+#define IQM_AF_CLP_CLIP__PRE                                                0x0
+
+#define IQM_AF_CLP_LEN__A                                                   0x1870023
+#define IQM_AF_CLP_LEN__W                                                   16
+#define IQM_AF_CLP_LEN__M                                                   0xFFFF
+#define IQM_AF_CLP_LEN__PRE                                                 0x0
+#define   IQM_AF_CLP_LEN_QAM_B_64                                           0x400
+#define   IQM_AF_CLP_LEN_QAM_B_256                                          0x400
+#define   IQM_AF_CLP_LEN_ATV                                                0x0
+
+#define IQM_AF_CLP_TH__A                                                    0x1870024
+#define IQM_AF_CLP_TH__W                                                    9
+#define IQM_AF_CLP_TH__M                                                    0x1FF
+#define IQM_AF_CLP_TH__PRE                                                  0x0
+#define   IQM_AF_CLP_TH_QAM_B_64                                            0x80
+#define   IQM_AF_CLP_TH_QAM_B_256                                           0x80
+#define   IQM_AF_CLP_TH_ATV                                                 0x1C0
+
+#define IQM_AF_DCF_BYPASS__A                                                0x1870025
+#define IQM_AF_DCF_BYPASS__W                                                1
+#define IQM_AF_DCF_BYPASS__M                                                0x1
+#define IQM_AF_DCF_BYPASS__PRE                                              0x0
+#define   IQM_AF_DCF_BYPASS_ACTIVE                                          0x0
+#define   IQM_AF_DCF_BYPASS_BYPASS                                          0x1
+
+#define IQM_AF_SNS_LEN__A                                                   0x1870026
+#define IQM_AF_SNS_LEN__W                                                   16
+#define IQM_AF_SNS_LEN__M                                                   0xFFFF
+#define IQM_AF_SNS_LEN__PRE                                                 0x0
+#define   IQM_AF_SNS_LEN_QAM_B_64                                           0x400
+#define   IQM_AF_SNS_LEN_QAM_B_256                                          0x400
+#define   IQM_AF_SNS_LEN_ATV                                                0x0
+
+#define IQM_AF_SNS_SENSE__A                                                 0x1870027
+#define IQM_AF_SNS_SENSE__W                                                 16
+#define IQM_AF_SNS_SENSE__M                                                 0xFFFF
+#define IQM_AF_SNS_SENSE__PRE                                               0x0
+
+#define IQM_AF_AGC_IF__A                                                    0x1870028
+#define IQM_AF_AGC_IF__W                                                    15
+#define IQM_AF_AGC_IF__M                                                    0x7FFF
+#define IQM_AF_AGC_IF__PRE                                                  0x0
+
+#define IQM_AF_AGC_RF__A                                                    0x1870029
+#define IQM_AF_AGC_RF__W                                                    15
+#define IQM_AF_AGC_RF__M                                                    0x7FFF
+#define IQM_AF_AGC_RF__PRE                                                  0x0
+
+#define IQM_AF_PGA_GAIN__A                                                  0x187002A
+#define IQM_AF_PGA_GAIN__W                                                  4
+#define IQM_AF_PGA_GAIN__M                                                  0xF
+#define IQM_AF_PGA_GAIN__PRE                                                0x0
+
+#define IQM_AF_PDREF__A                                                     0x187002B
+#define IQM_AF_PDREF__W                                                     5
+#define IQM_AF_PDREF__M                                                     0x1F
+#define IQM_AF_PDREF__PRE                                                   0x0
+#define   IQM_AF_PDREF_QAM_B_64                                             0xF
+#define   IQM_AF_PDREF_QAM_B_256                                            0xF
+#define   IQM_AF_PDREF_ATV                                                  0xF
+
+#define IQM_AF_STDBY__A                                                     0x187002C
+#define IQM_AF_STDBY__W                                                     6
+#define IQM_AF_STDBY__M                                                     0x3F
+#define IQM_AF_STDBY__PRE                                                   0x0
+
+#define   IQM_AF_STDBY_STDBY_BIAS__B                                        0
+#define   IQM_AF_STDBY_STDBY_BIAS__W                                        1
+#define   IQM_AF_STDBY_STDBY_BIAS__M                                        0x1
+#define   IQM_AF_STDBY_STDBY_BIAS__PRE                                      0x0
+#define     IQM_AF_STDBY_STDBY_BIAS_ACTIVE                                  0x0
+#define     IQM_AF_STDBY_STDBY_BIAS_STANDBY                                 0x1
+
+#define   IQM_AF_STDBY_STDBY_ADC__B                                         1
+#define   IQM_AF_STDBY_STDBY_ADC__W                                         1
+#define   IQM_AF_STDBY_STDBY_ADC__M                                         0x2
+#define   IQM_AF_STDBY_STDBY_ADC__PRE                                       0x0
+#define     IQM_AF_STDBY_STDBY_ADC_A1_ACTIVE                                0x0
+#define     IQM_AF_STDBY_STDBY_ADC_A1_STANDBY                               0x2
+#define     IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE                                0x2
+#define     IQM_AF_STDBY_STDBY_ADC_A2_STANDBY                               0x0
+
+#define   IQM_AF_STDBY_STDBY_AMP__B                                         2
+#define   IQM_AF_STDBY_STDBY_AMP__W                                         1
+#define   IQM_AF_STDBY_STDBY_AMP__M                                         0x4
+#define   IQM_AF_STDBY_STDBY_AMP__PRE                                       0x0
+#define     IQM_AF_STDBY_STDBY_AMP_A1_ACTIVE                                0x0
+#define     IQM_AF_STDBY_STDBY_AMP_A1_STANDBY                               0x4
+#define     IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE                                0x4
+#define     IQM_AF_STDBY_STDBY_AMP_A2_STANDBY                               0x0
+
+#define   IQM_AF_STDBY_STDBY_PD__B                                          3
+#define   IQM_AF_STDBY_STDBY_PD__W                                          1
+#define   IQM_AF_STDBY_STDBY_PD__M                                          0x8
+#define   IQM_AF_STDBY_STDBY_PD__PRE                                        0x0
+#define     IQM_AF_STDBY_STDBY_PD_A1_ACTIVE                                 0x0
+#define     IQM_AF_STDBY_STDBY_PD_A1_STANDBY                                0x8
+#define     IQM_AF_STDBY_STDBY_PD_A2_ACTIVE                                 0x8
+#define     IQM_AF_STDBY_STDBY_PD_A2_STANDBY                                0x0
+
+#define   IQM_AF_STDBY_STDBY_TAGC_IF__B                                     4
+#define   IQM_AF_STDBY_STDBY_TAGC_IF__W                                     1
+#define   IQM_AF_STDBY_STDBY_TAGC_IF__M                                     0x10
+#define   IQM_AF_STDBY_STDBY_TAGC_IF__PRE                                   0x0
+#define     IQM_AF_STDBY_STDBY_TAGC_IF_A1_ACTIVE                            0x0
+#define     IQM_AF_STDBY_STDBY_TAGC_IF_A1_STANDBY                           0x10
+#define     IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE                            0x10
+#define     IQM_AF_STDBY_STDBY_TAGC_IF_A2_STANDBY                           0x0
+
+#define   IQM_AF_STDBY_STDBY_TAGC_RF__B                                     5
+#define   IQM_AF_STDBY_STDBY_TAGC_RF__W                                     1
+#define   IQM_AF_STDBY_STDBY_TAGC_RF__M                                     0x20
+#define   IQM_AF_STDBY_STDBY_TAGC_RF__PRE                                   0x0
+#define     IQM_AF_STDBY_STDBY_TAGC_RF_A1_ACTIVE                            0x0
+#define     IQM_AF_STDBY_STDBY_TAGC_RF_A1_STANDBY                           0x20
+#define     IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE                            0x20
+#define     IQM_AF_STDBY_STDBY_TAGC_RF_A2_STANDBY                           0x0
+
+#define IQM_AF_AMUX__A                                                      0x187002D
+#define IQM_AF_AMUX__W                                                      2
+#define IQM_AF_AMUX__M                                                      0x3
+#define IQM_AF_AMUX__PRE                                                    0x0
+
+#define IQM_AF_TST_AFEMAIN__A                                               0x187002E
+#define IQM_AF_TST_AFEMAIN__W                                               8
+#define IQM_AF_TST_AFEMAIN__M                                               0xFF
+#define IQM_AF_TST_AFEMAIN__PRE                                             0x0
+
+#define IQM_RT_RAM__A                                                       0x1880000
+
+#define   IQM_RT_RAM_DLY__B                                                 0
+#define   IQM_RT_RAM_DLY__W                                                 13
+#define   IQM_RT_RAM_DLY__M                                                 0x1FFF
+#define   IQM_RT_RAM_DLY__PRE                                               0x0
+
+#define ORX_COMM_EXEC__A                                                    0x2000000
+#define ORX_COMM_EXEC__W                                                    2
+#define ORX_COMM_EXEC__M                                                    0x3
+#define ORX_COMM_EXEC__PRE                                                  0x0
+#define   ORX_COMM_EXEC_STOP                                                0x0
+#define   ORX_COMM_EXEC_ACTIVE                                              0x1
+#define   ORX_COMM_EXEC_HOLD                                                0x2
+
+#define ORX_COMM_STATE__A                                                   0x2000001
+#define ORX_COMM_STATE__W                                                   16
+#define ORX_COMM_STATE__M                                                   0xFFFF
+#define ORX_COMM_STATE__PRE                                                 0x0
+#define ORX_COMM_MB__A                                                      0x2000002
+#define ORX_COMM_MB__W                                                      16
+#define ORX_COMM_MB__M                                                      0xFFFF
+#define ORX_COMM_MB__PRE                                                    0x0
+#define ORX_COMM_INT_REQ__A                                                 0x2000003
+#define ORX_COMM_INT_REQ__W                                                 16
+#define ORX_COMM_INT_REQ__M                                                 0xFFFF
+#define ORX_COMM_INT_REQ__PRE                                               0x0
+#define   ORX_COMM_INT_REQ_EQU_REQ__B                                       0
+#define   ORX_COMM_INT_REQ_EQU_REQ__W                                       1
+#define   ORX_COMM_INT_REQ_EQU_REQ__M                                       0x1
+#define   ORX_COMM_INT_REQ_EQU_REQ__PRE                                     0x0
+#define   ORX_COMM_INT_REQ_DDC_REQ__B                                       1
+#define   ORX_COMM_INT_REQ_DDC_REQ__W                                       1
+#define   ORX_COMM_INT_REQ_DDC_REQ__M                                       0x2
+#define   ORX_COMM_INT_REQ_DDC_REQ__PRE                                     0x0
+#define   ORX_COMM_INT_REQ_FWP_REQ__B                                       2
+#define   ORX_COMM_INT_REQ_FWP_REQ__W                                       1
+#define   ORX_COMM_INT_REQ_FWP_REQ__M                                       0x4
+#define   ORX_COMM_INT_REQ_FWP_REQ__PRE                                     0x0
+#define   ORX_COMM_INT_REQ_CON_REQ__B                                       3
+#define   ORX_COMM_INT_REQ_CON_REQ__W                                       1
+#define   ORX_COMM_INT_REQ_CON_REQ__M                                       0x8
+#define   ORX_COMM_INT_REQ_CON_REQ__PRE                                     0x0
+#define   ORX_COMM_INT_REQ_NSU_REQ__B                                       4
+#define   ORX_COMM_INT_REQ_NSU_REQ__W                                       1
+#define   ORX_COMM_INT_REQ_NSU_REQ__M                                       0x10
+#define   ORX_COMM_INT_REQ_NSU_REQ__PRE                                     0x0
+
+#define ORX_COMM_INT_STA__A                                                 0x2000005
+#define ORX_COMM_INT_STA__W                                                 16
+#define ORX_COMM_INT_STA__M                                                 0xFFFF
+#define ORX_COMM_INT_STA__PRE                                               0x0
+#define ORX_COMM_INT_MSK__A                                                 0x2000006
+#define ORX_COMM_INT_MSK__W                                                 16
+#define ORX_COMM_INT_MSK__M                                                 0xFFFF
+#define ORX_COMM_INT_MSK__PRE                                               0x0
+#define ORX_COMM_INT_STM__A                                                 0x2000007
+#define ORX_COMM_INT_STM__W                                                 16
+#define ORX_COMM_INT_STM__M                                                 0xFFFF
+#define ORX_COMM_INT_STM__PRE                                               0x0
+
+#define ORX_TOP_COMM_EXEC__A                                                0x2010000
+#define ORX_TOP_COMM_EXEC__W                                                2
+#define ORX_TOP_COMM_EXEC__M                                                0x3
+#define ORX_TOP_COMM_EXEC__PRE                                              0x0
+#define   ORX_TOP_COMM_EXEC_STOP                                            0x0
+#define   ORX_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_TOP_COMM_KEY__A                                                 0x201000F
+#define ORX_TOP_COMM_KEY__W                                                 16
+#define ORX_TOP_COMM_KEY__M                                                 0xFFFF
+#define ORX_TOP_COMM_KEY__PRE                                               0x0
+#define   ORX_TOP_COMM_KEY_KEY                                              0xFABA
+
+#define ORX_TOP_MDE_W__A                                                    0x2010010
+#define ORX_TOP_MDE_W__W                                                    2
+#define ORX_TOP_MDE_W__M                                                    0x3
+#define ORX_TOP_MDE_W__PRE                                                  0x2
+#define   ORX_TOP_MDE_W_RATE_1544KBPS                                       0x0
+#define   ORX_TOP_MDE_W_RATE_3088KBPS                                       0x1
+#define   ORX_TOP_MDE_W_RATE_2048KBPS_SQRT                                  0x2
+#define   ORX_TOP_MDE_W_RATE_2048KBPS_RO                                    0x3
+
+#define ORX_TOP_AIF_CTRL_W__A                                               0x2010011
+#define ORX_TOP_AIF_CTRL_W__W                                               3
+#define ORX_TOP_AIF_CTRL_W__M                                               0x7
+#define ORX_TOP_AIF_CTRL_W__PRE                                             0x0
+#define   ORX_TOP_AIF_CTRL_W_NEG_CLK_EDGE__B                                0
+#define   ORX_TOP_AIF_CTRL_W_NEG_CLK_EDGE__W                                1
+#define   ORX_TOP_AIF_CTRL_W_NEG_CLK_EDGE__M                                0x1
+#define   ORX_TOP_AIF_CTRL_W_NEG_CLK_EDGE__PRE                              0x0
+#define     ORX_TOP_AIF_CTRL_W_NEG_CLK_EDGE_ADC_SAMPL_ON_POS_CLK_EDGE       0x0
+#define     ORX_TOP_AIF_CTRL_W_NEG_CLK_EDGE_ADC_SAMPL_ON_NEG_CLK_EDGE       0x1
+#define   ORX_TOP_AIF_CTRL_W_BIT_REVERSE__B                                 1
+#define   ORX_TOP_AIF_CTRL_W_BIT_REVERSE__W                                 1
+#define   ORX_TOP_AIF_CTRL_W_BIT_REVERSE__M                                 0x2
+#define   ORX_TOP_AIF_CTRL_W_BIT_REVERSE__PRE                               0x0
+#define     ORX_TOP_AIF_CTRL_W_BIT_REVERSE_REGULAR_BIT_ORDER_ADC            0x0
+#define     ORX_TOP_AIF_CTRL_W_BIT_REVERSE_REVERSAL_BIT_ORDER_ADC           0x2
+#define   ORX_TOP_AIF_CTRL_W_INV_MSB__B                                     2
+#define   ORX_TOP_AIF_CTRL_W_INV_MSB__W                                     1
+#define   ORX_TOP_AIF_CTRL_W_INV_MSB__M                                     0x4
+#define   ORX_TOP_AIF_CTRL_W_INV_MSB__PRE                                   0x0
+#define     ORX_TOP_AIF_CTRL_W_INV_MSB_NO_MSB_INVERSION_ADC                 0x0
+#define     ORX_TOP_AIF_CTRL_W_INV_MSB_MSB_INVERSION_ADC                    0x4
+
+#define ORX_FWP_COMM_EXEC__A                                                0x2020000
+#define ORX_FWP_COMM_EXEC__W                                                2
+#define ORX_FWP_COMM_EXEC__M                                                0x3
+#define ORX_FWP_COMM_EXEC__PRE                                              0x0
+#define   ORX_FWP_COMM_EXEC_STOP                                            0x0
+#define   ORX_FWP_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_FWP_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_FWP_COMM_MB__A                                                  0x2020002
+#define ORX_FWP_COMM_MB__W                                                  8
+#define ORX_FWP_COMM_MB__M                                                  0xFF
+#define ORX_FWP_COMM_MB__PRE                                                0x0
+#define   ORX_FWP_COMM_MB_CTL__B                                            0
+#define   ORX_FWP_COMM_MB_CTL__W                                            1
+#define   ORX_FWP_COMM_MB_CTL__M                                            0x1
+#define   ORX_FWP_COMM_MB_CTL__PRE                                          0x0
+#define     ORX_FWP_COMM_MB_CTL_OFF                                         0x0
+#define     ORX_FWP_COMM_MB_CTL_ON                                          0x1
+#define   ORX_FWP_COMM_MB_OBS__B                                            1
+#define   ORX_FWP_COMM_MB_OBS__W                                            1
+#define   ORX_FWP_COMM_MB_OBS__M                                            0x2
+#define   ORX_FWP_COMM_MB_OBS__PRE                                          0x0
+#define     ORX_FWP_COMM_MB_OBS_OFF                                         0x0
+#define     ORX_FWP_COMM_MB_OBS_ON                                          0x2
+
+#define   ORX_FWP_COMM_MB_CTL_MUX__B                                        2
+#define   ORX_FWP_COMM_MB_CTL_MUX__W                                        3
+#define   ORX_FWP_COMM_MB_CTL_MUX__M                                        0x1C
+#define   ORX_FWP_COMM_MB_CTL_MUX__PRE                                      0x0
+
+#define   ORX_FWP_COMM_MB_OBS_MUX__B                                        5
+#define   ORX_FWP_COMM_MB_OBS_MUX__W                                        3
+#define   ORX_FWP_COMM_MB_OBS_MUX__M                                        0xE0
+#define   ORX_FWP_COMM_MB_OBS_MUX__PRE                                      0x0
+
+#define ORX_FWP_AAG_LEN_W__A                                                0x2020010
+#define ORX_FWP_AAG_LEN_W__W                                                16
+#define ORX_FWP_AAG_LEN_W__M                                                0xFFFF
+#define ORX_FWP_AAG_LEN_W__PRE                                              0x800
+
+#define ORX_FWP_AAG_THR_W__A                                                0x2020011
+#define ORX_FWP_AAG_THR_W__W                                                8
+#define ORX_FWP_AAG_THR_W__M                                                0xFF
+#define ORX_FWP_AAG_THR_W__PRE                                              0x50
+
+#define ORX_FWP_AAG_THR_CNT_R__A                                            0x2020012
+#define ORX_FWP_AAG_THR_CNT_R__W                                            16
+#define ORX_FWP_AAG_THR_CNT_R__M                                            0xFFFF
+#define ORX_FWP_AAG_THR_CNT_R__PRE                                          0x0
+
+#define ORX_FWP_AAG_SNS_CNT_R__A                                            0x2020013
+#define ORX_FWP_AAG_SNS_CNT_R__W                                            16
+#define ORX_FWP_AAG_SNS_CNT_R__M                                            0xFFFF
+#define ORX_FWP_AAG_SNS_CNT_R__PRE                                          0x0
+
+#define ORX_FWP_PFI_A_W__A                                                  0x2020014
+#define ORX_FWP_PFI_A_W__W                                                  8
+#define ORX_FWP_PFI_A_W__M                                                  0xFF
+#define ORX_FWP_PFI_A_W__PRE                                                0xB0
+#define   ORX_FWP_PFI_A_W_RATE_2048KBPS                                     0xB0
+#define   ORX_FWP_PFI_A_W_RATE_1544KBPS                                     0xA4
+#define   ORX_FWP_PFI_A_W_RATE_3088KBPS                                     0xC0
+
+#define ORX_FWP_PFI_B_W__A                                                  0x2020015
+#define ORX_FWP_PFI_B_W__W                                                  8
+#define ORX_FWP_PFI_B_W__M                                                  0xFF
+#define ORX_FWP_PFI_B_W__PRE                                                0x9E
+#define   ORX_FWP_PFI_B_W_RATE_2048KBPS                                     0x9E
+#define   ORX_FWP_PFI_B_W_RATE_1544KBPS                                     0x94
+#define   ORX_FWP_PFI_B_W_RATE_3088KBPS                                     0xB0
+
+#define ORX_FWP_PFI_C_W__A                                                  0x2020016
+#define ORX_FWP_PFI_C_W__W                                                  8
+#define ORX_FWP_PFI_C_W__M                                                  0xFF
+#define ORX_FWP_PFI_C_W__PRE                                                0x5C
+#define   ORX_FWP_PFI_C_W_RATE_2048KBPS                                     0x5C
+#define   ORX_FWP_PFI_C_W_RATE_1544KBPS                                     0x64
+#define   ORX_FWP_PFI_C_W_RATE_3088KBPS                                     0x50
+
+#define ORX_FWP_KR1_AMP_R__A                                                0x2020017
+#define ORX_FWP_KR1_AMP_R__W                                                9
+#define ORX_FWP_KR1_AMP_R__M                                                0x1FF
+#define ORX_FWP_KR1_AMP_R__PRE                                              0x0
+
+#define ORX_FWP_KR1_LDT_W__A                                                0x2020018
+#define ORX_FWP_KR1_LDT_W__W                                                3
+#define ORX_FWP_KR1_LDT_W__M                                                0x7
+#define ORX_FWP_KR1_LDT_W__PRE                                              0x2
+#define ORX_FWP_SRC_DGN_W__A                                                0x2020019
+#define ORX_FWP_SRC_DGN_W__W                                                16
+#define ORX_FWP_SRC_DGN_W__M                                                0xFFFF
+#define ORX_FWP_SRC_DGN_W__PRE                                              0x1FF
+
+#define   ORX_FWP_SRC_DGN_W_MANT__B                                         0
+#define   ORX_FWP_SRC_DGN_W_MANT__W                                         9
+#define   ORX_FWP_SRC_DGN_W_MANT__M                                         0x1FF
+#define   ORX_FWP_SRC_DGN_W_MANT__PRE                                       0x1FF
+
+#define   ORX_FWP_SRC_DGN_W_EXP__B                                          12
+#define   ORX_FWP_SRC_DGN_W_EXP__W                                          4
+#define   ORX_FWP_SRC_DGN_W_EXP__M                                          0xF000
+#define   ORX_FWP_SRC_DGN_W_EXP__PRE                                        0x0
+
+#define ORX_FWP_NYQ_ADR_W__A                                                0x202001A
+#define ORX_FWP_NYQ_ADR_W__W                                                5
+#define ORX_FWP_NYQ_ADR_W__M                                                0x1F
+#define ORX_FWP_NYQ_ADR_W__PRE                                              0x1F
+
+#define ORX_FWP_NYQ_COF_RW__A                                               0x202001B
+#define ORX_FWP_NYQ_COF_RW__W                                               10
+#define ORX_FWP_NYQ_COF_RW__M                                               0x3FF
+#define ORX_FWP_NYQ_COF_RW__PRE                                             0x0
+
+#define ORX_FWP_IQM_FRQ_W__A                                                0x202001C
+#define ORX_FWP_IQM_FRQ_W__W                                                16
+#define ORX_FWP_IQM_FRQ_W__M                                                0xFFFF
+#define ORX_FWP_IQM_FRQ_W__PRE                                              0x4301
+
+#define ORX_EQU_COMM_EXEC__A                                                0x2030000
+#define ORX_EQU_COMM_EXEC__W                                                2
+#define ORX_EQU_COMM_EXEC__M                                                0x3
+#define ORX_EQU_COMM_EXEC__PRE                                              0x0
+#define   ORX_EQU_COMM_EXEC_STOP                                            0x0
+#define   ORX_EQU_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_EQU_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_EQU_COMM_MB__A                                                  0x2030002
+#define ORX_EQU_COMM_MB__W                                                  8
+#define ORX_EQU_COMM_MB__M                                                  0xFF
+#define ORX_EQU_COMM_MB__PRE                                                0x0
+#define   ORX_EQU_COMM_MB_CTL__B                                            0
+#define   ORX_EQU_COMM_MB_CTL__W                                            1
+#define   ORX_EQU_COMM_MB_CTL__M                                            0x1
+#define   ORX_EQU_COMM_MB_CTL__PRE                                          0x0
+#define     ORX_EQU_COMM_MB_CTL_OFF                                         0x0
+#define     ORX_EQU_COMM_MB_CTL_ON                                          0x1
+#define   ORX_EQU_COMM_MB_OBS__B                                            1
+#define   ORX_EQU_COMM_MB_OBS__W                                            1
+#define   ORX_EQU_COMM_MB_OBS__M                                            0x2
+#define   ORX_EQU_COMM_MB_OBS__PRE                                          0x0
+#define     ORX_EQU_COMM_MB_OBS_OFF                                         0x0
+#define     ORX_EQU_COMM_MB_OBS_ON                                          0x2
+
+#define   ORX_EQU_COMM_MB_CTL_MUX__B                                        2
+#define   ORX_EQU_COMM_MB_CTL_MUX__W                                        3
+#define   ORX_EQU_COMM_MB_CTL_MUX__M                                        0x1C
+#define   ORX_EQU_COMM_MB_CTL_MUX__PRE                                      0x0
+
+#define   ORX_EQU_COMM_MB_OBS_MUX__B                                        5
+#define   ORX_EQU_COMM_MB_OBS_MUX__W                                        3
+#define   ORX_EQU_COMM_MB_OBS_MUX__M                                        0xE0
+#define   ORX_EQU_COMM_MB_OBS_MUX__PRE                                      0x0
+
+#define ORX_EQU_COMM_INT_REQ__A                                             0x2030003
+#define ORX_EQU_COMM_INT_REQ__W                                             1
+#define ORX_EQU_COMM_INT_REQ__M                                             0x1
+#define ORX_EQU_COMM_INT_REQ__PRE                                           0x0
+#define ORX_EQU_COMM_INT_STA__A                                             0x2030005
+#define ORX_EQU_COMM_INT_STA__W                                             2
+#define ORX_EQU_COMM_INT_STA__M                                             0x3
+#define ORX_EQU_COMM_INT_STA__PRE                                           0x0
+
+#define   ORX_EQU_COMM_INT_STA_FFF_READ__B                                  0
+#define   ORX_EQU_COMM_INT_STA_FFF_READ__W                                  1
+#define   ORX_EQU_COMM_INT_STA_FFF_READ__M                                  0x1
+#define   ORX_EQU_COMM_INT_STA_FFF_READ__PRE                                0x0
+
+#define   ORX_EQU_COMM_INT_STA_FBF_READ__B                                  1
+#define   ORX_EQU_COMM_INT_STA_FBF_READ__W                                  1
+#define   ORX_EQU_COMM_INT_STA_FBF_READ__M                                  0x2
+#define   ORX_EQU_COMM_INT_STA_FBF_READ__PRE                                0x0
+
+#define ORX_EQU_COMM_INT_MSK__A                                             0x2030006
+#define ORX_EQU_COMM_INT_MSK__W                                             2
+#define ORX_EQU_COMM_INT_MSK__M                                             0x3
+#define ORX_EQU_COMM_INT_MSK__PRE                                           0x0
+#define   ORX_EQU_COMM_INT_MSK_FFF_READ__B                                  0
+#define   ORX_EQU_COMM_INT_MSK_FFF_READ__W                                  1
+#define   ORX_EQU_COMM_INT_MSK_FFF_READ__M                                  0x1
+#define   ORX_EQU_COMM_INT_MSK_FFF_READ__PRE                                0x0
+#define   ORX_EQU_COMM_INT_MSK_FBF_READ__B                                  1
+#define   ORX_EQU_COMM_INT_MSK_FBF_READ__W                                  1
+#define   ORX_EQU_COMM_INT_MSK_FBF_READ__M                                  0x2
+#define   ORX_EQU_COMM_INT_MSK_FBF_READ__PRE                                0x0
+
+#define ORX_EQU_COMM_INT_STM__A                                             0x2030007
+#define ORX_EQU_COMM_INT_STM__W                                             2
+#define ORX_EQU_COMM_INT_STM__M                                             0x3
+#define ORX_EQU_COMM_INT_STM__PRE                                           0x0
+#define   ORX_EQU_COMM_INT_STM_FFF_READ__B                                  0
+#define   ORX_EQU_COMM_INT_STM_FFF_READ__W                                  1
+#define   ORX_EQU_COMM_INT_STM_FFF_READ__M                                  0x1
+#define   ORX_EQU_COMM_INT_STM_FFF_READ__PRE                                0x0
+#define   ORX_EQU_COMM_INT_STM_FBF_READ__B                                  1
+#define   ORX_EQU_COMM_INT_STM_FBF_READ__W                                  1
+#define   ORX_EQU_COMM_INT_STM_FBF_READ__M                                  0x2
+#define   ORX_EQU_COMM_INT_STM_FBF_READ__PRE                                0x0
+
+#define ORX_EQU_FFF_SCL_W__A                                                0x2030010
+#define ORX_EQU_FFF_SCL_W__W                                                1
+#define ORX_EQU_FFF_SCL_W__M                                                0x1
+#define ORX_EQU_FFF_SCL_W__PRE                                              0x0
+#define   ORX_EQU_FFF_SCL_W_SCALE_GAIN_1                                    0x0
+#define   ORX_EQU_FFF_SCL_W_SCALE_GAIN_2                                    0x1
+
+#define ORX_EQU_FFF_UPD_W__A                                                0x2030011
+#define ORX_EQU_FFF_UPD_W__W                                                1
+#define ORX_EQU_FFF_UPD_W__M                                                0x1
+#define ORX_EQU_FFF_UPD_W__PRE                                              0x0
+#define   ORX_EQU_FFF_UPD_W_NO_UPDATE                                       0x0
+#define   ORX_EQU_FFF_UPD_W_LMS_UPDATE                                      0x1
+
+#define ORX_EQU_FFF_STP_W__A                                                0x2030012
+#define ORX_EQU_FFF_STP_W__W                                                3
+#define ORX_EQU_FFF_STP_W__M                                                0x7
+#define ORX_EQU_FFF_STP_W__PRE                                              0x2
+
+#define ORX_EQU_FFF_LEA_W__A                                                0x2030013
+#define ORX_EQU_FFF_LEA_W__W                                                4
+#define ORX_EQU_FFF_LEA_W__M                                                0xF
+#define ORX_EQU_FFF_LEA_W__PRE                                              0x4
+
+#define ORX_EQU_FFF_RWT_W__A                                                0x2030014
+#define ORX_EQU_FFF_RWT_W__W                                                2
+#define ORX_EQU_FFF_RWT_W__M                                                0x3
+#define ORX_EQU_FFF_RWT_W__PRE                                              0x0
+
+#define ORX_EQU_FFF_C0RE_RW__A                                              0x2030015
+#define ORX_EQU_FFF_C0RE_RW__W                                              12
+#define ORX_EQU_FFF_C0RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C0RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C0IM_RW__A                                              0x2030016
+#define ORX_EQU_FFF_C0IM_RW__W                                              12
+#define ORX_EQU_FFF_C0IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C0IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C1RE_RW__A                                              0x2030017
+#define ORX_EQU_FFF_C1RE_RW__W                                              12
+#define ORX_EQU_FFF_C1RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C1RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C1IM_RW__A                                              0x2030018
+#define ORX_EQU_FFF_C1IM_RW__W                                              12
+#define ORX_EQU_FFF_C1IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C1IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C2RE_RW__A                                              0x2030019
+#define ORX_EQU_FFF_C2RE_RW__W                                              12
+#define ORX_EQU_FFF_C2RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C2RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C2IM_RW__A                                              0x203001A
+#define ORX_EQU_FFF_C2IM_RW__W                                              12
+#define ORX_EQU_FFF_C2IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C2IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C3RE_RW__A                                              0x203001B
+#define ORX_EQU_FFF_C3RE_RW__W                                              12
+#define ORX_EQU_FFF_C3RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C3RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C3IM_RW__A                                              0x203001C
+#define ORX_EQU_FFF_C3IM_RW__W                                              12
+#define ORX_EQU_FFF_C3IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C3IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C4RE_RW__A                                              0x203001D
+#define ORX_EQU_FFF_C4RE_RW__W                                              12
+#define ORX_EQU_FFF_C4RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C4RE_RW__PRE                                            0x400
+
+#define ORX_EQU_FFF_C4IM_RW__A                                              0x203001E
+#define ORX_EQU_FFF_C4IM_RW__W                                              12
+#define ORX_EQU_FFF_C4IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C4IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C5RE_RW__A                                              0x203001F
+#define ORX_EQU_FFF_C5RE_RW__W                                              12
+#define ORX_EQU_FFF_C5RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C5RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C5IM_RW__A                                              0x2030020
+#define ORX_EQU_FFF_C5IM_RW__W                                              12
+#define ORX_EQU_FFF_C5IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C5IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C6RE_RW__A                                              0x2030021
+#define ORX_EQU_FFF_C6RE_RW__W                                              12
+#define ORX_EQU_FFF_C6RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C6RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C6IM_RW__A                                              0x2030022
+#define ORX_EQU_FFF_C6IM_RW__W                                              12
+#define ORX_EQU_FFF_C6IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C6IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C7RE_RW__A                                              0x2030023
+#define ORX_EQU_FFF_C7RE_RW__W                                              12
+#define ORX_EQU_FFF_C7RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C7RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C7IM_RW__A                                              0x2030024
+#define ORX_EQU_FFF_C7IM_RW__W                                              12
+#define ORX_EQU_FFF_C7IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C7IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C8RE_RW__A                                              0x2030025
+#define ORX_EQU_FFF_C8RE_RW__W                                              12
+#define ORX_EQU_FFF_C8RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C8RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C8IM_RW__A                                              0x2030026
+#define ORX_EQU_FFF_C8IM_RW__W                                              12
+#define ORX_EQU_FFF_C8IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C8IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C9RE_RW__A                                              0x2030027
+#define ORX_EQU_FFF_C9RE_RW__W                                              12
+#define ORX_EQU_FFF_C9RE_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C9RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C9IM_RW__A                                              0x2030028
+#define ORX_EQU_FFF_C9IM_RW__W                                              12
+#define ORX_EQU_FFF_C9IM_RW__M                                              0xFFF
+#define ORX_EQU_FFF_C9IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FFF_C10RE_RW__A                                             0x2030029
+#define ORX_EQU_FFF_C10RE_RW__W                                             12
+#define ORX_EQU_FFF_C10RE_RW__M                                             0xFFF
+#define ORX_EQU_FFF_C10RE_RW__PRE                                           0x0
+
+#define ORX_EQU_FFF_C10IM_RW__A                                             0x203002A
+#define ORX_EQU_FFF_C10IM_RW__W                                             12
+#define ORX_EQU_FFF_C10IM_RW__M                                             0xFFF
+#define ORX_EQU_FFF_C10IM_RW__PRE                                           0x0
+
+#define ORX_EQU_MXB_SEL_W__A                                                0x203002B
+#define ORX_EQU_MXB_SEL_W__W                                                1
+#define ORX_EQU_MXB_SEL_W__M                                                0x1
+#define ORX_EQU_MXB_SEL_W__PRE                                              0x0
+#define   ORX_EQU_MXB_SEL_W_UNDECIDED_SYMBOLS                               0x0
+#define   ORX_EQU_MXB_SEL_W_DECIDED_SYMBOLS                                 0x1
+
+#define ORX_EQU_FBF_UPD_W__A                                                0x203002C
+#define ORX_EQU_FBF_UPD_W__W                                                1
+#define ORX_EQU_FBF_UPD_W__M                                                0x1
+#define ORX_EQU_FBF_UPD_W__PRE                                              0x0
+#define   ORX_EQU_FBF_UPD_W_NO_UPDATE                                       0x0
+#define   ORX_EQU_FBF_UPD_W_LMS_UPDATE                                      0x1
+
+#define ORX_EQU_FBF_STP_W__A                                                0x203002D
+#define ORX_EQU_FBF_STP_W__W                                                3
+#define ORX_EQU_FBF_STP_W__M                                                0x7
+#define ORX_EQU_FBF_STP_W__PRE                                              0x2
+
+#define ORX_EQU_FBF_LEA_W__A                                                0x203002E
+#define ORX_EQU_FBF_LEA_W__W                                                4
+#define ORX_EQU_FBF_LEA_W__M                                                0xF
+#define ORX_EQU_FBF_LEA_W__PRE                                              0x4
+
+#define ORX_EQU_FBF_RWT_W__A                                                0x203002F
+#define ORX_EQU_FBF_RWT_W__W                                                2
+#define ORX_EQU_FBF_RWT_W__M                                                0x3
+#define ORX_EQU_FBF_RWT_W__PRE                                              0x0
+
+#define ORX_EQU_FBF_C0RE_RW__A                                              0x2030030
+#define ORX_EQU_FBF_C0RE_RW__W                                              12
+#define ORX_EQU_FBF_C0RE_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C0RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C0IM_RW__A                                              0x2030031
+#define ORX_EQU_FBF_C0IM_RW__W                                              12
+#define ORX_EQU_FBF_C0IM_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C0IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C1RE_RW__A                                              0x2030032
+#define ORX_EQU_FBF_C1RE_RW__W                                              12
+#define ORX_EQU_FBF_C1RE_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C1RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C1IM_RW__A                                              0x2030033
+#define ORX_EQU_FBF_C1IM_RW__W                                              12
+#define ORX_EQU_FBF_C1IM_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C1IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C2RE_RW__A                                              0x2030034
+#define ORX_EQU_FBF_C2RE_RW__W                                              12
+#define ORX_EQU_FBF_C2RE_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C2RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C2IM_RW__A                                              0x2030035
+#define ORX_EQU_FBF_C2IM_RW__W                                              12
+#define ORX_EQU_FBF_C2IM_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C2IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C3RE_RW__A                                              0x2030036
+#define ORX_EQU_FBF_C3RE_RW__W                                              12
+#define ORX_EQU_FBF_C3RE_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C3RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C3IM_RW__A                                              0x2030037
+#define ORX_EQU_FBF_C3IM_RW__W                                              12
+#define ORX_EQU_FBF_C3IM_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C3IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C4RE_RW__A                                              0x2030038
+#define ORX_EQU_FBF_C4RE_RW__W                                              12
+#define ORX_EQU_FBF_C4RE_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C4RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C4IM_RW__A                                              0x2030039
+#define ORX_EQU_FBF_C4IM_RW__W                                              12
+#define ORX_EQU_FBF_C4IM_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C4IM_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C5RE_RW__A                                              0x203003A
+#define ORX_EQU_FBF_C5RE_RW__W                                              12
+#define ORX_EQU_FBF_C5RE_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C5RE_RW__PRE                                            0x0
+
+#define ORX_EQU_FBF_C5IM_RW__A                                              0x203003B
+#define ORX_EQU_FBF_C5IM_RW__W                                              12
+#define ORX_EQU_FBF_C5IM_RW__M                                              0xFFF
+#define ORX_EQU_FBF_C5IM_RW__PRE                                            0x0
+
+#define ORX_EQU_ERR_SEL_W__A                                                0x203003C
+#define ORX_EQU_ERR_SEL_W__W                                                1
+#define ORX_EQU_ERR_SEL_W__M                                                0x1
+#define ORX_EQU_ERR_SEL_W__PRE                                              0x0
+#define   ORX_EQU_ERR_SEL_W_CMA_ERROR                                       0x0
+#define   ORX_EQU_ERR_SEL_W_DDA_ERROR                                       0x1
+
+#define ORX_EQU_ERR_TIS_W__A                                                0x203003D
+#define ORX_EQU_ERR_TIS_W__W                                                1
+#define ORX_EQU_ERR_TIS_W__M                                                0x1
+#define ORX_EQU_ERR_TIS_W__PRE                                              0x0
+#define   ORX_EQU_ERR_TIS_W_CMA_SIGNALS                                     0x0
+#define   ORX_EQU_ERR_TIS_W_DDA_SIGNALS                                     0x1
+
+#define ORX_EQU_ERR_EDI_R__A                                                0x203003E
+#define ORX_EQU_ERR_EDI_R__W                                                5
+#define ORX_EQU_ERR_EDI_R__M                                                0x1F
+#define ORX_EQU_ERR_EDI_R__PRE                                              0xF
+
+#define ORX_EQU_ERR_EDQ_R__A                                                0x203003F
+#define ORX_EQU_ERR_EDQ_R__W                                                5
+#define ORX_EQU_ERR_EDQ_R__M                                                0x1F
+#define ORX_EQU_ERR_EDQ_R__PRE                                              0xF
+
+#define ORX_EQU_ERR_ECI_R__A                                                0x2030040
+#define ORX_EQU_ERR_ECI_R__W                                                5
+#define ORX_EQU_ERR_ECI_R__M                                                0x1F
+#define ORX_EQU_ERR_ECI_R__PRE                                              0xF
+
+#define ORX_EQU_ERR_ECQ_R__A                                                0x2030041
+#define ORX_EQU_ERR_ECQ_R__W                                                5
+#define ORX_EQU_ERR_ECQ_R__M                                                0x1F
+#define ORX_EQU_ERR_ECQ_R__PRE                                              0xF
+
+#define ORX_EQU_MER_MER_R__A                                                0x2030042
+#define ORX_EQU_MER_MER_R__W                                                6
+#define ORX_EQU_MER_MER_R__M                                                0x3F
+#define ORX_EQU_MER_MER_R__PRE                                              0x3F
+
+#define ORX_EQU_MER_LDT_W__A                                                0x2030043
+#define ORX_EQU_MER_LDT_W__W                                                3
+#define ORX_EQU_MER_LDT_W__M                                                0x7
+#define ORX_EQU_MER_LDT_W__PRE                                              0x4
+
+#define ORX_EQU_SYN_LEN_W__A                                                0x2030044
+#define ORX_EQU_SYN_LEN_W__W                                                16
+#define ORX_EQU_SYN_LEN_W__M                                                0xFFFF
+#define ORX_EQU_SYN_LEN_W__PRE                                              0x0
+
+#define ORX_DDC_COMM_EXEC__A                                                0x2040000
+#define ORX_DDC_COMM_EXEC__W                                                2
+#define ORX_DDC_COMM_EXEC__M                                                0x3
+#define ORX_DDC_COMM_EXEC__PRE                                              0x0
+#define   ORX_DDC_COMM_EXEC_STOP                                            0x0
+#define   ORX_DDC_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_DDC_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_DDC_COMM_MB__A                                                  0x2040002
+#define ORX_DDC_COMM_MB__W                                                  6
+#define ORX_DDC_COMM_MB__M                                                  0x3F
+#define ORX_DDC_COMM_MB__PRE                                                0x0
+#define   ORX_DDC_COMM_MB_CTL__B                                            0
+#define   ORX_DDC_COMM_MB_CTL__W                                            1
+#define   ORX_DDC_COMM_MB_CTL__M                                            0x1
+#define   ORX_DDC_COMM_MB_CTL__PRE                                          0x0
+#define     ORX_DDC_COMM_MB_CTL_OFF                                         0x0
+#define     ORX_DDC_COMM_MB_CTL_ON                                          0x1
+#define   ORX_DDC_COMM_MB_OBS__B                                            1
+#define   ORX_DDC_COMM_MB_OBS__W                                            1
+#define   ORX_DDC_COMM_MB_OBS__M                                            0x2
+#define   ORX_DDC_COMM_MB_OBS__PRE                                          0x0
+#define     ORX_DDC_COMM_MB_OBS_OFF                                         0x0
+#define     ORX_DDC_COMM_MB_OBS_ON                                          0x2
+
+#define   ORX_DDC_COMM_MB_CTL_MUX__B                                        2
+#define   ORX_DDC_COMM_MB_CTL_MUX__W                                        2
+#define   ORX_DDC_COMM_MB_CTL_MUX__M                                        0xC
+#define   ORX_DDC_COMM_MB_CTL_MUX__PRE                                      0x0
+
+#define   ORX_DDC_COMM_MB_OBS_MUX__B                                        4
+#define   ORX_DDC_COMM_MB_OBS_MUX__W                                        2
+#define   ORX_DDC_COMM_MB_OBS_MUX__M                                        0x30
+#define   ORX_DDC_COMM_MB_OBS_MUX__PRE                                      0x0
+
+#define ORX_DDC_COMM_INT_REQ__A                                             0x2040003
+#define ORX_DDC_COMM_INT_REQ__W                                             1
+#define ORX_DDC_COMM_INT_REQ__M                                             0x1
+#define ORX_DDC_COMM_INT_REQ__PRE                                           0x0
+#define ORX_DDC_COMM_INT_STA__A                                             0x2040005
+#define ORX_DDC_COMM_INT_STA__W                                             1
+#define ORX_DDC_COMM_INT_STA__M                                             0x1
+#define ORX_DDC_COMM_INT_STA__PRE                                           0x0
+#define ORX_DDC_COMM_INT_MSK__A                                             0x2040006
+#define ORX_DDC_COMM_INT_MSK__W                                             1
+#define ORX_DDC_COMM_INT_MSK__M                                             0x1
+#define ORX_DDC_COMM_INT_MSK__PRE                                           0x0
+#define ORX_DDC_COMM_INT_STM__A                                             0x2040007
+#define ORX_DDC_COMM_INT_STM__W                                             1
+#define ORX_DDC_COMM_INT_STM__M                                             0x1
+#define ORX_DDC_COMM_INT_STM__PRE                                           0x0
+#define ORX_DDC_DEC_MAP_W__A                                                0x2040010
+#define ORX_DDC_DEC_MAP_W__W                                                9
+#define ORX_DDC_DEC_MAP_W__M                                                0x1FF
+#define ORX_DDC_DEC_MAP_W__PRE                                              0x178
+
+#define   ORX_DDC_DEC_MAP_W_QUADR0__B                                       0
+#define   ORX_DDC_DEC_MAP_W_QUADR0__W                                       2
+#define   ORX_DDC_DEC_MAP_W_QUADR0__M                                       0x3
+#define   ORX_DDC_DEC_MAP_W_QUADR0__PRE                                     0x0
+#define     ORX_DDC_DEC_MAP_W_QUADR0_ROTATE_DEFAULT                         0x0
+#define     ORX_DDC_DEC_MAP_W_QUADR0_ROTATE_ALTERNATE                       0x0
+
+#define   ORX_DDC_DEC_MAP_W_QUADR1__B                                       2
+#define   ORX_DDC_DEC_MAP_W_QUADR1__W                                       2
+#define   ORX_DDC_DEC_MAP_W_QUADR1__M                                       0xC
+#define   ORX_DDC_DEC_MAP_W_QUADR1__PRE                                     0x8
+#define     ORX_DDC_DEC_MAP_W_QUADR1_ROTATE_DEFAULT                         0x8
+#define     ORX_DDC_DEC_MAP_W_QUADR1_ROTATE_ALTERNATE                       0x4
+
+#define   ORX_DDC_DEC_MAP_W_QUADR2__B                                       4
+#define   ORX_DDC_DEC_MAP_W_QUADR2__W                                       2
+#define   ORX_DDC_DEC_MAP_W_QUADR2__M                                       0x30
+#define   ORX_DDC_DEC_MAP_W_QUADR2__PRE                                     0x30
+#define     ORX_DDC_DEC_MAP_W_QUADR2_ROTATE_DEFAULT                         0x30
+#define     ORX_DDC_DEC_MAP_W_QUADR2_ROTATE_ALTERNATE                       0x30
+
+#define   ORX_DDC_DEC_MAP_W_QUADR3__B                                       6
+#define   ORX_DDC_DEC_MAP_W_QUADR3__W                                       2
+#define   ORX_DDC_DEC_MAP_W_QUADR3__M                                       0xC0
+#define   ORX_DDC_DEC_MAP_W_QUADR3__PRE                                     0x40
+#define     ORX_DDC_DEC_MAP_W_QUADR3_ROTATE_DEFAULT                         0x40
+#define     ORX_DDC_DEC_MAP_W_QUADR3_ROTATE_ALTERNATE                       0x80
+#define   ORX_DDC_DEC_MAP_W_DIFF_DECOD__B                                   8
+#define   ORX_DDC_DEC_MAP_W_DIFF_DECOD__W                                   1
+#define   ORX_DDC_DEC_MAP_W_DIFF_DECOD__M                                   0x100
+#define   ORX_DDC_DEC_MAP_W_DIFF_DECOD__PRE                                 0x100
+#define     ORX_DDC_DEC_MAP_W_DIFF_DECOD_COHERENT_DECODING                  0x0
+#define     ORX_DDC_DEC_MAP_W_DIFF_DECOD_DIFF_DECODING                      0x100
+
+#define ORX_DDC_OFO_SET_W__A                                                0x2040011
+#define ORX_DDC_OFO_SET_W__W                                                16
+#define ORX_DDC_OFO_SET_W__M                                                0xFFFF
+#define ORX_DDC_OFO_SET_W__PRE                                              0x1402
+
+#define   ORX_DDC_OFO_SET_W_PHASE__B                                        0
+#define   ORX_DDC_OFO_SET_W_PHASE__W                                        7
+#define   ORX_DDC_OFO_SET_W_PHASE__M                                        0x7F
+#define   ORX_DDC_OFO_SET_W_PHASE__PRE                                      0x2
+
+#define   ORX_DDC_OFO_SET_W_CRXHITIME__B                                    7
+#define   ORX_DDC_OFO_SET_W_CRXHITIME__W                                    7
+#define   ORX_DDC_OFO_SET_W_CRXHITIME__M                                    0x3F80
+#define   ORX_DDC_OFO_SET_W_CRXHITIME__PRE                                  0x1400
+
+#define   ORX_DDC_OFO_SET_W_CRXINV__B                                       14
+#define   ORX_DDC_OFO_SET_W_CRXINV__W                                       1
+#define   ORX_DDC_OFO_SET_W_CRXINV__M                                       0x4000
+#define   ORX_DDC_OFO_SET_W_CRXINV__PRE                                     0x0
+
+#define   ORX_DDC_OFO_SET_W_DISABLE__B                                      15
+#define   ORX_DDC_OFO_SET_W_DISABLE__W                                      1
+#define   ORX_DDC_OFO_SET_W_DISABLE__M                                      0x8000
+#define   ORX_DDC_OFO_SET_W_DISABLE__PRE                                    0x0
+
+#define ORX_CON_COMM_EXEC__A                                                0x2050000
+#define ORX_CON_COMM_EXEC__W                                                2
+#define ORX_CON_COMM_EXEC__M                                                0x3
+#define ORX_CON_COMM_EXEC__PRE                                              0x0
+#define   ORX_CON_COMM_EXEC_STOP                                            0x0
+#define   ORX_CON_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_CON_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_CON_LDT_W__A                                                    0x2050010
+#define ORX_CON_LDT_W__W                                                    3
+#define ORX_CON_LDT_W__M                                                    0x7
+#define ORX_CON_LDT_W__PRE                                                  0x3
+
+#define   ORX_CON_LDT_W_CON_LDT_W__B                                        0
+#define   ORX_CON_LDT_W_CON_LDT_W__W                                        3
+#define   ORX_CON_LDT_W_CON_LDT_W__M                                        0x7
+#define   ORX_CON_LDT_W_CON_LDT_W__PRE                                      0x3
+
+#define ORX_CON_RST_W__A                                                    0x2050011
+#define ORX_CON_RST_W__W                                                    4
+#define ORX_CON_RST_W__M                                                    0xF
+#define ORX_CON_RST_W__PRE                                                  0x0
+
+#define   ORX_CON_RST_W_CPH__B                                              0
+#define   ORX_CON_RST_W_CPH__W                                              1
+#define   ORX_CON_RST_W_CPH__M                                              0x1
+#define   ORX_CON_RST_W_CPH__PRE                                            0x0
+
+#define   ORX_CON_RST_W_CTI__B                                              1
+#define   ORX_CON_RST_W_CTI__W                                              1
+#define   ORX_CON_RST_W_CTI__M                                              0x2
+#define   ORX_CON_RST_W_CTI__PRE                                            0x0
+
+#define   ORX_CON_RST_W_KRN__B                                              2
+#define   ORX_CON_RST_W_KRN__W                                              1
+#define   ORX_CON_RST_W_KRN__M                                              0x4
+#define   ORX_CON_RST_W_KRN__PRE                                            0x0
+
+#define   ORX_CON_RST_W_KRP__B                                              3
+#define   ORX_CON_RST_W_KRP__W                                              1
+#define   ORX_CON_RST_W_KRP__M                                              0x8
+#define   ORX_CON_RST_W_KRP__PRE                                            0x0
+
+#define ORX_CON_CPH_PHI_R__A                                                0x2050012
+#define ORX_CON_CPH_PHI_R__W                                                16
+#define ORX_CON_CPH_PHI_R__M                                                0xFFFF
+#define ORX_CON_CPH_PHI_R__PRE                                              0x0
+
+#define ORX_CON_CPH_FRQ_R__A                                                0x2050013
+#define ORX_CON_CPH_FRQ_R__W                                                16
+#define ORX_CON_CPH_FRQ_R__M                                                0xFFFF
+#define ORX_CON_CPH_FRQ_R__PRE                                              0x0
+
+#define ORX_CON_CPH_AMP_R__A                                                0x2050014
+#define ORX_CON_CPH_AMP_R__W                                                16
+#define ORX_CON_CPH_AMP_R__M                                                0xFFFF
+#define ORX_CON_CPH_AMP_R__PRE                                              0x0
+
+#define ORX_CON_CPH_KDF_W__A                                                0x2050015
+#define ORX_CON_CPH_KDF_W__W                                                4
+#define ORX_CON_CPH_KDF_W__M                                                0xF
+#define ORX_CON_CPH_KDF_W__PRE                                              0x0
+
+#define ORX_CON_CPH_KPF_W__A                                                0x2050016
+#define ORX_CON_CPH_KPF_W__W                                                4
+#define ORX_CON_CPH_KPF_W__M                                                0xF
+#define ORX_CON_CPH_KPF_W__PRE                                              0x0
+
+#define ORX_CON_CPH_KIF_W__A                                                0x2050017
+#define ORX_CON_CPH_KIF_W__W                                                4
+#define ORX_CON_CPH_KIF_W__M                                                0xF
+#define ORX_CON_CPH_KIF_W__PRE                                              0x0
+#define ORX_CON_CPH_APT_W__A                                                0x2050018
+#define ORX_CON_CPH_APT_W__W                                                16
+#define ORX_CON_CPH_APT_W__M                                                0xFFFF
+#define ORX_CON_CPH_APT_W__PRE                                              0x804
+
+#define   ORX_CON_CPH_APT_W_PTH__B                                          0
+#define   ORX_CON_CPH_APT_W_PTH__W                                          8
+#define   ORX_CON_CPH_APT_W_PTH__M                                          0xFF
+#define   ORX_CON_CPH_APT_W_PTH__PRE                                        0x4
+
+#define   ORX_CON_CPH_APT_W_ATH__B                                          8
+#define   ORX_CON_CPH_APT_W_ATH__W                                          8
+#define   ORX_CON_CPH_APT_W_ATH__M                                          0xFF00
+#define   ORX_CON_CPH_APT_W_ATH__PRE                                        0x800
+
+#define ORX_CON_CPH_WLC_W__A                                                0x2050019
+#define ORX_CON_CPH_WLC_W__W                                                8
+#define ORX_CON_CPH_WLC_W__M                                                0xFF
+#define ORX_CON_CPH_WLC_W__PRE                                              0x81
+
+#define   ORX_CON_CPH_WLC_W_LATC__B                                         0
+#define   ORX_CON_CPH_WLC_W_LATC__W                                         4
+#define   ORX_CON_CPH_WLC_W_LATC__M                                         0xF
+#define   ORX_CON_CPH_WLC_W_LATC__PRE                                       0x1
+
+#define   ORX_CON_CPH_WLC_W_WLIM__B                                         4
+#define   ORX_CON_CPH_WLC_W_WLIM__W                                         4
+#define   ORX_CON_CPH_WLC_W_WLIM__M                                         0xF0
+#define   ORX_CON_CPH_WLC_W_WLIM__PRE                                       0x80
+
+#define ORX_CON_CPH_DLY_W__A                                                0x205001A
+#define ORX_CON_CPH_DLY_W__W                                                3
+#define ORX_CON_CPH_DLY_W__M                                                0x7
+#define ORX_CON_CPH_DLY_W__PRE                                              0x4
+
+#define ORX_CON_CPH_TCL_W__A                                                0x205001B
+#define ORX_CON_CPH_TCL_W__W                                                3
+#define ORX_CON_CPH_TCL_W__M                                                0x7
+#define ORX_CON_CPH_TCL_W__PRE                                              0x3
+
+#define ORX_CON_KRP_AMP_R__A                                                0x205001C
+#define ORX_CON_KRP_AMP_R__W                                                9
+#define ORX_CON_KRP_AMP_R__M                                                0x1FF
+#define ORX_CON_KRP_AMP_R__PRE                                              0x0
+
+#define ORX_CON_KRN_AMP_R__A                                                0x205001D
+#define ORX_CON_KRN_AMP_R__W                                                9
+#define ORX_CON_KRN_AMP_R__M                                                0x1FF
+#define ORX_CON_KRN_AMP_R__PRE                                              0x0
+
+#define ORX_CON_CTI_DTI_R__A                                                0x205001E
+#define ORX_CON_CTI_DTI_R__W                                                16
+#define ORX_CON_CTI_DTI_R__M                                                0xFFFF
+#define ORX_CON_CTI_DTI_R__PRE                                              0x0
+
+#define ORX_CON_CTI_KDT_W__A                                                0x205001F
+#define ORX_CON_CTI_KDT_W__W                                                4
+#define ORX_CON_CTI_KDT_W__M                                                0xF
+#define ORX_CON_CTI_KDT_W__PRE                                              0x4
+
+#define ORX_CON_CTI_KPT_W__A                                                0x2050020
+#define ORX_CON_CTI_KPT_W__W                                                4
+#define ORX_CON_CTI_KPT_W__M                                                0xF
+#define ORX_CON_CTI_KPT_W__PRE                                              0x3
+
+#define ORX_CON_CTI_KIT_W__A                                                0x2050021
+#define ORX_CON_CTI_KIT_W__W                                                4
+#define ORX_CON_CTI_KIT_W__M                                                0xF
+#define ORX_CON_CTI_KIT_W__PRE                                              0xB
+
+#define ORX_CON_CTI_TAT_W__A                                                0x2050022
+#define ORX_CON_CTI_TAT_W__W                                                4
+#define ORX_CON_CTI_TAT_W__M                                                0xF
+#define ORX_CON_CTI_TAT_W__PRE                                              0x3
+
+#define ORX_NSU_COMM_EXEC__A                                                0x2060000
+#define ORX_NSU_COMM_EXEC__W                                                2
+#define ORX_NSU_COMM_EXEC__M                                                0x3
+#define ORX_NSU_COMM_EXEC__PRE                                              0x0
+#define   ORX_NSU_COMM_EXEC_STOP                                            0x0
+#define   ORX_NSU_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_NSU_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_NSU_AOX_STDBY_W__A                                              0x2060010
+#define ORX_NSU_AOX_STDBY_W__W                                              8
+#define ORX_NSU_AOX_STDBY_W__M                                              0xFF
+#define ORX_NSU_AOX_STDBY_W__PRE                                            0x0
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYADC__B                                   0
+#define   ORX_NSU_AOX_STDBY_W_STDBYADC__W                                   1
+#define   ORX_NSU_AOX_STDBY_W_STDBYADC__M                                   0x1
+#define   ORX_NSU_AOX_STDBY_W_STDBYADC__PRE                                 0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYADC_A1_ON                              0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYADC_A1_OFF                             0x1
+#define     ORX_NSU_AOX_STDBY_W_STDBYADC_A2_OFF                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON                              0x1
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYAMP__B                                   1
+#define   ORX_NSU_AOX_STDBY_W_STDBYAMP__W                                   1
+#define   ORX_NSU_AOX_STDBY_W_STDBYAMP__M                                   0x2
+#define   ORX_NSU_AOX_STDBY_W_STDBYAMP__PRE                                 0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYAMP_A1_ON                              0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYAMP_A1_OFF                             0x2
+#define     ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_OFF                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON                              0x2
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYBIAS__B                                  2
+#define   ORX_NSU_AOX_STDBY_W_STDBYBIAS__W                                  1
+#define   ORX_NSU_AOX_STDBY_W_STDBYBIAS__M                                  0x4
+#define   ORX_NSU_AOX_STDBY_W_STDBYBIAS__PRE                                0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYBIAS_A1_ON                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYBIAS_A1_OFF                            0x4
+#define     ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_OFF                            0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON                             0x4
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYPLL__B                                   3
+#define   ORX_NSU_AOX_STDBY_W_STDBYPLL__W                                   1
+#define   ORX_NSU_AOX_STDBY_W_STDBYPLL__M                                   0x8
+#define   ORX_NSU_AOX_STDBY_W_STDBYPLL__PRE                                 0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYPLL_A1_ON                              0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYPLL_A1_OFF                             0x8
+#define     ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_OFF                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON                              0x8
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYPD__B                                    4
+#define   ORX_NSU_AOX_STDBY_W_STDBYPD__W                                    1
+#define   ORX_NSU_AOX_STDBY_W_STDBYPD__M                                    0x10
+#define   ORX_NSU_AOX_STDBY_W_STDBYPD__PRE                                  0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYPD_A1_ON                               0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYPD_A1_OFF                              0x10
+#define     ORX_NSU_AOX_STDBY_W_STDBYPD_A2_OFF                              0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON                               0x10
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF__B                               5
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF__W                               1
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF__M                               0x20
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF__PRE                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A1_ON                          0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A1_OFF                         0x20
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_OFF                         0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON                          0x20
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF__B                               6
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF__W                               1
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF__M                               0x40
+#define   ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF__PRE                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A1_ON                          0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A1_OFF                         0x40
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_OFF                         0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON                          0x40
+
+#define   ORX_NSU_AOX_STDBY_W_STDBYFLT__B                                   7
+#define   ORX_NSU_AOX_STDBY_W_STDBYFLT__W                                   1
+#define   ORX_NSU_AOX_STDBY_W_STDBYFLT__M                                   0x80
+#define   ORX_NSU_AOX_STDBY_W_STDBYFLT__PRE                                 0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYFLT_A1_ON                              0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYFLT_A1_OFF                             0x80
+#define     ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_OFF                             0x0
+#define     ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON                              0x80
+
+#define ORX_NSU_AOX_LOFRQ_W__A                                              0x2060011
+#define ORX_NSU_AOX_LOFRQ_W__W                                              16
+#define ORX_NSU_AOX_LOFRQ_W__M                                              0xFFFF
+#define ORX_NSU_AOX_LOFRQ_W__PRE                                            0x0
+#define ORX_NSU_AOX_LOMDE_W__A                                              0x2060012
+#define ORX_NSU_AOX_LOMDE_W__W                                              16
+#define ORX_NSU_AOX_LOMDE_W__M                                              0xFFFF
+#define ORX_NSU_AOX_LOMDE_W__PRE                                            0x0
+
+#define   ORX_NSU_AOX_LOMDE_W_AOX_LOFRQ_EXT__B                              0
+#define   ORX_NSU_AOX_LOMDE_W_AOX_LOFRQ_EXT__W                              8
+#define   ORX_NSU_AOX_LOMDE_W_AOX_LOFRQ_EXT__M                              0xFF
+#define   ORX_NSU_AOX_LOMDE_W_AOX_LOFRQ_EXT__PRE                            0x0
+
+#define   ORX_NSU_AOX_LOMDE_W_RESET_VCO__B                                  13
+#define   ORX_NSU_AOX_LOMDE_W_RESET_VCO__W                                  1
+#define   ORX_NSU_AOX_LOMDE_W_RESET_VCO__M                                  0x2000
+#define   ORX_NSU_AOX_LOMDE_W_RESET_VCO__PRE                                0x0
+
+#define   ORX_NSU_AOX_LOMDE_W_PLL_DIV__B                                    14
+#define   ORX_NSU_AOX_LOMDE_W_PLL_DIV__W                                    2
+#define   ORX_NSU_AOX_LOMDE_W_PLL_DIV__M                                    0xC000
+#define   ORX_NSU_AOX_LOMDE_W_PLL_DIV__PRE                                  0x0
+
+#define ORX_NSU_AOX_LOPOW_W__A                                              0x2060013
+#define ORX_NSU_AOX_LOPOW_W__W                                              2
+#define ORX_NSU_AOX_LOPOW_W__M                                              0x3
+#define ORX_NSU_AOX_LOPOW_W__PRE                                            0x0
+#define   ORX_NSU_AOX_LOPOW_W_POWER_MINUS0DB                                0x0
+#define   ORX_NSU_AOX_LOPOW_W_POWER_MINUS5DB                                0x1
+#define   ORX_NSU_AOX_LOPOW_W_POWER_MINUS10DB                               0x2
+#define   ORX_NSU_AOX_LOPOW_W_POWER_MINUS15DB                               0x3
+
+#define ORX_NSU_AOX_STHR_W__A                                               0x2060014
+#define ORX_NSU_AOX_STHR_W__W                                               5
+#define ORX_NSU_AOX_STHR_W__M                                               0x1F
+#define ORX_NSU_AOX_STHR_W__PRE                                             0x0
+
+#define ORX_NSU_TUN_RFGAIN_W__A                                             0x2060015
+#define ORX_NSU_TUN_RFGAIN_W__W                                             15
+#define ORX_NSU_TUN_RFGAIN_W__M                                             0x7FFF
+#define ORX_NSU_TUN_RFGAIN_W__PRE                                           0x0
+
+#define ORX_NSU_TUN_IFGAIN_W__A                                             0x2060016
+#define ORX_NSU_TUN_IFGAIN_W__W                                             15
+#define ORX_NSU_TUN_IFGAIN_W__M                                             0x7FFF
+#define ORX_NSU_TUN_IFGAIN_W__PRE                                           0x0
+
+#define ORX_NSU_TUN_BPF_W__A                                                0x2060017
+#define ORX_NSU_TUN_BPF_W__W                                                15
+#define ORX_NSU_TUN_BPF_W__M                                                0x7FFF
+#define ORX_NSU_TUN_BPF_W__PRE                                              0x1F9
+#define ORX_NSU_NSS_BITSWAP_W__A                                            0x2060018
+#define ORX_NSU_NSS_BITSWAP_W__W                                            3
+#define ORX_NSU_NSS_BITSWAP_W__M                                            0x7
+#define ORX_NSU_NSS_BITSWAP_W__PRE                                          0x0
+
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS0_RF__B                           0
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS0_RF__W                           1
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS0_RF__M                           0x1
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS0_RF__PRE                         0x0
+
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS1_IF__B                           1
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS1_IF__W                           1
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS1_IF__M                           0x2
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS1_IF__PRE                         0x0
+
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS2_BP__B                           2
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS2_BP__W                           1
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS2_BP__M                           0x4
+#define   ORX_NSU_NSS_BITSWAP_W_BITSWAP_NS2_BP__PRE                         0x0
+
+#define ORX_TST_COMM_EXEC__A                                                0x23F0000
+#define ORX_TST_COMM_EXEC__W                                                2
+#define ORX_TST_COMM_EXEC__M                                                0x3
+#define ORX_TST_COMM_EXEC__PRE                                              0x0
+#define   ORX_TST_COMM_EXEC_STOP                                            0x0
+#define   ORX_TST_COMM_EXEC_ACTIVE                                          0x1
+#define   ORX_TST_COMM_EXEC_HOLD                                            0x2
+
+#define ORX_TST_AOX_TST_W__A                                                0x23F0010
+#define ORX_TST_AOX_TST_W__W                                                8
+#define ORX_TST_AOX_TST_W__M                                                0xFF
+#define ORX_TST_AOX_TST_W__PRE                                              0x0
+
+#define QAM_COMM_EXEC__A                                                    0x1400000
+#define QAM_COMM_EXEC__W                                                    2
+#define QAM_COMM_EXEC__M                                                    0x3
+#define QAM_COMM_EXEC__PRE                                                  0x0
+#define   QAM_COMM_EXEC_STOP                                                0x0
+#define   QAM_COMM_EXEC_ACTIVE                                              0x1
+#define   QAM_COMM_EXEC_HOLD                                                0x2
+
+#define QAM_COMM_MB__A                                                      0x1400002
+#define QAM_COMM_MB__W                                                      16
+#define QAM_COMM_MB__M                                                      0xFFFF
+#define QAM_COMM_MB__PRE                                                    0x0
+#define QAM_COMM_INT_REQ__A                                                 0x1400003
+#define QAM_COMM_INT_REQ__W                                                 16
+#define QAM_COMM_INT_REQ__M                                                 0xFFFF
+#define QAM_COMM_INT_REQ__PRE                                               0x0
+
+#define   QAM_COMM_INT_REQ_SL_REQ__B                                        0
+#define   QAM_COMM_INT_REQ_SL_REQ__W                                        1
+#define   QAM_COMM_INT_REQ_SL_REQ__M                                        0x1
+#define   QAM_COMM_INT_REQ_SL_REQ__PRE                                      0x0
+
+#define   QAM_COMM_INT_REQ_LC_REQ__B                                        1
+#define   QAM_COMM_INT_REQ_LC_REQ__W                                        1
+#define   QAM_COMM_INT_REQ_LC_REQ__M                                        0x2
+#define   QAM_COMM_INT_REQ_LC_REQ__PRE                                      0x0
+
+#define   QAM_COMM_INT_REQ_VD_REQ__B                                        2
+#define   QAM_COMM_INT_REQ_VD_REQ__W                                        1
+#define   QAM_COMM_INT_REQ_VD_REQ__M                                        0x4
+#define   QAM_COMM_INT_REQ_VD_REQ__PRE                                      0x0
+
+#define   QAM_COMM_INT_REQ_SY_REQ__B                                        3
+#define   QAM_COMM_INT_REQ_SY_REQ__W                                        1
+#define   QAM_COMM_INT_REQ_SY_REQ__M                                        0x8
+#define   QAM_COMM_INT_REQ_SY_REQ__PRE                                      0x0
+
+#define QAM_COMM_INT_STA__A                                                 0x1400005
+#define QAM_COMM_INT_STA__W                                                 16
+#define QAM_COMM_INT_STA__M                                                 0xFFFF
+#define QAM_COMM_INT_STA__PRE                                               0x0
+#define QAM_COMM_INT_MSK__A                                                 0x1400006
+#define QAM_COMM_INT_MSK__W                                                 16
+#define QAM_COMM_INT_MSK__M                                                 0xFFFF
+#define QAM_COMM_INT_MSK__PRE                                               0x0
+#define QAM_COMM_INT_STM__A                                                 0x1400007
+#define QAM_COMM_INT_STM__W                                                 16
+#define QAM_COMM_INT_STM__M                                                 0xFFFF
+#define QAM_COMM_INT_STM__PRE                                               0x0
+
+#define QAM_TOP_COMM_EXEC__A                                                0x1410000
+#define QAM_TOP_COMM_EXEC__W                                                2
+#define QAM_TOP_COMM_EXEC__M                                                0x3
+#define QAM_TOP_COMM_EXEC__PRE                                              0x0
+#define   QAM_TOP_COMM_EXEC_STOP                                            0x0
+#define   QAM_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   QAM_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define QAM_TOP_ANNEX__A                                                    0x1410010
+#define QAM_TOP_ANNEX__W                                                    2
+#define QAM_TOP_ANNEX__M                                                    0x3
+#define QAM_TOP_ANNEX__PRE                                                  0x1
+#define   QAM_TOP_ANNEX_A                                                   0x0
+#define   QAM_TOP_ANNEX_B                                                   0x1
+#define   QAM_TOP_ANNEX_C                                                   0x2
+#define   QAM_TOP_ANNEX_D                                                   0x3
+
+#define QAM_TOP_CONSTELLATION__A                                            0x1410011
+#define QAM_TOP_CONSTELLATION__W                                            3
+#define QAM_TOP_CONSTELLATION__M                                            0x7
+#define QAM_TOP_CONSTELLATION__PRE                                          0x5
+#define   QAM_TOP_CONSTELLATION_NONE                                        0x0
+#define   QAM_TOP_CONSTELLATION_QPSK                                        0x1
+#define   QAM_TOP_CONSTELLATION_QAM8                                        0x2
+#define   QAM_TOP_CONSTELLATION_QAM16                                       0x3
+#define   QAM_TOP_CONSTELLATION_QAM32                                       0x4
+#define   QAM_TOP_CONSTELLATION_QAM64                                       0x5
+#define   QAM_TOP_CONSTELLATION_QAM128                                      0x6
+#define   QAM_TOP_CONSTELLATION_QAM256                                      0x7
+
+#define QAM_FQ_COMM_EXEC__A                                                 0x1420000
+#define QAM_FQ_COMM_EXEC__W                                                 2
+#define QAM_FQ_COMM_EXEC__M                                                 0x3
+#define QAM_FQ_COMM_EXEC__PRE                                               0x0
+#define   QAM_FQ_COMM_EXEC_STOP                                             0x0
+#define   QAM_FQ_COMM_EXEC_ACTIVE                                           0x1
+#define   QAM_FQ_COMM_EXEC_HOLD                                             0x2
+
+#define QAM_FQ_MODE__A                                                      0x1420010
+#define QAM_FQ_MODE__W                                                      3
+#define QAM_FQ_MODE__M                                                      0x7
+#define QAM_FQ_MODE__PRE                                                    0x0
+
+#define   QAM_FQ_MODE_TAPRESET__B                                           0
+#define   QAM_FQ_MODE_TAPRESET__W                                           1
+#define   QAM_FQ_MODE_TAPRESET__M                                           0x1
+#define   QAM_FQ_MODE_TAPRESET__PRE                                         0x0
+#define     QAM_FQ_MODE_TAPRESET_RST                                        0x1
+
+#define   QAM_FQ_MODE_TAPLMS__B                                             1
+#define   QAM_FQ_MODE_TAPLMS__W                                             1
+#define   QAM_FQ_MODE_TAPLMS__M                                             0x2
+#define   QAM_FQ_MODE_TAPLMS__PRE                                           0x0
+#define     QAM_FQ_MODE_TAPLMS_UPD                                          0x2
+
+#define   QAM_FQ_MODE_TAPDRAIN__B                                           2
+#define   QAM_FQ_MODE_TAPDRAIN__W                                           1
+#define   QAM_FQ_MODE_TAPDRAIN__M                                           0x4
+#define   QAM_FQ_MODE_TAPDRAIN__PRE                                         0x0
+#define     QAM_FQ_MODE_TAPDRAIN_DRAIN                                      0x4
+
+#define QAM_FQ_MU_FACTOR__A                                                 0x1420011
+#define QAM_FQ_MU_FACTOR__W                                                 3
+#define QAM_FQ_MU_FACTOR__M                                                 0x7
+#define QAM_FQ_MU_FACTOR__PRE                                               0x0
+
+#define QAM_FQ_LA_FACTOR__A                                                 0x1420012
+#define QAM_FQ_LA_FACTOR__W                                                 4
+#define QAM_FQ_LA_FACTOR__M                                                 0xF
+#define QAM_FQ_LA_FACTOR__PRE                                               0xC
+#define QAM_FQ_CENTTAP_IDX__A                                               0x1420016
+#define QAM_FQ_CENTTAP_IDX__W                                               5
+#define QAM_FQ_CENTTAP_IDX__M                                               0x1F
+#define QAM_FQ_CENTTAP_IDX__PRE                                             0x13
+
+#define   QAM_FQ_CENTTAP_IDX_IDX__B                                         0
+#define   QAM_FQ_CENTTAP_IDX_IDX__W                                         5
+#define   QAM_FQ_CENTTAP_IDX_IDX__M                                         0x1F
+#define   QAM_FQ_CENTTAP_IDX_IDX__PRE                                       0x13
+
+#define QAM_FQ_CENTTAP_VALUE__A                                             0x1420017
+#define QAM_FQ_CENTTAP_VALUE__W                                             12
+#define QAM_FQ_CENTTAP_VALUE__M                                             0xFFF
+#define QAM_FQ_CENTTAP_VALUE__PRE                                           0x600
+
+#define   QAM_FQ_CENTTAP_VALUE_TAP__B                                       0
+#define   QAM_FQ_CENTTAP_VALUE_TAP__W                                       12
+#define   QAM_FQ_CENTTAP_VALUE_TAP__M                                       0xFFF
+#define   QAM_FQ_CENTTAP_VALUE_TAP__PRE                                     0x600
+
+#define QAM_FQ_TAP_RE_EL0__A                                                0x1420020
+#define QAM_FQ_TAP_RE_EL0__W                                                12
+#define QAM_FQ_TAP_RE_EL0__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL0__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL0_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL0_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL0_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL0_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL0__A                                                0x1420021
+#define QAM_FQ_TAP_IM_EL0__W                                                12
+#define QAM_FQ_TAP_IM_EL0__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL0__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL0_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL0_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL0_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL0_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL1__A                                                0x1420022
+#define QAM_FQ_TAP_RE_EL1__W                                                12
+#define QAM_FQ_TAP_RE_EL1__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL1__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL1_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL1_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL1_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL1_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL1__A                                                0x1420023
+#define QAM_FQ_TAP_IM_EL1__W                                                12
+#define QAM_FQ_TAP_IM_EL1__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL1__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL1_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL1_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL1_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL1_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL2__A                                                0x1420024
+#define QAM_FQ_TAP_RE_EL2__W                                                12
+#define QAM_FQ_TAP_RE_EL2__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL2__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL2_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL2_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL2_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL2_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL2__A                                                0x1420025
+#define QAM_FQ_TAP_IM_EL2__W                                                12
+#define QAM_FQ_TAP_IM_EL2__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL2__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL2_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL2_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL2_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL2_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL3__A                                                0x1420026
+#define QAM_FQ_TAP_RE_EL3__W                                                12
+#define QAM_FQ_TAP_RE_EL3__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL3__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL3_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL3_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL3_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL3_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL3__A                                                0x1420027
+#define QAM_FQ_TAP_IM_EL3__W                                                12
+#define QAM_FQ_TAP_IM_EL3__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL3__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL3_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL3_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL3_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL3_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL4__A                                                0x1420028
+#define QAM_FQ_TAP_RE_EL4__W                                                12
+#define QAM_FQ_TAP_RE_EL4__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL4__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL4_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL4_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL4_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL4_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL4__A                                                0x1420029
+#define QAM_FQ_TAP_IM_EL4__W                                                12
+#define QAM_FQ_TAP_IM_EL4__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL4__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL4_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL4_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL4_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL4_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL5__A                                                0x142002A
+#define QAM_FQ_TAP_RE_EL5__W                                                12
+#define QAM_FQ_TAP_RE_EL5__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL5__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL5_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL5_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL5_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL5_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL5__A                                                0x142002B
+#define QAM_FQ_TAP_IM_EL5__W                                                12
+#define QAM_FQ_TAP_IM_EL5__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL5__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL5_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL5_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL5_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL5_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL6__A                                                0x142002C
+#define QAM_FQ_TAP_RE_EL6__W                                                12
+#define QAM_FQ_TAP_RE_EL6__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL6__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL6_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL6_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL6_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL6_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL6__A                                                0x142002D
+#define QAM_FQ_TAP_IM_EL6__W                                                12
+#define QAM_FQ_TAP_IM_EL6__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL6__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL6_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL6_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL6_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL6_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL7__A                                                0x142002E
+#define QAM_FQ_TAP_RE_EL7__W                                                12
+#define QAM_FQ_TAP_RE_EL7__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL7__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL7_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL7_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL7_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL7_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL7__A                                                0x142002F
+#define QAM_FQ_TAP_IM_EL7__W                                                12
+#define QAM_FQ_TAP_IM_EL7__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL7__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL7_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL7_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL7_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL7_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL8__A                                                0x1420030
+#define QAM_FQ_TAP_RE_EL8__W                                                12
+#define QAM_FQ_TAP_RE_EL8__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL8__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL8_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL8_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL8_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL8_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL8__A                                                0x1420031
+#define QAM_FQ_TAP_IM_EL8__W                                                12
+#define QAM_FQ_TAP_IM_EL8__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL8__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL8_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL8_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL8_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL8_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL9__A                                                0x1420032
+#define QAM_FQ_TAP_RE_EL9__W                                                12
+#define QAM_FQ_TAP_RE_EL9__M                                                0xFFF
+#define QAM_FQ_TAP_RE_EL9__PRE                                              0x2
+
+#define   QAM_FQ_TAP_RE_EL9_TAP__B                                          0
+#define   QAM_FQ_TAP_RE_EL9_TAP__W                                          12
+#define   QAM_FQ_TAP_RE_EL9_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_RE_EL9_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_IM_EL9__A                                                0x1420033
+#define QAM_FQ_TAP_IM_EL9__W                                                12
+#define QAM_FQ_TAP_IM_EL9__M                                                0xFFF
+#define QAM_FQ_TAP_IM_EL9__PRE                                              0x2
+
+#define   QAM_FQ_TAP_IM_EL9_TAP__B                                          0
+#define   QAM_FQ_TAP_IM_EL9_TAP__W                                          12
+#define   QAM_FQ_TAP_IM_EL9_TAP__M                                          0xFFF
+#define   QAM_FQ_TAP_IM_EL9_TAP__PRE                                        0x2
+
+#define QAM_FQ_TAP_RE_EL10__A                                               0x1420034
+#define QAM_FQ_TAP_RE_EL10__W                                               12
+#define QAM_FQ_TAP_RE_EL10__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL10__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL10_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL10_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL10_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL10_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL10__A                                               0x1420035
+#define QAM_FQ_TAP_IM_EL10__W                                               12
+#define QAM_FQ_TAP_IM_EL10__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL10__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL10_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL10_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL10_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL10_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL11__A                                               0x1420036
+#define QAM_FQ_TAP_RE_EL11__W                                               12
+#define QAM_FQ_TAP_RE_EL11__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL11__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL11_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL11_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL11_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL11_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL11__A                                               0x1420037
+#define QAM_FQ_TAP_IM_EL11__W                                               12
+#define QAM_FQ_TAP_IM_EL11__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL11__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL11_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL11_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL11_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL11_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL12__A                                               0x1420038
+#define QAM_FQ_TAP_RE_EL12__W                                               12
+#define QAM_FQ_TAP_RE_EL12__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL12__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL12_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL12_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL12_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL12_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL12__A                                               0x1420039
+#define QAM_FQ_TAP_IM_EL12__W                                               12
+#define QAM_FQ_TAP_IM_EL12__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL12__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL12_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL12_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL12_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL12_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL13__A                                               0x142003A
+#define QAM_FQ_TAP_RE_EL13__W                                               12
+#define QAM_FQ_TAP_RE_EL13__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL13__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL13_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL13_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL13_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL13_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL13__A                                               0x142003B
+#define QAM_FQ_TAP_IM_EL13__W                                               12
+#define QAM_FQ_TAP_IM_EL13__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL13__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL13_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL13_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL13_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL13_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL14__A                                               0x142003C
+#define QAM_FQ_TAP_RE_EL14__W                                               12
+#define QAM_FQ_TAP_RE_EL14__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL14__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL14_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL14_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL14_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL14_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL14__A                                               0x142003D
+#define QAM_FQ_TAP_IM_EL14__W                                               12
+#define QAM_FQ_TAP_IM_EL14__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL14__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL14_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL14_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL14_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL14_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL15__A                                               0x142003E
+#define QAM_FQ_TAP_RE_EL15__W                                               12
+#define QAM_FQ_TAP_RE_EL15__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL15__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL15_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL15_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL15_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL15_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL15__A                                               0x142003F
+#define QAM_FQ_TAP_IM_EL15__W                                               12
+#define QAM_FQ_TAP_IM_EL15__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL15__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL15_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL15_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL15_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL15_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL16__A                                               0x1420040
+#define QAM_FQ_TAP_RE_EL16__W                                               12
+#define QAM_FQ_TAP_RE_EL16__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL16__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL16_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL16_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL16_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL16_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL16__A                                               0x1420041
+#define QAM_FQ_TAP_IM_EL16__W                                               12
+#define QAM_FQ_TAP_IM_EL16__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL16__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL16_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL16_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL16_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL16_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL17__A                                               0x1420042
+#define QAM_FQ_TAP_RE_EL17__W                                               12
+#define QAM_FQ_TAP_RE_EL17__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL17__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL17_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL17_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL17_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL17_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL17__A                                               0x1420043
+#define QAM_FQ_TAP_IM_EL17__W                                               12
+#define QAM_FQ_TAP_IM_EL17__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL17__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL17_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL17_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL17_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL17_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL18__A                                               0x1420044
+#define QAM_FQ_TAP_RE_EL18__W                                               12
+#define QAM_FQ_TAP_RE_EL18__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL18__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL18_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL18_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL18_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL18_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL18__A                                               0x1420045
+#define QAM_FQ_TAP_IM_EL18__W                                               12
+#define QAM_FQ_TAP_IM_EL18__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL18__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL18_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL18_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL18_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL18_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL19__A                                               0x1420046
+#define QAM_FQ_TAP_RE_EL19__W                                               12
+#define QAM_FQ_TAP_RE_EL19__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL19__PRE                                             0x600
+
+#define   QAM_FQ_TAP_RE_EL19_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL19_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL19_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL19_TAP__PRE                                       0x600
+
+#define QAM_FQ_TAP_IM_EL19__A                                               0x1420047
+#define QAM_FQ_TAP_IM_EL19__W                                               12
+#define QAM_FQ_TAP_IM_EL19__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL19__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL19_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL19_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL19_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL19_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL20__A                                               0x1420048
+#define QAM_FQ_TAP_RE_EL20__W                                               12
+#define QAM_FQ_TAP_RE_EL20__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL20__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL20_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL20_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL20_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL20_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL20__A                                               0x1420049
+#define QAM_FQ_TAP_IM_EL20__W                                               12
+#define QAM_FQ_TAP_IM_EL20__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL20__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL20_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL20_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL20_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL20_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL21__A                                               0x142004A
+#define QAM_FQ_TAP_RE_EL21__W                                               12
+#define QAM_FQ_TAP_RE_EL21__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL21__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL21_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL21_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL21_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL21_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL21__A                                               0x142004B
+#define QAM_FQ_TAP_IM_EL21__W                                               12
+#define QAM_FQ_TAP_IM_EL21__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL21__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL21_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL21_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL21_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL21_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL22__A                                               0x142004C
+#define QAM_FQ_TAP_RE_EL22__W                                               12
+#define QAM_FQ_TAP_RE_EL22__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL22__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL22_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL22_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL22_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL22_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL22__A                                               0x142004D
+#define QAM_FQ_TAP_IM_EL22__W                                               12
+#define QAM_FQ_TAP_IM_EL22__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL22__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL22_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL22_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL22_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL22_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_RE_EL23__A                                               0x142004E
+#define QAM_FQ_TAP_RE_EL23__W                                               12
+#define QAM_FQ_TAP_RE_EL23__M                                               0xFFF
+#define QAM_FQ_TAP_RE_EL23__PRE                                             0x2
+
+#define   QAM_FQ_TAP_RE_EL23_TAP__B                                         0
+#define   QAM_FQ_TAP_RE_EL23_TAP__W                                         12
+#define   QAM_FQ_TAP_RE_EL23_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_RE_EL23_TAP__PRE                                       0x2
+
+#define QAM_FQ_TAP_IM_EL23__A                                               0x142004F
+#define QAM_FQ_TAP_IM_EL23__W                                               12
+#define QAM_FQ_TAP_IM_EL23__M                                               0xFFF
+#define QAM_FQ_TAP_IM_EL23__PRE                                             0x2
+
+#define   QAM_FQ_TAP_IM_EL23_TAP__B                                         0
+#define   QAM_FQ_TAP_IM_EL23_TAP__W                                         12
+#define   QAM_FQ_TAP_IM_EL23_TAP__M                                         0xFFF
+#define   QAM_FQ_TAP_IM_EL23_TAP__PRE                                       0x2
+
+#define QAM_SL_COMM_EXEC__A                                                 0x1430000
+#define QAM_SL_COMM_EXEC__W                                                 2
+#define QAM_SL_COMM_EXEC__M                                                 0x3
+#define QAM_SL_COMM_EXEC__PRE                                               0x0
+#define   QAM_SL_COMM_EXEC_STOP                                             0x0
+#define   QAM_SL_COMM_EXEC_ACTIVE                                           0x1
+#define   QAM_SL_COMM_EXEC_HOLD                                             0x2
+
+#define QAM_SL_COMM_MB__A                                                   0x1430002
+#define QAM_SL_COMM_MB__W                                                   4
+#define QAM_SL_COMM_MB__M                                                   0xF
+#define QAM_SL_COMM_MB__PRE                                                 0x0
+#define   QAM_SL_COMM_MB_CTL__B                                             0
+#define   QAM_SL_COMM_MB_CTL__W                                             1
+#define   QAM_SL_COMM_MB_CTL__M                                             0x1
+#define   QAM_SL_COMM_MB_CTL__PRE                                           0x0
+#define     QAM_SL_COMM_MB_CTL_OFF                                          0x0
+#define     QAM_SL_COMM_MB_CTL_ON                                           0x1
+#define   QAM_SL_COMM_MB_OBS__B                                             1
+#define   QAM_SL_COMM_MB_OBS__W                                             1
+#define   QAM_SL_COMM_MB_OBS__M                                             0x2
+#define   QAM_SL_COMM_MB_OBS__PRE                                           0x0
+#define     QAM_SL_COMM_MB_OBS_OFF                                          0x0
+#define     QAM_SL_COMM_MB_OBS_ON                                           0x2
+#define   QAM_SL_COMM_MB_MUX_OBS__B                                         2
+#define   QAM_SL_COMM_MB_MUX_OBS__W                                         2
+#define   QAM_SL_COMM_MB_MUX_OBS__M                                         0xC
+#define   QAM_SL_COMM_MB_MUX_OBS__PRE                                       0x0
+#define     QAM_SL_COMM_MB_MUX_OBS_CONST_CORR                               0x0
+#define     QAM_SL_COMM_MB_MUX_OBS_CONST2LC_O                               0x4
+#define     QAM_SL_COMM_MB_MUX_OBS_CONST2DQ_O                               0x8
+#define     QAM_SL_COMM_MB_MUX_OBS_VDEC_O                                   0xC
+
+#define QAM_SL_COMM_INT_REQ__A                                              0x1430003
+#define QAM_SL_COMM_INT_REQ__W                                              1
+#define QAM_SL_COMM_INT_REQ__M                                              0x1
+#define QAM_SL_COMM_INT_REQ__PRE                                            0x0
+#define QAM_SL_COMM_INT_STA__A                                              0x1430005
+#define QAM_SL_COMM_INT_STA__W                                              2
+#define QAM_SL_COMM_INT_STA__M                                              0x3
+#define QAM_SL_COMM_INT_STA__PRE                                            0x0
+
+#define   QAM_SL_COMM_INT_STA_MED_ERR_INT__B                                0
+#define   QAM_SL_COMM_INT_STA_MED_ERR_INT__W                                1
+#define   QAM_SL_COMM_INT_STA_MED_ERR_INT__M                                0x1
+#define   QAM_SL_COMM_INT_STA_MED_ERR_INT__PRE                              0x0
+
+#define   QAM_SL_COMM_INT_STA_MER_INT__B                                    1
+#define   QAM_SL_COMM_INT_STA_MER_INT__W                                    1
+#define   QAM_SL_COMM_INT_STA_MER_INT__M                                    0x2
+#define   QAM_SL_COMM_INT_STA_MER_INT__PRE                                  0x0
+
+#define QAM_SL_COMM_INT_MSK__A                                              0x1430006
+#define QAM_SL_COMM_INT_MSK__W                                              2
+#define QAM_SL_COMM_INT_MSK__M                                              0x3
+#define QAM_SL_COMM_INT_MSK__PRE                                            0x0
+#define   QAM_SL_COMM_INT_MSK_MED_ERR_MSK__B                                0
+#define   QAM_SL_COMM_INT_MSK_MED_ERR_MSK__W                                1
+#define   QAM_SL_COMM_INT_MSK_MED_ERR_MSK__M                                0x1
+#define   QAM_SL_COMM_INT_MSK_MED_ERR_MSK__PRE                              0x0
+#define   QAM_SL_COMM_INT_MSK_MER_MSK__B                                    1
+#define   QAM_SL_COMM_INT_MSK_MER_MSK__W                                    1
+#define   QAM_SL_COMM_INT_MSK_MER_MSK__M                                    0x2
+#define   QAM_SL_COMM_INT_MSK_MER_MSK__PRE                                  0x0
+
+#define QAM_SL_COMM_INT_STM__A                                              0x1430007
+#define QAM_SL_COMM_INT_STM__W                                              2
+#define QAM_SL_COMM_INT_STM__M                                              0x3
+#define QAM_SL_COMM_INT_STM__PRE                                            0x0
+#define   QAM_SL_COMM_INT_STM_MED_ERR_STM__B                                0
+#define   QAM_SL_COMM_INT_STM_MED_ERR_STM__W                                1
+#define   QAM_SL_COMM_INT_STM_MED_ERR_STM__M                                0x1
+#define   QAM_SL_COMM_INT_STM_MED_ERR_STM__PRE                              0x0
+#define   QAM_SL_COMM_INT_STM_MER_STM__B                                    1
+#define   QAM_SL_COMM_INT_STM_MER_STM__W                                    1
+#define   QAM_SL_COMM_INT_STM_MER_STM__M                                    0x2
+#define   QAM_SL_COMM_INT_STM_MER_STM__PRE                                  0x0
+
+#define QAM_SL_MODE__A                                                      0x1430010
+#define QAM_SL_MODE__W                                                      11
+#define QAM_SL_MODE__M                                                      0x7FF
+#define QAM_SL_MODE__PRE                                                    0x0
+
+#define   QAM_SL_MODE_SLICER4LC__B                                          0
+#define   QAM_SL_MODE_SLICER4LC__W                                          2
+#define   QAM_SL_MODE_SLICER4LC__M                                          0x3
+#define   QAM_SL_MODE_SLICER4LC__PRE                                        0x0
+#define     QAM_SL_MODE_SLICER4LC_RECT                                      0x0
+#define     QAM_SL_MODE_SLICER4LC_ONET                                      0x1
+#define     QAM_SL_MODE_SLICER4LC_RAD                                       0x2
+
+#define   QAM_SL_MODE_SLICER4DQ__B                                          2
+#define   QAM_SL_MODE_SLICER4DQ__W                                          2
+#define   QAM_SL_MODE_SLICER4DQ__M                                          0xC
+#define   QAM_SL_MODE_SLICER4DQ__PRE                                        0x0
+#define     QAM_SL_MODE_SLICER4DQ_RECT                                      0x0
+#define     QAM_SL_MODE_SLICER4DQ_ONET                                      0x4
+#define     QAM_SL_MODE_SLICER4DQ_RAD                                       0x8
+
+#define   QAM_SL_MODE_SLICER4VD__B                                          4
+#define   QAM_SL_MODE_SLICER4VD__W                                          2
+#define   QAM_SL_MODE_SLICER4VD__M                                          0x30
+#define   QAM_SL_MODE_SLICER4VD__PRE                                        0x0
+#define     QAM_SL_MODE_SLICER4VD_RECT                                      0x0
+#define     QAM_SL_MODE_SLICER4VD_ONET                                      0x10
+#define     QAM_SL_MODE_SLICER4VD_RAD                                       0x20
+
+#define   QAM_SL_MODE_ROT_DIS__B                                            6
+#define   QAM_SL_MODE_ROT_DIS__W                                            1
+#define   QAM_SL_MODE_ROT_DIS__M                                            0x40
+#define   QAM_SL_MODE_ROT_DIS__PRE                                          0x0
+
+#define   QAM_SL_MODE_DQROT_DIS__B                                          7
+#define   QAM_SL_MODE_DQROT_DIS__W                                          1
+#define   QAM_SL_MODE_DQROT_DIS__M                                          0x80
+#define   QAM_SL_MODE_DQROT_DIS__PRE                                        0x0
+
+#define   QAM_SL_MODE_DFE_DIS__B                                            8
+#define   QAM_SL_MODE_DFE_DIS__W                                            1
+#define   QAM_SL_MODE_DFE_DIS__M                                            0x100
+#define   QAM_SL_MODE_DFE_DIS__PRE                                          0x0
+
+#define   QAM_SL_MODE_RADIUS_MIX__B                                         9
+#define   QAM_SL_MODE_RADIUS_MIX__W                                         1
+#define   QAM_SL_MODE_RADIUS_MIX__M                                         0x200
+#define   QAM_SL_MODE_RADIUS_MIX__PRE                                       0x0
+
+#define   QAM_SL_MODE_TILT_COMP__B                                          10
+#define   QAM_SL_MODE_TILT_COMP__W                                          1
+#define   QAM_SL_MODE_TILT_COMP__M                                          0x400
+#define   QAM_SL_MODE_TILT_COMP__PRE                                        0x0
+
+#define QAM_SL_K_FACTOR__A                                                  0x1430011
+#define QAM_SL_K_FACTOR__W                                                  4
+#define QAM_SL_K_FACTOR__M                                                  0xF
+#define QAM_SL_K_FACTOR__PRE                                                0x0
+#define QAM_SL_MEDIAN__A                                                    0x1430012
+#define QAM_SL_MEDIAN__W                                                    14
+#define QAM_SL_MEDIAN__M                                                    0x3FFF
+#define QAM_SL_MEDIAN__PRE                                                  0x0
+
+#define   QAM_SL_MEDIAN_LENGTH__B                                           0
+#define   QAM_SL_MEDIAN_LENGTH__W                                           2
+#define   QAM_SL_MEDIAN_LENGTH__M                                           0x3
+#define   QAM_SL_MEDIAN_LENGTH__PRE                                         0x0
+
+#define   QAM_SL_MEDIAN_CORRECT__B                                          2
+#define   QAM_SL_MEDIAN_CORRECT__W                                          4
+#define   QAM_SL_MEDIAN_CORRECT__M                                          0x3C
+#define   QAM_SL_MEDIAN_CORRECT__PRE                                        0x0
+
+#define   QAM_SL_MEDIAN_TOLERANCE__B                                        6
+#define   QAM_SL_MEDIAN_TOLERANCE__W                                        7
+#define   QAM_SL_MEDIAN_TOLERANCE__M                                        0x1FC0
+#define   QAM_SL_MEDIAN_TOLERANCE__PRE                                      0x0
+
+#define   QAM_SL_MEDIAN_FAST__B                                             13
+#define   QAM_SL_MEDIAN_FAST__W                                             1
+#define   QAM_SL_MEDIAN_FAST__M                                             0x2000
+#define   QAM_SL_MEDIAN_FAST__PRE                                           0x0
+
+#define QAM_SL_ALPHA__A                                                     0x1430013
+#define QAM_SL_ALPHA__W                                                     3
+#define QAM_SL_ALPHA__M                                                     0x7
+#define QAM_SL_ALPHA__PRE                                                   0x0
+
+#define QAM_SL_PHASELIMIT__A                                                0x1430014
+#define QAM_SL_PHASELIMIT__W                                                9
+#define QAM_SL_PHASELIMIT__M                                                0x1FF
+#define QAM_SL_PHASELIMIT__PRE                                              0x0
+#define QAM_SL_MTA_LENGTH__A                                                0x1430015
+#define QAM_SL_MTA_LENGTH__W                                                2
+#define QAM_SL_MTA_LENGTH__M                                                0x3
+#define QAM_SL_MTA_LENGTH__PRE                                              0x1
+
+#define   QAM_SL_MTA_LENGTH_LENGTH__B                                       0
+#define   QAM_SL_MTA_LENGTH_LENGTH__W                                       2
+#define   QAM_SL_MTA_LENGTH_LENGTH__M                                       0x3
+#define   QAM_SL_MTA_LENGTH_LENGTH__PRE                                     0x1
+
+#define QAM_SL_MEDIAN_ERROR__A                                              0x1430016
+#define QAM_SL_MEDIAN_ERROR__W                                              10
+#define QAM_SL_MEDIAN_ERROR__M                                              0x3FF
+#define QAM_SL_MEDIAN_ERROR__PRE                                            0x0
+
+#define   QAM_SL_MEDIAN_ERROR_MEDIAN_ERR__B                                 0
+#define   QAM_SL_MEDIAN_ERROR_MEDIAN_ERR__W                                 10
+#define   QAM_SL_MEDIAN_ERROR_MEDIAN_ERR__M                                 0x3FF
+#define   QAM_SL_MEDIAN_ERROR_MEDIAN_ERR__PRE                               0x0
+
+#define QAM_SL_ERR_POWER__A                                                 0x1430017
+#define QAM_SL_ERR_POWER__W                                                 16
+#define QAM_SL_ERR_POWER__M                                                 0xFFFF
+#define QAM_SL_ERR_POWER__PRE                                               0x0
+
+#define QAM_DQ_COMM_EXEC__A                                                 0x1440000
+#define QAM_DQ_COMM_EXEC__W                                                 2
+#define QAM_DQ_COMM_EXEC__M                                                 0x3
+#define QAM_DQ_COMM_EXEC__PRE                                               0x0
+#define   QAM_DQ_COMM_EXEC_STOP                                             0x0
+#define   QAM_DQ_COMM_EXEC_ACTIVE                                           0x1
+#define   QAM_DQ_COMM_EXEC_HOLD                                             0x2
+
+#define QAM_DQ_MODE__A                                                      0x1440010
+#define QAM_DQ_MODE__W                                                      5
+#define QAM_DQ_MODE__M                                                      0x1F
+#define QAM_DQ_MODE__PRE                                                    0x0
+
+#define   QAM_DQ_MODE_TAPRESET__B                                           0
+#define   QAM_DQ_MODE_TAPRESET__W                                           1
+#define   QAM_DQ_MODE_TAPRESET__M                                           0x1
+#define   QAM_DQ_MODE_TAPRESET__PRE                                         0x0
+#define     QAM_DQ_MODE_TAPRESET_RST                                        0x1
+
+#define   QAM_DQ_MODE_TAPLMS__B                                             1
+#define   QAM_DQ_MODE_TAPLMS__W                                             1
+#define   QAM_DQ_MODE_TAPLMS__M                                             0x2
+#define   QAM_DQ_MODE_TAPLMS__PRE                                           0x0
+#define     QAM_DQ_MODE_TAPLMS_UPD                                          0x2
+
+#define   QAM_DQ_MODE_TAPDRAIN__B                                           2
+#define   QAM_DQ_MODE_TAPDRAIN__W                                           1
+#define   QAM_DQ_MODE_TAPDRAIN__M                                           0x4
+#define   QAM_DQ_MODE_TAPDRAIN__PRE                                         0x0
+#define     QAM_DQ_MODE_TAPDRAIN_DRAIN                                      0x4
+
+#define   QAM_DQ_MODE_FB__B                                                 3
+#define   QAM_DQ_MODE_FB__W                                                 2
+#define   QAM_DQ_MODE_FB__M                                                 0x18
+#define   QAM_DQ_MODE_FB__PRE                                               0x0
+#define     QAM_DQ_MODE_FB_CMA                                              0x0
+#define     QAM_DQ_MODE_FB_RADIUS                                           0x8
+#define     QAM_DQ_MODE_FB_DFB                                              0x10
+#define     QAM_DQ_MODE_FB_TRELLIS                                          0x18
+
+#define QAM_DQ_MU_FACTOR__A                                                 0x1440011
+#define QAM_DQ_MU_FACTOR__W                                                 3
+#define QAM_DQ_MU_FACTOR__M                                                 0x7
+#define QAM_DQ_MU_FACTOR__PRE                                               0x0
+
+#define QAM_DQ_LA_FACTOR__A                                                 0x1440012
+#define QAM_DQ_LA_FACTOR__W                                                 4
+#define QAM_DQ_LA_FACTOR__M                                                 0xF
+#define QAM_DQ_LA_FACTOR__PRE                                               0xC
+
+#define QAM_DQ_CMA_RATIO__A                                                 0x1440013
+#define QAM_DQ_CMA_RATIO__W                                                 14
+#define QAM_DQ_CMA_RATIO__M                                                 0x3FFF
+#define QAM_DQ_CMA_RATIO__PRE                                               0x3CF9
+#define   QAM_DQ_CMA_RATIO_QPSK                                             0x2000
+#define   QAM_DQ_CMA_RATIO_QAM16                                            0x34CD
+#define   QAM_DQ_CMA_RATIO_QAM64                                            0x3A00
+#define   QAM_DQ_CMA_RATIO_QAM256                                           0x3B4D
+#define   QAM_DQ_CMA_RATIO_QAM1024                                          0x3BA0
+
+#define QAM_DQ_QUAL_RADSEL__A                                               0x1440014
+#define QAM_DQ_QUAL_RADSEL__W                                               3
+#define QAM_DQ_QUAL_RADSEL__M                                               0x7
+#define QAM_DQ_QUAL_RADSEL__PRE                                             0x0
+
+#define   QAM_DQ_QUAL_RADSEL_BIT__B                                         0
+#define   QAM_DQ_QUAL_RADSEL_BIT__W                                         3
+#define   QAM_DQ_QUAL_RADSEL_BIT__M                                         0x7
+#define   QAM_DQ_QUAL_RADSEL_BIT__PRE                                       0x0
+#define     QAM_DQ_QUAL_RADSEL_BIT_PURE_RADIUS                              0x0
+#define     QAM_DQ_QUAL_RADSEL_BIT_PURE_CMA                                 0x6
+
+#define QAM_DQ_QUAL_ENA__A                                                  0x1440015
+#define QAM_DQ_QUAL_ENA__W                                                  1
+#define QAM_DQ_QUAL_ENA__M                                                  0x1
+#define QAM_DQ_QUAL_ENA__PRE                                                0x0
+
+#define   QAM_DQ_QUAL_ENA_ENA__B                                            0
+#define   QAM_DQ_QUAL_ENA_ENA__W                                            1
+#define   QAM_DQ_QUAL_ENA_ENA__M                                            0x1
+#define   QAM_DQ_QUAL_ENA_ENA__PRE                                          0x0
+#define     QAM_DQ_QUAL_ENA_ENA_QUAL_WEIGHTING                              0x1
+
+#define QAM_DQ_QUAL_FUN0__A                                                 0x1440018
+#define QAM_DQ_QUAL_FUN0__W                                                 6
+#define QAM_DQ_QUAL_FUN0__M                                                 0x3F
+#define QAM_DQ_QUAL_FUN0__PRE                                               0x4
+
+#define   QAM_DQ_QUAL_FUN0_BIT__B                                           0
+#define   QAM_DQ_QUAL_FUN0_BIT__W                                           6
+#define   QAM_DQ_QUAL_FUN0_BIT__M                                           0x3F
+#define   QAM_DQ_QUAL_FUN0_BIT__PRE                                         0x4
+
+#define QAM_DQ_QUAL_FUN1__A                                                 0x1440019
+#define QAM_DQ_QUAL_FUN1__W                                                 6
+#define QAM_DQ_QUAL_FUN1__M                                                 0x3F
+#define QAM_DQ_QUAL_FUN1__PRE                                               0x4
+
+#define   QAM_DQ_QUAL_FUN1_BIT__B                                           0
+#define   QAM_DQ_QUAL_FUN1_BIT__W                                           6
+#define   QAM_DQ_QUAL_FUN1_BIT__M                                           0x3F
+#define   QAM_DQ_QUAL_FUN1_BIT__PRE                                         0x4
+
+#define QAM_DQ_QUAL_FUN2__A                                                 0x144001A
+#define QAM_DQ_QUAL_FUN2__W                                                 6
+#define QAM_DQ_QUAL_FUN2__M                                                 0x3F
+#define QAM_DQ_QUAL_FUN2__PRE                                               0x4
+
+#define   QAM_DQ_QUAL_FUN2_BIT__B                                           0
+#define   QAM_DQ_QUAL_FUN2_BIT__W                                           6
+#define   QAM_DQ_QUAL_FUN2_BIT__M                                           0x3F
+#define   QAM_DQ_QUAL_FUN2_BIT__PRE                                         0x4
+
+#define QAM_DQ_QUAL_FUN3__A                                                 0x144001B
+#define QAM_DQ_QUAL_FUN3__W                                                 6
+#define QAM_DQ_QUAL_FUN3__M                                                 0x3F
+#define QAM_DQ_QUAL_FUN3__PRE                                               0x4
+
+#define   QAM_DQ_QUAL_FUN3_BIT__B                                           0
+#define   QAM_DQ_QUAL_FUN3_BIT__W                                           6
+#define   QAM_DQ_QUAL_FUN3_BIT__M                                           0x3F
+#define   QAM_DQ_QUAL_FUN3_BIT__PRE                                         0x4
+
+#define QAM_DQ_QUAL_FUN4__A                                                 0x144001C
+#define QAM_DQ_QUAL_FUN4__W                                                 6
+#define QAM_DQ_QUAL_FUN4__M                                                 0x3F
+#define QAM_DQ_QUAL_FUN4__PRE                                               0x6
+
+#define   QAM_DQ_QUAL_FUN4_BIT__B                                           0
+#define   QAM_DQ_QUAL_FUN4_BIT__W                                           6
+#define   QAM_DQ_QUAL_FUN4_BIT__M                                           0x3F
+#define   QAM_DQ_QUAL_FUN4_BIT__PRE                                         0x6
+
+#define QAM_DQ_QUAL_FUN5__A                                                 0x144001D
+#define QAM_DQ_QUAL_FUN5__W                                                 6
+#define QAM_DQ_QUAL_FUN5__M                                                 0x3F
+#define QAM_DQ_QUAL_FUN5__PRE                                               0x6
+
+#define   QAM_DQ_QUAL_FUN5_BIT__B                                           0
+#define   QAM_DQ_QUAL_FUN5_BIT__W                                           6
+#define   QAM_DQ_QUAL_FUN5_BIT__M                                           0x3F
+#define   QAM_DQ_QUAL_FUN5_BIT__PRE                                         0x6
+
+#define QAM_DQ_RAW_LIM__A                                                   0x144001E
+#define QAM_DQ_RAW_LIM__W                                                   5
+#define QAM_DQ_RAW_LIM__M                                                   0x1F
+#define QAM_DQ_RAW_LIM__PRE                                                 0x1F
+
+#define   QAM_DQ_RAW_LIM_BIT__B                                             0
+#define   QAM_DQ_RAW_LIM_BIT__W                                             5
+#define   QAM_DQ_RAW_LIM_BIT__M                                             0x1F
+#define   QAM_DQ_RAW_LIM_BIT__PRE                                           0x1F
+
+#define QAM_DQ_TAP_RE_EL0__A                                                0x1440020
+#define QAM_DQ_TAP_RE_EL0__W                                                12
+#define QAM_DQ_TAP_RE_EL0__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL0__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL0_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL0_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL0_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL0_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL0__A                                                0x1440021
+#define QAM_DQ_TAP_IM_EL0__W                                                12
+#define QAM_DQ_TAP_IM_EL0__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL0__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL0_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL0_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL0_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL0_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL1__A                                                0x1440022
+#define QAM_DQ_TAP_RE_EL1__W                                                12
+#define QAM_DQ_TAP_RE_EL1__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL1__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL1_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL1_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL1_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL1_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL1__A                                                0x1440023
+#define QAM_DQ_TAP_IM_EL1__W                                                12
+#define QAM_DQ_TAP_IM_EL1__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL1__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL1_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL1_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL1_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL1_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL2__A                                                0x1440024
+#define QAM_DQ_TAP_RE_EL2__W                                                12
+#define QAM_DQ_TAP_RE_EL2__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL2__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL2_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL2_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL2_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL2_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL2__A                                                0x1440025
+#define QAM_DQ_TAP_IM_EL2__W                                                12
+#define QAM_DQ_TAP_IM_EL2__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL2__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL2_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL2_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL2_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL2_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL3__A                                                0x1440026
+#define QAM_DQ_TAP_RE_EL3__W                                                12
+#define QAM_DQ_TAP_RE_EL3__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL3__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL3_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL3_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL3_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL3_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL3__A                                                0x1440027
+#define QAM_DQ_TAP_IM_EL3__W                                                12
+#define QAM_DQ_TAP_IM_EL3__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL3__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL3_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL3_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL3_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL3_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL4__A                                                0x1440028
+#define QAM_DQ_TAP_RE_EL4__W                                                12
+#define QAM_DQ_TAP_RE_EL4__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL4__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL4_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL4_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL4_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL4_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL4__A                                                0x1440029
+#define QAM_DQ_TAP_IM_EL4__W                                                12
+#define QAM_DQ_TAP_IM_EL4__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL4__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL4_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL4_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL4_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL4_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL5__A                                                0x144002A
+#define QAM_DQ_TAP_RE_EL5__W                                                12
+#define QAM_DQ_TAP_RE_EL5__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL5__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL5_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL5_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL5_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL5_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL5__A                                                0x144002B
+#define QAM_DQ_TAP_IM_EL5__W                                                12
+#define QAM_DQ_TAP_IM_EL5__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL5__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL5_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL5_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL5_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL5_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL6__A                                                0x144002C
+#define QAM_DQ_TAP_RE_EL6__W                                                12
+#define QAM_DQ_TAP_RE_EL6__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL6__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL6_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL6_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL6_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL6_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL6__A                                                0x144002D
+#define QAM_DQ_TAP_IM_EL6__W                                                12
+#define QAM_DQ_TAP_IM_EL6__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL6__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL6_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL6_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL6_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL6_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL7__A                                                0x144002E
+#define QAM_DQ_TAP_RE_EL7__W                                                12
+#define QAM_DQ_TAP_RE_EL7__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL7__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL7_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL7_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL7_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL7_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL7__A                                                0x144002F
+#define QAM_DQ_TAP_IM_EL7__W                                                12
+#define QAM_DQ_TAP_IM_EL7__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL7__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL7_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL7_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL7_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL7_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL8__A                                                0x1440030
+#define QAM_DQ_TAP_RE_EL8__W                                                12
+#define QAM_DQ_TAP_RE_EL8__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL8__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL8_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL8_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL8_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL8_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL8__A                                                0x1440031
+#define QAM_DQ_TAP_IM_EL8__W                                                12
+#define QAM_DQ_TAP_IM_EL8__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL8__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL8_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL8_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL8_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL8_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL9__A                                                0x1440032
+#define QAM_DQ_TAP_RE_EL9__W                                                12
+#define QAM_DQ_TAP_RE_EL9__M                                                0xFFF
+#define QAM_DQ_TAP_RE_EL9__PRE                                              0x2
+
+#define   QAM_DQ_TAP_RE_EL9_TAP__B                                          0
+#define   QAM_DQ_TAP_RE_EL9_TAP__W                                          12
+#define   QAM_DQ_TAP_RE_EL9_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_RE_EL9_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_IM_EL9__A                                                0x1440033
+#define QAM_DQ_TAP_IM_EL9__W                                                12
+#define QAM_DQ_TAP_IM_EL9__M                                                0xFFF
+#define QAM_DQ_TAP_IM_EL9__PRE                                              0x2
+
+#define   QAM_DQ_TAP_IM_EL9_TAP__B                                          0
+#define   QAM_DQ_TAP_IM_EL9_TAP__W                                          12
+#define   QAM_DQ_TAP_IM_EL9_TAP__M                                          0xFFF
+#define   QAM_DQ_TAP_IM_EL9_TAP__PRE                                        0x2
+
+#define QAM_DQ_TAP_RE_EL10__A                                               0x1440034
+#define QAM_DQ_TAP_RE_EL10__W                                               12
+#define QAM_DQ_TAP_RE_EL10__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL10__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL10_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL10_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL10_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL10_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL10__A                                               0x1440035
+#define QAM_DQ_TAP_IM_EL10__W                                               12
+#define QAM_DQ_TAP_IM_EL10__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL10__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL10_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL10_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL10_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL10_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL11__A                                               0x1440036
+#define QAM_DQ_TAP_RE_EL11__W                                               12
+#define QAM_DQ_TAP_RE_EL11__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL11__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL11_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL11_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL11_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL11_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL11__A                                               0x1440037
+#define QAM_DQ_TAP_IM_EL11__W                                               12
+#define QAM_DQ_TAP_IM_EL11__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL11__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL11_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL11_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL11_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL11_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL12__A                                               0x1440038
+#define QAM_DQ_TAP_RE_EL12__W                                               12
+#define QAM_DQ_TAP_RE_EL12__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL12__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL12_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL12_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL12_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL12_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL12__A                                               0x1440039
+#define QAM_DQ_TAP_IM_EL12__W                                               12
+#define QAM_DQ_TAP_IM_EL12__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL12__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL12_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL12_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL12_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL12_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL13__A                                               0x144003A
+#define QAM_DQ_TAP_RE_EL13__W                                               12
+#define QAM_DQ_TAP_RE_EL13__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL13__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL13_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL13_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL13_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL13_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL13__A                                               0x144003B
+#define QAM_DQ_TAP_IM_EL13__W                                               12
+#define QAM_DQ_TAP_IM_EL13__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL13__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL13_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL13_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL13_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL13_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL14__A                                               0x144003C
+#define QAM_DQ_TAP_RE_EL14__W                                               12
+#define QAM_DQ_TAP_RE_EL14__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL14__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL14_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL14_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL14_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL14_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL14__A                                               0x144003D
+#define QAM_DQ_TAP_IM_EL14__W                                               12
+#define QAM_DQ_TAP_IM_EL14__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL14__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL14_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL14_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL14_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL14_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL15__A                                               0x144003E
+#define QAM_DQ_TAP_RE_EL15__W                                               12
+#define QAM_DQ_TAP_RE_EL15__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL15__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL15_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL15_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL15_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL15_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL15__A                                               0x144003F
+#define QAM_DQ_TAP_IM_EL15__W                                               12
+#define QAM_DQ_TAP_IM_EL15__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL15__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL15_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL15_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL15_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL15_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL16__A                                               0x1440040
+#define QAM_DQ_TAP_RE_EL16__W                                               12
+#define QAM_DQ_TAP_RE_EL16__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL16__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL16_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL16_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL16_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL16_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL16__A                                               0x1440041
+#define QAM_DQ_TAP_IM_EL16__W                                               12
+#define QAM_DQ_TAP_IM_EL16__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL16__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL16_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL16_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL16_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL16_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL17__A                                               0x1440042
+#define QAM_DQ_TAP_RE_EL17__W                                               12
+#define QAM_DQ_TAP_RE_EL17__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL17__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL17_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL17_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL17_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL17_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL17__A                                               0x1440043
+#define QAM_DQ_TAP_IM_EL17__W                                               12
+#define QAM_DQ_TAP_IM_EL17__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL17__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL17_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL17_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL17_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL17_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL18__A                                               0x1440044
+#define QAM_DQ_TAP_RE_EL18__W                                               12
+#define QAM_DQ_TAP_RE_EL18__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL18__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL18_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL18_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL18_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL18_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL18__A                                               0x1440045
+#define QAM_DQ_TAP_IM_EL18__W                                               12
+#define QAM_DQ_TAP_IM_EL18__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL18__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL18_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL18_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL18_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL18_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL19__A                                               0x1440046
+#define QAM_DQ_TAP_RE_EL19__W                                               12
+#define QAM_DQ_TAP_RE_EL19__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL19__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL19_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL19_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL19_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL19_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL19__A                                               0x1440047
+#define QAM_DQ_TAP_IM_EL19__W                                               12
+#define QAM_DQ_TAP_IM_EL19__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL19__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL19_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL19_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL19_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL19_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL20__A                                               0x1440048
+#define QAM_DQ_TAP_RE_EL20__W                                               12
+#define QAM_DQ_TAP_RE_EL20__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL20__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL20_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL20_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL20_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL20_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL20__A                                               0x1440049
+#define QAM_DQ_TAP_IM_EL20__W                                               12
+#define QAM_DQ_TAP_IM_EL20__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL20__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL20_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL20_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL20_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL20_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL21__A                                               0x144004A
+#define QAM_DQ_TAP_RE_EL21__W                                               12
+#define QAM_DQ_TAP_RE_EL21__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL21__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL21_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL21_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL21_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL21_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL21__A                                               0x144004B
+#define QAM_DQ_TAP_IM_EL21__W                                               12
+#define QAM_DQ_TAP_IM_EL21__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL21__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL21_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL21_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL21_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL21_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL22__A                                               0x144004C
+#define QAM_DQ_TAP_RE_EL22__W                                               12
+#define QAM_DQ_TAP_RE_EL22__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL22__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL22_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL22_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL22_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL22_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL22__A                                               0x144004D
+#define QAM_DQ_TAP_IM_EL22__W                                               12
+#define QAM_DQ_TAP_IM_EL22__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL22__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL22_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL22_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL22_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL22_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL23__A                                               0x144004E
+#define QAM_DQ_TAP_RE_EL23__W                                               12
+#define QAM_DQ_TAP_RE_EL23__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL23__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL23_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL23_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL23_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL23_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL23__A                                               0x144004F
+#define QAM_DQ_TAP_IM_EL23__W                                               12
+#define QAM_DQ_TAP_IM_EL23__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL23__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL23_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL23_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL23_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL23_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL24__A                                               0x1440050
+#define QAM_DQ_TAP_RE_EL24__W                                               12
+#define QAM_DQ_TAP_RE_EL24__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL24__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL24_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL24_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL24_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL24_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL24__A                                               0x1440051
+#define QAM_DQ_TAP_IM_EL24__W                                               12
+#define QAM_DQ_TAP_IM_EL24__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL24__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL24_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL24_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL24_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL24_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL25__A                                               0x1440052
+#define QAM_DQ_TAP_RE_EL25__W                                               12
+#define QAM_DQ_TAP_RE_EL25__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL25__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL25_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL25_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL25_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL25_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL25__A                                               0x1440053
+#define QAM_DQ_TAP_IM_EL25__W                                               12
+#define QAM_DQ_TAP_IM_EL25__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL25__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL25_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL25_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL25_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL25_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL26__A                                               0x1440054
+#define QAM_DQ_TAP_RE_EL26__W                                               12
+#define QAM_DQ_TAP_RE_EL26__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL26__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL26_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL26_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL26_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL26_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL26__A                                               0x1440055
+#define QAM_DQ_TAP_IM_EL26__W                                               12
+#define QAM_DQ_TAP_IM_EL26__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL26__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL26_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL26_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL26_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL26_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_RE_EL27__A                                               0x1440056
+#define QAM_DQ_TAP_RE_EL27__W                                               12
+#define QAM_DQ_TAP_RE_EL27__M                                               0xFFF
+#define QAM_DQ_TAP_RE_EL27__PRE                                             0x2
+
+#define   QAM_DQ_TAP_RE_EL27_TAP__B                                         0
+#define   QAM_DQ_TAP_RE_EL27_TAP__W                                         12
+#define   QAM_DQ_TAP_RE_EL27_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_RE_EL27_TAP__PRE                                       0x2
+
+#define QAM_DQ_TAP_IM_EL27__A                                               0x1440057
+#define QAM_DQ_TAP_IM_EL27__W                                               12
+#define QAM_DQ_TAP_IM_EL27__M                                               0xFFF
+#define QAM_DQ_TAP_IM_EL27__PRE                                             0x2
+
+#define   QAM_DQ_TAP_IM_EL27_TAP__B                                         0
+#define   QAM_DQ_TAP_IM_EL27_TAP__W                                         12
+#define   QAM_DQ_TAP_IM_EL27_TAP__M                                         0xFFF
+#define   QAM_DQ_TAP_IM_EL27_TAP__PRE                                       0x2
+
+#define QAM_LC_COMM_EXEC__A                                                 0x1450000
+#define QAM_LC_COMM_EXEC__W                                                 2
+#define QAM_LC_COMM_EXEC__M                                                 0x3
+#define QAM_LC_COMM_EXEC__PRE                                               0x0
+#define   QAM_LC_COMM_EXEC_STOP                                             0x0
+#define   QAM_LC_COMM_EXEC_ACTIVE                                           0x1
+#define   QAM_LC_COMM_EXEC_HOLD                                             0x2
+
+#define QAM_LC_COMM_MB__A                                                   0x1450002
+#define QAM_LC_COMM_MB__W                                                   2
+#define QAM_LC_COMM_MB__M                                                   0x3
+#define QAM_LC_COMM_MB__PRE                                                 0x0
+#define   QAM_LC_COMM_MB_CTL__B                                             0
+#define   QAM_LC_COMM_MB_CTL__W                                             1
+#define   QAM_LC_COMM_MB_CTL__M                                             0x1
+#define   QAM_LC_COMM_MB_CTL__PRE                                           0x0
+#define     QAM_LC_COMM_MB_CTL_OFF                                          0x0
+#define     QAM_LC_COMM_MB_CTL_ON                                           0x1
+#define   QAM_LC_COMM_MB_OBS__B                                             1
+#define   QAM_LC_COMM_MB_OBS__W                                             1
+#define   QAM_LC_COMM_MB_OBS__M                                             0x2
+#define   QAM_LC_COMM_MB_OBS__PRE                                           0x0
+#define     QAM_LC_COMM_MB_OBS_OFF                                          0x0
+#define     QAM_LC_COMM_MB_OBS_ON                                           0x2
+
+#define QAM_LC_COMM_INT_REQ__A                                              0x1450003
+#define QAM_LC_COMM_INT_REQ__W                                              1
+#define QAM_LC_COMM_INT_REQ__M                                              0x1
+#define QAM_LC_COMM_INT_REQ__PRE                                            0x0
+#define QAM_LC_COMM_INT_STA__A                                              0x1450005
+#define QAM_LC_COMM_INT_STA__W                                              3
+#define QAM_LC_COMM_INT_STA__M                                              0x7
+#define QAM_LC_COMM_INT_STA__PRE                                            0x0
+
+#define   QAM_LC_COMM_INT_STA_READY__B                                      0
+#define   QAM_LC_COMM_INT_STA_READY__W                                      1
+#define   QAM_LC_COMM_INT_STA_READY__M                                      0x1
+#define   QAM_LC_COMM_INT_STA_READY__PRE                                    0x0
+
+#define   QAM_LC_COMM_INT_STA_OVERFLOW__B                                   1
+#define   QAM_LC_COMM_INT_STA_OVERFLOW__W                                   1
+#define   QAM_LC_COMM_INT_STA_OVERFLOW__M                                   0x2
+#define   QAM_LC_COMM_INT_STA_OVERFLOW__PRE                                 0x0
+
+#define   QAM_LC_COMM_INT_STA_FREQ_WRAP__B                                  2
+#define   QAM_LC_COMM_INT_STA_FREQ_WRAP__W                                  1
+#define   QAM_LC_COMM_INT_STA_FREQ_WRAP__M                                  0x4
+#define   QAM_LC_COMM_INT_STA_FREQ_WRAP__PRE                                0x0
+
+#define QAM_LC_COMM_INT_MSK__A                                              0x1450006
+#define QAM_LC_COMM_INT_MSK__W                                              3
+#define QAM_LC_COMM_INT_MSK__M                                              0x7
+#define QAM_LC_COMM_INT_MSK__PRE                                            0x0
+#define   QAM_LC_COMM_INT_MSK_READY__B                                      0
+#define   QAM_LC_COMM_INT_MSK_READY__W                                      1
+#define   QAM_LC_COMM_INT_MSK_READY__M                                      0x1
+#define   QAM_LC_COMM_INT_MSK_READY__PRE                                    0x0
+#define   QAM_LC_COMM_INT_MSK_OVERFLOW__B                                   1
+#define   QAM_LC_COMM_INT_MSK_OVERFLOW__W                                   1
+#define   QAM_LC_COMM_INT_MSK_OVERFLOW__M                                   0x2
+#define   QAM_LC_COMM_INT_MSK_OVERFLOW__PRE                                 0x0
+#define   QAM_LC_COMM_INT_MSK_FREQ_WRAP__B                                  2
+#define   QAM_LC_COMM_INT_MSK_FREQ_WRAP__W                                  1
+#define   QAM_LC_COMM_INT_MSK_FREQ_WRAP__M                                  0x4
+#define   QAM_LC_COMM_INT_MSK_FREQ_WRAP__PRE                                0x0
+
+#define QAM_LC_COMM_INT_STM__A                                              0x1450007
+#define QAM_LC_COMM_INT_STM__W                                              3
+#define QAM_LC_COMM_INT_STM__M                                              0x7
+#define QAM_LC_COMM_INT_STM__PRE                                            0x0
+#define   QAM_LC_COMM_INT_STM_READY__B                                      0
+#define   QAM_LC_COMM_INT_STM_READY__W                                      1
+#define   QAM_LC_COMM_INT_STM_READY__M                                      0x1
+#define   QAM_LC_COMM_INT_STM_READY__PRE                                    0x0
+#define   QAM_LC_COMM_INT_STM_OVERFLOW__B                                   1
+#define   QAM_LC_COMM_INT_STM_OVERFLOW__W                                   1
+#define   QAM_LC_COMM_INT_STM_OVERFLOW__M                                   0x2
+#define   QAM_LC_COMM_INT_STM_OVERFLOW__PRE                                 0x0
+#define   QAM_LC_COMM_INT_STM_FREQ_WRAP__B                                  2
+#define   QAM_LC_COMM_INT_STM_FREQ_WRAP__W                                  1
+#define   QAM_LC_COMM_INT_STM_FREQ_WRAP__M                                  0x4
+#define   QAM_LC_COMM_INT_STM_FREQ_WRAP__PRE                                0x0
+
+#define QAM_LC_MODE__A                                                      0x1450010
+#define QAM_LC_MODE__W                                                      3
+#define QAM_LC_MODE__M                                                      0x7
+#define QAM_LC_MODE__PRE                                                    0x7
+
+#define   QAM_LC_MODE_ENABLE_A__B                                           0
+#define   QAM_LC_MODE_ENABLE_A__W                                           1
+#define   QAM_LC_MODE_ENABLE_A__M                                           0x1
+#define   QAM_LC_MODE_ENABLE_A__PRE                                         0x1
+
+#define   QAM_LC_MODE_ENABLE_F__B                                           1
+#define   QAM_LC_MODE_ENABLE_F__W                                           1
+#define   QAM_LC_MODE_ENABLE_F__M                                           0x2
+#define   QAM_LC_MODE_ENABLE_F__PRE                                         0x2
+
+#define   QAM_LC_MODE_ENABLE_R__B                                           2
+#define   QAM_LC_MODE_ENABLE_R__W                                           1
+#define   QAM_LC_MODE_ENABLE_R__M                                           0x4
+#define   QAM_LC_MODE_ENABLE_R__PRE                                         0x4
+
+#define QAM_LC_CA__A                                                        0x1450011
+#define QAM_LC_CA__W                                                        6
+#define QAM_LC_CA__M                                                        0x3F
+#define QAM_LC_CA__PRE                                                      0x28
+
+#define   QAM_LC_CA_COEF__B                                                 0
+#define   QAM_LC_CA_COEF__W                                                 6
+#define   QAM_LC_CA_COEF__M                                                 0x3F
+#define   QAM_LC_CA_COEF__PRE                                               0x28
+
+#define QAM_LC_CF__A                                                        0x1450012
+#define QAM_LC_CF__W                                                        8
+#define QAM_LC_CF__M                                                        0xFF
+#define QAM_LC_CF__PRE                                                      0x8C
+
+#define   QAM_LC_CF_COEF__B                                                 0
+#define   QAM_LC_CF_COEF__W                                                 8
+#define   QAM_LC_CF_COEF__M                                                 0xFF
+#define   QAM_LC_CF_COEF__PRE                                               0x8C
+
+#define QAM_LC_CF1__A                                                       0x1450013
+#define QAM_LC_CF1__W                                                       8
+#define QAM_LC_CF1__M                                                       0xFF
+#define QAM_LC_CF1__PRE                                                     0x1E
+
+#define   QAM_LC_CF1_COEF__B                                                0
+#define   QAM_LC_CF1_COEF__W                                                8
+#define   QAM_LC_CF1_COEF__M                                                0xFF
+#define   QAM_LC_CF1_COEF__PRE                                              0x1E
+
+#define QAM_LC_CP__A                                                        0x1450014
+#define QAM_LC_CP__W                                                        8
+#define QAM_LC_CP__M                                                        0xFF
+#define QAM_LC_CP__PRE                                                      0x78
+
+#define   QAM_LC_CP_COEF__B                                                 0
+#define   QAM_LC_CP_COEF__W                                                 8
+#define   QAM_LC_CP_COEF__M                                                 0xFF
+#define   QAM_LC_CP_COEF__PRE                                               0x78
+
+#define QAM_LC_CI__A                                                        0x1450015
+#define QAM_LC_CI__W                                                        8
+#define QAM_LC_CI__M                                                        0xFF
+#define QAM_LC_CI__PRE                                                      0x46
+
+#define   QAM_LC_CI_COEF__B                                                 0
+#define   QAM_LC_CI_COEF__W                                                 8
+#define   QAM_LC_CI_COEF__M                                                 0xFF
+#define   QAM_LC_CI_COEF__PRE                                               0x46
+
+#define QAM_LC_EP__A                                                        0x1450016
+#define QAM_LC_EP__W                                                        6
+#define QAM_LC_EP__M                                                        0x3F
+#define QAM_LC_EP__PRE                                                      0x0
+
+#define   QAM_LC_EP_COEF__B                                                 0
+#define   QAM_LC_EP_COEF__W                                                 6
+#define   QAM_LC_EP_COEF__M                                                 0x3F
+#define   QAM_LC_EP_COEF__PRE                                               0x0
+
+#define QAM_LC_EI__A                                                        0x1450017
+#define QAM_LC_EI__W                                                        6
+#define QAM_LC_EI__M                                                        0x3F
+#define QAM_LC_EI__PRE                                                      0x0
+
+#define   QAM_LC_EI_COEF__B                                                 0
+#define   QAM_LC_EI_COEF__W                                                 6
+#define   QAM_LC_EI_COEF__M                                                 0x3F
+#define   QAM_LC_EI_COEF__PRE                                               0x0
+
+#define QAM_LC_QUAL_TAB0__A                                                 0x1450018
+#define QAM_LC_QUAL_TAB0__W                                                 5
+#define QAM_LC_QUAL_TAB0__M                                                 0x1F
+#define QAM_LC_QUAL_TAB0__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB0_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB0_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB0_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB0_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB1__A                                                 0x1450019
+#define QAM_LC_QUAL_TAB1__W                                                 5
+#define QAM_LC_QUAL_TAB1__M                                                 0x1F
+#define QAM_LC_QUAL_TAB1__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB1_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB1_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB1_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB1_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB2__A                                                 0x145001A
+#define QAM_LC_QUAL_TAB2__W                                                 5
+#define QAM_LC_QUAL_TAB2__M                                                 0x1F
+#define QAM_LC_QUAL_TAB2__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB2_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB2_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB2_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB2_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB3__A                                                 0x145001B
+#define QAM_LC_QUAL_TAB3__W                                                 5
+#define QAM_LC_QUAL_TAB3__M                                                 0x1F
+#define QAM_LC_QUAL_TAB3__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB3_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB3_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB3_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB3_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB4__A                                                 0x145001C
+#define QAM_LC_QUAL_TAB4__W                                                 5
+#define QAM_LC_QUAL_TAB4__M                                                 0x1F
+#define QAM_LC_QUAL_TAB4__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB4_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB4_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB4_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB4_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB5__A                                                 0x145001D
+#define QAM_LC_QUAL_TAB5__W                                                 5
+#define QAM_LC_QUAL_TAB5__M                                                 0x1F
+#define QAM_LC_QUAL_TAB5__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB5_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB5_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB5_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB5_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB6__A                                                 0x145001E
+#define QAM_LC_QUAL_TAB6__W                                                 5
+#define QAM_LC_QUAL_TAB6__M                                                 0x1F
+#define QAM_LC_QUAL_TAB6__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB6_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB6_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB6_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB6_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB8__A                                                 0x145001F
+#define QAM_LC_QUAL_TAB8__W                                                 5
+#define QAM_LC_QUAL_TAB8__M                                                 0x1F
+#define QAM_LC_QUAL_TAB8__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB8_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB8_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB8_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB8_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB9__A                                                 0x1450020
+#define QAM_LC_QUAL_TAB9__W                                                 5
+#define QAM_LC_QUAL_TAB9__M                                                 0x1F
+#define QAM_LC_QUAL_TAB9__PRE                                               0x1
+
+#define   QAM_LC_QUAL_TAB9_VALUE__B                                         0
+#define   QAM_LC_QUAL_TAB9_VALUE__W                                         5
+#define   QAM_LC_QUAL_TAB9_VALUE__M                                         0x1F
+#define   QAM_LC_QUAL_TAB9_VALUE__PRE                                       0x1
+
+#define QAM_LC_QUAL_TAB10__A                                                0x1450021
+#define QAM_LC_QUAL_TAB10__W                                                5
+#define QAM_LC_QUAL_TAB10__M                                                0x1F
+#define QAM_LC_QUAL_TAB10__PRE                                              0x1
+
+#define   QAM_LC_QUAL_TAB10_VALUE__B                                        0
+#define   QAM_LC_QUAL_TAB10_VALUE__W                                        5
+#define   QAM_LC_QUAL_TAB10_VALUE__M                                        0x1F
+#define   QAM_LC_QUAL_TAB10_VALUE__PRE                                      0x1
+
+#define QAM_LC_QUAL_TAB12__A                                                0x1450022
+#define QAM_LC_QUAL_TAB12__W                                                5
+#define QAM_LC_QUAL_TAB12__M                                                0x1F
+#define QAM_LC_QUAL_TAB12__PRE                                              0x1
+
+#define   QAM_LC_QUAL_TAB12_VALUE__B                                        0
+#define   QAM_LC_QUAL_TAB12_VALUE__W                                        5
+#define   QAM_LC_QUAL_TAB12_VALUE__M                                        0x1F
+#define   QAM_LC_QUAL_TAB12_VALUE__PRE                                      0x1
+
+#define QAM_LC_QUAL_TAB15__A                                                0x1450023
+#define QAM_LC_QUAL_TAB15__W                                                5
+#define QAM_LC_QUAL_TAB15__M                                                0x1F
+#define QAM_LC_QUAL_TAB15__PRE                                              0x1
+
+#define   QAM_LC_QUAL_TAB15_VALUE__B                                        0
+#define   QAM_LC_QUAL_TAB15_VALUE__W                                        5
+#define   QAM_LC_QUAL_TAB15_VALUE__M                                        0x1F
+#define   QAM_LC_QUAL_TAB15_VALUE__PRE                                      0x1
+
+#define QAM_LC_QUAL_TAB16__A                                                0x1450024
+#define QAM_LC_QUAL_TAB16__W                                                5
+#define QAM_LC_QUAL_TAB16__M                                                0x1F
+#define QAM_LC_QUAL_TAB16__PRE                                              0x1
+
+#define   QAM_LC_QUAL_TAB16_VALUE__B                                        0
+#define   QAM_LC_QUAL_TAB16_VALUE__W                                        5
+#define   QAM_LC_QUAL_TAB16_VALUE__M                                        0x1F
+#define   QAM_LC_QUAL_TAB16_VALUE__PRE                                      0x1
+
+#define QAM_LC_QUAL_TAB20__A                                                0x1450025
+#define QAM_LC_QUAL_TAB20__W                                                5
+#define QAM_LC_QUAL_TAB20__M                                                0x1F
+#define QAM_LC_QUAL_TAB20__PRE                                              0x1
+
+#define   QAM_LC_QUAL_TAB20_VALUE__B                                        0
+#define   QAM_LC_QUAL_TAB20_VALUE__W                                        5
+#define   QAM_LC_QUAL_TAB20_VALUE__M                                        0x1F
+#define   QAM_LC_QUAL_TAB20_VALUE__PRE                                      0x1
+
+#define QAM_LC_QUAL_TAB25__A                                                0x1450026
+#define QAM_LC_QUAL_TAB25__W                                                5
+#define QAM_LC_QUAL_TAB25__M                                                0x1F
+#define QAM_LC_QUAL_TAB25__PRE                                              0x1
+
+#define   QAM_LC_QUAL_TAB25_VALUE__B                                        0
+#define   QAM_LC_QUAL_TAB25_VALUE__W                                        5
+#define   QAM_LC_QUAL_TAB25_VALUE__M                                        0x1F
+#define   QAM_LC_QUAL_TAB25_VALUE__PRE                                      0x1
+
+#define QAM_LC_EQ_TIMING__A                                                 0x1450027
+#define QAM_LC_EQ_TIMING__W                                                 10
+#define QAM_LC_EQ_TIMING__M                                                 0x3FF
+#define QAM_LC_EQ_TIMING__PRE                                               0x0
+
+#define   QAM_LC_EQ_TIMING_OFFS__B                                          0
+#define   QAM_LC_EQ_TIMING_OFFS__W                                          10
+#define   QAM_LC_EQ_TIMING_OFFS__M                                          0x3FF
+#define   QAM_LC_EQ_TIMING_OFFS__PRE                                        0x0
+
+#define QAM_LC_LPF_FACTORP__A                                               0x1450028
+#define QAM_LC_LPF_FACTORP__W                                               3
+#define QAM_LC_LPF_FACTORP__M                                               0x7
+#define QAM_LC_LPF_FACTORP__PRE                                             0x3
+
+#define   QAM_LC_LPF_FACTORP_FACTOR__B                                      0
+#define   QAM_LC_LPF_FACTORP_FACTOR__W                                      3
+#define   QAM_LC_LPF_FACTORP_FACTOR__M                                      0x7
+#define   QAM_LC_LPF_FACTORP_FACTOR__PRE                                    0x3
+
+#define QAM_LC_LPF_FACTORI__A                                               0x1450029
+#define QAM_LC_LPF_FACTORI__W                                               3
+#define QAM_LC_LPF_FACTORI__M                                               0x7
+#define QAM_LC_LPF_FACTORI__PRE                                             0x3
+
+#define   QAM_LC_LPF_FACTORI_FACTOR__B                                      0
+#define   QAM_LC_LPF_FACTORI_FACTOR__W                                      3
+#define   QAM_LC_LPF_FACTORI_FACTOR__M                                      0x7
+#define   QAM_LC_LPF_FACTORI_FACTOR__PRE                                    0x3
+
+#define QAM_LC_RATE_LIMIT__A                                                0x145002A
+#define QAM_LC_RATE_LIMIT__W                                                2
+#define QAM_LC_RATE_LIMIT__M                                                0x3
+#define QAM_LC_RATE_LIMIT__PRE                                              0x3
+
+#define   QAM_LC_RATE_LIMIT_LIMIT__B                                        0
+#define   QAM_LC_RATE_LIMIT_LIMIT__W                                        2
+#define   QAM_LC_RATE_LIMIT_LIMIT__M                                        0x3
+#define   QAM_LC_RATE_LIMIT_LIMIT__PRE                                      0x3
+
+#define QAM_LC_SYMBOL_FREQ__A                                               0x145002B
+#define QAM_LC_SYMBOL_FREQ__W                                               10
+#define QAM_LC_SYMBOL_FREQ__M                                               0x3FF
+#define QAM_LC_SYMBOL_FREQ__PRE                                             0x199
+
+#define   QAM_LC_SYMBOL_FREQ_FREQ__B                                        0
+#define   QAM_LC_SYMBOL_FREQ_FREQ__W                                        10
+#define   QAM_LC_SYMBOL_FREQ_FREQ__M                                        0x3FF
+#define   QAM_LC_SYMBOL_FREQ_FREQ__PRE                                      0x199
+#define     QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_64                                0x197
+#define     QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256                               0x1B2
+
+#define QAM_LC_MTA_LENGTH__A                                                0x145002C
+#define QAM_LC_MTA_LENGTH__W                                                2
+#define QAM_LC_MTA_LENGTH__M                                                0x3
+#define QAM_LC_MTA_LENGTH__PRE                                              0x2
+
+#define   QAM_LC_MTA_LENGTH_LENGTH__B                                       0
+#define   QAM_LC_MTA_LENGTH_LENGTH__W                                       2
+#define   QAM_LC_MTA_LENGTH_LENGTH__M                                       0x3
+#define   QAM_LC_MTA_LENGTH_LENGTH__PRE                                     0x2
+
+#define QAM_LC_AMP_ACCU__A                                                  0x145002D
+#define QAM_LC_AMP_ACCU__W                                                  14
+#define QAM_LC_AMP_ACCU__M                                                  0x3FFF
+#define QAM_LC_AMP_ACCU__PRE                                                0x600
+
+#define   QAM_LC_AMP_ACCU_ACCU__B                                           0
+#define   QAM_LC_AMP_ACCU_ACCU__W                                           14
+#define   QAM_LC_AMP_ACCU_ACCU__M                                           0x3FFF
+#define   QAM_LC_AMP_ACCU_ACCU__PRE                                         0x600
+
+#define QAM_LC_FREQ_ACCU__A                                                 0x145002E
+#define QAM_LC_FREQ_ACCU__W                                                 10
+#define QAM_LC_FREQ_ACCU__M                                                 0x3FF
+#define QAM_LC_FREQ_ACCU__PRE                                               0x0
+
+#define   QAM_LC_FREQ_ACCU_ACCU__B                                          0
+#define   QAM_LC_FREQ_ACCU_ACCU__W                                          10
+#define   QAM_LC_FREQ_ACCU_ACCU__M                                          0x3FF
+#define   QAM_LC_FREQ_ACCU_ACCU__PRE                                        0x0
+
+#define QAM_LC_RATE_ACCU__A                                                 0x145002F
+#define QAM_LC_RATE_ACCU__W                                                 10
+#define QAM_LC_RATE_ACCU__M                                                 0x3FF
+#define QAM_LC_RATE_ACCU__PRE                                               0x0
+
+#define   QAM_LC_RATE_ACCU_ACCU__B                                          0
+#define   QAM_LC_RATE_ACCU_ACCU__W                                          10
+#define   QAM_LC_RATE_ACCU_ACCU__M                                          0x3FF
+#define   QAM_LC_RATE_ACCU_ACCU__PRE                                        0x0
+
+#define QAM_LC_AMPLITUDE__A                                                 0x1450030
+#define QAM_LC_AMPLITUDE__W                                                 10
+#define QAM_LC_AMPLITUDE__M                                                 0x3FF
+#define QAM_LC_AMPLITUDE__PRE                                               0x0
+
+#define   QAM_LC_AMPLITUDE_SIZE__B                                          0
+#define   QAM_LC_AMPLITUDE_SIZE__W                                          10
+#define   QAM_LC_AMPLITUDE_SIZE__M                                          0x3FF
+#define   QAM_LC_AMPLITUDE_SIZE__PRE                                        0x0
+
+#define QAM_LC_RAD_ERROR__A                                                 0x1450031
+#define QAM_LC_RAD_ERROR__W                                                 10
+#define QAM_LC_RAD_ERROR__M                                                 0x3FF
+#define QAM_LC_RAD_ERROR__PRE                                               0x0
+
+#define   QAM_LC_RAD_ERROR_SIZE__B                                          0
+#define   QAM_LC_RAD_ERROR_SIZE__W                                          10
+#define   QAM_LC_RAD_ERROR_SIZE__M                                          0x3FF
+#define   QAM_LC_RAD_ERROR_SIZE__PRE                                        0x0
+
+#define QAM_LC_FREQ_OFFS__A                                                 0x1450032
+#define QAM_LC_FREQ_OFFS__W                                                 10
+#define QAM_LC_FREQ_OFFS__M                                                 0x3FF
+#define QAM_LC_FREQ_OFFS__PRE                                               0x0
+
+#define   QAM_LC_FREQ_OFFS_OFFS__B                                          0
+#define   QAM_LC_FREQ_OFFS_OFFS__W                                          10
+#define   QAM_LC_FREQ_OFFS_OFFS__M                                          0x3FF
+#define   QAM_LC_FREQ_OFFS_OFFS__PRE                                        0x0
+
+#define QAM_LC_PHASE_ERROR__A                                               0x1450033
+#define QAM_LC_PHASE_ERROR__W                                               10
+#define QAM_LC_PHASE_ERROR__M                                               0x3FF
+#define QAM_LC_PHASE_ERROR__PRE                                             0x0
+
+#define   QAM_LC_PHASE_ERROR_SIZE__B                                        0
+#define   QAM_LC_PHASE_ERROR_SIZE__W                                        10
+#define   QAM_LC_PHASE_ERROR_SIZE__M                                        0x3FF
+#define   QAM_LC_PHASE_ERROR_SIZE__PRE                                      0x0
+
+#define QAM_VD_COMM_EXEC__A                                                 0x1460000
+#define QAM_VD_COMM_EXEC__W                                                 2
+#define QAM_VD_COMM_EXEC__M                                                 0x3
+#define QAM_VD_COMM_EXEC__PRE                                               0x0
+#define   QAM_VD_COMM_EXEC_STOP                                             0x0
+#define   QAM_VD_COMM_EXEC_ACTIVE                                           0x1
+#define   QAM_VD_COMM_EXEC_HOLD                                             0x2
+
+#define QAM_VD_COMM_MB__A                                                   0x1460002
+#define QAM_VD_COMM_MB__W                                                   2
+#define QAM_VD_COMM_MB__M                                                   0x3
+#define QAM_VD_COMM_MB__PRE                                                 0x0
+#define   QAM_VD_COMM_MB_CTL__B                                             0
+#define   QAM_VD_COMM_MB_CTL__W                                             1
+#define   QAM_VD_COMM_MB_CTL__M                                             0x1
+#define   QAM_VD_COMM_MB_CTL__PRE                                           0x0
+#define     QAM_VD_COMM_MB_CTL_OFF                                          0x0
+#define     QAM_VD_COMM_MB_CTL_ON                                           0x1
+#define   QAM_VD_COMM_MB_OBS__B                                             1
+#define   QAM_VD_COMM_MB_OBS__W                                             1
+#define   QAM_VD_COMM_MB_OBS__M                                             0x2
+#define   QAM_VD_COMM_MB_OBS__PRE                                           0x0
+#define     QAM_VD_COMM_MB_OBS_OFF                                          0x0
+#define     QAM_VD_COMM_MB_OBS_ON                                           0x2
+
+#define QAM_VD_COMM_INT_REQ__A                                              0x1460003
+#define QAM_VD_COMM_INT_REQ__W                                              1
+#define QAM_VD_COMM_INT_REQ__M                                              0x1
+#define QAM_VD_COMM_INT_REQ__PRE                                            0x0
+#define QAM_VD_COMM_INT_STA__A                                              0x1460005
+#define QAM_VD_COMM_INT_STA__W                                              2
+#define QAM_VD_COMM_INT_STA__M                                              0x3
+#define QAM_VD_COMM_INT_STA__PRE                                            0x0
+
+#define   QAM_VD_COMM_INT_STA_LOCK_INT__B                                   0
+#define   QAM_VD_COMM_INT_STA_LOCK_INT__W                                   1
+#define   QAM_VD_COMM_INT_STA_LOCK_INT__M                                   0x1
+#define   QAM_VD_COMM_INT_STA_LOCK_INT__PRE                                 0x0
+
+#define   QAM_VD_COMM_INT_STA_PERIOD_INT__B                                 1
+#define   QAM_VD_COMM_INT_STA_PERIOD_INT__W                                 1
+#define   QAM_VD_COMM_INT_STA_PERIOD_INT__M                                 0x2
+#define   QAM_VD_COMM_INT_STA_PERIOD_INT__PRE                               0x0
+
+#define QAM_VD_COMM_INT_MSK__A                                              0x1460006
+#define QAM_VD_COMM_INT_MSK__W                                              2
+#define QAM_VD_COMM_INT_MSK__M                                              0x3
+#define QAM_VD_COMM_INT_MSK__PRE                                            0x0
+#define   QAM_VD_COMM_INT_MSK_LOCK_INT__B                                   0
+#define   QAM_VD_COMM_INT_MSK_LOCK_INT__W                                   1
+#define   QAM_VD_COMM_INT_MSK_LOCK_INT__M                                   0x1
+#define   QAM_VD_COMM_INT_MSK_LOCK_INT__PRE                                 0x0
+#define   QAM_VD_COMM_INT_MSK_PERIOD_INT__B                                 1
+#define   QAM_VD_COMM_INT_MSK_PERIOD_INT__W                                 1
+#define   QAM_VD_COMM_INT_MSK_PERIOD_INT__M                                 0x2
+#define   QAM_VD_COMM_INT_MSK_PERIOD_INT__PRE                               0x0
+
+#define QAM_VD_COMM_INT_STM__A                                              0x1460007
+#define QAM_VD_COMM_INT_STM__W                                              2
+#define QAM_VD_COMM_INT_STM__M                                              0x3
+#define QAM_VD_COMM_INT_STM__PRE                                            0x0
+#define   QAM_VD_COMM_INT_STM_LOCK_INT__B                                   0
+#define   QAM_VD_COMM_INT_STM_LOCK_INT__W                                   1
+#define   QAM_VD_COMM_INT_STM_LOCK_INT__M                                   0x1
+#define   QAM_VD_COMM_INT_STM_LOCK_INT__PRE                                 0x0
+#define   QAM_VD_COMM_INT_STM_PERIOD_INT__B                                 1
+#define   QAM_VD_COMM_INT_STM_PERIOD_INT__W                                 1
+#define   QAM_VD_COMM_INT_STM_PERIOD_INT__M                                 0x2
+#define   QAM_VD_COMM_INT_STM_PERIOD_INT__PRE                               0x0
+
+#define QAM_VD_STATUS__A                                                    0x1460010
+#define QAM_VD_STATUS__W                                                    1
+#define QAM_VD_STATUS__M                                                    0x1
+#define QAM_VD_STATUS__PRE                                                  0x0
+
+#define   QAM_VD_STATUS_LOCK__B                                             0
+#define   QAM_VD_STATUS_LOCK__W                                             1
+#define   QAM_VD_STATUS_LOCK__M                                             0x1
+#define   QAM_VD_STATUS_LOCK__PRE                                           0x0
+
+#define QAM_VD_UNLOCK_CONTROL__A                                            0x1460011
+#define QAM_VD_UNLOCK_CONTROL__W                                            1
+#define QAM_VD_UNLOCK_CONTROL__M                                            0x1
+#define QAM_VD_UNLOCK_CONTROL__PRE                                          0x0
+
+#define   QAM_VD_UNLOCK_CONTROL_UNLOCK_CTRL__B                              0
+#define   QAM_VD_UNLOCK_CONTROL_UNLOCK_CTRL__W                              1
+#define   QAM_VD_UNLOCK_CONTROL_UNLOCK_CTRL__M                              0x1
+#define   QAM_VD_UNLOCK_CONTROL_UNLOCK_CTRL__PRE                            0x0
+
+#define QAM_VD_MIN_VOTING_ROUNDS__A                                         0x1460012
+#define QAM_VD_MIN_VOTING_ROUNDS__W                                         6
+#define QAM_VD_MIN_VOTING_ROUNDS__M                                         0x3F
+#define QAM_VD_MIN_VOTING_ROUNDS__PRE                                       0x10
+
+#define   QAM_VD_MIN_VOTING_ROUNDS_ROUNDS__B                                0
+#define   QAM_VD_MIN_VOTING_ROUNDS_ROUNDS__W                                6
+#define   QAM_VD_MIN_VOTING_ROUNDS_ROUNDS__M                                0x3F
+#define   QAM_VD_MIN_VOTING_ROUNDS_ROUNDS__PRE                              0x10
+
+#define QAM_VD_MAX_VOTING_ROUNDS__A                                         0x1460013
+#define QAM_VD_MAX_VOTING_ROUNDS__W                                         6
+#define QAM_VD_MAX_VOTING_ROUNDS__M                                         0x3F
+#define QAM_VD_MAX_VOTING_ROUNDS__PRE                                       0x10
+
+#define   QAM_VD_MAX_VOTING_ROUNDS_ROUNDS__B                                0
+#define   QAM_VD_MAX_VOTING_ROUNDS_ROUNDS__W                                6
+#define   QAM_VD_MAX_VOTING_ROUNDS_ROUNDS__M                                0x3F
+#define   QAM_VD_MAX_VOTING_ROUNDS_ROUNDS__PRE                              0x10
+
+#define QAM_VD_TRACEBACK_DEPTH__A                                           0x1460014
+#define QAM_VD_TRACEBACK_DEPTH__W                                           5
+#define QAM_VD_TRACEBACK_DEPTH__M                                           0x1F
+#define QAM_VD_TRACEBACK_DEPTH__PRE                                         0x10
+
+#define   QAM_VD_TRACEBACK_DEPTH_LENGTH__B                                  0
+#define   QAM_VD_TRACEBACK_DEPTH_LENGTH__W                                  5
+#define   QAM_VD_TRACEBACK_DEPTH_LENGTH__M                                  0x1F
+#define   QAM_VD_TRACEBACK_DEPTH_LENGTH__PRE                                0x10
+
+#define QAM_VD_UNLOCK__A                                                    0x1460015
+#define QAM_VD_UNLOCK__W                                                    1
+#define QAM_VD_UNLOCK__M                                                    0x1
+#define QAM_VD_UNLOCK__PRE                                                  0x0
+#define QAM_VD_MEASUREMENT_PERIOD__A                                        0x1460016
+#define QAM_VD_MEASUREMENT_PERIOD__W                                        16
+#define QAM_VD_MEASUREMENT_PERIOD__M                                        0xFFFF
+#define QAM_VD_MEASUREMENT_PERIOD__PRE                                      0x8236
+
+#define   QAM_VD_MEASUREMENT_PERIOD_PERIOD__B                               0
+#define   QAM_VD_MEASUREMENT_PERIOD_PERIOD__W                               16
+#define   QAM_VD_MEASUREMENT_PERIOD_PERIOD__M                               0xFFFF
+#define   QAM_VD_MEASUREMENT_PERIOD_PERIOD__PRE                             0x8236
+
+#define QAM_VD_MEASUREMENT_PRESCALE__A                                      0x1460017
+#define QAM_VD_MEASUREMENT_PRESCALE__W                                      16
+#define QAM_VD_MEASUREMENT_PRESCALE__M                                      0xFFFF
+#define QAM_VD_MEASUREMENT_PRESCALE__PRE                                    0x4
+
+#define   QAM_VD_MEASUREMENT_PRESCALE_PRESCALE__B                           0
+#define   QAM_VD_MEASUREMENT_PRESCALE_PRESCALE__W                           16
+#define   QAM_VD_MEASUREMENT_PRESCALE_PRESCALE__M                           0xFFFF
+#define   QAM_VD_MEASUREMENT_PRESCALE_PRESCALE__PRE                         0x4
+
+#define QAM_VD_DELTA_PATH_METRIC__A                                         0x1460018
+#define QAM_VD_DELTA_PATH_METRIC__W                                         16
+#define QAM_VD_DELTA_PATH_METRIC__M                                         0xFFFF
+#define QAM_VD_DELTA_PATH_METRIC__PRE                                       0xFFFF
+
+#define   QAM_VD_DELTA_PATH_METRIC_FIXED_MANT__B                            0
+#define   QAM_VD_DELTA_PATH_METRIC_FIXED_MANT__W                            12
+#define   QAM_VD_DELTA_PATH_METRIC_FIXED_MANT__M                            0xFFF
+#define   QAM_VD_DELTA_PATH_METRIC_FIXED_MANT__PRE                          0xFFF
+
+#define   QAM_VD_DELTA_PATH_METRIC_EXP__B                                   12
+#define   QAM_VD_DELTA_PATH_METRIC_EXP__W                                   4
+#define   QAM_VD_DELTA_PATH_METRIC_EXP__M                                   0xF000
+#define   QAM_VD_DELTA_PATH_METRIC_EXP__PRE                                 0xF000
+
+#define QAM_VD_NR_QSYM_ERRORS__A                                            0x1460019
+#define QAM_VD_NR_QSYM_ERRORS__W                                            16
+#define QAM_VD_NR_QSYM_ERRORS__M                                            0xFFFF
+#define QAM_VD_NR_QSYM_ERRORS__PRE                                          0xFFFF
+
+#define   QAM_VD_NR_QSYM_ERRORS_FIXED_MANT__B                               0
+#define   QAM_VD_NR_QSYM_ERRORS_FIXED_MANT__W                               12
+#define   QAM_VD_NR_QSYM_ERRORS_FIXED_MANT__M                               0xFFF
+#define   QAM_VD_NR_QSYM_ERRORS_FIXED_MANT__PRE                             0xFFF
+
+#define   QAM_VD_NR_QSYM_ERRORS_EXP__B                                      12
+#define   QAM_VD_NR_QSYM_ERRORS_EXP__W                                      4
+#define   QAM_VD_NR_QSYM_ERRORS_EXP__M                                      0xF000
+#define   QAM_VD_NR_QSYM_ERRORS_EXP__PRE                                    0xF000
+
+#define QAM_VD_NR_SYMBOL_ERRORS__A                                          0x146001A
+#define QAM_VD_NR_SYMBOL_ERRORS__W                                          16
+#define QAM_VD_NR_SYMBOL_ERRORS__M                                          0xFFFF
+#define QAM_VD_NR_SYMBOL_ERRORS__PRE                                        0xFFFF
+
+#define   QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B                             0
+#define   QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__W                             12
+#define   QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M                             0xFFF
+#define   QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__PRE                           0xFFF
+
+#define   QAM_VD_NR_SYMBOL_ERRORS_EXP__B                                    12
+#define   QAM_VD_NR_SYMBOL_ERRORS_EXP__W                                    4
+#define   QAM_VD_NR_SYMBOL_ERRORS_EXP__M                                    0xF000
+#define   QAM_VD_NR_SYMBOL_ERRORS_EXP__PRE                                  0xF000
+
+#define QAM_VD_RELOCK_COUNT__A                                              0x146001B
+#define QAM_VD_RELOCK_COUNT__W                                              16
+#define QAM_VD_RELOCK_COUNT__M                                              0xFFFF
+#define QAM_VD_RELOCK_COUNT__PRE                                            0x0
+
+#define   QAM_VD_RELOCK_COUNT_COUNT__B                                      0
+#define   QAM_VD_RELOCK_COUNT_COUNT__W                                      8
+#define   QAM_VD_RELOCK_COUNT_COUNT__M                                      0xFF
+#define   QAM_VD_RELOCK_COUNT_COUNT__PRE                                    0x0
+
+#define QAM_SY_COMM_EXEC__A                                                 0x1470000
+#define QAM_SY_COMM_EXEC__W                                                 2
+#define QAM_SY_COMM_EXEC__M                                                 0x3
+#define QAM_SY_COMM_EXEC__PRE                                               0x0
+#define   QAM_SY_COMM_EXEC_STOP                                             0x0
+#define   QAM_SY_COMM_EXEC_ACTIVE                                           0x1
+#define   QAM_SY_COMM_EXEC_HOLD                                             0x2
+
+#define QAM_SY_COMM_MB__A                                                   0x1470002
+#define QAM_SY_COMM_MB__W                                                   2
+#define QAM_SY_COMM_MB__M                                                   0x3
+#define QAM_SY_COMM_MB__PRE                                                 0x0
+#define   QAM_SY_COMM_MB_CTL__B                                             0
+#define   QAM_SY_COMM_MB_CTL__W                                             1
+#define   QAM_SY_COMM_MB_CTL__M                                             0x1
+#define   QAM_SY_COMM_MB_CTL__PRE                                           0x0
+#define     QAM_SY_COMM_MB_CTL_OFF                                          0x0
+#define     QAM_SY_COMM_MB_CTL_ON                                           0x1
+#define   QAM_SY_COMM_MB_OBS__B                                             1
+#define   QAM_SY_COMM_MB_OBS__W                                             1
+#define   QAM_SY_COMM_MB_OBS__M                                             0x2
+#define   QAM_SY_COMM_MB_OBS__PRE                                           0x0
+#define     QAM_SY_COMM_MB_OBS_OFF                                          0x0
+#define     QAM_SY_COMM_MB_OBS_ON                                           0x2
+
+#define QAM_SY_COMM_INT_REQ__A                                              0x1470003
+#define QAM_SY_COMM_INT_REQ__W                                              1
+#define QAM_SY_COMM_INT_REQ__M                                              0x1
+#define QAM_SY_COMM_INT_REQ__PRE                                            0x0
+#define QAM_SY_COMM_INT_STA__A                                              0x1470005
+#define QAM_SY_COMM_INT_STA__W                                              4
+#define QAM_SY_COMM_INT_STA__M                                              0xF
+#define QAM_SY_COMM_INT_STA__PRE                                            0x0
+
+#define   QAM_SY_COMM_INT_STA_LOCK_INT__B                                   0
+#define   QAM_SY_COMM_INT_STA_LOCK_INT__W                                   1
+#define   QAM_SY_COMM_INT_STA_LOCK_INT__M                                   0x1
+#define   QAM_SY_COMM_INT_STA_LOCK_INT__PRE                                 0x0
+
+#define   QAM_SY_COMM_INT_STA_UNLOCK_INT__B                                 1
+#define   QAM_SY_COMM_INT_STA_UNLOCK_INT__W                                 1
+#define   QAM_SY_COMM_INT_STA_UNLOCK_INT__M                                 0x2
+#define   QAM_SY_COMM_INT_STA_UNLOCK_INT__PRE                               0x0
+
+#define   QAM_SY_COMM_INT_STA_TIMEOUT_INT__B                                2
+#define   QAM_SY_COMM_INT_STA_TIMEOUT_INT__W                                1
+#define   QAM_SY_COMM_INT_STA_TIMEOUT_INT__M                                0x4
+#define   QAM_SY_COMM_INT_STA_TIMEOUT_INT__PRE                              0x0
+
+#define   QAM_SY_COMM_INT_STA_CTL_WORD_INT__B                               3
+#define   QAM_SY_COMM_INT_STA_CTL_WORD_INT__W                               1
+#define   QAM_SY_COMM_INT_STA_CTL_WORD_INT__M                               0x8
+#define   QAM_SY_COMM_INT_STA_CTL_WORD_INT__PRE                             0x0
+
+#define QAM_SY_COMM_INT_MSK__A                                              0x1470006
+#define QAM_SY_COMM_INT_MSK__W                                              4
+#define QAM_SY_COMM_INT_MSK__M                                              0xF
+#define QAM_SY_COMM_INT_MSK__PRE                                            0x0
+#define   QAM_SY_COMM_INT_MSK_LOCK_MSK__B                                   0
+#define   QAM_SY_COMM_INT_MSK_LOCK_MSK__W                                   1
+#define   QAM_SY_COMM_INT_MSK_LOCK_MSK__M                                   0x1
+#define   QAM_SY_COMM_INT_MSK_LOCK_MSK__PRE                                 0x0
+#define   QAM_SY_COMM_INT_MSK_UNLOCK_MSK__B                                 1
+#define   QAM_SY_COMM_INT_MSK_UNLOCK_MSK__W                                 1
+#define   QAM_SY_COMM_INT_MSK_UNLOCK_MSK__M                                 0x2
+#define   QAM_SY_COMM_INT_MSK_UNLOCK_MSK__PRE                               0x0
+#define   QAM_SY_COMM_INT_MSK_TIMEOUT_MSK__B                                2
+#define   QAM_SY_COMM_INT_MSK_TIMEOUT_MSK__W                                1
+#define   QAM_SY_COMM_INT_MSK_TIMEOUT_MSK__M                                0x4
+#define   QAM_SY_COMM_INT_MSK_TIMEOUT_MSK__PRE                              0x0
+#define   QAM_SY_COMM_INT_MSK_CTL_WORD_MSK__B                               3
+#define   QAM_SY_COMM_INT_MSK_CTL_WORD_MSK__W                               1
+#define   QAM_SY_COMM_INT_MSK_CTL_WORD_MSK__M                               0x8
+#define   QAM_SY_COMM_INT_MSK_CTL_WORD_MSK__PRE                             0x0
+
+#define QAM_SY_COMM_INT_STM__A                                              0x1470007
+#define QAM_SY_COMM_INT_STM__W                                              4
+#define QAM_SY_COMM_INT_STM__M                                              0xF
+#define QAM_SY_COMM_INT_STM__PRE                                            0x0
+#define   QAM_SY_COMM_INT_STM_LOCK_MSK__B                                   0
+#define   QAM_SY_COMM_INT_STM_LOCK_MSK__W                                   1
+#define   QAM_SY_COMM_INT_STM_LOCK_MSK__M                                   0x1
+#define   QAM_SY_COMM_INT_STM_LOCK_MSK__PRE                                 0x0
+#define   QAM_SY_COMM_INT_STM_UNLOCK_MSK__B                                 1
+#define   QAM_SY_COMM_INT_STM_UNLOCK_MSK__W                                 1
+#define   QAM_SY_COMM_INT_STM_UNLOCK_MSK__M                                 0x2
+#define   QAM_SY_COMM_INT_STM_UNLOCK_MSK__PRE                               0x0
+#define   QAM_SY_COMM_INT_STM_TIMEOUT_MSK__B                                2
+#define   QAM_SY_COMM_INT_STM_TIMEOUT_MSK__W                                1
+#define   QAM_SY_COMM_INT_STM_TIMEOUT_MSK__M                                0x4
+#define   QAM_SY_COMM_INT_STM_TIMEOUT_MSK__PRE                              0x0
+#define   QAM_SY_COMM_INT_STM_CTL_WORD_MSK__B                               3
+#define   QAM_SY_COMM_INT_STM_CTL_WORD_MSK__W                               1
+#define   QAM_SY_COMM_INT_STM_CTL_WORD_MSK__M                               0x8
+#define   QAM_SY_COMM_INT_STM_CTL_WORD_MSK__PRE                             0x0
+
+#define QAM_SY_STATUS__A                                                    0x1470010
+#define QAM_SY_STATUS__W                                                    2
+#define QAM_SY_STATUS__M                                                    0x3
+#define QAM_SY_STATUS__PRE                                                  0x0
+
+#define   QAM_SY_STATUS_SYNC_STATE__B                                       0
+#define   QAM_SY_STATUS_SYNC_STATE__W                                       2
+#define   QAM_SY_STATUS_SYNC_STATE__M                                       0x3
+#define   QAM_SY_STATUS_SYNC_STATE__PRE                                     0x0
+
+#define QAM_SY_TIMEOUT__A                                                   0x1470011
+#define QAM_SY_TIMEOUT__W                                                   16
+#define QAM_SY_TIMEOUT__M                                                   0xFFFF
+#define QAM_SY_TIMEOUT__PRE                                                 0x3A98
+
+#define QAM_SY_SYNC_LWM__A                                                  0x1470012
+#define QAM_SY_SYNC_LWM__W                                                  4
+#define QAM_SY_SYNC_LWM__M                                                  0xF
+#define QAM_SY_SYNC_LWM__PRE                                                0x2
+
+#define QAM_SY_SYNC_AWM__A                                                  0x1470013
+#define QAM_SY_SYNC_AWM__W                                                  4
+#define QAM_SY_SYNC_AWM__M                                                  0xF
+#define QAM_SY_SYNC_AWM__PRE                                                0x3
+
+#define QAM_SY_SYNC_HWM__A                                                  0x1470014
+#define QAM_SY_SYNC_HWM__W                                                  4
+#define QAM_SY_SYNC_HWM__M                                                  0xF
+#define QAM_SY_SYNC_HWM__PRE                                                0x5
+
+#define QAM_SY_UNLOCK__A                                                    0x1470015
+#define QAM_SY_UNLOCK__W                                                    1
+#define QAM_SY_UNLOCK__M                                                    0x1
+#define QAM_SY_UNLOCK__PRE                                                  0x0
+#define QAM_SY_CONTROL_WORD__A                                              0x1470016
+#define QAM_SY_CONTROL_WORD__W                                              4
+#define QAM_SY_CONTROL_WORD__M                                              0xF
+#define QAM_SY_CONTROL_WORD__PRE                                            0x0
+
+#define   QAM_SY_CONTROL_WORD_CTRL_WORD__B                                  0
+#define   QAM_SY_CONTROL_WORD_CTRL_WORD__W                                  4
+#define   QAM_SY_CONTROL_WORD_CTRL_WORD__M                                  0xF
+#define   QAM_SY_CONTROL_WORD_CTRL_WORD__PRE                                0x0
+
+#define QAM_VD_ISS_RAM__A                                                   0x1480000
+
+#define QAM_VD_QSS_RAM__A                                                   0x1490000
+
+#define QAM_VD_SYM_RAM__A                                                   0x14A0000
+
+#define SCU_COMM_EXEC__A                                                    0x800000
+#define SCU_COMM_EXEC__W                                                    2
+#define SCU_COMM_EXEC__M                                                    0x3
+#define SCU_COMM_EXEC__PRE                                                  0x0
+#define   SCU_COMM_EXEC_STOP                                                0x0
+#define   SCU_COMM_EXEC_ACTIVE                                              0x1
+#define   SCU_COMM_EXEC_HOLD                                                0x2
+
+#define SCU_COMM_STATE__A                                                   0x800001
+#define SCU_COMM_STATE__W                                                   16
+#define SCU_COMM_STATE__M                                                   0xFFFF
+#define SCU_COMM_STATE__PRE                                                 0x0
+
+#define   SCU_COMM_STATE_COMM_STATE__B                                      0
+#define   SCU_COMM_STATE_COMM_STATE__W                                      16
+#define   SCU_COMM_STATE_COMM_STATE__M                                      0xFFFF
+#define   SCU_COMM_STATE_COMM_STATE__PRE                                    0x0
+
+#define SCU_TOP_COMM_EXEC__A                                                0x810000
+#define SCU_TOP_COMM_EXEC__W                                                2
+#define SCU_TOP_COMM_EXEC__M                                                0x3
+#define SCU_TOP_COMM_EXEC__PRE                                              0x0
+#define   SCU_TOP_COMM_EXEC_STOP                                            0x0
+#define   SCU_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   SCU_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define SCU_TOP_COMM_STATE__A                                               0x810001
+#define SCU_TOP_COMM_STATE__W                                               16
+#define SCU_TOP_COMM_STATE__M                                               0xFFFF
+#define SCU_TOP_COMM_STATE__PRE                                             0x0
+#define SCU_TOP_MWAIT_CTR__A                                                0x810010
+#define SCU_TOP_MWAIT_CTR__W                                                2
+#define SCU_TOP_MWAIT_CTR__M                                                0x3
+#define SCU_TOP_MWAIT_CTR__PRE                                              0x0
+
+#define   SCU_TOP_MWAIT_CTR_MWAIT_SEL__B                                    0
+#define   SCU_TOP_MWAIT_CTR_MWAIT_SEL__W                                    1
+#define   SCU_TOP_MWAIT_CTR_MWAIT_SEL__M                                    0x1
+#define   SCU_TOP_MWAIT_CTR_MWAIT_SEL__PRE                                  0x0
+#define     SCU_TOP_MWAIT_CTR_MWAIT_SEL_TR_MW_OFF                           0x0
+#define     SCU_TOP_MWAIT_CTR_MWAIT_SEL_TR_MW_ON                            0x1
+
+#define   SCU_TOP_MWAIT_CTR_READY_DIS__B                                    1
+#define   SCU_TOP_MWAIT_CTR_READY_DIS__W                                    1
+#define   SCU_TOP_MWAIT_CTR_READY_DIS__M                                    0x2
+#define   SCU_TOP_MWAIT_CTR_READY_DIS__PRE                                  0x0
+#define     SCU_TOP_MWAIT_CTR_READY_DIS_NMI_ON                              0x0
+#define     SCU_TOP_MWAIT_CTR_READY_DIS_NMI_OFF                             0x2
+
+#define SCU_LOW_RAM__A                                                      0x820000
+
+#define   SCU_LOW_RAM_LOW__B                                                0
+#define   SCU_LOW_RAM_LOW__W                                                16
+#define   SCU_LOW_RAM_LOW__M                                                0xFFFF
+#define   SCU_LOW_RAM_LOW__PRE                                              0x0
+
+#define SCU_HIGH_RAM__A                                                     0x830000
+
+#define   SCU_HIGH_RAM_HIGH__B                                              0
+#define   SCU_HIGH_RAM_HIGH__W                                              16
+#define   SCU_HIGH_RAM_HIGH__M                                              0xFFFF
+#define   SCU_HIGH_RAM_HIGH__PRE                                            0x0
+
+#define SCU_RAM_AGC_RF_MAX__A                                               0x831E96
+#define SCU_RAM_AGC_RF_MAX__W                                               15
+#define SCU_RAM_AGC_RF_MAX__M                                               0x7FFF
+#define SCU_RAM_AGC_RF_MAX__PRE                                             0x0
+
+#define SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A                                  0x831E97
+#define SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__W                                  16
+#define SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__M                                  0xFFFF
+#define SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__PRE                                0x0
+
+#define SCU_RAM_AGC_KI_CYCCNT__A                                            0x831E98
+#define SCU_RAM_AGC_KI_CYCCNT__W                                            16
+#define SCU_RAM_AGC_KI_CYCCNT__M                                            0xFFFF
+#define SCU_RAM_AGC_KI_CYCCNT__PRE                                          0x0
+
+#define SCU_RAM_AGC_KI_CYCLEN__A                                            0x831E99
+#define SCU_RAM_AGC_KI_CYCLEN__W                                            16
+#define SCU_RAM_AGC_KI_CYCLEN__M                                            0xFFFF
+#define SCU_RAM_AGC_KI_CYCLEN__PRE                                          0x0
+
+#define SCU_RAM_AGC_SNS_CYCLEN__A                                           0x831E9A
+#define SCU_RAM_AGC_SNS_CYCLEN__W                                           16
+#define SCU_RAM_AGC_SNS_CYCLEN__M                                           0xFFFF
+#define SCU_RAM_AGC_SNS_CYCLEN__PRE                                         0x0
+
+#define SCU_RAM_AGC_RF_SNS_DEV_MAX__A                                       0x831E9B
+#define SCU_RAM_AGC_RF_SNS_DEV_MAX__W                                       16
+#define SCU_RAM_AGC_RF_SNS_DEV_MAX__M                                       0xFFFF
+#define SCU_RAM_AGC_RF_SNS_DEV_MAX__PRE                                     0x0
+
+#define SCU_RAM_AGC_RF_SNS_DEV_MIN__A                                       0x831E9C
+#define SCU_RAM_AGC_RF_SNS_DEV_MIN__W                                       16
+#define SCU_RAM_AGC_RF_SNS_DEV_MIN__M                                       0xFFFF
+#define SCU_RAM_AGC_RF_SNS_DEV_MIN__PRE                                     0x0
+#define SCU_RAM_AGC_KI__A                                                   0x831E9D
+#define SCU_RAM_AGC_KI__W                                                   15
+#define SCU_RAM_AGC_KI__M                                                   0x7FFF
+#define SCU_RAM_AGC_KI__PRE                                                 0x0
+
+#define   SCU_RAM_AGC_KI_DGAIN__B                                           0
+#define   SCU_RAM_AGC_KI_DGAIN__W                                           4
+#define   SCU_RAM_AGC_KI_DGAIN__M                                           0xF
+#define   SCU_RAM_AGC_KI_DGAIN__PRE                                         0x0
+
+#define   SCU_RAM_AGC_KI_RF__B                                              4
+#define   SCU_RAM_AGC_KI_RF__W                                              4
+#define   SCU_RAM_AGC_KI_RF__M                                              0xF0
+#define   SCU_RAM_AGC_KI_RF__PRE                                            0x0
+
+#define   SCU_RAM_AGC_KI_IF__B                                              8
+#define   SCU_RAM_AGC_KI_IF__W                                              4
+#define   SCU_RAM_AGC_KI_IF__M                                              0xF00
+#define   SCU_RAM_AGC_KI_IF__PRE                                            0x0
+
+#define   SCU_RAM_AGC_KI_IF_AGC_DISABLE__B                                  12
+#define   SCU_RAM_AGC_KI_IF_AGC_DISABLE__W                                  1
+#define   SCU_RAM_AGC_KI_IF_AGC_DISABLE__M                                  0x1000
+#define   SCU_RAM_AGC_KI_IF_AGC_DISABLE__PRE                                0x0
+
+#define   SCU_RAM_AGC_KI_INV_IF_POL__B                                      13
+#define   SCU_RAM_AGC_KI_INV_IF_POL__W                                      1
+#define   SCU_RAM_AGC_KI_INV_IF_POL__M                                      0x2000
+#define   SCU_RAM_AGC_KI_INV_IF_POL__PRE                                    0x0
+
+#define   SCU_RAM_AGC_KI_INV_RF_POL__B                                      14
+#define   SCU_RAM_AGC_KI_INV_RF_POL__W                                      1
+#define   SCU_RAM_AGC_KI_INV_RF_POL__M                                      0x4000
+#define   SCU_RAM_AGC_KI_INV_RF_POL__PRE                                    0x0
+
+#define SCU_RAM_AGC_KI_RED__A                                               0x831E9E
+#define SCU_RAM_AGC_KI_RED__W                                               6
+#define SCU_RAM_AGC_KI_RED__M                                               0x3F
+#define SCU_RAM_AGC_KI_RED__PRE                                             0x0
+
+#define   SCU_RAM_AGC_KI_RED_INNER_RED__B                                   0
+#define   SCU_RAM_AGC_KI_RED_INNER_RED__W                                   2
+#define   SCU_RAM_AGC_KI_RED_INNER_RED__M                                   0x3
+#define   SCU_RAM_AGC_KI_RED_INNER_RED__PRE                                 0x0
+
+#define   SCU_RAM_AGC_KI_RED_RAGC_RED__B                                    2
+#define   SCU_RAM_AGC_KI_RED_RAGC_RED__W                                    2
+#define   SCU_RAM_AGC_KI_RED_RAGC_RED__M                                    0xC
+#define   SCU_RAM_AGC_KI_RED_RAGC_RED__PRE                                  0x0
+
+#define   SCU_RAM_AGC_KI_RED_IAGC_RED__B                                    4
+#define   SCU_RAM_AGC_KI_RED_IAGC_RED__W                                    2
+#define   SCU_RAM_AGC_KI_RED_IAGC_RED__M                                    0x30
+#define   SCU_RAM_AGC_KI_RED_IAGC_RED__PRE                                  0x0
+
+#define SCU_RAM_AGC_KI_INNERGAIN_MIN__A                                     0x831E9F
+#define SCU_RAM_AGC_KI_INNERGAIN_MIN__W                                     16
+#define SCU_RAM_AGC_KI_INNERGAIN_MIN__M                                     0xFFFF
+#define SCU_RAM_AGC_KI_INNERGAIN_MIN__PRE                                   0x0
+
+#define SCU_RAM_AGC_KI_MINGAIN__A                                           0x831EA0
+#define SCU_RAM_AGC_KI_MINGAIN__W                                           16
+#define SCU_RAM_AGC_KI_MINGAIN__M                                           0xFFFF
+#define SCU_RAM_AGC_KI_MINGAIN__PRE                                         0x0
+
+#define SCU_RAM_AGC_KI_MAXGAIN__A                                           0x831EA1
+#define SCU_RAM_AGC_KI_MAXGAIN__W                                           16
+#define SCU_RAM_AGC_KI_MAXGAIN__M                                           0xFFFF
+#define SCU_RAM_AGC_KI_MAXGAIN__PRE                                         0x0
+
+#define SCU_RAM_AGC_KI_MAXMINGAIN_TH__A                                     0x831EA2
+#define SCU_RAM_AGC_KI_MAXMINGAIN_TH__W                                     16
+#define SCU_RAM_AGC_KI_MAXMINGAIN_TH__M                                     0xFFFF
+#define SCU_RAM_AGC_KI_MAXMINGAIN_TH__PRE                                   0x0
+#define SCU_RAM_AGC_KI_MIN__A                                               0x831EA3
+#define SCU_RAM_AGC_KI_MIN__W                                               12
+#define SCU_RAM_AGC_KI_MIN__M                                               0xFFF
+#define SCU_RAM_AGC_KI_MIN__PRE                                             0x0
+
+#define   SCU_RAM_AGC_KI_MIN_DGAIN__B                                       0
+#define   SCU_RAM_AGC_KI_MIN_DGAIN__W                                       4
+#define   SCU_RAM_AGC_KI_MIN_DGAIN__M                                       0xF
+#define   SCU_RAM_AGC_KI_MIN_DGAIN__PRE                                     0x0
+
+#define   SCU_RAM_AGC_KI_MIN_RF__B                                          4
+#define   SCU_RAM_AGC_KI_MIN_RF__W                                          4
+#define   SCU_RAM_AGC_KI_MIN_RF__M                                          0xF0
+#define   SCU_RAM_AGC_KI_MIN_RF__PRE                                        0x0
+
+#define   SCU_RAM_AGC_KI_MIN_IF__B                                          8
+#define   SCU_RAM_AGC_KI_MIN_IF__W                                          4
+#define   SCU_RAM_AGC_KI_MIN_IF__M                                          0xF00
+#define   SCU_RAM_AGC_KI_MIN_IF__PRE                                        0x0
+
+#define SCU_RAM_AGC_KI_MAX__A                                               0x831EA4
+#define SCU_RAM_AGC_KI_MAX__W                                               12
+#define SCU_RAM_AGC_KI_MAX__M                                               0xFFF
+#define SCU_RAM_AGC_KI_MAX__PRE                                             0x0
+
+#define   SCU_RAM_AGC_KI_MAX_DGAIN__B                                       0
+#define   SCU_RAM_AGC_KI_MAX_DGAIN__W                                       4
+#define   SCU_RAM_AGC_KI_MAX_DGAIN__M                                       0xF
+#define   SCU_RAM_AGC_KI_MAX_DGAIN__PRE                                     0x0
+
+#define   SCU_RAM_AGC_KI_MAX_RF__B                                          4
+#define   SCU_RAM_AGC_KI_MAX_RF__W                                          4
+#define   SCU_RAM_AGC_KI_MAX_RF__M                                          0xF0
+#define   SCU_RAM_AGC_KI_MAX_RF__PRE                                        0x0
+
+#define   SCU_RAM_AGC_KI_MAX_IF__B                                          8
+#define   SCU_RAM_AGC_KI_MAX_IF__W                                          4
+#define   SCU_RAM_AGC_KI_MAX_IF__M                                          0xF00
+#define   SCU_RAM_AGC_KI_MAX_IF__PRE                                        0x0
+
+#define SCU_RAM_AGC_CLP_SUM__A                                              0x831EA5
+#define SCU_RAM_AGC_CLP_SUM__W                                              16
+#define SCU_RAM_AGC_CLP_SUM__M                                              0xFFFF
+#define SCU_RAM_AGC_CLP_SUM__PRE                                            0x0
+
+#define SCU_RAM_AGC_CLP_SUM_MIN__A                                          0x831EA6
+#define SCU_RAM_AGC_CLP_SUM_MIN__W                                          16
+#define SCU_RAM_AGC_CLP_SUM_MIN__M                                          0xFFFF
+#define SCU_RAM_AGC_CLP_SUM_MIN__PRE                                        0x0
+
+#define SCU_RAM_AGC_CLP_SUM_MAX__A                                          0x831EA7
+#define SCU_RAM_AGC_CLP_SUM_MAX__W                                          16
+#define SCU_RAM_AGC_CLP_SUM_MAX__M                                          0xFFFF
+#define SCU_RAM_AGC_CLP_SUM_MAX__PRE                                        0x0
+
+#define SCU_RAM_AGC_CLP_CYCLEN__A                                           0x831EA8
+#define SCU_RAM_AGC_CLP_CYCLEN__W                                           16
+#define SCU_RAM_AGC_CLP_CYCLEN__M                                           0xFFFF
+#define SCU_RAM_AGC_CLP_CYCLEN__PRE                                         0x0
+
+#define SCU_RAM_AGC_CLP_CYCCNT__A                                           0x831EA9
+#define SCU_RAM_AGC_CLP_CYCCNT__W                                           16
+#define SCU_RAM_AGC_CLP_CYCCNT__M                                           0xFFFF
+#define SCU_RAM_AGC_CLP_CYCCNT__PRE                                         0x0
+
+#define SCU_RAM_AGC_CLP_DIR_TO__A                                           0x831EAA
+#define SCU_RAM_AGC_CLP_DIR_TO__W                                           8
+#define SCU_RAM_AGC_CLP_DIR_TO__M                                           0xFF
+#define SCU_RAM_AGC_CLP_DIR_TO__PRE                                         0x0
+
+#define SCU_RAM_AGC_CLP_DIR_WD__A                                           0x831EAB
+#define SCU_RAM_AGC_CLP_DIR_WD__W                                           8
+#define SCU_RAM_AGC_CLP_DIR_WD__M                                           0xFF
+#define SCU_RAM_AGC_CLP_DIR_WD__PRE                                         0x0
+
+#define SCU_RAM_AGC_CLP_DIR_STP__A                                          0x831EAC
+#define SCU_RAM_AGC_CLP_DIR_STP__W                                          16
+#define SCU_RAM_AGC_CLP_DIR_STP__M                                          0xFFFF
+#define SCU_RAM_AGC_CLP_DIR_STP__PRE                                        0x0
+
+#define SCU_RAM_AGC_SNS_SUM__A                                              0x831EAD
+#define SCU_RAM_AGC_SNS_SUM__W                                              16
+#define SCU_RAM_AGC_SNS_SUM__M                                              0xFFFF
+#define SCU_RAM_AGC_SNS_SUM__PRE                                            0x0
+
+#define SCU_RAM_AGC_SNS_SUM_MIN__A                                          0x831EAE
+#define SCU_RAM_AGC_SNS_SUM_MIN__W                                          16
+#define SCU_RAM_AGC_SNS_SUM_MIN__M                                          0xFFFF
+#define SCU_RAM_AGC_SNS_SUM_MIN__PRE                                        0x0
+
+#define SCU_RAM_AGC_SNS_SUM_MAX__A                                          0x831EAF
+#define SCU_RAM_AGC_SNS_SUM_MAX__W                                          16
+#define SCU_RAM_AGC_SNS_SUM_MAX__M                                          0xFFFF
+#define SCU_RAM_AGC_SNS_SUM_MAX__PRE                                        0x0
+
+#define SCU_RAM_AGC_SNS_CYCCNT__A                                           0x831EB0
+#define SCU_RAM_AGC_SNS_CYCCNT__W                                           16
+#define SCU_RAM_AGC_SNS_CYCCNT__M                                           0xFFFF
+#define SCU_RAM_AGC_SNS_CYCCNT__PRE                                         0x0
+
+#define SCU_RAM_AGC_SNS_DIR_TO__A                                           0x831EB1
+#define SCU_RAM_AGC_SNS_DIR_TO__W                                           8
+#define SCU_RAM_AGC_SNS_DIR_TO__M                                           0xFF
+#define SCU_RAM_AGC_SNS_DIR_TO__PRE                                         0x0
+
+#define SCU_RAM_AGC_SNS_DIR_WD__A                                           0x831EB2
+#define SCU_RAM_AGC_SNS_DIR_WD__W                                           8
+#define SCU_RAM_AGC_SNS_DIR_WD__M                                           0xFF
+#define SCU_RAM_AGC_SNS_DIR_WD__PRE                                         0x0
+
+#define SCU_RAM_AGC_SNS_DIR_STP__A                                          0x831EB3
+#define SCU_RAM_AGC_SNS_DIR_STP__W                                          16
+#define SCU_RAM_AGC_SNS_DIR_STP__M                                          0xFFFF
+#define SCU_RAM_AGC_SNS_DIR_STP__PRE                                        0x0
+
+#define SCU_RAM_AGC_INGAIN__A                                               0x831EB4
+#define SCU_RAM_AGC_INGAIN__W                                               16
+#define SCU_RAM_AGC_INGAIN__M                                               0xFFFF
+#define SCU_RAM_AGC_INGAIN__PRE                                             0x0
+
+#define SCU_RAM_AGC_INGAIN_TGT__A                                           0x831EB5
+#define SCU_RAM_AGC_INGAIN_TGT__W                                           15
+#define SCU_RAM_AGC_INGAIN_TGT__M                                           0x7FFF
+#define SCU_RAM_AGC_INGAIN_TGT__PRE                                         0x0
+
+#define SCU_RAM_AGC_INGAIN_TGT_MIN__A                                       0x831EB6
+#define SCU_RAM_AGC_INGAIN_TGT_MIN__W                                       15
+#define SCU_RAM_AGC_INGAIN_TGT_MIN__M                                       0x7FFF
+#define SCU_RAM_AGC_INGAIN_TGT_MIN__PRE                                     0x0
+
+#define SCU_RAM_AGC_INGAIN_TGT_MAX__A                                       0x831EB7
+#define SCU_RAM_AGC_INGAIN_TGT_MAX__W                                       15
+#define SCU_RAM_AGC_INGAIN_TGT_MAX__M                                       0x7FFF
+#define SCU_RAM_AGC_INGAIN_TGT_MAX__PRE                                     0x0
+
+#define SCU_RAM_AGC_IF_IACCU_HI__A                                          0x831EB8
+#define SCU_RAM_AGC_IF_IACCU_HI__W                                          16
+#define SCU_RAM_AGC_IF_IACCU_HI__M                                          0xFFFF
+#define SCU_RAM_AGC_IF_IACCU_HI__PRE                                        0x0
+
+#define SCU_RAM_AGC_IF_IACCU_LO__A                                          0x831EB9
+#define SCU_RAM_AGC_IF_IACCU_LO__W                                          8
+#define SCU_RAM_AGC_IF_IACCU_LO__M                                          0xFF
+#define SCU_RAM_AGC_IF_IACCU_LO__PRE                                        0x0
+
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT__A                                      0x831EBA
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT__W                                      15
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT__M                                      0x7FFF
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT__PRE                                    0x0
+
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A                                  0x831EBB
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__W                                  15
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__M                                  0x7FFF
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__PRE                                0x0
+
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A                                  0x831EBC
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__W                                  15
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__M                                  0x7FFF
+#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__PRE                                0x0
+
+#define SCU_RAM_AGC_RF_IACCU_HI__A                                          0x831EBD
+#define SCU_RAM_AGC_RF_IACCU_HI__W                                          16
+#define SCU_RAM_AGC_RF_IACCU_HI__M                                          0xFFFF
+#define SCU_RAM_AGC_RF_IACCU_HI__PRE                                        0x0
+
+#define SCU_RAM_AGC_RF_IACCU_LO__A                                          0x831EBE
+#define SCU_RAM_AGC_RF_IACCU_LO__W                                          8
+#define SCU_RAM_AGC_RF_IACCU_LO__M                                          0xFF
+#define SCU_RAM_AGC_RF_IACCU_LO__PRE                                        0x0
+
+#define SCU_RAM_AGC_RF_IACCU_HI_CO__A                                       0x831EBF
+#define SCU_RAM_AGC_RF_IACCU_HI_CO__W                                       16
+#define SCU_RAM_AGC_RF_IACCU_HI_CO__M                                       0xFFFF
+#define SCU_RAM_AGC_RF_IACCU_HI_CO__PRE                                     0x0
+
+#define SCU_RAM_SP__A                                                       0x831EC0
+#define SCU_RAM_SP__W                                                       16
+#define SCU_RAM_SP__M                                                       0xFFFF
+#define SCU_RAM_SP__PRE                                                     0x0
+
+#define SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A                                  0x831EC1
+#define SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__W                                  16
+#define SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__M                                  0xFFFF
+#define SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__PRE                                0x0
+
+#define SCU_RAM_AGC_KI_MIN_IFGAIN__A                                        0x831EC2
+#define SCU_RAM_AGC_KI_MIN_IFGAIN__W                                        16
+#define SCU_RAM_AGC_KI_MIN_IFGAIN__M                                        0xFFFF
+#define SCU_RAM_AGC_KI_MIN_IFGAIN__PRE                                      0x0
+
+#define SCU_RAM_AGC_KI_MAX_IFGAIN__A                                        0x831EC3
+#define SCU_RAM_AGC_KI_MAX_IFGAIN__W                                        16
+#define SCU_RAM_AGC_KI_MAX_IFGAIN__M                                        0xFFFF
+#define SCU_RAM_AGC_KI_MAX_IFGAIN__PRE                                      0x0
+
+#define SCU_RAM_FEC_MEAS_COUNT__A                                           0x831EC4
+#define SCU_RAM_FEC_MEAS_COUNT__W                                           16
+#define SCU_RAM_FEC_MEAS_COUNT__M                                           0xFFFF
+#define SCU_RAM_FEC_MEAS_COUNT__PRE                                         0x0
+
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A                                0x831EC5
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__W                                16
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__M                                0xFFFF
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__PRE                              0x0
+
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_HI__A                                0x831EC6
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_HI__W                                16
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_HI__M                                0xFFFF
+#define SCU_RAM_FEC_ACCUM_CW_CORRECTED_HI__PRE                              0x0
+#define SCU_RAM_GPIO__A                                                     0x831EC7
+#define SCU_RAM_GPIO__W                                                     1
+#define SCU_RAM_GPIO__M                                                     0x1
+#define SCU_RAM_GPIO__PRE                                                   0x0
+
+#define   SCU_RAM_GPIO_HW_LOCK_IND__B                                       0
+#define   SCU_RAM_GPIO_HW_LOCK_IND__W                                       1
+#define   SCU_RAM_GPIO_HW_LOCK_IND__M                                       0x1
+#define   SCU_RAM_GPIO_HW_LOCK_IND__PRE                                     0x0
+#define     SCU_RAM_GPIO_HW_LOCK_IND_DISABLE                                0x0
+#define     SCU_RAM_GPIO_HW_LOCK_IND_ENABLE                                 0x1
+
+#define SCU_RAM_AGC_CLP_CTRL_MODE__A                                        0x831EC8
+#define SCU_RAM_AGC_CLP_CTRL_MODE__W                                        8
+#define SCU_RAM_AGC_CLP_CTRL_MODE__M                                        0xFF
+#define SCU_RAM_AGC_CLP_CTRL_MODE__PRE                                      0x0
+
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_NARROW_POW__B                           0
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_NARROW_POW__W                           1
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_NARROW_POW__M                           0x1
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_NARROW_POW__PRE                         0x0
+#define     SCU_RAM_AGC_CLP_CTRL_MODE_NARROW_POW_false                      0x0
+#define     SCU_RAM_AGC_CLP_CTRL_MODE_NARROW_POW_true                       0x1
+
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_BP__B                          1
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_BP__W                          1
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_BP__M                          0x2
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_BP__PRE                        0x0
+#define     SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_BP_FCC_ENABLE                0x0
+#define     SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_BP_FCC_DISABLE               0x2
+
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_DEC__B                         2
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_DEC__W                         1
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_DEC__M                         0x4
+#define   SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_DEC__PRE                       0x0
+#define     SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_DEC_DEC_DISABLE              0x0
+#define     SCU_RAM_AGC_CLP_CTRL_MODE_FAST_CLP_DEC_DEC_ENABLE               0x4
+
+#define SCU_RAM_AGC_KI_MIN_RFGAIN__A                                        0x831EC9
+#define SCU_RAM_AGC_KI_MIN_RFGAIN__W                                        16
+#define SCU_RAM_AGC_KI_MIN_RFGAIN__M                                        0xFFFF
+#define SCU_RAM_AGC_KI_MIN_RFGAIN__PRE                                      0x0
+
+#define SCU_RAM_AGC_KI_MAX_RFGAIN__A                                        0x831ECA
+#define SCU_RAM_AGC_KI_MAX_RFGAIN__W                                        16
+#define SCU_RAM_AGC_KI_MAX_RFGAIN__M                                        0xFFFF
+#define SCU_RAM_AGC_KI_MAX_RFGAIN__PRE                                      0x0
+
+#define SCU_RAM_FEC_ACCUM_PKT_FAILURES__A                                   0x831ECB
+#define SCU_RAM_FEC_ACCUM_PKT_FAILURES__W                                   16
+#define SCU_RAM_FEC_ACCUM_PKT_FAILURES__M                                   0xFFFF
+#define SCU_RAM_FEC_ACCUM_PKT_FAILURES__PRE                                 0x0
+
+#define SCU_RAM_INHIBIT_1__A                                                0x831ECC
+#define SCU_RAM_INHIBIT_1__W                                                16
+#define SCU_RAM_INHIBIT_1__M                                                0xFFFF
+#define SCU_RAM_INHIBIT_1__PRE                                              0x0
+
+#define SCU_RAM_HTOL_BUF_0__A                                               0x831ECD
+#define SCU_RAM_HTOL_BUF_0__W                                               16
+#define SCU_RAM_HTOL_BUF_0__M                                               0xFFFF
+#define SCU_RAM_HTOL_BUF_0__PRE                                             0x0
+
+#define SCU_RAM_HTOL_BUF_1__A                                               0x831ECE
+#define SCU_RAM_HTOL_BUF_1__W                                               16
+#define SCU_RAM_HTOL_BUF_1__M                                               0xFFFF
+#define SCU_RAM_HTOL_BUF_1__PRE                                             0x0
+
+#define SCU_RAM_INHIBIT_2__A                                                0x831ECF
+#define SCU_RAM_INHIBIT_2__W                                                16
+#define SCU_RAM_INHIBIT_2__M                                                0xFFFF
+#define SCU_RAM_INHIBIT_2__PRE                                              0x0
+
+#define SCU_RAM_TR_SHORT_BUF_0__A                                           0x831ED0
+#define SCU_RAM_TR_SHORT_BUF_0__W                                           16
+#define SCU_RAM_TR_SHORT_BUF_0__M                                           0xFFFF
+#define SCU_RAM_TR_SHORT_BUF_0__PRE                                         0x0
+
+#define SCU_RAM_TR_SHORT_BUF_1__A                                           0x831ED1
+#define SCU_RAM_TR_SHORT_BUF_1__W                                           16
+#define SCU_RAM_TR_SHORT_BUF_1__M                                           0xFFFF
+#define SCU_RAM_TR_SHORT_BUF_1__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_0__A                                            0x831ED2
+#define SCU_RAM_TR_LONG_BUF_0__W                                            16
+#define SCU_RAM_TR_LONG_BUF_0__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_0__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_1__A                                            0x831ED3
+#define SCU_RAM_TR_LONG_BUF_1__W                                            16
+#define SCU_RAM_TR_LONG_BUF_1__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_1__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_2__A                                            0x831ED4
+#define SCU_RAM_TR_LONG_BUF_2__W                                            16
+#define SCU_RAM_TR_LONG_BUF_2__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_2__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_3__A                                            0x831ED5
+#define SCU_RAM_TR_LONG_BUF_3__W                                            16
+#define SCU_RAM_TR_LONG_BUF_3__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_3__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_4__A                                            0x831ED6
+#define SCU_RAM_TR_LONG_BUF_4__W                                            16
+#define SCU_RAM_TR_LONG_BUF_4__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_4__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_5__A                                            0x831ED7
+#define SCU_RAM_TR_LONG_BUF_5__W                                            16
+#define SCU_RAM_TR_LONG_BUF_5__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_5__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_6__A                                            0x831ED8
+#define SCU_RAM_TR_LONG_BUF_6__W                                            16
+#define SCU_RAM_TR_LONG_BUF_6__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_6__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_7__A                                            0x831ED9
+#define SCU_RAM_TR_LONG_BUF_7__W                                            16
+#define SCU_RAM_TR_LONG_BUF_7__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_7__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_8__A                                            0x831EDA
+#define SCU_RAM_TR_LONG_BUF_8__W                                            16
+#define SCU_RAM_TR_LONG_BUF_8__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_8__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_9__A                                            0x831EDB
+#define SCU_RAM_TR_LONG_BUF_9__W                                            16
+#define SCU_RAM_TR_LONG_BUF_9__M                                            0xFFFF
+#define SCU_RAM_TR_LONG_BUF_9__PRE                                          0x0
+
+#define SCU_RAM_TR_LONG_BUF_10__A                                           0x831EDC
+#define SCU_RAM_TR_LONG_BUF_10__W                                           16
+#define SCU_RAM_TR_LONG_BUF_10__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_10__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_11__A                                           0x831EDD
+#define SCU_RAM_TR_LONG_BUF_11__W                                           16
+#define SCU_RAM_TR_LONG_BUF_11__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_11__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_12__A                                           0x831EDE
+#define SCU_RAM_TR_LONG_BUF_12__W                                           16
+#define SCU_RAM_TR_LONG_BUF_12__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_12__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_13__A                                           0x831EDF
+#define SCU_RAM_TR_LONG_BUF_13__W                                           16
+#define SCU_RAM_TR_LONG_BUF_13__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_13__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_14__A                                           0x831EE0
+#define SCU_RAM_TR_LONG_BUF_14__W                                           16
+#define SCU_RAM_TR_LONG_BUF_14__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_14__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_15__A                                           0x831EE1
+#define SCU_RAM_TR_LONG_BUF_15__W                                           16
+#define SCU_RAM_TR_LONG_BUF_15__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_15__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_16__A                                           0x831EE2
+#define SCU_RAM_TR_LONG_BUF_16__W                                           16
+#define SCU_RAM_TR_LONG_BUF_16__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_16__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_17__A                                           0x831EE3
+#define SCU_RAM_TR_LONG_BUF_17__W                                           16
+#define SCU_RAM_TR_LONG_BUF_17__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_17__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_18__A                                           0x831EE4
+#define SCU_RAM_TR_LONG_BUF_18__W                                           16
+#define SCU_RAM_TR_LONG_BUF_18__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_18__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_19__A                                           0x831EE5
+#define SCU_RAM_TR_LONG_BUF_19__W                                           16
+#define SCU_RAM_TR_LONG_BUF_19__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_19__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_20__A                                           0x831EE6
+#define SCU_RAM_TR_LONG_BUF_20__W                                           16
+#define SCU_RAM_TR_LONG_BUF_20__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_20__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_21__A                                           0x831EE7
+#define SCU_RAM_TR_LONG_BUF_21__W                                           16
+#define SCU_RAM_TR_LONG_BUF_21__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_21__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_22__A                                           0x831EE8
+#define SCU_RAM_TR_LONG_BUF_22__W                                           16
+#define SCU_RAM_TR_LONG_BUF_22__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_22__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_23__A                                           0x831EE9
+#define SCU_RAM_TR_LONG_BUF_23__W                                           16
+#define SCU_RAM_TR_LONG_BUF_23__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_23__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_24__A                                           0x831EEA
+#define SCU_RAM_TR_LONG_BUF_24__W                                           16
+#define SCU_RAM_TR_LONG_BUF_24__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_24__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_25__A                                           0x831EEB
+#define SCU_RAM_TR_LONG_BUF_25__W                                           16
+#define SCU_RAM_TR_LONG_BUF_25__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_25__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_26__A                                           0x831EEC
+#define SCU_RAM_TR_LONG_BUF_26__W                                           16
+#define SCU_RAM_TR_LONG_BUF_26__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_26__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_27__A                                           0x831EED
+#define SCU_RAM_TR_LONG_BUF_27__W                                           16
+#define SCU_RAM_TR_LONG_BUF_27__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_27__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_28__A                                           0x831EEE
+#define SCU_RAM_TR_LONG_BUF_28__W                                           16
+#define SCU_RAM_TR_LONG_BUF_28__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_28__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_29__A                                           0x831EEF
+#define SCU_RAM_TR_LONG_BUF_29__W                                           16
+#define SCU_RAM_TR_LONG_BUF_29__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_29__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_30__A                                           0x831EF0
+#define SCU_RAM_TR_LONG_BUF_30__W                                           16
+#define SCU_RAM_TR_LONG_BUF_30__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_30__PRE                                         0x0
+
+#define SCU_RAM_TR_LONG_BUF_31__A                                           0x831EF1
+#define SCU_RAM_TR_LONG_BUF_31__W                                           16
+#define SCU_RAM_TR_LONG_BUF_31__M                                           0xFFFF
+#define SCU_RAM_TR_LONG_BUF_31__PRE                                         0x0
+#define SCU_RAM_ATV_AMS_MAX__A                                              0x831EF2
+#define SCU_RAM_ATV_AMS_MAX__W                                              11
+#define SCU_RAM_ATV_AMS_MAX__M                                              0x7FF
+#define SCU_RAM_ATV_AMS_MAX__PRE                                            0x0
+
+#define   SCU_RAM_ATV_AMS_MAX_AMS_MAX__B                                    0
+#define   SCU_RAM_ATV_AMS_MAX_AMS_MAX__W                                    11
+#define   SCU_RAM_ATV_AMS_MAX_AMS_MAX__M                                    0x7FF
+#define   SCU_RAM_ATV_AMS_MAX_AMS_MAX__PRE                                  0x0
+
+#define SCU_RAM_ATV_AMS_MIN__A                                              0x831EF3
+#define SCU_RAM_ATV_AMS_MIN__W                                              11
+#define SCU_RAM_ATV_AMS_MIN__M                                              0x7FF
+#define SCU_RAM_ATV_AMS_MIN__PRE                                            0x0
+
+#define   SCU_RAM_ATV_AMS_MIN_AMS_MIN__B                                    0
+#define   SCU_RAM_ATV_AMS_MIN_AMS_MIN__W                                    11
+#define   SCU_RAM_ATV_AMS_MIN_AMS_MIN__M                                    0x7FF
+#define   SCU_RAM_ATV_AMS_MIN_AMS_MIN__PRE                                  0x0
+
+#define SCU_RAM_ATV_FIELD_CNT__A                                            0x831EF4
+#define SCU_RAM_ATV_FIELD_CNT__W                                            9
+#define SCU_RAM_ATV_FIELD_CNT__M                                            0x1FF
+#define SCU_RAM_ATV_FIELD_CNT__PRE                                          0x0
+
+#define   SCU_RAM_ATV_FIELD_CNT_FIELD_CNT__B                                0
+#define   SCU_RAM_ATV_FIELD_CNT_FIELD_CNT__W                                9
+#define   SCU_RAM_ATV_FIELD_CNT_FIELD_CNT__M                                0x1FF
+#define   SCU_RAM_ATV_FIELD_CNT_FIELD_CNT__PRE                              0x0
+
+#define SCU_RAM_ATV_AAGC_FAST__A                                            0x831EF5
+#define SCU_RAM_ATV_AAGC_FAST__W                                            1
+#define SCU_RAM_ATV_AAGC_FAST__M                                            0x1
+#define SCU_RAM_ATV_AAGC_FAST__PRE                                          0x0
+
+#define   SCU_RAM_ATV_AAGC_FAST_AAGC_FAST__B                                0
+#define   SCU_RAM_ATV_AAGC_FAST_AAGC_FAST__W                                1
+#define   SCU_RAM_ATV_AAGC_FAST_AAGC_FAST__M                                0x1
+#define   SCU_RAM_ATV_AAGC_FAST_AAGC_FAST__PRE                              0x0
+#define     SCU_RAM_ATV_AAGC_FAST_AAGC_FAST_OFF                             0x0
+#define     SCU_RAM_ATV_AAGC_FAST_AAGC_FAST_ON                              0x1
+
+#define SCU_RAM_ATV_AAGC_LP2__A                                             0x831EF6
+#define SCU_RAM_ATV_AAGC_LP2__W                                             16
+#define SCU_RAM_ATV_AAGC_LP2__M                                             0xFFFF
+#define SCU_RAM_ATV_AAGC_LP2__PRE                                           0x0
+
+#define   SCU_RAM_ATV_AAGC_LP2_AAGC_LP2__B                                  0
+#define   SCU_RAM_ATV_AAGC_LP2_AAGC_LP2__W                                  16
+#define   SCU_RAM_ATV_AAGC_LP2_AAGC_LP2__M                                  0xFFFF
+#define   SCU_RAM_ATV_AAGC_LP2_AAGC_LP2__PRE                                0x0
+
+#define SCU_RAM_ATV_BP_LVL__A                                               0x831EF7
+#define SCU_RAM_ATV_BP_LVL__W                                               11
+#define SCU_RAM_ATV_BP_LVL__M                                               0x7FF
+#define SCU_RAM_ATV_BP_LVL__PRE                                             0x0
+
+#define   SCU_RAM_ATV_BP_LVL_BP_LVL__B                                      0
+#define   SCU_RAM_ATV_BP_LVL_BP_LVL__W                                      11
+#define   SCU_RAM_ATV_BP_LVL_BP_LVL__M                                      0x7FF
+#define   SCU_RAM_ATV_BP_LVL_BP_LVL__PRE                                    0x0
+
+#define SCU_RAM_ATV_BP_RELY__A                                              0x831EF8
+#define SCU_RAM_ATV_BP_RELY__W                                              8
+#define SCU_RAM_ATV_BP_RELY__M                                              0xFF
+#define SCU_RAM_ATV_BP_RELY__PRE                                            0x0
+
+#define   SCU_RAM_ATV_BP_RELY_BP_RELY__B                                    0
+#define   SCU_RAM_ATV_BP_RELY_BP_RELY__W                                    8
+#define   SCU_RAM_ATV_BP_RELY_BP_RELY__M                                    0xFF
+#define   SCU_RAM_ATV_BP_RELY_BP_RELY__PRE                                  0x0
+
+#define SCU_RAM_ATV_BP_MTA__A                                               0x831EF9
+#define SCU_RAM_ATV_BP_MTA__W                                               14
+#define SCU_RAM_ATV_BP_MTA__M                                               0x3FFF
+#define SCU_RAM_ATV_BP_MTA__PRE                                             0x0
+
+#define   SCU_RAM_ATV_BP_MTA_BP_MTA__B                                      0
+#define   SCU_RAM_ATV_BP_MTA_BP_MTA__W                                      14
+#define   SCU_RAM_ATV_BP_MTA_BP_MTA__M                                      0x3FFF
+#define   SCU_RAM_ATV_BP_MTA_BP_MTA__PRE                                    0x0
+
+#define SCU_RAM_ATV_BP_REF__A                                               0x831EFA
+#define SCU_RAM_ATV_BP_REF__W                                               11
+#define SCU_RAM_ATV_BP_REF__M                                               0x7FF
+#define SCU_RAM_ATV_BP_REF__PRE                                             0x0
+
+#define   SCU_RAM_ATV_BP_REF_BP_REF__B                                      0
+#define   SCU_RAM_ATV_BP_REF_BP_REF__W                                      11
+#define   SCU_RAM_ATV_BP_REF_BP_REF__M                                      0x7FF
+#define   SCU_RAM_ATV_BP_REF_BP_REF__PRE                                    0x0
+
+#define SCU_RAM_ATV_BP_REF_MIN__A                                           0x831EFB
+#define SCU_RAM_ATV_BP_REF_MIN__W                                           11
+#define SCU_RAM_ATV_BP_REF_MIN__M                                           0x7FF
+#define SCU_RAM_ATV_BP_REF_MIN__PRE                                         0x0
+
+#define   SCU_RAM_ATV_BP_REF_MIN_BP_REF_MIN__B                              0
+#define   SCU_RAM_ATV_BP_REF_MIN_BP_REF_MIN__W                              11
+#define   SCU_RAM_ATV_BP_REF_MIN_BP_REF_MIN__M                              0x7FF
+#define   SCU_RAM_ATV_BP_REF_MIN_BP_REF_MIN__PRE                            0x0
+
+#define SCU_RAM_ATV_BP_REF_MAX__A                                           0x831EFC
+#define SCU_RAM_ATV_BP_REF_MAX__W                                           11
+#define SCU_RAM_ATV_BP_REF_MAX__M                                           0x7FF
+#define SCU_RAM_ATV_BP_REF_MAX__PRE                                         0x0
+
+#define   SCU_RAM_ATV_BP_REF_MAX_BP_REF_MAX__B                              0
+#define   SCU_RAM_ATV_BP_REF_MAX_BP_REF_MAX__W                              11
+#define   SCU_RAM_ATV_BP_REF_MAX_BP_REF_MAX__M                              0x7FF
+#define   SCU_RAM_ATV_BP_REF_MAX_BP_REF_MAX__PRE                            0x0
+
+#define SCU_RAM_ATV_BP_CNT__A                                               0x831EFD
+#define SCU_RAM_ATV_BP_CNT__W                                               8
+#define SCU_RAM_ATV_BP_CNT__M                                               0xFF
+#define SCU_RAM_ATV_BP_CNT__PRE                                             0x0
+
+#define   SCU_RAM_ATV_BP_CNT_BP_CNT__B                                      0
+#define   SCU_RAM_ATV_BP_CNT_BP_CNT__W                                      8
+#define   SCU_RAM_ATV_BP_CNT_BP_CNT__M                                      0xFF
+#define   SCU_RAM_ATV_BP_CNT_BP_CNT__PRE                                    0x0
+
+#define SCU_RAM_ATV_BP_XD_CNT__A                                            0x831EFE
+#define SCU_RAM_ATV_BP_XD_CNT__W                                            12
+#define SCU_RAM_ATV_BP_XD_CNT__M                                            0xFFF
+#define SCU_RAM_ATV_BP_XD_CNT__PRE                                          0x0
+
+#define   SCU_RAM_ATV_BP_XD_CNT_BP_XD_CNT__B                                0
+#define   SCU_RAM_ATV_BP_XD_CNT_BP_XD_CNT__W                                12
+#define   SCU_RAM_ATV_BP_XD_CNT_BP_XD_CNT__M                                0xFFF
+#define   SCU_RAM_ATV_BP_XD_CNT_BP_XD_CNT__PRE                              0x0
+
+#define SCU_RAM_ATV_PAGC_KI_MIN__A                                          0x831EFF
+#define SCU_RAM_ATV_PAGC_KI_MIN__W                                          12
+#define SCU_RAM_ATV_PAGC_KI_MIN__M                                          0xFFF
+#define SCU_RAM_ATV_PAGC_KI_MIN__PRE                                        0x0
+
+#define   SCU_RAM_ATV_PAGC_KI_MIN_PAGC_KI_MIN__B                            0
+#define   SCU_RAM_ATV_PAGC_KI_MIN_PAGC_KI_MIN__W                            12
+#define   SCU_RAM_ATV_PAGC_KI_MIN_PAGC_KI_MIN__M                            0xFFF
+#define   SCU_RAM_ATV_PAGC_KI_MIN_PAGC_KI_MIN__PRE                          0x0
+
+#define SCU_RAM_ATV_BPC_KI_MIN__A                                           0x831F00
+#define SCU_RAM_ATV_BPC_KI_MIN__W                                           12
+#define SCU_RAM_ATV_BPC_KI_MIN__M                                           0xFFF
+#define SCU_RAM_ATV_BPC_KI_MIN__PRE                                         0x0
+
+#define   SCU_RAM_ATV_BPC_KI_MIN_BPC_KI_MIN__B                              0
+#define   SCU_RAM_ATV_BPC_KI_MIN_BPC_KI_MIN__W                              12
+#define   SCU_RAM_ATV_BPC_KI_MIN_BPC_KI_MIN__M                              0xFFF
+#define   SCU_RAM_ATV_BPC_KI_MIN_BPC_KI_MIN__PRE                            0x0
+
+#define SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A                                0x831F01
+#define SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__W                                16
+#define SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__M                                0xFFFF
+#define SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__PRE                              0x0
+
+#define SCU_RAM_ORX_RF_RX_DATA_RATE__A                                      0x831F02
+#define SCU_RAM_ORX_RF_RX_DATA_RATE__W                                      8
+#define SCU_RAM_ORX_RF_RX_DATA_RATE__M                                      0xFF
+#define SCU_RAM_ORX_RF_RX_DATA_RATE__PRE                                    0x0
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC                      0x0
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC                      0x1
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT                  0x40
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT                  0x41
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC                      0x80
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC                      0x81
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC                      0xC0
+#define   SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC                      0xC1
+
+#define SCU_RAM_ORX_SCU_STATE__A                                            0x831F03
+#define SCU_RAM_ORX_SCU_STATE__W                                            8
+#define SCU_RAM_ORX_SCU_STATE__M                                            0xFF
+#define SCU_RAM_ORX_SCU_STATE__PRE                                          0x0
+#define   SCU_RAM_ORX_SCU_STATE_RESET                                       0x0
+#define   SCU_RAM_ORX_SCU_STATE_AGN_HUNT                                    0x1
+#define   SCU_RAM_ORX_SCU_STATE_DGN_HUNT                                    0x2
+#define   SCU_RAM_ORX_SCU_STATE_AGC_HUNT                                    0x3
+#define   SCU_RAM_ORX_SCU_STATE_FRQ_HUNT                                    0x4
+#define   SCU_RAM_ORX_SCU_STATE_PHA_HUNT                                    0x8
+#define   SCU_RAM_ORX_SCU_STATE_TIM_HUNT                                    0x10
+#define   SCU_RAM_ORX_SCU_STATE_EQU_HUNT                                    0x20
+#define   SCU_RAM_ORX_SCU_STATE_EQT_HUNT                                    0x30
+#define   SCU_RAM_ORX_SCU_STATE_SYNC                                        0x40
+
+#define SCU_RAM_ORX_SCU_LOCK__A                                             0x831F04
+#define SCU_RAM_ORX_SCU_LOCK__W                                             16
+#define SCU_RAM_ORX_SCU_LOCK__M                                             0xFFFF
+#define SCU_RAM_ORX_SCU_LOCK__PRE                                           0x0
+
+#define SCU_RAM_ORX_TARGET_MODE__A                                          0x831F05
+#define SCU_RAM_ORX_TARGET_MODE__W                                          2
+#define SCU_RAM_ORX_TARGET_MODE__M                                          0x3
+#define SCU_RAM_ORX_TARGET_MODE__PRE                                        0x0
+#define   SCU_RAM_ORX_TARGET_MODE_1544KBPS                                  0x0
+#define   SCU_RAM_ORX_TARGET_MODE_3088KBPS                                  0x1
+#define   SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT                             0x2
+#define   SCU_RAM_ORX_TARGET_MODE_2048KBPS_RO                               0x3
+
+#define SCU_RAM_ORX_MER_MIN_DB__A                                           0x831F06
+#define SCU_RAM_ORX_MER_MIN_DB__W                                           8
+#define SCU_RAM_ORX_MER_MIN_DB__M                                           0xFF
+#define SCU_RAM_ORX_MER_MIN_DB__PRE                                         0x0
+
+#define SCU_RAM_ORX_RF_GAIN__A                                              0x831F07
+#define SCU_RAM_ORX_RF_GAIN__W                                              16
+#define SCU_RAM_ORX_RF_GAIN__M                                              0xFFFF
+#define SCU_RAM_ORX_RF_GAIN__PRE                                            0x0
+
+#define SCU_RAM_ORX_RF_GAIN_MIN__A                                          0x831F08
+#define SCU_RAM_ORX_RF_GAIN_MIN__W                                          16
+#define SCU_RAM_ORX_RF_GAIN_MIN__M                                          0xFFFF
+#define SCU_RAM_ORX_RF_GAIN_MIN__PRE                                        0x0
+
+#define SCU_RAM_ORX_RF_GAIN_MAX__A                                          0x831F09
+#define SCU_RAM_ORX_RF_GAIN_MAX__W                                          16
+#define SCU_RAM_ORX_RF_GAIN_MAX__M                                          0xFFFF
+#define SCU_RAM_ORX_RF_GAIN_MAX__PRE                                        0x0
+
+#define SCU_RAM_ORX_IF_GAIN__A                                              0x831F0A
+#define SCU_RAM_ORX_IF_GAIN__W                                              16
+#define SCU_RAM_ORX_IF_GAIN__M                                              0xFFFF
+#define SCU_RAM_ORX_IF_GAIN__PRE                                            0x0
+
+#define SCU_RAM_ORX_IF_GAIN_MIN__A                                          0x831F0B
+#define SCU_RAM_ORX_IF_GAIN_MIN__W                                          16
+#define SCU_RAM_ORX_IF_GAIN_MIN__M                                          0xFFFF
+#define SCU_RAM_ORX_IF_GAIN_MIN__PRE                                        0x0
+
+#define SCU_RAM_ORX_IF_GAIN_MAX__A                                          0x831F0C
+#define SCU_RAM_ORX_IF_GAIN_MAX__W                                          16
+#define SCU_RAM_ORX_IF_GAIN_MAX__M                                          0xFFFF
+#define SCU_RAM_ORX_IF_GAIN_MAX__PRE                                        0x0
+
+#define SCU_RAM_ORX_AGN_HEADR__A                                            0x831F0D
+#define SCU_RAM_ORX_AGN_HEADR__W                                            16
+#define SCU_RAM_ORX_AGN_HEADR__M                                            0xFFFF
+#define SCU_RAM_ORX_AGN_HEADR__PRE                                          0x0
+
+#define SCU_RAM_ORX_AGN_HEADR_STP__A                                        0x831F0E
+#define SCU_RAM_ORX_AGN_HEADR_STP__W                                        8
+#define SCU_RAM_ORX_AGN_HEADR_STP__M                                        0xFF
+#define SCU_RAM_ORX_AGN_HEADR_STP__PRE                                      0x0
+
+#define SCU_RAM_ORX_AGN_KI__A                                               0x831F0F
+#define SCU_RAM_ORX_AGN_KI__W                                               8
+#define SCU_RAM_ORX_AGN_KI__M                                               0xFF
+#define SCU_RAM_ORX_AGN_KI__PRE                                             0x0
+
+#define SCU_RAM_ORX_AGN_LOCK_TH__A                                          0x831F10
+#define SCU_RAM_ORX_AGN_LOCK_TH__W                                          16
+#define SCU_RAM_ORX_AGN_LOCK_TH__M                                          0xFFFF
+#define SCU_RAM_ORX_AGN_LOCK_TH__PRE                                        0x0
+
+#define SCU_RAM_ORX_AGN_LOCK_WD__A                                          0x831F11
+#define SCU_RAM_ORX_AGN_LOCK_WD__W                                          16
+#define SCU_RAM_ORX_AGN_LOCK_WD__M                                          0xFFFF
+#define SCU_RAM_ORX_AGN_LOCK_WD__PRE                                        0x0
+
+#define SCU_RAM_ORX_AGN_ONLOCK_TTH__A                                       0x831F12
+#define SCU_RAM_ORX_AGN_ONLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_AGN_ONLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_AGN_ONLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_AGN_UNLOCK_TTH__A                                       0x831F13
+#define SCU_RAM_ORX_AGN_UNLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_AGN_UNLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_AGN_UNLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_AGN_LOCK_TOTH__A                                        0x831F14
+#define SCU_RAM_ORX_AGN_LOCK_TOTH__W                                        16
+#define SCU_RAM_ORX_AGN_LOCK_TOTH__M                                        0xFFFF
+#define SCU_RAM_ORX_AGN_LOCK_TOTH__PRE                                      0x0
+
+#define SCU_RAM_ORX_AGN_LOCK_MASK__A                                        0x831F15
+#define SCU_RAM_ORX_AGN_LOCK_MASK__W                                        8
+#define SCU_RAM_ORX_AGN_LOCK_MASK__M                                        0xFF
+#define SCU_RAM_ORX_AGN_LOCK_MASK__PRE                                      0x0
+
+#define SCU_RAM_ORX_DGN__A                                                  0x831F16
+#define SCU_RAM_ORX_DGN__W                                                  16
+#define SCU_RAM_ORX_DGN__M                                                  0xFFFF
+#define SCU_RAM_ORX_DGN__PRE                                                0x0
+
+#define SCU_RAM_ORX_DGN_MIN__A                                              0x831F17
+#define SCU_RAM_ORX_DGN_MIN__W                                              16
+#define SCU_RAM_ORX_DGN_MIN__M                                              0xFFFF
+#define SCU_RAM_ORX_DGN_MIN__PRE                                            0x0
+
+#define SCU_RAM_ORX_DGN_MAX__A                                              0x831F18
+#define SCU_RAM_ORX_DGN_MAX__W                                              16
+#define SCU_RAM_ORX_DGN_MAX__M                                              0xFFFF
+#define SCU_RAM_ORX_DGN_MAX__PRE                                            0x0
+
+#define SCU_RAM_ORX_DGN_AMP__A                                              0x831F19
+#define SCU_RAM_ORX_DGN_AMP__W                                              16
+#define SCU_RAM_ORX_DGN_AMP__M                                              0xFFFF
+#define SCU_RAM_ORX_DGN_AMP__PRE                                            0x0
+
+#define SCU_RAM_ORX_DGN_AMPTARGET__A                                        0x831F1A
+#define SCU_RAM_ORX_DGN_AMPTARGET__W                                        16
+#define SCU_RAM_ORX_DGN_AMPTARGET__M                                        0xFFFF
+#define SCU_RAM_ORX_DGN_AMPTARGET__PRE                                      0x0
+
+#define SCU_RAM_ORX_DGN_KI__A                                               0x831F1B
+#define SCU_RAM_ORX_DGN_KI__W                                               8
+#define SCU_RAM_ORX_DGN_KI__M                                               0xFF
+#define SCU_RAM_ORX_DGN_KI__PRE                                             0x0
+
+#define SCU_RAM_ORX_DGN_LOCK_TH__A                                          0x831F1C
+#define SCU_RAM_ORX_DGN_LOCK_TH__W                                          16
+#define SCU_RAM_ORX_DGN_LOCK_TH__M                                          0xFFFF
+#define SCU_RAM_ORX_DGN_LOCK_TH__PRE                                        0x0
+
+#define SCU_RAM_ORX_DGN_LOCK_WD__A                                          0x831F1D
+#define SCU_RAM_ORX_DGN_LOCK_WD__W                                          16
+#define SCU_RAM_ORX_DGN_LOCK_WD__M                                          0xFFFF
+#define SCU_RAM_ORX_DGN_LOCK_WD__PRE                                        0x0
+
+#define SCU_RAM_ORX_DGN_ONLOCK_TTH__A                                       0x831F1E
+#define SCU_RAM_ORX_DGN_ONLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_DGN_ONLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_DGN_ONLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_DGN_UNLOCK_TTH__A                                       0x831F1F
+#define SCU_RAM_ORX_DGN_UNLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_DGN_UNLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_DGN_UNLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_DGN_LOCK_TOTH__A                                        0x831F20
+#define SCU_RAM_ORX_DGN_LOCK_TOTH__W                                        16
+#define SCU_RAM_ORX_DGN_LOCK_TOTH__M                                        0xFFFF
+#define SCU_RAM_ORX_DGN_LOCK_TOTH__PRE                                      0x0
+
+#define SCU_RAM_ORX_DGN_LOCK_MASK__A                                        0x831F21
+#define SCU_RAM_ORX_DGN_LOCK_MASK__W                                        8
+#define SCU_RAM_ORX_DGN_LOCK_MASK__M                                        0xFF
+#define SCU_RAM_ORX_DGN_LOCK_MASK__PRE                                      0x0
+
+#define SCU_RAM_ORX_FREQ_GAIN_CORR__A                                       0x831F22
+#define SCU_RAM_ORX_FREQ_GAIN_CORR__W                                       8
+#define SCU_RAM_ORX_FREQ_GAIN_CORR__M                                       0xFF
+#define SCU_RAM_ORX_FREQ_GAIN_CORR__PRE                                     0x0
+#define   SCU_RAM_ORX_FREQ_GAIN_CORR_1544KBPS                               0x60
+#define   SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS                               0x80
+#define   SCU_RAM_ORX_FREQ_GAIN_CORR_3088KBPS                               0xC0
+
+#define SCU_RAM_ORX_FRQ_OFFSET__A                                           0x831F23
+#define SCU_RAM_ORX_FRQ_OFFSET__W                                           16
+#define SCU_RAM_ORX_FRQ_OFFSET__M                                           0xFFFF
+#define SCU_RAM_ORX_FRQ_OFFSET__PRE                                         0x0
+
+#define SCU_RAM_ORX_FRQ_OFFSET_MAX__A                                       0x831F24
+#define SCU_RAM_ORX_FRQ_OFFSET_MAX__W                                       15
+#define SCU_RAM_ORX_FRQ_OFFSET_MAX__M                                       0x7FFF
+#define SCU_RAM_ORX_FRQ_OFFSET_MAX__PRE                                     0x0
+
+#define SCU_RAM_ORX_FRQ_KI__A                                               0x831F25
+#define SCU_RAM_ORX_FRQ_KI__W                                               8
+#define SCU_RAM_ORX_FRQ_KI__M                                               0xFF
+#define SCU_RAM_ORX_FRQ_KI__PRE                                             0x0
+
+#define SCU_RAM_ORX_FRQ_DIFF__A                                             0x831F26
+#define SCU_RAM_ORX_FRQ_DIFF__W                                             16
+#define SCU_RAM_ORX_FRQ_DIFF__M                                             0xFFFF
+#define SCU_RAM_ORX_FRQ_DIFF__PRE                                           0x0
+
+#define SCU_RAM_ORX_FRQ_LOCK_TH__A                                          0x831F27
+#define SCU_RAM_ORX_FRQ_LOCK_TH__W                                          16
+#define SCU_RAM_ORX_FRQ_LOCK_TH__M                                          0xFFFF
+#define SCU_RAM_ORX_FRQ_LOCK_TH__PRE                                        0x0
+
+#define SCU_RAM_ORX_FRQ_LOCK_WD__A                                          0x831F28
+#define SCU_RAM_ORX_FRQ_LOCK_WD__W                                          16
+#define SCU_RAM_ORX_FRQ_LOCK_WD__M                                          0xFFFF
+#define SCU_RAM_ORX_FRQ_LOCK_WD__PRE                                        0x0
+
+#define SCU_RAM_ORX_FRQ_ONLOCK_TTH__A                                       0x831F29
+#define SCU_RAM_ORX_FRQ_ONLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_FRQ_ONLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_FRQ_ONLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_FRQ_UNLOCK_TTH__A                                       0x831F2A
+#define SCU_RAM_ORX_FRQ_UNLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_FRQ_UNLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_FRQ_UNLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_FRQ_LOCK_TOTH__A                                        0x831F2B
+#define SCU_RAM_ORX_FRQ_LOCK_TOTH__W                                        16
+#define SCU_RAM_ORX_FRQ_LOCK_TOTH__M                                        0xFFFF
+#define SCU_RAM_ORX_FRQ_LOCK_TOTH__PRE                                      0x0
+
+#define SCU_RAM_ORX_FRQ_LOCK_MASK__A                                        0x831F2C
+#define SCU_RAM_ORX_FRQ_LOCK_MASK__W                                        8
+#define SCU_RAM_ORX_FRQ_LOCK_MASK__M                                        0xFF
+#define SCU_RAM_ORX_FRQ_LOCK_MASK__PRE                                      0x0
+
+#define SCU_RAM_ORX_PHA_DIFF__A                                             0x831F2D
+#define SCU_RAM_ORX_PHA_DIFF__W                                             16
+#define SCU_RAM_ORX_PHA_DIFF__M                                             0xFFFF
+#define SCU_RAM_ORX_PHA_DIFF__PRE                                           0x0
+
+#define SCU_RAM_ORX_PHA_LOCK_TH__A                                          0x831F2E
+#define SCU_RAM_ORX_PHA_LOCK_TH__W                                          16
+#define SCU_RAM_ORX_PHA_LOCK_TH__M                                          0xFFFF
+#define SCU_RAM_ORX_PHA_LOCK_TH__PRE                                        0x0
+
+#define SCU_RAM_ORX_PHA_LOCK_WD__A                                          0x831F2F
+#define SCU_RAM_ORX_PHA_LOCK_WD__W                                          16
+#define SCU_RAM_ORX_PHA_LOCK_WD__M                                          0xFFFF
+#define SCU_RAM_ORX_PHA_LOCK_WD__PRE                                        0x0
+
+#define SCU_RAM_ORX_PHA_ONLOCK_TTH__A                                       0x831F30
+#define SCU_RAM_ORX_PHA_ONLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_PHA_ONLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_PHA_ONLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_PHA_UNLOCK_TTH__A                                       0x831F31
+#define SCU_RAM_ORX_PHA_UNLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_PHA_UNLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_PHA_UNLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_PHA_LOCK_TOTH__A                                        0x831F32
+#define SCU_RAM_ORX_PHA_LOCK_TOTH__W                                        16
+#define SCU_RAM_ORX_PHA_LOCK_TOTH__M                                        0xFFFF
+#define SCU_RAM_ORX_PHA_LOCK_TOTH__PRE                                      0x0
+
+#define SCU_RAM_ORX_PHA_LOCK_MASK__A                                        0x831F33
+#define SCU_RAM_ORX_PHA_LOCK_MASK__W                                        8
+#define SCU_RAM_ORX_PHA_LOCK_MASK__M                                        0xFF
+#define SCU_RAM_ORX_PHA_LOCK_MASK__PRE                                      0x0
+
+#define SCU_RAM_ORX_TIM_OFFSET__A                                           0x831F34
+#define SCU_RAM_ORX_TIM_OFFSET__W                                           16
+#define SCU_RAM_ORX_TIM_OFFSET__M                                           0xFFFF
+#define SCU_RAM_ORX_TIM_OFFSET__PRE                                         0x0
+
+#define SCU_RAM_ORX_TIM_DIFF__A                                             0x831F35
+#define SCU_RAM_ORX_TIM_DIFF__W                                             16
+#define SCU_RAM_ORX_TIM_DIFF__M                                             0xFFFF
+#define SCU_RAM_ORX_TIM_DIFF__PRE                                           0x0
+
+#define SCU_RAM_ORX_TIM_LOCK_TH__A                                          0x831F36
+#define SCU_RAM_ORX_TIM_LOCK_TH__W                                          16
+#define SCU_RAM_ORX_TIM_LOCK_TH__M                                          0xFFFF
+#define SCU_RAM_ORX_TIM_LOCK_TH__PRE                                        0x0
+
+#define SCU_RAM_ORX_TIM_LOCK_WD__A                                          0x831F37
+#define SCU_RAM_ORX_TIM_LOCK_WD__W                                          16
+#define SCU_RAM_ORX_TIM_LOCK_WD__M                                          0xFFFF
+#define SCU_RAM_ORX_TIM_LOCK_WD__PRE                                        0x0
+
+#define SCU_RAM_ORX_TIM_ONLOCK_TTH__A                                       0x831F38
+#define SCU_RAM_ORX_TIM_ONLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_TIM_ONLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_TIM_ONLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_TIM_UNLOCK_TTH__A                                       0x831F39
+#define SCU_RAM_ORX_TIM_UNLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_TIM_UNLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_TIM_UNLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_TIM_LOCK_TOTH__A                                        0x831F3A
+#define SCU_RAM_ORX_TIM_LOCK_TOTH__W                                        16
+#define SCU_RAM_ORX_TIM_LOCK_TOTH__M                                        0xFFFF
+#define SCU_RAM_ORX_TIM_LOCK_TOTH__PRE                                      0x0
+
+#define SCU_RAM_ORX_TIM_LOCK_MASK__A                                        0x831F3B
+#define SCU_RAM_ORX_TIM_LOCK_MASK__W                                        8
+#define SCU_RAM_ORX_TIM_LOCK_MASK__M                                        0xFF
+#define SCU_RAM_ORX_TIM_LOCK_MASK__PRE                                      0x0
+
+#define SCU_RAM_ORX_EQU_DIFF__A                                             0x831F3C
+#define SCU_RAM_ORX_EQU_DIFF__W                                             16
+#define SCU_RAM_ORX_EQU_DIFF__M                                             0xFFFF
+#define SCU_RAM_ORX_EQU_DIFF__PRE                                           0x0
+
+#define SCU_RAM_ORX_EQU_LOCK_TH__A                                          0x831F3D
+#define SCU_RAM_ORX_EQU_LOCK_TH__W                                          16
+#define SCU_RAM_ORX_EQU_LOCK_TH__M                                          0xFFFF
+#define SCU_RAM_ORX_EQU_LOCK_TH__PRE                                        0x0
+
+#define SCU_RAM_ORX_EQU_LOCK_WD__A                                          0x831F3E
+#define SCU_RAM_ORX_EQU_LOCK_WD__W                                          16
+#define SCU_RAM_ORX_EQU_LOCK_WD__M                                          0xFFFF
+#define SCU_RAM_ORX_EQU_LOCK_WD__PRE                                        0x0
+
+#define SCU_RAM_ORX_EQU_ONLOCK_TTH__A                                       0x831F3F
+#define SCU_RAM_ORX_EQU_ONLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_EQU_ONLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_EQU_ONLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_EQU_UNLOCK_TTH__A                                       0x831F40
+#define SCU_RAM_ORX_EQU_UNLOCK_TTH__W                                       16
+#define SCU_RAM_ORX_EQU_UNLOCK_TTH__M                                       0xFFFF
+#define SCU_RAM_ORX_EQU_UNLOCK_TTH__PRE                                     0x0
+
+#define SCU_RAM_ORX_EQU_LOCK_TOTH__A                                        0x831F41
+#define SCU_RAM_ORX_EQU_LOCK_TOTH__W                                        16
+#define SCU_RAM_ORX_EQU_LOCK_TOTH__M                                        0xFFFF
+#define SCU_RAM_ORX_EQU_LOCK_TOTH__PRE                                      0x0
+
+#define SCU_RAM_ORX_EQU_LOCK_MASK__A                                        0x831F42
+#define SCU_RAM_ORX_EQU_LOCK_MASK__W                                        8
+#define SCU_RAM_ORX_EQU_LOCK_MASK__M                                        0xFF
+#define SCU_RAM_ORX_EQU_LOCK_MASK__PRE                                      0x0
+
+#define SCU_RAM_ORX_FLT_FRQ__A                                              0x831F43
+#define SCU_RAM_ORX_FLT_FRQ__W                                              16
+#define SCU_RAM_ORX_FLT_FRQ__M                                              0xFFFF
+#define SCU_RAM_ORX_FLT_FRQ__PRE                                            0x0
+#define SCU_RAM_ORX_RST_CPH__A                                              0x831F44
+#define SCU_RAM_ORX_RST_CPH__W                                              4
+#define SCU_RAM_ORX_RST_CPH__M                                              0xF
+#define SCU_RAM_ORX_RST_CPH__PRE                                            0x0
+
+#define   SCU_RAM_ORX_RST_CPH_RST_CPH__B                                    0
+#define   SCU_RAM_ORX_RST_CPH_RST_CPH__W                                    4
+#define   SCU_RAM_ORX_RST_CPH_RST_CPH__M                                    0xF
+#define   SCU_RAM_ORX_RST_CPH_RST_CPH__PRE                                  0x0
+
+#define SCU_RAM_ORX_RST_CTI__A                                              0x831F45
+#define SCU_RAM_ORX_RST_CTI__W                                              4
+#define SCU_RAM_ORX_RST_CTI__M                                              0xF
+#define SCU_RAM_ORX_RST_CTI__PRE                                            0x0
+
+#define   SCU_RAM_ORX_RST_CTI_RST_CTI__B                                    0
+#define   SCU_RAM_ORX_RST_CTI_RST_CTI__W                                    4
+#define   SCU_RAM_ORX_RST_CTI_RST_CTI__M                                    0xF
+#define   SCU_RAM_ORX_RST_CTI_RST_CTI__PRE                                  0x0
+
+#define SCU_RAM_ORX_RST_KRN__A                                              0x831F46
+#define SCU_RAM_ORX_RST_KRN__W                                              4
+#define SCU_RAM_ORX_RST_KRN__M                                              0xF
+#define SCU_RAM_ORX_RST_KRN__PRE                                            0x0
+
+#define   SCU_RAM_ORX_RST_KRN_RST_KRN__B                                    0
+#define   SCU_RAM_ORX_RST_KRN_RST_KRN__W                                    4
+#define   SCU_RAM_ORX_RST_KRN_RST_KRN__M                                    0xF
+#define   SCU_RAM_ORX_RST_KRN_RST_KRN__PRE                                  0x0
+
+#define SCU_RAM_ORX_RST_KRP__A                                              0x831F47
+#define SCU_RAM_ORX_RST_KRP__W                                              4
+#define SCU_RAM_ORX_RST_KRP__M                                              0xF
+#define SCU_RAM_ORX_RST_KRP__PRE                                            0x0
+
+#define   SCU_RAM_ORX_RST_KRP_RST_KRP__B                                    0
+#define   SCU_RAM_ORX_RST_KRP_RST_KRP__W                                    4
+#define   SCU_RAM_ORX_RST_KRP_RST_KRP__M                                    0xF
+#define   SCU_RAM_ORX_RST_KRP_RST_KRP__PRE                                  0x0
+
+#define SCU_RAM_ATV_STANDARD__A                                             0x831F48
+#define SCU_RAM_ATV_STANDARD__W                                             12
+#define SCU_RAM_ATV_STANDARD__M                                             0xFFF
+#define SCU_RAM_ATV_STANDARD__PRE                                           0x0
+
+#define   SCU_RAM_ATV_STANDARD_STANDARD__B                                  0
+#define   SCU_RAM_ATV_STANDARD_STANDARD__W                                  12
+#define   SCU_RAM_ATV_STANDARD_STANDARD__M                                  0xFFF
+#define   SCU_RAM_ATV_STANDARD_STANDARD__PRE                                0x0
+#define     SCU_RAM_ATV_STANDARD_STANDARD_MN                                0x2
+#define     SCU_RAM_ATV_STANDARD_STANDARD_B                                 0x103
+#define     SCU_RAM_ATV_STANDARD_STANDARD_G                                 0x3
+#define     SCU_RAM_ATV_STANDARD_STANDARD_DK                                0x4
+#define     SCU_RAM_ATV_STANDARD_STANDARD_L                                 0x9
+#define     SCU_RAM_ATV_STANDARD_STANDARD_LP                                0x109
+#define     SCU_RAM_ATV_STANDARD_STANDARD_I                                 0xA
+#define     SCU_RAM_ATV_STANDARD_STANDARD_FM                                0x40
+
+#define SCU_RAM_ATV_DETECT__A                                               0x831F49
+#define SCU_RAM_ATV_DETECT__W                                               1
+#define SCU_RAM_ATV_DETECT__M                                               0x1
+#define SCU_RAM_ATV_DETECT__PRE                                             0x0
+
+#define   SCU_RAM_ATV_DETECT_DETECT__B                                      0
+#define   SCU_RAM_ATV_DETECT_DETECT__W                                      1
+#define   SCU_RAM_ATV_DETECT_DETECT__M                                      0x1
+#define   SCU_RAM_ATV_DETECT_DETECT__PRE                                    0x0
+#define     SCU_RAM_ATV_DETECT_DETECT_false                                 0x0
+#define     SCU_RAM_ATV_DETECT_DETECT_true                                  0x1
+
+#define SCU_RAM_ATV_DETECT_TH__A                                            0x831F4A
+#define SCU_RAM_ATV_DETECT_TH__W                                            8
+#define SCU_RAM_ATV_DETECT_TH__M                                            0xFF
+#define SCU_RAM_ATV_DETECT_TH__PRE                                          0x0
+
+#define   SCU_RAM_ATV_DETECT_TH_DETECT_TH__B                                0
+#define   SCU_RAM_ATV_DETECT_TH_DETECT_TH__W                                8
+#define   SCU_RAM_ATV_DETECT_TH_DETECT_TH__M                                0xFF
+#define   SCU_RAM_ATV_DETECT_TH_DETECT_TH__PRE                              0x0
+
+#define SCU_RAM_ATV_LOCK__A                                                 0x831F4B
+#define SCU_RAM_ATV_LOCK__W                                                 2
+#define SCU_RAM_ATV_LOCK__M                                                 0x3
+#define SCU_RAM_ATV_LOCK__PRE                                               0x0
+
+#define   SCU_RAM_ATV_LOCK_CR_LOCK_BIT__B                                   0
+#define   SCU_RAM_ATV_LOCK_CR_LOCK_BIT__W                                   1
+#define   SCU_RAM_ATV_LOCK_CR_LOCK_BIT__M                                   0x1
+#define   SCU_RAM_ATV_LOCK_CR_LOCK_BIT__PRE                                 0x0
+#define     SCU_RAM_ATV_LOCK_CR_LOCK_BIT_NO_LOCK                            0x0
+#define     SCU_RAM_ATV_LOCK_CR_LOCK_BIT_LOCK                               0x1
+
+#define   SCU_RAM_ATV_LOCK_SYNC_FLAG__B                                     1
+#define   SCU_RAM_ATV_LOCK_SYNC_FLAG__W                                     1
+#define   SCU_RAM_ATV_LOCK_SYNC_FLAG__M                                     0x2
+#define   SCU_RAM_ATV_LOCK_SYNC_FLAG__PRE                                   0x0
+#define     SCU_RAM_ATV_LOCK_SYNC_FLAG_NO_SYNC                              0x0
+#define     SCU_RAM_ATV_LOCK_SYNC_FLAG_SYNC                                 0x2
+
+#define SCU_RAM_ATV_CR_LOCK__A                                              0x831F4C
+#define SCU_RAM_ATV_CR_LOCK__W                                              11
+#define SCU_RAM_ATV_CR_LOCK__M                                              0x7FF
+#define SCU_RAM_ATV_CR_LOCK__PRE                                            0x0
+
+#define   SCU_RAM_ATV_CR_LOCK_CR_LOCK__B                                    0
+#define   SCU_RAM_ATV_CR_LOCK_CR_LOCK__W                                    11
+#define   SCU_RAM_ATV_CR_LOCK_CR_LOCK__M                                    0x7FF
+#define   SCU_RAM_ATV_CR_LOCK_CR_LOCK__PRE                                  0x0
+
+#define SCU_RAM_ATV_AGC_MODE__A                                             0x831F4D
+#define SCU_RAM_ATV_AGC_MODE__W                                             8
+#define SCU_RAM_ATV_AGC_MODE__M                                             0xFF
+#define SCU_RAM_ATV_AGC_MODE__PRE                                           0x0
+
+#define   SCU_RAM_ATV_AGC_MODE_VAGC_VEL__B                                  2
+#define   SCU_RAM_ATV_AGC_MODE_VAGC_VEL__W                                  1
+#define   SCU_RAM_ATV_AGC_MODE_VAGC_VEL__M                                  0x4
+#define   SCU_RAM_ATV_AGC_MODE_VAGC_VEL__PRE                                0x0
+#define     SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_FAST                          0x0
+#define     SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW                          0x4
+
+#define   SCU_RAM_ATV_AGC_MODE_BP_EN__B                                     3
+#define   SCU_RAM_ATV_AGC_MODE_BP_EN__W                                     1
+#define   SCU_RAM_ATV_AGC_MODE_BP_EN__M                                     0x8
+#define   SCU_RAM_ATV_AGC_MODE_BP_EN__PRE                                   0x0
+#define     SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_DISABLE                          0x0
+#define     SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE                           0x8
+
+#define   SCU_RAM_ATV_AGC_MODE_SIF_STD__B                                   4
+#define   SCU_RAM_ATV_AGC_MODE_SIF_STD__W                                   2
+#define   SCU_RAM_ATV_AGC_MODE_SIF_STD__M                                   0x30
+#define   SCU_RAM_ATV_AGC_MODE_SIF_STD__PRE                                 0x0
+#define     SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_OFF                        0x0
+#define     SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM                         0x10
+#define     SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM                         0x20
+
+#define   SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN__B                              6
+#define   SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN__W                              1
+#define   SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN__M                              0x40
+#define   SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN__PRE                            0x0
+#define     SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_DISABLE                  0x0
+#define     SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE                   0x40
+
+#define   SCU_RAM_ATV_AGC_MODE_MOD_WA_BP__B                                 7
+#define   SCU_RAM_ATV_AGC_MODE_MOD_WA_BP__W                                 1
+#define   SCU_RAM_ATV_AGC_MODE_MOD_WA_BP__M                                 0x80
+#define   SCU_RAM_ATV_AGC_MODE_MOD_WA_BP__PRE                               0x0
+#define     SCU_RAM_ATV_AGC_MODE_MOD_WA_BP_MWA_ENABLE                       0x0
+#define     SCU_RAM_ATV_AGC_MODE_MOD_WA_BP_MWA_DISABLE                      0x80
+
+#define SCU_RAM_ATV_RSV_01__A                                               0x831F4E
+#define SCU_RAM_ATV_RSV_01__W                                               16
+#define SCU_RAM_ATV_RSV_01__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_01__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_02__A                                               0x831F4F
+#define SCU_RAM_ATV_RSV_02__W                                               16
+#define SCU_RAM_ATV_RSV_02__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_02__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_03__A                                               0x831F50
+#define SCU_RAM_ATV_RSV_03__W                                               16
+#define SCU_RAM_ATV_RSV_03__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_03__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_04__A                                               0x831F51
+#define SCU_RAM_ATV_RSV_04__W                                               16
+#define SCU_RAM_ATV_RSV_04__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_04__PRE                                             0x0
+#define SCU_RAM_ATV_FAGC_TH_RED__A                                          0x831F52
+#define SCU_RAM_ATV_FAGC_TH_RED__W                                          8
+#define SCU_RAM_ATV_FAGC_TH_RED__M                                          0xFF
+#define SCU_RAM_ATV_FAGC_TH_RED__PRE                                        0x0
+
+#define   SCU_RAM_ATV_FAGC_TH_RED_FAGC_TH_RED__B                            0
+#define   SCU_RAM_ATV_FAGC_TH_RED_FAGC_TH_RED__W                            8
+#define   SCU_RAM_ATV_FAGC_TH_RED_FAGC_TH_RED__M                            0xFF
+#define   SCU_RAM_ATV_FAGC_TH_RED_FAGC_TH_RED__PRE                          0x0
+
+#define SCU_RAM_ATV_AMS_MAX_REF__A                                          0x831F53
+#define SCU_RAM_ATV_AMS_MAX_REF__W                                          11
+#define SCU_RAM_ATV_AMS_MAX_REF__M                                          0x7FF
+#define SCU_RAM_ATV_AMS_MAX_REF__PRE                                        0x0
+
+#define   SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF__B                            0
+#define   SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF__W                            11
+#define   SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF__M                            0x7FF
+#define   SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF__PRE                          0x0
+#define     SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN                       0x2BC
+#define     SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK                          0x2D0
+#define     SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I                           0x314
+#define     SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP                         0x28A
+
+#define SCU_RAM_ATV_ACT_AMX__A                                              0x831F54
+#define SCU_RAM_ATV_ACT_AMX__W                                              11
+#define SCU_RAM_ATV_ACT_AMX__M                                              0x7FF
+#define SCU_RAM_ATV_ACT_AMX__PRE                                            0x0
+
+#define   SCU_RAM_ATV_ACT_AMX_ACT_AMX__B                                    0
+#define   SCU_RAM_ATV_ACT_AMX_ACT_AMX__W                                    11
+#define   SCU_RAM_ATV_ACT_AMX_ACT_AMX__M                                    0x7FF
+#define   SCU_RAM_ATV_ACT_AMX_ACT_AMX__PRE                                  0x0
+
+#define SCU_RAM_ATV_ACT_AMI__A                                              0x831F55
+#define SCU_RAM_ATV_ACT_AMI__W                                              11
+#define SCU_RAM_ATV_ACT_AMI__M                                              0x7FF
+#define SCU_RAM_ATV_ACT_AMI__PRE                                            0x0
+
+#define   SCU_RAM_ATV_ACT_AMI_ACT_AMI__B                                    0
+#define   SCU_RAM_ATV_ACT_AMI_ACT_AMI__W                                    11
+#define   SCU_RAM_ATV_ACT_AMI_ACT_AMI__M                                    0x7FF
+#define   SCU_RAM_ATV_ACT_AMI_ACT_AMI__PRE                                  0x0
+
+#define SCU_RAM_ATV_RSV_05__A                                               0x831F56
+#define SCU_RAM_ATV_RSV_05__W                                               16
+#define SCU_RAM_ATV_RSV_05__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_05__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_06__A                                               0x831F57
+#define SCU_RAM_ATV_RSV_06__W                                               16
+#define SCU_RAM_ATV_RSV_06__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_06__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_07__A                                               0x831F58
+#define SCU_RAM_ATV_RSV_07__W                                               16
+#define SCU_RAM_ATV_RSV_07__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_07__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_08__A                                               0x831F59
+#define SCU_RAM_ATV_RSV_08__W                                               16
+#define SCU_RAM_ATV_RSV_08__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_08__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_09__A                                               0x831F5A
+#define SCU_RAM_ATV_RSV_09__W                                               16
+#define SCU_RAM_ATV_RSV_09__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_09__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_10__A                                               0x831F5B
+#define SCU_RAM_ATV_RSV_10__W                                               16
+#define SCU_RAM_ATV_RSV_10__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_10__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_11__A                                               0x831F5C
+#define SCU_RAM_ATV_RSV_11__W                                               16
+#define SCU_RAM_ATV_RSV_11__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_11__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_12__A                                               0x831F5D
+#define SCU_RAM_ATV_RSV_12__W                                               16
+#define SCU_RAM_ATV_RSV_12__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_12__PRE                                             0x0
+#define SCU_RAM_ATV_VID_GAIN_HI__A                                          0x831F5E
+#define SCU_RAM_ATV_VID_GAIN_HI__W                                          16
+#define SCU_RAM_ATV_VID_GAIN_HI__M                                          0xFFFF
+#define SCU_RAM_ATV_VID_GAIN_HI__PRE                                        0x0
+
+#define   SCU_RAM_ATV_VID_GAIN_HI_VID_GAIN_HI__B                            0
+#define   SCU_RAM_ATV_VID_GAIN_HI_VID_GAIN_HI__W                            16
+#define   SCU_RAM_ATV_VID_GAIN_HI_VID_GAIN_HI__M                            0xFFFF
+#define   SCU_RAM_ATV_VID_GAIN_HI_VID_GAIN_HI__PRE                          0x0
+
+#define SCU_RAM_ATV_VID_GAIN_LO__A                                          0x831F5F
+#define SCU_RAM_ATV_VID_GAIN_LO__W                                          8
+#define SCU_RAM_ATV_VID_GAIN_LO__M                                          0xFF
+#define SCU_RAM_ATV_VID_GAIN_LO__PRE                                        0x0
+
+#define   SCU_RAM_ATV_VID_GAIN_LO_VID_GAIN_LO__B                            0
+#define   SCU_RAM_ATV_VID_GAIN_LO_VID_GAIN_LO__W                            8
+#define   SCU_RAM_ATV_VID_GAIN_LO_VID_GAIN_LO__M                            0xFF
+#define   SCU_RAM_ATV_VID_GAIN_LO_VID_GAIN_LO__PRE                          0x0
+
+#define SCU_RAM_ATV_RSV_13__A                                               0x831F60
+#define SCU_RAM_ATV_RSV_13__W                                               16
+#define SCU_RAM_ATV_RSV_13__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_13__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_14__A                                               0x831F61
+#define SCU_RAM_ATV_RSV_14__W                                               16
+#define SCU_RAM_ATV_RSV_14__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_14__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_15__A                                               0x831F62
+#define SCU_RAM_ATV_RSV_15__W                                               16
+#define SCU_RAM_ATV_RSV_15__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_15__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_16__A                                               0x831F63
+#define SCU_RAM_ATV_RSV_16__W                                               16
+#define SCU_RAM_ATV_RSV_16__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_16__PRE                                             0x0
+#define SCU_RAM_ATV_AAGC_CNT__A                                             0x831F64
+#define SCU_RAM_ATV_AAGC_CNT__W                                             8
+#define SCU_RAM_ATV_AAGC_CNT__M                                             0xFF
+#define SCU_RAM_ATV_AAGC_CNT__PRE                                           0x0
+
+#define   SCU_RAM_ATV_AAGC_CNT_AAGC_CNT__B                                  0
+#define   SCU_RAM_ATV_AAGC_CNT_AAGC_CNT__W                                  8
+#define   SCU_RAM_ATV_AAGC_CNT_AAGC_CNT__M                                  0xFF
+#define   SCU_RAM_ATV_AAGC_CNT_AAGC_CNT__PRE                                0x0
+
+#define SCU_RAM_ATV_SIF_GAIN__A                                             0x831F65
+#define SCU_RAM_ATV_SIF_GAIN__W                                             11
+#define SCU_RAM_ATV_SIF_GAIN__M                                             0x7FF
+#define SCU_RAM_ATV_SIF_GAIN__PRE                                           0x0
+
+#define   SCU_RAM_ATV_SIF_GAIN_SIF_GAIN__B                                  0
+#define   SCU_RAM_ATV_SIF_GAIN_SIF_GAIN__W                                  11
+#define   SCU_RAM_ATV_SIF_GAIN_SIF_GAIN__M                                  0x7FF
+#define   SCU_RAM_ATV_SIF_GAIN_SIF_GAIN__PRE                                0x0
+
+#define SCU_RAM_ATV_RSV_17__A                                               0x831F66
+#define SCU_RAM_ATV_RSV_17__W                                               16
+#define SCU_RAM_ATV_RSV_17__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_17__PRE                                             0x0
+
+#define SCU_RAM_ATV_RSV_18__A                                               0x831F67
+#define SCU_RAM_ATV_RSV_18__W                                               16
+#define SCU_RAM_ATV_RSV_18__M                                               0xFFFF
+#define SCU_RAM_ATV_RSV_18__PRE                                             0x0
+
+#define SCU_RAM_ATV_RATE_OFS__A                                             0x831F68
+#define SCU_RAM_ATV_RATE_OFS__W                                             12
+#define SCU_RAM_ATV_RATE_OFS__M                                             0xFFF
+#define SCU_RAM_ATV_RATE_OFS__PRE                                           0x0
+
+#define SCU_RAM_ATV_LO_INCR__A                                              0x831F69
+#define SCU_RAM_ATV_LO_INCR__W                                              12
+#define SCU_RAM_ATV_LO_INCR__M                                              0xFFF
+#define SCU_RAM_ATV_LO_INCR__PRE                                            0x0
+
+#define SCU_RAM_ATV_IIR_CRIT__A                                             0x831F6A
+#define SCU_RAM_ATV_IIR_CRIT__W                                             12
+#define SCU_RAM_ATV_IIR_CRIT__M                                             0xFFF
+#define SCU_RAM_ATV_IIR_CRIT__PRE                                           0x0
+
+#define SCU_RAM_ATV_DEF_RATE_OFS__A                                         0x831F6B
+#define SCU_RAM_ATV_DEF_RATE_OFS__W                                         12
+#define SCU_RAM_ATV_DEF_RATE_OFS__M                                         0xFFF
+#define SCU_RAM_ATV_DEF_RATE_OFS__PRE                                       0x0
+
+#define SCU_RAM_ATV_DEF_LO_INCR__A                                          0x831F6C
+#define SCU_RAM_ATV_DEF_LO_INCR__W                                          12
+#define SCU_RAM_ATV_DEF_LO_INCR__M                                          0xFFF
+#define SCU_RAM_ATV_DEF_LO_INCR__PRE                                        0x0
+
+#define SCU_RAM_ATV_ENABLE_IIR_WA__A                                        0x831F6D
+#define SCU_RAM_ATV_ENABLE_IIR_WA__W                                        1
+#define SCU_RAM_ATV_ENABLE_IIR_WA__M                                        0x1
+#define SCU_RAM_ATV_ENABLE_IIR_WA__PRE                                      0x0
+
+#define SCU_RAM_ATV_MOD_CONTROL__A                                          0x831F6E
+#define SCU_RAM_ATV_MOD_CONTROL__W                                          12
+#define SCU_RAM_ATV_MOD_CONTROL__M                                          0xFFF
+#define SCU_RAM_ATV_MOD_CONTROL__PRE                                        0x0
+
+#define SCU_RAM_ATV_PAGC_KI_MAX__A                                          0x831F6F
+#define SCU_RAM_ATV_PAGC_KI_MAX__W                                          12
+#define SCU_RAM_ATV_PAGC_KI_MAX__M                                          0xFFF
+#define SCU_RAM_ATV_PAGC_KI_MAX__PRE                                        0x0
+
+#define SCU_RAM_ATV_BPC_KI_MAX__A                                           0x831F70
+#define SCU_RAM_ATV_BPC_KI_MAX__W                                           12
+#define SCU_RAM_ATV_BPC_KI_MAX__M                                           0xFFF
+#define SCU_RAM_ATV_BPC_KI_MAX__PRE                                         0x0
+
+#define SCU_RAM_ATV_NAGC_KI_MAX__A                                          0x831F71
+#define SCU_RAM_ATV_NAGC_KI_MAX__W                                          12
+#define SCU_RAM_ATV_NAGC_KI_MAX__M                                          0xFFF
+#define SCU_RAM_ATV_NAGC_KI_MAX__PRE                                        0x0
+#define SCU_RAM_ATV_NAGC_KI_MIN__A                                          0x831F72
+#define SCU_RAM_ATV_NAGC_KI_MIN__W                                          12
+#define SCU_RAM_ATV_NAGC_KI_MIN__M                                          0xFFF
+#define SCU_RAM_ATV_NAGC_KI_MIN__PRE                                        0x0
+
+#define   SCU_RAM_ATV_NAGC_KI_MIN_NAGC_KI_MIN__B                            0
+#define   SCU_RAM_ATV_NAGC_KI_MIN_NAGC_KI_MIN__W                            12
+#define   SCU_RAM_ATV_NAGC_KI_MIN_NAGC_KI_MIN__M                            0xFFF
+#define   SCU_RAM_ATV_NAGC_KI_MIN_NAGC_KI_MIN__PRE                          0x0
+
+#define SCU_RAM_ATV_KI_CHANGE_TH__A                                         0x831F73
+#define SCU_RAM_ATV_KI_CHANGE_TH__W                                         8
+#define SCU_RAM_ATV_KI_CHANGE_TH__M                                         0xFF
+#define SCU_RAM_ATV_KI_CHANGE_TH__PRE                                       0x0
+
+#define   SCU_RAM_ATV_KI_CHANGE_TH_KI_CHANGE_TH__B                          0
+#define   SCU_RAM_ATV_KI_CHANGE_TH_KI_CHANGE_TH__W                          8
+#define   SCU_RAM_ATV_KI_CHANGE_TH_KI_CHANGE_TH__M                          0xFF
+#define   SCU_RAM_ATV_KI_CHANGE_TH_KI_CHANGE_TH__PRE                        0x0
+#define     SCU_RAM_ATV_KI_CHANGE_TH_KI_CHANGE_TH_NEG_MOD                   0x14
+#define     SCU_RAM_ATV_KI_CHANGE_TH_KI_CHANGE_TH_POS_MOD                   0x28
+
+#define SCU_RAM_QAM_PARAM_ANNEX__A                                          0x831F74
+#define SCU_RAM_QAM_PARAM_ANNEX__W                                          2
+#define SCU_RAM_QAM_PARAM_ANNEX__M                                          0x3
+#define SCU_RAM_QAM_PARAM_ANNEX__PRE                                        0x0
+
+#define   SCU_RAM_QAM_PARAM_ANNEX_BIT__B                                    0
+#define   SCU_RAM_QAM_PARAM_ANNEX_BIT__W                                    2
+#define   SCU_RAM_QAM_PARAM_ANNEX_BIT__M                                    0x3
+#define   SCU_RAM_QAM_PARAM_ANNEX_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_PARAM_ANNEX_BIT_ANNEX_A                             0x0
+#define     SCU_RAM_QAM_PARAM_ANNEX_BIT_ANNEX_B                             0x1
+#define     SCU_RAM_QAM_PARAM_ANNEX_BIT_ANNEX_C                             0x2
+#define     SCU_RAM_QAM_PARAM_ANNEX_BIT_ANNEX_D                             0x3
+
+#define SCU_RAM_QAM_PARAM_CONSTELLATION__A                                  0x831F75
+#define SCU_RAM_QAM_PARAM_CONSTELLATION__W                                  3
+#define SCU_RAM_QAM_PARAM_CONSTELLATION__M                                  0x7
+#define SCU_RAM_QAM_PARAM_CONSTELLATION__PRE                                0x0
+
+#define   SCU_RAM_QAM_PARAM_CONSTELLATION_BIT__B                            0
+#define   SCU_RAM_QAM_PARAM_CONSTELLATION_BIT__W                            3
+#define   SCU_RAM_QAM_PARAM_CONSTELLATION_BIT__M                            0x7
+#define   SCU_RAM_QAM_PARAM_CONSTELLATION_BIT__PRE                          0x0
+#define     SCU_RAM_QAM_PARAM_CONSTELLATION_BIT_UNKNOWN                     0x0
+#define     SCU_RAM_QAM_PARAM_CONSTELLATION_BIT_QAM_16                      0x3
+#define     SCU_RAM_QAM_PARAM_CONSTELLATION_BIT_QAM_32                      0x4
+#define     SCU_RAM_QAM_PARAM_CONSTELLATION_BIT_QAM_64                      0x5
+#define     SCU_RAM_QAM_PARAM_CONSTELLATION_BIT_QAM_128                     0x6
+#define     SCU_RAM_QAM_PARAM_CONSTELLATION_BIT_QAM_256                     0x7
+
+#define SCU_RAM_QAM_PARAM_INTERLEAVE__A                                     0x831F76
+#define SCU_RAM_QAM_PARAM_INTERLEAVE__W                                     8
+#define SCU_RAM_QAM_PARAM_INTERLEAVE__M                                     0xFF
+#define SCU_RAM_QAM_PARAM_INTERLEAVE__PRE                                   0x0
+
+#define   SCU_RAM_QAM_PARAM_INTERLEAVE_BIT__B                               0
+#define   SCU_RAM_QAM_PARAM_INTERLEAVE_BIT__W                               8
+#define   SCU_RAM_QAM_PARAM_INTERLEAVE_BIT__M                               0xFF
+#define   SCU_RAM_QAM_PARAM_INTERLEAVE_BIT__PRE                             0x0
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J1                        0x0
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J1_V2                     0x1
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J2                        0x2
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I64_J2                         0x3
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J3                        0x4
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I32_J4                         0x5
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J4                        0x6
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I16_J8                         0x7
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J5                        0x8
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I8_J16                         0x9
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J6                        0xA
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J7                        0xC
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I128_J8                        0xE
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I12_J17                        0x10
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_I5_J4                          0x11
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_UNKNOWN                        0xFE
+#define     SCU_RAM_QAM_PARAM_INTERLEAVE_BIT_AUTO                           0xFF
+
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_HI__A                                  0x831F77
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_HI__W                                  16
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_HI__M                                  0xFFFF
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_HI__PRE                                0x0
+
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_HI_BIT__B                            0
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_HI_BIT__W                            16
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_HI_BIT__M                            0xFFFF
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_HI_BIT__PRE                          0x0
+
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_LO__A                                  0x831F78
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_LO__W                                  16
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_LO__M                                  0xFFFF
+#define SCU_RAM_QAM_PARAM_SYM_RCRATE_LO__PRE                                0x0
+
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_LO_BIT__B                            0
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_LO_BIT__W                            16
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_LO_BIT__M                            0xFFFF
+#define   SCU_RAM_QAM_PARAM_SYM_RCRATE_LO_BIT__PRE                          0x0
+
+#define SCU_RAM_QAM_EQ_CENTERTAP__A                                         0x831F79
+#define SCU_RAM_QAM_EQ_CENTERTAP__W                                         16
+#define SCU_RAM_QAM_EQ_CENTERTAP__M                                         0xFFFF
+#define SCU_RAM_QAM_EQ_CENTERTAP__PRE                                       0x0
+
+#define   SCU_RAM_QAM_EQ_CENTERTAP_BIT__B                                   0
+#define   SCU_RAM_QAM_EQ_CENTERTAP_BIT__W                                   8
+#define   SCU_RAM_QAM_EQ_CENTERTAP_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_EQ_CENTERTAP_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_WR_RSV_0__A                                             0x831F7A
+#define SCU_RAM_QAM_WR_RSV_0__W                                             16
+#define SCU_RAM_QAM_WR_RSV_0__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_0__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_0_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_0_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_0_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_0_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_HI__A                                  0x831F7B
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_HI__W                                  16
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_HI__M                                  0xFFFF
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_HI__PRE                                0x0
+
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_HI_BIT__B                            0
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_HI_BIT__W                            16
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_HI_BIT__M                            0xFFFF
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_HI_BIT__PRE                          0x0
+
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_LO__A                                  0x831F7C
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_LO__W                                  16
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_LO__M                                  0xFFFF
+#define SCU_RAM_QAM_PARAM_ALT_RCRATE_LO__PRE                                0x0
+
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_LO_BIT__B                            0
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_LO_BIT__W                            16
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_LO_BIT__M                            0xFFFF
+#define   SCU_RAM_QAM_PARAM_ALT_RCRATE_LO_BIT__PRE                          0x0
+
+#define SCU_RAM_QAM_WR_RSV_5__A                                             0x831F7D
+#define SCU_RAM_QAM_WR_RSV_5__W                                             16
+#define SCU_RAM_QAM_WR_RSV_5__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_5__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_5_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_5_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_5_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_5_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_6__A                                             0x831F7E
+#define SCU_RAM_QAM_WR_RSV_6__W                                             16
+#define SCU_RAM_QAM_WR_RSV_6__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_6__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_6_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_6_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_6_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_6_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_7__A                                             0x831F7F
+#define SCU_RAM_QAM_WR_RSV_7__W                                             16
+#define SCU_RAM_QAM_WR_RSV_7__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_7__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_7_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_7_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_7_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_7_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_8__A                                             0x831F80
+#define SCU_RAM_QAM_WR_RSV_8__W                                             16
+#define SCU_RAM_QAM_WR_RSV_8__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_8__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_8_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_8_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_8_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_8_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_9__A                                             0x831F81
+#define SCU_RAM_QAM_WR_RSV_9__W                                             16
+#define SCU_RAM_QAM_WR_RSV_9__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_9__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_9_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_9_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_9_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_9_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_10__A                                            0x831F82
+#define SCU_RAM_QAM_WR_RSV_10__W                                            16
+#define SCU_RAM_QAM_WR_RSV_10__M                                            0xFFFF
+#define SCU_RAM_QAM_WR_RSV_10__PRE                                          0x0
+
+#define   SCU_RAM_QAM_WR_RSV_10_BIT__B                                      0
+#define   SCU_RAM_QAM_WR_RSV_10_BIT__W                                      16
+#define   SCU_RAM_QAM_WR_RSV_10_BIT__M                                      0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_10_BIT__PRE                                    0x0
+
+#define SCU_RAM_QAM_FSM_FMHUM_TO__A                                         0x831F83
+#define SCU_RAM_QAM_FSM_FMHUM_TO__W                                         16
+#define SCU_RAM_QAM_FSM_FMHUM_TO__M                                         0xFFFF
+#define SCU_RAM_QAM_FSM_FMHUM_TO__PRE                                       0x0
+
+#define   SCU_RAM_QAM_FSM_FMHUM_TO_BIT__B                                   0
+#define   SCU_RAM_QAM_FSM_FMHUM_TO_BIT__W                                   16
+#define   SCU_RAM_QAM_FSM_FMHUM_TO_BIT__M                                   0xFFFF
+#define   SCU_RAM_QAM_FSM_FMHUM_TO_BIT__PRE                                 0x0
+#define     SCU_RAM_QAM_FSM_FMHUM_TO_BIT_NO_FMHUM_TO                        0x0
+
+#define SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A                                   0x831F84
+#define SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__W                                   16
+#define SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__M                                   0xFFFF
+#define SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__PRE                                 0x0
+
+#define   SCU_RAM_QAM_FSM_MEDIAN_AV_MULT_BIT__B                             0
+#define   SCU_RAM_QAM_FSM_MEDIAN_AV_MULT_BIT__W                             16
+#define   SCU_RAM_QAM_FSM_MEDIAN_AV_MULT_BIT__M                             0xFFFF
+#define   SCU_RAM_QAM_FSM_MEDIAN_AV_MULT_BIT__PRE                           0x0
+
+#define SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A                                  0x831F85
+#define SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__W                                  16
+#define SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__M                                  0xFFFF
+#define SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__PRE                                0x0
+
+#define   SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT_BIT__B                            0
+#define   SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT_BIT__W                            16
+#define   SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT_BIT__M                            0xFFFF
+#define   SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT_BIT__PRE                          0x0
+
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A                                    0x831F86
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET1__W                                    16
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET1__M                                    0xFFFF
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET1__PRE                                  0x0
+
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET1_BIT__B                              0
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET1_BIT__W                              16
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET1_BIT__M                              0xFFFF
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET1_BIT__PRE                            0x0
+
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A                                    0x831F87
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET2__W                                    16
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET2__M                                    0xFFFF
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET2__PRE                                  0x0
+
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET2_BIT__B                              0
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET2_BIT__W                              16
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET2_BIT__M                              0xFFFF
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET2_BIT__PRE                            0x0
+
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A                                    0x831F88
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET3__W                                    16
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET3__M                                    0xFFFF
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET3__PRE                                  0x0
+
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET3_BIT__B                              0
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET3_BIT__W                              16
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET3_BIT__M                              0xFFFF
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET3_BIT__PRE                            0x0
+
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A                                    0x831F89
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET4__W                                    16
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET4__M                                    0xFFFF
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET4__PRE                                  0x0
+
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET4_BIT__B                              0
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET4_BIT__W                              16
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET4_BIT__M                              0xFFFF
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET4_BIT__PRE                            0x0
+
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A                                    0x831F8A
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET5__W                                    16
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET5__M                                    0xFFFF
+#define SCU_RAM_QAM_FSM_LCAVG_OFFSET5__PRE                                  0x0
+
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET5_BIT__B                              0
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET5_BIT__W                              16
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET5_BIT__M                              0xFFFF
+#define   SCU_RAM_QAM_FSM_LCAVG_OFFSET5_BIT__PRE                            0x0
+
+#define SCU_RAM_QAM_FSM_STATE_TGT__A                                        0x831F8B
+#define SCU_RAM_QAM_FSM_STATE_TGT__W                                        4
+#define SCU_RAM_QAM_FSM_STATE_TGT__M                                        0xF
+#define SCU_RAM_QAM_FSM_STATE_TGT__PRE                                      0x0
+
+#define   SCU_RAM_QAM_FSM_STATE_TGT_BIT__B                                  0
+#define   SCU_RAM_QAM_FSM_STATE_TGT_BIT__W                                  4
+#define   SCU_RAM_QAM_FSM_STATE_TGT_BIT__M                                  0xF
+#define   SCU_RAM_QAM_FSM_STATE_TGT_BIT__PRE                                0x0
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_HUNTING_AMP                       0x0
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_HUNTING_RATE                      0x1
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_HUNTING_FREQ                      0x2
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_HUNTING_UPRIGHT                   0x3
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_HUNTING_PHASE                     0x4
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_TRACKING_PHNOISE                  0x5
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_TRACKING                          0x6
+#define     SCU_RAM_QAM_FSM_STATE_TGT_BIT_TRACKING_BURST                    0x7
+
+#define SCU_RAM_QAM_FSM_LOCK_OVERRIDE__A                                    0x831F8C
+#define SCU_RAM_QAM_FSM_LOCK_OVERRIDE__W                                    9
+#define SCU_RAM_QAM_FSM_LOCK_OVERRIDE__M                                    0x1FF
+#define SCU_RAM_QAM_FSM_LOCK_OVERRIDE__PRE                                  0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_OVERRIDE_LCK_AMP__B                          0
+#define   SCU_RAM_QAM_FSM_LOCK_OVERRIDE_LCK_AMP__W                          1
+#define   SCU_RAM_QAM_FSM_LOCK_OVERRIDE_LCK_AMP__M                          0x1
+#define   SCU_RAM_QAM_FSM_LOCK_OVERRIDE_LCK_AMP__PRE                        0x0
+
+#define SCU_RAM_QAM_FSM_ATH__A                                              0x831F8D
+#define SCU_RAM_QAM_FSM_ATH__W                                              16
+#define SCU_RAM_QAM_FSM_ATH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_ATH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_ATH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_ATH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_ATH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_ATH_BIT__PRE                                      0x0
+
+#define SCU_RAM_QAM_FSM_RTH__A                                              0x831F8E
+#define SCU_RAM_QAM_FSM_RTH__W                                              16
+#define SCU_RAM_QAM_FSM_RTH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_RTH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_RTH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_RTH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_RTH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_RTH_BIT__PRE                                      0x0
+#define     SCU_RAM_QAM_FSM_RTH_BIT_QAM_16                                  0x8C
+#define     SCU_RAM_QAM_FSM_RTH_BIT_QAM_32                                  0x50
+#define     SCU_RAM_QAM_FSM_RTH_BIT_QAM_64                                  0x4E
+#define     SCU_RAM_QAM_FSM_RTH_BIT_QAM_128                                 0x32
+#define     SCU_RAM_QAM_FSM_RTH_BIT_QAM_256                                 0x2D
+
+#define SCU_RAM_QAM_FSM_FTH__A                                              0x831F8F
+#define SCU_RAM_QAM_FSM_FTH__W                                              16
+#define SCU_RAM_QAM_FSM_FTH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_FTH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_FTH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_FTH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_FTH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_FTH_BIT__PRE                                      0x0
+#define     SCU_RAM_QAM_FSM_FTH_BIT_QAM_16                                  0x32
+#define     SCU_RAM_QAM_FSM_FTH_BIT_QAM_32                                  0x1E
+#define     SCU_RAM_QAM_FSM_FTH_BIT_QAM_64                                  0x1E
+#define     SCU_RAM_QAM_FSM_FTH_BIT_QAM_128                                 0x14
+#define     SCU_RAM_QAM_FSM_FTH_BIT_QAM_256                                 0x14
+
+#define SCU_RAM_QAM_FSM_PTH__A                                              0x831F90
+#define SCU_RAM_QAM_FSM_PTH__W                                              16
+#define SCU_RAM_QAM_FSM_PTH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_PTH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_PTH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_PTH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_PTH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_PTH_BIT__PRE                                      0x0
+#define     SCU_RAM_QAM_FSM_PTH_BIT_QAM_16                                  0xC8
+#define     SCU_RAM_QAM_FSM_PTH_BIT_QAM_32                                  0x96
+#define     SCU_RAM_QAM_FSM_PTH_BIT_QAM_64                                  0x8C
+#define     SCU_RAM_QAM_FSM_PTH_BIT_QAM_128                                 0x64
+#define     SCU_RAM_QAM_FSM_PTH_BIT_QAM_256                                 0x64
+
+#define SCU_RAM_QAM_FSM_MTH__A                                              0x831F91
+#define SCU_RAM_QAM_FSM_MTH__W                                              16
+#define SCU_RAM_QAM_FSM_MTH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_MTH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_MTH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_MTH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_MTH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_MTH_BIT__PRE                                      0x0
+#define     SCU_RAM_QAM_FSM_MTH_BIT_QAM_16                                  0x5A
+#define     SCU_RAM_QAM_FSM_MTH_BIT_QAM_32                                  0x50
+#define     SCU_RAM_QAM_FSM_MTH_BIT_QAM_64                                  0x46
+#define     SCU_RAM_QAM_FSM_MTH_BIT_QAM_128                                 0x3C
+#define     SCU_RAM_QAM_FSM_MTH_BIT_QAM_256                                 0x50
+
+#define SCU_RAM_QAM_FSM_CTH__A                                              0x831F92
+#define SCU_RAM_QAM_FSM_CTH__W                                              16
+#define SCU_RAM_QAM_FSM_CTH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_CTH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_CTH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_CTH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_CTH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_CTH_BIT__PRE                                      0x0
+#define     SCU_RAM_QAM_FSM_CTH_BIT_QAM_16                                  0xA0
+#define     SCU_RAM_QAM_FSM_CTH_BIT_QAM_32                                  0x8C
+#define     SCU_RAM_QAM_FSM_CTH_BIT_QAM_64                                  0x8C
+#define     SCU_RAM_QAM_FSM_CTH_BIT_QAM_128                                 0x8C
+#define     SCU_RAM_QAM_FSM_CTH_BIT_QAM_256                                 0x8C
+
+#define SCU_RAM_QAM_FSM_QTH__A                                              0x831F93
+#define SCU_RAM_QAM_FSM_QTH__W                                              16
+#define SCU_RAM_QAM_FSM_QTH__M                                              0xFFFF
+#define SCU_RAM_QAM_FSM_QTH__PRE                                            0x0
+
+#define   SCU_RAM_QAM_FSM_QTH_BIT__B                                        0
+#define   SCU_RAM_QAM_FSM_QTH_BIT__W                                        16
+#define   SCU_RAM_QAM_FSM_QTH_BIT__M                                        0xFFFF
+#define   SCU_RAM_QAM_FSM_QTH_BIT__PRE                                      0x0
+#define     SCU_RAM_QAM_FSM_QTH_BIT_QAM_16                                  0xE6
+#define     SCU_RAM_QAM_FSM_QTH_BIT_QAM_32                                  0xAA
+#define     SCU_RAM_QAM_FSM_QTH_BIT_QAM_64                                  0xC3
+#define     SCU_RAM_QAM_FSM_QTH_BIT_QAM_128                                 0x8C
+#define     SCU_RAM_QAM_FSM_QTH_BIT_QAM_256                                 0x96
+
+#define SCU_RAM_QAM_FSM_RATE_LIM__A                                         0x831F94
+#define SCU_RAM_QAM_FSM_RATE_LIM__W                                         16
+#define SCU_RAM_QAM_FSM_RATE_LIM__M                                         0xFFFF
+#define SCU_RAM_QAM_FSM_RATE_LIM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_FSM_RATE_LIM_BIT__B                                   0
+#define   SCU_RAM_QAM_FSM_RATE_LIM_BIT__W                                   16
+#define   SCU_RAM_QAM_FSM_RATE_LIM_BIT__M                                   0xFFFF
+#define   SCU_RAM_QAM_FSM_RATE_LIM_BIT__PRE                                 0x0
+#define     SCU_RAM_QAM_FSM_RATE_LIM_BIT_QAM_16                             0x46
+#define     SCU_RAM_QAM_FSM_RATE_LIM_BIT_QAM_32                             0x46
+#define     SCU_RAM_QAM_FSM_RATE_LIM_BIT_QAM_64                             0x46
+#define     SCU_RAM_QAM_FSM_RATE_LIM_BIT_QAM_128                            0x46
+#define     SCU_RAM_QAM_FSM_RATE_LIM_BIT_QAM_256                            0x46
+
+#define SCU_RAM_QAM_FSM_FREQ_LIM__A                                         0x831F95
+#define SCU_RAM_QAM_FSM_FREQ_LIM__W                                         16
+#define SCU_RAM_QAM_FSM_FREQ_LIM__M                                         0xFFFF
+#define SCU_RAM_QAM_FSM_FREQ_LIM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_FSM_FREQ_LIM_BIT__B                                   0
+#define   SCU_RAM_QAM_FSM_FREQ_LIM_BIT__W                                   16
+#define   SCU_RAM_QAM_FSM_FREQ_LIM_BIT__M                                   0xFFFF
+#define   SCU_RAM_QAM_FSM_FREQ_LIM_BIT__PRE                                 0x0
+#define     SCU_RAM_QAM_FSM_FREQ_LIM_BIT_QAM_16                             0x1E
+#define     SCU_RAM_QAM_FSM_FREQ_LIM_BIT_QAM_32                             0x14
+#define     SCU_RAM_QAM_FSM_FREQ_LIM_BIT_QAM_64                             0x28
+#define     SCU_RAM_QAM_FSM_FREQ_LIM_BIT_QAM_128                            0x8
+#define     SCU_RAM_QAM_FSM_FREQ_LIM_BIT_QAM_256                            0x28
+
+#define SCU_RAM_QAM_FSM_COUNT_LIM__A                                        0x831F96
+#define SCU_RAM_QAM_FSM_COUNT_LIM__W                                        16
+#define SCU_RAM_QAM_FSM_COUNT_LIM__M                                        0xFFFF
+#define SCU_RAM_QAM_FSM_COUNT_LIM__PRE                                      0x0
+
+#define   SCU_RAM_QAM_FSM_COUNT_LIM_BIT__B                                  0
+#define   SCU_RAM_QAM_FSM_COUNT_LIM_BIT__W                                  16
+#define   SCU_RAM_QAM_FSM_COUNT_LIM_BIT__M                                  0xFFFF
+#define   SCU_RAM_QAM_FSM_COUNT_LIM_BIT__PRE                                0x0
+#define     SCU_RAM_QAM_FSM_COUNT_LIM_BIT_QAM_16                            0x4
+#define     SCU_RAM_QAM_FSM_COUNT_LIM_BIT_QAM_32                            0x6
+#define     SCU_RAM_QAM_FSM_COUNT_LIM_BIT_QAM_64                            0x6
+#define     SCU_RAM_QAM_FSM_COUNT_LIM_BIT_QAM_128                           0x7
+#define     SCU_RAM_QAM_FSM_COUNT_LIM_BIT_QAM_256                           0x6
+
+#define SCU_RAM_QAM_LC_CA_COARSE__A                                         0x831F97
+#define SCU_RAM_QAM_LC_CA_COARSE__W                                         16
+#define SCU_RAM_QAM_LC_CA_COARSE__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CA_COARSE__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CA_COARSE_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CA_COARSE_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CA_COARSE_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CA_COARSE_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CA_MEDIUM__A                                         0x831F98
+#define SCU_RAM_QAM_LC_CA_MEDIUM__W                                         16
+#define SCU_RAM_QAM_LC_CA_MEDIUM__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CA_MEDIUM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CA_MEDIUM_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CA_MEDIUM_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CA_MEDIUM_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CA_MEDIUM_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CA_FINE__A                                           0x831F99
+#define SCU_RAM_QAM_LC_CA_FINE__W                                           16
+#define SCU_RAM_QAM_LC_CA_FINE__M                                           0xFFFF
+#define SCU_RAM_QAM_LC_CA_FINE__PRE                                         0x0
+
+#define   SCU_RAM_QAM_LC_CA_FINE_BIT__B                                     0
+#define   SCU_RAM_QAM_LC_CA_FINE_BIT__W                                     8
+#define   SCU_RAM_QAM_LC_CA_FINE_BIT__M                                     0xFF
+#define   SCU_RAM_QAM_LC_CA_FINE_BIT__PRE                                   0x0
+
+#define SCU_RAM_QAM_LC_CP_COARSE__A                                         0x831F9A
+#define SCU_RAM_QAM_LC_CP_COARSE__W                                         16
+#define SCU_RAM_QAM_LC_CP_COARSE__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CP_COARSE__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CP_COARSE_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CP_COARSE_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CP_COARSE_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CP_COARSE_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CP_MEDIUM__A                                         0x831F9B
+#define SCU_RAM_QAM_LC_CP_MEDIUM__W                                         16
+#define SCU_RAM_QAM_LC_CP_MEDIUM__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CP_MEDIUM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CP_MEDIUM_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CP_MEDIUM_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CP_MEDIUM_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CP_MEDIUM_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CP_FINE__A                                           0x831F9C
+#define SCU_RAM_QAM_LC_CP_FINE__W                                           16
+#define SCU_RAM_QAM_LC_CP_FINE__M                                           0xFFFF
+#define SCU_RAM_QAM_LC_CP_FINE__PRE                                         0x0
+
+#define   SCU_RAM_QAM_LC_CP_FINE_BIT__B                                     0
+#define   SCU_RAM_QAM_LC_CP_FINE_BIT__W                                     8
+#define   SCU_RAM_QAM_LC_CP_FINE_BIT__M                                     0xFF
+#define   SCU_RAM_QAM_LC_CP_FINE_BIT__PRE                                   0x0
+
+#define SCU_RAM_QAM_LC_CI_COARSE__A                                         0x831F9D
+#define SCU_RAM_QAM_LC_CI_COARSE__W                                         16
+#define SCU_RAM_QAM_LC_CI_COARSE__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CI_COARSE__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CI_COARSE_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CI_COARSE_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CI_COARSE_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CI_COARSE_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CI_MEDIUM__A                                         0x831F9E
+#define SCU_RAM_QAM_LC_CI_MEDIUM__W                                         16
+#define SCU_RAM_QAM_LC_CI_MEDIUM__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CI_MEDIUM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CI_MEDIUM_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CI_MEDIUM_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CI_MEDIUM_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CI_MEDIUM_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CI_FINE__A                                           0x831F9F
+#define SCU_RAM_QAM_LC_CI_FINE__W                                           16
+#define SCU_RAM_QAM_LC_CI_FINE__M                                           0xFFFF
+#define SCU_RAM_QAM_LC_CI_FINE__PRE                                         0x0
+
+#define   SCU_RAM_QAM_LC_CI_FINE_BIT__B                                     0
+#define   SCU_RAM_QAM_LC_CI_FINE_BIT__W                                     8
+#define   SCU_RAM_QAM_LC_CI_FINE_BIT__M                                     0xFF
+#define   SCU_RAM_QAM_LC_CI_FINE_BIT__PRE                                   0x0
+
+#define SCU_RAM_QAM_LC_EP_COARSE__A                                         0x831FA0
+#define SCU_RAM_QAM_LC_EP_COARSE__W                                         16
+#define SCU_RAM_QAM_LC_EP_COARSE__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_EP_COARSE__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_EP_COARSE_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_EP_COARSE_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_EP_COARSE_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_EP_COARSE_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_EP_MEDIUM__A                                         0x831FA1
+#define SCU_RAM_QAM_LC_EP_MEDIUM__W                                         16
+#define SCU_RAM_QAM_LC_EP_MEDIUM__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_EP_MEDIUM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_EP_MEDIUM_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_EP_MEDIUM_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_EP_MEDIUM_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_EP_MEDIUM_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_EP_FINE__A                                           0x831FA2
+#define SCU_RAM_QAM_LC_EP_FINE__W                                           16
+#define SCU_RAM_QAM_LC_EP_FINE__M                                           0xFFFF
+#define SCU_RAM_QAM_LC_EP_FINE__PRE                                         0x0
+
+#define   SCU_RAM_QAM_LC_EP_FINE_BIT__B                                     0
+#define   SCU_RAM_QAM_LC_EP_FINE_BIT__W                                     8
+#define   SCU_RAM_QAM_LC_EP_FINE_BIT__M                                     0xFF
+#define   SCU_RAM_QAM_LC_EP_FINE_BIT__PRE                                   0x0
+
+#define SCU_RAM_QAM_LC_EI_COARSE__A                                         0x831FA3
+#define SCU_RAM_QAM_LC_EI_COARSE__W                                         16
+#define SCU_RAM_QAM_LC_EI_COARSE__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_EI_COARSE__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_EI_COARSE_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_EI_COARSE_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_EI_COARSE_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_EI_COARSE_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_EI_MEDIUM__A                                         0x831FA4
+#define SCU_RAM_QAM_LC_EI_MEDIUM__W                                         16
+#define SCU_RAM_QAM_LC_EI_MEDIUM__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_EI_MEDIUM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_EI_MEDIUM_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_EI_MEDIUM_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_EI_MEDIUM_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_EI_MEDIUM_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_EI_FINE__A                                           0x831FA5
+#define SCU_RAM_QAM_LC_EI_FINE__W                                           16
+#define SCU_RAM_QAM_LC_EI_FINE__M                                           0xFFFF
+#define SCU_RAM_QAM_LC_EI_FINE__PRE                                         0x0
+
+#define   SCU_RAM_QAM_LC_EI_FINE_BIT__B                                     0
+#define   SCU_RAM_QAM_LC_EI_FINE_BIT__W                                     8
+#define   SCU_RAM_QAM_LC_EI_FINE_BIT__M                                     0xFF
+#define   SCU_RAM_QAM_LC_EI_FINE_BIT__PRE                                   0x0
+
+#define SCU_RAM_QAM_LC_CF_COARSE__A                                         0x831FA6
+#define SCU_RAM_QAM_LC_CF_COARSE__W                                         16
+#define SCU_RAM_QAM_LC_CF_COARSE__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CF_COARSE__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CF_COARSE_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CF_COARSE_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CF_COARSE_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CF_COARSE_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CF_MEDIUM__A                                         0x831FA7
+#define SCU_RAM_QAM_LC_CF_MEDIUM__W                                         16
+#define SCU_RAM_QAM_LC_CF_MEDIUM__M                                         0xFFFF
+#define SCU_RAM_QAM_LC_CF_MEDIUM__PRE                                       0x0
+
+#define   SCU_RAM_QAM_LC_CF_MEDIUM_BIT__B                                   0
+#define   SCU_RAM_QAM_LC_CF_MEDIUM_BIT__W                                   8
+#define   SCU_RAM_QAM_LC_CF_MEDIUM_BIT__M                                   0xFF
+#define   SCU_RAM_QAM_LC_CF_MEDIUM_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_LC_CF_FINE__A                                           0x831FA8
+#define SCU_RAM_QAM_LC_CF_FINE__W                                           16
+#define SCU_RAM_QAM_LC_CF_FINE__M                                           0xFFFF
+#define SCU_RAM_QAM_LC_CF_FINE__PRE                                         0x0
+
+#define   SCU_RAM_QAM_LC_CF_FINE_BIT__B                                     0
+#define   SCU_RAM_QAM_LC_CF_FINE_BIT__W                                     8
+#define   SCU_RAM_QAM_LC_CF_FINE_BIT__M                                     0xFF
+#define   SCU_RAM_QAM_LC_CF_FINE_BIT__PRE                                   0x0
+
+#define SCU_RAM_QAM_LC_CF1_COARSE__A                                        0x831FA9
+#define SCU_RAM_QAM_LC_CF1_COARSE__W                                        16
+#define SCU_RAM_QAM_LC_CF1_COARSE__M                                        0xFFFF
+#define SCU_RAM_QAM_LC_CF1_COARSE__PRE                                      0x0
+
+#define   SCU_RAM_QAM_LC_CF1_COARSE_BIT__B                                  0
+#define   SCU_RAM_QAM_LC_CF1_COARSE_BIT__W                                  8
+#define   SCU_RAM_QAM_LC_CF1_COARSE_BIT__M                                  0xFF
+#define   SCU_RAM_QAM_LC_CF1_COARSE_BIT__PRE                                0x0
+
+#define SCU_RAM_QAM_LC_CF1_MEDIUM__A                                        0x831FAA
+#define SCU_RAM_QAM_LC_CF1_MEDIUM__W                                        16
+#define SCU_RAM_QAM_LC_CF1_MEDIUM__M                                        0xFFFF
+#define SCU_RAM_QAM_LC_CF1_MEDIUM__PRE                                      0x0
+
+#define   SCU_RAM_QAM_LC_CF1_MEDIUM_BIT__B                                  0
+#define   SCU_RAM_QAM_LC_CF1_MEDIUM_BIT__W                                  8
+#define   SCU_RAM_QAM_LC_CF1_MEDIUM_BIT__M                                  0xFF
+#define   SCU_RAM_QAM_LC_CF1_MEDIUM_BIT__PRE                                0x0
+
+#define SCU_RAM_QAM_LC_CF1_FINE__A                                          0x831FAB
+#define SCU_RAM_QAM_LC_CF1_FINE__W                                          16
+#define SCU_RAM_QAM_LC_CF1_FINE__M                                          0xFFFF
+#define SCU_RAM_QAM_LC_CF1_FINE__PRE                                        0x0
+
+#define   SCU_RAM_QAM_LC_CF1_FINE_BIT__B                                    0
+#define   SCU_RAM_QAM_LC_CF1_FINE_BIT__W                                    8
+#define   SCU_RAM_QAM_LC_CF1_FINE_BIT__M                                    0xFF
+#define   SCU_RAM_QAM_LC_CF1_FINE_BIT__PRE                                  0x0
+
+#define SCU_RAM_QAM_SL_SIG_POWER__A                                         0x831FAC
+#define SCU_RAM_QAM_SL_SIG_POWER__W                                         16
+#define SCU_RAM_QAM_SL_SIG_POWER__M                                         0xFFFF
+#define SCU_RAM_QAM_SL_SIG_POWER__PRE                                       0x0
+
+#define   SCU_RAM_QAM_SL_SIG_POWER_BIT__B                                   0
+#define   SCU_RAM_QAM_SL_SIG_POWER_BIT__W                                   16
+#define   SCU_RAM_QAM_SL_SIG_POWER_BIT__M                                   0xFFFF
+#define   SCU_RAM_QAM_SL_SIG_POWER_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_EQ_CMA_RAD0__A                                          0x831FAD
+#define SCU_RAM_QAM_EQ_CMA_RAD0__W                                          14
+#define SCU_RAM_QAM_EQ_CMA_RAD0__M                                          0x3FFF
+#define SCU_RAM_QAM_EQ_CMA_RAD0__PRE                                        0x0
+
+#define   SCU_RAM_QAM_EQ_CMA_RAD0_BIT__B                                    0
+#define   SCU_RAM_QAM_EQ_CMA_RAD0_BIT__W                                    14
+#define   SCU_RAM_QAM_EQ_CMA_RAD0_BIT__M                                    0x3FFF
+#define   SCU_RAM_QAM_EQ_CMA_RAD0_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_EQ_CMA_RAD0_BIT_QAM_16                              0x34CD
+#define     SCU_RAM_QAM_EQ_CMA_RAD0_BIT_QAM_32                              0x1A33
+#define     SCU_RAM_QAM_EQ_CMA_RAD0_BIT_QAM_64                              0x3418
+#define     SCU_RAM_QAM_EQ_CMA_RAD0_BIT_QAM_128                             0x1814
+#define     SCU_RAM_QAM_EQ_CMA_RAD0_BIT_QAM_256                             0x2CEE
+
+#define SCU_RAM_QAM_EQ_CMA_RAD1__A                                          0x831FAE
+#define SCU_RAM_QAM_EQ_CMA_RAD1__W                                          14
+#define SCU_RAM_QAM_EQ_CMA_RAD1__M                                          0x3FFF
+#define SCU_RAM_QAM_EQ_CMA_RAD1__PRE                                        0x0
+
+#define   SCU_RAM_QAM_EQ_CMA_RAD1_BIT__B                                    0
+#define   SCU_RAM_QAM_EQ_CMA_RAD1_BIT__W                                    14
+#define   SCU_RAM_QAM_EQ_CMA_RAD1_BIT__M                                    0x3FFF
+#define   SCU_RAM_QAM_EQ_CMA_RAD1_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_EQ_CMA_RAD1_BIT_QAM_16                              0x34CD
+#define     SCU_RAM_QAM_EQ_CMA_RAD1_BIT_QAM_32                              0x1A33
+#define     SCU_RAM_QAM_EQ_CMA_RAD1_BIT_QAM_64                              0x314A
+#define     SCU_RAM_QAM_EQ_CMA_RAD1_BIT_QAM_128                             0x19C6
+#define     SCU_RAM_QAM_EQ_CMA_RAD1_BIT_QAM_256                             0x2F34
+
+#define SCU_RAM_QAM_EQ_CMA_RAD2__A                                          0x831FAF
+#define SCU_RAM_QAM_EQ_CMA_RAD2__W                                          14
+#define SCU_RAM_QAM_EQ_CMA_RAD2__M                                          0x3FFF
+#define SCU_RAM_QAM_EQ_CMA_RAD2__PRE                                        0x0
+
+#define   SCU_RAM_QAM_EQ_CMA_RAD2_BIT__B                                    0
+#define   SCU_RAM_QAM_EQ_CMA_RAD2_BIT__W                                    14
+#define   SCU_RAM_QAM_EQ_CMA_RAD2_BIT__M                                    0x3FFF
+#define   SCU_RAM_QAM_EQ_CMA_RAD2_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_EQ_CMA_RAD2_BIT_QAM_16                              0x34CD
+#define     SCU_RAM_QAM_EQ_CMA_RAD2_BIT_QAM_32                              0x1A33
+#define     SCU_RAM_QAM_EQ_CMA_RAD2_BIT_QAM_64                              0x2ED4
+#define     SCU_RAM_QAM_EQ_CMA_RAD2_BIT_QAM_128                             0x18FA
+#define     SCU_RAM_QAM_EQ_CMA_RAD2_BIT_QAM_256                             0x30FF
+
+#define SCU_RAM_QAM_EQ_CMA_RAD3__A                                          0x831FB0
+#define SCU_RAM_QAM_EQ_CMA_RAD3__W                                          14
+#define SCU_RAM_QAM_EQ_CMA_RAD3__M                                          0x3FFF
+#define SCU_RAM_QAM_EQ_CMA_RAD3__PRE                                        0x0
+
+#define   SCU_RAM_QAM_EQ_CMA_RAD3_BIT__B                                    0
+#define   SCU_RAM_QAM_EQ_CMA_RAD3_BIT__W                                    14
+#define   SCU_RAM_QAM_EQ_CMA_RAD3_BIT__M                                    0x3FFF
+#define   SCU_RAM_QAM_EQ_CMA_RAD3_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_EQ_CMA_RAD3_BIT_QAM_16                              0x34CD
+#define     SCU_RAM_QAM_EQ_CMA_RAD3_BIT_QAM_32                              0x1A33
+#define     SCU_RAM_QAM_EQ_CMA_RAD3_BIT_QAM_64                              0x35F1
+#define     SCU_RAM_QAM_EQ_CMA_RAD3_BIT_QAM_128                             0x1909
+#define     SCU_RAM_QAM_EQ_CMA_RAD3_BIT_QAM_256                             0x3283
+
+#define SCU_RAM_QAM_EQ_CMA_RAD4__A                                          0x831FB1
+#define SCU_RAM_QAM_EQ_CMA_RAD4__W                                          14
+#define SCU_RAM_QAM_EQ_CMA_RAD4__M                                          0x3FFF
+#define SCU_RAM_QAM_EQ_CMA_RAD4__PRE                                        0x0
+
+#define   SCU_RAM_QAM_EQ_CMA_RAD4_BIT__B                                    0
+#define   SCU_RAM_QAM_EQ_CMA_RAD4_BIT__W                                    14
+#define   SCU_RAM_QAM_EQ_CMA_RAD4_BIT__M                                    0x3FFF
+#define   SCU_RAM_QAM_EQ_CMA_RAD4_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_EQ_CMA_RAD4_BIT_QAM_16                              0x34CD
+#define     SCU_RAM_QAM_EQ_CMA_RAD4_BIT_QAM_32                              0x1A33
+#define     SCU_RAM_QAM_EQ_CMA_RAD4_BIT_QAM_64                              0x35F1
+#define     SCU_RAM_QAM_EQ_CMA_RAD4_BIT_QAM_128                             0x1A00
+#define     SCU_RAM_QAM_EQ_CMA_RAD4_BIT_QAM_256                             0x353D
+
+#define SCU_RAM_QAM_EQ_CMA_RAD5__A                                          0x831FB2
+#define SCU_RAM_QAM_EQ_CMA_RAD5__W                                          14
+#define SCU_RAM_QAM_EQ_CMA_RAD5__M                                          0x3FFF
+#define SCU_RAM_QAM_EQ_CMA_RAD5__PRE                                        0x0
+
+#define   SCU_RAM_QAM_EQ_CMA_RAD5_BIT__B                                    0
+#define   SCU_RAM_QAM_EQ_CMA_RAD5_BIT__W                                    14
+#define   SCU_RAM_QAM_EQ_CMA_RAD5_BIT__M                                    0x3FFF
+#define   SCU_RAM_QAM_EQ_CMA_RAD5_BIT__PRE                                  0x0
+#define     SCU_RAM_QAM_EQ_CMA_RAD5_BIT_QAM_16                              0x34CD
+#define     SCU_RAM_QAM_EQ_CMA_RAD5_BIT_QAM_32                              0x1A33
+#define     SCU_RAM_QAM_EQ_CMA_RAD5_BIT_QAM_64                              0x3CF9
+#define     SCU_RAM_QAM_EQ_CMA_RAD5_BIT_QAM_128                             0x1C46
+#define     SCU_RAM_QAM_EQ_CMA_RAD5_BIT_QAM_256                             0x3C19
+
+#define SCU_RAM_QAM_CTL_ENA__A                                              0x831FB3
+#define SCU_RAM_QAM_CTL_ENA__W                                              16
+#define SCU_RAM_QAM_CTL_ENA__M                                              0xFFFF
+#define SCU_RAM_QAM_CTL_ENA__PRE                                            0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_AMP__B                                        0
+#define   SCU_RAM_QAM_CTL_ENA_AMP__W                                        1
+#define   SCU_RAM_QAM_CTL_ENA_AMP__M                                        0x1
+#define   SCU_RAM_QAM_CTL_ENA_AMP__PRE                                      0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_ACQ__B                                        1
+#define   SCU_RAM_QAM_CTL_ENA_ACQ__W                                        1
+#define   SCU_RAM_QAM_CTL_ENA_ACQ__M                                        0x2
+#define   SCU_RAM_QAM_CTL_ENA_ACQ__PRE                                      0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_EQU__B                                        2
+#define   SCU_RAM_QAM_CTL_ENA_EQU__W                                        1
+#define   SCU_RAM_QAM_CTL_ENA_EQU__M                                        0x4
+#define   SCU_RAM_QAM_CTL_ENA_EQU__PRE                                      0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_SLC__B                                        3
+#define   SCU_RAM_QAM_CTL_ENA_SLC__W                                        1
+#define   SCU_RAM_QAM_CTL_ENA_SLC__M                                        0x8
+#define   SCU_RAM_QAM_CTL_ENA_SLC__PRE                                      0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_LC__B                                         4
+#define   SCU_RAM_QAM_CTL_ENA_LC__W                                         1
+#define   SCU_RAM_QAM_CTL_ENA_LC__M                                         0x10
+#define   SCU_RAM_QAM_CTL_ENA_LC__PRE                                       0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_AGC__B                                        5
+#define   SCU_RAM_QAM_CTL_ENA_AGC__W                                        1
+#define   SCU_RAM_QAM_CTL_ENA_AGC__M                                        0x20
+#define   SCU_RAM_QAM_CTL_ENA_AGC__PRE                                      0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_FEC__B                                        6
+#define   SCU_RAM_QAM_CTL_ENA_FEC__W                                        1
+#define   SCU_RAM_QAM_CTL_ENA_FEC__M                                        0x40
+#define   SCU_RAM_QAM_CTL_ENA_FEC__PRE                                      0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_AXIS__B                                       7
+#define   SCU_RAM_QAM_CTL_ENA_AXIS__W                                       1
+#define   SCU_RAM_QAM_CTL_ENA_AXIS__M                                       0x80
+#define   SCU_RAM_QAM_CTL_ENA_AXIS__PRE                                     0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_FMHUM__B                                      8
+#define   SCU_RAM_QAM_CTL_ENA_FMHUM__W                                      1
+#define   SCU_RAM_QAM_CTL_ENA_FMHUM__M                                      0x100
+#define   SCU_RAM_QAM_CTL_ENA_FMHUM__PRE                                    0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_EQTIME__B                                     9
+#define   SCU_RAM_QAM_CTL_ENA_EQTIME__W                                     1
+#define   SCU_RAM_QAM_CTL_ENA_EQTIME__M                                     0x200
+#define   SCU_RAM_QAM_CTL_ENA_EQTIME__PRE                                   0x0
+
+#define   SCU_RAM_QAM_CTL_ENA_EXTLCK__B                                     10
+#define   SCU_RAM_QAM_CTL_ENA_EXTLCK__W                                     1
+#define   SCU_RAM_QAM_CTL_ENA_EXTLCK__M                                     0x400
+#define   SCU_RAM_QAM_CTL_ENA_EXTLCK__PRE                                   0x0
+
+#define SCU_RAM_QAM_WR_RSV_1__A                                             0x831FB4
+#define SCU_RAM_QAM_WR_RSV_1__W                                             16
+#define SCU_RAM_QAM_WR_RSV_1__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_1__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_1_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_1_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_1_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_1_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_2__A                                             0x831FB5
+#define SCU_RAM_QAM_WR_RSV_2__W                                             16
+#define SCU_RAM_QAM_WR_RSV_2__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_2__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_2_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_2_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_2_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_2_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_WR_RSV_3__A                                             0x831FB6
+#define SCU_RAM_QAM_WR_RSV_3__W                                             16
+#define SCU_RAM_QAM_WR_RSV_3__M                                             0xFFFF
+#define SCU_RAM_QAM_WR_RSV_3__PRE                                           0x0
+
+#define   SCU_RAM_QAM_WR_RSV_3_BIT__B                                       0
+#define   SCU_RAM_QAM_WR_RSV_3_BIT__W                                       16
+#define   SCU_RAM_QAM_WR_RSV_3_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_WR_RSV_3_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_ACTIVE_CONSTELLATION__A                                 0x831FB7
+#define SCU_RAM_QAM_ACTIVE_CONSTELLATION__W                                 3
+#define SCU_RAM_QAM_ACTIVE_CONSTELLATION__M                                 0x7
+#define SCU_RAM_QAM_ACTIVE_CONSTELLATION__PRE                               0x0
+
+#define   SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT__B                           0
+#define   SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT__W                           3
+#define   SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT__M                           0x7
+#define   SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT__PRE                         0x0
+#define     SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT_UNKNOWN                    0x0
+#define     SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT_QAM_16                     0x3
+#define     SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT_QAM_32                     0x4
+#define     SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT_QAM_64                     0x5
+#define     SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT_QAM_128                    0x6
+#define     SCU_RAM_QAM_ACTIVE_CONSTELLATION_BIT_QAM_256                    0x7
+
+#define SCU_RAM_QAM_ACTIVE_INTERLEAVE__A                                    0x831FB8
+#define SCU_RAM_QAM_ACTIVE_INTERLEAVE__W                                    8
+#define SCU_RAM_QAM_ACTIVE_INTERLEAVE__M                                    0xFF
+#define SCU_RAM_QAM_ACTIVE_INTERLEAVE__PRE                                  0x0
+
+#define   SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT__B                              0
+#define   SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT__W                              8
+#define   SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT__M                              0xFF
+#define   SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT__PRE                            0x0
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J1                       0x0
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J1_V2                    0x1
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J2                       0x2
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I64_J2                        0x3
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J3                       0x4
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I32_J4                        0x5
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J4                       0x6
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I16_J8                        0x7
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J5                       0x8
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I8_J16                        0x9
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J6                       0xA
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J7                       0xC
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I128_J8                       0xE
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I12_J17                       0x10
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_I5_J4                         0x11
+#define     SCU_RAM_QAM_ACTIVE_INTERLEAVE_BIT_UNKNOWN                       0xFE
+
+#define SCU_RAM_QAM_RD_RSV_4__A                                             0x831FB9
+#define SCU_RAM_QAM_RD_RSV_4__W                                             16
+#define SCU_RAM_QAM_RD_RSV_4__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_4__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_4_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_4_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_4_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_4_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_LOCKED__A                                               0x831FBA
+#define SCU_RAM_QAM_LOCKED__W                                               16
+#define SCU_RAM_QAM_LOCKED__M                                               0xFFFF
+#define SCU_RAM_QAM_LOCKED__PRE                                             0x0
+
+#define   SCU_RAM_QAM_LOCKED_INTLEVEL__B                                    0
+#define   SCU_RAM_QAM_LOCKED_INTLEVEL__W                                    8
+#define   SCU_RAM_QAM_LOCKED_INTLEVEL__M                                    0xFF
+#define   SCU_RAM_QAM_LOCKED_INTLEVEL__PRE                                  0x0
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_NOT_LOCKED                          0x0
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_AMP_OK                              0x1
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_RATE_OK                             0x2
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_FREQ_OK                             0x3
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_UPRIGHT_OK                          0x4
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_PHNOISE_OK                          0x5
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_TRACK_OK                            0x6
+#define     SCU_RAM_QAM_LOCKED_INTLEVEL_IMPNOISE_OK                         0x7
+
+#define   SCU_RAM_QAM_LOCKED_LOCKED__B                                      8
+#define   SCU_RAM_QAM_LOCKED_LOCKED__W                                      8
+#define   SCU_RAM_QAM_LOCKED_LOCKED__M                                      0xFF00
+#define   SCU_RAM_QAM_LOCKED_LOCKED__PRE                                    0x0
+#define     SCU_RAM_QAM_LOCKED_LOCKED_NOT_LOCKED                            0x0
+#define     SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED                          0x4000
+#define     SCU_RAM_QAM_LOCKED_LOCKED_LOCKED                                0x8000
+#define     SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK                            0xC000
+
+#define SCU_RAM_QAM_EVENTS_OCC_HI__A                                        0x831FBB
+#define SCU_RAM_QAM_EVENTS_OCC_HI__W                                        16
+#define SCU_RAM_QAM_EVENTS_OCC_HI__M                                        0xFFFF
+#define SCU_RAM_QAM_EVENTS_OCC_HI__PRE                                      0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PREBER__B                               0
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PREBER__W                               1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PREBER__M                               0x1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PREBER__PRE                             0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PACKET_FAIL__B                          1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PACKET_FAIL__W                          1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PACKET_FAIL__M                          0x2
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PACKET_FAIL__PRE                        0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PRBS__B                                 2
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PRBS__W                                 1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PRBS__M                                 0x4
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_PRBS__PRE                               0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_IN__B                           3
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_IN__W                           1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_IN__M                           0x8
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_IN__PRE                         0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_OUT__B                          4
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_OUT__W                          1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_OUT__M                          0x10
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_LOCK_OUT__PRE                        0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_POSTBER__B                              5
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_POSTBER__W                              1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_POSTBER__M                              0x20
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_POSTBER__PRE                            0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_FULL__B                            6
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_FULL__W                            1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_FULL__M                            0x40
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_FULL__PRE                          0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_EMPTY__B                           7
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_EMPTY__W                           1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_EMPTY__M                           0x80
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FIFO_EMPTY__PRE                         0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_GRAB__B                              8
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_GRAB__W                              1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_GRAB__M                              0x100
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_GRAB__PRE                            0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_CHANGE__B                            9
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_CHANGE__W                            1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_CHANGE__M                            0x200
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_OC_CHANGE__PRE                          0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_LCK_CHG__B                              10
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_LCK_CHG__W                              1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_LCK_CHG__M                              0x400
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_LCK_CHG__PRE                            0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FSM_CHG__B                              11
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FSM_CHG__W                              1
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FSM_CHG__M                              0x800
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_FSM_CHG__PRE                            0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_RSV__B                                  12
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_RSV__W                                  4
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_RSV__M                                  0xF000
+#define   SCU_RAM_QAM_EVENTS_OCC_HI_RSV__PRE                                0x0
+
+#define SCU_RAM_QAM_EVENTS_OCC_LO__A                                        0x831FBC
+#define SCU_RAM_QAM_EVENTS_OCC_LO__W                                        16
+#define SCU_RAM_QAM_EVENTS_OCC_LO__M                                        0xFFFF
+#define SCU_RAM_QAM_EVENTS_OCC_LO__PRE                                      0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_TIMER__B                                0
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_TIMER__W                                1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_TIMER__M                                0x1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_TIMER__PRE                              0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_CLIP__B                                 1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_CLIP__W                                 1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_CLIP__M                                 0x2
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_CLIP__PRE                               0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SENSE__B                                2
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SENSE__W                                1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SENSE__M                                0x4
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SENSE__PRE                              0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_POWER__B                                3
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_POWER__W                                1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_POWER__M                                0x8
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_POWER__PRE                              0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MEDIAN__B                               4
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MEDIAN__W                               1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MEDIAN__M                               0x10
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MEDIAN__PRE                             0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MER__B                                  5
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MER__W                                  1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MER__M                                  0x20
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_MER__PRE                                0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_LOOP__B                                 6
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_LOOP__W                                 1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_LOOP__M                                 0x40
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_LOOP__PRE                               0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_FREQWRAP__B                             7
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_FREQWRAP__W                             1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_FREQWRAP__M                             0x80
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_FREQWRAP__PRE                           0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SER__B                                  8
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SER__W                                  1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SER__M                                  0x100
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SER__PRE                                0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_VD_LOCK_IN__B                           9
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_VD_LOCK_IN__W                           1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_VD_LOCK_IN__M                           0x200
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_VD_LOCK_IN__PRE                         0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_IN__B                           10
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_IN__W                           1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_IN__M                           0x400
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_IN__PRE                         0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_OUT__B                          11
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_OUT__W                          1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_OUT__M                          0x800
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_LOCK_OUT__PRE                        0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_TIME_OUT__B                          12
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_TIME_OUT__W                          1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_TIME_OUT__M                          0x1000
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SY_TIME_OUT__PRE                        0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SYNCWORD__B                             13
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SYNCWORD__W                             1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SYNCWORD__M                             0x2000
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_SYNCWORD__PRE                           0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_IN__B                           14
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_IN__W                           1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_IN__M                           0x4000
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_IN__PRE                         0x0
+
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_OUT__B                          15
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_OUT__W                          1
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_OUT__M                          0x8000
+#define   SCU_RAM_QAM_EVENTS_OCC_LO_DI_LOCK_OUT__PRE                        0x0
+
+#define SCU_RAM_QAM_EVENTS_SCHED_HI__A                                      0x831FBD
+#define SCU_RAM_QAM_EVENTS_SCHED_HI__W                                      16
+#define SCU_RAM_QAM_EVENTS_SCHED_HI__M                                      0xFFFF
+#define SCU_RAM_QAM_EVENTS_SCHED_HI__PRE                                    0x0
+
+#define   SCU_RAM_QAM_EVENTS_SCHED_HI_BIT__B                                0
+#define   SCU_RAM_QAM_EVENTS_SCHED_HI_BIT__W                                16
+#define   SCU_RAM_QAM_EVENTS_SCHED_HI_BIT__M                                0xFFFF
+#define   SCU_RAM_QAM_EVENTS_SCHED_HI_BIT__PRE                              0x0
+
+#define SCU_RAM_QAM_EVENTS_SCHED_LO__A                                      0x831FBE
+#define SCU_RAM_QAM_EVENTS_SCHED_LO__W                                      16
+#define SCU_RAM_QAM_EVENTS_SCHED_LO__M                                      0xFFFF
+#define SCU_RAM_QAM_EVENTS_SCHED_LO__PRE                                    0x0
+
+#define   SCU_RAM_QAM_EVENTS_SCHED_LO_BIT__B                                0
+#define   SCU_RAM_QAM_EVENTS_SCHED_LO_BIT__W                                16
+#define   SCU_RAM_QAM_EVENTS_SCHED_LO_BIT__M                                0xFFFF
+#define   SCU_RAM_QAM_EVENTS_SCHED_LO_BIT__PRE                              0x0
+
+#define SCU_RAM_QAM_TASKLETS_SCHED__A                                       0x831FBF
+#define SCU_RAM_QAM_TASKLETS_SCHED__W                                       16
+#define SCU_RAM_QAM_TASKLETS_SCHED__M                                       0xFFFF
+#define SCU_RAM_QAM_TASKLETS_SCHED__PRE                                     0x0
+
+#define   SCU_RAM_QAM_TASKLETS_SCHED_BIT__B                                 0
+#define   SCU_RAM_QAM_TASKLETS_SCHED_BIT__W                                 16
+#define   SCU_RAM_QAM_TASKLETS_SCHED_BIT__M                                 0xFFFF
+#define   SCU_RAM_QAM_TASKLETS_SCHED_BIT__PRE                               0x0
+
+#define SCU_RAM_QAM_TASKLETS_RUN__A                                         0x831FC0
+#define SCU_RAM_QAM_TASKLETS_RUN__W                                         16
+#define SCU_RAM_QAM_TASKLETS_RUN__M                                         0xFFFF
+#define SCU_RAM_QAM_TASKLETS_RUN__PRE                                       0x0
+
+#define   SCU_RAM_QAM_TASKLETS_RUN_BIT__B                                   0
+#define   SCU_RAM_QAM_TASKLETS_RUN_BIT__W                                   16
+#define   SCU_RAM_QAM_TASKLETS_RUN_BIT__M                                   0xFFFF
+#define   SCU_RAM_QAM_TASKLETS_RUN_BIT__PRE                                 0x0
+
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI__A                                 0x831FC1
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI__W                                 16
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI__M                                 0xFFFF
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI__PRE                               0x0
+
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI_BIT__B                           0
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI_BIT__W                           16
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI_BIT__M                           0xFFFF
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_HI_BIT__PRE                         0x0
+
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO__A                                 0x831FC2
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO__W                                 16
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO__M                                 0xFFFF
+#define SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO__PRE                               0x0
+
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO_BIT__B                           0
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO_BIT__W                           16
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO_BIT__M                           0xFFFF
+#define   SCU_RAM_QAM_ACTIVE_SYM_RCRATE_LO_BIT__PRE                         0x0
+
+#define SCU_RAM_QAM_RD_RSV_5__A                                             0x831FC3
+#define SCU_RAM_QAM_RD_RSV_5__W                                             16
+#define SCU_RAM_QAM_RD_RSV_5__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_5__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_5_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_5_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_5_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_5_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_6__A                                             0x831FC4
+#define SCU_RAM_QAM_RD_RSV_6__W                                             16
+#define SCU_RAM_QAM_RD_RSV_6__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_6__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_6_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_6_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_6_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_6_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_7__A                                             0x831FC5
+#define SCU_RAM_QAM_RD_RSV_7__W                                             16
+#define SCU_RAM_QAM_RD_RSV_7__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_7__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_7_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_7_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_7_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_7_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_8__A                                             0x831FC6
+#define SCU_RAM_QAM_RD_RSV_8__W                                             16
+#define SCU_RAM_QAM_RD_RSV_8__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_8__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_8_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_8_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_8_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_8_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_9__A                                             0x831FC7
+#define SCU_RAM_QAM_RD_RSV_9__W                                             16
+#define SCU_RAM_QAM_RD_RSV_9__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_9__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_9_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_9_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_9_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_9_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_10__A                                            0x831FC8
+#define SCU_RAM_QAM_RD_RSV_10__W                                            16
+#define SCU_RAM_QAM_RD_RSV_10__M                                            0xFFFF
+#define SCU_RAM_QAM_RD_RSV_10__PRE                                          0x0
+
+#define   SCU_RAM_QAM_RD_RSV_10_BIT__B                                      0
+#define   SCU_RAM_QAM_RD_RSV_10_BIT__W                                      16
+#define   SCU_RAM_QAM_RD_RSV_10_BIT__M                                      0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_10_BIT__PRE                                    0x0
+
+#define SCU_RAM_QAM_AGC_TPOW_OFFS__A                                        0x831FC9
+#define SCU_RAM_QAM_AGC_TPOW_OFFS__W                                        16
+#define SCU_RAM_QAM_AGC_TPOW_OFFS__M                                        0xFFFF
+#define SCU_RAM_QAM_AGC_TPOW_OFFS__PRE                                      0x0
+
+#define   SCU_RAM_QAM_AGC_TPOW_OFFS_BIT__B                                  0
+#define   SCU_RAM_QAM_AGC_TPOW_OFFS_BIT__W                                  16
+#define   SCU_RAM_QAM_AGC_TPOW_OFFS_BIT__M                                  0xFFFF
+#define   SCU_RAM_QAM_AGC_TPOW_OFFS_BIT__PRE                                0x0
+
+#define SCU_RAM_QAM_FSM_STATE__A                                            0x831FCA
+#define SCU_RAM_QAM_FSM_STATE__W                                            4
+#define SCU_RAM_QAM_FSM_STATE__M                                            0xF
+#define SCU_RAM_QAM_FSM_STATE__PRE                                          0x0
+
+#define   SCU_RAM_QAM_FSM_STATE_BIT__B                                      0
+#define   SCU_RAM_QAM_FSM_STATE_BIT__W                                      4
+#define   SCU_RAM_QAM_FSM_STATE_BIT__M                                      0xF
+#define   SCU_RAM_QAM_FSM_STATE_BIT__PRE                                    0x0
+#define     SCU_RAM_QAM_FSM_STATE_BIT_HUNTING_AMP                           0x0
+#define     SCU_RAM_QAM_FSM_STATE_BIT_HUNTING_RATE                          0x1
+#define     SCU_RAM_QAM_FSM_STATE_BIT_HUNTING_FREQ                          0x2
+#define     SCU_RAM_QAM_FSM_STATE_BIT_HUNTING_UPRIGHT                       0x3
+#define     SCU_RAM_QAM_FSM_STATE_BIT_HUNTING_PHASE                         0x4
+#define     SCU_RAM_QAM_FSM_STATE_BIT_TRACKING_PHNOISE                      0x5
+#define     SCU_RAM_QAM_FSM_STATE_BIT_TRACKING                              0x6
+#define     SCU_RAM_QAM_FSM_STATE_BIT_TRACKING_BURST                        0x7
+
+#define SCU_RAM_QAM_FSM_STATE_NEW__A                                        0x831FCB
+#define SCU_RAM_QAM_FSM_STATE_NEW__W                                        4
+#define SCU_RAM_QAM_FSM_STATE_NEW__M                                        0xF
+#define SCU_RAM_QAM_FSM_STATE_NEW__PRE                                      0x0
+
+#define   SCU_RAM_QAM_FSM_STATE_NEW_BIT__B                                  0
+#define   SCU_RAM_QAM_FSM_STATE_NEW_BIT__W                                  4
+#define   SCU_RAM_QAM_FSM_STATE_NEW_BIT__M                                  0xF
+#define   SCU_RAM_QAM_FSM_STATE_NEW_BIT__PRE                                0x0
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_HUNTING_AMP                       0x0
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_HUNTING_RATE                      0x1
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_HUNTING_FREQ                      0x2
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_HUNTING_UPRIGHT                   0x3
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_HUNTING_PHASE                     0x4
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_TRACKING_PHNOISE                  0x5
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_TRACKING                          0x6
+#define     SCU_RAM_QAM_FSM_STATE_NEW_BIT_TRACKING_BURST                    0x7
+
+#define SCU_RAM_QAM_FSM_LOCK_FLAGS__A                                       0x831FCC
+#define SCU_RAM_QAM_FSM_LOCK_FLAGS__W                                       9
+#define SCU_RAM_QAM_FSM_LOCK_FLAGS__M                                       0x1FF
+#define SCU_RAM_QAM_FSM_LOCK_FLAGS__PRE                                     0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_AMP__B                             0
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_AMP__W                             1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_AMP__M                             0x1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_AMP__PRE                           0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RATEVAR__B                         1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RATEVAR__W                         1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RATEVAR__M                         0x2
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RATEVAR__PRE                       0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RADIUS__B                          2
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RADIUS__W                          1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RADIUS__M                          0x4
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_RADIUS__PRE                        0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQ__B                            3
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQ__W                            1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQ__M                            0x8
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQ__PRE                          0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQVAR__B                         4
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQVAR__W                         1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQVAR__M                         0x10
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_FREQVAR__PRE                       0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_CPHASE__B                          5
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_CPHASE__W                          1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_CPHASE__M                          0x20
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_CPHASE__PRE                        0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_UPRIGHT__B                         6
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_UPRIGHT__W                         1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_UPRIGHT__M                         0x40
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_UPRIGHT__PRE                       0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_PHASE__B                           7
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_PHASE__W                           1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_PHASE__M                           0x80
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_PHASE__PRE                         0x0
+
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_MEDIAN__B                          8
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_MEDIAN__W                          1
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_MEDIAN__M                          0x100
+#define   SCU_RAM_QAM_FSM_LOCK_FLAGS_LCK_MEDIAN__PRE                        0x0
+
+#define SCU_RAM_QAM_FSM_RATE_VARIATION__A                                   0x831FCD
+#define SCU_RAM_QAM_FSM_RATE_VARIATION__W                                   16
+#define SCU_RAM_QAM_FSM_RATE_VARIATION__M                                   0xFFFF
+#define SCU_RAM_QAM_FSM_RATE_VARIATION__PRE                                 0x0
+
+#define   SCU_RAM_QAM_FSM_RATE_VARIATION_BIT__B                             0
+#define   SCU_RAM_QAM_FSM_RATE_VARIATION_BIT__W                             16
+#define   SCU_RAM_QAM_FSM_RATE_VARIATION_BIT__M                             0xFFFF
+#define   SCU_RAM_QAM_FSM_RATE_VARIATION_BIT__PRE                           0x0
+
+#define SCU_RAM_QAM_FSM_FREQ_VARIATION__A                                   0x831FCE
+#define SCU_RAM_QAM_FSM_FREQ_VARIATION__W                                   16
+#define SCU_RAM_QAM_FSM_FREQ_VARIATION__M                                   0xFFFF
+#define SCU_RAM_QAM_FSM_FREQ_VARIATION__PRE                                 0x0
+
+#define   SCU_RAM_QAM_FSM_FREQ_VARIATION_BIT__B                             0
+#define   SCU_RAM_QAM_FSM_FREQ_VARIATION_BIT__W                             16
+#define   SCU_RAM_QAM_FSM_FREQ_VARIATION_BIT__M                             0xFFFF
+#define   SCU_RAM_QAM_FSM_FREQ_VARIATION_BIT__PRE                           0x0
+
+#define SCU_RAM_QAM_ERR_STATE__A                                            0x831FCF
+#define SCU_RAM_QAM_ERR_STATE__W                                            4
+#define SCU_RAM_QAM_ERR_STATE__M                                            0xF
+#define SCU_RAM_QAM_ERR_STATE__PRE                                          0x0
+
+#define   SCU_RAM_QAM_ERR_STATE_BIT__B                                      0
+#define   SCU_RAM_QAM_ERR_STATE_BIT__W                                      4
+#define   SCU_RAM_QAM_ERR_STATE_BIT__M                                      0xF
+#define   SCU_RAM_QAM_ERR_STATE_BIT__PRE                                    0x0
+#define     SCU_RAM_QAM_ERR_STATE_BIT_HUNTING_AMP                           0x0
+#define     SCU_RAM_QAM_ERR_STATE_BIT_HUNTING_RATE                          0x1
+#define     SCU_RAM_QAM_ERR_STATE_BIT_HUNTING_FREQ                          0x2
+#define     SCU_RAM_QAM_ERR_STATE_BIT_HUNTING_UPRIGHT                       0x3
+#define     SCU_RAM_QAM_ERR_STATE_BIT_HUNTING_PHASE                         0x4
+#define     SCU_RAM_QAM_ERR_STATE_BIT_TRACKING_PHNOISE                      0x5
+#define     SCU_RAM_QAM_ERR_STATE_BIT_TRACKING                              0x6
+#define     SCU_RAM_QAM_ERR_STATE_BIT_TRACKING_BURST                        0x7
+
+#define SCU_RAM_QAM_ERR_LOCK_FLAGS__A                                       0x831FD0
+#define SCU_RAM_QAM_ERR_LOCK_FLAGS__W                                       9
+#define SCU_RAM_QAM_ERR_LOCK_FLAGS__M                                       0x1FF
+#define SCU_RAM_QAM_ERR_LOCK_FLAGS__PRE                                     0x0
+
+#define   SCU_RAM_QAM_ERR_LOCK_FLAGS_LCK_AMP__B                             0
+#define   SCU_RAM_QAM_ERR_LOCK_FLAGS_LCK_AMP__W                             1
+#define   SCU_RAM_QAM_ERR_LOCK_FLAGS_LCK_AMP__M                             0x1
+#define   SCU_RAM_QAM_ERR_LOCK_FLAGS_LCK_AMP__PRE                           0x0
+
+#define SCU_RAM_QAM_EQ_LOCK__A                                              0x831FD1
+#define SCU_RAM_QAM_EQ_LOCK__W                                              1
+#define SCU_RAM_QAM_EQ_LOCK__M                                              0x1
+#define SCU_RAM_QAM_EQ_LOCK__PRE                                            0x0
+
+#define   SCU_RAM_QAM_EQ_LOCK_BIT__B                                        0
+#define   SCU_RAM_QAM_EQ_LOCK_BIT__W                                        1
+#define   SCU_RAM_QAM_EQ_LOCK_BIT__M                                        0x1
+#define   SCU_RAM_QAM_EQ_LOCK_BIT__PRE                                      0x0
+
+#define SCU_RAM_QAM_EQ_STATE__A                                             0x831FD2
+#define SCU_RAM_QAM_EQ_STATE__W                                             16
+#define SCU_RAM_QAM_EQ_STATE__M                                             0xFFFF
+#define SCU_RAM_QAM_EQ_STATE__PRE                                           0x0
+
+#define   SCU_RAM_QAM_EQ_STATE_BIT__B                                       0
+#define   SCU_RAM_QAM_EQ_STATE_BIT__W                                       16
+#define   SCU_RAM_QAM_EQ_STATE_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_EQ_STATE_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_0__A                                             0x831FD3
+#define SCU_RAM_QAM_RD_RSV_0__W                                             16
+#define SCU_RAM_QAM_RD_RSV_0__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_0__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_0_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_0_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_0_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_0_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_1__A                                             0x831FD4
+#define SCU_RAM_QAM_RD_RSV_1__W                                             16
+#define SCU_RAM_QAM_RD_RSV_1__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_1__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_1_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_1_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_1_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_1_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_2__A                                             0x831FD5
+#define SCU_RAM_QAM_RD_RSV_2__W                                             16
+#define SCU_RAM_QAM_RD_RSV_2__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_2__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_2_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_2_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_2_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_2_BIT__PRE                                     0x0
+
+#define SCU_RAM_QAM_RD_RSV_3__A                                             0x831FD6
+#define SCU_RAM_QAM_RD_RSV_3__W                                             16
+#define SCU_RAM_QAM_RD_RSV_3__M                                             0xFFFF
+#define SCU_RAM_QAM_RD_RSV_3__PRE                                           0x0
+
+#define   SCU_RAM_QAM_RD_RSV_3_BIT__B                                       0
+#define   SCU_RAM_QAM_RD_RSV_3_BIT__W                                       16
+#define   SCU_RAM_QAM_RD_RSV_3_BIT__M                                       0xFFFF
+#define   SCU_RAM_QAM_RD_RSV_3_BIT__PRE                                     0x0
+
+#define SCU_RAM_VSB_CTL_MODE__A                                             0x831FD7
+#define SCU_RAM_VSB_CTL_MODE__W                                             2
+#define SCU_RAM_VSB_CTL_MODE__M                                             0x3
+#define SCU_RAM_VSB_CTL_MODE__PRE                                           0x0
+
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_AGC__B                          0
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_AGC__W                          1
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_AGC__M                          0x1
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_AGC__PRE                        0x0
+#define     SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_AGC_OFF                       0x0
+#define     SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_AGC_ON                        0x1
+
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_MON__B                          1
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_MON__W                          1
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_MON__M                          0x2
+#define   SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_MON__PRE                        0x0
+#define     SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_MON_OFF                       0x0
+#define     SCU_RAM_VSB_CTL_MODE_VSB_CTL_MODE_MON_ON                        0x2
+
+#define SCU_RAM_VSB_NOTCH_THRESHOLD__A                                      0x831FD8
+#define SCU_RAM_VSB_NOTCH_THRESHOLD__W                                      16
+#define SCU_RAM_VSB_NOTCH_THRESHOLD__M                                      0xFFFF
+#define SCU_RAM_VSB_NOTCH_THRESHOLD__PRE                                    0x0
+
+#define SCU_RAM_VSB_RSV_0__A                                                0x831FD9
+#define SCU_RAM_VSB_RSV_0__W                                                16
+#define SCU_RAM_VSB_RSV_0__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_0__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_1__A                                                0x831FDA
+#define SCU_RAM_VSB_RSV_1__W                                                16
+#define SCU_RAM_VSB_RSV_1__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_1__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_2__A                                                0x831FDB
+#define SCU_RAM_VSB_RSV_2__W                                                16
+#define SCU_RAM_VSB_RSV_2__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_2__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_3__A                                                0x831FDC
+#define SCU_RAM_VSB_RSV_3__W                                                16
+#define SCU_RAM_VSB_RSV_3__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_3__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_4__A                                                0x831FDD
+#define SCU_RAM_VSB_RSV_4__W                                                16
+#define SCU_RAM_VSB_RSV_4__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_4__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_5__A                                                0x831FDE
+#define SCU_RAM_VSB_RSV_5__W                                                16
+#define SCU_RAM_VSB_RSV_5__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_5__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_6__A                                                0x831FDF
+#define SCU_RAM_VSB_RSV_6__W                                                16
+#define SCU_RAM_VSB_RSV_6__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_6__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_7__A                                                0x831FE0
+#define SCU_RAM_VSB_RSV_7__W                                                16
+#define SCU_RAM_VSB_RSV_7__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_7__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_8__A                                                0x831FE1
+#define SCU_RAM_VSB_RSV_8__W                                                16
+#define SCU_RAM_VSB_RSV_8__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_8__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_9__A                                                0x831FE2
+#define SCU_RAM_VSB_RSV_9__W                                                16
+#define SCU_RAM_VSB_RSV_9__M                                                0xFFFF
+#define SCU_RAM_VSB_RSV_9__PRE                                              0x0
+
+#define SCU_RAM_VSB_RSV_10__A                                               0x831FE3
+#define SCU_RAM_VSB_RSV_10__W                                               16
+#define SCU_RAM_VSB_RSV_10__M                                               0xFFFF
+#define SCU_RAM_VSB_RSV_10__PRE                                             0x0
+
+#define SCU_RAM_VSB_RSV_11__A                                               0x831FE4
+#define SCU_RAM_VSB_RSV_11__W                                               16
+#define SCU_RAM_VSB_RSV_11__M                                               0xFFFF
+#define SCU_RAM_VSB_RSV_11__PRE                                             0x0
+
+#define SCU_RAM_VSB_RSV_12__A                                               0x831FE5
+#define SCU_RAM_VSB_RSV_12__W                                               16
+#define SCU_RAM_VSB_RSV_12__M                                               0xFFFF
+#define SCU_RAM_VSB_RSV_12__PRE                                             0x0
+
+#define SCU_RAM_VSB_RSV_13__A                                               0x831FE6
+#define SCU_RAM_VSB_RSV_13__W                                               16
+#define SCU_RAM_VSB_RSV_13__M                                               0xFFFF
+#define SCU_RAM_VSB_RSV_13__PRE                                             0x0
+
+#define SCU_RAM_VSB_AGC_POW_TGT__A                                          0x831FE7
+#define SCU_RAM_VSB_AGC_POW_TGT__W                                          15
+#define SCU_RAM_VSB_AGC_POW_TGT__M                                          0x7FFF
+#define SCU_RAM_VSB_AGC_POW_TGT__PRE                                        0x0
+
+#define SCU_RAM_VSB_OUTER_LOOP_CYCLE__A                                     0x831FE8
+#define SCU_RAM_VSB_OUTER_LOOP_CYCLE__W                                     8
+#define SCU_RAM_VSB_OUTER_LOOP_CYCLE__M                                     0xFF
+#define SCU_RAM_VSB_OUTER_LOOP_CYCLE__PRE                                   0x0
+
+#define SCU_RAM_VSB_FIELD_NUMBER__A                                         0x831FE9
+#define SCU_RAM_VSB_FIELD_NUMBER__W                                         9
+#define SCU_RAM_VSB_FIELD_NUMBER__M                                         0x1FF
+#define SCU_RAM_VSB_FIELD_NUMBER__PRE                                       0x0
+
+#define SCU_RAM_VSB_SEGMENT_NUMBER__A                                       0x831FEA
+#define SCU_RAM_VSB_SEGMENT_NUMBER__W                                       10
+#define SCU_RAM_VSB_SEGMENT_NUMBER__M                                       0x3FF
+#define SCU_RAM_VSB_SEGMENT_NUMBER__PRE                                     0x0
+
+#define SCU_RAM_DRIVER_VER_HI__A                                            0x831FEB
+#define SCU_RAM_DRIVER_VER_HI__W                                            16
+#define SCU_RAM_DRIVER_VER_HI__M                                            0xFFFF
+#define SCU_RAM_DRIVER_VER_HI__PRE                                          0x0
+
+#define SCU_RAM_DRIVER_VER_LO__A                                            0x831FEC
+#define SCU_RAM_DRIVER_VER_LO__W                                            16
+#define SCU_RAM_DRIVER_VER_LO__M                                            0xFFFF
+#define SCU_RAM_DRIVER_VER_LO__PRE                                          0x0
+
+#define SCU_RAM_PARAM_15__A                                                 0x831FED
+#define SCU_RAM_PARAM_15__W                                                 16
+#define SCU_RAM_PARAM_15__M                                                 0xFFFF
+#define SCU_RAM_PARAM_15__PRE                                               0x0
+
+#define SCU_RAM_PARAM_14__A                                                 0x831FEE
+#define SCU_RAM_PARAM_14__W                                                 16
+#define SCU_RAM_PARAM_14__M                                                 0xFFFF
+#define SCU_RAM_PARAM_14__PRE                                               0x0
+
+#define SCU_RAM_PARAM_13__A                                                 0x831FEF
+#define SCU_RAM_PARAM_13__W                                                 16
+#define SCU_RAM_PARAM_13__M                                                 0xFFFF
+#define SCU_RAM_PARAM_13__PRE                                               0x0
+
+#define SCU_RAM_PARAM_12__A                                                 0x831FF0
+#define SCU_RAM_PARAM_12__W                                                 16
+#define SCU_RAM_PARAM_12__M                                                 0xFFFF
+#define SCU_RAM_PARAM_12__PRE                                               0x0
+
+#define SCU_RAM_PARAM_11__A                                                 0x831FF1
+#define SCU_RAM_PARAM_11__W                                                 16
+#define SCU_RAM_PARAM_11__M                                                 0xFFFF
+#define SCU_RAM_PARAM_11__PRE                                               0x0
+
+#define SCU_RAM_PARAM_10__A                                                 0x831FF2
+#define SCU_RAM_PARAM_10__W                                                 16
+#define SCU_RAM_PARAM_10__M                                                 0xFFFF
+#define SCU_RAM_PARAM_10__PRE                                               0x0
+
+#define SCU_RAM_PARAM_9__A                                                  0x831FF3
+#define SCU_RAM_PARAM_9__W                                                  16
+#define SCU_RAM_PARAM_9__M                                                  0xFFFF
+#define SCU_RAM_PARAM_9__PRE                                                0x0
+
+#define SCU_RAM_PARAM_8__A                                                  0x831FF4
+#define SCU_RAM_PARAM_8__W                                                  16
+#define SCU_RAM_PARAM_8__M                                                  0xFFFF
+#define SCU_RAM_PARAM_8__PRE                                                0x0
+
+#define SCU_RAM_PARAM_7__A                                                  0x831FF5
+#define SCU_RAM_PARAM_7__W                                                  16
+#define SCU_RAM_PARAM_7__M                                                  0xFFFF
+#define SCU_RAM_PARAM_7__PRE                                                0x0
+
+#define SCU_RAM_PARAM_6__A                                                  0x831FF6
+#define SCU_RAM_PARAM_6__W                                                  16
+#define SCU_RAM_PARAM_6__M                                                  0xFFFF
+#define SCU_RAM_PARAM_6__PRE                                                0x0
+
+#define SCU_RAM_PARAM_5__A                                                  0x831FF7
+#define SCU_RAM_PARAM_5__W                                                  16
+#define SCU_RAM_PARAM_5__M                                                  0xFFFF
+#define SCU_RAM_PARAM_5__PRE                                                0x0
+
+#define SCU_RAM_PARAM_4__A                                                  0x831FF8
+#define SCU_RAM_PARAM_4__W                                                  16
+#define SCU_RAM_PARAM_4__M                                                  0xFFFF
+#define SCU_RAM_PARAM_4__PRE                                                0x0
+
+#define SCU_RAM_PARAM_3__A                                                  0x831FF9
+#define SCU_RAM_PARAM_3__W                                                  16
+#define SCU_RAM_PARAM_3__M                                                  0xFFFF
+#define SCU_RAM_PARAM_3__PRE                                                0x0
+
+#define SCU_RAM_PARAM_2__A                                                  0x831FFA
+#define SCU_RAM_PARAM_2__W                                                  16
+#define SCU_RAM_PARAM_2__M                                                  0xFFFF
+#define SCU_RAM_PARAM_2__PRE                                                0x0
+
+#define SCU_RAM_PARAM_1__A                                                  0x831FFB
+#define SCU_RAM_PARAM_1__W                                                  16
+#define SCU_RAM_PARAM_1__M                                                  0xFFFF
+#define SCU_RAM_PARAM_1__PRE                                                0x0
+#define   SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NOT_LOCKED                     0x0
+#define   SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED                   0x4000
+#define   SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED                         0x8000
+#define   SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK                     0xC000
+
+#define SCU_RAM_PARAM_0__A                                                  0x831FFC
+#define SCU_RAM_PARAM_0__W                                                  16
+#define SCU_RAM_PARAM_0__M                                                  0xFFFF
+#define SCU_RAM_PARAM_0__PRE                                                0x0
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_MN_STANDARD                      0x2
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_B_STANDARD                       0x103
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_G_STANDARD                       0x3
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_DK_STANDARD                      0x4
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_L_STANDARD                       0x9
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_LP_STANDARD                      0x109
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_I_STANDARD                       0xA
+#define   SCU_RAM_PARAM_0_ATV_DEMOD_SETENV_FM_STANDARD                      0x40
+#define   SCU_RAM_PARAM_0_QAM_DEMOD_SETENV_ANNEX_A                          0x0
+#define   SCU_RAM_PARAM_0_QAM_DEMOD_SETENV_ANNEX_B                          0x1
+#define   SCU_RAM_PARAM_0_QAM_DEMOD_SETENV_ANNEX_C                          0x2
+#define   SCU_RAM_PARAM_0_QAM_DEMOD_SETENV_ANNEX_D                          0x3
+#define   SCU_RAM_PARAM_0_RESULT_OK                                         0x0
+#define   SCU_RAM_PARAM_0_RESULT_UNKCMD                                     0xFFFF
+#define   SCU_RAM_PARAM_0_RESULT_UNKSTD                                     0xFFFE
+#define   SCU_RAM_PARAM_0_RESULT_INVPAR                                     0xFFFD
+#define   SCU_RAM_PARAM_0_RESULT_SIZE                                       0xFFFC
+
+#define SCU_RAM_COMMAND__A                                                  0x831FFD
+#define SCU_RAM_COMMAND__W                                                  16
+#define SCU_RAM_COMMAND__M                                                  0xFFFF
+#define SCU_RAM_COMMAND__PRE                                                0x0
+#define   SCU_RAM_COMMAND_CMD_DEMOD_RESET                                   0x1
+#define   SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV                                 0x2
+#define   SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM                               0x3
+#define   SCU_RAM_COMMAND_CMD_DEMOD_START                                   0x4
+#define   SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK                                0x5
+#define   SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM                               0x6
+#define   SCU_RAM_COMMAND_CMD_DEMOD_HOLD                                    0x7
+#define   SCU_RAM_COMMAND_CMD_DEMOD_RESUME                                  0x8
+#define   SCU_RAM_COMMAND_CMD_DEMOD_STOP                                    0x9
+#define   SCU_RAM_COMMAND_CMD_STD_QAM_IRQ_ACTIVATE                          0x80
+#define   SCU_RAM_COMMAND_CMD_STD_QAM_IRQ_INACTIVATE                        0x81
+#define   SCU_RAM_COMMAND_CMD_STD_QAM_IRQ_SIGNAL                            0x82
+#define   SCU_RAM_COMMAND_CMD_STD_QAM_IRQ_MONITOR                           0x83
+#define   SCU_RAM_COMMAND_CMD_STD_QAM_TSK_ENABLE                            0x84
+#define   SCU_RAM_COMMAND_CMD_STD_QAM_FSM_SET_STATE                         0x85
+#define   SCU_RAM_COMMAND_CMD_DEBUG_GET_IRQ_REGS                            0x80
+#define   SCU_RAM_COMMAND_CMD_DEBUG_HTOL                                    0x81
+#define   SCU_RAM_COMMAND_CMD_DEBUG_GET_STACK_POINTER                       0x82
+#define   SCU_RAM_COMMAND_CMD_DEBUG_START_STACK_CHECK                       0x83
+#define   SCU_RAM_COMMAND_CMD_DEBUG_STOP_STACK_CHECK                        0x84
+#define   SCU_RAM_COMMAND_CMD_ADMIN_NOP                                     0xFF
+#define   SCU_RAM_COMMAND_CMD_ADMIN_GET_VERSION                             0xFE
+#define   SCU_RAM_COMMAND_CMD_ADMIN_GET_JTAG_VERSION                        0xFD
+#define   SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS                         0xC0
+
+#define   SCU_RAM_COMMAND_STANDARD__B                                       8
+#define   SCU_RAM_COMMAND_STANDARD__W                                       8
+#define   SCU_RAM_COMMAND_STANDARD__M                                       0xFF00
+#define   SCU_RAM_COMMAND_STANDARD__PRE                                     0x0
+#define     SCU_RAM_COMMAND_STANDARD_ATV                                    0x100
+#define     SCU_RAM_COMMAND_STANDARD_QAM                                    0x200
+#define     SCU_RAM_COMMAND_STANDARD_VSB                                    0x300
+#define     SCU_RAM_COMMAND_STANDARD_OFDM                                   0x400
+#define     SCU_RAM_COMMAND_STANDARD_OOB                                    0x8000
+#define     SCU_RAM_COMMAND_STANDARD_TOP                                    0xFF00
+
+#define SCU_RAM_VERSION_HI__A                                               0x831FFE
+#define SCU_RAM_VERSION_HI__W                                               16
+#define SCU_RAM_VERSION_HI__M                                               0xFFFF
+#define SCU_RAM_VERSION_HI__PRE                                             0x0
+
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N3__B                                12
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N3__W                                4
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N3__M                                0xF000
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N3__PRE                              0x0
+
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N2__B                                8
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N2__W                                4
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N2__M                                0xF00
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N2__PRE                              0x0
+
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N1__B                                4
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N1__W                                4
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N1__M                                0xF0
+#define   SCU_RAM_VERSION_HI_VER_MAJOR_N1__PRE                              0x0
+
+#define   SCU_RAM_VERSION_HI_VER_MINOR_N1__B                                0
+#define   SCU_RAM_VERSION_HI_VER_MINOR_N1__W                                4
+#define   SCU_RAM_VERSION_HI_VER_MINOR_N1__M                                0xF
+#define   SCU_RAM_VERSION_HI_VER_MINOR_N1__PRE                              0x0
+
+#define SCU_RAM_VERSION_LO__A                                               0x831FFF
+#define SCU_RAM_VERSION_LO__W                                               16
+#define SCU_RAM_VERSION_LO__M                                               0xFFFF
+#define SCU_RAM_VERSION_LO__PRE                                             0x0
+
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N4__B                                12
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N4__W                                4
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N4__M                                0xF000
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N4__PRE                              0x0
+
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N3__B                                8
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N3__W                                4
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N3__M                                0xF00
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N3__PRE                              0x0
+
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N2__B                                4
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N2__W                                4
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N2__M                                0xF0
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N2__PRE                              0x0
+
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N1__B                                0
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N1__W                                4
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N1__M                                0xF
+#define   SCU_RAM_VERSION_LO_VER_PATCH_N1__PRE                              0x0
+
+#define SIO_COMM_EXEC__A                                                    0x400000
+#define SIO_COMM_EXEC__W                                                    2
+#define SIO_COMM_EXEC__M                                                    0x3
+#define SIO_COMM_EXEC__PRE                                                  0x0
+#define   SIO_COMM_EXEC_STOP                                                0x0
+#define   SIO_COMM_EXEC_ACTIVE                                              0x1
+#define   SIO_COMM_EXEC_HOLD                                                0x2
+
+#define SIO_COMM_STATE__A                                                   0x400001
+#define SIO_COMM_STATE__W                                                   16
+#define SIO_COMM_STATE__M                                                   0xFFFF
+#define SIO_COMM_STATE__PRE                                                 0x0
+#define SIO_COMM_MB__A                                                      0x400002
+#define SIO_COMM_MB__W                                                      16
+#define SIO_COMM_MB__M                                                      0xFFFF
+#define SIO_COMM_MB__PRE                                                    0x0
+#define SIO_COMM_INT_REQ__A                                                 0x400003
+#define SIO_COMM_INT_REQ__W                                                 16
+#define SIO_COMM_INT_REQ__M                                                 0xFFFF
+#define SIO_COMM_INT_REQ__PRE                                               0x0
+
+#define   SIO_COMM_INT_REQ_HI_REQ__B                                        0
+#define   SIO_COMM_INT_REQ_HI_REQ__W                                        1
+#define   SIO_COMM_INT_REQ_HI_REQ__M                                        0x1
+#define   SIO_COMM_INT_REQ_HI_REQ__PRE                                      0x0
+
+#define   SIO_COMM_INT_REQ_SA_REQ__B                                        1
+#define   SIO_COMM_INT_REQ_SA_REQ__W                                        1
+#define   SIO_COMM_INT_REQ_SA_REQ__M                                        0x2
+#define   SIO_COMM_INT_REQ_SA_REQ__PRE                                      0x0
+
+#define SIO_COMM_INT_STA__A                                                 0x400005
+#define SIO_COMM_INT_STA__W                                                 16
+#define SIO_COMM_INT_STA__M                                                 0xFFFF
+#define SIO_COMM_INT_STA__PRE                                               0x0
+#define SIO_COMM_INT_MSK__A                                                 0x400006
+#define SIO_COMM_INT_MSK__W                                                 16
+#define SIO_COMM_INT_MSK__M                                                 0xFFFF
+#define SIO_COMM_INT_MSK__PRE                                               0x0
+#define SIO_COMM_INT_STM__A                                                 0x400007
+#define SIO_COMM_INT_STM__W                                                 16
+#define SIO_COMM_INT_STM__M                                                 0xFFFF
+#define SIO_COMM_INT_STM__PRE                                               0x0
+
+#define SIO_TOP_COMM_EXEC__A                                                0x410000
+#define SIO_TOP_COMM_EXEC__W                                                2
+#define SIO_TOP_COMM_EXEC__M                                                0x3
+#define SIO_TOP_COMM_EXEC__PRE                                              0x0
+#define   SIO_TOP_COMM_EXEC_STOP                                            0x0
+#define   SIO_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   SIO_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define SIO_TOP_COMM_KEY__A                                                 0x41000F
+#define SIO_TOP_COMM_KEY__W                                                 16
+#define SIO_TOP_COMM_KEY__M                                                 0xFFFF
+#define SIO_TOP_COMM_KEY__PRE                                               0x0
+#define   SIO_TOP_COMM_KEY_KEY                                              0xFABA
+
+#define SIO_TOP_JTAGID_LO__A                                                0x410012
+#define SIO_TOP_JTAGID_LO__W                                                16
+#define SIO_TOP_JTAGID_LO__M                                                0xFFFF
+#define SIO_TOP_JTAGID_LO__PRE                                              0x0
+
+#define SIO_TOP_JTAGID_HI__A                                                0x410013
+#define SIO_TOP_JTAGID_HI__W                                                16
+#define SIO_TOP_JTAGID_HI__M                                                0xFFFF
+#define SIO_TOP_JTAGID_HI__PRE                                              0x0
+
+#define SIO_HI_RA_RAM_S0_FLG_SMM__A                                         0x420010
+#define SIO_HI_RA_RAM_S0_FLG_SMM__W                                         1
+#define SIO_HI_RA_RAM_S0_FLG_SMM__M                                         0x1
+#define SIO_HI_RA_RAM_S0_FLG_SMM__PRE                                       0x0
+
+#define SIO_HI_RA_RAM_S0_DEV_ID__A                                          0x420011
+#define SIO_HI_RA_RAM_S0_DEV_ID__W                                          7
+#define SIO_HI_RA_RAM_S0_DEV_ID__M                                          0x7F
+#define SIO_HI_RA_RAM_S0_DEV_ID__PRE                                        0x52
+
+#define SIO_HI_RA_RAM_S0_FLG_CRC__A                                         0x420012
+#define SIO_HI_RA_RAM_S0_FLG_CRC__W                                         1
+#define SIO_HI_RA_RAM_S0_FLG_CRC__M                                         0x1
+#define SIO_HI_RA_RAM_S0_FLG_CRC__PRE                                       0x0
+#define SIO_HI_RA_RAM_S0_FLG_ACC__A                                         0x420013
+#define SIO_HI_RA_RAM_S0_FLG_ACC__W                                         4
+#define SIO_HI_RA_RAM_S0_FLG_ACC__M                                         0xF
+#define SIO_HI_RA_RAM_S0_FLG_ACC__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__B                                0
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__W                                2
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M                                0x3
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_BRC__B                            2
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_BRC__W                            1
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_BRC__M                            0x4
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_BRC__PRE                          0x0
+
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_SWP__B                            3
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_SWP__W                            1
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_SWP__M                            0x8
+#define   SIO_HI_RA_RAM_S0_FLG_ACC_S0_SLV_SWP__PRE                          0x0
+
+#define SIO_HI_RA_RAM_S0_STATE__A                                           0x420014
+#define SIO_HI_RA_RAM_S0_STATE__W                                           1
+#define SIO_HI_RA_RAM_S0_STATE__M                                           0x1
+#define SIO_HI_RA_RAM_S0_STATE__PRE                                         0x0
+
+#define   SIO_HI_RA_RAM_S0_STATE_S0_SLV_STA__B                              0
+#define   SIO_HI_RA_RAM_S0_STATE_S0_SLV_STA__W                              1
+#define   SIO_HI_RA_RAM_S0_STATE_S0_SLV_STA__M                              0x1
+#define   SIO_HI_RA_RAM_S0_STATE_S0_SLV_STA__PRE                            0x0
+
+#define SIO_HI_RA_RAM_S0_BLK_BNK__A                                         0x420015
+#define SIO_HI_RA_RAM_S0_BLK_BNK__W                                         12
+#define SIO_HI_RA_RAM_S0_BLK_BNK__M                                         0xFFF
+#define SIO_HI_RA_RAM_S0_BLK_BNK__PRE                                       0x82
+
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BNK__B                            0
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BNK__W                            6
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BNK__M                            0x3F
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BNK__PRE                          0x2
+
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BLK__B                            6
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BLK__W                            6
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BLK__M                            0xFC0
+#define   SIO_HI_RA_RAM_S0_BLK_BNK_S0_SLV_BLK__PRE                          0x80
+
+#define SIO_HI_RA_RAM_S0_ADDR__A                                            0x420016
+#define SIO_HI_RA_RAM_S0_ADDR__W                                            16
+#define SIO_HI_RA_RAM_S0_ADDR__M                                            0xFFFF
+#define SIO_HI_RA_RAM_S0_ADDR__PRE                                          0x0
+
+#define   SIO_HI_RA_RAM_S0_ADDR_S0_SLV_ADDR__B                              0
+#define   SIO_HI_RA_RAM_S0_ADDR_S0_SLV_ADDR__W                              16
+#define   SIO_HI_RA_RAM_S0_ADDR_S0_SLV_ADDR__M                              0xFFFF
+#define   SIO_HI_RA_RAM_S0_ADDR_S0_SLV_ADDR__PRE                            0x0
+
+#define SIO_HI_RA_RAM_S0_CRC__A                                             0x420017
+#define SIO_HI_RA_RAM_S0_CRC__W                                             16
+#define SIO_HI_RA_RAM_S0_CRC__M                                             0xFFFF
+#define SIO_HI_RA_RAM_S0_CRC__PRE                                           0x0
+
+#define SIO_HI_RA_RAM_S0_BUFFER__A                                          0x420018
+#define SIO_HI_RA_RAM_S0_BUFFER__W                                          16
+#define SIO_HI_RA_RAM_S0_BUFFER__M                                          0xFFFF
+#define SIO_HI_RA_RAM_S0_BUFFER__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S0_RMWBUF__A                                          0x420019
+#define SIO_HI_RA_RAM_S0_RMWBUF__W                                          16
+#define SIO_HI_RA_RAM_S0_RMWBUF__M                                          0xFFFF
+#define SIO_HI_RA_RAM_S0_RMWBUF__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S0_FLG_VB__A                                          0x42001A
+#define SIO_HI_RA_RAM_S0_FLG_VB__W                                          1
+#define SIO_HI_RA_RAM_S0_FLG_VB__M                                          0x1
+#define SIO_HI_RA_RAM_S0_FLG_VB__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S0_TEMP0__A                                           0x42001B
+#define SIO_HI_RA_RAM_S0_TEMP0__W                                           16
+#define SIO_HI_RA_RAM_S0_TEMP0__M                                           0xFFFF
+#define SIO_HI_RA_RAM_S0_TEMP0__PRE                                         0x0
+
+#define SIO_HI_RA_RAM_S0_TEMP1__A                                           0x42001C
+#define SIO_HI_RA_RAM_S0_TEMP1__W                                           16
+#define SIO_HI_RA_RAM_S0_TEMP1__M                                           0xFFFF
+#define SIO_HI_RA_RAM_S0_TEMP1__PRE                                         0x0
+
+#define SIO_HI_RA_RAM_S0_OFFSET__A                                          0x42001D
+#define SIO_HI_RA_RAM_S0_OFFSET__W                                          16
+#define SIO_HI_RA_RAM_S0_OFFSET__M                                          0xFFFF
+#define SIO_HI_RA_RAM_S0_OFFSET__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S1_FLG_SMM__A                                         0x420020
+#define SIO_HI_RA_RAM_S1_FLG_SMM__W                                         1
+#define SIO_HI_RA_RAM_S1_FLG_SMM__M                                         0x1
+#define SIO_HI_RA_RAM_S1_FLG_SMM__PRE                                       0x0
+
+#define SIO_HI_RA_RAM_S1_DEV_ID__A                                          0x420021
+#define SIO_HI_RA_RAM_S1_DEV_ID__W                                          7
+#define SIO_HI_RA_RAM_S1_DEV_ID__M                                          0x7F
+#define SIO_HI_RA_RAM_S1_DEV_ID__PRE                                        0x52
+
+#define SIO_HI_RA_RAM_S1_FLG_CRC__A                                         0x420022
+#define SIO_HI_RA_RAM_S1_FLG_CRC__W                                         1
+#define SIO_HI_RA_RAM_S1_FLG_CRC__M                                         0x1
+#define SIO_HI_RA_RAM_S1_FLG_CRC__PRE                                       0x0
+#define SIO_HI_RA_RAM_S1_FLG_ACC__A                                         0x420023
+#define SIO_HI_RA_RAM_S1_FLG_ACC__W                                         4
+#define SIO_HI_RA_RAM_S1_FLG_ACC__M                                         0xF
+#define SIO_HI_RA_RAM_S1_FLG_ACC__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_RWM__B                                0
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_RWM__W                                2
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_RWM__M                                0x3
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_RWM__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_BRC__B                            2
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_BRC__W                            1
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_BRC__M                            0x4
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_BRC__PRE                          0x0
+
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_SWP__B                            3
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_SWP__W                            1
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_SWP__M                            0x8
+#define   SIO_HI_RA_RAM_S1_FLG_ACC_S1_SLV_SWP__PRE                          0x0
+
+#define SIO_HI_RA_RAM_S1_STATE__A                                           0x420024
+#define SIO_HI_RA_RAM_S1_STATE__W                                           1
+#define SIO_HI_RA_RAM_S1_STATE__M                                           0x1
+#define SIO_HI_RA_RAM_S1_STATE__PRE                                         0x0
+
+#define   SIO_HI_RA_RAM_S1_STATE_S1_SLV_STA__B                              0
+#define   SIO_HI_RA_RAM_S1_STATE_S1_SLV_STA__W                              1
+#define   SIO_HI_RA_RAM_S1_STATE_S1_SLV_STA__M                              0x1
+#define   SIO_HI_RA_RAM_S1_STATE_S1_SLV_STA__PRE                            0x0
+
+#define SIO_HI_RA_RAM_S1_BLK_BNK__A                                         0x420025
+#define SIO_HI_RA_RAM_S1_BLK_BNK__W                                         12
+#define SIO_HI_RA_RAM_S1_BLK_BNK__M                                         0xFFF
+#define SIO_HI_RA_RAM_S1_BLK_BNK__PRE                                       0x82
+
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BNK__B                            0
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BNK__W                            6
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BNK__M                            0x3F
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BNK__PRE                          0x2
+
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BLK__B                            6
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BLK__W                            6
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BLK__M                            0xFC0
+#define   SIO_HI_RA_RAM_S1_BLK_BNK_S1_SLV_BLK__PRE                          0x80
+
+#define SIO_HI_RA_RAM_S1_ADDR__A                                            0x420026
+#define SIO_HI_RA_RAM_S1_ADDR__W                                            16
+#define SIO_HI_RA_RAM_S1_ADDR__M                                            0xFFFF
+#define SIO_HI_RA_RAM_S1_ADDR__PRE                                          0x0
+
+#define   SIO_HI_RA_RAM_S1_ADDR_S1_SLV_ADDR__B                              0
+#define   SIO_HI_RA_RAM_S1_ADDR_S1_SLV_ADDR__W                              16
+#define   SIO_HI_RA_RAM_S1_ADDR_S1_SLV_ADDR__M                              0xFFFF
+#define   SIO_HI_RA_RAM_S1_ADDR_S1_SLV_ADDR__PRE                            0x0
+
+#define SIO_HI_RA_RAM_S1_CRC__A                                             0x420027
+#define SIO_HI_RA_RAM_S1_CRC__W                                             16
+#define SIO_HI_RA_RAM_S1_CRC__M                                             0xFFFF
+#define SIO_HI_RA_RAM_S1_CRC__PRE                                           0x0
+
+#define SIO_HI_RA_RAM_S1_BUFFER__A                                          0x420028
+#define SIO_HI_RA_RAM_S1_BUFFER__W                                          16
+#define SIO_HI_RA_RAM_S1_BUFFER__M                                          0xFFFF
+#define SIO_HI_RA_RAM_S1_BUFFER__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S1_RMWBUF__A                                          0x420029
+#define SIO_HI_RA_RAM_S1_RMWBUF__W                                          16
+#define SIO_HI_RA_RAM_S1_RMWBUF__M                                          0xFFFF
+#define SIO_HI_RA_RAM_S1_RMWBUF__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S1_FLG_VB__A                                          0x42002A
+#define SIO_HI_RA_RAM_S1_FLG_VB__W                                          1
+#define SIO_HI_RA_RAM_S1_FLG_VB__M                                          0x1
+#define SIO_HI_RA_RAM_S1_FLG_VB__PRE                                        0x0
+
+#define SIO_HI_RA_RAM_S1_TEMP0__A                                           0x42002B
+#define SIO_HI_RA_RAM_S1_TEMP0__W                                           16
+#define SIO_HI_RA_RAM_S1_TEMP0__M                                           0xFFFF
+#define SIO_HI_RA_RAM_S1_TEMP0__PRE                                         0x0
+
+#define SIO_HI_RA_RAM_S1_TEMP1__A                                           0x42002C
+#define SIO_HI_RA_RAM_S1_TEMP1__W                                           16
+#define SIO_HI_RA_RAM_S1_TEMP1__M                                           0xFFFF
+#define SIO_HI_RA_RAM_S1_TEMP1__PRE                                         0x0
+
+#define SIO_HI_RA_RAM_S1_OFFSET__A                                          0x42002D
+#define SIO_HI_RA_RAM_S1_OFFSET__W                                          16
+#define SIO_HI_RA_RAM_S1_OFFSET__M                                          0xFFFF
+#define SIO_HI_RA_RAM_S1_OFFSET__PRE                                        0x0
+#define SIO_HI_RA_RAM_SEMA__A                                               0x420030
+#define SIO_HI_RA_RAM_SEMA__W                                               1
+#define SIO_HI_RA_RAM_SEMA__M                                               0x1
+#define SIO_HI_RA_RAM_SEMA__PRE                                             0x0
+#define   SIO_HI_RA_RAM_SEMA_FREE                                           0x0
+#define   SIO_HI_RA_RAM_SEMA_BUSY                                           0x1
+
+#define SIO_HI_RA_RAM_RES__A                                                0x420031
+#define SIO_HI_RA_RAM_RES__W                                                3
+#define SIO_HI_RA_RAM_RES__M                                                0x7
+#define SIO_HI_RA_RAM_RES__PRE                                              0x0
+#define   SIO_HI_RA_RAM_RES_OK                                              0x0
+#define   SIO_HI_RA_RAM_RES_ERROR                                           0x1
+#define   SIO_HI_RA_RAM_RES_I2C_START_FOUND                                 0x1
+#define   SIO_HI_RA_RAM_RES_I2C_STOP_FOUND                                  0x2
+#define   SIO_HI_RA_RAM_RES_I2C_ARB_LOST                                    0x3
+#define   SIO_HI_RA_RAM_RES_I2C_ERROR                                       0x4
+
+#define SIO_HI_RA_RAM_CMD__A                                                0x420032
+#define SIO_HI_RA_RAM_CMD__W                                                4
+#define SIO_HI_RA_RAM_CMD__M                                                0xF
+#define SIO_HI_RA_RAM_CMD__PRE                                              0x0
+#define   SIO_HI_RA_RAM_CMD_NULL                                            0x0
+#define   SIO_HI_RA_RAM_CMD_UIO                                             0x1
+#define   SIO_HI_RA_RAM_CMD_RESET                                           0x2
+#define   SIO_HI_RA_RAM_CMD_CONFIG                                          0x3
+#define   SIO_HI_RA_RAM_CMD_INTERNAL_TRANSFER                               0x4
+#define   SIO_HI_RA_RAM_CMD_I2C_TRANSMIT                                    0x5
+#define   SIO_HI_RA_RAM_CMD_EXEC                                            0x6
+#define   SIO_HI_RA_RAM_CMD_BRDCTRL                                         0x7
+#define   SIO_HI_RA_RAM_CMD_ATOMIC_COPY                                     0x8
+
+#define SIO_HI_RA_RAM_PAR_1__A                                              0x420033
+#define SIO_HI_RA_RAM_PAR_1__W                                              16
+#define SIO_HI_RA_RAM_PAR_1__M                                              0xFFFF
+#define SIO_HI_RA_RAM_PAR_1__PRE                                            0x0
+#define   SIO_HI_RA_RAM_PAR_1_PAR1__B                                       0
+#define   SIO_HI_RA_RAM_PAR_1_PAR1__W                                       16
+#define   SIO_HI_RA_RAM_PAR_1_PAR1__M                                       0xFFFF
+#define   SIO_HI_RA_RAM_PAR_1_PAR1__PRE                                     0x0
+#define     SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY                                0x3945
+
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BNK__B                                0
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BNK__W                                6
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BNK__M                                0x3F
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BNK__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BLK__B                                6
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BLK__W                                6
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BLK__M                                0xFC0
+#define   SIO_HI_RA_RAM_PAR_1_ITX_SRC_BLK__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_PORT__B                                 0
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_PORT__W                                 1
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_PORT__M                                 0x1
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_PORT__PRE                               0x0
+
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_TOE__B                                  1
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_TOE__W                                  1
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_TOE__M                                  0x2
+#define   SIO_HI_RA_RAM_PAR_1_I2CTX_TOE__PRE                                0x0
+#define     SIO_HI_RA_RAM_PAR_1_I2CTX_TOE_DISABLE                           0x0
+#define     SIO_HI_RA_RAM_PAR_1_I2CTX_TOE_ENABLE                            0x2
+
+#define   SIO_HI_RA_RAM_PAR_1_EXEC_FUNC__B                                  0
+#define   SIO_HI_RA_RAM_PAR_1_EXEC_FUNC__W                                  10
+#define   SIO_HI_RA_RAM_PAR_1_EXEC_FUNC__M                                  0x3FF
+#define   SIO_HI_RA_RAM_PAR_1_EXEC_FUNC__PRE                                0x0
+
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BNK__B                                0
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BNK__W                                6
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BNK__M                                0x3F
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BNK__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BLK__B                                6
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BLK__W                                6
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BLK__M                                0xFC0
+#define   SIO_HI_RA_RAM_PAR_1_ACP_INT_BLK__PRE                              0x0
+
+#define SIO_HI_RA_RAM_PAR_2__A                                              0x420034
+#define SIO_HI_RA_RAM_PAR_2__W                                              16
+#define SIO_HI_RA_RAM_PAR_2__M                                              0xFFFF
+#define SIO_HI_RA_RAM_PAR_2__PRE                                            0x0
+#define   SIO_HI_RA_RAM_PAR_2_PAR2__B                                       0
+#define   SIO_HI_RA_RAM_PAR_2_PAR2__W                                       16
+#define   SIO_HI_RA_RAM_PAR_2_PAR2__M                                       0xFFFF
+#define   SIO_HI_RA_RAM_PAR_2_PAR2__PRE                                     0x0
+
+#define   SIO_HI_RA_RAM_PAR_2_CFG_DIV__B                                    0
+#define   SIO_HI_RA_RAM_PAR_2_CFG_DIV__W                                    7
+#define   SIO_HI_RA_RAM_PAR_2_CFG_DIV__M                                    0x7F
+#define   SIO_HI_RA_RAM_PAR_2_CFG_DIV__PRE                                  0x25
+
+#define   SIO_HI_RA_RAM_PAR_2_ITX_SRC_OFF__B                                0
+#define   SIO_HI_RA_RAM_PAR_2_ITX_SRC_OFF__W                                16
+#define   SIO_HI_RA_RAM_PAR_2_ITX_SRC_OFF__M                                0xFFFF
+#define   SIO_HI_RA_RAM_PAR_2_ITX_SRC_OFF__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_2_I2CTX_BUF__B                                  0
+#define   SIO_HI_RA_RAM_PAR_2_I2CTX_BUF__W                                  16
+#define   SIO_HI_RA_RAM_PAR_2_I2CTX_BUF__M                                  0xFFFF
+#define   SIO_HI_RA_RAM_PAR_2_I2CTX_BUF__PRE                                0x0
+
+#define   SIO_HI_RA_RAM_PAR_2_BRD_CFG__B                                    2
+#define   SIO_HI_RA_RAM_PAR_2_BRD_CFG__W                                    1
+#define   SIO_HI_RA_RAM_PAR_2_BRD_CFG__M                                    0x4
+#define   SIO_HI_RA_RAM_PAR_2_BRD_CFG__PRE                                  0x0
+#define     SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN                                0x0
+#define     SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED                              0x4
+
+#define   SIO_HI_RA_RAM_PAR_2_ACP_INT_OFF__B                                0
+#define   SIO_HI_RA_RAM_PAR_2_ACP_INT_OFF__W                                16
+#define   SIO_HI_RA_RAM_PAR_2_ACP_INT_OFF__M                                0xFFFF
+#define   SIO_HI_RA_RAM_PAR_2_ACP_INT_OFF__PRE                              0x0
+
+#define SIO_HI_RA_RAM_PAR_3__A                                              0x420035
+#define SIO_HI_RA_RAM_PAR_3__W                                              16
+#define SIO_HI_RA_RAM_PAR_3__M                                              0xFFFF
+#define SIO_HI_RA_RAM_PAR_3__PRE                                            0x0
+#define   SIO_HI_RA_RAM_PAR_3_PAR3__B                                       0
+#define   SIO_HI_RA_RAM_PAR_3_PAR3__W                                       16
+#define   SIO_HI_RA_RAM_PAR_3_PAR3__M                                       0xFFFF
+#define   SIO_HI_RA_RAM_PAR_3_PAR3__PRE                                     0x0
+
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__B                                0
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__W                                7
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M                                0x7F
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__PRE                              0x3F
+
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B                                7
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__W                                7
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__M                                0x3F80
+#define   SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__PRE                              0x1F80
+
+#define   SIO_HI_RA_RAM_PAR_3_ITX_LEN__B                                    0
+#define   SIO_HI_RA_RAM_PAR_3_ITX_LEN__W                                    16
+#define   SIO_HI_RA_RAM_PAR_3_ITX_LEN__M                                    0xFFFF
+#define   SIO_HI_RA_RAM_PAR_3_ITX_LEN__PRE                                  0x0
+
+#define   SIO_HI_RA_RAM_PAR_3_ACP_LEN__B                                    0
+#define   SIO_HI_RA_RAM_PAR_3_ACP_LEN__W                                    3
+#define   SIO_HI_RA_RAM_PAR_3_ACP_LEN__M                                    0x7
+#define   SIO_HI_RA_RAM_PAR_3_ACP_LEN__PRE                                  0x0
+
+#define   SIO_HI_RA_RAM_PAR_3_ACP_RW__B                                     3
+#define   SIO_HI_RA_RAM_PAR_3_ACP_RW__W                                     1
+#define   SIO_HI_RA_RAM_PAR_3_ACP_RW__M                                     0x8
+#define   SIO_HI_RA_RAM_PAR_3_ACP_RW__PRE                                   0x0
+#define     SIO_HI_RA_RAM_PAR_3_ACP_RW_READ                                 0x0
+#define     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE                                0x8
+
+#define SIO_HI_RA_RAM_PAR_4__A                                              0x420036
+#define SIO_HI_RA_RAM_PAR_4__W                                              16
+#define SIO_HI_RA_RAM_PAR_4__M                                              0xFFFF
+#define SIO_HI_RA_RAM_PAR_4__PRE                                            0x0
+#define   SIO_HI_RA_RAM_PAR_4_PAR4__B                                       0
+#define   SIO_HI_RA_RAM_PAR_4_PAR4__W                                       16
+#define   SIO_HI_RA_RAM_PAR_4_PAR4__M                                       0xFFFF
+#define   SIO_HI_RA_RAM_PAR_4_PAR4__PRE                                     0x0
+
+#define   SIO_HI_RA_RAM_PAR_4_CFG_WUP__B                                    0
+#define   SIO_HI_RA_RAM_PAR_4_CFG_WUP__W                                    8
+#define   SIO_HI_RA_RAM_PAR_4_CFG_WUP__M                                    0xFF
+#define   SIO_HI_RA_RAM_PAR_4_CFG_WUP__PRE                                  0xC1
+
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BNK__B                                0
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BNK__W                                6
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BNK__M                                0x3F
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BNK__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BLK__B                                6
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BLK__W                                6
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BLK__M                                0xFC0
+#define   SIO_HI_RA_RAM_PAR_4_ITX_DST_BLK__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BNK__B                                0
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BNK__W                                6
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BNK__M                                0x3F
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BNK__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BLK__B                                6
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BLK__W                                6
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BLK__M                                0xFC0
+#define   SIO_HI_RA_RAM_PAR_4_ACP_EXT_BLK__PRE                              0x0
+
+#define SIO_HI_RA_RAM_PAR_5__A                                              0x420037
+#define SIO_HI_RA_RAM_PAR_5__W                                              16
+#define SIO_HI_RA_RAM_PAR_5__M                                              0xFFFF
+#define SIO_HI_RA_RAM_PAR_5__PRE                                            0x0
+#define   SIO_HI_RA_RAM_PAR_5_PAR5__B                                       0
+#define   SIO_HI_RA_RAM_PAR_5_PAR5__W                                       16
+#define   SIO_HI_RA_RAM_PAR_5_PAR5__M                                       0xFFFF
+#define   SIO_HI_RA_RAM_PAR_5_PAR5__PRE                                     0x0
+
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV0__B                                   0
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV0__W                                   1
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV0__M                                   0x1
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV0__PRE                                 0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_SLV0_NO_SLAVE                           0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE                              0x1
+
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV1__B                                   1
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV1__W                                   1
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV1__M                                   0x2
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLV1__PRE                                 0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_SLV1_NO_SLAVE                           0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_SLV1_SLAVE                              0x2
+
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__B                                  3
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__W                                  1
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M                                  0x8
+#define   SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__PRE                                0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_AWAKE                             0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ                               0x8
+
+#define   SIO_HI_RA_RAM_PAR_5_CFG_BDGST__B                                  5
+#define   SIO_HI_RA_RAM_PAR_5_CFG_BDGST__W                                  1
+#define   SIO_HI_RA_RAM_PAR_5_CFG_BDGST__M                                  0x20
+#define   SIO_HI_RA_RAM_PAR_5_CFG_BDGST__PRE                                0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_BDGST_DISABLE                           0x0
+#define     SIO_HI_RA_RAM_PAR_5_CFG_BDGST_ENABLE                            0x20
+
+#define   SIO_HI_RA_RAM_PAR_5_ITX_DST_OFF__B                                0
+#define   SIO_HI_RA_RAM_PAR_5_ITX_DST_OFF__W                                16
+#define   SIO_HI_RA_RAM_PAR_5_ITX_DST_OFF__M                                0xFFFF
+#define   SIO_HI_RA_RAM_PAR_5_ITX_DST_OFF__PRE                              0x0
+
+#define   SIO_HI_RA_RAM_PAR_5_ACP_EXT_OFF__B                                0
+#define   SIO_HI_RA_RAM_PAR_5_ACP_EXT_OFF__W                                16
+#define   SIO_HI_RA_RAM_PAR_5_ACP_EXT_OFF__M                                0xFFFF
+#define   SIO_HI_RA_RAM_PAR_5_ACP_EXT_OFF__PRE                              0x0
+
+#define SIO_HI_RA_RAM_PAR_6__A                                              0x420038
+#define SIO_HI_RA_RAM_PAR_6__W                                              16
+#define SIO_HI_RA_RAM_PAR_6__M                                              0xFFFF
+#define SIO_HI_RA_RAM_PAR_6__PRE                                            0x95FF
+#define   SIO_HI_RA_RAM_PAR_6_PAR6__B                                       0
+#define   SIO_HI_RA_RAM_PAR_6_PAR6__W                                       16
+#define   SIO_HI_RA_RAM_PAR_6_PAR6__M                                       0xFFFF
+#define   SIO_HI_RA_RAM_PAR_6_PAR6__PRE                                     0x0
+
+#define   SIO_HI_RA_RAM_PAR_6_CFG_TOD__B                                    0
+#define   SIO_HI_RA_RAM_PAR_6_CFG_TOD__W                                    8
+#define   SIO_HI_RA_RAM_PAR_6_CFG_TOD__M                                    0xFF
+#define   SIO_HI_RA_RAM_PAR_6_CFG_TOD__PRE                                  0xFF
+
+#define   SIO_HI_RA_RAM_PAR_6_CFG_WDD__B                                    8
+#define   SIO_HI_RA_RAM_PAR_6_CFG_WDD__W                                    8
+#define   SIO_HI_RA_RAM_PAR_6_CFG_WDD__M                                    0xFF00
+#define   SIO_HI_RA_RAM_PAR_6_CFG_WDD__PRE                                  0x9500
+
+#define SIO_HI_RA_RAM_AB_TEMP__A                                            0x42006E
+#define SIO_HI_RA_RAM_AB_TEMP__W                                            16
+#define SIO_HI_RA_RAM_AB_TEMP__M                                            0xFFFF
+#define SIO_HI_RA_RAM_AB_TEMP__PRE                                          0x0
+
+#define SIO_HI_RA_RAM_I2C_CTL__A                                            0x42006F
+#define SIO_HI_RA_RAM_I2C_CTL__W                                            16
+#define SIO_HI_RA_RAM_I2C_CTL__M                                            0xFFFF
+#define SIO_HI_RA_RAM_I2C_CTL__PRE                                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY0__A                                          0x420070
+#define SIO_HI_RA_RAM_VB_ENTRY0__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY0__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY0__PRE                                        0x0
+
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BNK__B                             0
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BNK__W                             4
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BNK__M                             0xF
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BNK__PRE                           0x0
+
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BLK__B                             4
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BLK__W                             4
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BLK__M                             0xF0
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_MAP_BLK__PRE                           0x0
+
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BNK__B                            8
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BNK__W                            4
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BNK__M                            0xF00
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BNK__PRE                          0x0
+
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BLK__B                            12
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BLK__W                            4
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BLK__M                            0xF000
+#define   SIO_HI_RA_RAM_VB_ENTRY0_HI_VIRT_BLK__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_OFFSET0__A                                         0x420071
+#define SIO_HI_RA_RAM_VB_OFFSET0__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET0__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET0__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET0_HI_MAP_OFF0__B                           0
+#define   SIO_HI_RA_RAM_VB_OFFSET0_HI_MAP_OFF0__W                           16
+#define   SIO_HI_RA_RAM_VB_OFFSET0_HI_MAP_OFF0__M                           0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET0_HI_MAP_OFF0__PRE                         0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY1__A                                          0x420072
+#define SIO_HI_RA_RAM_VB_ENTRY1__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY1__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY1__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET1__A                                         0x420073
+#define SIO_HI_RA_RAM_VB_OFFSET1__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET1__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET1__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET1_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET1_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET1_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET1_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY2__A                                          0x420074
+#define SIO_HI_RA_RAM_VB_ENTRY2__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY2__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY2__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET2__A                                         0x420075
+#define SIO_HI_RA_RAM_VB_OFFSET2__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET2__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET2__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET2_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET2_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET2_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET2_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY3__A                                          0x420076
+#define SIO_HI_RA_RAM_VB_ENTRY3__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY3__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY3__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET3__A                                         0x420077
+#define SIO_HI_RA_RAM_VB_OFFSET3__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET3__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET3__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET3_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET3_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET3_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET3_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY4__A                                          0x420078
+#define SIO_HI_RA_RAM_VB_ENTRY4__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY4__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY4__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET4__A                                         0x420079
+#define SIO_HI_RA_RAM_VB_OFFSET4__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET4__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET4__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET4_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET4_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET4_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET4_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY5__A                                          0x42007A
+#define SIO_HI_RA_RAM_VB_ENTRY5__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY5__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY5__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET5__A                                         0x42007B
+#define SIO_HI_RA_RAM_VB_OFFSET5__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET5__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET5__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET5_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET5_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET5_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET5_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY6__A                                          0x42007C
+#define SIO_HI_RA_RAM_VB_ENTRY6__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY6__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY6__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET6__A                                         0x42007D
+#define SIO_HI_RA_RAM_VB_OFFSET6__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET6__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET6__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET6_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET6_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET6_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET6_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_RA_RAM_VB_ENTRY7__A                                          0x42007E
+#define SIO_HI_RA_RAM_VB_ENTRY7__W                                          16
+#define SIO_HI_RA_RAM_VB_ENTRY7__M                                          0xFFFF
+#define SIO_HI_RA_RAM_VB_ENTRY7__PRE                                        0x0
+#define SIO_HI_RA_RAM_VB_OFFSET7__A                                         0x42007F
+#define SIO_HI_RA_RAM_VB_OFFSET7__W                                         16
+#define SIO_HI_RA_RAM_VB_OFFSET7__M                                         0xFFFF
+#define SIO_HI_RA_RAM_VB_OFFSET7__PRE                                       0x0
+
+#define   SIO_HI_RA_RAM_VB_OFFSET7_HI_MAP_OFF__B                            0
+#define   SIO_HI_RA_RAM_VB_OFFSET7_HI_MAP_OFF__W                            16
+#define   SIO_HI_RA_RAM_VB_OFFSET7_HI_MAP_OFF__M                            0xFFFF
+#define   SIO_HI_RA_RAM_VB_OFFSET7_HI_MAP_OFF__PRE                          0x0
+
+#define SIO_HI_IF_RAM_TRP_BPT_0__A                                          0x430000
+#define SIO_HI_IF_RAM_TRP_BPT_0__W                                          12
+#define SIO_HI_IF_RAM_TRP_BPT_0__M                                          0xFFF
+#define SIO_HI_IF_RAM_TRP_BPT_0__PRE                                        0x0
+#define SIO_HI_IF_RAM_TRP_BPT_1__A                                          0x430001
+#define SIO_HI_IF_RAM_TRP_BPT_1__W                                          12
+#define SIO_HI_IF_RAM_TRP_BPT_1__M                                          0xFFF
+#define SIO_HI_IF_RAM_TRP_BPT_1__PRE                                        0x0
+#define SIO_HI_IF_RAM_TRP_STK_0__A                                          0x430002
+#define SIO_HI_IF_RAM_TRP_STK_0__W                                          12
+#define SIO_HI_IF_RAM_TRP_STK_0__M                                          0xFFF
+#define SIO_HI_IF_RAM_TRP_STK_0__PRE                                        0x0
+#define SIO_HI_IF_RAM_TRP_STK_1__A                                          0x430003
+#define SIO_HI_IF_RAM_TRP_STK_1__W                                          12
+#define SIO_HI_IF_RAM_TRP_STK_1__M                                          0xFFF
+#define SIO_HI_IF_RAM_TRP_STK_1__PRE                                        0x0
+#define SIO_HI_IF_RAM_FUN_BASE__A                                           0x430300
+#define SIO_HI_IF_RAM_FUN_BASE__W                                           12
+#define SIO_HI_IF_RAM_FUN_BASE__M                                           0xFFF
+#define SIO_HI_IF_RAM_FUN_BASE__PRE                                         0x0
+
+#define SIO_HI_IF_COMM_EXEC__A                                              0x440000
+#define SIO_HI_IF_COMM_EXEC__W                                              2
+#define SIO_HI_IF_COMM_EXEC__M                                              0x3
+#define SIO_HI_IF_COMM_EXEC__PRE                                            0x0
+#define   SIO_HI_IF_COMM_EXEC_STOP                                          0x0
+#define   SIO_HI_IF_COMM_EXEC_ACTIVE                                        0x1
+#define   SIO_HI_IF_COMM_EXEC_HOLD                                          0x2
+#define   SIO_HI_IF_COMM_EXEC_STEP                                          0x3
+
+#define SIO_HI_IF_COMM_STATE__A                                             0x440001
+#define SIO_HI_IF_COMM_STATE__W                                             10
+#define SIO_HI_IF_COMM_STATE__M                                             0x3FF
+#define SIO_HI_IF_COMM_STATE__PRE                                           0x0
+#define SIO_HI_IF_COMM_INT_REQ__A                                           0x440003
+#define SIO_HI_IF_COMM_INT_REQ__W                                           1
+#define SIO_HI_IF_COMM_INT_REQ__M                                           0x1
+#define SIO_HI_IF_COMM_INT_REQ__PRE                                         0x0
+#define SIO_HI_IF_COMM_INT_STA__A                                           0x440005
+#define SIO_HI_IF_COMM_INT_STA__W                                           1
+#define SIO_HI_IF_COMM_INT_STA__M                                           0x1
+#define SIO_HI_IF_COMM_INT_STA__PRE                                         0x0
+#define   SIO_HI_IF_COMM_INT_STA_STAT__B                                    0
+#define   SIO_HI_IF_COMM_INT_STA_STAT__W                                    1
+#define   SIO_HI_IF_COMM_INT_STA_STAT__M                                    0x1
+#define   SIO_HI_IF_COMM_INT_STA_STAT__PRE                                  0x0
+
+#define SIO_HI_IF_COMM_INT_MSK__A                                           0x440006
+#define SIO_HI_IF_COMM_INT_MSK__W                                           1
+#define SIO_HI_IF_COMM_INT_MSK__M                                           0x1
+#define SIO_HI_IF_COMM_INT_MSK__PRE                                         0x0
+#define   SIO_HI_IF_COMM_INT_MSK_STAT__B                                    0
+#define   SIO_HI_IF_COMM_INT_MSK_STAT__W                                    1
+#define   SIO_HI_IF_COMM_INT_MSK_STAT__M                                    0x1
+#define   SIO_HI_IF_COMM_INT_MSK_STAT__PRE                                  0x0
+
+#define SIO_HI_IF_COMM_INT_STM__A                                           0x440007
+#define SIO_HI_IF_COMM_INT_STM__W                                           1
+#define SIO_HI_IF_COMM_INT_STM__M                                           0x1
+#define SIO_HI_IF_COMM_INT_STM__PRE                                         0x0
+#define   SIO_HI_IF_COMM_INT_STM_STAT__B                                    0
+#define   SIO_HI_IF_COMM_INT_STM_STAT__W                                    1
+#define   SIO_HI_IF_COMM_INT_STM_STAT__M                                    0x1
+#define   SIO_HI_IF_COMM_INT_STM_STAT__PRE                                  0x0
+
+#define SIO_HI_IF_STK_0__A                                                  0x440010
+#define SIO_HI_IF_STK_0__W                                                  10
+#define SIO_HI_IF_STK_0__M                                                  0x3FF
+#define SIO_HI_IF_STK_0__PRE                                                0x2
+
+#define   SIO_HI_IF_STK_0_ADDR__B                                           0
+#define   SIO_HI_IF_STK_0_ADDR__W                                           10
+#define   SIO_HI_IF_STK_0_ADDR__M                                           0x3FF
+#define   SIO_HI_IF_STK_0_ADDR__PRE                                         0x2
+
+#define SIO_HI_IF_STK_1__A                                                  0x440011
+#define SIO_HI_IF_STK_1__W                                                  10
+#define SIO_HI_IF_STK_1__M                                                  0x3FF
+#define SIO_HI_IF_STK_1__PRE                                                0x2
+#define   SIO_HI_IF_STK_1_ADDR__B                                           0
+#define   SIO_HI_IF_STK_1_ADDR__W                                           10
+#define   SIO_HI_IF_STK_1_ADDR__M                                           0x3FF
+#define   SIO_HI_IF_STK_1_ADDR__PRE                                         0x2
+
+#define SIO_HI_IF_STK_2__A                                                  0x440012
+#define SIO_HI_IF_STK_2__W                                                  10
+#define SIO_HI_IF_STK_2__M                                                  0x3FF
+#define SIO_HI_IF_STK_2__PRE                                                0x2
+#define   SIO_HI_IF_STK_2_ADDR__B                                           0
+#define   SIO_HI_IF_STK_2_ADDR__W                                           10
+#define   SIO_HI_IF_STK_2_ADDR__M                                           0x3FF
+#define   SIO_HI_IF_STK_2_ADDR__PRE                                         0x2
+
+#define SIO_HI_IF_STK_3__A                                                  0x440013
+#define SIO_HI_IF_STK_3__W                                                  10
+#define SIO_HI_IF_STK_3__M                                                  0x3FF
+#define SIO_HI_IF_STK_3__PRE                                                0x2
+
+#define   SIO_HI_IF_STK_3_ADDR__B                                           0
+#define   SIO_HI_IF_STK_3_ADDR__W                                           10
+#define   SIO_HI_IF_STK_3_ADDR__M                                           0x3FF
+#define   SIO_HI_IF_STK_3_ADDR__PRE                                         0x2
+
+#define SIO_HI_IF_BPT_IDX__A                                                0x44001F
+#define SIO_HI_IF_BPT_IDX__W                                                1
+#define SIO_HI_IF_BPT_IDX__M                                                0x1
+#define SIO_HI_IF_BPT_IDX__PRE                                              0x0
+
+#define   SIO_HI_IF_BPT_IDX_ADDR__B                                         0
+#define   SIO_HI_IF_BPT_IDX_ADDR__W                                         1
+#define   SIO_HI_IF_BPT_IDX_ADDR__M                                         0x1
+#define   SIO_HI_IF_BPT_IDX_ADDR__PRE                                       0x0
+
+#define SIO_HI_IF_BPT__A                                                    0x440020
+#define SIO_HI_IF_BPT__W                                                    10
+#define SIO_HI_IF_BPT__M                                                    0x3FF
+#define SIO_HI_IF_BPT__PRE                                                  0x2
+
+#define   SIO_HI_IF_BPT_ADDR__B                                             0
+#define   SIO_HI_IF_BPT_ADDR__W                                             10
+#define   SIO_HI_IF_BPT_ADDR__M                                             0x3FF
+#define   SIO_HI_IF_BPT_ADDR__PRE                                           0x2
+
+#define SIO_CC_COMM_EXEC__A                                                 0x450000
+#define SIO_CC_COMM_EXEC__W                                                 2
+#define SIO_CC_COMM_EXEC__M                                                 0x3
+#define SIO_CC_COMM_EXEC__PRE                                               0x0
+#define   SIO_CC_COMM_EXEC_STOP                                             0x0
+#define   SIO_CC_COMM_EXEC_ACTIVE                                           0x1
+#define   SIO_CC_COMM_EXEC_HOLD                                             0x2
+
+#define SIO_CC_PLL_MODE__A                                                  0x450010
+#define SIO_CC_PLL_MODE__W                                                  6
+#define SIO_CC_PLL_MODE__M                                                  0x3F
+#define SIO_CC_PLL_MODE__PRE                                                0x0
+
+#define   SIO_CC_PLL_MODE_FREF_SEL__B                                       0
+#define   SIO_CC_PLL_MODE_FREF_SEL__W                                       2
+#define   SIO_CC_PLL_MODE_FREF_SEL__M                                       0x3
+#define   SIO_CC_PLL_MODE_FREF_SEL__PRE                                     0x0
+#define     SIO_CC_PLL_MODE_FREF_SEL_OHW                                    0x0
+#define     SIO_CC_PLL_MODE_FREF_SEL_27_00                                  0x1
+#define     SIO_CC_PLL_MODE_FREF_SEL_20_25                                  0x2
+#define     SIO_CC_PLL_MODE_FREF_SEL_4_00                                   0x3
+
+#define   SIO_CC_PLL_MODE_LOCKSEL__B                                        2
+#define   SIO_CC_PLL_MODE_LOCKSEL__W                                        2
+#define   SIO_CC_PLL_MODE_LOCKSEL__M                                        0xC
+#define   SIO_CC_PLL_MODE_LOCKSEL__PRE                                      0x0
+
+#define   SIO_CC_PLL_MODE_BYPASS__B                                         4
+#define   SIO_CC_PLL_MODE_BYPASS__W                                         2
+#define   SIO_CC_PLL_MODE_BYPASS__M                                         0x30
+#define   SIO_CC_PLL_MODE_BYPASS__PRE                                       0x0
+#define     SIO_CC_PLL_MODE_BYPASS_OHW                                      0x0
+#define     SIO_CC_PLL_MODE_BYPASS_OFF                                      0x10
+#define     SIO_CC_PLL_MODE_BYPASS_ON                                       0x20
+
+#define SIO_CC_PLL_TEST__A                                                  0x450011
+#define SIO_CC_PLL_TEST__W                                                  8
+#define SIO_CC_PLL_TEST__M                                                  0xFF
+#define SIO_CC_PLL_TEST__PRE                                                0x0
+
+#define SIO_CC_PLL_LOCK__A                                                  0x450012
+#define SIO_CC_PLL_LOCK__W                                                  1
+#define SIO_CC_PLL_LOCK__M                                                  0x1
+#define SIO_CC_PLL_LOCK__PRE                                                0x0
+#define SIO_CC_CLK_MODE__A                                                  0x450014
+#define SIO_CC_CLK_MODE__W                                                  5
+#define SIO_CC_CLK_MODE__M                                                  0x1F
+#define SIO_CC_CLK_MODE__PRE                                                0x0
+
+#define   SIO_CC_CLK_MODE_DELAY__B                                          0
+#define   SIO_CC_CLK_MODE_DELAY__W                                          4
+#define   SIO_CC_CLK_MODE_DELAY__M                                          0xF
+#define   SIO_CC_CLK_MODE_DELAY__PRE                                        0x0
+
+#define   SIO_CC_CLK_MODE_INVERT__B                                         4
+#define   SIO_CC_CLK_MODE_INVERT__W                                         1
+#define   SIO_CC_CLK_MODE_INVERT__M                                         0x10
+#define   SIO_CC_CLK_MODE_INVERT__PRE                                       0x0
+
+#define SIO_CC_PWD_MODE__A                                                  0x450015
+#define SIO_CC_PWD_MODE__W                                                  3
+#define SIO_CC_PWD_MODE__M                                                  0x7
+#define SIO_CC_PWD_MODE__PRE                                                0x0
+
+#define   SIO_CC_PWD_MODE_LEVEL__B                                          0
+#define   SIO_CC_PWD_MODE_LEVEL__W                                          2
+#define   SIO_CC_PWD_MODE_LEVEL__M                                          0x3
+#define   SIO_CC_PWD_MODE_LEVEL__PRE                                        0x0
+#define     SIO_CC_PWD_MODE_LEVEL_NONE                                      0x0
+#define     SIO_CC_PWD_MODE_LEVEL_CLOCK                                     0x1
+#define     SIO_CC_PWD_MODE_LEVEL_PLL                                       0x2
+#define     SIO_CC_PWD_MODE_LEVEL_OSC                                       0x3
+
+#define   SIO_CC_PWD_MODE_USE_LOCK__B                                       2
+#define   SIO_CC_PWD_MODE_USE_LOCK__W                                       1
+#define   SIO_CC_PWD_MODE_USE_LOCK__M                                       0x4
+#define   SIO_CC_PWD_MODE_USE_LOCK__PRE                                     0x0
+
+#define SIO_CC_SOFT_RST__A                                                  0x450016
+#define SIO_CC_SOFT_RST__W                                                  2
+#define SIO_CC_SOFT_RST__M                                                  0x3
+#define SIO_CC_SOFT_RST__PRE                                                0x0
+
+#define   SIO_CC_SOFT_RST_SYS__B                                            0
+#define   SIO_CC_SOFT_RST_SYS__W                                            1
+#define   SIO_CC_SOFT_RST_SYS__M                                            0x1
+#define   SIO_CC_SOFT_RST_SYS__PRE                                          0x0
+
+#define   SIO_CC_SOFT_RST_OSC__B                                            1
+#define   SIO_CC_SOFT_RST_OSC__W                                            1
+#define   SIO_CC_SOFT_RST_OSC__M                                            0x2
+#define   SIO_CC_SOFT_RST_OSC__PRE                                          0x0
+
+#define SIO_CC_UPDATE__A                                                    0x450017
+#define SIO_CC_UPDATE__W                                                    16
+#define SIO_CC_UPDATE__M                                                    0xFFFF
+#define SIO_CC_UPDATE__PRE                                                  0x0
+#define   SIO_CC_UPDATE_KEY                                                 0xFABA
+
+#define SIO_SA_COMM_EXEC__A                                                 0x460000
+#define SIO_SA_COMM_EXEC__W                                                 2
+#define SIO_SA_COMM_EXEC__M                                                 0x3
+#define SIO_SA_COMM_EXEC__PRE                                               0x0
+#define   SIO_SA_COMM_EXEC_STOP                                             0x0
+#define   SIO_SA_COMM_EXEC_ACTIVE                                           0x1
+#define   SIO_SA_COMM_EXEC_HOLD                                             0x2
+
+#define SIO_SA_COMM_INT_REQ__A                                              0x460003
+#define SIO_SA_COMM_INT_REQ__W                                              1
+#define SIO_SA_COMM_INT_REQ__M                                              0x1
+#define SIO_SA_COMM_INT_REQ__PRE                                            0x0
+#define SIO_SA_COMM_INT_STA__A                                              0x460005
+#define SIO_SA_COMM_INT_STA__W                                              4
+#define SIO_SA_COMM_INT_STA__M                                              0xF
+#define SIO_SA_COMM_INT_STA__PRE                                            0x0
+
+#define   SIO_SA_COMM_INT_STA_TR_END_INT_STA__B                             0
+#define   SIO_SA_COMM_INT_STA_TR_END_INT_STA__W                             1
+#define   SIO_SA_COMM_INT_STA_TR_END_INT_STA__M                             0x1
+#define   SIO_SA_COMM_INT_STA_TR_END_INT_STA__PRE                           0x0
+
+#define   SIO_SA_COMM_INT_STA_TR_BUFF_EMPTY_INT__B                          1
+#define   SIO_SA_COMM_INT_STA_TR_BUFF_EMPTY_INT__W                          1
+#define   SIO_SA_COMM_INT_STA_TR_BUFF_EMPTY_INT__M                          0x2
+#define   SIO_SA_COMM_INT_STA_TR_BUFF_EMPTY_INT__PRE                        0x0
+
+#define   SIO_SA_COMM_INT_STA_RX_END_INT_STA__B                             2
+#define   SIO_SA_COMM_INT_STA_RX_END_INT_STA__W                             1
+#define   SIO_SA_COMM_INT_STA_RX_END_INT_STA__M                             0x4
+#define   SIO_SA_COMM_INT_STA_RX_END_INT_STA__PRE                           0x0
+
+#define   SIO_SA_COMM_INT_STA_RX_BUFF_FULL_INT__B                           3
+#define   SIO_SA_COMM_INT_STA_RX_BUFF_FULL_INT__W                           1
+#define   SIO_SA_COMM_INT_STA_RX_BUFF_FULL_INT__M                           0x8
+#define   SIO_SA_COMM_INT_STA_RX_BUFF_FULL_INT__PRE                         0x0
+
+#define SIO_SA_COMM_INT_MSK__A                                              0x460006
+#define SIO_SA_COMM_INT_MSK__W                                              4
+#define SIO_SA_COMM_INT_MSK__M                                              0xF
+#define SIO_SA_COMM_INT_MSK__PRE                                            0x0
+
+#define   SIO_SA_COMM_INT_MSK_TR_END_INT_MASK__B                            0
+#define   SIO_SA_COMM_INT_MSK_TR_END_INT_MASK__W                            1
+#define   SIO_SA_COMM_INT_MSK_TR_END_INT_MASK__M                            0x1
+#define   SIO_SA_COMM_INT_MSK_TR_END_INT_MASK__PRE                          0x0
+
+#define   SIO_SA_COMM_INT_MSK_TR_BUFF_EMPTY_MASK__B                         1
+#define   SIO_SA_COMM_INT_MSK_TR_BUFF_EMPTY_MASK__W                         1
+#define   SIO_SA_COMM_INT_MSK_TR_BUFF_EMPTY_MASK__M                         0x2
+#define   SIO_SA_COMM_INT_MSK_TR_BUFF_EMPTY_MASK__PRE                       0x0
+
+#define   SIO_SA_COMM_INT_MSK_RX_END_INT_MASK__B                            2
+#define   SIO_SA_COMM_INT_MSK_RX_END_INT_MASK__W                            1
+#define   SIO_SA_COMM_INT_MSK_RX_END_INT_MASK__M                            0x4
+#define   SIO_SA_COMM_INT_MSK_RX_END_INT_MASK__PRE                          0x0
+
+#define   SIO_SA_COMM_INT_MSK_RX_BUFF_FULL_MASK__B                          3
+#define   SIO_SA_COMM_INT_MSK_RX_BUFF_FULL_MASK__W                          1
+#define   SIO_SA_COMM_INT_MSK_RX_BUFF_FULL_MASK__M                          0x8
+#define   SIO_SA_COMM_INT_MSK_RX_BUFF_FULL_MASK__PRE                        0x0
+
+#define SIO_SA_COMM_INT_STM__A                                              0x460007
+#define SIO_SA_COMM_INT_STM__W                                              4
+#define SIO_SA_COMM_INT_STM__M                                              0xF
+#define SIO_SA_COMM_INT_STM__PRE                                            0x0
+
+#define   SIO_SA_COMM_INT_STM_TR_END_INT_MASK__B                            0
+#define   SIO_SA_COMM_INT_STM_TR_END_INT_MASK__W                            1
+#define   SIO_SA_COMM_INT_STM_TR_END_INT_MASK__M                            0x1
+#define   SIO_SA_COMM_INT_STM_TR_END_INT_MASK__PRE                          0x0
+
+#define   SIO_SA_COMM_INT_STM_TR_BUFF_EMPTY_MASK__B                         1
+#define   SIO_SA_COMM_INT_STM_TR_BUFF_EMPTY_MASK__W                         1
+#define   SIO_SA_COMM_INT_STM_TR_BUFF_EMPTY_MASK__M                         0x2
+#define   SIO_SA_COMM_INT_STM_TR_BUFF_EMPTY_MASK__PRE                       0x0
+
+#define   SIO_SA_COMM_INT_STM_RX_END_INT_MASK__B                            2
+#define   SIO_SA_COMM_INT_STM_RX_END_INT_MASK__W                            1
+#define   SIO_SA_COMM_INT_STM_RX_END_INT_MASK__M                            0x4
+#define   SIO_SA_COMM_INT_STM_RX_END_INT_MASK__PRE                          0x0
+
+#define   SIO_SA_COMM_INT_STM_RX_BUFF_FULL_MASK__B                          3
+#define   SIO_SA_COMM_INT_STM_RX_BUFF_FULL_MASK__W                          1
+#define   SIO_SA_COMM_INT_STM_RX_BUFF_FULL_MASK__M                          0x8
+#define   SIO_SA_COMM_INT_STM_RX_BUFF_FULL_MASK__PRE                        0x0
+
+#define SIO_SA_PRESCALER__A                                                 0x460010
+#define SIO_SA_PRESCALER__W                                                 13
+#define SIO_SA_PRESCALER__M                                                 0x1FFF
+#define SIO_SA_PRESCALER__PRE                                               0x18B7
+#define SIO_SA_TX_DATA0__A                                                  0x460011
+#define SIO_SA_TX_DATA0__W                                                  16
+#define SIO_SA_TX_DATA0__M                                                  0xFFFF
+#define SIO_SA_TX_DATA0__PRE                                                0x0
+#define SIO_SA_TX_DATA1__A                                                  0x460012
+#define SIO_SA_TX_DATA1__W                                                  16
+#define SIO_SA_TX_DATA1__M                                                  0xFFFF
+#define SIO_SA_TX_DATA1__PRE                                                0x0
+#define SIO_SA_TX_DATA2__A                                                  0x460013
+#define SIO_SA_TX_DATA2__W                                                  16
+#define SIO_SA_TX_DATA2__M                                                  0xFFFF
+#define SIO_SA_TX_DATA2__PRE                                                0x0
+#define SIO_SA_TX_DATA3__A                                                  0x460014
+#define SIO_SA_TX_DATA3__W                                                  16
+#define SIO_SA_TX_DATA3__M                                                  0xFFFF
+#define SIO_SA_TX_DATA3__PRE                                                0x0
+#define SIO_SA_TX_LENGTH__A                                                 0x460015
+#define SIO_SA_TX_LENGTH__W                                                 6
+#define SIO_SA_TX_LENGTH__M                                                 0x3F
+#define SIO_SA_TX_LENGTH__PRE                                               0x0
+#define SIO_SA_TX_COMMAND__A                                                0x460016
+#define SIO_SA_TX_COMMAND__W                                                2
+#define SIO_SA_TX_COMMAND__M                                                0x3
+#define SIO_SA_TX_COMMAND__PRE                                              0x3
+
+#define   SIO_SA_TX_COMMAND_TX_INVERT__B                                    0
+#define   SIO_SA_TX_COMMAND_TX_INVERT__W                                    1
+#define   SIO_SA_TX_COMMAND_TX_INVERT__M                                    0x1
+#define   SIO_SA_TX_COMMAND_TX_INVERT__PRE                                  0x1
+
+#define   SIO_SA_TX_COMMAND_TX_ENABLE__B                                    1
+#define   SIO_SA_TX_COMMAND_TX_ENABLE__W                                    1
+#define   SIO_SA_TX_COMMAND_TX_ENABLE__M                                    0x2
+#define   SIO_SA_TX_COMMAND_TX_ENABLE__PRE                                  0x2
+
+#define SIO_SA_TX_STATUS__A                                                 0x460017
+#define SIO_SA_TX_STATUS__W                                                 2
+#define SIO_SA_TX_STATUS__M                                                 0x3
+#define SIO_SA_TX_STATUS__PRE                                               0x0
+
+#define   SIO_SA_TX_STATUS_BUSY__B                                          0
+#define   SIO_SA_TX_STATUS_BUSY__W                                          1
+#define   SIO_SA_TX_STATUS_BUSY__M                                          0x1
+#define   SIO_SA_TX_STATUS_BUSY__PRE                                        0x0
+
+#define   SIO_SA_TX_STATUS_BUFF_FULL__B                                     1
+#define   SIO_SA_TX_STATUS_BUFF_FULL__W                                     1
+#define   SIO_SA_TX_STATUS_BUFF_FULL__M                                     0x2
+#define   SIO_SA_TX_STATUS_BUFF_FULL__PRE                                   0x0
+
+#define SIO_SA_RX_DATA0__A                                                  0x460018
+#define SIO_SA_RX_DATA0__W                                                  16
+#define SIO_SA_RX_DATA0__M                                                  0xFFFF
+#define SIO_SA_RX_DATA0__PRE                                                0x0
+#define SIO_SA_RX_DATA1__A                                                  0x460019
+#define SIO_SA_RX_DATA1__W                                                  16
+#define SIO_SA_RX_DATA1__M                                                  0xFFFF
+#define SIO_SA_RX_DATA1__PRE                                                0x0
+#define SIO_SA_RX_LENGTH__A                                                 0x46001A
+#define SIO_SA_RX_LENGTH__W                                                 6
+#define SIO_SA_RX_LENGTH__M                                                 0x3F
+#define SIO_SA_RX_LENGTH__PRE                                               0x0
+#define SIO_SA_RX_COMMAND__A                                                0x46001B
+#define SIO_SA_RX_COMMAND__W                                                1
+#define SIO_SA_RX_COMMAND__M                                                0x1
+#define SIO_SA_RX_COMMAND__PRE                                              0x1
+
+#define   SIO_SA_RX_COMMAND_RX_INVERT__B                                    0
+#define   SIO_SA_RX_COMMAND_RX_INVERT__W                                    1
+#define   SIO_SA_RX_COMMAND_RX_INVERT__M                                    0x1
+#define   SIO_SA_RX_COMMAND_RX_INVERT__PRE                                  0x1
+
+#define SIO_SA_RX_STATUS__A                                                 0x46001C
+#define SIO_SA_RX_STATUS__W                                                 2
+#define SIO_SA_RX_STATUS__M                                                 0x3
+#define SIO_SA_RX_STATUS__PRE                                               0x0
+
+#define   SIO_SA_RX_STATUS_BUSY__B                                          0
+#define   SIO_SA_RX_STATUS_BUSY__W                                          1
+#define   SIO_SA_RX_STATUS_BUSY__M                                          0x1
+#define   SIO_SA_RX_STATUS_BUSY__PRE                                        0x0
+
+#define   SIO_SA_RX_STATUS_BUFF_FULL__B                                     1
+#define   SIO_SA_RX_STATUS_BUFF_FULL__W                                     1
+#define   SIO_SA_RX_STATUS_BUFF_FULL__M                                     0x2
+#define   SIO_SA_RX_STATUS_BUFF_FULL__PRE                                   0x0
+
+#define SIO_PDR_COMM_EXEC__A                                                0x7F0000
+#define SIO_PDR_COMM_EXEC__W                                                2
+#define SIO_PDR_COMM_EXEC__M                                                0x3
+#define SIO_PDR_COMM_EXEC__PRE                                              0x0
+#define   SIO_PDR_COMM_EXEC_STOP                                            0x0
+#define   SIO_PDR_COMM_EXEC_ACTIVE                                          0x1
+#define   SIO_PDR_COMM_EXEC_HOLD                                            0x2
+
+#define SIO_PDR_MON_CFG__A                                                  0x7F0010
+#define SIO_PDR_MON_CFG__W                                                  2
+#define SIO_PDR_MON_CFG__M                                                  0x3
+#define SIO_PDR_MON_CFG__PRE                                                0x0
+
+#define   SIO_PDR_MON_CFG_OSEL__B                                           0
+#define   SIO_PDR_MON_CFG_OSEL__W                                           1
+#define   SIO_PDR_MON_CFG_OSEL__M                                           0x1
+#define   SIO_PDR_MON_CFG_OSEL__PRE                                         0x0
+
+#define   SIO_PDR_MON_CFG_IACT__B                                           1
+#define   SIO_PDR_MON_CFG_IACT__W                                           1
+#define   SIO_PDR_MON_CFG_IACT__M                                           0x2
+#define   SIO_PDR_MON_CFG_IACT__PRE                                         0x0
+
+#define SIO_PDR_FDB_CFG__A                                                  0x7F0011
+#define SIO_PDR_FDB_CFG__W                                                  2
+#define SIO_PDR_FDB_CFG__M                                                  0x3
+#define SIO_PDR_FDB_CFG__PRE                                                0x0
+#define   SIO_PDR_FDB_CFG_SEL__B                                            0
+#define   SIO_PDR_FDB_CFG_SEL__W                                            2
+#define   SIO_PDR_FDB_CFG_SEL__M                                            0x3
+#define   SIO_PDR_FDB_CFG_SEL__PRE                                          0x0
+
+#define SIO_PDR_SMA_RX_SEL__A                                               0x7F0012
+#define SIO_PDR_SMA_RX_SEL__W                                               4
+#define SIO_PDR_SMA_RX_SEL__M                                               0xF
+#define SIO_PDR_SMA_RX_SEL__PRE                                             0x0
+#define   SIO_PDR_SMA_RX_SEL_SEL__B                                         0
+#define   SIO_PDR_SMA_RX_SEL_SEL__W                                         4
+#define   SIO_PDR_SMA_RX_SEL_SEL__M                                         0xF
+#define   SIO_PDR_SMA_RX_SEL_SEL__PRE                                       0x0
+
+#define SIO_PDR_SMA_TX_SILENT__A                                            0x7F0013
+#define SIO_PDR_SMA_TX_SILENT__W                                            1
+#define SIO_PDR_SMA_TX_SILENT__M                                            0x1
+#define SIO_PDR_SMA_TX_SILENT__PRE                                          0x0
+#define SIO_PDR_UIO_IN_LO__A                                                0x7F0014
+#define SIO_PDR_UIO_IN_LO__W                                                16
+#define SIO_PDR_UIO_IN_LO__M                                                0xFFFF
+#define SIO_PDR_UIO_IN_LO__PRE                                              0x0
+#define   SIO_PDR_UIO_IN_LO_DATA__B                                         0
+#define   SIO_PDR_UIO_IN_LO_DATA__W                                         16
+#define   SIO_PDR_UIO_IN_LO_DATA__M                                         0xFFFF
+#define   SIO_PDR_UIO_IN_LO_DATA__PRE                                       0x0
+
+#define SIO_PDR_UIO_IN_HI__A                                                0x7F0015
+#define SIO_PDR_UIO_IN_HI__W                                                14
+#define SIO_PDR_UIO_IN_HI__M                                                0x3FFF
+#define SIO_PDR_UIO_IN_HI__PRE                                              0x0
+#define   SIO_PDR_UIO_IN_HI_DATA__B                                         0
+#define   SIO_PDR_UIO_IN_HI_DATA__W                                         14
+#define   SIO_PDR_UIO_IN_HI_DATA__M                                         0x3FFF
+#define   SIO_PDR_UIO_IN_HI_DATA__PRE                                       0x0
+
+#define SIO_PDR_UIO_OUT_LO__A                                               0x7F0016
+#define SIO_PDR_UIO_OUT_LO__W                                               16
+#define SIO_PDR_UIO_OUT_LO__M                                               0xFFFF
+#define SIO_PDR_UIO_OUT_LO__PRE                                             0x0
+#define   SIO_PDR_UIO_OUT_LO_DATA__B                                        0
+#define   SIO_PDR_UIO_OUT_LO_DATA__W                                        16
+#define   SIO_PDR_UIO_OUT_LO_DATA__M                                        0xFFFF
+#define   SIO_PDR_UIO_OUT_LO_DATA__PRE                                      0x0
+
+#define SIO_PDR_UIO_OUT_HI__A                                               0x7F0017
+#define SIO_PDR_UIO_OUT_HI__W                                               14
+#define SIO_PDR_UIO_OUT_HI__M                                               0x3FFF
+#define SIO_PDR_UIO_OUT_HI__PRE                                             0x0
+#define   SIO_PDR_UIO_OUT_HI_DATA__B                                        0
+#define   SIO_PDR_UIO_OUT_HI_DATA__W                                        14
+#define   SIO_PDR_UIO_OUT_HI_DATA__M                                        0x3FFF
+#define   SIO_PDR_UIO_OUT_HI_DATA__PRE                                      0x0
+
+#define SIO_PDR_PWM1_MODE__A                                                0x7F0018
+#define SIO_PDR_PWM1_MODE__W                                                2
+#define SIO_PDR_PWM1_MODE__M                                                0x3
+#define SIO_PDR_PWM1_MODE__PRE                                              0x0
+#define SIO_PDR_PWM1_PRESCALE__A                                            0x7F0019
+#define SIO_PDR_PWM1_PRESCALE__W                                            6
+#define SIO_PDR_PWM1_PRESCALE__M                                            0x3F
+#define SIO_PDR_PWM1_PRESCALE__PRE                                          0x0
+#define SIO_PDR_PWM1_VALUE__A                                               0x7F001A
+#define SIO_PDR_PWM1_VALUE__W                                               11
+#define SIO_PDR_PWM1_VALUE__M                                               0x7FF
+#define SIO_PDR_PWM1_VALUE__PRE                                             0x0
+#define SIO_PDR_PWM2_MODE__A                                                0x7F001C
+#define SIO_PDR_PWM2_MODE__W                                                2
+#define SIO_PDR_PWM2_MODE__M                                                0x3
+#define SIO_PDR_PWM2_MODE__PRE                                              0x0
+#define SIO_PDR_PWM2_PRESCALE__A                                            0x7F001D
+#define SIO_PDR_PWM2_PRESCALE__W                                            6
+#define SIO_PDR_PWM2_PRESCALE__M                                            0x3F
+#define SIO_PDR_PWM2_PRESCALE__PRE                                          0x0
+#define SIO_PDR_PWM2_VALUE__A                                               0x7F001E
+#define SIO_PDR_PWM2_VALUE__W                                               11
+#define SIO_PDR_PWM2_VALUE__M                                               0x7FF
+#define SIO_PDR_PWM2_VALUE__PRE                                             0x0
+#define SIO_PDR_OHW_CFG__A                                                  0x7F001F
+#define SIO_PDR_OHW_CFG__W                                                  7
+#define SIO_PDR_OHW_CFG__M                                                  0x7F
+#define SIO_PDR_OHW_CFG__PRE                                                0x0
+
+#define   SIO_PDR_OHW_CFG_FREF_SEL__B                                       0
+#define   SIO_PDR_OHW_CFG_FREF_SEL__W                                       2
+#define   SIO_PDR_OHW_CFG_FREF_SEL__M                                       0x3
+#define   SIO_PDR_OHW_CFG_FREF_SEL__PRE                                     0x0
+
+#define   SIO_PDR_OHW_CFG_BYPASS__B                                         2
+#define   SIO_PDR_OHW_CFG_BYPASS__W                                         1
+#define   SIO_PDR_OHW_CFG_BYPASS__M                                         0x4
+#define   SIO_PDR_OHW_CFG_BYPASS__PRE                                       0x0
+
+#define   SIO_PDR_OHW_CFG_ASEL__B                                           3
+#define   SIO_PDR_OHW_CFG_ASEL__W                                           3
+#define   SIO_PDR_OHW_CFG_ASEL__M                                           0x38
+#define   SIO_PDR_OHW_CFG_ASEL__PRE                                         0x0
+
+#define   SIO_PDR_OHW_CFG_SPEED__B                                          6
+#define   SIO_PDR_OHW_CFG_SPEED__W                                          1
+#define   SIO_PDR_OHW_CFG_SPEED__M                                          0x40
+#define   SIO_PDR_OHW_CFG_SPEED__PRE                                        0x0
+
+#define SIO_PDR_I2S_WS_CFG__A                                               0x7F0020
+#define SIO_PDR_I2S_WS_CFG__W                                               9
+#define SIO_PDR_I2S_WS_CFG__M                                               0x1FF
+#define SIO_PDR_I2S_WS_CFG__PRE                                             0x10
+#define   SIO_PDR_I2S_WS_CFG_MODE__B                                        0
+#define   SIO_PDR_I2S_WS_CFG_MODE__W                                        3
+#define   SIO_PDR_I2S_WS_CFG_MODE__M                                        0x7
+#define   SIO_PDR_I2S_WS_CFG_MODE__PRE                                      0x0
+#define   SIO_PDR_I2S_WS_CFG_DRIVE__B                                       3
+#define   SIO_PDR_I2S_WS_CFG_DRIVE__W                                       3
+#define   SIO_PDR_I2S_WS_CFG_DRIVE__M                                       0x38
+#define   SIO_PDR_I2S_WS_CFG_DRIVE__PRE                                     0x10
+#define   SIO_PDR_I2S_WS_CFG_KEEP__B                                        6
+#define   SIO_PDR_I2S_WS_CFG_KEEP__W                                        2
+#define   SIO_PDR_I2S_WS_CFG_KEEP__M                                        0xC0
+#define   SIO_PDR_I2S_WS_CFG_KEEP__PRE                                      0x0
+#define   SIO_PDR_I2S_WS_CFG_UIO__B                                         8
+#define   SIO_PDR_I2S_WS_CFG_UIO__W                                         1
+#define   SIO_PDR_I2S_WS_CFG_UIO__M                                         0x100
+#define   SIO_PDR_I2S_WS_CFG_UIO__PRE                                       0x0
+
+#define SIO_PDR_GPIO_CFG__A                                                 0x7F0021
+#define SIO_PDR_GPIO_CFG__W                                                 9
+#define SIO_PDR_GPIO_CFG__M                                                 0x1FF
+#define SIO_PDR_GPIO_CFG__PRE                                               0x10
+#define   SIO_PDR_GPIO_CFG_MODE__B                                          0
+#define   SIO_PDR_GPIO_CFG_MODE__W                                          3
+#define   SIO_PDR_GPIO_CFG_MODE__M                                          0x7
+#define   SIO_PDR_GPIO_CFG_MODE__PRE                                        0x0
+#define   SIO_PDR_GPIO_CFG_DRIVE__B                                         3
+#define   SIO_PDR_GPIO_CFG_DRIVE__W                                         3
+#define   SIO_PDR_GPIO_CFG_DRIVE__M                                         0x38
+#define   SIO_PDR_GPIO_CFG_DRIVE__PRE                                       0x10
+#define   SIO_PDR_GPIO_CFG_KEEP__B                                          6
+#define   SIO_PDR_GPIO_CFG_KEEP__W                                          2
+#define   SIO_PDR_GPIO_CFG_KEEP__M                                          0xC0
+#define   SIO_PDR_GPIO_CFG_KEEP__PRE                                        0x0
+#define   SIO_PDR_GPIO_CFG_UIO__B                                           8
+#define   SIO_PDR_GPIO_CFG_UIO__W                                           1
+#define   SIO_PDR_GPIO_CFG_UIO__M                                           0x100
+#define   SIO_PDR_GPIO_CFG_UIO__PRE                                         0x0
+
+#define SIO_PDR_IRQN_CFG__A                                                 0x7F0022
+#define SIO_PDR_IRQN_CFG__W                                                 9
+#define SIO_PDR_IRQN_CFG__M                                                 0x1FF
+#define SIO_PDR_IRQN_CFG__PRE                                               0x10
+#define   SIO_PDR_IRQN_CFG_MODE__B                                          0
+#define   SIO_PDR_IRQN_CFG_MODE__W                                          3
+#define   SIO_PDR_IRQN_CFG_MODE__M                                          0x7
+#define   SIO_PDR_IRQN_CFG_MODE__PRE                                        0x0
+#define   SIO_PDR_IRQN_CFG_DRIVE__B                                         3
+#define   SIO_PDR_IRQN_CFG_DRIVE__W                                         3
+#define   SIO_PDR_IRQN_CFG_DRIVE__M                                         0x38
+#define   SIO_PDR_IRQN_CFG_DRIVE__PRE                                       0x10
+#define   SIO_PDR_IRQN_CFG_KEEP__B                                          6
+#define   SIO_PDR_IRQN_CFG_KEEP__W                                          2
+#define   SIO_PDR_IRQN_CFG_KEEP__M                                          0xC0
+#define   SIO_PDR_IRQN_CFG_KEEP__PRE                                        0x0
+#define   SIO_PDR_IRQN_CFG_UIO__B                                           8
+#define   SIO_PDR_IRQN_CFG_UIO__W                                           1
+#define   SIO_PDR_IRQN_CFG_UIO__M                                           0x100
+#define   SIO_PDR_IRQN_CFG_UIO__PRE                                         0x0
+
+#define SIO_PDR_OOB_CRX_CFG__A                                              0x7F0023
+#define SIO_PDR_OOB_CRX_CFG__W                                              9
+#define SIO_PDR_OOB_CRX_CFG__M                                              0x1FF
+#define SIO_PDR_OOB_CRX_CFG__PRE                                            0x10
+#define   SIO_PDR_OOB_CRX_CFG_MODE__B                                       0
+#define   SIO_PDR_OOB_CRX_CFG_MODE__W                                       3
+#define   SIO_PDR_OOB_CRX_CFG_MODE__M                                       0x7
+#define   SIO_PDR_OOB_CRX_CFG_MODE__PRE                                     0x0
+#define   SIO_PDR_OOB_CRX_CFG_DRIVE__B                                      3
+#define   SIO_PDR_OOB_CRX_CFG_DRIVE__W                                      3
+#define   SIO_PDR_OOB_CRX_CFG_DRIVE__M                                      0x38
+#define   SIO_PDR_OOB_CRX_CFG_DRIVE__PRE                                    0x10
+#define   SIO_PDR_OOB_CRX_CFG_KEEP__B                                       6
+#define   SIO_PDR_OOB_CRX_CFG_KEEP__W                                       2
+#define   SIO_PDR_OOB_CRX_CFG_KEEP__M                                       0xC0
+#define   SIO_PDR_OOB_CRX_CFG_KEEP__PRE                                     0x0
+#define   SIO_PDR_OOB_CRX_CFG_UIO__B                                        8
+#define   SIO_PDR_OOB_CRX_CFG_UIO__W                                        1
+#define   SIO_PDR_OOB_CRX_CFG_UIO__M                                        0x100
+#define   SIO_PDR_OOB_CRX_CFG_UIO__PRE                                      0x0
+
+#define SIO_PDR_OOB_DRX_CFG__A                                              0x7F0024
+#define SIO_PDR_OOB_DRX_CFG__W                                              9
+#define SIO_PDR_OOB_DRX_CFG__M                                              0x1FF
+#define SIO_PDR_OOB_DRX_CFG__PRE                                            0x10
+#define   SIO_PDR_OOB_DRX_CFG_MODE__B                                       0
+#define   SIO_PDR_OOB_DRX_CFG_MODE__W                                       3
+#define   SIO_PDR_OOB_DRX_CFG_MODE__M                                       0x7
+#define   SIO_PDR_OOB_DRX_CFG_MODE__PRE                                     0x0
+#define   SIO_PDR_OOB_DRX_CFG_DRIVE__B                                      3
+#define   SIO_PDR_OOB_DRX_CFG_DRIVE__W                                      3
+#define   SIO_PDR_OOB_DRX_CFG_DRIVE__M                                      0x38
+#define   SIO_PDR_OOB_DRX_CFG_DRIVE__PRE                                    0x10
+#define   SIO_PDR_OOB_DRX_CFG_KEEP__B                                       6
+#define   SIO_PDR_OOB_DRX_CFG_KEEP__W                                       2
+#define   SIO_PDR_OOB_DRX_CFG_KEEP__M                                       0xC0
+#define   SIO_PDR_OOB_DRX_CFG_KEEP__PRE                                     0x0
+#define   SIO_PDR_OOB_DRX_CFG_UIO__B                                        8
+#define   SIO_PDR_OOB_DRX_CFG_UIO__W                                        1
+#define   SIO_PDR_OOB_DRX_CFG_UIO__M                                        0x100
+#define   SIO_PDR_OOB_DRX_CFG_UIO__PRE                                      0x0
+
+#define SIO_PDR_MSTRT_CFG__A                                                0x7F0025
+#define SIO_PDR_MSTRT_CFG__W                                                9
+#define SIO_PDR_MSTRT_CFG__M                                                0x1FF
+#define SIO_PDR_MSTRT_CFG__PRE                                              0x50
+#define   SIO_PDR_MSTRT_CFG_MODE__B                                         0
+#define   SIO_PDR_MSTRT_CFG_MODE__W                                         3
+#define   SIO_PDR_MSTRT_CFG_MODE__M                                         0x7
+#define   SIO_PDR_MSTRT_CFG_MODE__PRE                                       0x0
+#define   SIO_PDR_MSTRT_CFG_DRIVE__B                                        3
+#define   SIO_PDR_MSTRT_CFG_DRIVE__W                                        3
+#define   SIO_PDR_MSTRT_CFG_DRIVE__M                                        0x38
+#define   SIO_PDR_MSTRT_CFG_DRIVE__PRE                                      0x10
+#define   SIO_PDR_MSTRT_CFG_KEEP__B                                         6
+#define   SIO_PDR_MSTRT_CFG_KEEP__W                                         2
+#define   SIO_PDR_MSTRT_CFG_KEEP__M                                         0xC0
+#define   SIO_PDR_MSTRT_CFG_KEEP__PRE                                       0x40
+#define   SIO_PDR_MSTRT_CFG_UIO__B                                          8
+#define   SIO_PDR_MSTRT_CFG_UIO__W                                          1
+#define   SIO_PDR_MSTRT_CFG_UIO__M                                          0x100
+#define   SIO_PDR_MSTRT_CFG_UIO__PRE                                        0x0
+
+#define SIO_PDR_MERR_CFG__A                                                 0x7F0026
+#define SIO_PDR_MERR_CFG__W                                                 9
+#define SIO_PDR_MERR_CFG__M                                                 0x1FF
+#define SIO_PDR_MERR_CFG__PRE                                               0x50
+#define   SIO_PDR_MERR_CFG_MODE__B                                          0
+#define   SIO_PDR_MERR_CFG_MODE__W                                          3
+#define   SIO_PDR_MERR_CFG_MODE__M                                          0x7
+#define   SIO_PDR_MERR_CFG_MODE__PRE                                        0x0
+#define   SIO_PDR_MERR_CFG_DRIVE__B                                         3
+#define   SIO_PDR_MERR_CFG_DRIVE__W                                         3
+#define   SIO_PDR_MERR_CFG_DRIVE__M                                         0x38
+#define   SIO_PDR_MERR_CFG_DRIVE__PRE                                       0x10
+#define   SIO_PDR_MERR_CFG_KEEP__B                                          6
+#define   SIO_PDR_MERR_CFG_KEEP__W                                          2
+#define   SIO_PDR_MERR_CFG_KEEP__M                                          0xC0
+#define   SIO_PDR_MERR_CFG_KEEP__PRE                                        0x40
+#define   SIO_PDR_MERR_CFG_UIO__B                                           8
+#define   SIO_PDR_MERR_CFG_UIO__W                                           1
+#define   SIO_PDR_MERR_CFG_UIO__M                                           0x100
+#define   SIO_PDR_MERR_CFG_UIO__PRE                                         0x0
+
+#define SIO_PDR_MCLK_CFG__A                                                 0x7F0028
+#define SIO_PDR_MCLK_CFG__W                                                 9
+#define SIO_PDR_MCLK_CFG__M                                                 0x1FF
+#define SIO_PDR_MCLK_CFG__PRE                                               0x50
+#define   SIO_PDR_MCLK_CFG_MODE__B                                          0
+#define   SIO_PDR_MCLK_CFG_MODE__W                                          3
+#define   SIO_PDR_MCLK_CFG_MODE__M                                          0x7
+#define   SIO_PDR_MCLK_CFG_MODE__PRE                                        0x0
+#define   SIO_PDR_MCLK_CFG_DRIVE__B                                         3
+#define   SIO_PDR_MCLK_CFG_DRIVE__W                                         3
+#define   SIO_PDR_MCLK_CFG_DRIVE__M                                         0x38
+#define   SIO_PDR_MCLK_CFG_DRIVE__PRE                                       0x10
+#define   SIO_PDR_MCLK_CFG_KEEP__B                                          6
+#define   SIO_PDR_MCLK_CFG_KEEP__W                                          2
+#define   SIO_PDR_MCLK_CFG_KEEP__M                                          0xC0
+#define   SIO_PDR_MCLK_CFG_KEEP__PRE                                        0x40
+#define   SIO_PDR_MCLK_CFG_UIO__B                                           8
+#define   SIO_PDR_MCLK_CFG_UIO__W                                           1
+#define   SIO_PDR_MCLK_CFG_UIO__M                                           0x100
+#define   SIO_PDR_MCLK_CFG_UIO__PRE                                         0x0
+
+#define SIO_PDR_MVAL_CFG__A                                                 0x7F0029
+#define SIO_PDR_MVAL_CFG__W                                                 9
+#define SIO_PDR_MVAL_CFG__M                                                 0x1FF
+#define SIO_PDR_MVAL_CFG__PRE                                               0x50
+#define   SIO_PDR_MVAL_CFG_MODE__B                                          0
+#define   SIO_PDR_MVAL_CFG_MODE__W                                          3
+#define   SIO_PDR_MVAL_CFG_MODE__M                                          0x7
+#define   SIO_PDR_MVAL_CFG_MODE__PRE                                        0x0
+#define   SIO_PDR_MVAL_CFG_DRIVE__B                                         3
+#define   SIO_PDR_MVAL_CFG_DRIVE__W                                         3
+#define   SIO_PDR_MVAL_CFG_DRIVE__M                                         0x38
+#define   SIO_PDR_MVAL_CFG_DRIVE__PRE                                       0x10
+#define   SIO_PDR_MVAL_CFG_KEEP__B                                          6
+#define   SIO_PDR_MVAL_CFG_KEEP__W                                          2
+#define   SIO_PDR_MVAL_CFG_KEEP__M                                          0xC0
+#define   SIO_PDR_MVAL_CFG_KEEP__PRE                                        0x40
+#define   SIO_PDR_MVAL_CFG_UIO__B                                           8
+#define   SIO_PDR_MVAL_CFG_UIO__W                                           1
+#define   SIO_PDR_MVAL_CFG_UIO__M                                           0x100
+#define   SIO_PDR_MVAL_CFG_UIO__PRE                                         0x0
+
+#define SIO_PDR_MD0_CFG__A                                                  0x7F002A
+#define SIO_PDR_MD0_CFG__W                                                  9
+#define SIO_PDR_MD0_CFG__M                                                  0x1FF
+#define SIO_PDR_MD0_CFG__PRE                                                0x50
+#define   SIO_PDR_MD0_CFG_MODE__B                                           0
+#define   SIO_PDR_MD0_CFG_MODE__W                                           3
+#define   SIO_PDR_MD0_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD0_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD0_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD0_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD0_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD0_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD0_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD0_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD0_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD0_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD0_CFG_UIO__B                                            8
+#define   SIO_PDR_MD0_CFG_UIO__W                                            1
+#define   SIO_PDR_MD0_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD0_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD1_CFG__A                                                  0x7F002B
+#define SIO_PDR_MD1_CFG__W                                                  9
+#define SIO_PDR_MD1_CFG__M                                                  0x1FF
+#define SIO_PDR_MD1_CFG__PRE                                                0x50
+#define   SIO_PDR_MD1_CFG_MODE__B                                           0
+#define   SIO_PDR_MD1_CFG_MODE__W                                           3
+#define   SIO_PDR_MD1_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD1_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD1_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD1_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD1_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD1_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD1_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD1_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD1_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD1_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD1_CFG_UIO__B                                            8
+#define   SIO_PDR_MD1_CFG_UIO__W                                            1
+#define   SIO_PDR_MD1_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD1_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD2_CFG__A                                                  0x7F002C
+#define SIO_PDR_MD2_CFG__W                                                  9
+#define SIO_PDR_MD2_CFG__M                                                  0x1FF
+#define SIO_PDR_MD2_CFG__PRE                                                0x50
+#define   SIO_PDR_MD2_CFG_MODE__B                                           0
+#define   SIO_PDR_MD2_CFG_MODE__W                                           3
+#define   SIO_PDR_MD2_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD2_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD2_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD2_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD2_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD2_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD2_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD2_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD2_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD2_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD2_CFG_UIO__B                                            8
+#define   SIO_PDR_MD2_CFG_UIO__W                                            1
+#define   SIO_PDR_MD2_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD2_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD3_CFG__A                                                  0x7F002D
+#define SIO_PDR_MD3_CFG__W                                                  9
+#define SIO_PDR_MD3_CFG__M                                                  0x1FF
+#define SIO_PDR_MD3_CFG__PRE                                                0x50
+#define   SIO_PDR_MD3_CFG_MODE__B                                           0
+#define   SIO_PDR_MD3_CFG_MODE__W                                           3
+#define   SIO_PDR_MD3_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD3_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD3_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD3_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD3_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD3_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD3_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD3_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD3_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD3_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD3_CFG_UIO__B                                            8
+#define   SIO_PDR_MD3_CFG_UIO__W                                            1
+#define   SIO_PDR_MD3_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD3_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD4_CFG__A                                                  0x7F002F
+#define SIO_PDR_MD4_CFG__W                                                  9
+#define SIO_PDR_MD4_CFG__M                                                  0x1FF
+#define SIO_PDR_MD4_CFG__PRE                                                0x50
+#define   SIO_PDR_MD4_CFG_MODE__B                                           0
+#define   SIO_PDR_MD4_CFG_MODE__W                                           3
+#define   SIO_PDR_MD4_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD4_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD4_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD4_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD4_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD4_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD4_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD4_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD4_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD4_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD4_CFG_UIO__B                                            8
+#define   SIO_PDR_MD4_CFG_UIO__W                                            1
+#define   SIO_PDR_MD4_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD4_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD5_CFG__A                                                  0x7F0030
+#define SIO_PDR_MD5_CFG__W                                                  9
+#define SIO_PDR_MD5_CFG__M                                                  0x1FF
+#define SIO_PDR_MD5_CFG__PRE                                                0x50
+#define   SIO_PDR_MD5_CFG_MODE__B                                           0
+#define   SIO_PDR_MD5_CFG_MODE__W                                           3
+#define   SIO_PDR_MD5_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD5_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD5_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD5_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD5_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD5_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD5_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD5_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD5_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD5_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD5_CFG_UIO__B                                            8
+#define   SIO_PDR_MD5_CFG_UIO__W                                            1
+#define   SIO_PDR_MD5_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD5_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD6_CFG__A                                                  0x7F0031
+#define SIO_PDR_MD6_CFG__W                                                  9
+#define SIO_PDR_MD6_CFG__M                                                  0x1FF
+#define SIO_PDR_MD6_CFG__PRE                                                0x50
+#define   SIO_PDR_MD6_CFG_MODE__B                                           0
+#define   SIO_PDR_MD6_CFG_MODE__W                                           3
+#define   SIO_PDR_MD6_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD6_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD6_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD6_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD6_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD6_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD6_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD6_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD6_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD6_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD6_CFG_UIO__B                                            8
+#define   SIO_PDR_MD6_CFG_UIO__W                                            1
+#define   SIO_PDR_MD6_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD6_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_MD7_CFG__A                                                  0x7F0032
+#define SIO_PDR_MD7_CFG__W                                                  9
+#define SIO_PDR_MD7_CFG__M                                                  0x1FF
+#define SIO_PDR_MD7_CFG__PRE                                                0x50
+#define   SIO_PDR_MD7_CFG_MODE__B                                           0
+#define   SIO_PDR_MD7_CFG_MODE__W                                           3
+#define   SIO_PDR_MD7_CFG_MODE__M                                           0x7
+#define   SIO_PDR_MD7_CFG_MODE__PRE                                         0x0
+#define   SIO_PDR_MD7_CFG_DRIVE__B                                          3
+#define   SIO_PDR_MD7_CFG_DRIVE__W                                          3
+#define   SIO_PDR_MD7_CFG_DRIVE__M                                          0x38
+#define   SIO_PDR_MD7_CFG_DRIVE__PRE                                        0x10
+#define   SIO_PDR_MD7_CFG_KEEP__B                                           6
+#define   SIO_PDR_MD7_CFG_KEEP__W                                           2
+#define   SIO_PDR_MD7_CFG_KEEP__M                                           0xC0
+#define   SIO_PDR_MD7_CFG_KEEP__PRE                                         0x40
+#define   SIO_PDR_MD7_CFG_UIO__B                                            8
+#define   SIO_PDR_MD7_CFG_UIO__W                                            1
+#define   SIO_PDR_MD7_CFG_UIO__M                                            0x100
+#define   SIO_PDR_MD7_CFG_UIO__PRE                                          0x0
+
+#define SIO_PDR_I2C_SCL1_CFG__A                                             0x7F0033
+#define SIO_PDR_I2C_SCL1_CFG__W                                             9
+#define SIO_PDR_I2C_SCL1_CFG__M                                             0x1FF
+#define SIO_PDR_I2C_SCL1_CFG__PRE                                           0x11
+#define   SIO_PDR_I2C_SCL1_CFG_MODE__B                                      0
+#define   SIO_PDR_I2C_SCL1_CFG_MODE__W                                      3
+#define   SIO_PDR_I2C_SCL1_CFG_MODE__M                                      0x7
+#define   SIO_PDR_I2C_SCL1_CFG_MODE__PRE                                    0x1
+#define   SIO_PDR_I2C_SCL1_CFG_DRIVE__B                                     3
+#define   SIO_PDR_I2C_SCL1_CFG_DRIVE__W                                     3
+#define   SIO_PDR_I2C_SCL1_CFG_DRIVE__M                                     0x38
+#define   SIO_PDR_I2C_SCL1_CFG_DRIVE__PRE                                   0x10
+#define   SIO_PDR_I2C_SCL1_CFG_KEEP__B                                      6
+#define   SIO_PDR_I2C_SCL1_CFG_KEEP__W                                      2
+#define   SIO_PDR_I2C_SCL1_CFG_KEEP__M                                      0xC0
+#define   SIO_PDR_I2C_SCL1_CFG_KEEP__PRE                                    0x0
+#define   SIO_PDR_I2C_SCL1_CFG_UIO__B                                       8
+#define   SIO_PDR_I2C_SCL1_CFG_UIO__W                                       1
+#define   SIO_PDR_I2C_SCL1_CFG_UIO__M                                       0x100
+#define   SIO_PDR_I2C_SCL1_CFG_UIO__PRE                                     0x0
+
+#define SIO_PDR_I2C_SDA1_CFG__A                                             0x7F0034
+#define SIO_PDR_I2C_SDA1_CFG__W                                             9
+#define SIO_PDR_I2C_SDA1_CFG__M                                             0x1FF
+#define SIO_PDR_I2C_SDA1_CFG__PRE                                           0x11
+#define   SIO_PDR_I2C_SDA1_CFG_MODE__B                                      0
+#define   SIO_PDR_I2C_SDA1_CFG_MODE__W                                      3
+#define   SIO_PDR_I2C_SDA1_CFG_MODE__M                                      0x7
+#define   SIO_PDR_I2C_SDA1_CFG_MODE__PRE                                    0x1
+#define   SIO_PDR_I2C_SDA1_CFG_DRIVE__B                                     3
+#define   SIO_PDR_I2C_SDA1_CFG_DRIVE__W                                     3
+#define   SIO_PDR_I2C_SDA1_CFG_DRIVE__M                                     0x38
+#define   SIO_PDR_I2C_SDA1_CFG_DRIVE__PRE                                   0x10
+#define   SIO_PDR_I2C_SDA1_CFG_KEEP__B                                      6
+#define   SIO_PDR_I2C_SDA1_CFG_KEEP__W                                      2
+#define   SIO_PDR_I2C_SDA1_CFG_KEEP__M                                      0xC0
+#define   SIO_PDR_I2C_SDA1_CFG_KEEP__PRE                                    0x0
+#define   SIO_PDR_I2C_SDA1_CFG_UIO__B                                       8
+#define   SIO_PDR_I2C_SDA1_CFG_UIO__W                                       1
+#define   SIO_PDR_I2C_SDA1_CFG_UIO__M                                       0x100
+#define   SIO_PDR_I2C_SDA1_CFG_UIO__PRE                                     0x0
+
+#define SIO_PDR_VSYNC_CFG__A                                                0x7F0036
+#define SIO_PDR_VSYNC_CFG__W                                                9
+#define SIO_PDR_VSYNC_CFG__M                                                0x1FF
+#define SIO_PDR_VSYNC_CFG__PRE                                              0x10
+#define   SIO_PDR_VSYNC_CFG_MODE__B                                         0
+#define   SIO_PDR_VSYNC_CFG_MODE__W                                         3
+#define   SIO_PDR_VSYNC_CFG_MODE__M                                         0x7
+#define   SIO_PDR_VSYNC_CFG_MODE__PRE                                       0x0
+#define   SIO_PDR_VSYNC_CFG_DRIVE__B                                        3
+#define   SIO_PDR_VSYNC_CFG_DRIVE__W                                        3
+#define   SIO_PDR_VSYNC_CFG_DRIVE__M                                        0x38
+#define   SIO_PDR_VSYNC_CFG_DRIVE__PRE                                      0x10
+#define   SIO_PDR_VSYNC_CFG_KEEP__B                                         6
+#define   SIO_PDR_VSYNC_CFG_KEEP__W                                         2
+#define   SIO_PDR_VSYNC_CFG_KEEP__M                                         0xC0
+#define   SIO_PDR_VSYNC_CFG_KEEP__PRE                                       0x0
+#define   SIO_PDR_VSYNC_CFG_UIO__B                                          8
+#define   SIO_PDR_VSYNC_CFG_UIO__W                                          1
+#define   SIO_PDR_VSYNC_CFG_UIO__M                                          0x100
+#define   SIO_PDR_VSYNC_CFG_UIO__PRE                                        0x0
+
+#define SIO_PDR_SMA_RX_CFG__A                                               0x7F0037
+#define SIO_PDR_SMA_RX_CFG__W                                               9
+#define SIO_PDR_SMA_RX_CFG__M                                               0x1FF
+#define SIO_PDR_SMA_RX_CFG__PRE                                             0x10
+#define   SIO_PDR_SMA_RX_CFG_MODE__B                                        0
+#define   SIO_PDR_SMA_RX_CFG_MODE__W                                        3
+#define   SIO_PDR_SMA_RX_CFG_MODE__M                                        0x7
+#define   SIO_PDR_SMA_RX_CFG_MODE__PRE                                      0x0
+#define   SIO_PDR_SMA_RX_CFG_DRIVE__B                                       3
+#define   SIO_PDR_SMA_RX_CFG_DRIVE__W                                       3
+#define   SIO_PDR_SMA_RX_CFG_DRIVE__M                                       0x38
+#define   SIO_PDR_SMA_RX_CFG_DRIVE__PRE                                     0x10
+#define   SIO_PDR_SMA_RX_CFG_KEEP__B                                        6
+#define   SIO_PDR_SMA_RX_CFG_KEEP__W                                        2
+#define   SIO_PDR_SMA_RX_CFG_KEEP__M                                        0xC0
+#define   SIO_PDR_SMA_RX_CFG_KEEP__PRE                                      0x0
+#define   SIO_PDR_SMA_RX_CFG_UIO__B                                         8
+#define   SIO_PDR_SMA_RX_CFG_UIO__W                                         1
+#define   SIO_PDR_SMA_RX_CFG_UIO__M                                         0x100
+#define   SIO_PDR_SMA_RX_CFG_UIO__PRE                                       0x0
+
+#define SIO_PDR_SMA_TX_CFG__A                                               0x7F0038
+#define SIO_PDR_SMA_TX_CFG__W                                               9
+#define SIO_PDR_SMA_TX_CFG__M                                               0x1FF
+#define SIO_PDR_SMA_TX_CFG__PRE                                             0x90
+#define   SIO_PDR_SMA_TX_CFG_MODE__B                                        0
+#define   SIO_PDR_SMA_TX_CFG_MODE__W                                        3
+#define   SIO_PDR_SMA_TX_CFG_MODE__M                                        0x7
+#define   SIO_PDR_SMA_TX_CFG_MODE__PRE                                      0x0
+#define   SIO_PDR_SMA_TX_CFG_DRIVE__B                                       3
+#define   SIO_PDR_SMA_TX_CFG_DRIVE__W                                       3
+#define   SIO_PDR_SMA_TX_CFG_DRIVE__M                                       0x38
+#define   SIO_PDR_SMA_TX_CFG_DRIVE__PRE                                     0x10
+#define   SIO_PDR_SMA_TX_CFG_KEEP__B                                        6
+#define   SIO_PDR_SMA_TX_CFG_KEEP__W                                        2
+#define   SIO_PDR_SMA_TX_CFG_KEEP__M                                        0xC0
+#define   SIO_PDR_SMA_TX_CFG_KEEP__PRE                                      0x80
+#define   SIO_PDR_SMA_TX_CFG_UIO__B                                         8
+#define   SIO_PDR_SMA_TX_CFG_UIO__W                                         1
+#define   SIO_PDR_SMA_TX_CFG_UIO__M                                         0x100
+#define   SIO_PDR_SMA_TX_CFG_UIO__PRE                                       0x0
+
+#define SIO_PDR_I2C_SDA2_CFG__A                                             0x7F003F
+#define SIO_PDR_I2C_SDA2_CFG__W                                             9
+#define SIO_PDR_I2C_SDA2_CFG__M                                             0x1FF
+#define SIO_PDR_I2C_SDA2_CFG__PRE                                           0x11
+#define   SIO_PDR_I2C_SDA2_CFG_MODE__B                                      0
+#define   SIO_PDR_I2C_SDA2_CFG_MODE__W                                      3
+#define   SIO_PDR_I2C_SDA2_CFG_MODE__M                                      0x7
+#define   SIO_PDR_I2C_SDA2_CFG_MODE__PRE                                    0x1
+#define   SIO_PDR_I2C_SDA2_CFG_DRIVE__B                                     3
+#define   SIO_PDR_I2C_SDA2_CFG_DRIVE__W                                     3
+#define   SIO_PDR_I2C_SDA2_CFG_DRIVE__M                                     0x38
+#define   SIO_PDR_I2C_SDA2_CFG_DRIVE__PRE                                   0x10
+#define   SIO_PDR_I2C_SDA2_CFG_KEEP__B                                      6
+#define   SIO_PDR_I2C_SDA2_CFG_KEEP__W                                      2
+#define   SIO_PDR_I2C_SDA2_CFG_KEEP__M                                      0xC0
+#define   SIO_PDR_I2C_SDA2_CFG_KEEP__PRE                                    0x0
+#define   SIO_PDR_I2C_SDA2_CFG_UIO__B                                       8
+#define   SIO_PDR_I2C_SDA2_CFG_UIO__W                                       1
+#define   SIO_PDR_I2C_SDA2_CFG_UIO__M                                       0x100
+#define   SIO_PDR_I2C_SDA2_CFG_UIO__PRE                                     0x0
+
+#define SIO_PDR_I2C_SCL2_CFG__A                                             0x7F0040
+#define SIO_PDR_I2C_SCL2_CFG__W                                             9
+#define SIO_PDR_I2C_SCL2_CFG__M                                             0x1FF
+#define SIO_PDR_I2C_SCL2_CFG__PRE                                           0x11
+#define   SIO_PDR_I2C_SCL2_CFG_MODE__B                                      0
+#define   SIO_PDR_I2C_SCL2_CFG_MODE__W                                      3
+#define   SIO_PDR_I2C_SCL2_CFG_MODE__M                                      0x7
+#define   SIO_PDR_I2C_SCL2_CFG_MODE__PRE                                    0x1
+#define   SIO_PDR_I2C_SCL2_CFG_DRIVE__B                                     3
+#define   SIO_PDR_I2C_SCL2_CFG_DRIVE__W                                     3
+#define   SIO_PDR_I2C_SCL2_CFG_DRIVE__M                                     0x38
+#define   SIO_PDR_I2C_SCL2_CFG_DRIVE__PRE                                   0x10
+#define   SIO_PDR_I2C_SCL2_CFG_KEEP__B                                      6
+#define   SIO_PDR_I2C_SCL2_CFG_KEEP__W                                      2
+#define   SIO_PDR_I2C_SCL2_CFG_KEEP__M                                      0xC0
+#define   SIO_PDR_I2C_SCL2_CFG_KEEP__PRE                                    0x0
+#define   SIO_PDR_I2C_SCL2_CFG_UIO__B                                       8
+#define   SIO_PDR_I2C_SCL2_CFG_UIO__W                                       1
+#define   SIO_PDR_I2C_SCL2_CFG_UIO__M                                       0x100
+#define   SIO_PDR_I2C_SCL2_CFG_UIO__PRE                                     0x0
+
+#define SIO_PDR_I2S_CL_CFG__A                                               0x7F0041
+#define SIO_PDR_I2S_CL_CFG__W                                               9
+#define SIO_PDR_I2S_CL_CFG__M                                               0x1FF
+#define SIO_PDR_I2S_CL_CFG__PRE                                             0x10
+#define   SIO_PDR_I2S_CL_CFG_MODE__B                                        0
+#define   SIO_PDR_I2S_CL_CFG_MODE__W                                        3
+#define   SIO_PDR_I2S_CL_CFG_MODE__M                                        0x7
+#define   SIO_PDR_I2S_CL_CFG_MODE__PRE                                      0x0
+#define   SIO_PDR_I2S_CL_CFG_DRIVE__B                                       3
+#define   SIO_PDR_I2S_CL_CFG_DRIVE__W                                       3
+#define   SIO_PDR_I2S_CL_CFG_DRIVE__M                                       0x38
+#define   SIO_PDR_I2S_CL_CFG_DRIVE__PRE                                     0x10
+#define   SIO_PDR_I2S_CL_CFG_KEEP__B                                        6
+#define   SIO_PDR_I2S_CL_CFG_KEEP__W                                        2
+#define   SIO_PDR_I2S_CL_CFG_KEEP__M                                        0xC0
+#define   SIO_PDR_I2S_CL_CFG_KEEP__PRE                                      0x0
+#define   SIO_PDR_I2S_CL_CFG_UIO__B                                         8
+#define   SIO_PDR_I2S_CL_CFG_UIO__W                                         1
+#define   SIO_PDR_I2S_CL_CFG_UIO__M                                         0x100
+#define   SIO_PDR_I2S_CL_CFG_UIO__PRE                                       0x0
+
+#define SIO_PDR_I2S_DA_CFG__A                                               0x7F0042
+#define SIO_PDR_I2S_DA_CFG__W                                               9
+#define SIO_PDR_I2S_DA_CFG__M                                               0x1FF
+#define SIO_PDR_I2S_DA_CFG__PRE                                             0x10
+#define   SIO_PDR_I2S_DA_CFG_MODE__B                                        0
+#define   SIO_PDR_I2S_DA_CFG_MODE__W                                        3
+#define   SIO_PDR_I2S_DA_CFG_MODE__M                                        0x7
+#define   SIO_PDR_I2S_DA_CFG_MODE__PRE                                      0x0
+#define   SIO_PDR_I2S_DA_CFG_DRIVE__B                                       3
+#define   SIO_PDR_I2S_DA_CFG_DRIVE__W                                       3
+#define   SIO_PDR_I2S_DA_CFG_DRIVE__M                                       0x38
+#define   SIO_PDR_I2S_DA_CFG_DRIVE__PRE                                     0x10
+#define   SIO_PDR_I2S_DA_CFG_KEEP__B                                        6
+#define   SIO_PDR_I2S_DA_CFG_KEEP__W                                        2
+#define   SIO_PDR_I2S_DA_CFG_KEEP__M                                        0xC0
+#define   SIO_PDR_I2S_DA_CFG_KEEP__PRE                                      0x0
+#define   SIO_PDR_I2S_DA_CFG_UIO__B                                         8
+#define   SIO_PDR_I2S_DA_CFG_UIO__W                                         1
+#define   SIO_PDR_I2S_DA_CFG_UIO__M                                         0x100
+#define   SIO_PDR_I2S_DA_CFG_UIO__PRE                                       0x0
+
+#define SIO_PDR_GPIO_GPIO_FNC__A                                            0x7F0050
+#define SIO_PDR_GPIO_GPIO_FNC__W                                            2
+#define SIO_PDR_GPIO_GPIO_FNC__M                                            0x3
+#define SIO_PDR_GPIO_GPIO_FNC__PRE                                          0x0
+#define   SIO_PDR_GPIO_GPIO_FNC_SEL__B                                      0
+#define   SIO_PDR_GPIO_GPIO_FNC_SEL__W                                      2
+#define   SIO_PDR_GPIO_GPIO_FNC_SEL__M                                      0x3
+#define   SIO_PDR_GPIO_GPIO_FNC_SEL__PRE                                    0x0
+
+#define SIO_PDR_IRQN_GPIO_FNC__A                                            0x7F0051
+#define SIO_PDR_IRQN_GPIO_FNC__W                                            2
+#define SIO_PDR_IRQN_GPIO_FNC__M                                            0x3
+#define SIO_PDR_IRQN_GPIO_FNC__PRE                                          0x0
+#define   SIO_PDR_IRQN_GPIO_FNC_SEL__B                                      0
+#define   SIO_PDR_IRQN_GPIO_FNC_SEL__W                                      2
+#define   SIO_PDR_IRQN_GPIO_FNC_SEL__M                                      0x3
+#define   SIO_PDR_IRQN_GPIO_FNC_SEL__PRE                                    0x0
+
+#define SIO_PDR_MSTRT_GPIO_FNC__A                                           0x7F0052
+#define SIO_PDR_MSTRT_GPIO_FNC__W                                           2
+#define SIO_PDR_MSTRT_GPIO_FNC__M                                           0x3
+#define SIO_PDR_MSTRT_GPIO_FNC__PRE                                         0x0
+#define   SIO_PDR_MSTRT_GPIO_FNC_SEL__B                                     0
+#define   SIO_PDR_MSTRT_GPIO_FNC_SEL__W                                     2
+#define   SIO_PDR_MSTRT_GPIO_FNC_SEL__M                                     0x3
+#define   SIO_PDR_MSTRT_GPIO_FNC_SEL__PRE                                   0x0
+
+#define SIO_PDR_MERR_GPIO_FNC__A                                            0x7F0053
+#define SIO_PDR_MERR_GPIO_FNC__W                                            2
+#define SIO_PDR_MERR_GPIO_FNC__M                                            0x3
+#define SIO_PDR_MERR_GPIO_FNC__PRE                                          0x0
+#define   SIO_PDR_MERR_GPIO_FNC_SEL__B                                      0
+#define   SIO_PDR_MERR_GPIO_FNC_SEL__W                                      2
+#define   SIO_PDR_MERR_GPIO_FNC_SEL__M                                      0x3
+#define   SIO_PDR_MERR_GPIO_FNC_SEL__PRE                                    0x0
+
+#define SIO_PDR_MCLK_GPIO_FNC__A                                            0x7F0054
+#define SIO_PDR_MCLK_GPIO_FNC__W                                            2
+#define SIO_PDR_MCLK_GPIO_FNC__M                                            0x3
+#define SIO_PDR_MCLK_GPIO_FNC__PRE                                          0x0
+#define   SIO_PDR_MCLK_GPIO_FNC_SEL__B                                      0
+#define   SIO_PDR_MCLK_GPIO_FNC_SEL__W                                      2
+#define   SIO_PDR_MCLK_GPIO_FNC_SEL__M                                      0x3
+#define   SIO_PDR_MCLK_GPIO_FNC_SEL__PRE                                    0x0
+
+#define SIO_PDR_MVAL_GPIO_FNC__A                                            0x7F0055
+#define SIO_PDR_MVAL_GPIO_FNC__W                                            2
+#define SIO_PDR_MVAL_GPIO_FNC__M                                            0x3
+#define SIO_PDR_MVAL_GPIO_FNC__PRE                                          0x0
+#define   SIO_PDR_MVAL_GPIO_FNC_SEL__B                                      0
+#define   SIO_PDR_MVAL_GPIO_FNC_SEL__W                                      2
+#define   SIO_PDR_MVAL_GPIO_FNC_SEL__M                                      0x3
+#define   SIO_PDR_MVAL_GPIO_FNC_SEL__PRE                                    0x0
+
+#define SIO_PDR_MD0_GPIO_FNC__A                                             0x7F0056
+#define SIO_PDR_MD0_GPIO_FNC__W                                             2
+#define SIO_PDR_MD0_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD0_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD0_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD0_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD0_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD0_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD1_GPIO_FNC__A                                             0x7F0057
+#define SIO_PDR_MD1_GPIO_FNC__W                                             2
+#define SIO_PDR_MD1_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD1_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD1_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD1_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD1_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD1_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD2_GPIO_FNC__A                                             0x7F0058
+#define SIO_PDR_MD2_GPIO_FNC__W                                             2
+#define SIO_PDR_MD2_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD2_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD2_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD2_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD2_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD2_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD3_GPIO_FNC__A                                             0x7F0059
+#define SIO_PDR_MD3_GPIO_FNC__W                                             2
+#define SIO_PDR_MD3_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD3_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD3_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD3_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD3_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD3_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD4_GPIO_FNC__A                                             0x7F005A
+#define SIO_PDR_MD4_GPIO_FNC__W                                             2
+#define SIO_PDR_MD4_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD4_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD4_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD4_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD4_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD4_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD5_GPIO_FNC__A                                             0x7F005B
+#define SIO_PDR_MD5_GPIO_FNC__W                                             2
+#define SIO_PDR_MD5_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD5_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD5_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD5_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD5_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD5_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD6_GPIO_FNC__A                                             0x7F005C
+#define SIO_PDR_MD6_GPIO_FNC__W                                             2
+#define SIO_PDR_MD6_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD6_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD6_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD6_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD6_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD6_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_MD7_GPIO_FNC__A                                             0x7F005D
+#define SIO_PDR_MD7_GPIO_FNC__W                                             2
+#define SIO_PDR_MD7_GPIO_FNC__M                                             0x3
+#define SIO_PDR_MD7_GPIO_FNC__PRE                                           0x0
+#define   SIO_PDR_MD7_GPIO_FNC_SEL__B                                       0
+#define   SIO_PDR_MD7_GPIO_FNC_SEL__W                                       2
+#define   SIO_PDR_MD7_GPIO_FNC_SEL__M                                       0x3
+#define   SIO_PDR_MD7_GPIO_FNC_SEL__PRE                                     0x0
+
+#define SIO_PDR_SMA_RX_GPIO_FNC__A                                          0x7F005E
+#define SIO_PDR_SMA_RX_GPIO_FNC__W                                          2
+#define SIO_PDR_SMA_RX_GPIO_FNC__M                                          0x3
+#define SIO_PDR_SMA_RX_GPIO_FNC__PRE                                        0x0
+#define   SIO_PDR_SMA_RX_GPIO_FNC_SEL__B                                    0
+#define   SIO_PDR_SMA_RX_GPIO_FNC_SEL__W                                    2
+#define   SIO_PDR_SMA_RX_GPIO_FNC_SEL__M                                    0x3
+#define   SIO_PDR_SMA_RX_GPIO_FNC_SEL__PRE                                  0x0
+
+#define SIO_PDR_SMA_TX_GPIO_FNC__A                                          0x7F005F
+#define SIO_PDR_SMA_TX_GPIO_FNC__W                                          2
+#define SIO_PDR_SMA_TX_GPIO_FNC__M                                          0x3
+#define SIO_PDR_SMA_TX_GPIO_FNC__PRE                                        0x0
+#define   SIO_PDR_SMA_TX_GPIO_FNC_SEL__B                                    0
+#define   SIO_PDR_SMA_TX_GPIO_FNC_SEL__W                                    2
+#define   SIO_PDR_SMA_TX_GPIO_FNC_SEL__M                                    0x3
+#define   SIO_PDR_SMA_TX_GPIO_FNC_SEL__PRE                                  0x0
+
+#define VSB_COMM_EXEC__A                                                    0x1C00000
+#define VSB_COMM_EXEC__W                                                    2
+#define VSB_COMM_EXEC__M                                                    0x3
+#define VSB_COMM_EXEC__PRE                                                  0x0
+#define   VSB_COMM_EXEC_STOP                                                0x0
+#define   VSB_COMM_EXEC_ACTIVE                                              0x1
+#define   VSB_COMM_EXEC_HOLD                                                0x2
+
+#define VSB_COMM_MB__A                                                      0x1C00002
+#define VSB_COMM_MB__W                                                      16
+#define VSB_COMM_MB__M                                                      0xFFFF
+#define VSB_COMM_MB__PRE                                                    0x0
+#define VSB_COMM_INT_REQ__A                                                 0x1C00003
+#define VSB_COMM_INT_REQ__W                                                 1
+#define VSB_COMM_INT_REQ__M                                                 0x1
+#define VSB_COMM_INT_REQ__PRE                                               0x0
+
+#define   VSB_COMM_INT_REQ_TOP_INT_REQ__B                                   0
+#define   VSB_COMM_INT_REQ_TOP_INT_REQ__W                                   1
+#define   VSB_COMM_INT_REQ_TOP_INT_REQ__M                                   0x1
+#define   VSB_COMM_INT_REQ_TOP_INT_REQ__PRE                                 0x0
+
+#define VSB_COMM_INT_STA__A                                                 0x1C00005
+#define VSB_COMM_INT_STA__W                                                 16
+#define VSB_COMM_INT_STA__M                                                 0xFFFF
+#define VSB_COMM_INT_STA__PRE                                               0x0
+
+#define VSB_COMM_INT_MSK__A                                                 0x1C00006
+#define VSB_COMM_INT_MSK__W                                                 16
+#define VSB_COMM_INT_MSK__M                                                 0xFFFF
+#define VSB_COMM_INT_MSK__PRE                                               0x0
+
+#define VSB_COMM_INT_STM__A                                                 0x1C00007
+#define VSB_COMM_INT_STM__W                                                 16
+#define VSB_COMM_INT_STM__M                                                 0xFFFF
+#define VSB_COMM_INT_STM__PRE                                               0x0
+
+#define VSB_TOP_COMM_EXEC__A                                                0x1C10000
+#define VSB_TOP_COMM_EXEC__W                                                2
+#define VSB_TOP_COMM_EXEC__M                                                0x3
+#define VSB_TOP_COMM_EXEC__PRE                                              0x0
+#define   VSB_TOP_COMM_EXEC_STOP                                            0x0
+#define   VSB_TOP_COMM_EXEC_ACTIVE                                          0x1
+#define   VSB_TOP_COMM_EXEC_HOLD                                            0x2
+
+#define VSB_TOP_COMM_MB__A                                                  0x1C10002
+#define VSB_TOP_COMM_MB__W                                                  10
+#define VSB_TOP_COMM_MB__M                                                  0x3FF
+#define VSB_TOP_COMM_MB__PRE                                                0x0
+
+#define   VSB_TOP_COMM_MB_CTL__B                                            0
+#define   VSB_TOP_COMM_MB_CTL__W                                            1
+#define   VSB_TOP_COMM_MB_CTL__M                                            0x1
+#define   VSB_TOP_COMM_MB_CTL__PRE                                          0x0
+#define     VSB_TOP_COMM_MB_CTL_CTL_OFF                                     0x0
+#define     VSB_TOP_COMM_MB_CTL_CTL_ON                                      0x1
+
+#define   VSB_TOP_COMM_MB_OBS__B                                            1
+#define   VSB_TOP_COMM_MB_OBS__W                                            1
+#define   VSB_TOP_COMM_MB_OBS__M                                            0x2
+#define   VSB_TOP_COMM_MB_OBS__PRE                                          0x0
+#define     VSB_TOP_COMM_MB_OBS_OBS_OFF                                     0x0
+#define     VSB_TOP_COMM_MB_OBS_OBS_ON                                      0x2
+
+#define   VSB_TOP_COMM_MB_MUX_CTL__B                                        2
+#define   VSB_TOP_COMM_MB_MUX_CTL__W                                        4
+#define   VSB_TOP_COMM_MB_MUX_CTL__M                                        0x3C
+#define   VSB_TOP_COMM_MB_MUX_CTL__PRE                                      0x0
+
+#define   VSB_TOP_COMM_MB_MUX_OBS__B                                        6
+#define   VSB_TOP_COMM_MB_MUX_OBS__W                                        4
+#define   VSB_TOP_COMM_MB_MUX_OBS__M                                        0x3C0
+#define   VSB_TOP_COMM_MB_MUX_OBS__PRE                                      0x0
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_FEC                                 0x0
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_IQM                                 0x40
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_IQM_AMPLITUDE                       0x80
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_1                             0xC0
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2                             0x100
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_FFE_1                               0x140
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_FFE_2                               0x180
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_DFE_1                               0x1C0
+#define     VSB_TOP_COMM_MB_MUX_OBS_VSB_DFE_2                               0x200
+
+#define VSB_TOP_COMM_INT_REQ__A                                             0x1C10003
+#define VSB_TOP_COMM_INT_REQ__W                                             1
+#define VSB_TOP_COMM_INT_REQ__M                                             0x1
+#define VSB_TOP_COMM_INT_REQ__PRE                                           0x0
+#define VSB_TOP_COMM_INT_STA__A                                             0x1C10005
+#define VSB_TOP_COMM_INT_STA__W                                             6
+#define VSB_TOP_COMM_INT_STA__M                                             0x3F
+#define VSB_TOP_COMM_INT_STA__PRE                                           0x0
+
+#define   VSB_TOP_COMM_INT_STA_FIELD_INT_STA__B                             0
+#define   VSB_TOP_COMM_INT_STA_FIELD_INT_STA__W                             1
+#define   VSB_TOP_COMM_INT_STA_FIELD_INT_STA__M                             0x1
+#define   VSB_TOP_COMM_INT_STA_FIELD_INT_STA__PRE                           0x0
+
+#define   VSB_TOP_COMM_INT_STA_LOCK_STA__B                                  1
+#define   VSB_TOP_COMM_INT_STA_LOCK_STA__W                                  1
+#define   VSB_TOP_COMM_INT_STA_LOCK_STA__M                                  0x2
+#define   VSB_TOP_COMM_INT_STA_LOCK_STA__PRE                                0x0
+
+#define   VSB_TOP_COMM_INT_STA_UNLOCK_STA__B                                2
+#define   VSB_TOP_COMM_INT_STA_UNLOCK_STA__W                                1
+#define   VSB_TOP_COMM_INT_STA_UNLOCK_STA__M                                0x4
+#define   VSB_TOP_COMM_INT_STA_UNLOCK_STA__PRE                              0x0
+
+#define   VSB_TOP_COMM_INT_STA_TAPREADER_STA__B                             3
+#define   VSB_TOP_COMM_INT_STA_TAPREADER_STA__W                             1
+#define   VSB_TOP_COMM_INT_STA_TAPREADER_STA__M                             0x8
+#define   VSB_TOP_COMM_INT_STA_TAPREADER_STA__PRE                           0x0
+
+#define   VSB_TOP_COMM_INT_STA_SEGSYNCINTR_STA__B                           4
+#define   VSB_TOP_COMM_INT_STA_SEGSYNCINTR_STA__W                           1
+#define   VSB_TOP_COMM_INT_STA_SEGSYNCINTR_STA__M                           0x10
+#define   VSB_TOP_COMM_INT_STA_SEGSYNCINTR_STA__PRE                         0x0
+
+#define   VSB_TOP_COMM_INT_STA_MERSER_STA__B                                5
+#define   VSB_TOP_COMM_INT_STA_MERSER_STA__W                                1
+#define   VSB_TOP_COMM_INT_STA_MERSER_STA__M                                0x20
+#define   VSB_TOP_COMM_INT_STA_MERSER_STA__PRE                              0x0
+
+#define VSB_TOP_COMM_INT_MSK__A                                             0x1C10006
+#define VSB_TOP_COMM_INT_MSK__W                                             6
+#define VSB_TOP_COMM_INT_MSK__M                                             0x3F
+#define VSB_TOP_COMM_INT_MSK__PRE                                           0x0
+
+#define   VSB_TOP_COMM_INT_MSK_FIELD_INT_MSK__B                             0
+#define   VSB_TOP_COMM_INT_MSK_FIELD_INT_MSK__W                             1
+#define   VSB_TOP_COMM_INT_MSK_FIELD_INT_MSK__M                             0x1
+#define   VSB_TOP_COMM_INT_MSK_FIELD_INT_MSK__PRE                           0x0
+
+#define   VSB_TOP_COMM_INT_MSK_LOCK_MSK__B                                  1
+#define   VSB_TOP_COMM_INT_MSK_LOCK_MSK__W                                  1
+#define   VSB_TOP_COMM_INT_MSK_LOCK_MSK__M                                  0x2
+#define   VSB_TOP_COMM_INT_MSK_LOCK_MSK__PRE                                0x0
+
+#define   VSB_TOP_COMM_INT_MSK_UNLOCK_MSK__B                                2
+#define   VSB_TOP_COMM_INT_MSK_UNLOCK_MSK__W                                1
+#define   VSB_TOP_COMM_INT_MSK_UNLOCK_MSK__M                                0x4
+#define   VSB_TOP_COMM_INT_MSK_UNLOCK_MSK__PRE                              0x0
+
+#define   VSB_TOP_COMM_INT_MSK_TAPREADER_MSK__B                             3
+#define   VSB_TOP_COMM_INT_MSK_TAPREADER_MSK__W                             1
+#define   VSB_TOP_COMM_INT_MSK_TAPREADER_MSK__M                             0x8
+#define   VSB_TOP_COMM_INT_MSK_TAPREADER_MSK__PRE                           0x0
+
+#define   VSB_TOP_COMM_INT_MSK_SEGSYNCINTR_MSK__B                           4
+#define   VSB_TOP_COMM_INT_MSK_SEGSYNCINTR_MSK__W                           1
+#define   VSB_TOP_COMM_INT_MSK_SEGSYNCINTR_MSK__M                           0x10
+#define   VSB_TOP_COMM_INT_MSK_SEGSYNCINTR_MSK__PRE                         0x0
+
+#define   VSB_TOP_COMM_INT_MSK_MERSER_MSK__B                                5
+#define   VSB_TOP_COMM_INT_MSK_MERSER_MSK__W                                1
+#define   VSB_TOP_COMM_INT_MSK_MERSER_MSK__M                                0x20
+#define   VSB_TOP_COMM_INT_MSK_MERSER_MSK__PRE                              0x0
+
+#define VSB_TOP_COMM_INT_STM__A                                             0x1C10007
+#define VSB_TOP_COMM_INT_STM__W                                             6
+#define VSB_TOP_COMM_INT_STM__M                                             0x3F
+#define VSB_TOP_COMM_INT_STM__PRE                                           0x0
+
+#define   VSB_TOP_COMM_INT_STM_FIELD_INT_STM__B                             0
+#define   VSB_TOP_COMM_INT_STM_FIELD_INT_STM__W                             1
+#define   VSB_TOP_COMM_INT_STM_FIELD_INT_STM__M                             0x1
+#define   VSB_TOP_COMM_INT_STM_FIELD_INT_STM__PRE                           0x0
+
+#define   VSB_TOP_COMM_INT_STM_LOCK_STM__B                                  1
+#define   VSB_TOP_COMM_INT_STM_LOCK_STM__W                                  1
+#define   VSB_TOP_COMM_INT_STM_LOCK_STM__M                                  0x2
+#define   VSB_TOP_COMM_INT_STM_LOCK_STM__PRE                                0x0
+
+#define   VSB_TOP_COMM_INT_STM_UNLOCK_STM__B                                2
+#define   VSB_TOP_COMM_INT_STM_UNLOCK_STM__W                                1
+#define   VSB_TOP_COMM_INT_STM_UNLOCK_STM__M                                0x4
+#define   VSB_TOP_COMM_INT_STM_UNLOCK_STM__PRE                              0x0
+
+#define   VSB_TOP_COMM_INT_STM_TAPREADER_STM__B                             3
+#define   VSB_TOP_COMM_INT_STM_TAPREADER_STM__W                             1
+#define   VSB_TOP_COMM_INT_STM_TAPREADER_STM__M                             0x8
+#define   VSB_TOP_COMM_INT_STM_TAPREADER_STM__PRE                           0x0
+
+#define   VSB_TOP_COMM_INT_STM_SEGSYNCINTR_STM__B                           4
+#define   VSB_TOP_COMM_INT_STM_SEGSYNCINTR_STM__W                           1
+#define   VSB_TOP_COMM_INT_STM_SEGSYNCINTR_STM__M                           0x10
+#define   VSB_TOP_COMM_INT_STM_SEGSYNCINTR_STM__PRE                         0x0
+
+#define   VSB_TOP_COMM_INT_STM_MERSER_STM__B                                5
+#define   VSB_TOP_COMM_INT_STM_MERSER_STM__W                                1
+#define   VSB_TOP_COMM_INT_STM_MERSER_STM__M                                0x20
+#define   VSB_TOP_COMM_INT_STM_MERSER_STM__PRE                              0x0
+
+#define VSB_TOP_CKGN1ACQ__A                                                 0x1C10010
+#define VSB_TOP_CKGN1ACQ__W                                                 8
+#define VSB_TOP_CKGN1ACQ__M                                                 0xFF
+#define VSB_TOP_CKGN1ACQ__PRE                                               0x4
+
+#define VSB_TOP_CKGN1TRK__A                                                 0x1C10011
+#define VSB_TOP_CKGN1TRK__W                                                 8
+#define VSB_TOP_CKGN1TRK__M                                                 0xFF
+#define VSB_TOP_CKGN1TRK__PRE                                               0x0
+
+#define VSB_TOP_CKGN2ACQ__A                                                 0x1C10012
+#define VSB_TOP_CKGN2ACQ__W                                                 8
+#define VSB_TOP_CKGN2ACQ__M                                                 0xFF
+#define VSB_TOP_CKGN2ACQ__PRE                                               0x2
+
+#define VSB_TOP_CKGN2TRK__A                                                 0x1C10013
+#define VSB_TOP_CKGN2TRK__W                                                 8
+#define VSB_TOP_CKGN2TRK__M                                                 0xFF
+#define VSB_TOP_CKGN2TRK__PRE                                               0x1
+
+#define VSB_TOP_CKGN3__A                                                    0x1C10014
+#define VSB_TOP_CKGN3__W                                                    8
+#define VSB_TOP_CKGN3__M                                                    0xFF
+#define VSB_TOP_CKGN3__PRE                                                  0x5
+
+#define VSB_TOP_CYGN1ACQ__A                                                 0x1C10015
+#define VSB_TOP_CYGN1ACQ__W                                                 8
+#define VSB_TOP_CYGN1ACQ__M                                                 0xFF
+#define VSB_TOP_CYGN1ACQ__PRE                                               0x3
+
+#define VSB_TOP_CYGN1TRK__A                                                 0x1C10016
+#define VSB_TOP_CYGN1TRK__W                                                 8
+#define VSB_TOP_CYGN1TRK__M                                                 0xFF
+#define VSB_TOP_CYGN1TRK__PRE                                               0x0
+
+#define VSB_TOP_CYGN2ACQ__A                                                 0x1C10017
+#define VSB_TOP_CYGN2ACQ__W                                                 8
+#define VSB_TOP_CYGN2ACQ__M                                                 0xFF
+#define VSB_TOP_CYGN2ACQ__PRE                                               0x3
+
+#define VSB_TOP_CYGN2TRK__A                                                 0x1C10018
+#define VSB_TOP_CYGN2TRK__W                                                 8
+#define VSB_TOP_CYGN2TRK__M                                                 0xFF
+#define VSB_TOP_CYGN2TRK__PRE                                               0x2
+
+#define VSB_TOP_CYGN3__A                                                    0x1C10019
+#define VSB_TOP_CYGN3__W                                                    8
+#define VSB_TOP_CYGN3__M                                                    0xFF
+#define VSB_TOP_CYGN3__PRE                                                  0x6
+#define VSB_TOP_SYNCCTRLWORD__A                                             0x1C1001A
+#define VSB_TOP_SYNCCTRLWORD__W                                             5
+#define VSB_TOP_SYNCCTRLWORD__M                                             0x1F
+#define VSB_TOP_SYNCCTRLWORD__PRE                                           0x0
+
+#define   VSB_TOP_SYNCCTRLWORD_PRST__B                                      0
+#define   VSB_TOP_SYNCCTRLWORD_PRST__W                                      1
+#define   VSB_TOP_SYNCCTRLWORD_PRST__M                                      0x1
+#define   VSB_TOP_SYNCCTRLWORD_PRST__PRE                                    0x0
+
+#define   VSB_TOP_SYNCCTRLWORD_DCFREEZ__B                                   1
+#define   VSB_TOP_SYNCCTRLWORD_DCFREEZ__W                                   1
+#define   VSB_TOP_SYNCCTRLWORD_DCFREEZ__M                                   0x2
+#define   VSB_TOP_SYNCCTRLWORD_DCFREEZ__PRE                                 0x0
+
+#define   VSB_TOP_SYNCCTRLWORD_INVCNST__B                                   2
+#define   VSB_TOP_SYNCCTRLWORD_INVCNST__W                                   1
+#define   VSB_TOP_SYNCCTRLWORD_INVCNST__M                                   0x4
+#define   VSB_TOP_SYNCCTRLWORD_INVCNST__PRE                                 0x0
+
+#define   VSB_TOP_SYNCCTRLWORD_CPUAGCRST__B                                 3
+#define   VSB_TOP_SYNCCTRLWORD_CPUAGCRST__W                                 1
+#define   VSB_TOP_SYNCCTRLWORD_CPUAGCRST__M                                 0x8
+#define   VSB_TOP_SYNCCTRLWORD_CPUAGCRST__PRE                               0x0
+
+#define   VSB_TOP_SYNCCTRLWORD_AGCIGNOREFS__B                               4
+#define   VSB_TOP_SYNCCTRLWORD_AGCIGNOREFS__W                               1
+#define   VSB_TOP_SYNCCTRLWORD_AGCIGNOREFS__M                               0x10
+#define   VSB_TOP_SYNCCTRLWORD_AGCIGNOREFS__PRE                             0x0
+
+#define VSB_TOP_MAINSMUP__A                                                 0x1C1001B
+#define VSB_TOP_MAINSMUP__W                                                 8
+#define VSB_TOP_MAINSMUP__M                                                 0xFF
+#define VSB_TOP_MAINSMUP__PRE                                               0xFF
+
+#define VSB_TOP_EQSMUP__A                                                   0x1C1001C
+#define VSB_TOP_EQSMUP__W                                                   8
+#define VSB_TOP_EQSMUP__M                                                   0xFF
+#define VSB_TOP_EQSMUP__PRE                                                 0xFF
+#define VSB_TOP_SYSMUXCTRL__A                                               0x1C1001D
+#define VSB_TOP_SYSMUXCTRL__W                                               13
+#define VSB_TOP_SYSMUXCTRL__M                                               0x1FFF
+#define VSB_TOP_SYSMUXCTRL__PRE                                             0x0
+
+#define   VSB_TOP_SYSMUXCTRL_CYLK_STATIC__B                                 0
+#define   VSB_TOP_SYSMUXCTRL_CYLK_STATIC__W                                 1
+#define   VSB_TOP_SYSMUXCTRL_CYLK_STATIC__M                                 0x1
+#define   VSB_TOP_SYSMUXCTRL_CYLK_STATIC__PRE                               0x0
+
+#define   VSB_TOP_SYSMUXCTRL_CYLK_SEL_STATIC__B                             1
+#define   VSB_TOP_SYSMUXCTRL_CYLK_SEL_STATIC__W                             1
+#define   VSB_TOP_SYSMUXCTRL_CYLK_SEL_STATIC__M                             0x2
+#define   VSB_TOP_SYSMUXCTRL_CYLK_SEL_STATIC__PRE                           0x0
+
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_STATIC__B                            2
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_STATIC__W                            1
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_STATIC__M                            0x4
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_STATIC__PRE                          0x0
+
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_SEL_STATIC__B                        3
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_SEL_STATIC__W                        1
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_SEL_STATIC__M                        0x8
+#define   VSB_TOP_SYSMUXCTRL_CTCALDONE_SEL_STATIC__PRE                      0x0
+
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_STATIC__B                            4
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_STATIC__W                            1
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_STATIC__M                            0x10
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_STATIC__PRE                          0x0
+
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_SEL_STATIC__B                        5
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_SEL_STATIC__W                        1
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_SEL_STATIC__M                        0x20
+#define   VSB_TOP_SYSMUXCTRL_FRAMELOCK_SEL_STATIC__PRE                      0x0
+
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_STATIC__B                            6
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_STATIC__W                            1
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_STATIC__M                            0x40
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_STATIC__PRE                          0x0
+
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_SEL_STATIC__B                        7
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_SEL_STATIC__W                        1
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_SEL_STATIC__M                        0x80
+#define   VSB_TOP_SYSMUXCTRL_FRAMESYNC_SEL_STATIC__PRE                      0x0
+
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_STATIC__B                              8
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_STATIC__W                              4
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_STATIC__M                              0xF00
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_STATIC__PRE                            0x0
+
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_SEL_STATIC__B                          12
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_SEL_STATIC__W                          1
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_SEL_STATIC__M                          0x1000
+#define   VSB_TOP_SYSMUXCTRL_SNROVTH_SEL_STATIC__PRE                        0x0
+
+#define VSB_TOP_SNRTH_RCA1__A                                               0x1C1001E
+#define VSB_TOP_SNRTH_RCA1__W                                               8
+#define VSB_TOP_SNRTH_RCA1__M                                               0xFF
+#define VSB_TOP_SNRTH_RCA1__PRE                                             0x53
+
+#define   VSB_TOP_SNRTH_RCA1_DN__B                                          0
+#define   VSB_TOP_SNRTH_RCA1_DN__W                                          4
+#define   VSB_TOP_SNRTH_RCA1_DN__M                                          0xF
+#define   VSB_TOP_SNRTH_RCA1_DN__PRE                                        0x3
+
+#define   VSB_TOP_SNRTH_RCA1_UP__B                                          4
+#define   VSB_TOP_SNRTH_RCA1_UP__W                                          4
+#define   VSB_TOP_SNRTH_RCA1_UP__M                                          0xF0
+#define   VSB_TOP_SNRTH_RCA1_UP__PRE                                        0x50
+
+#define VSB_TOP_SNRTH_RCA2__A                                               0x1C1001F
+#define VSB_TOP_SNRTH_RCA2__W                                               8
+#define VSB_TOP_SNRTH_RCA2__M                                               0xFF
+#define VSB_TOP_SNRTH_RCA2__PRE                                             0x75
+
+#define   VSB_TOP_SNRTH_RCA2_DN__B                                          0
+#define   VSB_TOP_SNRTH_RCA2_DN__W                                          4
+#define   VSB_TOP_SNRTH_RCA2_DN__M                                          0xF
+#define   VSB_TOP_SNRTH_RCA2_DN__PRE                                        0x5
+
+#define   VSB_TOP_SNRTH_RCA2_UP__B                                          4
+#define   VSB_TOP_SNRTH_RCA2_UP__W                                          4
+#define   VSB_TOP_SNRTH_RCA2_UP__M                                          0xF0
+#define   VSB_TOP_SNRTH_RCA2_UP__PRE                                        0x70
+
+#define VSB_TOP_SNRTH_DDM1__A                                               0x1C10020
+#define VSB_TOP_SNRTH_DDM1__W                                               8
+#define VSB_TOP_SNRTH_DDM1__M                                               0xFF
+#define VSB_TOP_SNRTH_DDM1__PRE                                             0xCA
+
+#define   VSB_TOP_SNRTH_DDM1_DN__B                                          0
+#define   VSB_TOP_SNRTH_DDM1_DN__W                                          4
+#define   VSB_TOP_SNRTH_DDM1_DN__M                                          0xF
+#define   VSB_TOP_SNRTH_DDM1_DN__PRE                                        0xA
+
+#define   VSB_TOP_SNRTH_DDM1_UP__B                                          4
+#define   VSB_TOP_SNRTH_DDM1_UP__W                                          4
+#define   VSB_TOP_SNRTH_DDM1_UP__M                                          0xF0
+#define   VSB_TOP_SNRTH_DDM1_UP__PRE                                        0xC0
+
+#define VSB_TOP_SNRTH_DDM2__A                                               0x1C10021
+#define VSB_TOP_SNRTH_DDM2__W                                               8
+#define VSB_TOP_SNRTH_DDM2__M                                               0xFF
+#define VSB_TOP_SNRTH_DDM2__PRE                                             0xCA
+
+#define   VSB_TOP_SNRTH_DDM2_DN__B                                          0
+#define   VSB_TOP_SNRTH_DDM2_DN__W                                          4
+#define   VSB_TOP_SNRTH_DDM2_DN__M                                          0xF
+#define   VSB_TOP_SNRTH_DDM2_DN__PRE                                        0xA
+
+#define   VSB_TOP_SNRTH_DDM2_UP__B                                          4
+#define   VSB_TOP_SNRTH_DDM2_UP__W                                          4
+#define   VSB_TOP_SNRTH_DDM2_UP__M                                          0xF0
+#define   VSB_TOP_SNRTH_DDM2_UP__PRE                                        0xC0
+
+#define VSB_TOP_SNRTH_PT__A                                                 0x1C10022
+#define VSB_TOP_SNRTH_PT__W                                                 8
+#define VSB_TOP_SNRTH_PT__M                                                 0xFF
+#define VSB_TOP_SNRTH_PT__PRE                                               0xD8
+
+#define   VSB_TOP_SNRTH_PT_DN__B                                            0
+#define   VSB_TOP_SNRTH_PT_DN__W                                            4
+#define   VSB_TOP_SNRTH_PT_DN__M                                            0xF
+#define   VSB_TOP_SNRTH_PT_DN__PRE                                          0x8
+
+#define   VSB_TOP_SNRTH_PT_UP__B                                            4
+#define   VSB_TOP_SNRTH_PT_UP__W                                            4
+#define   VSB_TOP_SNRTH_PT_UP__M                                            0xF0
+#define   VSB_TOP_SNRTH_PT_UP__PRE                                          0xD0
+
+#define VSB_TOP_CYSMSTATES__A                                               0x1C10023
+#define VSB_TOP_CYSMSTATES__W                                               8
+#define VSB_TOP_CYSMSTATES__M                                               0xFF
+#define VSB_TOP_CYSMSTATES__PRE                                             0x0
+
+#define   VSB_TOP_CYSMSTATES_SYSST__B                                       0
+#define   VSB_TOP_CYSMSTATES_SYSST__W                                       4
+#define   VSB_TOP_CYSMSTATES_SYSST__M                                       0xF
+#define   VSB_TOP_CYSMSTATES_SYSST__PRE                                     0x0
+
+#define   VSB_TOP_CYSMSTATES_EQST__B                                        4
+#define   VSB_TOP_CYSMSTATES_EQST__W                                        4
+#define   VSB_TOP_CYSMSTATES_EQST__M                                        0xF0
+#define   VSB_TOP_CYSMSTATES_EQST__PRE                                      0x0
+
+#define VSB_TOP_SMALL_NOTCH_CONTROL__A                                      0x1C10024
+#define VSB_TOP_SMALL_NOTCH_CONTROL__W                                      8
+#define VSB_TOP_SMALL_NOTCH_CONTROL__M                                      0xFF
+#define VSB_TOP_SMALL_NOTCH_CONTROL__PRE                                    0x0
+
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_GO__B                                 0
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_GO__W                                 1
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_GO__M                                 0x1
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_GO__PRE                               0x0
+
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS1__B                            1
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS1__W                            1
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS1__M                            0x2
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS1__PRE                          0x0
+
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS2__B                            2
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS2__W                            1
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS2__M                            0x4
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_BYPASS2__PRE                          0x0
+
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SPARE__B                              3
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SPARE__W                              4
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SPARE__M                              0x78
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SPARE__PRE                            0x0
+
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SOFT_RESET__B                         7
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SOFT_RESET__W                         1
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SOFT_RESET__M                         0x80
+#define   VSB_TOP_SMALL_NOTCH_CONTROL_SOFT_RESET__PRE                       0x0
+
+#define VSB_TOP_TAPREADCYC__A                                               0x1C10025
+#define VSB_TOP_TAPREADCYC__W                                               9
+#define VSB_TOP_TAPREADCYC__M                                               0x1FF
+#define VSB_TOP_TAPREADCYC__PRE                                             0x1
+
+#define VSB_TOP_VALIDPKLVL__A                                               0x1C10026
+#define VSB_TOP_VALIDPKLVL__W                                               13
+#define VSB_TOP_VALIDPKLVL__M                                               0x1FFF
+#define VSB_TOP_VALIDPKLVL__PRE                                             0x100
+
+#define VSB_TOP_CENTROID_FINE_DELAY__A                                      0x1C10027
+#define VSB_TOP_CENTROID_FINE_DELAY__W                                      10
+#define VSB_TOP_CENTROID_FINE_DELAY__M                                      0x3FF
+#define VSB_TOP_CENTROID_FINE_DELAY__PRE                                    0xFF
+
+#define VSB_TOP_CENTROID_SMACH_DELAY__A                                     0x1C10028
+#define VSB_TOP_CENTROID_SMACH_DELAY__W                                     10
+#define VSB_TOP_CENTROID_SMACH_DELAY__M                                     0x3FF
+#define VSB_TOP_CENTROID_SMACH_DELAY__PRE                                   0x1FF
+
+#define VSB_TOP_SNR__A                                                      0x1C10029
+#define VSB_TOP_SNR__W                                                      14
+#define VSB_TOP_SNR__M                                                      0x3FFF
+#define VSB_TOP_SNR__PRE                                                    0x0
+#define VSB_TOP_LOCKSTATUS__A                                               0x1C1002A
+#define VSB_TOP_LOCKSTATUS__W                                               7
+#define VSB_TOP_LOCKSTATUS__M                                               0x7F
+#define VSB_TOP_LOCKSTATUS__PRE                                             0x0
+
+#define   VSB_TOP_LOCKSTATUS_VSBMODE__B                                     0
+#define   VSB_TOP_LOCKSTATUS_VSBMODE__W                                     4
+#define   VSB_TOP_LOCKSTATUS_VSBMODE__M                                     0xF
+#define   VSB_TOP_LOCKSTATUS_VSBMODE__PRE                                   0x0
+
+#define   VSB_TOP_LOCKSTATUS_FRMLOCK__B                                     4
+#define   VSB_TOP_LOCKSTATUS_FRMLOCK__W                                     1
+#define   VSB_TOP_LOCKSTATUS_FRMLOCK__M                                     0x10
+#define   VSB_TOP_LOCKSTATUS_FRMLOCK__PRE                                   0x0
+
+#define   VSB_TOP_LOCKSTATUS_CYLOCK__B                                      5
+#define   VSB_TOP_LOCKSTATUS_CYLOCK__W                                      1
+#define   VSB_TOP_LOCKSTATUS_CYLOCK__M                                      0x20
+#define   VSB_TOP_LOCKSTATUS_CYLOCK__PRE                                    0x0
+
+#define   VSB_TOP_LOCKSTATUS_DDMON__B                                       6
+#define   VSB_TOP_LOCKSTATUS_DDMON__W                                       1
+#define   VSB_TOP_LOCKSTATUS_DDMON__M                                       0x40
+#define   VSB_TOP_LOCKSTATUS_DDMON__PRE                                     0x0
+
+#define VSB_TOP_CTST__A                                                     0x1C1002B
+#define VSB_TOP_CTST__W                                                     4
+#define VSB_TOP_CTST__M                                                     0xF
+#define VSB_TOP_CTST__PRE                                                   0x0
+#define VSB_TOP_EQSMRSTCTRL__A                                              0x1C1002C
+#define VSB_TOP_EQSMRSTCTRL__W                                              7
+#define VSB_TOP_EQSMRSTCTRL__M                                              0x7F
+#define VSB_TOP_EQSMRSTCTRL__PRE                                            0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_RCAON__B                                      0
+#define   VSB_TOP_EQSMRSTCTRL_RCAON__W                                      1
+#define   VSB_TOP_EQSMRSTCTRL_RCAON__M                                      0x1
+#define   VSB_TOP_EQSMRSTCTRL_RCAON__PRE                                    0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_DFEON__B                                      1
+#define   VSB_TOP_EQSMRSTCTRL_DFEON__W                                      1
+#define   VSB_TOP_EQSMRSTCTRL_DFEON__M                                      0x2
+#define   VSB_TOP_EQSMRSTCTRL_DFEON__PRE                                    0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN1__B                                     2
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN1__W                                     1
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN1__M                                     0x4
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN1__PRE                                   0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN2__B                                     3
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN2__W                                     1
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN2__M                                     0x8
+#define   VSB_TOP_EQSMRSTCTRL_DDMEN2__PRE                                   0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_DIGIAGCON__B                                  4
+#define   VSB_TOP_EQSMRSTCTRL_DIGIAGCON__W                                  1
+#define   VSB_TOP_EQSMRSTCTRL_DIGIAGCON__M                                  0x10
+#define   VSB_TOP_EQSMRSTCTRL_DIGIAGCON__PRE                                0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_PARAINITEN__B                                 5
+#define   VSB_TOP_EQSMRSTCTRL_PARAINITEN__W                                 1
+#define   VSB_TOP_EQSMRSTCTRL_PARAINITEN__M                                 0x20
+#define   VSB_TOP_EQSMRSTCTRL_PARAINITEN__PRE                               0x0
+
+#define   VSB_TOP_EQSMRSTCTRL_TIMEOUTFRMCNTEN__B                            6
+#define   VSB_TOP_EQSMRSTCTRL_TIMEOUTFRMCNTEN__W                            1
+#define   VSB_TOP_EQSMRSTCTRL_TIMEOUTFRMCNTEN__M                            0x40
+#define   VSB_TOP_EQSMRSTCTRL_TIMEOUTFRMCNTEN__PRE                          0x0
+
+#define VSB_TOP_EQSMTRNCTRL__A                                              0x1C1002D
+#define VSB_TOP_EQSMTRNCTRL__W                                              7
+#define VSB_TOP_EQSMTRNCTRL__M                                              0x7F
+#define VSB_TOP_EQSMTRNCTRL__PRE                                            0x40
+
+#define   VSB_TOP_EQSMTRNCTRL_RCAON__B                                      0
+#define   VSB_TOP_EQSMTRNCTRL_RCAON__W                                      1
+#define   VSB_TOP_EQSMTRNCTRL_RCAON__M                                      0x1
+#define   VSB_TOP_EQSMTRNCTRL_RCAON__PRE                                    0x0
+
+#define   VSB_TOP_EQSMTRNCTRL_DFEON__B                                      1
+#define   VSB_TOP_EQSMTRNCTRL_DFEON__W                                      1
+#define   VSB_TOP_EQSMTRNCTRL_DFEON__M                                      0x2
+#define   VSB_TOP_EQSMTRNCTRL_DFEON__PRE                                    0x0
+
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN1__B                                     2
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN1__W                                     1
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN1__M                                     0x4
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN1__PRE                                   0x0
+
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN2__B                                     3
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN2__W                                     1
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN2__M                                     0x8
+#define   VSB_TOP_EQSMTRNCTRL_DDMEN2__PRE                                   0x0
+
+#define   VSB_TOP_EQSMTRNCTRL_DIGIAGCON__B                                  4
+#define   VSB_TOP_EQSMTRNCTRL_DIGIAGCON__W                                  1
+#define   VSB_TOP_EQSMTRNCTRL_DIGIAGCON__M                                  0x10
+#define   VSB_TOP_EQSMTRNCTRL_DIGIAGCON__PRE                                0x0
+
+#define   VSB_TOP_EQSMTRNCTRL_PARAINITEN__B                                 5
+#define   VSB_TOP_EQSMTRNCTRL_PARAINITEN__W                                 1
+#define   VSB_TOP_EQSMTRNCTRL_PARAINITEN__M                                 0x20
+#define   VSB_TOP_EQSMTRNCTRL_PARAINITEN__PRE                               0x0
+
+#define   VSB_TOP_EQSMTRNCTRL_TIMEOUTFRMCNTEN__B                            6
+#define   VSB_TOP_EQSMTRNCTRL_TIMEOUTFRMCNTEN__W                            1
+#define   VSB_TOP_EQSMTRNCTRL_TIMEOUTFRMCNTEN__M                            0x40
+#define   VSB_TOP_EQSMTRNCTRL_TIMEOUTFRMCNTEN__PRE                          0x40
+
+#define VSB_TOP_EQSMRCA1CTRL__A                                             0x1C1002E
+#define VSB_TOP_EQSMRCA1CTRL__W                                             7
+#define VSB_TOP_EQSMRCA1CTRL__M                                             0x7F
+#define VSB_TOP_EQSMRCA1CTRL__PRE                                           0x1
+
+#define   VSB_TOP_EQSMRCA1CTRL_RCAON__B                                     0
+#define   VSB_TOP_EQSMRCA1CTRL_RCAON__W                                     1
+#define   VSB_TOP_EQSMRCA1CTRL_RCAON__M                                     0x1
+#define   VSB_TOP_EQSMRCA1CTRL_RCAON__PRE                                   0x1
+
+#define   VSB_TOP_EQSMRCA1CTRL_DFEON__B                                     1
+#define   VSB_TOP_EQSMRCA1CTRL_DFEON__W                                     1
+#define   VSB_TOP_EQSMRCA1CTRL_DFEON__M                                     0x2
+#define   VSB_TOP_EQSMRCA1CTRL_DFEON__PRE                                   0x0
+
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN1__B                                    2
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN1__W                                    1
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN1__M                                    0x4
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN1__PRE                                  0x0
+
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN2__B                                    3
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN2__W                                    1
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN2__M                                    0x8
+#define   VSB_TOP_EQSMRCA1CTRL_DDMEN2__PRE                                  0x0
+
+#define   VSB_TOP_EQSMRCA1CTRL_DIGIAGCON__B                                 4
+#define   VSB_TOP_EQSMRCA1CTRL_DIGIAGCON__W                                 1
+#define   VSB_TOP_EQSMRCA1CTRL_DIGIAGCON__M                                 0x10
+#define   VSB_TOP_EQSMRCA1CTRL_DIGIAGCON__PRE                               0x0
+
+#define   VSB_TOP_EQSMRCA1CTRL_PARAINITEN__B                                5
+#define   VSB_TOP_EQSMRCA1CTRL_PARAINITEN__W                                1
+#define   VSB_TOP_EQSMRCA1CTRL_PARAINITEN__M                                0x20
+#define   VSB_TOP_EQSMRCA1CTRL_PARAINITEN__PRE                              0x0
+
+#define   VSB_TOP_EQSMRCA1CTRL_TIMEOUTFRMCNTEN__B                           6
+#define   VSB_TOP_EQSMRCA1CTRL_TIMEOUTFRMCNTEN__W                           1
+#define   VSB_TOP_EQSMRCA1CTRL_TIMEOUTFRMCNTEN__M                           0x40
+#define   VSB_TOP_EQSMRCA1CTRL_TIMEOUTFRMCNTEN__PRE                         0x0
+
+#define VSB_TOP_EQSMRCA2CTRL__A                                             0x1C1002F
+#define VSB_TOP_EQSMRCA2CTRL__W                                             7
+#define VSB_TOP_EQSMRCA2CTRL__M                                             0x7F
+#define VSB_TOP_EQSMRCA2CTRL__PRE                                           0x3
+
+#define   VSB_TOP_EQSMRCA2CTRL_RCAON__B                                     0
+#define   VSB_TOP_EQSMRCA2CTRL_RCAON__W                                     1
+#define   VSB_TOP_EQSMRCA2CTRL_RCAON__M                                     0x1
+#define   VSB_TOP_EQSMRCA2CTRL_RCAON__PRE                                   0x1
+
+#define   VSB_TOP_EQSMRCA2CTRL_DFEON__B                                     1
+#define   VSB_TOP_EQSMRCA2CTRL_DFEON__W                                     1
+#define   VSB_TOP_EQSMRCA2CTRL_DFEON__M                                     0x2
+#define   VSB_TOP_EQSMRCA2CTRL_DFEON__PRE                                   0x2
+
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN1__B                                    2
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN1__W                                    1
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN1__M                                    0x4
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN1__PRE                                  0x0
+
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN2__B                                    3
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN2__W                                    1
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN2__M                                    0x8
+#define   VSB_TOP_EQSMRCA2CTRL_DDMEN2__PRE                                  0x0
+
+#define   VSB_TOP_EQSMRCA2CTRL_DIGIAGCON__B                                 4
+#define   VSB_TOP_EQSMRCA2CTRL_DIGIAGCON__W                                 1
+#define   VSB_TOP_EQSMRCA2CTRL_DIGIAGCON__M                                 0x10
+#define   VSB_TOP_EQSMRCA2CTRL_DIGIAGCON__PRE                               0x0
+
+#define   VSB_TOP_EQSMRCA2CTRL_PARAINITEN__B                                5
+#define   VSB_TOP_EQSMRCA2CTRL_PARAINITEN__W                                1
+#define   VSB_TOP_EQSMRCA2CTRL_PARAINITEN__M                                0x20
+#define   VSB_TOP_EQSMRCA2CTRL_PARAINITEN__PRE                              0x0
+
+#define   VSB_TOP_EQSMRCA2CTRL_TIMEOUTFRMCNTEN__B                           6
+#define   VSB_TOP_EQSMRCA2CTRL_TIMEOUTFRMCNTEN__W                           1
+#define   VSB_TOP_EQSMRCA2CTRL_TIMEOUTFRMCNTEN__M                           0x40
+#define   VSB_TOP_EQSMRCA2CTRL_TIMEOUTFRMCNTEN__PRE                         0x0
+
+#define VSB_TOP_EQSMDDM1CTRL__A                                             0x1C10030
+#define VSB_TOP_EQSMDDM1CTRL__W                                             7
+#define VSB_TOP_EQSMDDM1CTRL__M                                             0x7F
+#define VSB_TOP_EQSMDDM1CTRL__PRE                                           0x6
+
+#define   VSB_TOP_EQSMDDM1CTRL_RCAON__B                                     0
+#define   VSB_TOP_EQSMDDM1CTRL_RCAON__W                                     1
+#define   VSB_TOP_EQSMDDM1CTRL_RCAON__M                                     0x1
+#define   VSB_TOP_EQSMDDM1CTRL_RCAON__PRE                                   0x0
+
+#define   VSB_TOP_EQSMDDM1CTRL_DFEON__B                                     1
+#define   VSB_TOP_EQSMDDM1CTRL_DFEON__W                                     1
+#define   VSB_TOP_EQSMDDM1CTRL_DFEON__M                                     0x2
+#define   VSB_TOP_EQSMDDM1CTRL_DFEON__PRE                                   0x2
+
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN1__B                                    2
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN1__W                                    1
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN1__M                                    0x4
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN1__PRE                                  0x4
+
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN2__B                                    3
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN2__W                                    1
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN2__M                                    0x8
+#define   VSB_TOP_EQSMDDM1CTRL_DDMEN2__PRE                                  0x0
+
+#define   VSB_TOP_EQSMDDM1CTRL_DIGIAGCON__B                                 4
+#define   VSB_TOP_EQSMDDM1CTRL_DIGIAGCON__W                                 1
+#define   VSB_TOP_EQSMDDM1CTRL_DIGIAGCON__M                                 0x10
+#define   VSB_TOP_EQSMDDM1CTRL_DIGIAGCON__PRE                               0x0
+
+#define   VSB_TOP_EQSMDDM1CTRL_PARAINITEN__B                                5
+#define   VSB_TOP_EQSMDDM1CTRL_PARAINITEN__W                                1
+#define   VSB_TOP_EQSMDDM1CTRL_PARAINITEN__M                                0x20
+#define   VSB_TOP_EQSMDDM1CTRL_PARAINITEN__PRE                              0x0
+
+#define   VSB_TOP_EQSMDDM1CTRL_TIMEOUTFRMCNTEN__B                           6
+#define   VSB_TOP_EQSMDDM1CTRL_TIMEOUTFRMCNTEN__W                           1
+#define   VSB_TOP_EQSMDDM1CTRL_TIMEOUTFRMCNTEN__M                           0x40
+#define   VSB_TOP_EQSMDDM1CTRL_TIMEOUTFRMCNTEN__PRE                         0x0
+
+#define VSB_TOP_EQSMDDM2CTRL__A                                             0x1C10031
+#define VSB_TOP_EQSMDDM2CTRL__W                                             7
+#define VSB_TOP_EQSMDDM2CTRL__M                                             0x7F
+#define VSB_TOP_EQSMDDM2CTRL__PRE                                           0x1E
+
+#define   VSB_TOP_EQSMDDM2CTRL_RCAON__B                                     0
+#define   VSB_TOP_EQSMDDM2CTRL_RCAON__W                                     1
+#define   VSB_TOP_EQSMDDM2CTRL_RCAON__M                                     0x1
+#define   VSB_TOP_EQSMDDM2CTRL_RCAON__PRE                                   0x0
+
+#define   VSB_TOP_EQSMDDM2CTRL_DFEON__B                                     1
+#define   VSB_TOP_EQSMDDM2CTRL_DFEON__W                                     1
+#define   VSB_TOP_EQSMDDM2CTRL_DFEON__M                                     0x2
+#define   VSB_TOP_EQSMDDM2CTRL_DFEON__PRE                                   0x2
+
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN1__B                                    2
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN1__W                                    1
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN1__M                                    0x4
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN1__PRE                                  0x4
+
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN2__B                                    3
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN2__W                                    1
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN2__M                                    0x8
+#define   VSB_TOP_EQSMDDM2CTRL_DDMEN2__PRE                                  0x8
+
+#define   VSB_TOP_EQSMDDM2CTRL_DIGIAGCON__B                                 4
+#define   VSB_TOP_EQSMDDM2CTRL_DIGIAGCON__W                                 1
+#define   VSB_TOP_EQSMDDM2CTRL_DIGIAGCON__M                                 0x10
+#define   VSB_TOP_EQSMDDM2CTRL_DIGIAGCON__PRE                               0x10
+
+#define   VSB_TOP_EQSMDDM2CTRL_PARAINITEN__B                                5
+#define   VSB_TOP_EQSMDDM2CTRL_PARAINITEN__W                                1
+#define   VSB_TOP_EQSMDDM2CTRL_PARAINITEN__M                                0x20
+#define   VSB_TOP_EQSMDDM2CTRL_PARAINITEN__PRE                              0x0
+
+#define   VSB_TOP_EQSMDDM2CTRL_TIMEOUTFRMCNTEN__B                           6
+#define   VSB_TOP_EQSMDDM2CTRL_TIMEOUTFRMCNTEN__W                           1
+#define   VSB_TOP_EQSMDDM2CTRL_TIMEOUTFRMCNTEN__M                           0x40
+#define   VSB_TOP_EQSMDDM2CTRL_TIMEOUTFRMCNTEN__PRE                         0x0
+
+#define VSB_TOP_SYSSMRSTCTRL__A                                             0x1C10032
+#define VSB_TOP_SYSSMRSTCTRL__W                                             11
+#define VSB_TOP_SYSSMRSTCTRL__M                                             0x7FF
+#define VSB_TOP_SYSSMRSTCTRL__PRE                                           0x7F9
+
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCTCAL__B                                  0
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCTCAL__W                                  1
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCTCAL__M                                  0x1
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCTCAL__PRE                                0x1
+
+#define   VSB_TOP_SYSSMRSTCTRL_CTCALEN__B                                   1
+#define   VSB_TOP_SYSSMRSTCTRL_CTCALEN__W                                   1
+#define   VSB_TOP_SYSSMRSTCTRL_CTCALEN__M                                   0x2
+#define   VSB_TOP_SYSSMRSTCTRL_CTCALEN__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMRSTCTRL_STARTTRN__B                                  2
+#define   VSB_TOP_SYSSMRSTCTRL_STARTTRN__W                                  1
+#define   VSB_TOP_SYSSMRSTCTRL_STARTTRN__M                                  0x4
+#define   VSB_TOP_SYSSMRSTCTRL_STARTTRN__PRE                                0x0
+
+#define   VSB_TOP_SYSSMRSTCTRL_RSTFRMSYNCDET__B                             3
+#define   VSB_TOP_SYSSMRSTCTRL_RSTFRMSYNCDET__W                             1
+#define   VSB_TOP_SYSSMRSTCTRL_RSTFRMSYNCDET__M                             0x8
+#define   VSB_TOP_SYSSMRSTCTRL_RSTFRMSYNCDET__PRE                           0x8
+
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCYDET__B                                  4
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCYDET__W                                  1
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCYDET__M                                  0x10
+#define   VSB_TOP_SYSSMRSTCTRL_RSTCYDET__PRE                                0x10
+
+#define   VSB_TOP_SYSSMRSTCTRL_RSTDCRMV__B                                  5
+#define   VSB_TOP_SYSSMRSTCTRL_RSTDCRMV__W                                  1
+#define   VSB_TOP_SYSSMRSTCTRL_RSTDCRMV__M                                  0x20
+#define   VSB_TOP_SYSSMRSTCTRL_RSTDCRMV__PRE                                0x20
+
+#define   VSB_TOP_SYSSMRSTCTRL_RSTEQSIG__B                                  6
+#define   VSB_TOP_SYSSMRSTCTRL_RSTEQSIG__W                                  1
+#define   VSB_TOP_SYSSMRSTCTRL_RSTEQSIG__M                                  0x40
+#define   VSB_TOP_SYSSMRSTCTRL_RSTEQSIG__PRE                                0x40
+
+#define   VSB_TOP_SYSSMRSTCTRL_CKFRZ__B                                     7
+#define   VSB_TOP_SYSSMRSTCTRL_CKFRZ__W                                     1
+#define   VSB_TOP_SYSSMRSTCTRL_CKFRZ__M                                     0x80
+#define   VSB_TOP_SYSSMRSTCTRL_CKFRZ__PRE                                   0x80
+
+#define   VSB_TOP_SYSSMRSTCTRL_CKBWSW__B                                    8
+#define   VSB_TOP_SYSSMRSTCTRL_CKBWSW__W                                    1
+#define   VSB_TOP_SYSSMRSTCTRL_CKBWSW__M                                    0x100
+#define   VSB_TOP_SYSSMRSTCTRL_CKBWSW__PRE                                  0x100
+
+#define   VSB_TOP_SYSSMRSTCTRL_NCOBWSW__B                                   9
+#define   VSB_TOP_SYSSMRSTCTRL_NCOBWSW__W                                   1
+#define   VSB_TOP_SYSSMRSTCTRL_NCOBWSW__M                                   0x200
+#define   VSB_TOP_SYSSMRSTCTRL_NCOBWSW__PRE                                 0x200
+
+#define   VSB_TOP_SYSSMRSTCTRL_NCOTIMEOUTCNTEN__B                           10
+#define   VSB_TOP_SYSSMRSTCTRL_NCOTIMEOUTCNTEN__W                           1
+#define   VSB_TOP_SYSSMRSTCTRL_NCOTIMEOUTCNTEN__M                           0x400
+#define   VSB_TOP_SYSSMRSTCTRL_NCOTIMEOUTCNTEN__PRE                         0x400
+
+#define VSB_TOP_SYSSMCYCTRL__A                                              0x1C10033
+#define VSB_TOP_SYSSMCYCTRL__W                                              11
+#define VSB_TOP_SYSSMCYCTRL__M                                              0x7FF
+#define VSB_TOP_SYSSMCYCTRL__PRE                                            0x4E9
+
+#define   VSB_TOP_SYSSMCYCTRL_RSTCTCAL__B                                   0
+#define   VSB_TOP_SYSSMCYCTRL_RSTCTCAL__W                                   1
+#define   VSB_TOP_SYSSMCYCTRL_RSTCTCAL__M                                   0x1
+#define   VSB_TOP_SYSSMCYCTRL_RSTCTCAL__PRE                                 0x1
+
+#define   VSB_TOP_SYSSMCYCTRL_CTCALEN__B                                    1
+#define   VSB_TOP_SYSSMCYCTRL_CTCALEN__W                                    1
+#define   VSB_TOP_SYSSMCYCTRL_CTCALEN__M                                    0x2
+#define   VSB_TOP_SYSSMCYCTRL_CTCALEN__PRE                                  0x0
+
+#define   VSB_TOP_SYSSMCYCTRL_STARTTRN__B                                   2
+#define   VSB_TOP_SYSSMCYCTRL_STARTTRN__W                                   1
+#define   VSB_TOP_SYSSMCYCTRL_STARTTRN__M                                   0x4
+#define   VSB_TOP_SYSSMCYCTRL_STARTTRN__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMCYCTRL_RSTFRMSYNCDET__B                              3
+#define   VSB_TOP_SYSSMCYCTRL_RSTFRMSYNCDET__W                              1
+#define   VSB_TOP_SYSSMCYCTRL_RSTFRMSYNCDET__M                              0x8
+#define   VSB_TOP_SYSSMCYCTRL_RSTFRMSYNCDET__PRE                            0x8
+
+#define   VSB_TOP_SYSSMCYCTRL_RSTCYDET__B                                   4
+#define   VSB_TOP_SYSSMCYCTRL_RSTCYDET__W                                   1
+#define   VSB_TOP_SYSSMCYCTRL_RSTCYDET__M                                   0x10
+#define   VSB_TOP_SYSSMCYCTRL_RSTCYDET__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMCYCTRL_RSTDCRMV__B                                   5
+#define   VSB_TOP_SYSSMCYCTRL_RSTDCRMV__W                                   1
+#define   VSB_TOP_SYSSMCYCTRL_RSTDCRMV__M                                   0x20
+#define   VSB_TOP_SYSSMCYCTRL_RSTDCRMV__PRE                                 0x20
+
+#define   VSB_TOP_SYSSMCYCTRL_RSTEQSIG__B                                   6
+#define   VSB_TOP_SYSSMCYCTRL_RSTEQSIG__W                                   1
+#define   VSB_TOP_SYSSMCYCTRL_RSTEQSIG__M                                   0x40
+#define   VSB_TOP_SYSSMCYCTRL_RSTEQSIG__PRE                                 0x40
+
+#define   VSB_TOP_SYSSMCYCTRL_CKFRZ__B                                      7
+#define   VSB_TOP_SYSSMCYCTRL_CKFRZ__W                                      1
+#define   VSB_TOP_SYSSMCYCTRL_CKFRZ__M                                      0x80
+#define   VSB_TOP_SYSSMCYCTRL_CKFRZ__PRE                                    0x80
+
+#define   VSB_TOP_SYSSMCYCTRL_CKBWSW__B                                     8
+#define   VSB_TOP_SYSSMCYCTRL_CKBWSW__W                                     1
+#define   VSB_TOP_SYSSMCYCTRL_CKBWSW__M                                     0x100
+#define   VSB_TOP_SYSSMCYCTRL_CKBWSW__PRE                                   0x0
+
+#define   VSB_TOP_SYSSMCYCTRL_NCOBWSW__B                                    9
+#define   VSB_TOP_SYSSMCYCTRL_NCOBWSW__W                                    1
+#define   VSB_TOP_SYSSMCYCTRL_NCOBWSW__M                                    0x200
+#define   VSB_TOP_SYSSMCYCTRL_NCOBWSW__PRE                                  0x0
+
+#define   VSB_TOP_SYSSMCYCTRL_NCOTIMEOUTCNTEN__B                            10
+#define   VSB_TOP_SYSSMCYCTRL_NCOTIMEOUTCNTEN__W                            1
+#define   VSB_TOP_SYSSMCYCTRL_NCOTIMEOUTCNTEN__M                            0x400
+#define   VSB_TOP_SYSSMCYCTRL_NCOTIMEOUTCNTEN__PRE                          0x400
+
+#define VSB_TOP_SYSSMTRNCTRL__A                                             0x1C10034
+#define VSB_TOP_SYSSMTRNCTRL__W                                             11
+#define VSB_TOP_SYSSMTRNCTRL__M                                             0x7FF
+#define VSB_TOP_SYSSMTRNCTRL__PRE                                           0x204
+
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCTCAL__B                                  0
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCTCAL__W                                  1
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCTCAL__M                                  0x1
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCTCAL__PRE                                0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_CTCALEN__B                                   1
+#define   VSB_TOP_SYSSMTRNCTRL_CTCALEN__W                                   1
+#define   VSB_TOP_SYSSMTRNCTRL_CTCALEN__M                                   0x2
+#define   VSB_TOP_SYSSMTRNCTRL_CTCALEN__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_STARTTRN__B                                  2
+#define   VSB_TOP_SYSSMTRNCTRL_STARTTRN__W                                  1
+#define   VSB_TOP_SYSSMTRNCTRL_STARTTRN__M                                  0x4
+#define   VSB_TOP_SYSSMTRNCTRL_STARTTRN__PRE                                0x4
+
+#define   VSB_TOP_SYSSMTRNCTRL_RSTFRMSYNCDET__B                             3
+#define   VSB_TOP_SYSSMTRNCTRL_RSTFRMSYNCDET__W                             1
+#define   VSB_TOP_SYSSMTRNCTRL_RSTFRMSYNCDET__M                             0x8
+#define   VSB_TOP_SYSSMTRNCTRL_RSTFRMSYNCDET__PRE                           0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCYDET__B                                  4
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCYDET__W                                  1
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCYDET__M                                  0x10
+#define   VSB_TOP_SYSSMTRNCTRL_RSTCYDET__PRE                                0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_RSTDCRMV__B                                  5
+#define   VSB_TOP_SYSSMTRNCTRL_RSTDCRMV__W                                  1
+#define   VSB_TOP_SYSSMTRNCTRL_RSTDCRMV__M                                  0x20
+#define   VSB_TOP_SYSSMTRNCTRL_RSTDCRMV__PRE                                0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_RSTEQSIG__B                                  6
+#define   VSB_TOP_SYSSMTRNCTRL_RSTEQSIG__W                                  1
+#define   VSB_TOP_SYSSMTRNCTRL_RSTEQSIG__M                                  0x40
+#define   VSB_TOP_SYSSMTRNCTRL_RSTEQSIG__PRE                                0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_CKFRZ__B                                     7
+#define   VSB_TOP_SYSSMTRNCTRL_CKFRZ__W                                     1
+#define   VSB_TOP_SYSSMTRNCTRL_CKFRZ__M                                     0x80
+#define   VSB_TOP_SYSSMTRNCTRL_CKFRZ__PRE                                   0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_CKBWSW__B                                    8
+#define   VSB_TOP_SYSSMTRNCTRL_CKBWSW__W                                    1
+#define   VSB_TOP_SYSSMTRNCTRL_CKBWSW__M                                    0x100
+#define   VSB_TOP_SYSSMTRNCTRL_CKBWSW__PRE                                  0x0
+
+#define   VSB_TOP_SYSSMTRNCTRL_NCOBWSW__B                                   9
+#define   VSB_TOP_SYSSMTRNCTRL_NCOBWSW__W                                   1
+#define   VSB_TOP_SYSSMTRNCTRL_NCOBWSW__M                                   0x200
+#define   VSB_TOP_SYSSMTRNCTRL_NCOBWSW__PRE                                 0x200
+
+#define   VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__B                           10
+#define   VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__W                           1
+#define   VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M                           0x400
+#define   VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__PRE                         0x0
+
+#define VSB_TOP_SYSSMEQCTRL__A                                              0x1C10035
+#define VSB_TOP_SYSSMEQCTRL__W                                              11
+#define VSB_TOP_SYSSMEQCTRL__M                                              0x7FF
+#define VSB_TOP_SYSSMEQCTRL__PRE                                            0x304
+
+#define   VSB_TOP_SYSSMEQCTRL_RSTCTCAL__B                                   0
+#define   VSB_TOP_SYSSMEQCTRL_RSTCTCAL__W                                   1
+#define   VSB_TOP_SYSSMEQCTRL_RSTCTCAL__M                                   0x1
+#define   VSB_TOP_SYSSMEQCTRL_RSTCTCAL__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_CTCALEN__B                                    1
+#define   VSB_TOP_SYSSMEQCTRL_CTCALEN__W                                    1
+#define   VSB_TOP_SYSSMEQCTRL_CTCALEN__M                                    0x2
+#define   VSB_TOP_SYSSMEQCTRL_CTCALEN__PRE                                  0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_STARTTRN__B                                   2
+#define   VSB_TOP_SYSSMEQCTRL_STARTTRN__W                                   1
+#define   VSB_TOP_SYSSMEQCTRL_STARTTRN__M                                   0x4
+#define   VSB_TOP_SYSSMEQCTRL_STARTTRN__PRE                                 0x4
+
+#define   VSB_TOP_SYSSMEQCTRL_RSTFRMSYNCDET__B                              3
+#define   VSB_TOP_SYSSMEQCTRL_RSTFRMSYNCDET__W                              1
+#define   VSB_TOP_SYSSMEQCTRL_RSTFRMSYNCDET__M                              0x8
+#define   VSB_TOP_SYSSMEQCTRL_RSTFRMSYNCDET__PRE                            0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_RSTCYDET__B                                   4
+#define   VSB_TOP_SYSSMEQCTRL_RSTCYDET__W                                   1
+#define   VSB_TOP_SYSSMEQCTRL_RSTCYDET__M                                   0x10
+#define   VSB_TOP_SYSSMEQCTRL_RSTCYDET__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_RSTDCRMV__B                                   5
+#define   VSB_TOP_SYSSMEQCTRL_RSTDCRMV__W                                   1
+#define   VSB_TOP_SYSSMEQCTRL_RSTDCRMV__M                                   0x20
+#define   VSB_TOP_SYSSMEQCTRL_RSTDCRMV__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_RSTEQSIG__B                                   6
+#define   VSB_TOP_SYSSMEQCTRL_RSTEQSIG__W                                   1
+#define   VSB_TOP_SYSSMEQCTRL_RSTEQSIG__M                                   0x40
+#define   VSB_TOP_SYSSMEQCTRL_RSTEQSIG__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_CKFRZ__B                                      7
+#define   VSB_TOP_SYSSMEQCTRL_CKFRZ__W                                      1
+#define   VSB_TOP_SYSSMEQCTRL_CKFRZ__M                                      0x80
+#define   VSB_TOP_SYSSMEQCTRL_CKFRZ__PRE                                    0x0
+
+#define   VSB_TOP_SYSSMEQCTRL_CKBWSW__B                                     8
+#define   VSB_TOP_SYSSMEQCTRL_CKBWSW__W                                     1
+#define   VSB_TOP_SYSSMEQCTRL_CKBWSW__M                                     0x100
+#define   VSB_TOP_SYSSMEQCTRL_CKBWSW__PRE                                   0x100
+
+#define   VSB_TOP_SYSSMEQCTRL_NCOBWSW__B                                    9
+#define   VSB_TOP_SYSSMEQCTRL_NCOBWSW__W                                    1
+#define   VSB_TOP_SYSSMEQCTRL_NCOBWSW__M                                    0x200
+#define   VSB_TOP_SYSSMEQCTRL_NCOBWSW__PRE                                  0x200
+
+#define   VSB_TOP_SYSSMEQCTRL_NCOTIMEOUTCNTEN__B                            10
+#define   VSB_TOP_SYSSMEQCTRL_NCOTIMEOUTCNTEN__W                            1
+#define   VSB_TOP_SYSSMEQCTRL_NCOTIMEOUTCNTEN__M                            0x400
+#define   VSB_TOP_SYSSMEQCTRL_NCOTIMEOUTCNTEN__PRE                          0x0
+
+#define VSB_TOP_SYSSMAGCCTRL__A                                             0x1C10036
+#define VSB_TOP_SYSSMAGCCTRL__W                                             11
+#define VSB_TOP_SYSSMAGCCTRL__M                                             0x7FF
+#define VSB_TOP_SYSSMAGCCTRL__PRE                                           0xF9
+
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCTCAL__B                                  0
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCTCAL__W                                  1
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCTCAL__M                                  0x1
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCTCAL__PRE                                0x1
+
+#define   VSB_TOP_SYSSMAGCCTRL_CTCALEN__B                                   1
+#define   VSB_TOP_SYSSMAGCCTRL_CTCALEN__W                                   1
+#define   VSB_TOP_SYSSMAGCCTRL_CTCALEN__M                                   0x2
+#define   VSB_TOP_SYSSMAGCCTRL_CTCALEN__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMAGCCTRL_STARTTRN__B                                  2
+#define   VSB_TOP_SYSSMAGCCTRL_STARTTRN__W                                  1
+#define   VSB_TOP_SYSSMAGCCTRL_STARTTRN__M                                  0x4
+#define   VSB_TOP_SYSSMAGCCTRL_STARTTRN__PRE                                0x0
+
+#define   VSB_TOP_SYSSMAGCCTRL_RSTFRMSYNCDET__B                             3
+#define   VSB_TOP_SYSSMAGCCTRL_RSTFRMSYNCDET__W                             1
+#define   VSB_TOP_SYSSMAGCCTRL_RSTFRMSYNCDET__M                             0x8
+#define   VSB_TOP_SYSSMAGCCTRL_RSTFRMSYNCDET__PRE                           0x8
+
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCYDET__B                                  4
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCYDET__W                                  1
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCYDET__M                                  0x10
+#define   VSB_TOP_SYSSMAGCCTRL_RSTCYDET__PRE                                0x10
+
+#define   VSB_TOP_SYSSMAGCCTRL_RSTDCRMV__B                                  5
+#define   VSB_TOP_SYSSMAGCCTRL_RSTDCRMV__W                                  1
+#define   VSB_TOP_SYSSMAGCCTRL_RSTDCRMV__M                                  0x20
+#define   VSB_TOP_SYSSMAGCCTRL_RSTDCRMV__PRE                                0x20
+
+#define   VSB_TOP_SYSSMAGCCTRL_RSTEQSIG__B                                  6
+#define   VSB_TOP_SYSSMAGCCTRL_RSTEQSIG__W                                  1
+#define   VSB_TOP_SYSSMAGCCTRL_RSTEQSIG__M                                  0x40
+#define   VSB_TOP_SYSSMAGCCTRL_RSTEQSIG__PRE                                0x40
+
+#define   VSB_TOP_SYSSMAGCCTRL_CKFRZ__B                                     7
+#define   VSB_TOP_SYSSMAGCCTRL_CKFRZ__W                                     1
+#define   VSB_TOP_SYSSMAGCCTRL_CKFRZ__M                                     0x80
+#define   VSB_TOP_SYSSMAGCCTRL_CKFRZ__PRE                                   0x80
+
+#define   VSB_TOP_SYSSMAGCCTRL_CKBWSW__B                                    8
+#define   VSB_TOP_SYSSMAGCCTRL_CKBWSW__W                                    1
+#define   VSB_TOP_SYSSMAGCCTRL_CKBWSW__M                                    0x100
+#define   VSB_TOP_SYSSMAGCCTRL_CKBWSW__PRE                                  0x0
+
+#define   VSB_TOP_SYSSMAGCCTRL_NCOBWSW__B                                   9
+#define   VSB_TOP_SYSSMAGCCTRL_NCOBWSW__W                                   1
+#define   VSB_TOP_SYSSMAGCCTRL_NCOBWSW__M                                   0x200
+#define   VSB_TOP_SYSSMAGCCTRL_NCOBWSW__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMAGCCTRL_NCOTIMEOUTCNTEN__B                           10
+#define   VSB_TOP_SYSSMAGCCTRL_NCOTIMEOUTCNTEN__W                           1
+#define   VSB_TOP_SYSSMAGCCTRL_NCOTIMEOUTCNTEN__M                           0x400
+#define   VSB_TOP_SYSSMAGCCTRL_NCOTIMEOUTCNTEN__PRE                         0x0
+
+#define VSB_TOP_SYSSMCTCTRL__A                                              0x1C10037
+#define VSB_TOP_SYSSMCTCTRL__W                                              11
+#define VSB_TOP_SYSSMCTCTRL__M                                              0x7FF
+#define VSB_TOP_SYSSMCTCTRL__PRE                                            0x4A
+
+#define   VSB_TOP_SYSSMCTCTRL_RSTCTCAL__B                                   0
+#define   VSB_TOP_SYSSMCTCTRL_RSTCTCAL__W                                   1
+#define   VSB_TOP_SYSSMCTCTRL_RSTCTCAL__M                                   0x1
+#define   VSB_TOP_SYSSMCTCTRL_RSTCTCAL__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_CTCALEN__B                                    1
+#define   VSB_TOP_SYSSMCTCTRL_CTCALEN__W                                    1
+#define   VSB_TOP_SYSSMCTCTRL_CTCALEN__M                                    0x2
+#define   VSB_TOP_SYSSMCTCTRL_CTCALEN__PRE                                  0x2
+
+#define   VSB_TOP_SYSSMCTCTRL_STARTTRN__B                                   2
+#define   VSB_TOP_SYSSMCTCTRL_STARTTRN__W                                   1
+#define   VSB_TOP_SYSSMCTCTRL_STARTTRN__M                                   0x4
+#define   VSB_TOP_SYSSMCTCTRL_STARTTRN__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_RSTFRMSYNCDET__B                              3
+#define   VSB_TOP_SYSSMCTCTRL_RSTFRMSYNCDET__W                              1
+#define   VSB_TOP_SYSSMCTCTRL_RSTFRMSYNCDET__M                              0x8
+#define   VSB_TOP_SYSSMCTCTRL_RSTFRMSYNCDET__PRE                            0x8
+
+#define   VSB_TOP_SYSSMCTCTRL_RSTCYDET__B                                   4
+#define   VSB_TOP_SYSSMCTCTRL_RSTCYDET__W                                   1
+#define   VSB_TOP_SYSSMCTCTRL_RSTCYDET__M                                   0x10
+#define   VSB_TOP_SYSSMCTCTRL_RSTCYDET__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_RSTDCRMV__B                                   5
+#define   VSB_TOP_SYSSMCTCTRL_RSTDCRMV__W                                   1
+#define   VSB_TOP_SYSSMCTCTRL_RSTDCRMV__M                                   0x20
+#define   VSB_TOP_SYSSMCTCTRL_RSTDCRMV__PRE                                 0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_RSTEQSIG__B                                   6
+#define   VSB_TOP_SYSSMCTCTRL_RSTEQSIG__W                                   1
+#define   VSB_TOP_SYSSMCTCTRL_RSTEQSIG__M                                   0x40
+#define   VSB_TOP_SYSSMCTCTRL_RSTEQSIG__PRE                                 0x40
+
+#define   VSB_TOP_SYSSMCTCTRL_CKFRZ__B                                      7
+#define   VSB_TOP_SYSSMCTCTRL_CKFRZ__W                                      1
+#define   VSB_TOP_SYSSMCTCTRL_CKFRZ__M                                      0x80
+#define   VSB_TOP_SYSSMCTCTRL_CKFRZ__PRE                                    0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_CKBWSW__B                                     8
+#define   VSB_TOP_SYSSMCTCTRL_CKBWSW__W                                     1
+#define   VSB_TOP_SYSSMCTCTRL_CKBWSW__M                                     0x100
+#define   VSB_TOP_SYSSMCTCTRL_CKBWSW__PRE                                   0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_NCOBWSW__B                                    9
+#define   VSB_TOP_SYSSMCTCTRL_NCOBWSW__W                                    1
+#define   VSB_TOP_SYSSMCTCTRL_NCOBWSW__M                                    0x200
+#define   VSB_TOP_SYSSMCTCTRL_NCOBWSW__PRE                                  0x0
+
+#define   VSB_TOP_SYSSMCTCTRL_NCOTIMEOUTCNTEN__B                            10
+#define   VSB_TOP_SYSSMCTCTRL_NCOTIMEOUTCNTEN__W                            1
+#define   VSB_TOP_SYSSMCTCTRL_NCOTIMEOUTCNTEN__M                            0x400
+#define   VSB_TOP_SYSSMCTCTRL_NCOTIMEOUTCNTEN__PRE                          0x0
+
+#define VSB_TOP_EQCTRL__A                                                   0x1C10038
+#define VSB_TOP_EQCTRL__W                                                   10
+#define VSB_TOP_EQCTRL__M                                                   0x3FF
+#define VSB_TOP_EQCTRL__PRE                                                 0x6
+
+#define   VSB_TOP_EQCTRL_STASSIGNEN__B                                      0
+#define   VSB_TOP_EQCTRL_STASSIGNEN__W                                      1
+#define   VSB_TOP_EQCTRL_STASSIGNEN__M                                      0x1
+#define   VSB_TOP_EQCTRL_STASSIGNEN__PRE                                    0x0
+
+#define   VSB_TOP_EQCTRL_ORCANCMAEN__B                                      1
+#define   VSB_TOP_EQCTRL_ORCANCMAEN__W                                      1
+#define   VSB_TOP_EQCTRL_ORCANCMAEN__M                                      0x2
+#define   VSB_TOP_EQCTRL_ORCANCMAEN__PRE                                    0x2
+
+#define   VSB_TOP_EQCTRL_ODAGCGO__B                                         2
+#define   VSB_TOP_EQCTRL_ODAGCGO__W                                         1
+#define   VSB_TOP_EQCTRL_ODAGCGO__M                                         0x4
+#define   VSB_TOP_EQCTRL_ODAGCGO__PRE                                       0x4
+
+#define   VSB_TOP_EQCTRL_OPTGAIN__B                                         3
+#define   VSB_TOP_EQCTRL_OPTGAIN__W                                         3
+#define   VSB_TOP_EQCTRL_OPTGAIN__M                                         0x38
+#define   VSB_TOP_EQCTRL_OPTGAIN__PRE                                       0x0
+
+#define   VSB_TOP_EQCTRL_TAPRAMWRTEN__B                                     6
+#define   VSB_TOP_EQCTRL_TAPRAMWRTEN__W                                     1
+#define   VSB_TOP_EQCTRL_TAPRAMWRTEN__M                                     0x40
+#define   VSB_TOP_EQCTRL_TAPRAMWRTEN__PRE                                   0x0
+
+#define   VSB_TOP_EQCTRL_CMAGAIN__B                                         7
+#define   VSB_TOP_EQCTRL_CMAGAIN__W                                         3
+#define   VSB_TOP_EQCTRL_CMAGAIN__M                                         0x380
+#define   VSB_TOP_EQCTRL_CMAGAIN__PRE                                       0x0
+
+#define VSB_TOP_PREEQAGCCTRL__A                                             0x1C10039
+#define VSB_TOP_PREEQAGCCTRL__W                                             5
+#define VSB_TOP_PREEQAGCCTRL__M                                             0x1F
+#define VSB_TOP_PREEQAGCCTRL__PRE                                           0x10
+
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCBWSEL__B                             0
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCBWSEL__W                             4
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCBWSEL__M                             0xF
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCBWSEL__PRE                           0x0
+
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCFRZ__B                               4
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCFRZ__W                               1
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCFRZ__M                               0x10
+#define   VSB_TOP_PREEQAGCCTRL_PREEQAGCFRZ__PRE                             0x10
+
+#define VSB_TOP_PREEQAGCPWRREFLVLHI__A                                      0x1C1003A
+#define VSB_TOP_PREEQAGCPWRREFLVLHI__W                                      8
+#define VSB_TOP_PREEQAGCPWRREFLVLHI__M                                      0xFF
+#define VSB_TOP_PREEQAGCPWRREFLVLHI__PRE                                    0x0
+
+#define VSB_TOP_PREEQAGCPWRREFLVLLO__A                                      0x1C1003B
+#define VSB_TOP_PREEQAGCPWRREFLVLLO__W                                      16
+#define VSB_TOP_PREEQAGCPWRREFLVLLO__M                                      0xFFFF
+#define VSB_TOP_PREEQAGCPWRREFLVLLO__PRE                                    0x1D66
+
+#define VSB_TOP_CORINGSEL__A                                                0x1C1003C
+#define VSB_TOP_CORINGSEL__W                                                8
+#define VSB_TOP_CORINGSEL__M                                                0xFF
+#define VSB_TOP_CORINGSEL__PRE                                              0x3
+#define VSB_TOP_BEDETCTRL__A                                                0x1C1003D
+#define VSB_TOP_BEDETCTRL__W                                                9
+#define VSB_TOP_BEDETCTRL__M                                                0x1FF
+#define VSB_TOP_BEDETCTRL__PRE                                              0x145
+
+#define   VSB_TOP_BEDETCTRL_MIXRATIO__B                                     0
+#define   VSB_TOP_BEDETCTRL_MIXRATIO__W                                     3
+#define   VSB_TOP_BEDETCTRL_MIXRATIO__M                                     0x7
+#define   VSB_TOP_BEDETCTRL_MIXRATIO__PRE                                   0x5
+
+#define   VSB_TOP_BEDETCTRL_CYOFFSEL__B                                     3
+#define   VSB_TOP_BEDETCTRL_CYOFFSEL__W                                     1
+#define   VSB_TOP_BEDETCTRL_CYOFFSEL__M                                     0x8
+#define   VSB_TOP_BEDETCTRL_CYOFFSEL__PRE                                   0x0
+
+#define   VSB_TOP_BEDETCTRL_DATAOFFSEL__B                                   4
+#define   VSB_TOP_BEDETCTRL_DATAOFFSEL__W                                   1
+#define   VSB_TOP_BEDETCTRL_DATAOFFSEL__M                                   0x10
+#define   VSB_TOP_BEDETCTRL_DATAOFFSEL__PRE                                 0x0
+
+#define   VSB_TOP_BEDETCTRL_BYPASS_DSQ__B                                   5
+#define   VSB_TOP_BEDETCTRL_BYPASS_DSQ__W                                   1
+#define   VSB_TOP_BEDETCTRL_BYPASS_DSQ__M                                   0x20
+#define   VSB_TOP_BEDETCTRL_BYPASS_DSQ__PRE                                 0x0
+
+#define   VSB_TOP_BEDETCTRL_BYPASS_PSQ__B                                   6
+#define   VSB_TOP_BEDETCTRL_BYPASS_PSQ__W                                   1
+#define   VSB_TOP_BEDETCTRL_BYPASS_PSQ__M                                   0x40
+#define   VSB_TOP_BEDETCTRL_BYPASS_PSQ__PRE                                 0x40
+
+#define   VSB_TOP_BEDETCTRL_BYPASS_CSQ__B                                   7
+#define   VSB_TOP_BEDETCTRL_BYPASS_CSQ__W                                   1
+#define   VSB_TOP_BEDETCTRL_BYPASS_CSQ__M                                   0x80
+#define   VSB_TOP_BEDETCTRL_BYPASS_CSQ__PRE                                 0x0
+
+#define   VSB_TOP_BEDETCTRL_BYPASS_DMP__B                                   8
+#define   VSB_TOP_BEDETCTRL_BYPASS_DMP__W                                   1
+#define   VSB_TOP_BEDETCTRL_BYPASS_DMP__M                                   0x100
+#define   VSB_TOP_BEDETCTRL_BYPASS_DMP__PRE                                 0x100
+
+#define VSB_TOP_LBAGCREFLVL__A                                              0x1C1003E
+#define VSB_TOP_LBAGCREFLVL__W                                              12
+#define VSB_TOP_LBAGCREFLVL__M                                              0xFFF
+#define VSB_TOP_LBAGCREFLVL__PRE                                            0x200
+
+#define VSB_TOP_UBAGCREFLVL__A                                              0x1C1003F
+#define VSB_TOP_UBAGCREFLVL__W                                              12
+#define VSB_TOP_UBAGCREFLVL__M                                              0xFFF
+#define VSB_TOP_UBAGCREFLVL__PRE                                            0x400
+
+#define VSB_TOP_NOTCH1_BIN_NUM__A                                           0x1C10040
+#define VSB_TOP_NOTCH1_BIN_NUM__W                                           11
+#define VSB_TOP_NOTCH1_BIN_NUM__M                                           0x7FF
+#define VSB_TOP_NOTCH1_BIN_NUM__PRE                                         0xB2
+
+#define VSB_TOP_NOTCH2_BIN_NUM__A                                           0x1C10041
+#define VSB_TOP_NOTCH2_BIN_NUM__W                                           11
+#define VSB_TOP_NOTCH2_BIN_NUM__M                                           0x7FF
+#define VSB_TOP_NOTCH2_BIN_NUM__PRE                                         0x40B
+
+#define VSB_TOP_NOTCH_START_BIN_NUM__A                                      0x1C10042
+#define VSB_TOP_NOTCH_START_BIN_NUM__W                                      11
+#define VSB_TOP_NOTCH_START_BIN_NUM__M                                      0x7FF
+#define VSB_TOP_NOTCH_START_BIN_NUM__PRE                                    0x7C0
+
+#define VSB_TOP_NOTCH_STOP_BIN_NUM__A                                       0x1C10043
+#define VSB_TOP_NOTCH_STOP_BIN_NUM__W                                       11
+#define VSB_TOP_NOTCH_STOP_BIN_NUM__M                                       0x7FF
+#define VSB_TOP_NOTCH_STOP_BIN_NUM__PRE                                     0x43F
+
+#define VSB_TOP_NOTCH_TEST_DURATION__A                                      0x1C10044
+#define VSB_TOP_NOTCH_TEST_DURATION__W                                      11
+#define VSB_TOP_NOTCH_TEST_DURATION__M                                      0x7FF
+#define VSB_TOP_NOTCH_TEST_DURATION__PRE                                    0x7FF
+
+#define VSB_TOP_RESULT_LARGE_PEAK_BIN__A                                    0x1C10045
+#define VSB_TOP_RESULT_LARGE_PEAK_BIN__W                                    11
+#define VSB_TOP_RESULT_LARGE_PEAK_BIN__M                                    0x7FF
+#define VSB_TOP_RESULT_LARGE_PEAK_BIN__PRE                                  0x0
+
+#define VSB_TOP_RESULT_LARGE_PEAK_VALUE__A                                  0x1C10046
+#define VSB_TOP_RESULT_LARGE_PEAK_VALUE__W                                  16
+#define VSB_TOP_RESULT_LARGE_PEAK_VALUE__M                                  0xFFFF
+#define VSB_TOP_RESULT_LARGE_PEAK_VALUE__PRE                                0x0
+
+#define VSB_TOP_RESULT_SMALL_PEAK_BIN__A                                    0x1C10047
+#define VSB_TOP_RESULT_SMALL_PEAK_BIN__W                                    11
+#define VSB_TOP_RESULT_SMALL_PEAK_BIN__M                                    0x7FF
+#define VSB_TOP_RESULT_SMALL_PEAK_BIN__PRE                                  0x0
+
+#define VSB_TOP_RESULT_SMALL_PEAK_VALUE__A                                  0x1C10048
+#define VSB_TOP_RESULT_SMALL_PEAK_VALUE__W                                  16
+#define VSB_TOP_RESULT_SMALL_PEAK_VALUE__M                                  0xFFFF
+#define VSB_TOP_RESULT_SMALL_PEAK_VALUE__PRE                                0x0
+
+#define VSB_TOP_NOTCH_SWEEP_RUNNING__A                                      0x1C10049
+#define VSB_TOP_NOTCH_SWEEP_RUNNING__W                                      1
+#define VSB_TOP_NOTCH_SWEEP_RUNNING__M                                      0x1
+#define VSB_TOP_NOTCH_SWEEP_RUNNING__PRE                                    0x0
+
+#define VSB_TOP_PREEQDAGCRATIO__A                                           0x1C1004A
+#define VSB_TOP_PREEQDAGCRATIO__W                                           13
+#define VSB_TOP_PREEQDAGCRATIO__M                                           0x1FFF
+#define VSB_TOP_PREEQDAGCRATIO__PRE                                         0x0
+#define VSB_TOP_AGC_TRUNCCTRL__A                                            0x1C1004B
+#define VSB_TOP_AGC_TRUNCCTRL__W                                            4
+#define VSB_TOP_AGC_TRUNCCTRL__M                                            0xF
+#define VSB_TOP_AGC_TRUNCCTRL__PRE                                          0xF
+
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_LSB__B                                0
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_LSB__W                                2
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_LSB__M                                0x3
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_LSB__PRE                              0x3
+
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_12N__B                                2
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_12N__W                                1
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_12N__M                                0x4
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_12N__PRE                              0x4
+
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_EN__B                                 3
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_EN__W                                 1
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_EN__M                                 0x8
+#define   VSB_TOP_AGC_TRUNCCTRL_TRUNC_EN__PRE                               0x8
+
+#define VSB_TOP_BEAGC_DEADZONEINIT__A                                       0x1C1004C
+#define VSB_TOP_BEAGC_DEADZONEINIT__W                                       8
+#define VSB_TOP_BEAGC_DEADZONEINIT__M                                       0xFF
+#define VSB_TOP_BEAGC_DEADZONEINIT__PRE                                     0x50
+
+#define VSB_TOP_BEAGC_REFLEVEL__A                                           0x1C1004D
+#define VSB_TOP_BEAGC_REFLEVEL__W                                           9
+#define VSB_TOP_BEAGC_REFLEVEL__M                                           0x1FF
+#define VSB_TOP_BEAGC_REFLEVEL__PRE                                         0xAE
+
+#define VSB_TOP_BEAGC_GAINSHIFT__A                                          0x1C1004E
+#define VSB_TOP_BEAGC_GAINSHIFT__W                                          3
+#define VSB_TOP_BEAGC_GAINSHIFT__M                                          0x7
+#define VSB_TOP_BEAGC_GAINSHIFT__PRE                                        0x3
+
+#define VSB_TOP_BEAGC_REGINIT__A                                            0x1C1004F
+#define VSB_TOP_BEAGC_REGINIT__W                                            15
+#define VSB_TOP_BEAGC_REGINIT__M                                            0x7FFF
+#define VSB_TOP_BEAGC_REGINIT__PRE                                          0x40
+
+#define   VSB_TOP_BEAGC_REGINIT_BEAGC_RST__B                                14
+#define   VSB_TOP_BEAGC_REGINIT_BEAGC_RST__W                                1
+#define   VSB_TOP_BEAGC_REGINIT_BEAGC_RST__M                                0x4000
+#define   VSB_TOP_BEAGC_REGINIT_BEAGC_RST__PRE                              0x0
+
+#define VSB_TOP_BEAGC_SCALE__A                                              0x1C10050
+#define VSB_TOP_BEAGC_SCALE__W                                              14
+#define VSB_TOP_BEAGC_SCALE__M                                              0x3FFF
+#define VSB_TOP_BEAGC_SCALE__PRE                                            0x0
+
+#define VSB_TOP_CFAGC_DEADZONEINIT__A                                       0x1C10051
+#define VSB_TOP_CFAGC_DEADZONEINIT__W                                       8
+#define VSB_TOP_CFAGC_DEADZONEINIT__M                                       0xFF
+#define VSB_TOP_CFAGC_DEADZONEINIT__PRE                                     0x50
+
+#define VSB_TOP_CFAGC_REFLEVEL__A                                           0x1C10052
+#define VSB_TOP_CFAGC_REFLEVEL__W                                           9
+#define VSB_TOP_CFAGC_REFLEVEL__M                                           0x1FF
+#define VSB_TOP_CFAGC_REFLEVEL__PRE                                         0xAE
+
+#define VSB_TOP_CFAGC_GAINSHIFT__A                                          0x1C10053
+#define VSB_TOP_CFAGC_GAINSHIFT__W                                          3
+#define VSB_TOP_CFAGC_GAINSHIFT__M                                          0x7
+#define VSB_TOP_CFAGC_GAINSHIFT__PRE                                        0x3
+
+#define VSB_TOP_CFAGC_REGINIT__A                                            0x1C10054
+#define VSB_TOP_CFAGC_REGINIT__W                                            15
+#define VSB_TOP_CFAGC_REGINIT__M                                            0x7FFF
+#define VSB_TOP_CFAGC_REGINIT__PRE                                          0x80
+
+#define   VSB_TOP_CFAGC_REGINIT_CFAGC_RST__B                                14
+#define   VSB_TOP_CFAGC_REGINIT_CFAGC_RST__W                                1
+#define   VSB_TOP_CFAGC_REGINIT_CFAGC_RST__M                                0x4000
+#define   VSB_TOP_CFAGC_REGINIT_CFAGC_RST__PRE                              0x0
+
+#define VSB_TOP_CFAGC_SCALE__A                                              0x1C10055
+#define VSB_TOP_CFAGC_SCALE__W                                              14
+#define VSB_TOP_CFAGC_SCALE__M                                              0x3FFF
+#define VSB_TOP_CFAGC_SCALE__PRE                                            0x0
+
+#define VSB_TOP_CKTRKONCTL__A                                               0x1C10056
+#define VSB_TOP_CKTRKONCTL__W                                               2
+#define VSB_TOP_CKTRKONCTL__M                                               0x3
+#define VSB_TOP_CKTRKONCTL__PRE                                             0x0
+
+#define VSB_TOP_CYTRKONCTL__A                                               0x1C10057
+#define VSB_TOP_CYTRKONCTL__W                                               2
+#define VSB_TOP_CYTRKONCTL__M                                               0x3
+#define VSB_TOP_CYTRKONCTL__PRE                                             0x0
+
+#define VSB_TOP_PTONCTL__A                                                  0x1C10058
+#define VSB_TOP_PTONCTL__W                                                  2
+#define VSB_TOP_PTONCTL__M                                                  0x3
+#define VSB_TOP_PTONCTL__PRE                                                0x0
+
+#define VSB_TOP_NOTCH_SCALE_1__A                                            0x1C10059
+#define VSB_TOP_NOTCH_SCALE_1__W                                            8
+#define VSB_TOP_NOTCH_SCALE_1__M                                            0xFF
+#define VSB_TOP_NOTCH_SCALE_1__PRE                                          0xA
+
+#define VSB_TOP_NOTCH_SCALE_2__A                                            0x1C1005A
+#define VSB_TOP_NOTCH_SCALE_2__W                                            8
+#define VSB_TOP_NOTCH_SCALE_2__M                                            0xFF
+#define VSB_TOP_NOTCH_SCALE_2__PRE                                          0xA
+
+#define VSB_TOP_FIRSTLARGFFETAP__A                                          0x1C1005B
+#define VSB_TOP_FIRSTLARGFFETAP__W                                          12
+#define VSB_TOP_FIRSTLARGFFETAP__M                                          0xFFF
+#define VSB_TOP_FIRSTLARGFFETAP__PRE                                        0x0
+
+#define VSB_TOP_FIRSTLARGFFETAPADDR__A                                      0x1C1005C
+#define VSB_TOP_FIRSTLARGFFETAPADDR__W                                      11
+#define VSB_TOP_FIRSTLARGFFETAPADDR__M                                      0x7FF
+#define VSB_TOP_FIRSTLARGFFETAPADDR__PRE                                    0x0
+
+#define VSB_TOP_SECONDLARGFFETAP__A                                         0x1C1005D
+#define VSB_TOP_SECONDLARGFFETAP__W                                         12
+#define VSB_TOP_SECONDLARGFFETAP__M                                         0xFFF
+#define VSB_TOP_SECONDLARGFFETAP__PRE                                       0x0
+
+#define VSB_TOP_SECONDLARGFFETAPADDR__A                                     0x1C1005E
+#define VSB_TOP_SECONDLARGFFETAPADDR__W                                     11
+#define VSB_TOP_SECONDLARGFFETAPADDR__M                                     0x7FF
+#define VSB_TOP_SECONDLARGFFETAPADDR__PRE                                   0x0
+
+#define VSB_TOP_FIRSTLARGDFETAP__A                                          0x1C1005F
+#define VSB_TOP_FIRSTLARGDFETAP__W                                          12
+#define VSB_TOP_FIRSTLARGDFETAP__M                                          0xFFF
+#define VSB_TOP_FIRSTLARGDFETAP__PRE                                        0x0
+
+#define VSB_TOP_FIRSTLARGDFETAPADDR__A                                      0x1C10060
+#define VSB_TOP_FIRSTLARGDFETAPADDR__W                                      11
+#define VSB_TOP_FIRSTLARGDFETAPADDR__M                                      0x7FF
+#define VSB_TOP_FIRSTLARGDFETAPADDR__PRE                                    0x0
+
+#define VSB_TOP_SECONDLARGDFETAP__A                                         0x1C10061
+#define VSB_TOP_SECONDLARGDFETAP__W                                         12
+#define VSB_TOP_SECONDLARGDFETAP__M                                         0xFFF
+#define VSB_TOP_SECONDLARGDFETAP__PRE                                       0x0
+
+#define VSB_TOP_SECONDLARGDFETAPADDR__A                                     0x1C10062
+#define VSB_TOP_SECONDLARGDFETAPADDR__W                                     11
+#define VSB_TOP_SECONDLARGDFETAPADDR__M                                     0x7FF
+#define VSB_TOP_SECONDLARGDFETAPADDR__PRE                                   0x0
+
+#define VSB_TOP_PARAOWDBUS__A                                               0x1C10063
+#define VSB_TOP_PARAOWDBUS__W                                               12
+#define VSB_TOP_PARAOWDBUS__M                                               0xFFF
+#define VSB_TOP_PARAOWDBUS__PRE                                             0x0
+#define VSB_TOP_PARAOWCTRL__A                                               0x1C10064
+#define VSB_TOP_PARAOWCTRL__W                                               7
+#define VSB_TOP_PARAOWCTRL__M                                               0x7F
+#define VSB_TOP_PARAOWCTRL__PRE                                             0x0
+
+#define   VSB_TOP_PARAOWCTRL_PARAOWABUS__B                                  0
+#define   VSB_TOP_PARAOWCTRL_PARAOWABUS__W                                  6
+#define   VSB_TOP_PARAOWCTRL_PARAOWABUS__M                                  0x3F
+#define   VSB_TOP_PARAOWCTRL_PARAOWABUS__PRE                                0x0
+
+#define   VSB_TOP_PARAOWCTRL_PARAOWEN__B                                    6
+#define   VSB_TOP_PARAOWCTRL_PARAOWEN__W                                    1
+#define   VSB_TOP_PARAOWCTRL_PARAOWEN__M                                    0x40
+#define   VSB_TOP_PARAOWCTRL_PARAOWEN__PRE                                  0x0
+
+#define VSB_TOP_CURRENTSEGLOCAT__A                                          0x1C10065
+#define VSB_TOP_CURRENTSEGLOCAT__W                                          10
+#define VSB_TOP_CURRENTSEGLOCAT__M                                          0x3FF
+#define VSB_TOP_CURRENTSEGLOCAT__PRE                                        0x0
+
+#define VSB_TOP_MEASUREMENT_PERIOD__A                                       0x1C10066
+#define VSB_TOP_MEASUREMENT_PERIOD__W                                       16
+#define VSB_TOP_MEASUREMENT_PERIOD__M                                       0xFFFF
+#define VSB_TOP_MEASUREMENT_PERIOD__PRE                                     0x0
+
+#define VSB_TOP_NR_SYM_ERRS__A                                              0x1C10067
+#define VSB_TOP_NR_SYM_ERRS__W                                              16
+#define VSB_TOP_NR_SYM_ERRS__M                                              0xFFFF
+#define VSB_TOP_NR_SYM_ERRS__PRE                                            0xFFFF
+
+#define VSB_TOP_ERR_ENERGY_L__A                                             0x1C10068
+#define VSB_TOP_ERR_ENERGY_L__W                                             16
+#define VSB_TOP_ERR_ENERGY_L__M                                             0xFFFF
+#define VSB_TOP_ERR_ENERGY_L__PRE                                           0xFFFF
+
+#define VSB_TOP_ERR_ENERGY_H__A                                             0x1C10069
+#define VSB_TOP_ERR_ENERGY_H__W                                             16
+#define VSB_TOP_ERR_ENERGY_H__M                                             0xFFFF
+#define VSB_TOP_ERR_ENERGY_H__PRE                                           0xFFFF
+
+#define VSB_TOP_SLICER_SEL_8LEV__A                                          0x1C1006A
+#define VSB_TOP_SLICER_SEL_8LEV__W                                          1
+#define VSB_TOP_SLICER_SEL_8LEV__M                                          0x1
+#define VSB_TOP_SLICER_SEL_8LEV__PRE                                        0x1
+
+#define VSB_TOP_BNFIELD__A                                                  0x1C1006B
+#define VSB_TOP_BNFIELD__W                                                  3
+#define VSB_TOP_BNFIELD__M                                                  0x7
+#define VSB_TOP_BNFIELD__PRE                                                0x3
+
+#define VSB_TOP_CLPLASTNUM__A                                               0x1C1006C
+#define VSB_TOP_CLPLASTNUM__W                                               8
+#define VSB_TOP_CLPLASTNUM__M                                               0xFF
+#define VSB_TOP_CLPLASTNUM__PRE                                             0x0
+
+#define VSB_TOP_BNSQERR__A                                                  0x1C1006D
+#define VSB_TOP_BNSQERR__W                                                  16
+#define VSB_TOP_BNSQERR__M                                                  0xFFFF
+#define VSB_TOP_BNSQERR__PRE                                                0x1AD
+
+#define VSB_TOP_BNTHRESH__A                                                 0x1C1006E
+#define VSB_TOP_BNTHRESH__W                                                 9
+#define VSB_TOP_BNTHRESH__M                                                 0x1FF
+#define VSB_TOP_BNTHRESH__PRE                                               0x120
+
+#define VSB_TOP_BNCLPNUM__A                                                 0x1C1006F
+#define VSB_TOP_BNCLPNUM__W                                                 16
+#define VSB_TOP_BNCLPNUM__M                                                 0xFFFF
+#define VSB_TOP_BNCLPNUM__PRE                                               0x0
+#define VSB_TOP_PHASELOCKCTRL__A                                            0x1C10070
+#define VSB_TOP_PHASELOCKCTRL__W                                            7
+#define VSB_TOP_PHASELOCKCTRL__M                                            0x7F
+#define VSB_TOP_PHASELOCKCTRL__PRE                                          0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPOLARITY__B                           0
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPOLARITY__W                           1
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPOLARITY__M                           0x1
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPOLARITY__PRE                         0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPLL__B                                1
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPLL__W                                1
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPLL__M                                0x2
+#define   VSB_TOP_PHASELOCKCTRL_DFORCEPLL__PRE                              0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPOLARITY__B                           2
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPOLARITY__W                           1
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPOLARITY__M                           0x4
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPOLARITY__PRE                         0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPLL__B                                3
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPLL__W                                1
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPLL__M                                0x8
+#define   VSB_TOP_PHASELOCKCTRL_PFORCEPLL__PRE                              0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPOLARITY__B                           4
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPOLARITY__W                           1
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPOLARITY__M                           0x10
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPOLARITY__PRE                         0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPLL__B                                5
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPLL__W                                1
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPLL__M                                0x20
+#define   VSB_TOP_PHASELOCKCTRL_CFORCEPLL__PRE                              0x0
+
+#define   VSB_TOP_PHASELOCKCTRL_IQSWITCH__B                                 6
+#define   VSB_TOP_PHASELOCKCTRL_IQSWITCH__W                                 1
+#define   VSB_TOP_PHASELOCKCTRL_IQSWITCH__M                                 0x40
+#define   VSB_TOP_PHASELOCKCTRL_IQSWITCH__PRE                               0x0
+
+#define VSB_TOP_DLOCKACCUM__A                                               0x1C10071
+#define VSB_TOP_DLOCKACCUM__W                                               16
+#define VSB_TOP_DLOCKACCUM__M                                               0xFFFF
+#define VSB_TOP_DLOCKACCUM__PRE                                             0x0
+
+#define VSB_TOP_PLOCKACCUM__A                                               0x1C10072
+#define VSB_TOP_PLOCKACCUM__W                                               16
+#define VSB_TOP_PLOCKACCUM__M                                               0xFFFF
+#define VSB_TOP_PLOCKACCUM__PRE                                             0x0
+
+#define VSB_TOP_CLOCKACCUM__A                                               0x1C10073
+#define VSB_TOP_CLOCKACCUM__W                                               16
+#define VSB_TOP_CLOCKACCUM__M                                               0xFFFF
+#define VSB_TOP_CLOCKACCUM__PRE                                             0x0
+
+#define VSB_TOP_DCRMVACUMI__A                                               0x1C10074
+#define VSB_TOP_DCRMVACUMI__W                                               10
+#define VSB_TOP_DCRMVACUMI__M                                               0x3FF
+#define VSB_TOP_DCRMVACUMI__PRE                                             0x0
+
+#define VSB_TOP_DCRMVACUMQ__A                                               0x1C10075
+#define VSB_TOP_DCRMVACUMQ__W                                               10
+#define VSB_TOP_DCRMVACUMQ__M                                               0x3FF
+#define VSB_TOP_DCRMVACUMQ__PRE                                             0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A                                0x1C20000
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO2__A                                0x1C20001
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO2__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO2__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO2__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO3__A                                0x1C20002
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO3__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO3__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO3__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO4__A                                0x1C20003
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO4__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO4__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO4__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO5__A                                0x1C20004
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO5__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO5__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO5__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO6__A                                0x1C20005
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO6__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO6__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO6__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO7__A                                0x1C20006
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO7__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO7__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO7__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO8__A                                0x1C20007
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO8__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO8__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO8__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO9__A                                0x1C20008
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO9__W                                12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO9__M                                0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO9__PRE                              0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO10__A                               0x1C20009
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO10__W                               12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO10__M                               0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO10__PRE                             0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO11__A                               0x1C2000A
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO11__W                               12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO11__M                               0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO11__PRE                             0x0
+
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO12__A                               0x1C2000B
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO12__W                               12
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO12__M                               0xFFF
+#define VSB_SYSCTRL_RAM0_FFETRAINLKRATIO12__PRE                             0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO1__A                            0x1C2000C
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO1__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO1__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO1__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO2__A                            0x1C2000D
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO2__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO2__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO2__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO3__A                            0x1C2000E
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO3__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO3__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO3__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO4__A                            0x1C2000F
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO4__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO4__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO4__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO5__A                            0x1C20010
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO5__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO5__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO5__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO6__A                            0x1C20011
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO6__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO6__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO6__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO7__A                            0x1C20012
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO7__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO7__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO7__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO8__A                            0x1C20013
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO8__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO8__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO8__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO9__A                            0x1C20014
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO9__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO9__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO9__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO10__A                           0x1C20015
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO10__W                           12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO10__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO10__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO11__A                           0x1C20016
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO11__W                           12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO11__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO11__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO12__A                           0x1C20017
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO12__W                           12
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO12__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1TRAINLKRATIO12__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO1__A                             0x1C20018
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO1__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO1__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO1__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO2__A                             0x1C20019
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO2__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO2__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO2__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO3__A                             0x1C2001A
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO3__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO3__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO3__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO4__A                             0x1C2001B
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO4__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO4__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO4__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO5__A                             0x1C2001C
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO5__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO5__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO5__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO6__A                             0x1C2001D
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO6__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO6__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO6__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO7__A                             0x1C2001E
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO7__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO7__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO7__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO8__A                             0x1C2001F
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO8__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO8__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO8__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO9__A                             0x1C20020
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO9__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO9__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO9__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO10__A                            0x1C20021
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO10__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO10__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO10__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO11__A                            0x1C20022
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO11__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO11__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO11__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO12__A                            0x1C20023
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO12__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO12__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA1DATALKRATIO12__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO1__A                            0x1C20024
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO1__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO1__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO1__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO2__A                            0x1C20025
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO2__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO2__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO2__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO3__A                            0x1C20026
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO3__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO3__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO3__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO4__A                            0x1C20027
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO4__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO4__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO4__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO5__A                            0x1C20028
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO5__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO5__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO5__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO6__A                            0x1C20029
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO6__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO6__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO6__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO7__A                            0x1C2002A
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO7__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO7__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO7__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO8__A                            0x1C2002B
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO8__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO8__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO8__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO9__A                            0x1C2002C
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO9__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO9__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO9__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO10__A                           0x1C2002D
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO10__W                           12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO10__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO10__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO11__A                           0x1C2002E
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO11__W                           12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO11__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO11__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO12__A                           0x1C2002F
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO12__W                           12
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO12__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2TRAINLKRATIO12__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO1__A                             0x1C20030
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO1__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO1__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO1__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO2__A                             0x1C20031
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO2__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO2__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO2__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO3__A                             0x1C20032
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO3__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO3__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO3__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO4__A                             0x1C20033
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO4__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO4__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO4__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO5__A                             0x1C20034
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO5__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO5__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO5__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO6__A                             0x1C20035
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO6__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO6__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO6__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO7__A                             0x1C20036
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO7__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO7__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO7__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO8__A                             0x1C20037
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO8__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO8__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO8__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO9__A                             0x1C20038
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO9__W                             12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO9__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO9__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO10__A                            0x1C20039
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO10__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO10__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO10__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO11__A                            0x1C2003A
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO11__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO11__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO11__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO12__A                            0x1C2003B
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO12__W                            12
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO12__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFERCA2DATALKRATIO12__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO1__A                            0x1C2003C
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO1__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO1__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO1__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO2__A                            0x1C2003D
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO2__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO2__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO2__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO3__A                            0x1C2003E
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO3__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO3__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO3__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO4__A                            0x1C2003F
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO4__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO4__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO4__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO5__A                            0x1C20040
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO5__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO5__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO5__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO6__A                            0x1C20041
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO6__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO6__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO6__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO7__A                            0x1C20042
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO7__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO7__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO7__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO8__A                            0x1C20043
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO8__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO8__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO8__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO9__A                            0x1C20044
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO9__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO9__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO9__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO10__A                           0x1C20045
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO10__W                           12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO10__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO10__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO11__A                           0x1C20046
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO11__W                           12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO11__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO11__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO12__A                           0x1C20047
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO12__W                           12
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO12__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1TRAINLKRATIO12__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO1__A                             0x1C20048
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO1__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO1__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO1__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO2__A                             0x1C20049
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO2__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO2__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO2__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO3__A                             0x1C2004A
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO3__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO3__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO3__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO4__A                             0x1C2004B
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO4__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO4__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO4__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO5__A                             0x1C2004C
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO5__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO5__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO5__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO6__A                             0x1C2004D
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO6__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO6__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO6__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO7__A                             0x1C2004E
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO7__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO7__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO7__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO8__A                             0x1C2004F
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO8__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO8__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO8__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO9__A                             0x1C20050
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO9__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO9__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO9__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO10__A                            0x1C20051
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO10__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO10__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO10__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO11__A                            0x1C20052
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO11__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO11__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO11__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO12__A                            0x1C20053
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO12__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO12__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM1DATALKRATIO12__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO1__A                            0x1C20054
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO1__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO1__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO1__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO2__A                            0x1C20055
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO2__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO2__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO2__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO3__A                            0x1C20056
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO3__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO3__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO3__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO4__A                            0x1C20057
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO4__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO4__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO4__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO5__A                            0x1C20058
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO5__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO5__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO5__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO6__A                            0x1C20059
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO6__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO6__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO6__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO7__A                            0x1C2005A
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO7__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO7__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO7__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO8__A                            0x1C2005B
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO8__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO8__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO8__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO9__A                            0x1C2005C
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO9__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO9__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO9__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO10__A                           0x1C2005D
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO10__W                           12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO10__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO10__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO11__A                           0x1C2005E
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO11__W                           12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO11__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO11__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO12__A                           0x1C2005F
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO12__W                           12
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO12__M                           0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2TRAINLKRATIO12__PRE                         0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO1__A                             0x1C20060
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO1__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO1__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO1__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO2__A                             0x1C20061
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO2__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO2__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO2__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO3__A                             0x1C20062
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO3__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO3__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO3__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO4__A                             0x1C20063
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO4__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO4__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO4__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO5__A                             0x1C20064
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO5__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO5__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO5__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO6__A                             0x1C20065
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO6__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO6__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO6__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO7__A                             0x1C20066
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO7__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO7__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO7__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO8__A                             0x1C20067
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO8__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO8__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO8__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO9__A                             0x1C20068
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO9__W                             12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO9__M                             0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO9__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO10__A                            0x1C20069
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO10__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO10__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO10__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO11__A                            0x1C2006A
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO11__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO11__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO11__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO12__A                            0x1C2006B
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO12__W                            12
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO12__M                            0xFFF
+#define VSB_SYSCTRL_RAM0_FFEDDM2DATALKRATIO12__PRE                          0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN1__A                                   0x1C2006C
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN1__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN1__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN1__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN2__A                                   0x1C2006D
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN2__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN2__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN2__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN3__A                                   0x1C2006E
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN3__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN3__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN3__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN4__A                                   0x1C2006F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN4__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN4__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN4__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN5__A                                   0x1C20070
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN5__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN5__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN5__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN6__A                                   0x1C20071
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN6__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN6__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN6__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN7__A                                   0x1C20072
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN7__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN7__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN7__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN8__A                                   0x1C20073
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN8__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN8__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN8__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN9__A                                   0x1C20074
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN9__W                                   7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN9__M                                   0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN9__PRE                                 0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN10__A                                  0x1C20075
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN10__W                                  7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN10__M                                  0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN10__PRE                                0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN11__A                                  0x1C20076
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN11__W                                  7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN11__M                                  0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN11__PRE                                0x0
+
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN12__A                                  0x1C20077
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN12__W                                  7
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN12__M                                  0x7F
+#define VSB_SYSCTRL_RAM0_FIRTRAINGAIN12__PRE                                0x0
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN1__A                                    0x1C20078
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN1__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN1__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN1__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1TRAINGAIN1__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1TRAINGAIN1__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1TRAINGAIN1__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1TRAINGAIN1__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1DATAGAIN1__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1DATAGAIN1__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1DATAGAIN1__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN1_FIRRCA1DATAGAIN1__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN2__A                                    0x1C20079
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN2__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN2__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN2__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1TRAINGAIN2__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1TRAINGAIN2__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1TRAINGAIN2__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1TRAINGAIN2__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1DATAGAIN2__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1DATAGAIN2__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1DATAGAIN2__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN2_FIRRCA1DATAGAIN2__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN3__A                                    0x1C2007A
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN3__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN3__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN3__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1TRAINGAIN3__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1TRAINGAIN3__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1TRAINGAIN3__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1TRAINGAIN3__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1DATAGAIN3__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1DATAGAIN3__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1DATAGAIN3__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN3_FIRRCA1DATAGAIN3__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN4__A                                    0x1C2007B
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN4__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN4__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN4__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1TRAINGAIN4__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1TRAINGAIN4__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1TRAINGAIN4__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1TRAINGAIN4__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1DATAGAIN4__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1DATAGAIN4__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1DATAGAIN4__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN4_FIRRCA1DATAGAIN4__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN5__A                                    0x1C2007C
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN5__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN5__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN5__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1TRAINGAIN5__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1TRAINGAIN5__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1TRAINGAIN5__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1TRAINGAIN5__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1DATAGAIN5__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1DATAGAIN5__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1DATAGAIN5__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN5_FIRRCA1DATAGAIN5__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN6__A                                    0x1C2007D
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN6__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN6__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN6__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1TRAINGAIN6__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1TRAINGAIN6__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1TRAINGAIN6__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1TRAINGAIN6__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1DATAGAIN6__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1DATAGAIN6__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1DATAGAIN6__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN6_FIRRCA1DATAGAIN6__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN7__A                                    0x1C2007E
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN7__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN7__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN7__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1TRAINGAIN7__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1TRAINGAIN7__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1TRAINGAIN7__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1TRAINGAIN7__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1DATAGAIN7__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1DATAGAIN7__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1DATAGAIN7__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN7_FIRRCA1DATAGAIN7__PRE               0x0
+
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN8__A                                    0x1C2007F
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN8__W                                    15
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN8__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM0_FIRRCA1GAIN8__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1TRAINGAIN8__B                0
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1TRAINGAIN8__W                7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1TRAINGAIN8__M                0x7F
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1TRAINGAIN8__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1DATAGAIN8__B                 8
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1DATAGAIN8__W                 7
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1DATAGAIN8__M                 0x7F00
+#define   VSB_SYSCTRL_RAM0_FIRRCA1GAIN8_FIRRCA1DATAGAIN8__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A                                    0x1C30000
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1TRAINGAIN9__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1TRAINGAIN9__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1TRAINGAIN9__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1TRAINGAIN9__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1DATAGAIN9__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1DATAGAIN9__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1DATAGAIN9__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN9_FIRRCA1DATAGAIN9__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN10__A                                   0x1C30001
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN10__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN10__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN10__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1TRAINGAIN10__B              0
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1TRAINGAIN10__W              7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1TRAINGAIN10__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1TRAINGAIN10__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1DATAGAIN10__B               8
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1DATAGAIN10__W               7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1DATAGAIN10__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN10_FIRRCA1DATAGAIN10__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN11__A                                   0x1C30002
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN11__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN11__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN11__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1TRAINGAIN11__B              0
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1TRAINGAIN11__W              7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1TRAINGAIN11__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1TRAINGAIN11__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1DATAGAIN11__B               8
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1DATAGAIN11__W               7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1DATAGAIN11__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN11_FIRRCA1DATAGAIN11__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN12__A                                   0x1C30003
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN12__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN12__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA1GAIN12__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1TRAINGAIN12__B              0
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1TRAINGAIN12__W              7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1TRAINGAIN12__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1TRAINGAIN12__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1DATAGAIN12__B               8
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1DATAGAIN12__W               7
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1DATAGAIN12__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA1GAIN12_FIRRCA1DATAGAIN12__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN1__A                                    0x1C30004
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN1__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN1__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN1__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2TRAINGAIN1__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2TRAINGAIN1__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2TRAINGAIN1__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2TRAINGAIN1__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2DATAGAIN1__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2DATAGAIN1__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2DATAGAIN1__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN1_FIRRCA2DATAGAIN1__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN2__A                                    0x1C30005
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN2__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN2__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN2__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2TRAINGAIN2__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2TRAINGAIN2__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2TRAINGAIN2__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2TRAINGAIN2__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2DATAGAIN2__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2DATAGAIN2__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2DATAGAIN2__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN2_FIRRCA2DATAGAIN2__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN3__A                                    0x1C30006
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN3__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN3__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN3__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2TRAINGAIN3__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2TRAINGAIN3__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2TRAINGAIN3__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2TRAINGAIN3__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2DATAGAIN3__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2DATAGAIN3__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2DATAGAIN3__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN3_FIRRCA2DATAGAIN3__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN4__A                                    0x1C30007
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN4__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN4__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN4__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2TRAINGAIN4__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2TRAINGAIN4__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2TRAINGAIN4__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2TRAINGAIN4__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2DATAGAIN4__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2DATAGAIN4__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2DATAGAIN4__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN4_FIRRCA2DATAGAIN4__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN5__A                                    0x1C30008
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN5__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN5__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN5__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2TRAINGAIN5__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2TRAINGAIN5__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2TRAINGAIN5__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2TRAINGAIN5__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2DATAGAIN5__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2DATAGAIN5__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2DATAGAIN5__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN5_FIRRCA2DATAGAIN5__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN6__A                                    0x1C30009
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN6__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN6__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN6__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2TRAINGAIN6__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2TRAINGAIN6__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2TRAINGAIN6__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2TRAINGAIN6__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2DATAGAIN6__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2DATAGAIN6__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2DATAGAIN6__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN6_FIRRCA2DATAGAIN6__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN7__A                                    0x1C3000A
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN7__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN7__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN7__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2TRAINGAIN7__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2TRAINGAIN7__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2TRAINGAIN7__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2TRAINGAIN7__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2DATAGAIN7__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2DATAGAIN7__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2DATAGAIN7__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN7_FIRRCA2DATAGAIN7__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN8__A                                    0x1C3000B
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN8__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN8__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN8__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2TRAINGAIN8__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2TRAINGAIN8__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2TRAINGAIN8__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2TRAINGAIN8__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2DATAGAIN8__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2DATAGAIN8__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2DATAGAIN8__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN8_FIRRCA2DATAGAIN8__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN9__A                                    0x1C3000C
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN9__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN9__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN9__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2TRAINGAIN9__B                0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2TRAINGAIN9__W                7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2TRAINGAIN9__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2TRAINGAIN9__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2DATAGAIN9__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2DATAGAIN9__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2DATAGAIN9__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN9_FIRRCA2DATAGAIN9__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN10__A                                   0x1C3000D
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN10__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN10__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN10__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2TRAINGAIN10__B              0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2TRAINGAIN10__W              7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2TRAINGAIN10__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2TRAINGAIN10__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2DATAGAIN10__B               8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2DATAGAIN10__W               7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2DATAGAIN10__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN10_FIRRCA2DATAGAIN10__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN11__A                                   0x1C3000E
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN11__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN11__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN11__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2TRAINGAIN11__B              0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2TRAINGAIN11__W              7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2TRAINGAIN11__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2TRAINGAIN11__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2DATAGAIN11__B               8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2DATAGAIN11__W               7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2DATAGAIN11__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN11_FIRRCA2DATAGAIN11__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN12__A                                   0x1C3000F
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN12__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN12__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRRCA2GAIN12__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2TRAINGAIN12__B              0
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2TRAINGAIN12__W              7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2TRAINGAIN12__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2TRAINGAIN12__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2DATAGAIN12__B               8
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2DATAGAIN12__W               7
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2DATAGAIN12__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRRCA2GAIN12_FIRRCA2DATAGAIN12__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN1__A                                    0x1C30010
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN1__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN1__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN1__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1TRAINGAIN1__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1TRAINGAIN1__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1TRAINGAIN1__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1TRAINGAIN1__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1DATAGAIN1__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1DATAGAIN1__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1DATAGAIN1__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN1_FIRDDM1DATAGAIN1__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN2__A                                    0x1C30011
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN2__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN2__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN2__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1TRAINGAIN2__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1TRAINGAIN2__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1TRAINGAIN2__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1TRAINGAIN2__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1DATAGAIN2__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1DATAGAIN2__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1DATAGAIN2__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN2_FIRDDM1DATAGAIN2__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN3__A                                    0x1C30012
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN3__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN3__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN3__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1TRAINGAIN3__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1TRAINGAIN3__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1TRAINGAIN3__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1TRAINGAIN3__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1DATAGAIN3__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1DATAGAIN3__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1DATAGAIN3__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN3_FIRDDM1DATAGAIN3__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN4__A                                    0x1C30013
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN4__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN4__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN4__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1TRAINGAIN4__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1TRAINGAIN4__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1TRAINGAIN4__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1TRAINGAIN4__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1DATAGAIN4__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1DATAGAIN4__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1DATAGAIN4__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN4_FIRDDM1DATAGAIN4__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN5__A                                    0x1C30014
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN5__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN5__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN5__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1TRAINGAIN5__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1TRAINGAIN5__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1TRAINGAIN5__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1TRAINGAIN5__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1DATAGAIN5__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1DATAGAIN5__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1DATAGAIN5__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN5_FIRDDM1DATAGAIN5__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN6__A                                    0x1C30015
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN6__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN6__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN6__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1TRAINGAIN6__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1TRAINGAIN6__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1TRAINGAIN6__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1TRAINGAIN6__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1DATAGAIN6__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1DATAGAIN6__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1DATAGAIN6__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN6_FIRDDM1DATAGAIN6__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN7__A                                    0x1C30016
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN7__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN7__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN7__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1TRAINGAIN7__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1TRAINGAIN7__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1TRAINGAIN7__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1TRAINGAIN7__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1DATAGAIN7__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1DATAGAIN7__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1DATAGAIN7__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN7_FIRDDM1DATAGAIN7__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN8__A                                    0x1C30017
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN8__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN8__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN8__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1TRAINGAIN8__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1TRAINGAIN8__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1TRAINGAIN8__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1TRAINGAIN8__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1DATAGAIN8__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1DATAGAIN8__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1DATAGAIN8__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN8_FIRDDM1DATAGAIN8__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN9__A                                    0x1C30018
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN9__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN9__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN9__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1TRAINGAIN9__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1TRAINGAIN9__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1TRAINGAIN9__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1TRAINGAIN9__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1DATAGAIN9__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1DATAGAIN9__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1DATAGAIN9__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN9_FIRDDM1DATAGAIN9__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN10__A                                   0x1C30019
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN10__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN10__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN10__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1TRAINGAIN10__B              0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1TRAINGAIN10__W              7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1TRAINGAIN10__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1TRAINGAIN10__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1DATAGAIN10__B               8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1DATAGAIN10__W               7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1DATAGAIN10__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN10_FIRDDM1DATAGAIN10__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN11__A                                   0x1C3001A
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN11__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN11__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN11__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1TRAINGAIN11__B              0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1TRAINGAIN11__W              7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1TRAINGAIN11__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1TRAINGAIN11__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1DATAGAIN11__B               8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1DATAGAIN11__W               7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1DATAGAIN11__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN11_FIRDDM1DATAGAIN11__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN12__A                                   0x1C3001B
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN12__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN12__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM1GAIN12__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1TRAINGAIN12__B              0
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1TRAINGAIN12__W              7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1TRAINGAIN12__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1TRAINGAIN12__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1DATAGAIN12__B               8
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1DATAGAIN12__W               7
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1DATAGAIN12__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM1GAIN12_FIRDDM1DATAGAIN12__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN1__A                                    0x1C3001C
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN1__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN1__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN1__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2TRAINGAIN1__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2TRAINGAIN1__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2TRAINGAIN1__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2TRAINGAIN1__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2DATAGAIN1__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2DATAGAIN1__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2DATAGAIN1__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN1_FIRDDM2DATAGAIN1__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN2__A                                    0x1C3001D
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN2__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN2__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN2__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2TRAINGAIN2__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2TRAINGAIN2__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2TRAINGAIN2__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2TRAINGAIN2__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2DATAGAIN2__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2DATAGAIN2__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2DATAGAIN2__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN2_FIRDDM2DATAGAIN2__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN3__A                                    0x1C3001E
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN3__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN3__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN3__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2TRAINGAIN3__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2TRAINGAIN3__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2TRAINGAIN3__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2TRAINGAIN3__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2DATAGAIN3__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2DATAGAIN3__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2DATAGAIN3__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN3_FIRDDM2DATAGAIN3__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN4__A                                    0x1C3001F
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN4__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN4__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN4__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2TRAINGAIN4__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2TRAINGAIN4__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2TRAINGAIN4__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2TRAINGAIN4__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2DATAGAIN4__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2DATAGAIN4__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2DATAGAIN4__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN4_FIRDDM2DATAGAIN4__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN5__A                                    0x1C30020
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN5__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN5__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN5__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2TRAINGAIN5__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2TRAINGAIN5__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2TRAINGAIN5__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2TRAINGAIN5__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2DATAGAIN5__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2DATAGAIN5__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2DATAGAIN5__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN5_FIRDDM2DATAGAIN5__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN6__A                                    0x1C30021
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN6__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN6__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN6__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2TRAINGAIN6__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2TRAINGAIN6__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2TRAINGAIN6__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2TRAINGAIN6__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2DATAGAIN6__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2DATAGAIN6__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2DATAGAIN6__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN6_FIRDDM2DATAGAIN6__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN7__A                                    0x1C30022
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN7__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN7__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN7__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2TRAINGAIN7__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2TRAINGAIN7__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2TRAINGAIN7__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2TRAINGAIN7__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2DATAGAIN7__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2DATAGAIN7__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2DATAGAIN7__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN7_FIRDDM2DATAGAIN7__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN8__A                                    0x1C30023
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN8__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN8__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN8__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2TRAINGAIN8__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2TRAINGAIN8__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2TRAINGAIN8__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2TRAINGAIN8__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2DATAGAIN8__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2DATAGAIN8__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2DATAGAIN8__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN8_FIRDDM2DATAGAIN8__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN9__A                                    0x1C30024
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN9__W                                    15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN9__M                                    0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN9__PRE                                  0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2TRAINGAIN9__B                0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2TRAINGAIN9__W                7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2TRAINGAIN9__M                0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2TRAINGAIN9__PRE              0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2DATAGAIN9__B                 8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2DATAGAIN9__W                 7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2DATAGAIN9__M                 0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN9_FIRDDM2DATAGAIN9__PRE               0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN10__A                                   0x1C30025
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN10__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN10__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN10__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2TRAINGAIN10__B              0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2TRAINGAIN10__W              7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2TRAINGAIN10__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2TRAINGAIN10__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2DATAGAIN10__B               8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2DATAGAIN10__W               7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2DATAGAIN10__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN10_FIRDDM2DATAGAIN10__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN11__A                                   0x1C30026
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN11__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN11__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN11__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2TRAINGAIN11__B              0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2TRAINGAIN11__W              7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2TRAINGAIN11__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2TRAINGAIN11__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2DATAGAIN11__B               8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2DATAGAIN11__W               7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2DATAGAIN11__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN11_FIRDDM2DATAGAIN11__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN12__A                                   0x1C30027
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN12__W                                   15
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN12__M                                   0x7FFF
+#define VSB_SYSCTRL_RAM1_FIRDDM2GAIN12__PRE                                 0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2TRAINGAIN12__B              0
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2TRAINGAIN12__W              7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2TRAINGAIN12__M              0x7F
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2TRAINGAIN12__PRE            0x0
+
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2DATAGAIN12__B               8
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2DATAGAIN12__W               7
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2DATAGAIN12__M               0x7F00
+#define   VSB_SYSCTRL_RAM1_FIRDDM2GAIN12_FIRDDM2DATAGAIN12__PRE             0x0
+
+#define VSB_SYSCTRL_RAM1_DFETRAINLKRATIO__A                                 0x1C30028
+#define VSB_SYSCTRL_RAM1_DFETRAINLKRATIO__W                                 12
+#define VSB_SYSCTRL_RAM1_DFETRAINLKRATIO__M                                 0xFFF
+#define VSB_SYSCTRL_RAM1_DFETRAINLKRATIO__PRE                               0x0
+
+#define VSB_SYSCTRL_RAM1_DFERCA1TRAINLKRATIO__A                             0x1C30029
+#define VSB_SYSCTRL_RAM1_DFERCA1TRAINLKRATIO__W                             12
+#define VSB_SYSCTRL_RAM1_DFERCA1TRAINLKRATIO__M                             0xFFF
+#define VSB_SYSCTRL_RAM1_DFERCA1TRAINLKRATIO__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM1_DFERCA1DATALKRATIO__A                              0x1C3002A
+#define VSB_SYSCTRL_RAM1_DFERCA1DATALKRATIO__W                              12
+#define VSB_SYSCTRL_RAM1_DFERCA1DATALKRATIO__M                              0xFFF
+#define VSB_SYSCTRL_RAM1_DFERCA1DATALKRATIO__PRE                            0x0
+
+#define VSB_SYSCTRL_RAM1_DFERCA2TRAINLKRATIO__A                             0x1C3002B
+#define VSB_SYSCTRL_RAM1_DFERCA2TRAINLKRATIO__W                             12
+#define VSB_SYSCTRL_RAM1_DFERCA2TRAINLKRATIO__M                             0xFFF
+#define VSB_SYSCTRL_RAM1_DFERCA2TRAINLKRATIO__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM1_DFERCA2DATALKRATIO__A                              0x1C3002C
+#define VSB_SYSCTRL_RAM1_DFERCA2DATALKRATIO__W                              12
+#define VSB_SYSCTRL_RAM1_DFERCA2DATALKRATIO__M                              0xFFF
+#define VSB_SYSCTRL_RAM1_DFERCA2DATALKRATIO__PRE                            0x0
+
+#define VSB_SYSCTRL_RAM1_DFEDDM1TRAINLKRATIO__A                             0x1C3002D
+#define VSB_SYSCTRL_RAM1_DFEDDM1TRAINLKRATIO__W                             12
+#define VSB_SYSCTRL_RAM1_DFEDDM1TRAINLKRATIO__M                             0xFFF
+#define VSB_SYSCTRL_RAM1_DFEDDM1TRAINLKRATIO__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM1_DFEDDM1DATALKRATIO__A                              0x1C3002E
+#define VSB_SYSCTRL_RAM1_DFEDDM1DATALKRATIO__W                              12
+#define VSB_SYSCTRL_RAM1_DFEDDM1DATALKRATIO__M                              0xFFF
+#define VSB_SYSCTRL_RAM1_DFEDDM1DATALKRATIO__PRE                            0x0
+
+#define VSB_SYSCTRL_RAM1_DFEDDM2TRAINLKRATIO__A                             0x1C3002F
+#define VSB_SYSCTRL_RAM1_DFEDDM2TRAINLKRATIO__W                             12
+#define VSB_SYSCTRL_RAM1_DFEDDM2TRAINLKRATIO__M                             0xFFF
+#define VSB_SYSCTRL_RAM1_DFEDDM2TRAINLKRATIO__PRE                           0x0
+
+#define VSB_SYSCTRL_RAM1_DFEDDM2DATALKRATIO__A                              0x1C30030
+#define VSB_SYSCTRL_RAM1_DFEDDM2DATALKRATIO__W                              12
+#define VSB_SYSCTRL_RAM1_DFEDDM2DATALKRATIO__M                              0xFFF
+#define VSB_SYSCTRL_RAM1_DFEDDM2DATALKRATIO__PRE                            0x0
+
+#define VSB_SYSCTRL_RAM1_DFETRAINGAIN__A                                    0x1C30031
+#define VSB_SYSCTRL_RAM1_DFETRAINGAIN__W                                    7
+#define VSB_SYSCTRL_RAM1_DFETRAINGAIN__M                                    0x7F
+#define VSB_SYSCTRL_RAM1_DFETRAINGAIN__PRE                                  0x0
+#define VSB_SYSCTRL_RAM1_DFERCA1GAIN__A                                     0x1C30032
+#define VSB_SYSCTRL_RAM1_DFERCA1GAIN__W                                     15
+#define VSB_SYSCTRL_RAM1_DFERCA1GAIN__M                                     0x7FFF
+#define VSB_SYSCTRL_RAM1_DFERCA1GAIN__PRE                                   0x0
+
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1TRAINGAIN__B                  0
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1TRAINGAIN__W                  7
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1TRAINGAIN__M                  0x7F
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1TRAINGAIN__PRE                0x0
+
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1DATAGAIN__B                   8
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1DATAGAIN__W                   7
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1DATAGAIN__M                   0x7F00
+#define   VSB_SYSCTRL_RAM1_DFERCA1GAIN_DFERCA1DATAGAIN__PRE                 0x0
+
+#define VSB_SYSCTRL_RAM1_DFERCA2GAIN__A                                     0x1C30033
+#define VSB_SYSCTRL_RAM1_DFERCA2GAIN__W                                     15
+#define VSB_SYSCTRL_RAM1_DFERCA2GAIN__M                                     0x7FFF
+#define VSB_SYSCTRL_RAM1_DFERCA2GAIN__PRE                                   0x0
+
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2TRAINGAIN__B                  0
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2TRAINGAIN__W                  7
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2TRAINGAIN__M                  0x7F
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2TRAINGAIN__PRE                0x0
+
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2DATAGAIN__B                   8
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2DATAGAIN__W                   7
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2DATAGAIN__M                   0x7F00
+#define   VSB_SYSCTRL_RAM1_DFERCA2GAIN_DFERCA2DATAGAIN__PRE                 0x0
+
+#define VSB_SYSCTRL_RAM1_DFEDDM1GAIN__A                                     0x1C30034
+#define VSB_SYSCTRL_RAM1_DFEDDM1GAIN__W                                     15
+#define VSB_SYSCTRL_RAM1_DFEDDM1GAIN__M                                     0x7FFF
+#define VSB_SYSCTRL_RAM1_DFEDDM1GAIN__PRE                                   0x0
+
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1TRAINGAIN__B                  0
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1TRAINGAIN__W                  7
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1TRAINGAIN__M                  0x7F
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1TRAINGAIN__PRE                0x0
+
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1DATAGAIN__B                   8
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1DATAGAIN__W                   7
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1DATAGAIN__M                   0x7F00
+#define   VSB_SYSCTRL_RAM1_DFEDDM1GAIN_DFEDDM1DATAGAIN__PRE                 0x0
+
+#define VSB_SYSCTRL_RAM1_DFEDDM2GAIN__A                                     0x1C30035
+#define VSB_SYSCTRL_RAM1_DFEDDM2GAIN__W                                     15
+#define VSB_SYSCTRL_RAM1_DFEDDM2GAIN__M                                     0x7FFF
+#define VSB_SYSCTRL_RAM1_DFEDDM2GAIN__PRE                                   0x0
+
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2TRAINGAIN__B                  0
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2TRAINGAIN__W                  7
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2TRAINGAIN__M                  0x7F
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2TRAINGAIN__PRE                0x0
+
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2DATAGAIN__B                   8
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2DATAGAIN__W                   7
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2DATAGAIN__M                   0x7F00
+#define   VSB_SYSCTRL_RAM1_DFEDDM2GAIN_DFEDDM2DATAGAIN__PRE                 0x0
+
+#define VSB_TCMEQ_RAM__A                                                    0x1C40000
+
+#define   VSB_TCMEQ_RAM_TCMEQ_RAM__B                                        0
+#define   VSB_TCMEQ_RAM_TCMEQ_RAM__W                                        16
+#define   VSB_TCMEQ_RAM_TCMEQ_RAM__M                                        0xFFFF
+#define   VSB_TCMEQ_RAM_TCMEQ_RAM__PRE                                      0x0
+
+#define VSB_FCPRE_RAM__A                                                    0x1C50000
+
+#define   VSB_FCPRE_RAM_FCPRE_RAM__B                                        0
+#define   VSB_FCPRE_RAM_FCPRE_RAM__W                                        16
+#define   VSB_FCPRE_RAM_FCPRE_RAM__M                                        0xFFFF
+#define   VSB_FCPRE_RAM_FCPRE_RAM__PRE                                      0x0
+
+#define VSB_EQTAP_RAM__A                                                    0x1C60000
+
+#define   VSB_EQTAP_RAM_EQTAP_RAM__B                                        0
+#define   VSB_EQTAP_RAM_EQTAP_RAM__W                                        12
+#define   VSB_EQTAP_RAM_EQTAP_RAM__M                                        0xFFF
+#define   VSB_EQTAP_RAM_EQTAP_RAM__PRE                                      0x0
+
+#endif
index 959ae36403b827263d6b028f919f2fe9fe2fa224..5b87ece69414fcdbfbc1bb967931e87d47fd13b8 100644 (file)
@@ -2688,11 +2688,11 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
                status = EnableAndResetMB(state);
                if (status < 0)
                        break;
-               if (state->type_A)
+               if (state->type_A) {
                        status = ResetCEFR(state);
                        if (status < 0)
                                break;
-
+               }
                if (fw) {
                        status = DownloadMicrocode(state, fw, fw_size);
                        if (status < 0)
index 1e344b033277c3ccf362b163aa3069f431327346..335daeff91b941d97854d74292435f977e3cc2a5 100644 (file)
@@ -616,7 +616,7 @@ static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
                        snr_reading = dvbs2_noise_reading / tmp;
                        if (snr_reading > 80)
                                snr_reading = 80;
-                       *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
+                       *snr = -(dvbs2_snr_tab[snr_reading - 1] / 1000);
                }
                dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
                                snr_reading, *snr);
diff --git a/drivers/media/dvb-frontends/it913x-fe-priv.h b/drivers/media/dvb-frontends/it913x-fe-priv.h
deleted file mode 100644 (file)
index eb6fd8a..0000000
+++ /dev/null
@@ -1,1051 +0,0 @@
-
-struct it913xset {     u32 pro;
-                       u32 address;
-                       u8 reg[15];
-                       u8 count;
-};
-
-struct adctable {      u32 adcFrequency;
-                       u32 bandwidth;
-                       u32 coeff_1_2048;
-                       u32 coeff_1_4096;
-                       u32 coeff_1_8191;
-                       u32 coeff_1_8192;
-                       u32 coeff_1_8193;
-                       u32 coeff_2_2k;
-                       u32 coeff_2_4k;
-                       u32 coeff_2_8k;
-                       u16 bfsfcw_fftinx_ratio;
-                       u16 fftinx_bfsfcw_ratio;
-};
-
-/* clock and coeff tables only table 3 is used with IT9137*/
-/* TODO other tables relate AF9035 may be removed */
-static struct adctable tab1[] = {
-       {       20156250, 6000000,
-               0x02b8ba6e, 0x015c5d37, 0x00ae340d, 0x00ae2e9b, 0x00ae292a,
-               0x015c5d37, 0x00ae2e9b, 0x0057174e, 0x02f1, 0x015c      },
-       {       20156250, 7000000,
-               0x032cd980, 0x01966cc0, 0x00cb3cba, 0x00cb3660, 0x00cb3007,
-               0x01966cc0, 0x00cb3660, 0x00659b30, 0x0285, 0x0196      },
-       {       20156250, 8000000,
-               0x03a0f893, 0x01d07c49, 0x00e84567, 0x00e83e25, 0x00e836e3,
-               0x01d07c49, 0x00e83e25, 0x00741f12, 0x0234, 0x01d0      },
-       {       20156250, 5000000,
-               0x02449b5c, 0x01224dae, 0x00912b60, 0x009126d7, 0x0091224e,
-               0x01224dae, 0x009126d7, 0x0048936b, 0x0387, 0x0122      }
-};
-
-static struct adctable tab2[] = {
-       {       20187500, 6000000,
-               0x02b7a654, 0x015bd32a, 0x00adef04, 0x00ade995, 0x00ade426,
-               0x015bd32a, 0x00ade995, 0x0056f4ca, 0x02f2, 0x015c      },
-       {       20187500, 7000000,
-               0x032b9761, 0x0195cbb1, 0x00caec30, 0x00cae5d8, 0x00cadf81,
-               0x0195cbb1, 0x00cae5d8, 0x006572ec, 0x0286, 0x0196      },
-       {       20187500, 8000000,
-               0x039f886f, 0x01cfc438, 0x00e7e95b, 0x00e7e21c, 0x00e7dadd,
-               0x01cfc438, 0x00e7e21c, 0x0073f10e, 0x0235, 0x01d0      },
-       {       20187500, 5000000,
-               0x0243b546, 0x0121daa3, 0x0090f1d9, 0x0090ed51, 0x0090e8ca,
-               0x0121daa3, 0x0090ed51, 0x004876a9, 0x0388, 0x0122      }
-
-};
-
-static struct adctable tab3[] = {
-       {       20250000, 6000000,
-               0x02b580ad, 0x015ac057, 0x00ad6597, 0x00ad602b, 0x00ad5ac1,
-               0x015ac057, 0x00ad602b, 0x0056b016, 0x02f4, 0x015b      },
-       {       20250000, 7000000,
-               0x03291620, 0x01948b10, 0x00ca4bda, 0x00ca4588, 0x00ca3f36,
-               0x01948b10, 0x00ca4588, 0x006522c4, 0x0288, 0x0195      },
-       {       20250000, 8000000,
-               0x039cab92, 0x01ce55c9, 0x00e7321e, 0x00e72ae4, 0x00e723ab,
-               0x01ce55c9, 0x00e72ae4, 0x00739572, 0x0237, 0x01ce      },
-       {       20250000, 5000000,
-               0x0241eb3b, 0x0120f59e, 0x00907f53, 0x00907acf, 0x0090764b,
-               0x0120f59e, 0x00907acf, 0x00483d67, 0x038b, 0x0121      }
-
-};
-
-static struct adctable tab4[] = {
-       {       20583333, 6000000,
-               0x02aa4598, 0x015522cc, 0x00aa96bb, 0x00aa9166, 0x00aa8c12,
-               0x015522cc, 0x00aa9166, 0x005548b3, 0x0300, 0x0155      },
-       {       20583333, 7000000,
-               0x031bfbdc, 0x018dfdee, 0x00c7052f, 0x00c6fef7, 0x00c6f8bf,
-               0x018dfdee, 0x00c6fef7, 0x00637f7b, 0x0293, 0x018e      },
-       {       20583333, 8000000,
-               0x038db21f, 0x01c6d910, 0x00e373a3, 0x00e36c88, 0x00e3656d,
-               0x01c6d910, 0x00e36c88, 0x0071b644, 0x0240, 0x01c7      },
-       {       20583333, 5000000,
-               0x02388f54, 0x011c47aa, 0x008e2846, 0x008e23d5, 0x008e1f64,
-               0x011c47aa, 0x008e23d5, 0x004711ea, 0x039a, 0x011c      }
-
-};
-
-static struct adctable tab5[] = {
-       {       20416667, 6000000,
-               0x02afd765, 0x0157ebb3, 0x00abfb39, 0x00abf5d9, 0x00abf07a,
-               0x0157ebb3, 0x00abf5d9, 0x0055faed, 0x02fa, 0x0158      },
-       {       20416667, 7000000,
-               0x03227b4b, 0x01913da6, 0x00c8a518, 0x00c89ed3, 0x00c8988e,
-               0x01913da6, 0x00c89ed3, 0x00644f69, 0x028d, 0x0191      },
-       {       20416667, 8000000,
-               0x03951f32, 0x01ca8f99, 0x00e54ef7, 0x00e547cc, 0x00e540a2,
-               0x01ca8f99, 0x00e547cc, 0x0072a3e6, 0x023c, 0x01cb      },
-       {       20416667, 5000000,
-               0x023d337f, 0x011e99c0, 0x008f515a, 0x008f4ce0, 0x008f4865,
-               0x011e99c0, 0x008f4ce0, 0x0047a670, 0x0393, 0x011f      }
-
-};
-
-static struct adctable tab6[] = {
-       {       20480000, 6000000,
-               0x02adb6db, 0x0156db6e, 0x00ab7312, 0x00ab6db7, 0x00ab685c,
-               0x0156db6e, 0x00ab6db7, 0x0055b6db, 0x02fd, 0x0157      },
-       {       20480000, 7000000,
-               0x03200000, 0x01900000, 0x00c80640, 0x00c80000, 0x00c7f9c0,
-               0x01900000, 0x00c80000, 0x00640000, 0x028f, 0x0190      },
-       {       20480000, 8000000,
-               0x03924925, 0x01c92492, 0x00e4996e, 0x00e49249, 0x00e48b25,
-               0x01c92492, 0x00e49249, 0x00724925, 0x023d, 0x01c9      },
-       {       20480000, 5000000,
-               0x023b6db7, 0x011db6db, 0x008edfe5, 0x008edb6e, 0x008ed6f7,
-               0x011db6db, 0x008edb6e, 0x00476db7, 0x0396, 0x011e      }
-};
-
-static struct adctable tab7[] = {
-       {       20500000, 6000000,
-               0x02ad0b99, 0x015685cc, 0x00ab4840, 0x00ab42e6, 0x00ab3d8c,
-               0x015685cc, 0x00ab42e6, 0x0055a173, 0x02fd, 0x0157      },
-       {       20500000, 7000000,
-               0x031f3832, 0x018f9c19, 0x00c7d44b, 0x00c7ce0c, 0x00c7c7ce,
-               0x018f9c19, 0x00c7ce0c, 0x0063e706, 0x0290, 0x0190      },
-       {       20500000, 8000000,
-               0x039164cb, 0x01c8b266, 0x00e46056, 0x00e45933, 0x00e45210,
-               0x01c8b266, 0x00e45933, 0x00722c99, 0x023e, 0x01c9      },
-       {       20500000, 5000000,
-               0x023adeff, 0x011d6f80, 0x008ebc36, 0x008eb7c0, 0x008eb34a,
-               0x011d6f80, 0x008eb7c0, 0x00475be0, 0x0396, 0x011d      }
-
-};
-
-static struct adctable tab8[] = {
-       {       20625000, 6000000,
-               0x02a8e4bd, 0x0154725e, 0x00aa3e81, 0x00aa392f, 0x00aa33de,
-               0x0154725e, 0x00aa392f, 0x00551c98, 0x0302, 0x0154      },
-       {       20625000, 7000000,
-               0x031a6032, 0x018d3019, 0x00c69e41, 0x00c6980c, 0x00c691d8,
-               0x018d3019, 0x00c6980c, 0x00634c06, 0x0294, 0x018d      },
-       {       20625000, 8000000,
-               0x038bdba6, 0x01c5edd3, 0x00e2fe02, 0x00e2f6ea, 0x00e2efd2,
-               0x01c5edd3, 0x00e2f6ea, 0x00717b75, 0x0242, 0x01c6      },
-       {       20625000, 5000000,
-               0x02376948, 0x011bb4a4, 0x008ddec1, 0x008dda52, 0x008dd5e3,
-               0x011bb4a4, 0x008dda52, 0x0046ed29, 0x039c, 0x011c      }
-
-};
-
-struct table {
-               u32 xtal;
-               struct adctable *table;
-};
-
-static struct table fe_clockTable[] = {
-               {12000000, tab3},       /* 12.00MHz */
-               {20480000, tab6},       /* 20.48MHz */
-               {36000000, tab3},       /* 36.00MHz */
-               {30000000, tab1},       /* 30.00MHz */
-               {26000000, tab4},       /* 26.00MHz */
-               {28000000, tab5},       /* 28.00MHz */
-               {32000000, tab7},       /* 32.00MHz */
-               {34000000, tab2},       /* 34.00MHz */
-               {24000000, tab1},       /* 24.00MHz */
-               {22000000, tab8},       /* 22.00MHz */
-};
-
-/* fe get */
-fe_code_rate_t fe_code[] = {
-       FEC_1_2,
-       FEC_2_3,
-       FEC_3_4,
-       FEC_5_6,
-       FEC_7_8,
-       FEC_NONE,
-};
-
-fe_guard_interval_t fe_gi[] = {
-       GUARD_INTERVAL_1_32,
-       GUARD_INTERVAL_1_16,
-       GUARD_INTERVAL_1_8,
-       GUARD_INTERVAL_1_4,
-};
-
-fe_hierarchy_t fe_hi[] = {
-       HIERARCHY_NONE,
-       HIERARCHY_1,
-       HIERARCHY_2,
-       HIERARCHY_4,
-};
-
-fe_transmit_mode_t fe_mode[] = {
-       TRANSMISSION_MODE_2K,
-       TRANSMISSION_MODE_8K,
-       TRANSMISSION_MODE_4K,
-};
-
-fe_modulation_t fe_con[] = {
-       QPSK,
-       QAM_16,
-       QAM_64,
-};
-
-enum {
-       PRIORITY_HIGH = 0,      /* High-priority stream */
-       PRIORITY_LOW,   /* Low-priority stream */
-};
-
-/* Standard demodulator functions */
-static struct it913xset set_solo_fe[] = {
-       {PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
-       {PRO_LINK, GPIOH5_ON, {0x01}, 0x01},
-       {PRO_LINK, GPIOH5_O, {0x00}, 0x01},
-       {PRO_LINK, GPIOH5_O, {0x01}, 0x01},
-       {PRO_LINK, DVBT_INTEN, {0x04}, 0x01},
-       {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01},
-       {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_MPEG_SER_MODE, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_MPEG_PAR_MODE, {0x00}, 0x01},
-       {PRO_DMOD, DCA_UPPER_CHIP, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_DCA_UPPER, {0x00}, 0x01},
-       {PRO_DMOD, DCA_LOWER_CHIP, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_DCA_LOWER, {0x00}, 0x01},
-       {PRO_DMOD, DCA_PLATCH, {0x00}, 0x01},
-       {PRO_DMOD, DCA_FPGA_LATCH, {0x00}, 0x01},
-       {PRO_DMOD, DCA_STAND_ALONE, {0x01}, 0x01},
-       {PRO_DMOD, DCA_ENABLE, {0x00}, 0x01},
-       {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
-       {PRO_DMOD, BFS_FCW, {0x00, 0x00, 0x00}, 0x03},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
-
-
-static struct it913xset init_1[] = {
-       {PRO_LINK, LOCK3_OUT, {0x01}, 0x01},
-       {PRO_LINK, PADMISCDRSR, {0x01}, 0x01},
-       {PRO_LINK, PADMISCDR2, {0x00}, 0x01},
-       {PRO_DMOD, 0xec57, {0x00, 0x00}, 0x02},
-       {PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */
-       {PRO_LINK, PADMISCDR8, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-
-/* Version 1 types */
-static struct it913xset it9135_v1[] = {
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a}, 0x01},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a}, 0x01},
-       {PRO_DMOD, 0x008a, {0x01}, 0x01},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06}, 0x01},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009f, {0xe1}, 0x01},
-       {PRO_DMOD, 0x00a0, {0xcf}, 0x01},
-       {PRO_DMOD, 0x00a3, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a5, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a6, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a9, {0x00}, 0x01},
-       {PRO_DMOD, 0x00aa, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00c2, {0x05}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10}, 0x01},
-       {PRO_DMOD, 0xf017, {0x04}, 0x01},
-       {PRO_DMOD, 0xf018, {0x05}, 0x01},
-       {PRO_DMOD, 0xf019, {0x04}, 0x01},
-       {PRO_DMOD, 0xf01a, {0x05}, 0x01},
-       {PRO_DMOD, 0xf021, {0x03}, 0x01},
-       {PRO_DMOD, 0xf022, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf023, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf02b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf02c, {0x01}, 0x01},
-       {PRO_DMOD, 0xf064, {0x03}, 0x01},
-       {PRO_DMOD, 0xf065, {0xf9}, 0x01},
-       {PRO_DMOD, 0xf066, {0x03}, 0x01},
-       {PRO_DMOD, 0xf067, {0x01}, 0x01},
-       {PRO_DMOD, 0xf06f, {0xe0}, 0x01},
-       {PRO_DMOD, 0xf070, {0x03}, 0x01},
-       {PRO_DMOD, 0xf072, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf073, {0x03}, 0x01},
-       {PRO_DMOD, 0xf078, {0x00}, 0x01},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f}, 0x01},
-       {PRO_DMOD, 0xf09c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09d, {0x20}, 0x01},
-       {PRO_DMOD, 0xf09e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09f, {0x0c}, 0x01},
-       {PRO_DMOD, 0xf0a0, {0x00}, 0x01},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14d, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf15b, {0x08}, 0x01},
-       {PRO_DMOD, 0xf15d, {0x03}, 0x01},
-       {PRO_DMOD, 0xf15e, {0x05}, 0x01},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01}, 0x01},
-       {PRO_DMOD, 0xf167, {0x40}, 0x01},
-       {PRO_DMOD, 0xf168, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf17a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf17b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36}, 0x01},
-       {PRO_DMOD, 0xf1bd, {0x00}, 0x01},
-       {PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
-       {PRO_DMOD, 0xf1cc, {0x01}, 0x01},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf40e, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf40f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf410, {0x08}, 0x01},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15}, 0x01},
-       {PRO_DMOD, 0xf562, {0x20}, 0x01},
-       {PRO_DMOD, 0xf5df, {0xfb}, 0x01},
-       {PRO_DMOD, 0xf5e0, {0x00}, 0x01},
-       {PRO_DMOD, 0xf5e3, {0x09}, 0x01},
-       {PRO_DMOD, 0xf5e4, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5e5, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {0x05}, 0x01},
-       {PRO_DMOD, 0xf601, {0x08}, 0x01},
-       {PRO_DMOD, 0xf602, {0x0b}, 0x01},
-       {PRO_DMOD, 0xf603, {0x0e}, 0x01},
-       {PRO_DMOD, 0xf604, {0x11}, 0x01},
-       {PRO_DMOD, 0xf605, {0x14}, 0x01},
-       {PRO_DMOD, 0xf606, {0x17}, 0x01},
-       {PRO_DMOD, 0xf607, {0x1f}, 0x01},
-       {PRO_DMOD, 0xf60e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf60f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf610, {0x32}, 0x01},
-       {PRO_DMOD, 0xf611, {0x10}, 0x01},
-       {PRO_DMOD, 0xf707, {0xfc}, 0x01},
-       {PRO_DMOD, 0xf708, {0x00}, 0x01},
-       {PRO_DMOD, 0xf709, {0x37}, 0x01},
-       {PRO_DMOD, 0xf70a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf810, {0x54}, 0x01},
-       {PRO_DMOD, 0xf811, {0x5a}, 0x01},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_38[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x38}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
-       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8,
-                               0xd0, 0xc3, 0x01}, 0x0a},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x32}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
-       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
-       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77,
-                               0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
-       {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04},
-       {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03},
-       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
-       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_51[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x51}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
-       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96,
-                               0xcf, 0xc3, 0x01}, 0x0a},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
-       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
-       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77,
-                               0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
-       {PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04},
-       {PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03},
-       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
-       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_52[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x52}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x10}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
-       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97,
-                               0xc0, 0x9e, 0x01}, 0x0a},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
-       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
-       {PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77,
-                               0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
-       {PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04},
-       {PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03},
-       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05},
-       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-/* Version 2 types */
-static struct it913xset it9135_v2[] = {
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a}, 0x01},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a}, 0x01},
-       {PRO_DMOD, 0x008a, {0x01}, 0x01},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06}, 0x01},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009f, {0xe1}, 0x01},
-       {PRO_DMOD, 0x00a0, {0xcf}, 0x01},
-       {PRO_DMOD, 0x00a3, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a5, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a6, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a9, {0x00}, 0x01},
-       {PRO_DMOD, 0x00aa, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00c2, {0x05}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf02b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf064, {0x03}, 0x01},
-       {PRO_DMOD, 0xf065, {0xf9}, 0x01},
-       {PRO_DMOD, 0xf066, {0x03}, 0x01},
-       {PRO_DMOD, 0xf067, {0x01}, 0x01},
-       {PRO_DMOD, 0xf06f, {0xe0}, 0x01},
-       {PRO_DMOD, 0xf070, {0x03}, 0x01},
-       {PRO_DMOD, 0xf072, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf073, {0x03}, 0x01},
-       {PRO_DMOD, 0xf078, {0x00}, 0x01},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f}, 0x01},
-       {PRO_DMOD, 0xf09c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09d, {0x20}, 0x01},
-       {PRO_DMOD, 0xf09e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09f, {0x0c}, 0x01},
-       {PRO_DMOD, 0xf0a0, {0x00}, 0x01},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14d, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf15b, {0x08}, 0x01},
-       {PRO_DMOD, 0xf15d, {0x03}, 0x01},
-       {PRO_DMOD, 0xf15e, {0x05}, 0x01},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01}, 0x01},
-       {PRO_DMOD, 0xf167, {0x40}, 0x01},
-       {PRO_DMOD, 0xf168, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf17a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf17b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36}, 0x01},
-       {PRO_DMOD, 0xf1bd, {0x00}, 0x01},
-       {PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
-       {PRO_DMOD, 0xf1cc, {0x01}, 0x01},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf40e, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf40f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf410, {0x08}, 0x01},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15}, 0x01},
-       {PRO_DMOD, 0xf562, {0x20}, 0x01},
-       {PRO_DMOD, 0xf5e3, {0x09}, 0x01},
-       {PRO_DMOD, 0xf5e4, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5e5, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {0x05}, 0x01},
-       {PRO_DMOD, 0xf601, {0x08}, 0x01},
-       {PRO_DMOD, 0xf602, {0x0b}, 0x01},
-       {PRO_DMOD, 0xf603, {0x0e}, 0x01},
-       {PRO_DMOD, 0xf604, {0x11}, 0x01},
-       {PRO_DMOD, 0xf605, {0x14}, 0x01},
-       {PRO_DMOD, 0xf606, {0x17}, 0x01},
-       {PRO_DMOD, 0xf607, {0x1f}, 0x01},
-       {PRO_DMOD, 0xf60e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf60f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf610, {0x32}, 0x01},
-       {PRO_DMOD, 0xf611, {0x10}, 0x01},
-       {PRO_DMOD, 0xf707, {0xfc}, 0x01},
-       {PRO_DMOD, 0xf708, {0x00}, 0x01},
-       {PRO_DMOD, 0xf709, {0x37}, 0x01},
-       {PRO_DMOD, 0xf70a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf810, {0x54}, 0x01},
-       {PRO_DMOD, 0xf811, {0x5a}, 0x01},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_60[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x60}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x006a, {0x03}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
-       {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
-       {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c,
-                               0x00, 0x02, 0xbe, 0x00}, 0x0b},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-       {PRO_DMOD, 0x011a, {0xbe}, 0x01},
-       {PRO_DMOD, 0x0124, {0xae}, 0x01},
-       {PRO_DMOD, 0x0127, {0x00}, 0x01},
-       {PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00}, 0x01},
-       {PRO_DMOD, 0x013b, {0x08}, 0x01},
-       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
-       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c,
-                               0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6,
-                               0x33}, 0x0f},
-       {PRO_DMOD, 0x0151, {0x28}, 0x01},
-       {PRO_DMOD, 0x0153, {0xbc}, 0x01},
-       {PRO_DMOD, 0x0178, {0x09}, 0x01},
-       {PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02},
-       {PRO_DMOD, 0x0185, {0x24}, 0x01},
-       {PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05},
-       {PRO_DMOD, 0xed02, {0xff}, 0x01},
-       {PRO_DMOD, 0xee42, {0xff}, 0x01},
-       {PRO_DMOD, 0xee82, {0xff}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17
-               , 0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_61[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x61}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x06}, 0x01},
-       {PRO_DMOD, 0x006a, {0x03}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
-       {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
-       {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c,
-                               0x01, 0x02, 0xc8, 0x00}, 0x0b},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-       {PRO_DMOD, 0x011a, {0xc6}, 0x01},
-       {PRO_DMOD, 0x0124, {0xa8}, 0x01},
-       {PRO_DMOD, 0x0127, {0x00}, 0x01},
-       {PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00}, 0x01},
-       {PRO_DMOD, 0x013b, {0x05}, 0x01},
-       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
-       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c,
-                               0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6,
-                               0x33}, 0x0f},
-       {PRO_DMOD, 0x0151, {0x28}, 0x01},
-       {PRO_DMOD, 0x0153, {0xcc}, 0x01},
-       {PRO_DMOD, 0x0178, {0x09}, 0x01},
-       {PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02},
-       {PRO_DMOD, 0x0185, {0x28}, 0x01},
-       {PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05},
-       {PRO_DMOD, 0xed02, {0xff}, 0x01},
-       {PRO_DMOD, 0xee42, {0xff}, 0x01},
-       {PRO_DMOD, 0xee82, {0xff}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_62[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x62}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x006a, {0x03}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
-       {PRO_DMOD, 0x0084, {    0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01},
-                               0x07},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
-       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c,
-                               0x02, 0x02, 0xc2, 0x00}, 0x0b},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-       {PRO_DMOD, 0x011a, {0xb8}, 0x01},
-       {PRO_DMOD, 0x0124, {0xa8}, 0x01},
-       {PRO_DMOD, 0x0127, {0x00}, 0x01},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00}, 0x01},
-       {PRO_DMOD, 0x013b, {0x05}, 0x01},
-       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
-       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c,
-                               0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0,
-                               0x33}, 0x0f},
-       {PRO_DMOD, 0x0151, {0x28}, 0x01},
-       {PRO_DMOD, 0x0153, {0xb2}, 0x01},
-       {PRO_DMOD, 0x0178, {0x09}, 0x01},
-       {PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02},
-       {PRO_DMOD, 0x0185, {0x24}, 0x01},
-       {PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05},
-       {PRO_DMOD, 0xed02, {0xff}, 0x01},
-       {PRO_DMOD, 0xee42, {0xff}, 0x01},
-       {PRO_DMOD, 0xee82, {0xff}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-/* Tuner setting scripts (still keeping it9137) */
-static struct it913xset it9137_tuner_off[] = {
-       {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off  */
-       {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */
-       {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04},
-       {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00}, 0x0c},
-       {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04},
-       {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00}, 0x09},
-       {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00}, 0x0a},
-       {PRO_DMOD, 0xec20, {0x00}, 0x01},
-       {PRO_DMOD, 0xec3f, {0x01}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
-
-static struct it913xset set_it9135_template[] = {
-       {PRO_DMOD, 0xee06, {0x00}, 0x01},
-       {PRO_DMOD, 0xec56, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4c, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4d, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4e, {0x00}, 0x01},
-       {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */
-       {PRO_DMOD, 0x011f, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
-
-static struct it913xset set_it9137_template[] = {
-       {PRO_DMOD, 0xee06, {0x00}, 0x01},
-       {PRO_DMOD, 0xec56, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4c, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4d, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4e, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4f, {0x00}, 0x01},
-       {PRO_DMOD, 0xec50, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
diff --git a/drivers/media/dvb-frontends/it913x-fe.c b/drivers/media/dvb-frontends/it913x-fe.c
deleted file mode 100644 (file)
index 6e1c6eb..0000000
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- *  Driver for it913x-fe Frontend
- *
- *  with support for on chip it9137 integral tuner
- *
- *  Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
- *  IT9137 Copyright (C) ITE Tech Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include "dvb_frontend.h"
-#include "it913x-fe.h"
-#include "it913x-fe-priv.h"
-
-static int it913x_debug;
-
-module_param_named(debug, it913x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define dprintk(level, args...) do { \
-       if (level & it913x_debug) \
-               printk(KERN_DEBUG "it913x-fe: " args); \
-} while (0)
-
-#define deb_info(args...)  dprintk(0x01, args)
-#define debug_data_snipet(level, name, p) \
-         dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
-               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
-                       *(p+5), *(p+6), *(p+7));
-#define info(format, arg...) \
-       printk(KERN_INFO "it913x-fe: " format "\n" , ## arg)
-
-struct it913x_fe_state {
-       struct dvb_frontend frontend;
-       struct i2c_adapter *i2c_adap;
-       struct ite_config *config;
-       u8 i2c_addr;
-       u32 frequency;
-       fe_modulation_t constellation;
-       fe_transmit_mode_t transmission_mode;
-       u8 priority;
-       u32 crystalFrequency;
-       u32 adcFrequency;
-       u8 tuner_type;
-       struct adctable *table;
-       fe_status_t it913x_status;
-       u16 tun_xtal;
-       u8 tun_fdiv;
-       u8 tun_clk_mode;
-       u32 tun_fn_min;
-       u32 ucblocks;
-};
-
-static int it913x_read_reg(struct it913x_fe_state *state,
-               u32 reg, u8 *data, u8 count)
-{
-       int ret;
-       u8 pro = PRO_DMOD; /* All reads from demodulator */
-       u8 b[4];
-       struct i2c_msg msg[2] = {
-               { .addr = state->i2c_addr + (pro << 1), .flags = 0,
-                       .buf = b, .len = sizeof(b) },
-               { .addr = state->i2c_addr + (pro << 1), .flags = I2C_M_RD,
-                       .buf = data, .len = count }
-       };
-       b[0] = (u8) reg >> 24;
-       b[1] = (u8)(reg >> 16) & 0xff;
-       b[2] = (u8)(reg >> 8) & 0xff;
-       b[3] = (u8) reg & 0xff;
-
-       ret = i2c_transfer(state->i2c_adap, msg, 2);
-
-       return ret;
-}
-
-static int it913x_read_reg_u8(struct it913x_fe_state *state, u32 reg)
-{
-       int ret;
-       u8 b[1];
-       ret = it913x_read_reg(state, reg, &b[0], sizeof(b));
-       return (ret < 0) ? -ENODEV : b[0];
-}
-
-static int it913x_write(struct it913x_fe_state *state,
-               u8 pro, u32 reg, u8 buf[], u8 count)
-{
-       u8 b[256];
-       struct i2c_msg msg[1] = {
-               { .addr = state->i2c_addr + (pro << 1), .flags = 0,
-                 .buf = b, .len = count + 4 }
-       };
-       int ret;
-
-       b[0] = (u8) reg >> 24;
-       b[1] = (u8)(reg >> 16) & 0xff;
-       b[2] = (u8)(reg >> 8) & 0xff;
-       b[3] = (u8) reg & 0xff;
-       memcpy(&b[4], buf, count);
-
-       ret = i2c_transfer(state->i2c_adap, msg, 1);
-
-       if (ret < 0)
-               return -EIO;
-
-       return 0;
-}
-
-static int it913x_write_reg(struct it913x_fe_state *state,
-               u8 pro, u32 reg, u32 data)
-{
-       int ret;
-       u8 b[4];
-       u8 s;
-
-       b[0] = data >> 24;
-       b[1] = (data >> 16) & 0xff;
-       b[2] = (data >> 8) & 0xff;
-       b[3] = data & 0xff;
-       /* expand write as needed */
-       if (data < 0x100)
-               s = 3;
-       else if (data < 0x1000)
-               s = 2;
-       else if (data < 0x100000)
-               s = 1;
-       else
-               s = 0;
-
-       ret = it913x_write(state, pro, reg, &b[s], sizeof(b) - s);
-
-       return ret;
-}
-
-static int it913x_fe_script_loader(struct it913x_fe_state *state,
-               struct it913xset *loadscript)
-{
-       int ret, i;
-       if (loadscript == NULL)
-               return -EINVAL;
-
-       for (i = 0; i < 1000; ++i) {
-               if (loadscript[i].pro == 0xff)
-                       break;
-               ret = it913x_write(state, loadscript[i].pro,
-                       loadscript[i].address,
-                       loadscript[i].reg, loadscript[i].count);
-               if (ret < 0)
-                       return -ENODEV;
-       }
-       return 0;
-}
-
-static int it913x_init_tuner(struct it913x_fe_state *state)
-{
-       int ret, i, reg;
-       u8 val, nv_val;
-       u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
-       u8 b[2];
-
-       reg = it913x_read_reg_u8(state, 0xec86);
-       switch (reg) {
-       case 0:
-               state->tun_clk_mode = reg;
-               state->tun_xtal = 2000;
-               state->tun_fdiv = 3;
-               val = 16;
-               break;
-       case -ENODEV:
-               return -ENODEV;
-       case 1:
-       default:
-               state->tun_clk_mode = reg;
-               state->tun_xtal = 640;
-               state->tun_fdiv = 1;
-               val = 6;
-               break;
-       }
-
-       reg = it913x_read_reg_u8(state, 0xed03);
-
-       if (reg < 0)
-               return -ENODEV;
-       else if (reg < ARRAY_SIZE(nv))
-               nv_val = nv[reg];
-       else
-               nv_val = 2;
-
-       for (i = 0; i < 50; i++) {
-               ret = it913x_read_reg(state, 0xed23, &b[0], sizeof(b));
-               reg = (b[1] << 8) + b[0];
-               if (reg > 0)
-                       break;
-               if (ret < 0)
-                       return -ENODEV;
-               udelay(2000);
-       }
-       state->tun_fn_min = state->tun_xtal * reg;
-       state->tun_fn_min /= (state->tun_fdiv * nv_val);
-       deb_info("Tuner fn_min %d", state->tun_fn_min);
-
-       if (state->config->chip_ver > 1)
-               msleep(50);
-       else {
-               for (i = 0; i < 50; i++) {
-                       reg = it913x_read_reg_u8(state, 0xec82);
-                       if (reg > 0)
-                               break;
-                       if (reg < 0)
-                               return -ENODEV;
-                       udelay(2000);
-               }
-       }
-
-       return it913x_write_reg(state, PRO_DMOD, 0xed81, val);
-}
-
-static int it9137_set_tuner(struct it913x_fe_state *state,
-               u32 bandwidth, u32 frequency_m)
-{
-       struct it913xset *set_tuner = set_it9137_template;
-       int ret, reg;
-       u32 frequency = frequency_m / 1000;
-       u32 freq, temp_f, tmp;
-       u16 iqik_m_cal;
-       u16 n_div;
-       u8 n;
-       u8 l_band;
-       u8 lna_band;
-       u8 bw;
-
-       if (state->config->firmware_ver == 1)
-               set_tuner = set_it9135_template;
-       else
-               set_tuner = set_it9137_template;
-
-       deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth);
-
-       if (frequency >= 51000 && frequency <= 440000) {
-               l_band = 0;
-               lna_band = 0;
-       } else if (frequency > 440000 && frequency <= 484000) {
-               l_band = 1;
-               lna_band = 1;
-       } else if (frequency > 484000 && frequency <= 533000) {
-               l_band = 1;
-               lna_band = 2;
-       } else if (frequency > 533000 && frequency <= 587000) {
-               l_band = 1;
-               lna_band = 3;
-       } else if (frequency > 587000 && frequency <= 645000) {
-               l_band = 1;
-               lna_band = 4;
-       } else if (frequency > 645000 && frequency <= 710000) {
-               l_band = 1;
-               lna_band = 5;
-       } else if (frequency > 710000 && frequency <= 782000) {
-               l_band = 1;
-               lna_band = 6;
-       } else if (frequency > 782000 && frequency <= 860000) {
-               l_band = 1;
-               lna_band = 7;
-       } else if (frequency > 1450000 && frequency <= 1492000) {
-               l_band = 1;
-               lna_band = 0;
-       } else if (frequency > 1660000 && frequency <= 1685000) {
-               l_band = 1;
-               lna_band = 1;
-       } else
-               return -EINVAL;
-       set_tuner[0].reg[0] = lna_band;
-
-       switch (bandwidth) {
-       case 5000000:
-               bw = 0;
-               break;
-       case 6000000:
-               bw = 2;
-               break;
-       case 7000000:
-               bw = 4;
-               break;
-       default:
-       case 8000000:
-               bw = 6;
-               break;
-       }
-
-       set_tuner[1].reg[0] = bw;
-       set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
-
-       if (frequency > 53000 && frequency <= 74000) {
-               n_div = 48;
-               n = 0;
-       } else if (frequency > 74000 && frequency <= 111000) {
-               n_div = 32;
-               n = 1;
-       } else if (frequency > 111000 && frequency <= 148000) {
-               n_div = 24;
-               n = 2;
-       } else if (frequency > 148000 && frequency <= 222000) {
-               n_div = 16;
-               n = 3;
-       } else if (frequency > 222000 && frequency <= 296000) {
-               n_div = 12;
-               n = 4;
-       } else if (frequency > 296000 && frequency <= 445000) {
-               n_div = 8;
-               n = 5;
-       } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
-               n_div = 6;
-               n = 6;
-       } else if (frequency > state->tun_fn_min && frequency <= 950000) {
-               n_div = 4;
-               n = 7;
-       } else if (frequency > 1450000 && frequency <= 1680000) {
-               n_div = 2;
-               n = 0;
-       } else
-               return -EINVAL;
-
-       reg = it913x_read_reg_u8(state, 0xed81);
-       iqik_m_cal = (u16)reg * n_div;
-
-       if (reg < 0x20) {
-               if (state->tun_clk_mode == 0)
-                       iqik_m_cal = (iqik_m_cal * 9) >> 5;
-               else
-                       iqik_m_cal >>= 1;
-       } else {
-               iqik_m_cal = 0x40 - iqik_m_cal;
-               if (state->tun_clk_mode == 0)
-                       iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
-               else
-                       iqik_m_cal = ~(iqik_m_cal >> 1);
-       }
-
-       temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv;
-       freq = temp_f / state->tun_xtal;
-       tmp = freq * state->tun_xtal;
-
-       if ((temp_f - tmp) >= (state->tun_xtal >> 1))
-               freq++;
-
-       freq += (u32) n << 13;
-       /* Frequency OMEGA_IQIK_M_CAL_MID*/
-       temp_f = freq + (u32)iqik_m_cal;
-
-       set_tuner[3].reg[0] =  temp_f & 0xff;
-       set_tuner[4].reg[0] =  (temp_f >> 8) & 0xff;
-
-       deb_info("High Frequency = %04x", temp_f);
-
-       /* Lower frequency */
-       set_tuner[5].reg[0] =  freq & 0xff;
-       set_tuner[6].reg[0] =  (freq >> 8) & 0xff;
-
-       deb_info("low Frequency = %04x", freq);
-
-       ret = it913x_fe_script_loader(state, set_tuner);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_select_bw(struct it913x_fe_state *state,
-                       u32 bandwidth, u32 adcFrequency)
-{
-       int ret, i;
-       u8 buffer[256];
-       u32 coeff[8];
-       u16 bfsfcw_fftinx_ratio;
-       u16 fftinx_bfsfcw_ratio;
-       u8 count;
-       u8 bw;
-       u8 adcmultiplier;
-
-       deb_info("Bandwidth %d Adc %d", bandwidth, adcFrequency);
-
-       switch (bandwidth) {
-       case 5000000:
-               bw = 3;
-               break;
-       case 6000000:
-               bw = 0;
-               break;
-       case 7000000:
-               bw = 1;
-               break;
-       default:
-       case 8000000:
-               bw = 2;
-               break;
-       }
-       ret = it913x_write_reg(state, PRO_DMOD, REG_BW, bw);
-
-       if (state->table == NULL)
-               return -EINVAL;
-
-       /* In write order */
-       coeff[0] = state->table[bw].coeff_1_2048;
-       coeff[1] = state->table[bw].coeff_2_2k;
-       coeff[2] = state->table[bw].coeff_1_8191;
-       coeff[3] = state->table[bw].coeff_1_8192;
-       coeff[4] = state->table[bw].coeff_1_8193;
-       coeff[5] = state->table[bw].coeff_2_8k;
-       coeff[6] = state->table[bw].coeff_1_4096;
-       coeff[7] = state->table[bw].coeff_2_4k;
-       bfsfcw_fftinx_ratio = state->table[bw].bfsfcw_fftinx_ratio;
-       fftinx_bfsfcw_ratio = state->table[bw].fftinx_bfsfcw_ratio;
-
-       /* ADC multiplier */
-       ret = it913x_read_reg_u8(state, ADC_X_2);
-       if (ret < 0)
-               return -EINVAL;
-
-       adcmultiplier = ret;
-
-       count = 0;
-
-       /*  Build Buffer for COEFF Registers */
-       for (i = 0; i < 8; i++) {
-               if (adcmultiplier == 1)
-                       coeff[i] /= 2;
-               buffer[count++] = (coeff[i] >> 24) & 0x3;
-               buffer[count++] = (coeff[i] >> 16) & 0xff;
-               buffer[count++] = (coeff[i] >> 8) & 0xff;
-               buffer[count++] = coeff[i] & 0xff;
-       }
-
-       /* bfsfcw_fftinx_ratio register 0x21-0x22 */
-       buffer[count++] = bfsfcw_fftinx_ratio & 0xff;
-       buffer[count++] = (bfsfcw_fftinx_ratio >> 8) & 0xff;
-       /* fftinx_bfsfcw_ratio register 0x23-0x24 */
-       buffer[count++] = fftinx_bfsfcw_ratio & 0xff;
-       buffer[count++] = (fftinx_bfsfcw_ratio >> 8) & 0xff;
-       /* start at COEFF_1_2048 and write through to fftinx_bfsfcw_ratio*/
-       ret = it913x_write(state, PRO_DMOD, COEFF_1_2048, buffer, count);
-
-       for (i = 0; i < 42; i += 8)
-               debug_data_snipet(0x1, "Buffer", &buffer[i]);
-
-       return ret;
-}
-
-
-
-static int it913x_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret, i;
-       fe_status_t old_status = state->it913x_status;
-       *status = 0;
-
-       if (state->it913x_status == 0) {
-               ret = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
-               if (ret == 0x1) {
-                       *status |= FE_HAS_SIGNAL;
-                       for (i = 0; i < 40; i++) {
-                               ret = it913x_read_reg_u8(state, MP2IF_SYNC_LK);
-                               if (ret == 0x1)
-                                       break;
-                               msleep(25);
-                       }
-                       if (ret == 0x1)
-                               *status |= FE_HAS_CARRIER
-                                       | FE_HAS_VITERBI
-                                       | FE_HAS_SYNC;
-                       state->it913x_status = *status;
-               }
-       }
-
-       if (state->it913x_status & FE_HAS_SYNC) {
-               ret = it913x_read_reg_u8(state, TPSD_LOCK);
-               if (ret == 0x1)
-                       *status |= FE_HAS_LOCK
-                               | state->it913x_status;
-               else
-                       state->it913x_status = 0;
-               if (old_status != state->it913x_status)
-                       ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, ret);
-       }
-
-       return 0;
-}
-
-/* FEC values based on fe_code_rate_t non supported values 0*/
-int it913x_qpsk_pval[] = {0, -93, -91, -90, 0, -89, -88};
-int it913x_16qam_pval[] = {0, -87, -85, -84, 0, -83, -82};
-int it913x_64qam_pval[] = {0, -82, -80, -78, 0, -77, -76};
-
-static int it913x_get_signal_strength(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       u8 code_rate;
-       int ret, temp;
-       u8 lna_gain_os;
-
-       ret = it913x_read_reg_u8(state, VAR_P_INBAND);
-       if (ret < 0)
-               return ret;
-
-       /* VHF/UHF gain offset */
-       if (state->frequency < 300000000)
-               lna_gain_os = 7;
-       else
-               lna_gain_os = 14;
-
-       temp = (ret - 100) - lna_gain_os;
-
-       if (state->priority == PRIORITY_HIGH)
-               code_rate = p->code_rate_HP;
-       else
-               code_rate = p->code_rate_LP;
-
-       if (code_rate >= ARRAY_SIZE(it913x_qpsk_pval))
-               return -EINVAL;
-
-       deb_info("Reg VAR_P_INBAND:%d Calc Offset Value:%d", ret, temp);
-
-       /* Apply FEC offset values*/
-       switch (p->modulation) {
-       case QPSK:
-               temp -= it913x_qpsk_pval[code_rate];
-               break;
-       case QAM_16:
-               temp -= it913x_16qam_pval[code_rate];
-               break;
-       case QAM_64:
-               temp -= it913x_64qam_pval[code_rate];
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (temp < -15)
-               ret = 0;
-       else if ((-15 <= temp) && (temp < 0))
-               ret = (2 * (temp + 15)) / 3;
-       else if ((0 <= temp) && (temp < 20))
-               ret = 4 * temp + 10;
-       else if ((20 <= temp) && (temp < 35))
-               ret = (2 * (temp - 20)) / 3 + 90;
-       else if (temp >= 35)
-               ret = 100;
-
-       deb_info("Signal Strength :%d", ret);
-
-       return ret;
-}
-
-static int it913x_fe_read_signal_strength(struct dvb_frontend *fe,
-               u16 *strength)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret = 0;
-       if (state->config->read_slevel) {
-               if (state->it913x_status & FE_HAS_SIGNAL)
-                       ret = it913x_read_reg_u8(state, SIGNAL_LEVEL);
-       } else
-               ret = it913x_get_signal_strength(fe);
-
-       if (ret >= 0)
-               *strength = (u16)((u32)ret * 0xffff / 0x64);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 reg[3];
-       u32 snr_val, snr_min, snr_max;
-       u32 temp;
-
-       ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg));
-
-       snr_val = (u32)(reg[2] << 16) | (reg[1] << 8) | reg[0];
-
-       ret |= it913x_read_reg(state, 0xf78b, reg, 1);
-       if (reg[0])
-               snr_val /= reg[0];
-
-       if (state->transmission_mode == TRANSMISSION_MODE_2K)
-               snr_val *= 4;
-       else if (state->transmission_mode == TRANSMISSION_MODE_4K)
-               snr_val *= 2;
-
-       if (state->constellation == QPSK) {
-               snr_min = 0xb4711;
-               snr_max = 0x191451;
-       } else if (state->constellation == QAM_16) {
-               snr_min = 0x4f0d5;
-               snr_max = 0xc7925;
-       } else if (state->constellation == QAM_64) {
-               snr_min = 0x256d0;
-               snr_max = 0x626be;
-       } else
-               return -EINVAL;
-
-       if (snr_val < snr_min)
-               *snr = 0;
-       else if (snr_val < snr_max) {
-               temp = (snr_val - snr_min) >> 5;
-               temp *= 0xffff;
-               temp /= (snr_max - snr_min) >> 5;
-               *snr = (u16)temp;
-       } else
-               *snr = 0xffff;
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       u8 reg[5];
-       /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */
-       it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
-       state->ucblocks += (u32)(reg[1] << 8) | reg[0];
-       *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2];
-       return 0;
-}
-
-static int it913x_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 reg[2];
-       /* Aborted Packets */
-       ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
-       state->ucblocks += (u32)(reg[1] << 8) | reg[0];
-       *ucblocks = state->ucblocks;
-       return ret;
-}
-
-static int it913x_fe_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       u8 reg[8];
-
-       it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg));
-
-       if (reg[3] < 3)
-               p->modulation = fe_con[reg[3]];
-
-       if (reg[0] < 3)
-               p->transmission_mode = fe_mode[reg[0]];
-
-       if (reg[1] < 4)
-               p->guard_interval = fe_gi[reg[1]];
-
-       if (reg[2] < 4)
-               p->hierarchy = fe_hi[reg[2]];
-
-       state->priority = reg[5];
-
-       p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE;
-       p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE;
-
-       /* Update internal state to reflect the autodetected props */
-       state->constellation = p->modulation;
-       state->transmission_mode = p->transmission_mode;
-
-       return 0;
-}
-
-static int it913x_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int i;
-       u8 empty_ch, last_ch;
-
-       state->it913x_status = 0;
-
-       /* Set bw*/
-       it913x_fe_select_bw(state, p->bandwidth_hz,
-               state->adcFrequency);
-
-       /* Training Mode Off */
-       it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0);
-
-       /* Clear Empty Channel */
-       it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0);
-
-       /* Clear bits */
-       it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0);
-       /* LED on */
-       it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
-       /* Select Band*/
-       if ((p->frequency >= 51000000) && (p->frequency <= 230000000))
-               i = 0;
-       else if ((p->frequency >= 350000000) && (p->frequency <= 900000000))
-                       i = 1;
-       else if ((p->frequency >= 1450000000) && (p->frequency <= 1680000000))
-                       i = 2;
-       else
-               return -EOPNOTSUPP;
-
-       it913x_write_reg(state, PRO_DMOD, FREE_BAND, i);
-
-       deb_info("Frontend Set Tuner Type %02x", state->tuner_type);
-       switch (state->tuner_type) {
-       case IT9135_38:
-       case IT9135_51:
-       case IT9135_52:
-       case IT9135_60:
-       case IT9135_61:
-       case IT9135_62:
-               it9137_set_tuner(state,
-                       p->bandwidth_hz, p->frequency);
-               break;
-       default:
-               if (fe->ops.tuner_ops.set_params) {
-                       fe->ops.tuner_ops.set_params(fe);
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-               break;
-       }
-       /* LED off */
-       it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
-       /* Trigger ofsm */
-       it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
-       last_ch = 2;
-       for (i = 0; i < 40; ++i) {
-               empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
-               if (last_ch == 1 && empty_ch == 1)
-                       break;
-               if (last_ch == 2 && empty_ch == 2)
-                       return 0;
-               last_ch = empty_ch;
-               msleep(25);
-       }
-       for (i = 0; i < 40; ++i) {
-               if (it913x_read_reg_u8(state, D_TPSD_LOCK) == 1)
-                       break;
-               msleep(25);
-       }
-
-       state->frequency = p->frequency;
-       return 0;
-}
-
-static int it913x_fe_suspend(struct it913x_fe_state *state)
-{
-       int ret, i;
-       u8 b;
-
-       ret = it913x_write_reg(state, PRO_DMOD, SUSPEND_FLAG, 0x1);
-
-       ret |= it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
-
-       for (i = 0; i < 128; i++) {
-               ret = it913x_read_reg(state, SUSPEND_FLAG, &b, 1);
-               if (ret < 0)
-                       return -ENODEV;
-               if (b == 0)
-                       break;
-
-       }
-
-       ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x8);
-       /* Turn LED off */
-       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
-
-       ret |= it913x_fe_script_loader(state, it9137_tuner_off);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-/* Power sequence */
-/* Power Up    Tuner on -> Frontend suspend off -> Tuner clk on */
-/* Power Down  Frontend suspend on -> Tuner clk off -> Tuner off */
-
-static int it913x_fe_sleep(struct dvb_frontend *fe)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       return it913x_fe_suspend(state);
-}
-
-static u32 compute_div(u32 a, u32 b, u32 x)
-{
-       u32 res = 0;
-       u32 c = 0;
-       u32 i = 0;
-
-       if (a > b) {
-               c = a / b;
-               a = a - c * b;
-       }
-
-       for (i = 0; i < x; i++) {
-               if (a >= b) {
-                       res += 1;
-                       a -= b;
-               }
-               a <<= 1;
-               res <<= 1;
-       }
-
-       res = (c << x) + res;
-
-       return res;
-}
-
-static int it913x_fe_start(struct it913x_fe_state *state)
-{
-       struct it913xset *set_lna;
-       struct it913xset *set_mode;
-       int ret;
-       u8 adf = (state->config->adf & 0xf);
-       u32 adc, xtal;
-       u8 b[4];
-
-       if (state->config->chip_ver == 1)
-               ret = it913x_init_tuner(state);
-
-       info("ADF table value   :%02x", adf);
-
-       if (adf < 10) {
-               state->crystalFrequency = fe_clockTable[adf].xtal ;
-               state->table = fe_clockTable[adf].table;
-               state->adcFrequency = state->table->adcFrequency;
-
-               adc = compute_div(state->adcFrequency, 1000000ul, 19ul);
-               xtal = compute_div(state->crystalFrequency, 1000000ul, 19ul);
-
-       } else
-               return -EINVAL;
-
-       /* Set LED indicator on GPIOH3 */
-       ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1);
-       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1);
-       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
-
-       ret |= it913x_write_reg(state, PRO_LINK, 0xf641, state->tuner_type);
-       ret |= it913x_write_reg(state, PRO_DMOD, 0xf5ca, 0x01);
-       ret |= it913x_write_reg(state, PRO_DMOD, 0xf715, 0x01);
-
-       b[0] = xtal & 0xff;
-       b[1] = (xtal >> 8) & 0xff;
-       b[2] = (xtal >> 16) & 0xff;
-       b[3] = (xtal >> 24);
-       ret |= it913x_write(state, PRO_DMOD, XTAL_CLK, b , 4);
-
-       b[0] = adc & 0xff;
-       b[1] = (adc >> 8) & 0xff;
-       b[2] = (adc >> 16) & 0xff;
-       ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3);
-
-       if (state->config->adc_x2)
-               ret |= it913x_write_reg(state, PRO_DMOD, ADC_X_2, 0x01);
-       b[0] = 0;
-       b[1] = 0;
-       b[2] = 0;
-       ret |= it913x_write(state, PRO_DMOD, 0x0029, b, 3);
-
-       info("Crystal Frequency :%d Adc Frequency :%d ADC X2: %02x",
-               state->crystalFrequency, state->adcFrequency,
-                       state->config->adc_x2);
-       deb_info("Xtal value :%04x Adc value :%04x", xtal, adc);
-
-       if (ret < 0)
-               return -ENODEV;
-
-       /* v1 or v2 tuner script */
-       if (state->config->chip_ver > 1)
-               ret = it913x_fe_script_loader(state, it9135_v2);
-       else
-               ret = it913x_fe_script_loader(state, it9135_v1);
-       if (ret < 0)
-               return ret;
-
-       /* LNA Scripts */
-       switch (state->tuner_type) {
-       case IT9135_51:
-               set_lna = it9135_51;
-               break;
-       case IT9135_52:
-               set_lna = it9135_52;
-               break;
-       case IT9135_60:
-               set_lna = it9135_60;
-               break;
-       case IT9135_61:
-               set_lna = it9135_61;
-               break;
-       case IT9135_62:
-               set_lna = it9135_62;
-               break;
-       case IT9135_38:
-       default:
-               set_lna = it9135_38;
-       }
-       info("Tuner LNA type :%02x", state->tuner_type);
-
-       ret = it913x_fe_script_loader(state, set_lna);
-       if (ret < 0)
-               return ret;
-
-       if (state->config->chip_ver == 2) {
-               ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1);
-               ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0);
-               ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0);
-               ret |= it913x_init_tuner(state);
-       }
-       if (ret < 0)
-               return -ENODEV;
-
-       /* Always solo frontend */
-       set_mode = set_solo_fe;
-       ret |= it913x_fe_script_loader(state, set_mode);
-
-       ret |= it913x_fe_suspend(state);
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_init(struct dvb_frontend *fe)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret = 0;
-       /* Power Up Tuner - common all versions */
-       ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1);
-
-       ret |= it913x_fe_script_loader(state, init_1);
-
-       ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
-
-       ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static void it913x_fe_release(struct dvb_frontend *fe)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops it913x_fe_ofdm_ops;
-
-struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
-               u8 i2c_addr, struct ite_config *config)
-{
-       struct it913x_fe_state *state = NULL;
-       int ret;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-       if (config == NULL)
-               goto error;
-
-       state->i2c_adap = i2c_adap;
-       state->i2c_addr = i2c_addr;
-       state->config = config;
-
-       switch (state->config->tuner_id_0) {
-       case IT9135_51:
-       case IT9135_52:
-       case IT9135_60:
-       case IT9135_61:
-       case IT9135_62:
-               state->tuner_type = state->config->tuner_id_0;
-               break;
-       default:
-       case IT9135_38:
-               state->tuner_type = IT9135_38;
-       }
-
-       ret = it913x_fe_start(state);
-       if (ret < 0)
-               goto error;
-
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &it913x_fe_ofdm_ops,
-                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(it913x_fe_attach);
-
-static struct dvb_frontend_ops it913x_fe_ofdm_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "it913x-fe DVB-T",
-               .frequency_min          = 51000000,
-               .frequency_max          = 1680000000,
-               .frequency_stepsize     = 62500,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = it913x_fe_release,
-
-       .init = it913x_fe_init,
-       .sleep = it913x_fe_sleep,
-
-       .set_frontend = it913x_fe_set_frontend,
-       .get_frontend = it913x_fe_get_frontend,
-
-       .read_status = it913x_fe_read_status,
-       .read_signal_strength = it913x_fe_read_signal_strength,
-       .read_snr = it913x_fe_read_snr,
-       .read_ber = it913x_fe_read_ber,
-       .read_ucblocks = it913x_fe_read_ucblocks,
-};
-
-MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
-MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
-MODULE_VERSION("1.15");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/it913x-fe.h b/drivers/media/dvb-frontends/it913x-fe.h
deleted file mode 100644 (file)
index df0ad42..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *  Driver for it913x Frontend
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef IT913X_FE_H
-#define IT913X_FE_H
-
-#include <linux/kconfig.h>
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct ite_config {
-       u8 chip_ver;
-       u16 chip_type;
-       u32 firmware;
-       u8 firmware_ver;
-       u8 adc_x2;
-       u8 tuner_id_0;
-       u8 tuner_id_1;
-       u8 dual_mode;
-       u8 adf;
-       /* option to read SIGNAL_LEVEL */
-       u8 read_slevel;
-};
-
-#if IS_ENABLED(CONFIG_DVB_IT913X_FE)
-extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
-                       u8 i2c_addr, struct ite_config *config);
-#else
-static inline struct dvb_frontend *it913x_fe_attach(
-               struct i2c_adapter *i2c_adap,
-                       u8 i2c_addr, struct ite_config *config)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_IT913X_FE */
-#define I2C_BASE_ADDR          0x10
-#define DEV_0                  0x0
-#define DEV_1                  0x10
-#define PRO_LINK               0x0
-#define PRO_DMOD               0x1
-#define DEV_0_DMOD             (PRO_DMOD << 0x7)
-#define DEV_1_DMOD             (DEV_0_DMOD | DEV_1)
-#define CHIP2_I2C_ADDR         0x3a
-
-#define AFE_MEM0               0xfb24
-
-#define MP2_SW_RST             0xf99d
-#define MP2IF2_SW_RST          0xf9a4
-
-#define        PADODPU                 0xd827
-#define THIRDODPU              0xd828
-#define AGC_O_D                        0xd829
-
-#define EP0_TX_EN              0xdd11
-#define EP0_TX_NAK             0xdd13
-#define EP4_TX_LEN_LSB         0xdd88
-#define EP4_TX_LEN_MSB         0xdd89
-#define EP4_MAX_PKT            0xdd0c
-#define EP5_TX_LEN_LSB         0xdd8a
-#define EP5_TX_LEN_MSB         0xdd8b
-#define EP5_MAX_PKT            0xdd0d
-
-#define IO_MUX_POWER_CLK       0xd800
-#define CLK_O_EN               0xd81a
-#define I2C_CLK                        0xf103
-#define I2C_CLK_100            0x7
-#define I2C_CLK_400            0x1a
-
-#define D_TPSD_LOCK            0xf5a9
-#define MP2IF2_EN              0xf9a3
-#define MP2IF_SERIAL           0xf985
-#define TSIS_ENABLE            0xf9cd
-#define MP2IF2_HALF_PSB                0xf9a5
-#define MP2IF_STOP_EN          0xf9b5
-#define MPEG_FULL_SPEED                0xf990
-#define TOP_HOSTB_SER_MODE     0xd91c
-
-#define PID_RST                        0xf992
-#define PID_EN                 0xf993
-#define PID_INX_EN             0xf994
-#define PID_INX                        0xf995
-#define PID_LSB                        0xf996
-#define PID_MSB                        0xf997
-
-#define MP2IF_MPEG_PAR_MODE    0xf986
-#define DCA_UPPER_CHIP         0xf731
-#define DCA_LOWER_CHIP         0xf732
-#define DCA_PLATCH             0xf730
-#define DCA_FPGA_LATCH         0xf778
-#define DCA_STAND_ALONE                0xf73c
-#define DCA_ENABLE             0xf776
-
-#define DVBT_INTEN             0xf41f
-#define DVBT_ENABLE            0xf41a
-#define HOSTB_DCA_LOWER                0xd91f
-#define HOSTB_MPEG_PAR_MODE    0xd91b
-#define HOSTB_MPEG_SER_MODE    0xd91c
-#define HOSTB_MPEG_SER_DO7     0xd91d
-#define HOSTB_DCA_UPPER                0xd91e
-#define PADMISCDR2             0xd830
-#define PADMISCDR4             0xd831
-#define PADMISCDR8             0xd832
-#define PADMISCDRSR            0xd833
-#define LOCK3_OUT              0xd8fd
-
-#define GPIOH1_O               0xd8af
-#define GPIOH1_EN              0xd8b0
-#define GPIOH1_ON              0xd8b1
-#define GPIOH3_O               0xd8b3
-#define GPIOH3_EN              0xd8b4
-#define GPIOH3_ON              0xd8b5
-#define GPIOH5_O               0xd8bb
-#define GPIOH5_EN              0xd8bc
-#define GPIOH5_ON              0xd8bd
-
-#define AFE_MEM0               0xfb24
-
-#define REG_TPSD_TX_MODE       0xf900
-#define REG_TPSD_GI            0xf901
-#define REG_TPSD_HIER          0xf902
-#define REG_TPSD_CONST         0xf903
-#define REG_BW                 0xf904
-#define REG_PRIV               0xf905
-#define REG_TPSD_HP_CODE       0xf906
-#define REG_TPSD_LP_CODE       0xf907
-
-#define MP2IF_SYNC_LK          0xf999
-#define ADC_FREQ               0xf1cd
-
-#define TRIGGER_OFSM           0x0000
-/* COEFF Registers start at 0x0001 to 0x0020 */
-#define COEFF_1_2048           0x0001
-#define XTAL_CLK               0x0025
-#define BFS_FCW                        0x0029
-
-/* Error Regs */
-#define RSD_ABORT_PKT_LSB      0x0032
-#define RSD_ABORT_PKT_MSB      0x0033
-#define RSD_BIT_ERR_0_7                0x0034
-#define RSD_BIT_ERR_8_15       0x0035
-#define RSD_BIT_ERR_23_16      0x0036
-#define RSD_BIT_COUNT_LSB      0x0037
-#define RSD_BIT_COUNT_MSB      0x0038
-
-#define TPSD_LOCK              0x003c
-#define TRAINING_MODE          0x0040
-#define ADC_X_2                        0x0045
-#define TUNER_ID               0x0046
-#define EMPTY_CHANNEL_STATUS   0x0047
-#define SIGNAL_LEVEL           0x0048
-#define SIGNAL_QUALITY         0x0049
-#define EST_SIGNAL_LEVEL       0x004a
-#define FREE_BAND              0x004b
-#define SUSPEND_FLAG           0x004c
-#define VAR_P_INBAND           0x00f7
-
-/* Build in tuner types */
-#define IT9137 0x38
-#define IT9135_38 0x38
-#define IT9135_51 0x51
-#define IT9135_52 0x52
-#define IT9135_60 0x60
-#define IT9135_61 0x61
-#define IT9135_62 0x62
-
-enum {
-       CMD_DEMOD_READ = 0,
-       CMD_DEMOD_WRITE,
-       CMD_TUNER_READ,
-       CMD_TUNER_WRITE,
-       CMD_REG_EEPROM_READ,
-       CMD_REG_EEPROM_WRITE,
-       CMD_DATA_READ,
-       CMD_VAR_READ = 8,
-       CMD_VAR_WRITE,
-       CMD_PLATFORM_GET,
-       CMD_PLATFORM_SET,
-       CMD_IP_CACHE,
-       CMD_IP_ADD,
-       CMD_IP_REMOVE,
-       CMD_PID_ADD,
-       CMD_PID_REMOVE,
-       CMD_SIPSI_GET,
-       CMD_SIPSI_MPE_RESET,
-       CMD_H_PID_ADD = 0x15,
-       CMD_H_PID_REMOVE,
-       CMD_ABORT,
-       CMD_IR_GET,
-       CMD_IR_SET,
-       CMD_FW_DOWNLOAD = 0x21,
-       CMD_QUERYINFO,
-       CMD_BOOT,
-       CMD_FW_DOWNLOAD_BEGIN,
-       CMD_FW_DOWNLOAD_END,
-       CMD_RUN_CODE,
-       CMD_SCATTER_READ = 0x28,
-       CMD_SCATTER_WRITE,
-       CMD_GENERIC_READ,
-       CMD_GENERIC_WRITE
-};
-
-enum {
-       READ_LONG,
-       WRITE_LONG,
-       READ_SHORT,
-       WRITE_SHORT,
-       READ_DATA,
-       WRITE_DATA,
-       WRITE_CMD,
-};
-
-enum {
-       IT9135_AUTO = 0,
-       IT9137_FW,
-       IT9135_V1_FW,
-       IT9135_V2_FW,
-};
-
-#endif /* IT913X_FE_H */
index b8a7897e7bd81210e4f35f43d551541385c37c27..2ef8ce13fb602a984063a0845f9d1ce362935231 100644 (file)
@@ -271,6 +271,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_frequency);
                if (ret)
                        goto err;
+       } else {
+               /*
+                * Use nominal target frequency as tuner driver does not provide
+                * actual frequency used. Carrier offset calculation is not
+                * valid.
+                */
+               tuner_frequency = c->frequency;
        }
 
        /* reset */
@@ -428,18 +435,10 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                goto err;
 
        switch (target_mclk) {
-       case 72000:
-               u8tmp1 = 0x00; /* 0b00 */
-               u8tmp2 = 0x03; /* 0b11 */
-               break;
        case 96000:
                u8tmp1 = 0x02; /* 0b10 */
                u8tmp2 = 0x01; /* 0b01 */
                break;
-       case 115200:
-               u8tmp1 = 0x01; /* 0b01 */
-               u8tmp2 = 0x01; /* 0b01 */
-               break;
        case 144000:
                u8tmp1 = 0x00; /* 0b00 */
                u8tmp2 = 0x01; /* 0b01 */
@@ -448,10 +447,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                u8tmp1 = 0x03; /* 0b11 */
                u8tmp2 = 0x00; /* 0b00 */
                break;
-       default:
-               dev_dbg(&priv->i2c->dev, "%s: invalid target_mclk\n", __func__);
-               ret = -EINVAL;
-               goto err;
        }
 
        ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0);
@@ -711,9 +706,6 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
                case 1:
                        c->inversion = INVERSION_ON;
                        break;
-               default:
-                       dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n",
-                                       __func__);
                }
 
                switch ((buf[1] >> 5) & 0x07) {
@@ -793,9 +785,6 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
                case 1:
                        c->pilot = PILOT_ON;
                        break;
-               default:
-                       dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n",
-                                       __func__);
                }
 
                switch ((buf[0] >> 6) & 0x07) {
@@ -823,9 +812,6 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
                case 1:
                        c->inversion = INVERSION_ON;
                        break;
-               default:
-                       dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n",
-                                       __func__);
                }
 
                switch ((buf[2] >> 0) & 0x03) {
@@ -958,7 +944,7 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
        switch (fe_sec_tone_mode) {
        case SEC_TONE_ON:
                tone = 0;
-               reg_a1_mask = 0x87;
+               reg_a1_mask = 0x47;
                break;
        case SEC_TONE_OFF:
                tone = 1;
index b2351466b0dac0e73b7de1b6ad96698e1ed88c97..32cffca14d0b6ada3e96cdfb8a561c8f0ad1c4a4 100644 (file)
@@ -715,6 +715,22 @@ static int m88rs2000_get_frontend(struct dvb_frontend *fe)
        return 0;
 }
 
+static int m88rs2000_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *tune)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       if (c->symbol_rate > 3000000)
+               tune->min_delay_ms = 2000;
+       else
+               tune->min_delay_ms = 3000;
+
+       tune->step_size = c->symbol_rate / 16000;
+       tune->max_drift = c->symbol_rate / 2000;
+
+       return 0;
+}
+
 static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
        struct m88rs2000_state *state = fe->demodulator_priv;
@@ -746,7 +762,7 @@ static struct dvb_frontend_ops m88rs2000_ops = {
                .symbol_rate_tolerance  = 500,  /* ppm */
                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
                      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                     FE_CAN_QPSK |
+                     FE_CAN_QPSK | FE_CAN_INVERSION_AUTO |
                      FE_CAN_FEC_AUTO
        },
 
@@ -766,6 +782,7 @@ static struct dvb_frontend_ops m88rs2000_ops = {
 
        .set_frontend = m88rs2000_set_frontend,
        .get_frontend = m88rs2000_get_frontend,
+       .get_tune_settings = m88rs2000_get_tune_settings,
 };
 
 struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
index 2c7217fb1415fae76c897d8b5cc31c06c253883d..2f458bb188c738756312ae898aaf5287531bf58b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
  *
- *   Copyright (C) 2010-2013 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2010-2013 Mauro Carvalho Chehab
  *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
  *
  *   This program is free software; you can redistribute it and/or
@@ -2156,5 +2156,5 @@ static struct dvb_frontend_ops mb86a20s_ops = {
 };
 
 MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
index 6627a397608732ca6cdd363a248f7ac646794c92..cbeb941fba7c16c11d7b4c46f82f7be23492aa65 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   Fujitsu mb86a20s driver
  *
- *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2010 Mauro Carvalho Chehab
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License as
index ff73da9365e3c7083a6dea2343f0de0bb27a3bb6..fdbed35c87fa08472dbce4c2b016a7edd6231dd2 100644 (file)
 
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  64
-
-int rtl2832_debug;
-module_param_named(debug, rtl2832_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
 #define REG_MASK(b) (BIT(b + 1) - 1)
 
 static const struct rtl2832_reg_entry registers[] = {
@@ -185,12 +180,13 @@ static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
        buf[0] = reg;
        memcpy(&buf[1], val, len);
 
-       ret = i2c_transfer(priv->i2c, msg, 1);
+       ret = i2c_transfer(priv->i2c_adapter, msg, 1);
        if (ret == 1) {
                ret = 0;
        } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               dev_warn(&priv->i2c->dev,
+                               "%s: i2c wr failed=%d reg=%02x len=%d\n",
+                               KBUILD_MODNAME, ret, reg, len);
                ret = -EREMOTEIO;
        }
        return ret;
@@ -214,12 +210,13 @@ static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
                }
        };
 
-       ret = i2c_transfer(priv->i2c, msg, 2);
+       ret = i2c_transfer(priv->i2c_adapter, msg, 2);
        if (ret == 2) {
                ret = 0;
        } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               dev_warn(&priv->i2c->dev,
+                               "%s: i2c rd failed=%d reg=%02x len=%d\n",
+                               KBUILD_MODNAME, ret, reg, len);
                ret = -EREMOTEIO;
        }
        return ret;
@@ -417,7 +414,7 @@ static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
 
        ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
 
-       return (ret);
+       return ret;
 }
 
 static int rtl2832_init(struct dvb_frontend *fe)
@@ -514,15 +511,10 @@ static int rtl2832_init(struct dvb_frontend *fe)
                        goto err;
        }
 
-       if (!fe->ops.tuner_ops.get_if_frequency) {
-               ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
-               if (ret)
-                       goto err;
-       }
-
        /*
         * r820t NIM code does a software reset here at the demod -
-        * may not be needed, as there's already a software reset at set_params()
+        * may not be needed, as there's already a software reset at
+        * set_params()
         */
 #if 1
        /* soft reset */
@@ -599,9 +591,9 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
        };
 
 
-       dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
-                       "inversion=%d\n", __func__, c->frequency,
-                       c->bandwidth_hz, c->inversion);
+       dev_dbg(&priv->i2c->dev,
+                       "%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
+                       __func__, c->frequency, c->bandwidth_hz, c->inversion);
 
        /* program tuner */
        if (fe->ops.tuner_ops.set_params)
@@ -899,9 +891,149 @@ static void rtl2832_release(struct dvb_frontend *fe)
        struct rtl2832_priv *priv = fe->demodulator_priv;
 
        dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+       cancel_delayed_work_sync(&priv->i2c_gate_work);
+       i2c_del_mux_adapter(priv->i2c_adapter_tuner);
+       i2c_del_mux_adapter(priv->i2c_adapter);
        kfree(priv);
 }
 
+/*
+ * Delay mechanism to avoid unneeded I2C gate open / close. Gate close is
+ * delayed here a little bit in order to see if there is sequence of I2C
+ * messages sent to same I2C bus.
+ * We must use unlocked version of __i2c_transfer() in order to avoid deadlock
+ * as lock is already taken by calling muxed i2c_transfer().
+ */
+static void rtl2832_i2c_gate_work(struct work_struct *work)
+{
+       struct rtl2832_priv *priv = container_of(work,
+                       struct rtl2832_priv, i2c_gate_work.work);
+       struct i2c_adapter *adap = priv->i2c;
+       int ret;
+       u8 buf[2];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       /* select reg bank 1 */
+       buf[0] = 0x00;
+       buf[1] = 0x01;
+       ret = __i2c_transfer(adap, msg, 1);
+       if (ret != 1)
+               goto err;
+
+       priv->page = 1;
+
+       /* close I2C repeater gate */
+       buf[0] = 0x01;
+       buf[1] = 0x10;
+       ret = __i2c_transfer(adap, msg, 1);
+       if (ret != 1)
+               goto err;
+
+       priv->i2c_gate_state = 0;
+
+       return;
+err:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+
+       return;
+}
+
+static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
+{
+       struct rtl2832_priv *priv = mux_priv;
+       int ret;
+       u8 buf[2], val;
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+       struct i2c_msg msg_rd[2] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = "\x01",
+               }, {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = 1,
+                       .buf = &val,
+               }
+       };
+
+       /* terminate possible gate closing */
+       cancel_delayed_work_sync(&priv->i2c_gate_work);
+
+       if (priv->i2c_gate_state == chan_id)
+               return 0;
+
+       /* select reg bank 1 */
+       buf[0] = 0x00;
+       buf[1] = 0x01;
+       ret = __i2c_transfer(adap, msg, 1);
+       if (ret != 1)
+               goto err;
+
+       priv->page = 1;
+
+       /* we must read that register, otherwise there will be errors */
+       ret = __i2c_transfer(adap, msg_rd, 2);
+       if (ret != 2)
+               goto err;
+
+       /* open or close I2C repeater gate */
+       buf[0] = 0x01;
+       if (chan_id == 1)
+               buf[1] = 0x18; /* open */
+       else
+               buf[1] = 0x10; /* close */
+
+       ret = __i2c_transfer(adap, msg, 1);
+       if (ret != 1)
+               goto err;
+
+       priv->i2c_gate_state = chan_id;
+
+       return 0;
+err:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+
+       return -EREMOTEIO;
+}
+
+static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv,
+               u32 chan_id)
+{
+       struct rtl2832_priv *priv = mux_priv;
+       schedule_delayed_work(&priv->i2c_gate_work, usecs_to_jiffies(100));
+       return 0;
+}
+
+struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+       return priv->i2c_adapter_tuner;
+}
+EXPORT_SYMBOL(rtl2832_get_i2c_adapter);
+
+struct i2c_adapter *rtl2832_get_private_i2c_adapter(struct dvb_frontend *fe)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+       return priv->i2c_adapter;
+}
+EXPORT_SYMBOL(rtl2832_get_private_i2c_adapter);
+
 struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
        struct i2c_adapter *i2c)
 {
@@ -920,12 +1052,25 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
        priv->i2c = i2c;
        priv->tuner = cfg->tuner;
        memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
+       INIT_DELAYED_WORK(&priv->i2c_gate_work, rtl2832_i2c_gate_work);
+
+       /* create muxed i2c adapter for demod itself */
+       priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
+                       rtl2832_select, NULL);
+       if (priv->i2c_adapter == NULL)
+               goto err;
 
        /* check if the demod is there */
        ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
        if (ret)
                goto err;
 
+       /* create muxed i2c adapter for demod tuner bus */
+       priv->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, priv,
+                       0, 1, 0, rtl2832_select, rtl2832_deselect);
+       if (priv->i2c_adapter_tuner == NULL)
+               goto err;
+
        /* create dvb_frontend */
        memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
        priv->fe.demodulator_priv = priv;
@@ -936,6 +1081,8 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
        return &priv->fe;
 err:
        dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+       if (priv && priv->i2c_adapter)
+               i2c_del_mux_adapter(priv->i2c_adapter);
        kfree(priv);
        return NULL;
 }
index 2cfbb6a97061b166bac354c964a64a0e5a227eaa..cb3b6b0775b8288b3f71af7c9f47d63b67e6755b 100644 (file)
@@ -37,13 +37,6 @@ struct rtl2832_config {
         */
        u32 xtal;
 
-       /*
-        * IFs for all used modes.
-        * Hz
-        * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
-        */
-       u32 if_dvbt;
-
        /*
         * tuner
         * XXX: This must be keep sync with dvb_usb_rtl28xxu demod driver.
@@ -58,11 +51,21 @@ struct rtl2832_config {
 };
 
 #if IS_ENABLED(CONFIG_DVB_RTL2832)
-extern struct dvb_frontend *rtl2832_attach(
+struct dvb_frontend *rtl2832_attach(
        const struct rtl2832_config *cfg,
        struct i2c_adapter *i2c
 );
+
+extern struct i2c_adapter *rtl2832_get_i2c_adapter(
+       struct dvb_frontend *fe
+);
+
+extern struct i2c_adapter *rtl2832_get_private_i2c_adapter(
+       struct dvb_frontend *fe
+);
+
 #else
+
 static inline struct dvb_frontend *rtl2832_attach(
        const struct rtl2832_config *config,
        struct i2c_adapter *i2c
@@ -71,6 +74,21 @@ static inline struct dvb_frontend *rtl2832_attach(
        pr_warn("%s: driver disabled by Kconfig\n", __func__);
        return NULL;
 }
+
+static inline struct i2c_adapter *rtl2832_get_i2c_adapter(
+       struct dvb_frontend *fe
+)
+{
+       return NULL;
+}
+
+static inline struct i2c_adapter *rtl2832_get_private_i2c_adapter(
+       struct dvb_frontend *fe
+)
+{
+       return NULL;
+}
+
 #endif
 
 
index b5f2b80092eed0fb048404894e2cffec37ef8cb7..ae469f032fe6543f2713e3357ce594e3b27e9cb4 100644 (file)
 
 #include "dvb_frontend.h"
 #include "rtl2832.h"
+#include <linux/i2c-mux.h>
 
 struct rtl2832_priv {
        struct i2c_adapter *i2c;
+       struct i2c_adapter *i2c_adapter;
+       struct i2c_adapter *i2c_adapter_tuner;
        struct dvb_frontend fe;
        struct rtl2832_config cfg;
 
@@ -34,6 +37,7 @@ struct rtl2832_priv {
 
        u8 tuner;
        u8 page; /* active register page */
+       struct delayed_work i2c_gate_work;
 };
 
 struct rtl2832_reg_entry {
@@ -267,7 +271,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = {
        {DVBT_OPT_ADC_IQ,                0x1},
        {DVBT_AD_AVI,                    0x0},
        {DVBT_AD_AVQ,                    0x0},
-       {DVBT_SPEC_INV,                  0x0},
+       {DVBT_SPEC_INV,                  0x0},
 };
 
 static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
@@ -301,7 +305,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
        {DVBT_GI_PGA_STATE,              0x0},
        {DVBT_EN_AGC_PGA,                0x1},
        {DVBT_IF_AGC_MAN,                0x0},
-       {DVBT_SPEC_INV,                  0x0},
+       {DVBT_SPEC_INV,                  0x0},
 };
 
 static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
@@ -339,32 +343,32 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
        {DVBT_REG_MONSEL,                0x1},
        {DVBT_REG_MON,                   0x1},
        {DVBT_REG_4MSEL,                 0x0},
-       {DVBT_SPEC_INV,                  0x0},
+       {DVBT_SPEC_INV,                  0x0},
 };
 
 static const struct rtl2832_reg_value rtl2832_tuner_init_r820t[] = {
-       {DVBT_DAGC_TRG_VAL,             0x39},
-       {DVBT_AGC_TARG_VAL_0,           0x0},
-       {DVBT_AGC_TARG_VAL_8_1,         0x40},
-       {DVBT_AAGC_LOOP_GAIN,           0x16},
-       {DVBT_LOOP_GAIN2_3_0,           0x8},
-       {DVBT_LOOP_GAIN2_4,             0x1},
-       {DVBT_LOOP_GAIN3,               0x18},
-       {DVBT_VTOP1,                    0x35},
-       {DVBT_VTOP2,                    0x21},
-       {DVBT_VTOP3,                    0x21},
-       {DVBT_KRF1,                     0x0},
-       {DVBT_KRF2,                     0x40},
-       {DVBT_KRF3,                     0x10},
-       {DVBT_KRF4,                     0x10},
-       {DVBT_IF_AGC_MIN,               0x80},
-       {DVBT_IF_AGC_MAX,               0x7f},
-       {DVBT_RF_AGC_MIN,               0x80},
-       {DVBT_RF_AGC_MAX,               0x7f},
-       {DVBT_POLAR_RF_AGC,             0x0},
-       {DVBT_POLAR_IF_AGC,             0x0},
-       {DVBT_AD7_SETTING,              0xe9f4},
-       {DVBT_SPEC_INV,                 0x1},
+       {DVBT_DAGC_TRG_VAL,             0x39},
+       {DVBT_AGC_TARG_VAL_0,            0x0},
+       {DVBT_AGC_TARG_VAL_8_1,         0x40},
+       {DVBT_AAGC_LOOP_GAIN,           0x16},
+       {DVBT_LOOP_GAIN2_3_0,            0x8},
+       {DVBT_LOOP_GAIN2_4,              0x1},
+       {DVBT_LOOP_GAIN3,               0x18},
+       {DVBT_VTOP1,                    0x35},
+       {DVBT_VTOP2,                    0x21},
+       {DVBT_VTOP3,                    0x21},
+       {DVBT_KRF1,                      0x0},
+       {DVBT_KRF2,                     0x40},
+       {DVBT_KRF3,                     0x10},
+       {DVBT_KRF4,                     0x10},
+       {DVBT_IF_AGC_MIN,               0x80},
+       {DVBT_IF_AGC_MAX,               0x7f},
+       {DVBT_RF_AGC_MIN,               0x80},
+       {DVBT_RF_AGC_MAX,               0x7f},
+       {DVBT_POLAR_RF_AGC,              0x0},
+       {DVBT_POLAR_IF_AGC,              0x0},
+       {DVBT_AD7_SETTING,            0xe9f4},
+       {DVBT_SPEC_INV,                  0x1},
 };
 
 #endif /* RTL2832_PRIV_H */
index a271ac3eaec04dc4e85c62a616837bfb4f27ff4f..69862e1fd9e9d514e5e1f8ff927e2259b938880c 100644 (file)
@@ -2,7 +2,7 @@
  *   Sharp VA3A5JZ921 One Seg Broadcast Module driver
  *   This device is labeled as just S. 921 at the top of the frontend can
  *
- *   Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2009-2010 Mauro Carvalho Chehab
  *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
  *
  *   Developed for Leadership SBTVD 1seg device sold in Brazil
@@ -539,6 +539,6 @@ static struct dvb_frontend_ops s921_ops = {
 };
 
 MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
 MODULE_LICENSE("GPL");
index 8d5e2a6e187c55c00384450a81eba3776112838f..9b20c9e0eb88d7f18f6df0fda01f673ded6108f4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   Sharp s921 driver
  *
- *   Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2009 Mauro Carvalho Chehab
  *   Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
  *
  *   This program is free software; you can redistribute it and/or
index cea175d1989076e8f53cc3550efefe7a48dabf88..4ef8a5c7003e907c2836e3ad77f6306fbafe1576 100644 (file)
@@ -193,7 +193,7 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
                .len    = len + 1
        };
 
-       if (1 + len > sizeof(buf)) {
+       if (1 + len > sizeof(cmdbuf)) {
                printk(KERN_WARNING
                       "%s: i2c wr: len=%d is too big!\n",
                       KBUILD_MODNAME, len);
index 0a40edfad73945423049ce48892c62bd7c1a9836..4ce1d260b3eba1b7e4acdce23345df8b2108e0f3 100644 (file)
@@ -1081,7 +1081,7 @@ static int stv0900_wait_for_lock(struct stv0900_internal *intp,
        lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
 
        if (lock)
-               lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
+               lock = stv0900_get_fec_lock(intp, demod, fec_timeout);
 
        if (lock) {
                lock = 0;
index 8ad3a57cf64032446fb50fc28d2cfce6739bb18b..522fe00f5eee167f6fa59a657aaad1b4dce55783 100644 (file)
@@ -42,8 +42,8 @@ static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
 
        if (1 + len > sizeof(buf)) {
                dev_warn(&priv->i2c->dev,
-                        "%s: i2c wr reg=%04x: len=%d is too big!\n",
-                        KBUILD_MODNAME, reg, len);
+                               "%s: i2c wr reg=%04x: len=%d is too big!\n",
+                               KBUILD_MODNAME, reg, len);
                return -EINVAL;
        }
 
@@ -54,8 +54,9 @@ static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
        if (ret == 1) {
                ret = 0;
        } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               dev_warn(&priv->i2c->dev,
+                               "%s: i2c wr failed=%d reg=%02x len=%d\n",
+                               KBUILD_MODNAME, ret, reg, len);
                ret = -EREMOTEIO;
        }
        return ret;
@@ -83,8 +84,8 @@ static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
 
        if (len > sizeof(buf)) {
                dev_warn(&priv->i2c->dev,
-                        "%s: i2c wr reg=%04x: len=%d is too big!\n",
-                        KBUILD_MODNAME, reg, len);
+                               "%s: i2c wr reg=%04x: len=%d is too big!\n",
+                               KBUILD_MODNAME, reg, len);
                return -EINVAL;
        }
 
@@ -93,8 +94,9 @@ static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
                memcpy(val, buf, len);
                ret = 0;
        } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               dev_warn(&priv->i2c->dev,
+                               "%s: i2c rd failed=%d reg=%02x len=%d\n",
+                               KBUILD_MODNAME, ret, reg, len);
                ret = -EREMOTEIO;
        }
        return ret;
@@ -491,10 +493,9 @@ static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status)
        if (ret)
                goto error;
 
-       if (tmp & 0x01) /* tuner PLL */
-               *status |= FE_HAS_SIGNAL;
+       /* 0x39[0] tuner PLL */
        if (tmp & 0x02) /* demod PLL */
-               *status |= FE_HAS_CARRIER;
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
        if (tmp & 0x04) /* viterbi or LDPC*/
                *status |= FE_HAS_VITERBI;
        if (tmp & 0x08) /* RS or BCH */
@@ -668,11 +669,11 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
        int ret, i;
        u8 mode, rolloff, pilot, inversion, div;
 
-       dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
-               "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
-               "rolloff=%d\n", __func__, c->delivery_system, c->modulation,
-               c->frequency, c->symbol_rate, c->inversion, c->pilot,
-               c->rolloff);
+       dev_dbg(&priv->i2c->dev,
+                       "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
+                       __func__, c->delivery_system, c->modulation,
+                       c->frequency, c->symbol_rate, c->inversion, c->pilot,
+                       c->rolloff);
 
        priv->delivery_system = SYS_UNDEFINED;
 
@@ -952,10 +953,8 @@ static int tda10071_init(struct dvb_frontend *fe)
                /* request the firmware, this will block and timeout */
                ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
                if (ret) {
-                       dev_err(&priv->i2c->dev, "%s: did not find the " \
-                                       "firmware file. (%s) Please see " \
-                                       "linux/Documentation/dvb/ for more " \
-                                       "details on firmware-problems. (%d)\n",
+                       dev_err(&priv->i2c->dev,
+                                       "%s: did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)\n",
                                        KBUILD_MODNAME, fw_file, ret);
                        goto error;
                }
@@ -985,11 +984,12 @@ static int tda10071_init(struct dvb_frontend *fe)
                if (ret)
                        goto error_release_firmware;
 
-               dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \
-                               "will try to load a firmware\n", KBUILD_MODNAME,
-                               tda10071_ops.info.name);
-               dev_info(&priv->i2c->dev, "%s: downloading firmware from " \
-                               "file '%s'\n", KBUILD_MODNAME, fw_file);
+               dev_info(&priv->i2c->dev,
+                               "%s: found a '%s' in cold state, will try to load a firmware\n",
+                               KBUILD_MODNAME, tda10071_ops.info.name);
+               dev_info(&priv->i2c->dev,
+                               "%s: downloading firmware from file '%s'\n",
+                               KBUILD_MODNAME, fw_file);
 
                /* do not download last byte */
                fw_size = fw->size - 1;
@@ -1003,11 +1003,10 @@ static int tda10071_init(struct dvb_frontend *fe)
                        ret = tda10071_wr_regs(priv, 0xfa,
                                (u8 *) &fw->data[fw_size - remaining], len);
                        if (ret) {
-                               dev_err(&priv->i2c->dev, "%s: firmware " \
-                                               "download failed=%d\n",
+                               dev_err(&priv->i2c->dev,
+                                               "%s: firmware download failed=%d\n",
                                                KBUILD_MODNAME, ret);
-                               if (ret)
-                                       goto error_release_firmware;
+                               goto error_release_firmware;
                        }
                }
                release_firmware(fw);
@@ -1069,12 +1068,17 @@ static int tda10071_init(struct dvb_frontend *fe)
                if (ret)
                        goto error;
 
+               if (priv->cfg.tuner_i2c_addr)
+                       tmp = priv->cfg.tuner_i2c_addr;
+               else
+                       tmp = 0x14;
+
                cmd.args[0] = CMD_TUNER_INIT;
                cmd.args[1] = 0x00;
                cmd.args[2] = 0x00;
                cmd.args[3] = 0x00;
                cmd.args[4] = 0x00;
-               cmd.args[5] = (priv->cfg.tuner_i2c_addr) ? priv->cfg.tuner_i2c_addr : 0x14;
+               cmd.args[5] = tmp;
                cmd.args[6] = 0x00;
                cmd.args[7] = 0x03;
                cmd.args[8] = 0x02;
@@ -1214,14 +1218,14 @@ struct dvb_frontend *tda10071_attach(const struct tda10071_config *config,
 
        /* make sure demod i2c address is specified */
        if (!config->demod_i2c_addr) {
-               dev_dbg(&i2c->dev, "%s: invalid demod i2c address!\n", __func__);
+               dev_dbg(&i2c->dev, "%s: invalid demod i2c address\n", __func__);
                ret = -EINVAL;
                goto error;
        }
 
        /* make sure tuner i2c address is specified */
        if (!config->tuner_i2c_addr) {
-               dev_dbg(&i2c->dev, "%s: invalid tuner i2c address!\n", __func__);
+               dev_dbg(&i2c->dev, "%s: invalid tuner i2c address\n", __func__);
                ret = -EINVAL;
                goto error;
        }
index f9542f68fe78f6c4eb79b194a99b3cb18ac71588..331b5a819383dbad3464ecb8bfaac9ac5a2dc89f 100644 (file)
@@ -79,7 +79,7 @@ extern struct dvb_frontend *tda10071_attach(
 static inline struct dvb_frontend *tda10071_attach(
        const struct tda10071_config *config, struct i2c_adapter *i2c)
 {
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
        return NULL;
 }
 #endif
index 4aa9c5311cc506c6cca0a61c83b48402ae5fe684..441053be7f5520aeaae391336b2b689f77add681 100644 (file)
@@ -196,7 +196,7 @@ config VIDEO_ADV7183
 
 config VIDEO_ADV7604
        tristate "Analog Devices ADV7604 decoder"
-       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
        ---help---
          Support for the Analog Devices ADV7604 video decoder.
 
@@ -208,7 +208,7 @@ config VIDEO_ADV7604
 
 config VIDEO_ADV7842
        tristate "Analog Devices ADV7842 decoder"
-       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
        ---help---
          Support for the Analog Devices ADV7842 video decoder.
 
@@ -431,7 +431,7 @@ config VIDEO_ADV7393
 
 config VIDEO_ADV7511
        tristate "Analog Devices ADV7511 encoder"
-       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
        ---help---
          Support for the Analog Devices ADV7511 video encoder.
 
@@ -579,6 +579,14 @@ config VIDEO_S5K6AA
          This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
          camera sensor with an embedded SoC image signal processor.
 
+config VIDEO_S5K6A3
+       tristate "Samsung S5K6A3 sensor support"
+       depends on MEDIA_CAMERA_SUPPORT
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       ---help---
+         This is a V4L2 sensor-level driver for Samsung S5K6A3 raw
+         camera sensor.
+
 config VIDEO_S5K4ECGX
         tristate "Samsung S5K4ECGX sensor support"
         depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
@@ -629,6 +637,15 @@ config VIDEO_LM3560
          This is a driver for the lm3560 dual flash controllers. It controls
          flash, torch LEDs.
 
+config VIDEO_LM3646
+       tristate "LM3646 dual flash driver support"
+       depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+       depends on MEDIA_CAMERA_SUPPORT
+       select REGMAP_I2C
+       ---help---
+         This is a driver for the lm3646 dual flash controllers. It controls
+         flash, torch LEDs.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
@@ -659,6 +676,7 @@ comment "Audio/Video compression chips"
 config VIDEO_SAA6752HS
        tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder"
        depends on VIDEO_V4L2 && I2C
+       select CRC32
        ---help---
          Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3
          audio encoder with multiplexer.
index 48888ae876fb36f2b83080619f2605f9ae62563d..01ae9328e5821e6ec2b70b46b915865efc8c8cf3 100644 (file)
@@ -66,12 +66,14 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
 obj-$(CONFIG_VIDEO_SR030PC30)  += sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)        += noon010pc30.o
 obj-$(CONFIG_VIDEO_S5K6AA)     += s5k6aa.o
+obj-$(CONFIG_VIDEO_S5K6A3)     += s5k6a3.o
 obj-$(CONFIG_VIDEO_S5K4ECGX)   += s5k4ecgx.o
 obj-$(CONFIG_VIDEO_S5K5BAF)    += s5k5baf.o
 obj-$(CONFIG_VIDEO_S5C73M3)    += s5c73m3/
 obj-$(CONFIG_VIDEO_ADP1653)    += adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)    += as3645a.o
 obj-$(CONFIG_VIDEO_LM3560)     += lm3560.o
+obj-$(CONFIG_VIDEO_LM3646)     += lm3646.o
 obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
 obj-$(CONFIG_VIDEO_AK881X)             += ak881x.o
 obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
index 83225d6a0dd96069f62976ae5255deeee4374005..1b7ecfd88673b2c27d6de1d12520b6c4e43ece4a 100644 (file)
@@ -573,7 +573,7 @@ static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
 
 /* ------------------------------ PAD OPS ------------------------------ */
 
-static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 {
        struct ad9389b_state *state = get_ad9389b_state(sd);
 
index d7d99f1c69e4f9459d0515a9eb8769dd182900c3..5e638b1594529242ea20128253bbe37d99586d2f 100644 (file)
 struct adv7180_state {
        struct v4l2_ctrl_handler ctrl_hdl;
        struct v4l2_subdev      sd;
-       struct work_struct      work;
        struct mutex            mutex; /* mutual excl. when accessing chip */
        int                     irq;
        v4l2_std_id             curr_norm;
        bool                    autodetect;
+       bool                    powered;
        u8                      input;
 };
 #define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler,            \
@@ -312,6 +312,37 @@ out:
        return ret;
 }
 
+static int adv7180_set_power(struct adv7180_state *state,
+       struct i2c_client *client, bool on)
+{
+       u8 val;
+
+       if (on)
+               val = ADV7180_PWR_MAN_ON;
+       else
+               val = ADV7180_PWR_MAN_OFF;
+
+       return i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG, val);
+}
+
+static int adv7180_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct adv7180_state *state = to_state(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+
+       ret = mutex_lock_interruptible(&state->mutex);
+       if (ret)
+               return ret;
+
+       ret = adv7180_set_power(state, client, on);
+       if (ret == 0)
+               state->powered = on;
+
+       mutex_unlock(&state->mutex);
+       return ret;
+}
+
 static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
@@ -442,6 +473,7 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
        .s_std = adv7180_s_std,
+       .s_power = adv7180_s_power,
 };
 
 static const struct v4l2_subdev_ops adv7180_ops = {
@@ -449,10 +481,9 @@ static const struct v4l2_subdev_ops adv7180_ops = {
        .video = &adv7180_video_ops,
 };
 
-static void adv7180_work(struct work_struct *work)
+static irqreturn_t adv7180_irq(int irq, void *devid)
 {
-       struct adv7180_state *state = container_of(work, struct adv7180_state,
-                                                  work);
+       struct adv7180_state *state = devid;
        struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
        u8 isr3;
 
@@ -468,17 +499,6 @@ static void adv7180_work(struct work_struct *work)
                __adv7180_status(client, NULL, &state->curr_norm);
        mutex_unlock(&state->mutex);
 
-       enable_irq(state->irq);
-}
-
-static irqreturn_t adv7180_irq(int irq, void *devid)
-{
-       struct adv7180_state *state = devid;
-
-       schedule_work(&state->work);
-
-       disable_irq_nosync(state->irq);
-
        return IRQ_HANDLED;
 }
 
@@ -533,48 +553,52 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state)
 
        /* register for interrupts */
        if (state->irq > 0) {
-               ret = request_irq(state->irq, adv7180_irq, 0, KBUILD_MODNAME,
-                                 state);
+               ret = request_threaded_irq(state->irq, NULL, adv7180_irq,
+                                          IRQF_ONESHOT, KBUILD_MODNAME, state);
                if (ret)
                        return ret;
 
                ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
                                                ADV7180_ADI_CTRL_IRQ_SPACE);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                /* config the Interrupt pin to be active low */
                ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
                                                ADV7180_ICONF1_ACTIVE_LOW |
                                                ADV7180_ICONF1_PSYNC_ONLY);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                /* enable AD change interrupts interrupts */
                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
                                                ADV7180_IRQ3_AD_CHANGE);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
                                                0);
                if (ret < 0)
-                       return ret;
+                       goto err;
        }
 
        return 0;
+
+err:
+       free_irq(state->irq, state);
+       return ret;
 }
 
 static int adv7180_probe(struct i2c_client *client,
@@ -598,9 +622,9 @@ static int adv7180_probe(struct i2c_client *client,
        }
 
        state->irq = client->irq;
-       INIT_WORK(&state->work, adv7180_work);
        mutex_init(&state->mutex);
        state->autodetect = true;
+       state->powered = true;
        state->input = 0;
        sd = &state->sd;
        v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
@@ -611,15 +635,21 @@ static int adv7180_probe(struct i2c_client *client,
        ret = init_device(client, state);
        if (ret)
                goto err_free_ctrl;
+
+       ret = v4l2_async_register_subdev(sd);
+       if (ret)
+               goto err_free_irq;
+
        return 0;
 
+err_free_irq:
+       if (state->irq > 0)
+               free_irq(client->irq, state);
 err_free_ctrl:
        adv7180_exit_controls(state);
 err_unreg_subdev:
        mutex_destroy(&state->mutex);
-       v4l2_device_unregister_subdev(sd);
 err:
-       printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
        return ret;
 }
 
@@ -628,20 +658,14 @@ static int adv7180_remove(struct i2c_client *client)
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
        struct adv7180_state *state = to_state(sd);
 
-       if (state->irq > 0) {
+       v4l2_async_unregister_subdev(sd);
+
+       if (state->irq > 0)
                free_irq(client->irq, state);
-               if (cancel_work_sync(&state->work)) {
-                       /*
-                        * Work was pending, therefore we need to enable
-                        * IRQ here to balance the disable_irq() done in the
-                        * interrupt handler.
-                        */
-                       enable_irq(state->irq);
-               }
-       }
 
-       mutex_destroy(&state->mutex);
        v4l2_device_unregister_subdev(sd);
+       adv7180_exit_controls(state);
+       mutex_destroy(&state->mutex);
        return 0;
 }
 
@@ -654,13 +678,10 @@ static const struct i2c_device_id adv7180_id[] = {
 static int adv7180_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
-       int ret;
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct adv7180_state *state = to_state(sd);
 
-       ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
-                                       ADV7180_PWR_MAN_OFF);
-       if (ret < 0)
-               return ret;
-       return 0;
+       return adv7180_set_power(state, client, false);
 }
 
 static int adv7180_resume(struct device *dev)
@@ -670,10 +691,11 @@ static int adv7180_resume(struct device *dev)
        struct adv7180_state *state = to_state(sd);
        int ret;
 
-       ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
-                                       ADV7180_PWR_MAN_ON);
-       if (ret < 0)
-               return ret;
+       if (state->powered) {
+               ret = adv7180_set_power(state, client, true);
+               if (ret)
+                       return ret;
+       }
        ret = init_device(client, state);
        if (ret < 0)
                return ret;
index ee618942cb8eca1ec3ca2f6c50421e5b492075c7..942ca4b99297954d365580162a3934e389f77f1d 100644 (file)
@@ -597,7 +597,7 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
        return 0;
 }
 
-static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 {
        struct adv7511_state *state = get_adv7511_state(sd);
 
index 71c8570bd9eafd3dab56faf9b8fdf2453415e193..98cc5407f1b12935f817f8f63902dada77d1355c 100644 (file)
@@ -1658,7 +1658,7 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
        return 0;
 }
 
-static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 {
        struct adv7604_state *state = to_state(sd);
        u8 *data = NULL;
@@ -1728,7 +1728,7 @@ static int get_edid_spa_location(const u8 *edid)
        return -1;
 }
 
-static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 {
        struct adv7604_state *state = to_state(sd);
        int spa_loc;
index 9bbd6656fb8ff72fcb14e440bbecf633d353d6b1..636ac08925f66de45514101c75c93c6e392075d8 100644 (file)
@@ -546,6 +546,14 @@ static void main_reset(struct v4l2_subdev *sd)
 
 /* ----------------------------------------------------------------------- */
 
+static inline bool is_analog_input(struct v4l2_subdev *sd)
+{
+       struct adv7842_state *state = to_state(sd);
+
+       return ((state->mode == ADV7842_MODE_RGB) ||
+               (state->mode == ADV7842_MODE_COMP));
+}
+
 static inline bool is_digital_input(struct v4l2_subdev *sd)
 {
        struct adv7842_state *state = to_state(sd);
@@ -1027,12 +1035,72 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
        cp_write(sd, 0xac, (height & 0x0f) << 4);
 }
 
+static void adv7842_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 offset_a, u16 offset_b, u16 offset_c)
+{
+       struct adv7842_state *state = to_state(sd);
+       u8 offset_buf[4];
+
+       if (auto_offset) {
+               offset_a = 0x3ff;
+               offset_b = 0x3ff;
+               offset_c = 0x3ff;
+       }
+
+       v4l2_dbg(2, debug, sd, "%s: %s offset: a = 0x%x, b = 0x%x, c = 0x%x\n",
+                __func__, auto_offset ? "Auto" : "Manual",
+                offset_a, offset_b, offset_c);
+
+       offset_buf[0]= (cp_read(sd, 0x77) & 0xc0) | ((offset_a & 0x3f0) >> 4);
+       offset_buf[1] = ((offset_a & 0x00f) << 4) | ((offset_b & 0x3c0) >> 6);
+       offset_buf[2] = ((offset_b & 0x03f) << 2) | ((offset_c & 0x300) >> 8);
+       offset_buf[3] = offset_c & 0x0ff;
+
+       /* Registers must be written in this order with no i2c access in between */
+       if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf))
+               v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__);
+}
+
+static void adv7842_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, u16 gain_b, u16 gain_c)
+{
+       struct adv7842_state *state = to_state(sd);
+       u8 gain_buf[4];
+       u8 gain_man = 1;
+       u8 agc_mode_man = 1;
+
+       if (auto_gain) {
+               gain_man = 0;
+               agc_mode_man = 0;
+               gain_a = 0x100;
+               gain_b = 0x100;
+               gain_c = 0x100;
+       }
+
+       v4l2_dbg(2, debug, sd, "%s: %s gain: a = 0x%x, b = 0x%x, c = 0x%x\n",
+                __func__, auto_gain ? "Auto" : "Manual",
+                gain_a, gain_b, gain_c);
+
+       gain_buf[0] = ((gain_man << 7) | (agc_mode_man << 6) | ((gain_a & 0x3f0) >> 4));
+       gain_buf[1] = (((gain_a & 0x00f) << 4) | ((gain_b & 0x3c0) >> 6));
+       gain_buf[2] = (((gain_b & 0x03f) << 2) | ((gain_c & 0x300) >> 8));
+       gain_buf[3] = ((gain_c & 0x0ff));
+
+       /* Registers must be written in this order with no i2c access in between */
+       if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf))
+               v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__);
+}
+
 static void set_rgb_quantization_range(struct v4l2_subdev *sd)
 {
        struct adv7842_state *state = to_state(sd);
+       bool rgb_output = io_read(sd, 0x02) & 0x02;
+       bool hdmi_signal = hdmi_read(sd, 0x05) & 0x80;
+
+       v4l2_dbg(2, debug, sd, "%s: RGB quantization range: %d, RGB out: %d, HDMI: %d\n",
+                       __func__, state->rgb_quantization_range,
+                       rgb_output, hdmi_signal);
 
-       v4l2_dbg(2, debug, sd, "%s: rgb_quantization_range = %d\n",
-                      __func__, state->rgb_quantization_range);
+       adv7842_set_gain(sd, true, 0x0, 0x0, 0x0);
+       adv7842_set_offset(sd, true, 0x0, 0x0, 0x0);
 
        switch (state->rgb_quantization_range) {
        case V4L2_DV_RGB_RANGE_AUTO:
@@ -1050,7 +1118,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
                        break;
                }
 
-               if (hdmi_read(sd, 0x05) & 0x80) {
+               if (hdmi_signal) {
                        /* Receiving HDMI signal
                         * Set automode */
                        io_write_and_or(sd, 0x02, 0x0f, 0xf0);
@@ -1066,24 +1134,45 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
                } else {
                        /* RGB full range (0-255) */
                        io_write_and_or(sd, 0x02, 0x0f, 0x10);
+
+                       if (is_digital_input(sd) && rgb_output) {
+                               adv7842_set_offset(sd, false, 0x40, 0x40, 0x40);
+                       } else {
+                               adv7842_set_gain(sd, false, 0xe0, 0xe0, 0xe0);
+                               adv7842_set_offset(sd, false, 0x70, 0x70, 0x70);
+                       }
                }
                break;
        case V4L2_DV_RGB_RANGE_LIMITED:
                if (state->mode == ADV7842_MODE_COMP) {
                        /* YCrCb limited range (16-235) */
                        io_write_and_or(sd, 0x02, 0x0f, 0x20);
-               } else {
-                       /* RGB limited range (16-235) */
-                       io_write_and_or(sd, 0x02, 0x0f, 0x00);
+                       break;
                }
+
+               /* RGB limited range (16-235) */
+               io_write_and_or(sd, 0x02, 0x0f, 0x00);
+
                break;
        case V4L2_DV_RGB_RANGE_FULL:
                if (state->mode == ADV7842_MODE_COMP) {
                        /* YCrCb full range (0-255) */
                        io_write_and_or(sd, 0x02, 0x0f, 0x60);
+                       break;
+               }
+
+               /* RGB full range (0-255) */
+               io_write_and_or(sd, 0x02, 0x0f, 0x10);
+
+               if (is_analog_input(sd) || hdmi_signal)
+                       break;
+
+               /* Adjust gain/offset for DVI-D signals only */
+               if (rgb_output) {
+                       adv7842_set_offset(sd, false, 0x40, 0x40, 0x40);
                } else {
-                       /* RGB full range (0-255) */
-                       io_write_and_or(sd, 0x02, 0x0f, 0x10);
+                       adv7842_set_gain(sd, false, 0xe0, 0xe0, 0xe0);
+                       adv7842_set_offset(sd, false, 0x70, 0x70, 0x70);
                }
                break;
        }
@@ -1360,12 +1449,11 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
 
                bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08);
                bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a);
-               freq = (hdmi_read(sd, 0x06) * 1000000) +
-                      ((hdmi_read(sd, 0x3b) & 0x30) >> 4) * 250000;
-
+               freq = ((hdmi_read(sd, 0x51) << 1) + (hdmi_read(sd, 0x52) >> 7)) * 1000000;
+               freq += ((hdmi_read(sd, 0x52) & 0x7f) * 7813);
                if (is_hdmi(sd)) {
                        /* adjust for deep color mode */
-                       freq = freq * 8 / (((hdmi_read(sd, 0x0b) & 0xc0) >> 5) + 8);
+                       freq = freq * 8 / (((hdmi_read(sd, 0x0b) & 0xc0) >> 6) * 2 + 8);
                }
                bt->pixelclock = freq;
                bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x03) * 256 +
@@ -1717,8 +1805,8 @@ static void select_input(struct v4l2_subdev *sd,
                 * (rev. 2.5, June 2010)" p. 17. */
                afe_write(sd, 0x12, 0xfb); /* ADC noise shaping filter controls */
                afe_write(sd, 0x0c, 0x0d); /* CP core gain controls */
-               cp_write(sd, 0x3e, 0x80); /* CP core pre-gain control,
-                                            enable color control */
+               cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */
+
                /* CP coast control */
                cp_write(sd, 0xc3, 0x33); /* Component mode */
 
@@ -1926,7 +2014,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
        return 0;
 }
 
-static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 {
        struct adv7842_state *state = to_state(sd);
        u8 *data = NULL;
@@ -1966,7 +2054,7 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi
        return 0;
 }
 
-static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
+static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
 {
        struct adv7842_state *state = to_state(sd);
        int err = 0;
@@ -2103,7 +2191,8 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
 {
        int i;
        uint8_t buf[14];
-       uint8_t avi_inf_len;
+       u8 avi_len;
+       u8 avi_ver;
        struct avi_info_frame avi;
 
        if (!(hdmi_read(sd, 0x05) & 0x80)) {
@@ -2116,18 +2205,20 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
        }
 
        if (io_read(sd, 0x88) & 0x10) {
-               /* Note: the ADV7842 calculated incorrect checksums for InfoFrames
-                  with a length of 14 or 15. See the ADV7842 Register Settings
-                  Recommendations document for more details. */
-               v4l2_info(sd, "AVI infoframe checksum error\n");
-               return;
+               v4l2_info(sd, "AVI infoframe checksum error has occurred earlier\n");
+               io_write(sd, 0x8a, 0x10); /* clear AVI_INF_CKS_ERR_RAW */
+               if (io_read(sd, 0x88) & 0x10) {
+                       v4l2_info(sd, "AVI infoframe checksum error still present\n");
+                       io_write(sd, 0x8a, 0x10); /* clear AVI_INF_CKS_ERR_RAW */
+               }
        }
 
-       avi_inf_len = infoframe_read(sd, 0xe2);
+       avi_len = infoframe_read(sd, 0xe2);
+       avi_ver = infoframe_read(sd, 0xe1);
        v4l2_info(sd, "AVI infoframe version %d (%d byte)\n",
-                 infoframe_read(sd, 0xe1), avi_inf_len);
+                 avi_ver, avi_len);
 
-       if (infoframe_read(sd, 0xe1) != 0x02)
+       if (avi_ver != 0x02)
                return;
 
        for (i = 0; i < 14; i++)
@@ -2602,9 +2693,15 @@ static int adv7842_core_init(struct v4l2_subdev *sd)
        /* disable I2C access to internal EDID ram from HDMI DDC ports */
        rep_write_and_or(sd, 0x77, 0xf3, 0x00);
 
-       hdmi_write(sd, 0x69, 0xa3); /* HPA manual */
-       /* HPA disable on port A and B */
-       io_write_and_or(sd, 0x20, 0xcf, 0x00);
+       if (pdata->hpa_auto) {
+               /* HPA auto, HPA 0.5s after Edid set and Cable detect */
+               hdmi_write(sd, 0x69, 0x5c);
+       } else {
+               /* HPA manual */
+               hdmi_write(sd, 0x69, 0xa3);
+               /* HPA disable on port A and B */
+               io_write_and_or(sd, 0x20, 0xcf, 0x00);
+       }
 
        /* LLC */
        io_write(sd, 0x19, 0x80 | pdata->llc_dll_phase);
index 99ee456700f4972ef53888d692aa5f4b19930bce..c8fe1358ec9e14b24db0d465878104f730e407c9 100644 (file)
@@ -431,8 +431,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
         * Initialize the other fields of rc_dev
         */
        rc->map_name       = ir->ir_codes;
-       rc->allowed_protos = rc_type;
-       rc->enabled_protocols = rc_type;
+       rc_set_allowed_protocols(rc, rc_type);
+       rc_set_enabled_protocols(rc, rc_type);
        if (!rc->driver_name)
                rc->driver_name = MODULE_NAME;
 
index d98ca3aebe235d7ae494ec2381ebe801899f6aa1..c23de593c17d5572ff2123403ad6e4e006d21e55 100644 (file)
  * WITHOUT 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/delay.h>
@@ -42,7 +36,7 @@
 #define REG_FLAG               0xd0
 #define REG_CONFIG1            0xe0
 
-/* Fault Mask */
+/* fault mask */
 #define FAULT_TIMEOUT  (1<<0)
 #define FAULT_OVERTEMP (1<<1)
 #define FAULT_SHORT_CIRCUIT    (1<<2)
@@ -53,7 +47,8 @@ enum led_enable {
        MODE_FLASH = 0x3,
 };
 
-/* struct lm3560_flash
+/**
+ * struct lm3560_flash
  *
  * @pdata: platform data
  * @regmap: reg. map for i2c
@@ -98,7 +93,7 @@ static int lm3560_mode_ctrl(struct lm3560_flash *flash)
        return rval;
 }
 
-/* led1/2  enable/disable */
+/* led1/2 enable/disable */
 static int lm3560_enable_ctrl(struct lm3560_flash *flash,
                              enum lm3560_led_id led_no, bool on)
 {
@@ -168,7 +163,7 @@ static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash,
        return rval;
 }
 
-/* V4L2 controls  */
+/* v4l2 controls  */
 static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
 {
        struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
@@ -297,6 +292,7 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
        const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no];
 
        v4l2_ctrl_handler_init(hdl, 8);
+
        /* flash mode */
        v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE,
                               V4L2_FLASH_LED_MODE_TORCH, ~0x7,
@@ -309,6 +305,7 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
 
        /* flash strobe */
        v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
+
        /* flash strobe stop */
        v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
 
@@ -395,7 +392,7 @@ static int lm3560_init_device(struct lm3560_flash *flash)
        rval = lm3560_mode_ctrl(flash);
        if (rval < 0)
                return rval;
-       /* Reset faults */
+       /* reset faults */
        rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
        return rval;
 }
@@ -419,8 +416,7 @@ static int lm3560_probe(struct i2c_client *client,
 
        /* if there is no platform data, use chip default value */
        if (pdata == NULL) {
-               pdata =
-                   kzalloc(sizeof(struct lm3560_platform_data), GFP_KERNEL);
+               pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
                if (pdata == NULL)
                        return -ENODEV;
                pdata->peak = LM3560_PEAK_3600mA;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c
new file mode 100644 (file)
index 0000000..626fb46
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ * drivers/media/i2c/lm3646.c
+ * General device driver for TI lm3646, Dual FLASH LED Driver
+ *
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * Contact: Daniel Jeong <gshark.jeong@gmail.com>
+ *                     Ldd-Mlp <ldd-mlp@list.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/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/videodev2.h>
+#include <media/lm3646.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+
+/* registers definitions */
+#define REG_ENABLE             0x01
+#define REG_TORCH_BR   0x05
+#define REG_FLASH_BR   0x05
+#define REG_FLASH_TOUT 0x04
+#define REG_FLAG               0x08
+#define REG_STROBE_SRC 0x06
+#define REG_LED1_FLASH_BR 0x06
+#define REG_LED1_TORCH_BR 0x07
+
+#define MASK_ENABLE            0x03
+#define MASK_TORCH_BR  0x70
+#define MASK_FLASH_BR  0x0F
+#define MASK_FLASH_TOUT        0x07
+#define MASK_FLAG              0xFF
+#define MASK_STROBE_SRC        0x80
+
+/* Fault Mask */
+#define FAULT_TIMEOUT  (1<<0)
+#define FAULT_SHORT_CIRCUIT    (1<<1)
+#define FAULT_UVLO             (1<<2)
+#define FAULT_IVFM             (1<<3)
+#define FAULT_OCP              (1<<4)
+#define FAULT_OVERTEMP (1<<5)
+#define FAULT_NTC_TRIP (1<<6)
+#define FAULT_OVP              (1<<7)
+
+enum led_mode {
+       MODE_SHDN = 0x0,
+       MODE_TORCH = 0x2,
+       MODE_FLASH = 0x3,
+};
+
+/*
+ * struct lm3646_flash
+ *
+ * @pdata: platform data
+ * @regmap: reg. map for i2c
+ * @lock: muxtex for serial access.
+ * @led_mode: V4L2 LED mode
+ * @ctrls_led: V4L2 contols
+ * @subdev_led: V4L2 subdev
+ * @mode_reg : mode register value
+ */
+struct lm3646_flash {
+       struct device *dev;
+       struct lm3646_platform_data *pdata;
+       struct regmap *regmap;
+
+       struct v4l2_ctrl_handler ctrls_led;
+       struct v4l2_subdev subdev_led;
+
+       u8 mode_reg;
+};
+
+#define to_lm3646_flash(_ctrl) \
+       container_of(_ctrl->handler, struct lm3646_flash, ctrls_led)
+
+/* enable mode control */
+static int lm3646_mode_ctrl(struct lm3646_flash *flash,
+                           enum v4l2_flash_led_mode led_mode)
+{
+       switch (led_mode) {
+       case V4L2_FLASH_LED_MODE_NONE:
+               return regmap_write(flash->regmap,
+                                   REG_ENABLE, flash->mode_reg | MODE_SHDN);
+       case V4L2_FLASH_LED_MODE_TORCH:
+               return regmap_write(flash->regmap,
+                                   REG_ENABLE, flash->mode_reg | MODE_TORCH);
+       case V4L2_FLASH_LED_MODE_FLASH:
+               return regmap_write(flash->regmap,
+                                   REG_ENABLE, flash->mode_reg | MODE_FLASH);
+       }
+       return -EINVAL;
+}
+
+/* V4L2 controls  */
+static int lm3646_get_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct lm3646_flash *flash = to_lm3646_flash(ctrl);
+       unsigned int reg_val;
+       int rval;
+
+       if (ctrl->id != V4L2_CID_FLASH_FAULT)
+               return -EINVAL;
+
+       rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
+       if (rval < 0)
+               return rval;
+
+       ctrl->val = 0;
+       if (reg_val & FAULT_TIMEOUT)
+               ctrl->val |= V4L2_FLASH_FAULT_TIMEOUT;
+       if (reg_val & FAULT_SHORT_CIRCUIT)
+               ctrl->val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
+       if (reg_val & FAULT_UVLO)
+               ctrl->val |= V4L2_FLASH_FAULT_UNDER_VOLTAGE;
+       if (reg_val & FAULT_IVFM)
+               ctrl->val |= V4L2_FLASH_FAULT_INPUT_VOLTAGE;
+       if (reg_val & FAULT_OCP)
+               ctrl->val |= V4L2_FLASH_FAULT_OVER_CURRENT;
+       if (reg_val & FAULT_OVERTEMP)
+               ctrl->val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
+       if (reg_val & FAULT_NTC_TRIP)
+               ctrl->val |= V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE;
+       if (reg_val & FAULT_OVP)
+               ctrl->val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
+
+       return 0;
+}
+
+static int lm3646_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct lm3646_flash *flash = to_lm3646_flash(ctrl);
+       unsigned int reg_val;
+       int rval = -EINVAL;
+
+       switch (ctrl->id) {
+       case V4L2_CID_FLASH_LED_MODE:
+
+               if (ctrl->val != V4L2_FLASH_LED_MODE_FLASH)
+                       return lm3646_mode_ctrl(flash, ctrl->val);
+               /* switch to SHDN mode before flash strobe on */
+               return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
+
+       case V4L2_CID_FLASH_STROBE_SOURCE:
+               return regmap_update_bits(flash->regmap,
+                                         REG_STROBE_SRC, MASK_STROBE_SRC,
+                                         (ctrl->val) << 7);
+
+       case V4L2_CID_FLASH_STROBE:
+
+               /* read and check current mode of chip to start flash */
+               rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val);
+               if (rval < 0 || ((reg_val & MASK_ENABLE) != MODE_SHDN))
+                       return rval;
+               /* flash on */
+               return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_FLASH);
+
+       case V4L2_CID_FLASH_STROBE_STOP:
+
+               /*
+                * flash mode will be turned automatically
+                * from FLASH mode to SHDN mode after flash duration timeout
+                * read and check current mode of chip to stop flash
+                */
+               rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val);
+               if (rval < 0)
+                       return rval;
+               if ((reg_val & MASK_ENABLE) == MODE_FLASH)
+                       return lm3646_mode_ctrl(flash,
+                                               V4L2_FLASH_LED_MODE_NONE);
+               return rval;
+
+       case V4L2_CID_FLASH_TIMEOUT:
+               return regmap_update_bits(flash->regmap,
+                                         REG_FLASH_TOUT, MASK_FLASH_TOUT,
+                                         LM3646_FLASH_TOUT_ms_TO_REG
+                                         (ctrl->val));
+
+       case V4L2_CID_FLASH_INTENSITY:
+               return regmap_update_bits(flash->regmap,
+                                         REG_FLASH_BR, MASK_FLASH_BR,
+                                         LM3646_TOTAL_FLASH_BRT_uA_TO_REG
+                                         (ctrl->val));
+
+       case V4L2_CID_FLASH_TORCH_INTENSITY:
+               return regmap_update_bits(flash->regmap,
+                                         REG_TORCH_BR, MASK_TORCH_BR,
+                                         LM3646_TOTAL_TORCH_BRT_uA_TO_REG
+                                         (ctrl->val) << 4);
+       }
+
+       return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops lm3646_led_ctrl_ops = {
+       .g_volatile_ctrl = lm3646_get_ctrl,
+       .s_ctrl = lm3646_set_ctrl,
+};
+
+static int lm3646_init_controls(struct lm3646_flash *flash)
+{
+       struct v4l2_ctrl *fault;
+       struct v4l2_ctrl_handler *hdl = &flash->ctrls_led;
+       const struct v4l2_ctrl_ops *ops = &lm3646_led_ctrl_ops;
+
+       v4l2_ctrl_handler_init(hdl, 8);
+       /* flash mode */
+       v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE,
+                              V4L2_FLASH_LED_MODE_TORCH, ~0x7,
+                              V4L2_FLASH_LED_MODE_NONE);
+
+       /* flash source */
+       v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE,
+                              0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
+
+       /* flash strobe */
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
+       /* flash strobe stop */
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
+
+       /* flash strobe timeout */
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT,
+                         LM3646_FLASH_TOUT_MIN,
+                         LM3646_FLASH_TOUT_MAX,
+                         LM3646_FLASH_TOUT_STEP, flash->pdata->flash_timeout);
+
+       /* max flash current */
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY,
+                         LM3646_TOTAL_FLASH_BRT_MIN,
+                         LM3646_TOTAL_FLASH_BRT_MAX,
+                         LM3646_TOTAL_FLASH_BRT_STEP,
+                         LM3646_TOTAL_FLASH_BRT_MAX);
+
+       /* max torch current */
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY,
+                         LM3646_TOTAL_TORCH_BRT_MIN,
+                         LM3646_TOTAL_TORCH_BRT_MAX,
+                         LM3646_TOTAL_TORCH_BRT_STEP,
+                         LM3646_TOTAL_TORCH_BRT_MAX);
+
+       /* fault */
+       fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0,
+                                 V4L2_FLASH_FAULT_OVER_VOLTAGE
+                                 | V4L2_FLASH_FAULT_OVER_TEMPERATURE
+                                 | V4L2_FLASH_FAULT_SHORT_CIRCUIT
+                                 | V4L2_FLASH_FAULT_TIMEOUT, 0, 0);
+       if (fault != NULL)
+               fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+       if (hdl->error)
+               return hdl->error;
+
+       flash->subdev_led.ctrl_handler = hdl;
+       return 0;
+}
+
+/* initialize device */
+static const struct v4l2_subdev_ops lm3646_ops = {
+       .core = NULL,
+};
+
+static const struct regmap_config lm3646_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = 0xFF,
+};
+
+static int lm3646_subdev_init(struct lm3646_flash *flash)
+{
+       struct i2c_client *client = to_i2c_client(flash->dev);
+       int rval;
+
+       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);
+       rval = lm3646_init_controls(flash);
+       if (rval)
+               goto err_out;
+       rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0);
+       if (rval < 0)
+               goto err_out;
+       flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
+       return rval;
+
+err_out:
+       v4l2_ctrl_handler_free(&flash->ctrls_led);
+       return rval;
+}
+
+static int lm3646_init_device(struct lm3646_flash *flash)
+{
+       unsigned int reg_val;
+       int rval;
+
+       /* read the value of mode register to reduce redundant i2c accesses */
+       rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val);
+       if (rval < 0)
+               return rval;
+       flash->mode_reg = reg_val & 0xfc;
+
+       /* output disable */
+       rval = lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
+       if (rval < 0)
+               return rval;
+
+       /*
+        * LED1 flash current setting
+        * LED2 flash current = Total(Max) flash current - LED1 flash current
+        */
+       rval = regmap_update_bits(flash->regmap,
+                                 REG_LED1_FLASH_BR, 0x7F,
+                                 LM3646_LED1_FLASH_BRT_uA_TO_REG
+                                 (flash->pdata->led1_flash_brt));
+
+       if (rval < 0)
+               return rval;
+
+       /*
+        * LED1 torch current setting
+        * LED2 torch current = Total(Max) torch current - LED1 torch current
+        */
+       rval = regmap_update_bits(flash->regmap,
+                                 REG_LED1_TORCH_BR, 0x7F,
+                                 LM3646_LED1_TORCH_BRT_uA_TO_REG
+                                 (flash->pdata->led1_torch_brt));
+       if (rval < 0)
+               return rval;
+
+       /* Reset flag register */
+       return regmap_read(flash->regmap, REG_FLAG, &reg_val);
+}
+
+static int lm3646_probe(struct i2c_client *client,
+                       const struct i2c_device_id *devid)
+{
+       struct lm3646_flash *flash;
+       struct lm3646_platform_data *pdata = dev_get_platdata(&client->dev);
+       int rval;
+
+       flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
+       if (flash == NULL)
+               return -ENOMEM;
+
+       flash->regmap = devm_regmap_init_i2c(client, &lm3646_regmap);
+       if (IS_ERR(flash->regmap))
+               return PTR_ERR(flash->regmap);
+
+       /* check device tree if there is no platform data */
+       if (pdata == NULL) {
+               pdata = devm_kzalloc(&client->dev,
+                                    sizeof(struct lm3646_platform_data),
+                                    GFP_KERNEL);
+               if (pdata == NULL)
+                       return -ENOMEM;
+               /* use default data in case of no platform data */
+               pdata->flash_timeout = LM3646_FLASH_TOUT_MAX;
+               pdata->led1_torch_brt = LM3646_LED1_TORCH_BRT_MAX;
+               pdata->led1_flash_brt = LM3646_LED1_FLASH_BRT_MAX;
+       }
+       flash->pdata = pdata;
+       flash->dev = &client->dev;
+
+       rval = lm3646_subdev_init(flash);
+       if (rval < 0)
+               return rval;
+
+       rval = lm3646_init_device(flash);
+       if (rval < 0)
+               return rval;
+
+       i2c_set_clientdata(client, flash);
+
+       return 0;
+}
+
+static int lm3646_remove(struct i2c_client *client)
+{
+       struct lm3646_flash *flash = i2c_get_clientdata(client);
+
+       v4l2_device_unregister_subdev(&flash->subdev_led);
+       v4l2_ctrl_handler_free(&flash->ctrls_led);
+       media_entity_cleanup(&flash->subdev_led.entity);
+
+       return 0;
+}
+
+static const struct i2c_device_id lm3646_id_table[] = {
+       {LM3646_NAME, 0},
+       {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3646_id_table);
+
+static struct i2c_driver lm3646_i2c_driver = {
+       .driver = {
+                  .name = LM3646_NAME,
+                  },
+       .probe = lm3646_probe,
+       .remove = lm3646_remove,
+       .id_table = lm3646_id_table,
+};
+
+module_i2c_driver(lm3646_i2c_driver);
+
+MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>");
+MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>");
+MODULE_DESCRIPTION("Texas Instruments LM3646 Dual Flash LED driver");
+MODULE_LICENSE("GPL");
index 192c4aad05d67f938c8c2e5543ea4d91bff75bcc..33daace8129724366f29441c4f643604915306b0 100644 (file)
@@ -78,6 +78,9 @@
 #define        MT9P031_PLL_CONFIG_1                            0x11
 #define        MT9P031_PLL_CONFIG_2                            0x12
 #define MT9P031_PIXEL_CLOCK_CONTROL                    0x0a
+#define                MT9P031_PIXEL_CLOCK_INVERT              (1 << 15)
+#define                MT9P031_PIXEL_CLOCK_SHIFT(n)            ((n) << 8)
+#define                MT9P031_PIXEL_CLOCK_DIVIDE(n)           ((n) << 0)
 #define MT9P031_FRAME_RESTART                          0x0b
 #define MT9P031_SHUTTER_DELAY                          0x0c
 #define MT9P031_RST                                    0x0d
@@ -130,6 +133,8 @@ struct mt9p031 {
 
        enum mt9p031_model model;
        struct aptina_pll pll;
+       unsigned int clk_div;
+       bool use_pll;
        int reset;
 
        struct v4l2_ctrl_handler ctrls;
@@ -198,6 +203,11 @@ static int mt9p031_reset(struct mt9p031 *mt9p031)
        if (ret < 0)
                return ret;
 
+       ret = mt9p031_write(client, MT9P031_PIXEL_CLOCK_CONTROL,
+                           MT9P031_PIXEL_CLOCK_DIVIDE(mt9p031->clk_div));
+       if (ret < 0)
+               return ret;
+
        return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
                                          0);
 }
@@ -222,15 +232,34 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
 
        struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
        struct mt9p031_platform_data *pdata = mt9p031->pdata;
+       int ret;
 
        mt9p031->clk = devm_clk_get(&client->dev, NULL);
        if (IS_ERR(mt9p031->clk))
                return PTR_ERR(mt9p031->clk);
 
-       clk_set_rate(mt9p031->clk, pdata->ext_freq);
+       ret = clk_set_rate(mt9p031->clk, pdata->ext_freq);
+       if (ret < 0)
+               return ret;
+
+       /* If the external clock frequency is out of bounds for the PLL use the
+        * pixel clock divider only and disable the PLL.
+        */
+       if (pdata->ext_freq > limits.ext_clock_max) {
+               unsigned int div;
+
+               div = DIV_ROUND_UP(pdata->ext_freq, pdata->target_freq);
+               div = roundup_pow_of_two(div) / 2;
+
+               mt9p031->clk_div = max_t(unsigned int, div, 64);
+               mt9p031->use_pll = false;
+
+               return 0;
+       }
 
        mt9p031->pll.ext_clock = pdata->ext_freq;
        mt9p031->pll.pix_clock = pdata->target_freq;
+       mt9p031->use_pll = true;
 
        return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
 }
@@ -240,6 +269,9 @@ static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
        struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
        int ret;
 
+       if (!mt9p031->use_pll)
+               return 0;
+
        ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
                            MT9P031_PLL_CONTROL_PWRON);
        if (ret < 0)
@@ -265,6 +297,9 @@ static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
 {
        struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
 
+       if (!mt9p031->use_pll)
+               return 0;
+
        return mt9p031_write(client, MT9P031_PLL_CONTROL,
                             MT9P031_PLL_CONTROL_PWROFF);
 }
@@ -285,9 +320,15 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031)
        if (ret < 0)
                return ret;
 
-       /* Emable clock */
-       if (mt9p031->clk)
-               clk_prepare_enable(mt9p031->clk);
+       /* Enable clock */
+       if (mt9p031->clk) {
+               ret = clk_prepare_enable(mt9p031->clk);
+               if (ret) {
+                       regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
+                                              mt9p031->regulators);
+                       return ret;
+               }
+       }
 
        /* Now RESET_BAR must be high */
        if (gpio_is_valid(mt9p031->reset)) {
index d41c70eaf838b0b7ced8acc48c4609c522d0a3bb..422e068f5f1b873d453ce63f07cb44c2f5702f29 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk.h>
 #include <linux/i2c.h>
-#include <linux/module.h>
 #include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/v4l2-mediabus.h>
@@ -55,6 +57,7 @@
 #define                MT9T001_OUTPUT_CONTROL_SYNC             (1 << 0)
 #define                MT9T001_OUTPUT_CONTROL_CHIP_ENABLE      (1 << 1)
 #define                MT9T001_OUTPUT_CONTROL_TEST_DATA        (1 << 6)
+#define                MT9T001_OUTPUT_CONTROL_DEF              0x0002
 #define MT9T001_SHUTTER_WIDTH_HIGH                     0x08
 #define MT9T001_SHUTTER_WIDTH_LOW                      0x09
 #define                MT9T001_SHUTTER_WIDTH_MIN               1
@@ -116,6 +119,12 @@ struct mt9t001 {
        struct v4l2_subdev subdev;
        struct media_pad pad;
 
+       struct clk *clk;
+       struct regulator_bulk_data regulators[2];
+
+       struct mutex power_lock; /* lock to protect power_count */
+       int power_count;
+
        struct v4l2_mbus_framefmt format;
        struct v4l2_rect crop;
 
@@ -159,6 +168,77 @@ static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
        return 0;
 }
 
+static int mt9t001_reset(struct mt9t001 *mt9t001)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
+       int ret;
+
+       /* Reset the chip and stop data read out */
+       ret = mt9t001_write(client, MT9T001_RESET, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = mt9t001_write(client, MT9T001_RESET, 0);
+       if (ret < 0)
+               return ret;
+
+       mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
+
+       return mt9t001_set_output_control(mt9t001,
+                                         MT9T001_OUTPUT_CONTROL_CHIP_ENABLE,
+                                         0);
+}
+
+static int mt9t001_power_on(struct mt9t001 *mt9t001)
+{
+       int ret;
+
+       /* Bring up the supplies */
+       ret = regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
+                                  mt9t001->regulators);
+       if (ret < 0)
+               return ret;
+
+       /* Enable clock */
+       ret = clk_prepare_enable(mt9t001->clk);
+       if (ret < 0)
+               regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
+                                      mt9t001->regulators);
+
+       return ret;
+}
+
+static void mt9t001_power_off(struct mt9t001 *mt9t001)
+{
+       regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
+                              mt9t001->regulators);
+
+       clk_disable_unprepare(mt9t001->clk);
+}
+
+static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
+       int ret;
+
+       if (!on) {
+               mt9t001_power_off(mt9t001);
+               return 0;
+       }
+
+       ret = mt9t001_power_on(mt9t001);
+       if (ret < 0)
+               return ret;
+
+       ret = mt9t001_reset(mt9t001);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to reset the camera\n");
+               return ret;
+       }
+
+       return v4l2_ctrl_handler_setup(&mt9t001->ctrls);
+}
+
 /* -----------------------------------------------------------------------------
  * V4L2 subdev video operations
  */
@@ -195,6 +275,7 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
 {
        const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE;
        struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       struct mt9t001_platform_data *pdata = client->dev.platform_data;
        struct mt9t001 *mt9t001 = to_mt9t001(subdev);
        struct v4l2_mbus_framefmt *format = &mt9t001->format;
        struct v4l2_rect *crop = &mt9t001->crop;
@@ -205,6 +286,14 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
        if (!enable)
                return mt9t001_set_output_control(mt9t001, mode, 0);
 
+       /* Configure the pixel clock polarity */
+       if (pdata->clk_pol) {
+               ret  = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
+                                    MT9T001_PIXEL_CLOCK_INVERT);
+               if (ret < 0)
+                       return ret;
+       }
+
        /* Configure the window size and row/column bin */
        hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
        vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
@@ -629,10 +718,68 @@ static const struct v4l2_ctrl_config mt9t001_gains[] = {
        },
 };
 
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev core operations
+ */
+
+static int mt9t001_set_power(struct v4l2_subdev *subdev, int on)
+{
+       struct mt9t001 *mt9t001 = to_mt9t001(subdev);
+       int ret = 0;
+
+       mutex_lock(&mt9t001->power_lock);
+
+       /* If the power count is modified from 0 to != 0 or from != 0 to 0,
+        * update the power state.
+        */
+       if (mt9t001->power_count == !on) {
+               ret = __mt9t001_set_power(mt9t001, !!on);
+               if (ret < 0)
+                       goto out;
+       }
+
+       /* Update the power count. */
+       mt9t001->power_count += on ? 1 : -1;
+       WARN_ON(mt9t001->power_count < 0);
+
+out:
+       mutex_unlock(&mt9t001->power_lock);
+       return ret;
+}
+
 /* -----------------------------------------------------------------------------
  * V4L2 subdev internal operations
  */
 
+static int mt9t001_registered(struct v4l2_subdev *subdev)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       struct mt9t001 *mt9t001 = to_mt9t001(subdev);
+       s32 data;
+       int ret;
+
+       ret = mt9t001_power_on(mt9t001);
+       if (ret < 0) {
+               dev_err(&client->dev, "MT9T001 power up failed\n");
+               return ret;
+       }
+
+       /* Read out the chip version register */
+       data = mt9t001_read(client, MT9T001_CHIP_VERSION);
+       mt9t001_power_off(mt9t001);
+
+       if (data != MT9T001_CHIP_ID) {
+               dev_err(&client->dev,
+                       "MT9T001 not detected, wrong version 0x%04x\n", data);
+               return -ENODEV;
+       }
+
+       dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
+                client->addr);
+
+       return 0;
+}
+
 static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
 {
        struct v4l2_mbus_framefmt *format;
@@ -651,9 +798,18 @@ static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
        format->field = V4L2_FIELD_NONE;
        format->colorspace = V4L2_COLORSPACE_SRGB;
 
-       return 0;
+       return mt9t001_set_power(subdev, 1);
+}
+
+static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+       return mt9t001_set_power(subdev, 0);
 }
 
+static struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = {
+       .s_power = mt9t001_set_power,
+};
+
 static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = {
        .s_stream = mt9t001_s_stream,
 };
@@ -668,58 +824,17 @@ static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = {
 };
 
 static struct v4l2_subdev_ops mt9t001_subdev_ops = {
+       .core = &mt9t001_subdev_core_ops,
        .video = &mt9t001_subdev_video_ops,
        .pad = &mt9t001_subdev_pad_ops,
 };
 
 static struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = {
+       .registered = mt9t001_registered,
        .open = mt9t001_open,
+       .close = mt9t001_close,
 };
 
-static int mt9t001_video_probe(struct i2c_client *client)
-{
-       struct mt9t001_platform_data *pdata = client->dev.platform_data;
-       s32 data;
-       int ret;
-
-       dev_info(&client->dev, "Probing MT9T001 at address 0x%02x\n",
-                client->addr);
-
-       /* Reset the chip and stop data read out */
-       ret = mt9t001_write(client, MT9T001_RESET, 1);
-       if (ret < 0)
-               return ret;
-
-       ret = mt9t001_write(client, MT9T001_RESET, 0);
-       if (ret < 0)
-               return ret;
-
-       ret  = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, 0);
-       if (ret < 0)
-               return ret;
-
-       /* Configure the pixel clock polarity */
-       if (pdata->clk_pol) {
-               ret  = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
-                                    MT9T001_PIXEL_CLOCK_INVERT);
-               if (ret < 0)
-                       return ret;
-       }
-
-       /* Read and check the sensor version */
-       data = mt9t001_read(client, MT9T001_CHIP_VERSION);
-       if (data != MT9T001_CHIP_ID) {
-               dev_err(&client->dev, "MT9T001 not detected, wrong version "
-                       "0x%04x\n", data);
-               return -ENODEV;
-       }
-
-       dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
-                client->addr);
-
-       return ret;
-}
-
 static int mt9t001_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
@@ -740,14 +855,28 @@ static int mt9t001_probe(struct i2c_client *client,
                return -EIO;
        }
 
-       ret = mt9t001_video_probe(client);
-       if (ret < 0)
-               return ret;
-
        mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
        if (!mt9t001)
                return -ENOMEM;
 
+       mutex_init(&mt9t001->power_lock);
+       mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
+
+       mt9t001->regulators[0].supply = "vdd";
+       mt9t001->regulators[1].supply = "vaa";
+
+       ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators);
+       if (ret < 0) {
+               dev_err(&client->dev, "Unable to get regulators\n");
+               return ret;
+       }
+
+       mt9t001->clk = devm_clk_get(&client->dev, NULL);
+       if (IS_ERR(mt9t001->clk)) {
+               dev_err(&client->dev, "Unable to get clock\n");
+               return PTR_ERR(mt9t001->clk);
+       }
+
        v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
                                                ARRAY_SIZE(mt9t001_gains) + 4);
 
index f74698cf14c94d343e8ae1861bc7d730ff139b60..47e475319a249d9da5872e3cccc09a43f0c9174e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
  *
- * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
+ * Copyright (c) 2009 Mauro Carvalho Chehab
  * This code is placed under the terms of the GNU General Public License v2
  */
 
@@ -16,7 +16,7 @@
 #include <media/mt9v011.h>
 
 MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 
 static int debug;
index 36c504b78f2c6233b711fbe46a7c509aae7f101e..40172b8d8ea227f284cb56e50dfe7ac637d71c24 100644 (file)
@@ -317,8 +317,14 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
        struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
        int ret;
 
-       clk_set_rate(mt9v032->clk, mt9v032->sysclk);
-       clk_prepare_enable(mt9v032->clk);
+       ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
+       if (ret < 0)
+               return ret;
+
+       ret = clk_prepare_enable(mt9v032->clk);
+       if (ret)
+               return ret;
+
        udelay(1);
 
        /* Reset the chip and stop data read out */
index e7f555cc827abb4ddc1eba44bb1526e1d32576e4..a4459301b5f829efcae8563241ef1108933194d7 100644 (file)
@@ -15,7 +15,7 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/sizes.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/gpio.h>
@@ -23,7 +23,9 @@
 #include <linux/init.h>
 #include <linux/media.h>
 #include <linux/module.h>
+#include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/videodev2.h>
@@ -33,6 +35,7 @@
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-mediabus.h>
 #include <media/s5c73m3.h>
+#include <media/v4l2-of.h>
 
 #include "s5c73m3.h"
 
@@ -46,6 +49,8 @@ static int update_fw;
 module_param(update_fw, int, 0644);
 
 #define S5C73M3_EMBEDDED_DATA_MAXLEN   SZ_4K
+#define S5C73M3_MIPI_DATA_LANES                4
+#define S5C73M3_CLK_NAME               "cis_extclk"
 
 static const char * const s5c73m3_supply_names[S5C73M3_MAX_SUPPLIES] = {
        "vdd-int",      /* Digital Core supply (1.2V), CAM_ISP_CORE_1.2V */
@@ -1355,9 +1360,20 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
        for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++) {
                ret = regulator_enable(state->supplies[i].consumer);
                if (ret)
-                       goto err;
+                       goto err_reg_dis;
        }
 
+       ret = clk_set_rate(state->clock, state->mclk_frequency);
+       if (ret < 0)
+               goto err_reg_dis;
+
+       ret = clk_prepare_enable(state->clock);
+       if (ret < 0)
+               goto err_reg_dis;
+
+       v4l2_dbg(1, s5c73m3_dbg, &state->oif_sd, "clock frequency: %ld\n",
+                                       clk_get_rate(state->clock));
+
        s5c73m3_gpio_deassert(state, STBY);
        usleep_range(100, 200);
 
@@ -1365,7 +1381,8 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
        usleep_range(50, 100);
 
        return 0;
-err:
+
+err_reg_dis:
        for (--i; i >= 0; i--)
                regulator_disable(state->supplies[i].consumer);
        return ret;
@@ -1380,6 +1397,9 @@ static int __s5c73m3_power_off(struct s5c73m3 *state)
 
        if (s5c73m3_gpio_assert(state, STBY))
                usleep_range(100, 200);
+
+       clk_disable_unprepare(state->clock);
+
        state->streaming = 0;
        state->isp_ready = 0;
 
@@ -1388,6 +1408,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state)
                if (ret)
                        goto err;
        }
+
        return 0;
 err:
        for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
@@ -1396,6 +1417,8 @@ err:
                        v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n",
                                 state->supplies[i].supply, r);
        }
+
+       clk_prepare_enable(state->clock);
        return ret;
 }
 
@@ -1451,17 +1474,6 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
                        S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
                        MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-       mutex_lock(&state->lock);
-       ret = __s5c73m3_power_on(state);
-       if (ret == 0)
-               s5c73m3_get_fw_version(state);
-
-       __s5c73m3_power_off(state);
-       mutex_unlock(&state->lock);
-
-       v4l2_dbg(1, s5c73m3_dbg, sd, "%s: Booting %s (%d)\n",
-                __func__, ret ? "failed" : "succeeded", ret);
-
        return ret;
 }
 
@@ -1519,41 +1531,112 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
        .video  = &s5c73m3_oif_video_ops,
 };
 
-static int s5c73m3_configure_gpios(struct s5c73m3 *state,
-                                  const struct s5c73m3_platform_data *pdata)
+static int s5c73m3_configure_gpios(struct s5c73m3 *state)
+{
+       static const char * const gpio_names[] = {
+               "S5C73M3_STBY", "S5C73M3_RST"
+       };
+       struct i2c_client *c = state->i2c_client;
+       struct s5c73m3_gpio *g = state->gpio;
+       int ret, i;
+
+       for (i = 0; i < GPIO_NUM; ++i) {
+               unsigned int flags = GPIOF_DIR_OUT;
+               if (g[i].level)
+                       flags |= GPIOF_INIT_HIGH;
+               ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags,
+                                           gpio_names[i]);
+               if (ret) {
+                       v4l2_err(c, "failed to request gpio %s\n",
+                                gpio_names[i]);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+static int s5c73m3_parse_gpios(struct s5c73m3 *state)
+{
+       static const char * const prop_names[] = {
+               "standby-gpios", "xshutdown-gpios",
+       };
+       struct device *dev = &state->i2c_client->dev;
+       struct device_node *node = dev->of_node;
+       int ret, i;
+
+       for (i = 0; i < GPIO_NUM; ++i) {
+               enum of_gpio_flags of_flags;
+
+               ret = of_get_named_gpio_flags(node, prop_names[i],
+                                             0, &of_flags);
+               if (ret < 0) {
+                       dev_err(dev, "failed to parse %s DT property\n",
+                               prop_names[i]);
+                       return -EINVAL;
+               }
+               state->gpio[i].gpio = ret;
+               state->gpio[i].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
+       }
+       return 0;
+}
+
+static int s5c73m3_get_platform_data(struct s5c73m3 *state)
 {
        struct device *dev = &state->i2c_client->dev;
-       const struct s5c73m3_gpio *gpio;
-       unsigned long flags;
+       const struct s5c73m3_platform_data *pdata = dev->platform_data;
+       struct device_node *node = dev->of_node;
+       struct device_node *node_ep;
+       struct v4l2_of_endpoint ep;
        int ret;
 
-       state->gpio[STBY].gpio = -EINVAL;
-       state->gpio[RST].gpio  = -EINVAL;
+       if (!node) {
+               if (!pdata) {
+                       dev_err(dev, "Platform data not specified\n");
+                       return -EINVAL;
+               }
 
-       gpio = &pdata->gpio_stby;
-       if (gpio_is_valid(gpio->gpio)) {
-               flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
-                     | GPIOF_EXPORT;
-               ret = devm_gpio_request_one(dev, gpio->gpio, flags,
-                                           "S5C73M3_STBY");
-               if (ret < 0)
-                       return ret;
+               state->mclk_frequency = pdata->mclk_frequency;
+               state->gpio[STBY] = pdata->gpio_stby;
+               state->gpio[RST] = pdata->gpio_reset;
+               return 0;
+       }
+
+       state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME);
+       if (IS_ERR(state->clock))
+               return PTR_ERR(state->clock);
 
-               state->gpio[STBY] = *gpio;
+       if (of_property_read_u32(node, "clock-frequency",
+                                &state->mclk_frequency)) {
+               state->mclk_frequency = S5C73M3_DEFAULT_MCLK_FREQ;
+               dev_info(dev, "using default %u Hz clock frequency\n",
+                                       state->mclk_frequency);
        }
 
-       gpio = &pdata->gpio_reset;
-       if (gpio_is_valid(gpio->gpio)) {
-               flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
-                     | GPIOF_EXPORT;
-               ret = devm_gpio_request_one(dev, gpio->gpio, flags,
-                                           "S5C73M3_RST");
-               if (ret < 0)
-                       return ret;
+       ret = s5c73m3_parse_gpios(state);
+       if (ret < 0)
+               return -EINVAL;
 
-               state->gpio[RST] = *gpio;
+       node_ep = v4l2_of_get_next_endpoint(node, NULL);
+       if (!node_ep) {
+               dev_warn(dev, "no endpoint defined for node: %s\n",
+                                               node->full_name);
+               return 0;
        }
 
+       v4l2_of_parse_endpoint(node_ep, &ep);
+       of_node_put(node_ep);
+
+       if (ep.bus_type != V4L2_MBUS_CSI2) {
+               dev_err(dev, "unsupported bus type\n");
+               return -EINVAL;
+       }
+       /*
+        * Number of MIPI CSI-2 data lanes is currently not configurable,
+        * always a default value of 4 lanes is used.
+        */
+       if (ep.bus.mipi_csi2.num_data_lanes != S5C73M3_MIPI_DATA_LANES)
+               dev_info(dev, "falling back to 4 MIPI CSI-2 data lanes\n");
+
        return 0;
 }
 
@@ -1561,21 +1644,20 @@ static int s5c73m3_probe(struct i2c_client *client,
                                const struct i2c_device_id *id)
 {
        struct device *dev = &client->dev;
-       const struct s5c73m3_platform_data *pdata = client->dev.platform_data;
        struct v4l2_subdev *sd;
        struct v4l2_subdev *oif_sd;
        struct s5c73m3 *state;
        int ret, i;
 
-       if (pdata == NULL) {
-               dev_err(&client->dev, "Platform data not specified\n");
-               return -EINVAL;
-       }
-
        state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
        if (!state)
                return -ENOMEM;
 
+       state->i2c_client = client;
+       ret = s5c73m3_get_platform_data(state);
+       if (ret < 0)
+               return ret;
+
        mutex_init(&state->lock);
        sd = &state->sensor_sd;
        oif_sd = &state->oif_sd;
@@ -1613,11 +1695,7 @@ static int s5c73m3_probe(struct i2c_client *client,
        if (ret < 0)
                return ret;
 
-       state->mclk_frequency = pdata->mclk_frequency;
-       state->bus_type = pdata->bus_type;
-       state->i2c_client = client;
-
-       ret = s5c73m3_configure_gpios(state, pdata);
+       ret = s5c73m3_configure_gpios(state);
        if (ret)
                goto out_err;
 
@@ -1651,9 +1729,29 @@ static int s5c73m3_probe(struct i2c_client *client,
        if (ret < 0)
                goto out_err;
 
+       oif_sd->dev = dev;
+
+       ret = __s5c73m3_power_on(state);
+       if (ret < 0)
+               goto out_err1;
+
+       ret = s5c73m3_get_fw_version(state);
+       __s5c73m3_power_off(state);
+
+       if (ret < 0) {
+               dev_err(dev, "Device detection failed: %d\n", ret);
+               goto out_err1;
+       }
+
+       ret = v4l2_async_register_subdev(oif_sd);
+       if (ret < 0)
+               goto out_err1;
+
        v4l2_info(sd, "%s: completed successfully\n", __func__);
        return 0;
 
+out_err1:
+       s5c73m3_unregister_spi_driver(state);
 out_err:
        media_entity_cleanup(&sd->entity);
        return ret;
@@ -1665,7 +1763,7 @@ static int s5c73m3_remove(struct i2c_client *client)
        struct s5c73m3 *state = oif_sd_to_s5c73m3(oif_sd);
        struct v4l2_subdev *sensor_sd = &state->sensor_sd;
 
-       v4l2_device_unregister_subdev(oif_sd);
+       v4l2_async_unregister_subdev(oif_sd);
 
        v4l2_ctrl_handler_free(oif_sd->ctrl_handler);
        media_entity_cleanup(&oif_sd->entity);
@@ -1684,8 +1782,17 @@ static const struct i2c_device_id s5c73m3_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id s5c73m3_of_match[] = {
+       { .compatible = "samsung,s5c73m3" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, s5c73m3_of_match);
+#endif
+
 static struct i2c_driver s5c73m3_i2c_driver = {
        .driver = {
+               .of_match_table = of_match_ptr(s5c73m3_of_match),
                .name   = DRIVER_NAME,
        },
        .probe          = s5c73m3_probe,
index 8079e26eb5e2f7c4c5dfec7b725e5b0d061cc33e..f60b265b4da15a949701fac80c7de4927e0a49fd 100644 (file)
 
 #define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI"
 
+static const struct of_device_id s5c73m3_spi_ids[] = {
+       { .compatible = "samsung,s5c73m3" },
+       { }
+};
+
 enum spi_direction {
        SPI_DIR_RX,
        SPI_DIR_TX
@@ -146,6 +151,7 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
        spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
        spidrv->driver.bus = &spi_bus_type;
        spidrv->driver.owner = THIS_MODULE;
+       spidrv->driver.of_match_table = s5c73m3_spi_ids;
 
        return spi_register_driver(spidrv);
 }
index 9dfa516f694471660f9de431c948ae279ed07bb9..9656b6723dc63a5af8bc511825555a20b8829293 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef S5C73M3_H_
 #define S5C73M3_H_
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/regulator/consumer.h>
 #include <media/v4l2-common.h>
@@ -321,6 +322,7 @@ enum s5c73m3_oif_pads {
 
 
 #define S5C73M3_MAX_SUPPLIES                   6
+#define S5C73M3_DEFAULT_MCLK_FREQ              24000000U
 
 struct s5c73m3_ctrls {
        struct v4l2_ctrl_handler handler;
@@ -391,6 +393,8 @@ struct s5c73m3 {
        struct regulator_bulk_data supplies[S5C73M3_MAX_SUPPLIES];
        struct s5c73m3_gpio gpio[GPIO_NUM];
 
+       struct clk *clock;
+
        /* External master clock frequency */
        u32 mclk_frequency;
        /* Video bus type - MIPI-CSI2/parallel */
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
new file mode 100644 (file)
index 0000000..7bc2271
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * Samsung S5K6A3 image sensor driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-subdev.h>
+
+#define S5K6A3_SENSOR_MAX_WIDTH                1412
+#define S5K6A3_SENSOR_MAX_HEIGHT       1412
+#define S5K6A3_SENSOR_MIN_WIDTH                32
+#define S5K6A3_SENSOR_MIN_HEIGHT       32
+
+#define S5K6A3_DEFAULT_WIDTH           1296
+#define S5K6A3_DEFAULT_HEIGHT          732
+
+#define S5K6A3_DRV_NAME                        "S5K6A3"
+#define S5K6A3_CLK_NAME                        "extclk"
+#define S5K6A3_DEFAULT_CLK_FREQ                24000000U
+
+enum {
+       S5K6A3_SUPP_VDDA,
+       S5K6A3_SUPP_VDDIO,
+       S5K6A3_SUPP_AFVDD,
+       S5K6A3_NUM_SUPPLIES,
+};
+
+/**
+ * struct s5k6a3 - fimc-is sensor data structure
+ * @dev: pointer to this I2C client device structure
+ * @subdev: the image sensor's v4l2 subdev
+ * @pad: subdev media source pad
+ * @supplies: image sensor's voltage regulator supplies
+ * @gpio_reset: GPIO connected to the sensor's reset pin
+ * @lock: mutex protecting the structure's members below
+ * @format: media bus format at the sensor's source pad
+ */
+struct s5k6a3 {
+       struct device *dev;
+       struct v4l2_subdev subdev;
+       struct media_pad pad;
+       struct regulator_bulk_data supplies[S5K6A3_NUM_SUPPLIES];
+       int gpio_reset;
+       struct mutex lock;
+       struct v4l2_mbus_framefmt format;
+       struct clk *clock;
+       u32 clock_frequency;
+       int power_count;
+};
+
+static const char * const s5k6a3_supply_names[] = {
+       [S5K6A3_SUPP_VDDA]      = "svdda",
+       [S5K6A3_SUPP_VDDIO]     = "svddio",
+       [S5K6A3_SUPP_AFVDD]     = "afvdd",
+};
+
+static inline struct s5k6a3 *sd_to_s5k6a3(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct s5k6a3, subdev);
+}
+
+static const struct v4l2_mbus_framefmt s5k6a3_formats[] = {
+       {
+               .code = V4L2_MBUS_FMT_SGRBG10_1X10,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .field = V4L2_FIELD_NONE,
+       }
+};
+
+static const struct v4l2_mbus_framefmt *find_sensor_format(
+       struct v4l2_mbus_framefmt *mf)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(s5k6a3_formats); i++)
+               if (mf->code == s5k6a3_formats[i].code)
+                       return &s5k6a3_formats[i];
+
+       return &s5k6a3_formats[0];
+}
+
+static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_fh *fh,
+                                 struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->index >= ARRAY_SIZE(s5k6a3_formats))
+               return -EINVAL;
+
+       code->code = s5k6a3_formats[code->index].code;
+       return 0;
+}
+
+static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf)
+{
+       const struct v4l2_mbus_framefmt *fmt;
+
+       fmt = find_sensor_format(mf);
+       mf->code = fmt->code;
+       v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH,
+                             S5K6A3_SENSOR_MAX_WIDTH, 0,
+                             &mf->height, S5K6A3_SENSOR_MIN_HEIGHT,
+                             S5K6A3_SENSOR_MAX_HEIGHT, 0, 0);
+}
+
+static struct v4l2_mbus_framefmt *__s5k6a3_get_format(
+               struct s5k6a3 *sensor, struct v4l2_subdev_fh *fh,
+               u32 pad, enum v4l2_subdev_format_whence which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
+
+       return &sensor->format;
+}
+
+static int s5k6a3_set_fmt(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_fh *fh,
+                                 struct v4l2_subdev_format *fmt)
+{
+       struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
+       struct v4l2_mbus_framefmt *mf;
+
+       s5k6a3_try_format(&fmt->format);
+
+       mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which);
+       if (mf) {
+               mutex_lock(&sensor->lock);
+               if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+                       *mf = fmt->format;
+               mutex_unlock(&sensor->lock);
+       }
+       return 0;
+}
+
+static int s5k6a3_get_fmt(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_fh *fh,
+                                 struct v4l2_subdev_format *fmt)
+{
+       struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
+       struct v4l2_mbus_framefmt *mf;
+
+       mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which);
+
+       mutex_lock(&sensor->lock);
+       fmt->format = *mf;
+       mutex_unlock(&sensor->lock);
+       return 0;
+}
+
+static struct v4l2_subdev_pad_ops s5k6a3_pad_ops = {
+       .enum_mbus_code = s5k6a3_enum_mbus_code,
+       .get_fmt        = s5k6a3_get_fmt,
+       .set_fmt        = s5k6a3_set_fmt,
+};
+
+static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
+
+       *format         = s5k6a3_formats[0];
+       format->width   = S5K6A3_DEFAULT_WIDTH;
+       format->height  = S5K6A3_DEFAULT_HEIGHT;
+
+       return 0;
+}
+
+static const struct v4l2_subdev_internal_ops s5k6a3_sd_internal_ops = {
+       .open = s5k6a3_open,
+};
+
+static int __s5k6a3_power_on(struct s5k6a3 *sensor)
+{
+       int i = S5K6A3_SUPP_VDDA;
+       int ret;
+
+       ret = clk_set_rate(sensor->clock, sensor->clock_frequency);
+       if (ret < 0)
+               return ret;
+
+       ret = pm_runtime_get(sensor->dev);
+       if (ret < 0)
+               return ret;
+
+       ret = regulator_enable(sensor->supplies[i].consumer);
+       if (ret < 0)
+               goto error_rpm_put;
+
+       ret = clk_prepare_enable(sensor->clock);
+       if (ret < 0)
+               goto error_reg_dis;
+
+       for (i++; i < S5K6A3_NUM_SUPPLIES; i++) {
+               ret = regulator_enable(sensor->supplies[i].consumer);
+               if (ret < 0)
+                       goto error_reg_dis;
+       }
+
+       gpio_set_value(sensor->gpio_reset, 1);
+       usleep_range(600, 800);
+       gpio_set_value(sensor->gpio_reset, 0);
+       usleep_range(600, 800);
+       gpio_set_value(sensor->gpio_reset, 1);
+
+       /* Delay needed for the sensor initialization */
+       msleep(20);
+       return 0;
+
+error_reg_dis:
+       for (--i; i >= 0; --i)
+               regulator_disable(sensor->supplies[i].consumer);
+error_rpm_put:
+       pm_runtime_put(sensor->dev);
+       return ret;
+}
+
+static int __s5k6a3_power_off(struct s5k6a3 *sensor)
+{
+       int i;
+
+       gpio_set_value(sensor->gpio_reset, 0);
+
+       for (i = S5K6A3_NUM_SUPPLIES - 1; i >= 0; i--)
+               regulator_disable(sensor->supplies[i].consumer);
+
+       clk_disable_unprepare(sensor->clock);
+       pm_runtime_put(sensor->dev);
+       return 0;
+}
+
+static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
+       int ret = 0;
+
+       mutex_lock(&sensor->lock);
+
+       if (sensor->power_count == !on) {
+               if (on)
+                       ret = __s5k6a3_power_on(sensor);
+               else
+                       ret = __s5k6a3_power_off(sensor);
+
+               if (ret == 0)
+                       sensor->power_count += on ? 1 : -1;
+       }
+
+       mutex_unlock(&sensor->lock);
+       return ret;
+}
+
+static struct v4l2_subdev_core_ops s5k6a3_core_ops = {
+       .s_power = s5k6a3_s_power,
+};
+
+static struct v4l2_subdev_ops s5k6a3_subdev_ops = {
+       .core = &s5k6a3_core_ops,
+       .pad = &s5k6a3_pad_ops,
+};
+
+static int s5k6a3_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct s5k6a3 *sensor;
+       struct v4l2_subdev *sd;
+       int gpio, i, ret;
+
+       sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
+       if (!sensor)
+               return -ENOMEM;
+
+       mutex_init(&sensor->lock);
+       sensor->gpio_reset = -EINVAL;
+       sensor->clock = ERR_PTR(-EINVAL);
+       sensor->dev = dev;
+
+       sensor->clock = devm_clk_get(sensor->dev, S5K6A3_CLK_NAME);
+       if (IS_ERR(sensor->clock))
+               return PTR_ERR(sensor->clock);
+
+       gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
+       if (!gpio_is_valid(gpio))
+               return gpio;
+
+       ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
+                                               S5K6A3_DRV_NAME);
+       if (ret < 0)
+               return ret;
+
+       sensor->gpio_reset = gpio;
+
+       if (of_property_read_u32(dev->of_node, "clock-frequency",
+                                &sensor->clock_frequency)) {
+               sensor->clock_frequency = S5K6A3_DEFAULT_CLK_FREQ;
+               dev_info(dev, "using default %u Hz clock frequency\n",
+                                       sensor->clock_frequency);
+       }
+
+       for (i = 0; i < S5K6A3_NUM_SUPPLIES; i++)
+               sensor->supplies[i].supply = s5k6a3_supply_names[i];
+
+       ret = devm_regulator_bulk_get(&client->dev, S5K6A3_NUM_SUPPLIES,
+                                     sensor->supplies);
+       if (ret < 0)
+               return ret;
+
+       sd = &sensor->subdev;
+       v4l2_i2c_subdev_init(sd, client, &s5k6a3_subdev_ops);
+       sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       sd->internal_ops = &s5k6a3_sd_internal_ops;
+
+       sensor->format.code = s5k6a3_formats[0].code;
+       sensor->format.width = S5K6A3_DEFAULT_WIDTH;
+       sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
+
+       sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
+       if (ret < 0)
+               return ret;
+
+       pm_runtime_no_callbacks(dev);
+       pm_runtime_enable(dev);
+
+       ret = v4l2_async_register_subdev(sd);
+
+       if (ret < 0) {
+               pm_runtime_disable(&client->dev);
+               media_entity_cleanup(&sd->entity);
+       }
+
+       return ret;
+}
+
+static int s5k6a3_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+       pm_runtime_disable(&client->dev);
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       return 0;
+}
+
+static const struct i2c_device_id s5k6a3_ids[] = {
+       { }
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id s5k6a3_of_match[] = {
+       { .compatible = "samsung,s5k6a3" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, s5k6a3_of_match);
+#endif
+
+static struct i2c_driver s5k6a3_driver = {
+       .driver = {
+               .of_match_table = of_match_ptr(s5k6a3_of_match),
+               .name           = S5K6A3_DRV_NAME,
+               .owner          = THIS_MODULE,
+       },
+       .probe          = s5k6a3_probe,
+       .remove         = s5k6a3_remove,
+       .id_table       = s5k6a3_ids,
+};
+
+module_i2c_driver(s5k6a3_driver);
+
+MODULE_DESCRIPTION("S5K6A3 image sensor subdev driver");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_LICENSE("GPL v2");
index ae9432637fcbb7d3e7777a2e9918ed4b37c37efe..118f8ee88465acec05bef5c452b9753601ed760b 100644 (file)
@@ -8,7 +8,7 @@
  * and HeungJun Kim <riverful.kim@samsung.com>.
  *
  * Based on mt9v011 Micron Digital Image Sensor driver
- * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
+ * Copyright (c) 2009 Mauro Carvalho Chehab
  *
  * 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
index 04139eec8c4eb9ba5780d360b37bc5dbc8b204d2..f72561e79739f4603e96b560931954691aafe604 100644 (file)
@@ -217,8 +217,8 @@ static void ths8200_core_init(struct v4l2_subdev *sd)
        /* Disable embedded syncs on the output by setting
         * the amplitude to zero for all channels.
         */
-       ths8200_write(sd, THS8200_DTG1_Y_SYNC_MSB, 0x2a);
-       ths8200_write(sd, THS8200_DTG1_CBCR_SYNC_MSB, 0x2a);
+       ths8200_write(sd, THS8200_DTG1_Y_SYNC_MSB, 0x00);
+       ths8200_write(sd, THS8200_DTG1_CBCR_SYNC_MSB, 0x00);
 }
 
 static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
@@ -318,15 +318,15 @@ static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
                             (htotal(bt) >> 8) & 0x1f);
        ths8200_write(sd, THS8200_DTG2_HLENGTH_HDLY_LSB, htotal(bt));
 
-       /* v sync width transmitted */
-       ths8200_write(sd, THS8200_DTG2_VLENGTH1_LSB, (bt->vsync) & 0xff);
+       /* v sync width transmitted (must add 1 to get correct output) */
+       ths8200_write(sd, THS8200_DTG2_VLENGTH1_LSB, (bt->vsync + 1) & 0xff);
        ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0x3f,
-                            ((bt->vsync) >> 2) & 0xc0);
+                            ((bt->vsync + 1) >> 2) & 0xc0);
 
-       /* The pixel value v sync is asserted on */
+       /* The pixel value v sync is asserted on (must add 1 to get correct output) */
        ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0xf8,
-                            (vtotal(bt)>>8) & 0x7);
-       ths8200_write(sd, THS8200_DTG2_VDLY1_LSB, vtotal(bt));
+                            ((vtotal(bt) + 1) >> 8) & 0x7);
+       ths8200_write(sd, THS8200_DTG2_VDLY1_LSB, vtotal(bt) + 1);
 
        /* For progressive video vlength2 must be set to all 0 and vdly2 must
         * be set to all 1.
@@ -336,11 +336,11 @@ static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
        ths8200_write(sd, THS8200_DTG2_VDLY2_LSB, 0xff);
 
        /* Internal delay factors to synchronize the sync pulses and the data */
-       /* Experimental values delays (hor 4, ver 1) */
-       ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_MSB, (htotal(bt)>>8) & 0x1f);
-       ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_LSB, (htotal(bt) - 4) & 0xff);
+       /* Experimental values delays (hor 0, ver 0) */
+       ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_MSB, 0);
+       ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_LSB, 0);
        ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_MSB, 0);
-       ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_LSB, 1);
+       ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_LSB, 0);
 
        /* Polarity of received and transmitted sync signals */
        if (bt->polarities & V4L2_DV_HSYNC_POS_POL) {
@@ -356,7 +356,7 @@ static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
        /* Timing of video input bus is derived from HS, VS, and FID dedicated
         * inputs
         */
-       ths8200_write(sd, THS8200_DTG2_CNTL, 0x47 | polarity);
+       ths8200_write(sd, THS8200_DTG2_CNTL, 0x44 | polarity);
 
        /* leave reset */
        ths8200_s_stream(sd, true);
index 542d2528b3f913767c37db19512303dbed2e76b2..4fd3688e1164e77ee69f8342d0c0125a1b0d01cd 100644 (file)
@@ -16,9 +16,9 @@
 
 #include "tvp5150_reg.h"
 
-#define TVP5150_H_MAX          720
-#define TVP5150_V_MAX_525_60   480
-#define TVP5150_V_MAX_OTHERS   576
+#define TVP5150_H_MAX          720U
+#define TVP5150_V_MAX_525_60   480U
+#define TVP5150_V_MAX_OTHERS   576U
 #define TVP5150_MAX_CROP_LEFT  511
 #define TVP5150_MAX_CROP_TOP   127
 #define TVP5150_CROP_SHIFT     2
@@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
 
 
 static int debug;
-module_param(debug, int, 0);
+module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 struct tvp5150 {
index d12bd33f39cb3c7f322a0ef4d2965d1ebfa542c6..8a0e84c7d495a158a01771dd693ce18db0428114 100644 (file)
@@ -667,13 +667,16 @@ static void buffer_queue(struct vb2_buffer *vb)
        vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 }
 
-static int buffer_finish(struct vb2_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
 {
        struct qcam *qcam = vb2_get_drv_priv(vb->vb2_queue);
        void *vbuf = vb2_plane_vaddr(vb, 0);
        int size = vb->vb2_queue->plane_sizes[0];
        int len;
 
+       if (!vb2_is_streaming(vb->vb2_queue))
+               return;
+
        mutex_lock(&qcam->lock);
        parport_claim_or_block(qcam->pdev);
 
@@ -691,7 +694,6 @@ static int buffer_finish(struct vb2_buffer *vb)
        if (len != size)
                vb->state = VB2_BUF_STATE_ERROR;
        vb2_set_plane_payload(vb, 0, len);
-       return 0;
 }
 
 static struct vb2_ops qcam_video_qops = {
@@ -965,7 +967,7 @@ static struct qcam *qcam_init(struct parport *port)
        q->drv_priv = qcam;
        q->ops = &qcam_video_qops;
        q->mem_ops = &vb2_vmalloc_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        err = vb2_queue_init(q);
        if (err < 0) {
                v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name);
index 6662b495b22c637c73ee2f6e50bf8571e5d2e948..d06963b3dcf3b62677d4e2f90146c82df51cae7e 100644 (file)
@@ -2855,7 +2855,22 @@ struct tvcard bttv_tvcards[] = {
                .tuner_type     = TUNER_ABSENT,
                .tuner_addr     = ADDR_UNSET,
        },
-
+       [BTTV_BOARD_KWORLD_VSTREAM_XPERT] = {
+               /* Pojar George <geoubuntu@gmail.com> */
+               .name           = "Kworld V-Stream Xpert TV PVR878",
+               .video_inputs   = 3,
+               /* .audio_inputs= 1, */
+               .svhs           = 2,
+               .gpiomask       = 0x001c0007,
+               .muxsel         = MUXSEL(2, 3, 1, 1),
+               .gpiomux        = { 0, 1, 2, 2 },
+               .gpiomute       = 3,
+               .pll            = PLL_28,
+               .tuner_type     = TUNER_TENA_9533_DI,
+               .tuner_addr    = ADDR_UNSET,
+               .has_remote     = 1,
+               .has_radio      = 1,
+       },
 };
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
index f36821367d8d708c24294234a4b58038486476cc..5930bce166588ecf7d8de6ca7e901532ab62f5b6 100644 (file)
@@ -483,6 +483,7 @@ int bttv_input_init(struct bttv *btv)
        case BTTV_BOARD_ASKEY_CPH03X:
        case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
        case BTTV_BOARD_CONTVFMI:
+       case BTTV_BOARD_KWORLD_VSTREAM_XPERT:
                ir_codes         = RC_MAP_PIXELVIEW;
                ir->mask_keycode = 0x001F00;
                ir->mask_keyup   = 0x006000;
index df578efe03c9a7d4faa6cbe6410e9e83e94f863f..bb5da349a46ec6755aea58e5f534073ad45402e5 100644 (file)
 #define BTTV_BOARD_ADLINK_MPG24            0xa2
 #define BTTV_BOARD_BT848_CAP_14            0xa3
 #define BTTV_BOARD_CYBERVISION_CV06        0xa4
+#define BTTV_BOARD_KWORLD_VSTREAM_XPERT    0xa5
 
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10
index 05492053b473033da6da030fb1f64d7dcf2ea0ef..4be01b3bd4f55da45db9d7d771a1181a395a5d6c 100644 (file)
@@ -473,6 +473,7 @@ static struct ds3000_config tevii_ds3000_config = {
 static struct ts2020_config tevii_ts2020_config  = {
        .tuner_address = 0x60,
        .clk_out_div = 1,
+       .frequency_div = 1146000,
 };
 
 static struct cx24116_config dvbworld_cx24116_config = {
index 8a49e7c9eddd76f508f8131a8533f552ad7db98b..097d0a0b5f57ada60fd50ae78b6c2ffd654b7b37 100644 (file)
@@ -346,7 +346,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
        }
        rc->dev.parent = &dev->pci->dev;
        rc->driver_type = driver_type;
-       rc->allowed_protos = allowed_protos;
+       rc_set_allowed_protocols(rc, allowed_protos);
        rc->priv = kernel_ir;
        rc->open = cx23885_input_ir_open;
        rc->close = cx23885_input_ir_close;
index f29e18c72f44ffa6462c09ae870445a67326431b..f991696a6c5923a99f2fe654932331b42cb7036f 100644 (file)
@@ -469,7 +469,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
                dev->timeout = 10 * 1000 * 1000; /* 10 ms */
        } else {
                dev->driver_type = RC_DRIVER_SCANCODE;
-               dev->allowed_protos = rc_type;
+               rc_set_allowed_protocols(dev, rc_type);
        }
 
        ir->core = core;
index 9375f30d9a81bfcc5fba2a35953855f8741a6610..fb52bda8d45f7922b9eb1b3dfd0002aa9fce2c73 100644 (file)
@@ -876,10 +876,8 @@ static int dvb_input_attach(struct ddb_input *input)
                        return -ENODEV;
                if (tuner_attach_tda18271(input) < 0)
                        return -ENODEV;
-               if (input->fe) {
-                       if (dvb_register_frontend(adap, input->fe) < 0)
-                               return -ENODEV;
-               }
+               if (dvb_register_frontend(adap, input->fe) < 0)
+                       return -ENODEV;
                if (input->fe2) {
                        if (dvb_register_frontend(adap, input->fe2) < 0)
                                return -ENODEV;
index c9b2350e92c863f87b329e8972d50fafa883dc90..6e4bdb90aa92e63c13d0d00c5bba90b4b4f09325 100644 (file)
@@ -8045,8 +8045,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                break;
        } /* switch() */
 
-       /* initialize tuner */
-       if (TUNER_ABSENT != dev->tuner_type) {
+       /* initialize tuner (don't do this when resuming) */
+       if (!dev->insuspend && TUNER_ABSENT != dev->tuner_type) {
                int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
 
                /* Note: radio tuner address is always filled in,
index e5cfb6cfa18da513e70e7e41d9a06084eedd1555..bb11443ed63e840b9bdd933e3aa4fdaaa1aa3330 100644 (file)
@@ -327,7 +327,7 @@ static void buffer_queue(struct vb2_buffer *vb)
        }
        spin_unlock(&vip->lock);
 }
-static int buffer_finish(struct vb2_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
 {
        struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
        struct vip_buffer *vip_buf = to_vip_buffer(vb);
@@ -337,9 +337,8 @@ static int buffer_finish(struct vb2_buffer *vb)
        list_del_init(&vip_buf->list);
        spin_unlock(&vip->lock);
 
-       vip_active_buf_next(vip);
-
-       return 0;
+       if (vb2_is_streaming(vb->vb2_queue))
+               vip_active_buf_next(vip);
 }
 
 static int start_streaming(struct vb2_queue *vq, unsigned int count)
index 6299d5dadb822758bc4a2d9c1bb8a922bdfcd193..300bd3c9473876fb7b2751da7ab91532397621c2 100644 (file)
@@ -501,7 +501,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
 
 //     dprintk(4, "%p\n", av7110);
 
-       if (2 + num > sizeof(buf)) {
+       if (2 + num > ARRAY_SIZE(buf)) {
                printk(KERN_WARNING
                       "%s: %s len=%d is too big!\n",
                       KBUILD_MODNAME, __func__, num);
index b2a4403940c551e68d00bc8974b89707c4f35d98..c137abfa0c543dd33f15e3888ab4590900733bba 100644 (file)
@@ -36,7 +36,7 @@ source "drivers/media/platform/blackfin/Kconfig"
 config VIDEO_SH_VOU
        tristate "SuperH VOU video output driver"
        depends on MEDIA_CAMERA_SUPPORT
-       depends on VIDEO_DEV && I2C
+       depends on VIDEO_DEV && I2C && HAS_DMA
        depends on ARCH_SHMOBILE || COMPILE_TEST
        select VIDEOBUF_DMA_CONTIG
        help
index e346d32d08ce5cd5a95a3fef8e86385c6ae5ca91..e9410e41ae0cfd7f1e0c7d4fc6ae7e62c073b281 100644 (file)
@@ -109,7 +109,7 @@ extern struct cpuinfo_m32r  boot_cpu_data;
 struct ar {
        struct v4l2_device v4l2_dev;
        struct video_device vdev;
-       unsigned int start_capture;     /* duaring capture in INT. mode. */
+       int start_capture;      /* duaring capture in INT. mode. */
 #if USE_INT
        unsigned char *line_buff;       /* DMA line buffer */
 #endif
@@ -307,11 +307,11 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
        /*
         * Okay, kick AR LSI to invoke an interrupt
         */
-       ar->start_capture = 0;
+       ar->start_capture = -1;
        ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
        local_irq_restore(flags);
        /* .... AR interrupts .... */
-       interruptible_sleep_on(&ar->wait);
+       wait_event_interruptible(ar->wait, ar->start_capture == 0);
        if (signal_pending(current)) {
                printk(KERN_ERR "arv: interrupted while get frame data.\n");
                ret = -EINTR;
index 281916591437fa8196cf9312a873c36135a7f915..200bec91182e9179d1e3c1acabc75eed1b70d3c2 100644 (file)
@@ -997,7 +997,7 @@ static int bcap_probe(struct platform_device *pdev)
        q->buf_struct_size = sizeof(struct bcap_buffer);
        q->ops = &bcap_video_qops;
        q->mem_ops = &vb2_dma_contig_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        ret = vb2_queue_init(q);
        if (ret)
index 61f3dbcc259f40f8a0f6f2b4bfa9b52ed6bf24ee..3e5199ee5d2503c57f37276748f527aa00e8cc18 100644 (file)
@@ -2428,7 +2428,7 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &coda_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        ret = vb2_queue_init(src_vq);
        if (ret)
@@ -2440,7 +2440,7 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &coda_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        return vb2_queue_init(dst_vq);
 }
@@ -2829,6 +2829,9 @@ static void coda_finish_encode(struct coda_ctx *ctx)
        }
 
        dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
+       dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       dst_buf->v4l2_buf.flags |=
+               src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
        dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
 
        v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
index b02aba48882632661962aa52380248409a8457d4..b4f12d00be059c3f381b31295d435074ee291dab 100644 (file)
@@ -341,14 +341,8 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
        struct vpbe_fh *fh = vb2_get_drv_priv(vq);
        struct vpbe_layer *layer = fh->layer;
-       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
        int ret;
 
-       /* If buffer queue is empty, return error */
-       if (list_empty(&layer->dma_queue)) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
-               return -ENOBUFS;
-       }
        /* Get the next frame from the buffer queue */
        layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
                                struct vpbe_disp_buffer, list);
@@ -1415,7 +1409,8 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
        q->ops = &video_qops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->min_buffers_needed = 1;
 
        ret = vb2_queue_init(q);
        if (ret) {
index 735ec47601a9c3241e790315e46efbc437668e56..756da78bac23109dbd3e7da464243da381354231 100644 (file)
@@ -272,13 +272,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        unsigned long flags;
        int ret;
 
-       /* If buffer queue is empty, return error */
        spin_lock_irqsave(&common->irqlock, flags);
-       if (list_empty(&common->dma_queue)) {
-               spin_unlock_irqrestore(&common->irqlock, flags);
-               vpif_dbg(1, debug, "buffer queue is empty\n");
-               return -ENOBUFS;
-       }
 
        /* Get the next frame from the buffer queue */
        common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
@@ -1023,7 +1017,8 @@ static int vpif_reqbufs(struct file *file, void *priv,
        q->ops = &video_qops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct vpif_cap_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->min_buffers_needed = 1;
 
        ret = vb2_queue_init(q);
        if (ret) {
index 9d115cdc6bdbfdbfc7b1a655346d6a2ad3a13d7e..0ac841e35aa48dd59bdf17b32f97afbe94b561b5 100644 (file)
@@ -234,13 +234,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        unsigned long flags;
        int ret;
 
-       /* If buffer queue is empty, return error */
        spin_lock_irqsave(&common->irqlock, flags);
-       if (list_empty(&common->dma_queue)) {
-               spin_unlock_irqrestore(&common->irqlock, flags);
-               vpif_err("buffer queue is empty\n");
-               return -ENOBUFS;
-       }
 
        /* Get the next frame from the buffer queue */
        common->next_frm = common->cur_frm =
@@ -983,7 +977,8 @@ static int vpif_reqbufs(struct file *file, void *priv,
        q->ops = &video_qops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct vpif_disp_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->min_buffers_needed = 1;
 
        ret = vb2_queue_init(q);
        if (ret) {
index 810c3e13970caec5787cfda77ff5c3c30314997d..d0ea94f58d6f5ce84e05dfc6efcdfd49f48f74ff 100644 (file)
@@ -88,8 +88,12 @@ void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
        dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
        if (src_vb && dst_vb) {
-               src_vb->v4l2_buf.timestamp = dst_vb->v4l2_buf.timestamp;
-               src_vb->v4l2_buf.timecode = dst_vb->v4l2_buf.timecode;
+               dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
+               dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
+               dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+               dst_vb->v4l2_buf.flags |=
+                       src_vb->v4l2_buf.flags
+                       & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 
                v4l2_m2m_buf_done(src_vb, vb_state);
                v4l2_m2m_buf_done(dst_vb, vb_state);
@@ -590,7 +594,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->ops = &gsc_m2m_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        ret = vb2_queue_init(src_vq);
        if (ret)
@@ -603,7 +607,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->ops = &gsc_m2m_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        return vb2_queue_init(dst_vq);
 }
index 01ed1ecdff7e671fd46b4f0f3438c3a8f6c60658..e1b2ceba00c13e2136e548693ff3038df5c89cae 100644 (file)
@@ -64,4 +64,13 @@ config VIDEO_EXYNOS4_FIMC_IS
          To compile this driver as a module, choose M here: the
          module will be called exynos4-fimc-is.
 
+config VIDEO_EXYNOS4_ISP_DMA_CAPTURE
+       bool "EXYNOS4x12 FIMC-IS ISP Direct DMA capture support"
+       depends on VIDEO_EXYNOS4_FIMC_IS
+       select VIDEO_EXYNOS4_IS_COMMON
+       default y
+         help
+         This option enables an additional video device node exposing a V4L2
+         video capture interface for the FIMC-IS ISP raw (Bayer) capture DMA.
+
 endif # VIDEO_SAMSUNG_EXYNOS4_IS
index c2ff29ba68561302c1c9d78c31d6229fa63e8bef..eed1b185d813e22fa343f2893548a52118282a63 100644 (file)
@@ -6,6 +6,10 @@ exynos4-is-common-objs := common.o
 exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
 exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
 
+ifeq ($(CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE),y)
+exynos-fimc-is-objs += fimc-isp-video.o
+endif
+
 obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS)      += s5p-csis.o
 obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE)   += exynos-fimc-lite.o
 obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS)    += exynos-fimc-is.o
index 8a712ca91d11bcf46f424778433b3c7c07bbdc78..92ae812abce273690ea1cc4e0cd55f73cf3a66c0 100644 (file)
@@ -1782,7 +1782,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
        q->ops = &fimc_capture_qops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct fimc_vid_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        q->lock = &fimc->lock;
 
        ret = vb2_queue_init(q);
index 9bf3ddd9e028d6686cd8a0941080364da1622aa9..bf1465d1bf6d709b266862bef57b61b257f22bfc 100644 (file)
@@ -56,7 +56,7 @@ static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
        __hw_param_copy(dst, src);
 }
 
-static int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset)
+int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset)
 {
        struct is_param_region *par = &is->is_p_region->parameter;
        struct chain_config *cfg = &is->config[is->config_index];
index f9358c27ae2dc723a01c17708b9c7ca1a0b45fe6..8e31f76427762b2b35d08633fc7aa0a4d0337bf0 100644 (file)
@@ -911,6 +911,10 @@ struct is_region {
        u32 shared[MAX_SHARED_COUNT];
 } __packed;
 
+/* Offset to the ISP DMA2 output buffer address array. */
+#define DMA2_OUTPUT_ADDR_ARRAY_OFFS \
+       (offsetof(struct is_region, shared) + 32 * sizeof(u32))
+
 struct is_debug_frame_descriptor {
        u32 sensor_frame_time;
        u32 sensor_exposure_time;
@@ -988,6 +992,7 @@ struct sensor_open_extended {
 struct fimc_is;
 
 int fimc_is_hw_get_sensor_max_framerate(struct fimc_is *is);
+int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset);
 void fimc_is_set_initial_params(struct fimc_is *is);
 unsigned int __get_pending_param_count(struct fimc_is *is);
 
index 2628733c4e104f6e7790a74b40f1add7416a2760..cfe4406a83ffc0fc3e7fca6dd03cee84a9f3838b 100644 (file)
@@ -105,6 +105,20 @@ int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num_args)
        return 0;
 }
 
+void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask)
+{
+       if (hweight32(mask) == 1) {
+               dev_err(&is->pdev->dev, "%s(): not enough buffers (mask %#x)\n",
+                                                       __func__, mask);
+               return;
+       }
+
+       if (mcuctl_read(is, MCUCTL_REG_ISSR(23)) != 0)
+               dev_dbg(&is->pdev->dev, "non-zero DMA buffer mask\n");
+
+       mcuctl_write(mask, is, MCUCTL_REG_ISSR(23));
+}
+
 void fimc_is_hw_set_sensor_num(struct fimc_is *is)
 {
        pr_debug("setting sensor index to: %d\n", is->sensor_index);
@@ -112,7 +126,7 @@ void fimc_is_hw_set_sensor_num(struct fimc_is *is)
        mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0));
        mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
        mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2));
-       mcuctl_write(FIMC_IS_SENSOR_NUM, is, MCUCTL_REG_ISSR(3));
+       mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3));
 }
 
 void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
index 1d9d4ffc6ad59ca8d24fbd0bef0005ece14d1354..141e5ddadbeb47b27b584238a02ab21897dcc8fe 100644 (file)
@@ -147,6 +147,7 @@ int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num);
 void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is);
 int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is);
 void fimc_is_hw_set_sensor_num(struct fimc_is *is);
+void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask);
 void fimc_is_hw_stream_on(struct fimc_is *is);
 void fimc_is_hw_stream_off(struct fimc_is *is);
 int fimc_is_hw_set_param(struct fimc_is *is);
index 6647421e5d3af6fca69e364c2e87af0abc2f2bf6..10e82e21b5d16d20b8297783be40b6e6f046c379 100644 (file)
  * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
  *
  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of_gpio.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <media/v4l2-subdev.h>
 
-#include "fimc-is.h"
 #include "fimc-is-sensor.h"
 
-#define DRIVER_NAME "FIMC-IS-SENSOR"
-
-static const char * const sensor_supply_names[] = {
-       "svdda",
-       "svddio",
-};
-
-static const struct v4l2_mbus_framefmt fimc_is_sensor_formats[] = {
-       {
-               .code = V4L2_MBUS_FMT_SGRBG10_1X10,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .field = V4L2_FIELD_NONE,
-       }
-};
-
-static const struct v4l2_mbus_framefmt *find_sensor_format(
-       struct v4l2_mbus_framefmt *mf)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(fimc_is_sensor_formats); i++)
-               if (mf->code == fimc_is_sensor_formats[i].code)
-                       return &fimc_is_sensor_formats[i];
-
-       return &fimc_is_sensor_formats[0];
-}
-
-static int fimc_is_sensor_enum_mbus_code(struct v4l2_subdev *sd,
-                                 struct v4l2_subdev_fh *fh,
-                                 struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->index >= ARRAY_SIZE(fimc_is_sensor_formats))
-               return -EINVAL;
-
-       code->code = fimc_is_sensor_formats[code->index].code;
-       return 0;
-}
-
-static void fimc_is_sensor_try_format(struct fimc_is_sensor *sensor,
-                                     struct v4l2_mbus_framefmt *mf)
-{
-       const struct sensor_drv_data *dd = sensor->drvdata;
-       const struct v4l2_mbus_framefmt *fmt;
-
-       fmt = find_sensor_format(mf);
-       mf->code = fmt->code;
-       v4l_bound_align_image(&mf->width, 16 + 8, dd->width, 0,
-                             &mf->height, 12 + 8, dd->height, 0, 0);
-}
-
-static struct v4l2_mbus_framefmt *__fimc_is_sensor_get_format(
-               struct fimc_is_sensor *sensor, struct v4l2_subdev_fh *fh,
-               u32 pad, enum v4l2_subdev_format_whence which)
-{
-       if (which == V4L2_SUBDEV_FORMAT_TRY)
-               return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
-
-       return &sensor->format;
-}
-
-static int fimc_is_sensor_set_fmt(struct v4l2_subdev *sd,
-                                 struct v4l2_subdev_fh *fh,
-                                 struct v4l2_subdev_format *fmt)
-{
-       struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd);
-       struct v4l2_mbus_framefmt *mf;
-
-       fimc_is_sensor_try_format(sensor, &fmt->format);
-
-       mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which);
-       if (mf) {
-               mutex_lock(&sensor->lock);
-               if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-                       *mf = fmt->format;
-               mutex_unlock(&sensor->lock);
-       }
-       return 0;
-}
-
-static int fimc_is_sensor_get_fmt(struct v4l2_subdev *sd,
-                                 struct v4l2_subdev_fh *fh,
-                                 struct v4l2_subdev_format *fmt)
-{
-       struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd);
-       struct v4l2_mbus_framefmt *mf;
-
-       mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which);
-
-       mutex_lock(&sensor->lock);
-       fmt->format = *mf;
-       mutex_unlock(&sensor->lock);
-       return 0;
-}
-
-static struct v4l2_subdev_pad_ops fimc_is_sensor_pad_ops = {
-       .enum_mbus_code = fimc_is_sensor_enum_mbus_code,
-       .get_fmt        = fimc_is_sensor_get_fmt,
-       .set_fmt        = fimc_is_sensor_set_fmt,
-};
-
-static int fimc_is_sensor_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-       struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
-
-       *format         = fimc_is_sensor_formats[0];
-       format->width   = FIMC_IS_SENSOR_DEF_PIX_WIDTH;
-       format->height  = FIMC_IS_SENSOR_DEF_PIX_HEIGHT;
-
-       return 0;
-}
-
-static const struct v4l2_subdev_internal_ops fimc_is_sensor_sd_internal_ops = {
-       .open = fimc_is_sensor_open,
-};
-
-static int fimc_is_sensor_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd);
-       int gpio = sensor->gpio_reset;
-       int ret;
-
-       if (on) {
-               ret = pm_runtime_get(sensor->dev);
-               if (ret < 0)
-                       return ret;
-
-               ret = regulator_bulk_enable(SENSOR_NUM_SUPPLIES,
-                                           sensor->supplies);
-               if (ret < 0) {
-                       pm_runtime_put(sensor->dev);
-                       return ret;
-               }
-               if (gpio_is_valid(gpio)) {
-                       gpio_set_value(gpio, 1);
-                       usleep_range(600, 800);
-                       gpio_set_value(gpio, 0);
-                       usleep_range(10000, 11000);
-                       gpio_set_value(gpio, 1);
-               }
-
-               /* A delay needed for the sensor initialization. */
-               msleep(20);
-       } else {
-               if (gpio_is_valid(gpio))
-                       gpio_set_value(gpio, 0);
-
-               ret = regulator_bulk_disable(SENSOR_NUM_SUPPLIES,
-                                            sensor->supplies);
-               if (!ret)
-                       pm_runtime_put(sensor->dev);
-       }
-
-       pr_info("%s:%d: on: %d, ret: %d\n", __func__, __LINE__, on, ret);
-
-       return ret;
-}
-
-static struct v4l2_subdev_core_ops fimc_is_sensor_core_ops = {
-       .s_power = fimc_is_sensor_s_power,
-};
-
-static struct v4l2_subdev_ops fimc_is_sensor_subdev_ops = {
-       .core = &fimc_is_sensor_core_ops,
-       .pad = &fimc_is_sensor_pad_ops,
-};
-
-static const struct of_device_id fimc_is_sensor_of_match[];
-
-static int fimc_is_sensor_probe(struct i2c_client *client,
-                               const struct i2c_device_id *id)
-{
-       struct device *dev = &client->dev;
-       struct fimc_is_sensor *sensor;
-       const struct of_device_id *of_id;
-       struct v4l2_subdev *sd;
-       int gpio, i, ret;
-
-       sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
-       if (!sensor)
-               return -ENOMEM;
-
-       mutex_init(&sensor->lock);
-       sensor->gpio_reset = -EINVAL;
-
-       gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
-       if (gpio_is_valid(gpio)) {
-               ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
-                                                       DRIVER_NAME);
-               if (ret < 0)
-                       return ret;
-       }
-       sensor->gpio_reset = gpio;
-
-       for (i = 0; i < SENSOR_NUM_SUPPLIES; i++)
-               sensor->supplies[i].supply = sensor_supply_names[i];
-
-       ret = devm_regulator_bulk_get(&client->dev, SENSOR_NUM_SUPPLIES,
-                                     sensor->supplies);
-       if (ret < 0)
-               return ret;
-
-       of_id = of_match_node(fimc_is_sensor_of_match, dev->of_node);
-       if (!of_id)
-               return -ENODEV;
-
-       sensor->drvdata = of_id->data;
-       sensor->dev = dev;
-
-       sd = &sensor->subdev;
-       v4l2_i2c_subdev_init(sd, client, &fimc_is_sensor_subdev_ops);
-       snprintf(sd->name, sizeof(sd->name), sensor->drvdata->subdev_name);
-       sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
-       sensor->format.code = fimc_is_sensor_formats[0].code;
-       sensor->format.width = FIMC_IS_SENSOR_DEF_PIX_WIDTH;
-       sensor->format.height = FIMC_IS_SENSOR_DEF_PIX_HEIGHT;
-
-       sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-       ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
-       if (ret < 0)
-               return ret;
-
-       pm_runtime_no_callbacks(dev);
-       pm_runtime_enable(dev);
-
-       return ret;
-}
-
-static int fimc_is_sensor_remove(struct i2c_client *client)
-{
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
-       media_entity_cleanup(&sd->entity);
-       return 0;
-}
-
-static const struct i2c_device_id fimc_is_sensor_ids[] = {
-       { }
-};
-
 static const struct sensor_drv_data s5k6a3_drvdata = {
        .id             = FIMC_IS_SENSOR_ID_S5K6A3,
-       .subdev_name    = "S5K6A3",
-       .width          = S5K6A3_SENSOR_WIDTH,
-       .height         = S5K6A3_SENSOR_HEIGHT,
+       .open_timeout   = S5K6A3_OPEN_TIMEOUT,
 };
 
-static const struct of_device_id fimc_is_sensor_of_match[] = {
+static const struct of_device_id fimc_is_sensor_of_ids[] = {
        {
                .compatible     = "samsung,s5k6a3",
                .data           = &s5k6a3_drvdata,
@@ -279,27 +24,11 @@ static const struct of_device_id fimc_is_sensor_of_match[] = {
        {  }
 };
 
-static struct i2c_driver fimc_is_sensor_driver = {
-       .driver = {
-               .of_match_table = fimc_is_sensor_of_match,
-               .name           = DRIVER_NAME,
-               .owner          = THIS_MODULE,
-       },
-       .probe          = fimc_is_sensor_probe,
-       .remove         = fimc_is_sensor_remove,
-       .id_table       = fimc_is_sensor_ids,
-};
-
-int fimc_is_register_sensor_driver(void)
+const struct sensor_drv_data *fimc_is_sensor_get_drvdata(
+                       struct device_node *node)
 {
-       return i2c_add_driver(&fimc_is_sensor_driver);
-}
+       const struct of_device_id *of_id;
 
-void fimc_is_unregister_sensor_driver(void)
-{
-       i2c_del_driver(&fimc_is_sensor_driver);
+       of_id = of_match_node(fimc_is_sensor_of_ids, node);
+       return of_id ? of_id->data : NULL;
 }
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("Exynos4x12 FIMC-IS image sensor subdev driver");
-MODULE_LICENSE("GPL");
index 6036d49a6c689e5bf10e2ec92fcdf5cab8efda2b..173ccffa4bcdbf48337c24a9fa52cfbbf6c0e37a 100644 (file)
 #ifndef FIMC_IS_SENSOR_H_
 #define FIMC_IS_SENSOR_H_
 
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-
-#define FIMC_IS_SENSOR_OPEN_TIMEOUT    2000 /* ms */
-
-#define FIMC_IS_SENSOR_DEF_PIX_WIDTH   1296
-#define FIMC_IS_SENSOR_DEF_PIX_HEIGHT  732
+#include <linux/of.h>
+#include <linux/types.h>
 
+#define S5K6A3_OPEN_TIMEOUT            2000 /* ms */
 #define S5K6A3_SENSOR_WIDTH            1392
 #define S5K6A3_SENSOR_HEIGHT           1392
 
-#define SENSOR_NUM_SUPPLIES            2
-
 enum fimc_is_sensor_id {
        FIMC_IS_SENSOR_ID_S5K3H2 = 1,
        FIMC_IS_SENSOR_ID_S5K6A3,
@@ -45,45 +34,23 @@ enum fimc_is_sensor_id {
 
 struct sensor_drv_data {
        enum fimc_is_sensor_id id;
-       const char * const subdev_name;
-       unsigned int width;
-       unsigned int height;
+       /* sensor open timeout in ms */
+       unsigned short open_timeout;
 };
 
 /**
  * struct fimc_is_sensor - fimc-is sensor data structure
- * @dev: pointer to this I2C client device structure
- * @subdev: the image sensor's v4l2 subdev
- * @pad: subdev media source pad
- * @supplies: image sensor's voltage regulator supplies
- * @gpio_reset: GPIO connected to the sensor's reset pin
  * @drvdata: a pointer to the sensor's parameters data structure
  * @i2c_bus: ISP I2C bus index (0...1)
  * @test_pattern: true to enable video test pattern
- * @lock: mutex protecting the structure's members below
- * @format: media bus format at the sensor's source pad
  */
 struct fimc_is_sensor {
-       struct device *dev;
-       struct v4l2_subdev subdev;
-       struct media_pad pad;
-       struct regulator_bulk_data supplies[SENSOR_NUM_SUPPLIES];
-       int gpio_reset;
        const struct sensor_drv_data *drvdata;
        unsigned int i2c_bus;
-       bool test_pattern;
-
-       struct mutex lock;
-       struct v4l2_mbus_framefmt format;
+       u8 test_pattern;
 };
 
-static inline
-struct fimc_is_sensor *sd_to_fimc_is_sensor(struct v4l2_subdev *sd)
-{
-       return container_of(sd, struct fimc_is_sensor, subdev);
-}
-
-int fimc_is_register_sensor_driver(void);
-void fimc_is_unregister_sensor_driver(void);
+const struct sensor_drv_data *fimc_is_sensor_get_drvdata(
+                               struct device_node *node);
 
 #endif /* FIMC_IS_SENSOR_H_ */
index 9bdfa4599bc30d47d696945fa04c9179d0f8e538..128b73b6cce26289702fdd47cad801d3164caf12 100644 (file)
@@ -161,78 +161,69 @@ static void fimc_is_disable_clocks(struct fimc_is *is)
        }
 }
 
-static int fimc_is_parse_sensor_config(struct fimc_is_sensor *sensor,
-                                      struct device_node *np)
+static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
+                                               struct device_node *node)
 {
+       struct fimc_is_sensor *sensor = &is->sensor[index];
        u32 tmp = 0;
        int ret;
 
-       np = of_graph_get_next_endpoint(np, NULL);
-       if (!np)
+       sensor->drvdata = fimc_is_sensor_get_drvdata(node);
+       if (!sensor->drvdata) {
+               dev_err(&is->pdev->dev, "no driver data found for: %s\n",
+                                                        node->full_name);
+               return -EINVAL;
+       }
+
+       node = of_graph_get_next_endpoint(node, NULL);
+       if (!node)
                return -ENXIO;
-       np = of_graph_get_remote_port(np);
-       if (!np)
+
+       node = of_graph_get_remote_port(node);
+       if (!node)
                return -ENXIO;
 
        /* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */
-       ret = of_property_read_u32(np, "reg", &tmp);
-       sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;
+       ret = of_property_read_u32(node, "reg", &tmp);
+       if (ret < 0) {
+               dev_err(&is->pdev->dev, "reg property not found at: %s\n",
+                                                        node->full_name);
+               return ret;
+       }
 
-       return ret;
+       sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;
+       return 0;
 }
 
 static int fimc_is_register_subdevs(struct fimc_is *is)
 {
-       struct device_node *adapter, *child;
-       int ret;
+       struct device_node *i2c_bus, *child;
+       int ret, index = 0;
 
        ret = fimc_isp_subdev_create(&is->isp);
        if (ret < 0)
                return ret;
 
-       for_each_compatible_node(adapter, NULL, FIMC_IS_I2C_COMPATIBLE) {
-               if (!of_find_device_by_node(adapter)) {
-                       of_node_put(adapter);
-                       return -EPROBE_DEFER;
-               }
-
-               for_each_available_child_of_node(adapter, child) {
-                       struct i2c_client *client;
-                       struct v4l2_subdev *sd;
-
-                       client = of_find_i2c_device_by_node(child);
-                       if (!client)
-                               goto e_retry;
-
-                       sd = i2c_get_clientdata(client);
-                       if (!sd)
-                               goto e_retry;
+       /* Initialize memory allocator context for the ISP DMA. */
+       is->isp.alloc_ctx = is->alloc_ctx;
 
-                       /* FIXME: Add support for multiple sensors. */
-                       if (WARN_ON(is->sensor))
-                               continue;
+       for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {
+               for_each_available_child_of_node(i2c_bus, child) {
+                       ret = fimc_is_parse_sensor_config(is, index, child);
 
-                       is->sensor = sd_to_fimc_is_sensor(sd);
-
-                       if (fimc_is_parse_sensor_config(is->sensor, child)) {
-                               dev_warn(&is->pdev->dev, "DT parse error: %s\n",
-                                                        child->full_name);
+                       if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
+                               of_node_put(child);
+                               return ret;
                        }
-                       pr_debug("%s(): registered subdev: %p\n",
-                                __func__, sd->name);
+                       index++;
                }
        }
        return 0;
-
-e_retry:
-       of_node_put(child);
-       return -EPROBE_DEFER;
 }
 
 static int fimc_is_unregister_subdevs(struct fimc_is *is)
 {
        fimc_isp_subdev_destroy(&is->isp);
-       is->sensor = NULL;
        return 0;
 }
 
@@ -647,7 +638,7 @@ static int fimc_is_hw_open_sensor(struct fimc_is *is,
        fimc_is_hw_set_intgr0_gd0(is);
 
        return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1,
-                                 FIMC_IS_SENSOR_OPEN_TIMEOUT);
+                                 sensor->drvdata->open_timeout);
 }
 
 
@@ -661,8 +652,8 @@ int fimc_is_hw_initialize(struct fimc_is *is)
        u32 prev_id;
        int i, ret;
 
-       /* Sensor initialization. */
-       ret = fimc_is_hw_open_sensor(is, is->sensor);
+       /* Sensor initialization. Only one sensor is currently supported. */
+       ret = fimc_is_hw_open_sensor(is, &is->sensor[0]);
        if (ret < 0)
                return ret;
 
@@ -977,27 +968,20 @@ static int fimc_is_module_init(void)
 {
        int ret;
 
-       ret = fimc_is_register_sensor_driver();
-       if (ret < 0)
-               return ret;
-
        ret = fimc_is_register_i2c_driver();
        if (ret < 0)
-               goto err_sens;
+               return ret;
 
        ret = platform_driver_register(&fimc_is_driver);
-       if (!ret)
-               return ret;
 
-       fimc_is_unregister_i2c_driver();
-err_sens:
-       fimc_is_unregister_sensor_driver();
+       if (ret < 0)
+               fimc_is_unregister_i2c_driver();
+
        return ret;
 }
 
 static void fimc_is_module_exit(void)
 {
-       fimc_is_unregister_sensor_driver();
        fimc_is_unregister_i2c_driver();
        platform_driver_unregister(&fimc_is_driver);
 }
index 61bb0127e19d525835ce75d9f55ecb848762354b..e0be691af2d33967b7c9109fbf8cae74156c05c8 100644 (file)
@@ -39,7 +39,7 @@
 #define FIMC_IS_FW_LOAD_TIMEOUT                1000 /* ms */
 #define FIMC_IS_POWER_ON_TIMEOUT       1000 /* us */
 
-#define FIMC_IS_SENSOR_NUM             2
+#define FIMC_IS_SENSORS_NUM            2
 
 /* Memory definitions */
 #define FIMC_IS_CPU_MEM_SIZE           (0xa00000)
@@ -253,7 +253,7 @@ struct fimc_is {
        struct firmware                 *f_w;
 
        struct fimc_isp                 isp;
-       struct fimc_is_sensor           *sensor;
+       struct fimc_is_sensor           sensor[FIMC_IS_SENSORS_NUM];
        struct fimc_is_setfile          setfile;
 
        struct vb2_alloc_ctx            *alloc_ctx;
@@ -292,6 +292,11 @@ static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp)
        return container_of(isp, struct fimc_is, isp);
 }
 
+static inline struct chain_config *__get_curr_is_config(struct fimc_is *is)
+{
+       return &is->config[is->config_index];
+}
+
 static inline void fimc_is_mem_barrier(void)
 {
        mb();
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
new file mode 100644 (file)
index 0000000..e92b4e1
--- /dev/null
@@ -0,0 +1,660 @@
+/*
+ * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
+ *
+ * FIMC-IS ISP video input and video output DMA interface driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * The hardware handling code derived from a driver written by
+ * Younghwan Joo <yhwan.joo@samsung.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/printk.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/s5p_fimc.h>
+
+#include "common.h"
+#include "media-dev.h"
+#include "fimc-is.h"
+#include "fimc-isp-video.h"
+#include "fimc-is-param.h"
+
+static int isp_video_capture_queue_setup(struct vb2_queue *vq,
+                       const struct v4l2_format *pfmt,
+                       unsigned int *num_buffers, unsigned int *num_planes,
+                       unsigned int sizes[], void *allocators[])
+{
+       struct fimc_isp *isp = vb2_get_drv_priv(vq);
+       struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt;
+       const struct v4l2_pix_format_mplane *pixm = NULL;
+       const struct fimc_fmt *fmt;
+       unsigned int wh, i;
+
+       if (pfmt) {
+               pixm = &pfmt->fmt.pix_mp;
+               fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, -1);
+               wh = pixm->width * pixm->height;
+       } else {
+               fmt = isp->video_capture.format;
+               wh = vid_fmt->width * vid_fmt->height;
+       }
+
+       if (fmt == NULL)
+               return -EINVAL;
+
+       *num_buffers = clamp_t(u32, *num_buffers, FIMC_ISP_REQ_BUFS_MIN,
+                                               FIMC_ISP_REQ_BUFS_MAX);
+       *num_planes = fmt->memplanes;
+
+       for (i = 0; i < fmt->memplanes; i++) {
+               unsigned int size = (wh * fmt->depth[i]) / 8;
+               if (pixm)
+                       sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
+               else
+                       sizes[i] = size;
+               allocators[i] = isp->alloc_ctx;
+       }
+
+       return 0;
+}
+
+static inline struct param_dma_output *__get_isp_dma2(struct fimc_is *is)
+{
+       return &__get_curr_is_config(is)->isp.dma2_output;
+}
+
+static int isp_video_capture_start_streaming(struct vb2_queue *q,
+                                               unsigned int count)
+{
+       struct fimc_isp *isp = vb2_get_drv_priv(q);
+       struct fimc_is *is = fimc_isp_to_is(isp);
+       struct param_dma_output *dma = __get_isp_dma2(is);
+       struct fimc_is_video *video = &isp->video_capture;
+       int ret;
+
+       if (!test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state) ||
+           test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state))
+               return 0;
+
+
+       dma->cmd = DMA_OUTPUT_COMMAND_ENABLE;
+       dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_ENABLE;
+       dma->buffer_address = is->is_dma_p_region +
+                               DMA2_OUTPUT_ADDR_ARRAY_OFFS;
+       dma->buffer_number = video->reqbufs_count;
+       dma->dma_out_mask = video->buf_mask;
+
+       isp_dbg(2, &video->ve.vdev,
+               "buf_count: %d, planes: %d, dma addr table: %#x\n",
+               video->buf_count, video->format->memplanes,
+               dma->buffer_address);
+
+       fimc_is_mem_barrier();
+
+       fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
+       __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT);
+
+       ret = fimc_is_itf_s_param(is, false);
+       if (ret < 0)
+               return ret;
+
+       ret = fimc_pipeline_call(&video->ve, set_stream, 1);
+       if (ret < 0)
+               return ret;
+
+       set_bit(ST_ISP_VID_CAP_STREAMING, &isp->state);
+       return ret;
+}
+
+static int isp_video_capture_stop_streaming(struct vb2_queue *q)
+{
+       struct fimc_isp *isp = vb2_get_drv_priv(q);
+       struct fimc_is *is = fimc_isp_to_is(isp);
+       struct param_dma_output *dma = __get_isp_dma2(is);
+       int ret;
+
+       ret = fimc_pipeline_call(&isp->video_capture.ve, set_stream, 0);
+       if (ret < 0)
+               return ret;
+
+       dma->cmd = DMA_OUTPUT_COMMAND_DISABLE;
+       dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE;
+       dma->buffer_number = 0;
+       dma->buffer_address = 0;
+       dma->dma_out_mask = 0;
+
+       fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
+       __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT);
+
+       ret = fimc_is_itf_s_param(is, false);
+       if (ret < 0)
+               dev_warn(&is->pdev->dev, "%s: DMA stop failed\n", __func__);
+
+       fimc_is_hw_set_isp_buf_mask(is, 0);
+
+       clear_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state);
+       clear_bit(ST_ISP_VID_CAP_STREAMING, &isp->state);
+
+       isp->video_capture.buf_count = 0;
+       return 0;
+}
+
+static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb)
+{
+       struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
+       struct fimc_is_video *video = &isp->video_capture;
+       int i;
+
+       if (video->format == NULL)
+               return -EINVAL;
+
+       for (i = 0; i < video->format->memplanes; i++) {
+               unsigned long size = video->pixfmt.plane_fmt[i].sizeimage;
+
+               if (vb2_plane_size(vb, i) < size) {
+                       v4l2_err(&video->ve.vdev,
+                                "User buffer too small (%ld < %ld)\n",
+                                vb2_plane_size(vb, i), size);
+                       return -EINVAL;
+               }
+               vb2_set_plane_payload(vb, i, size);
+       }
+
+       /* Check if we get one of the already known buffers. */
+       if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) {
+               dma_addr_t dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+               int i;
+
+               for (i = 0; i < video->buf_count; i++)
+                       if (video->buffers[i]->dma_addr[0] == dma_addr)
+                               return 0;
+               return -ENXIO;
+       }
+
+       return 0;
+}
+
+static void isp_video_capture_buffer_queue(struct vb2_buffer *vb)
+{
+       struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
+       struct fimc_is_video *video = &isp->video_capture;
+       struct fimc_is *is = fimc_isp_to_is(isp);
+       struct isp_video_buf *ivb = to_isp_video_buf(vb);
+       unsigned long flags;
+       unsigned int i;
+
+       if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) {
+               spin_lock_irqsave(&is->slock, flags);
+               video->buf_mask |= BIT(ivb->index);
+               spin_unlock_irqrestore(&is->slock, flags);
+       } else {
+               unsigned int num_planes = video->format->memplanes;
+
+               ivb->index = video->buf_count;
+               video->buffers[ivb->index] = ivb;
+
+               for (i = 0; i < num_planes; i++) {
+                       int buf_index = ivb->index * num_planes + i;
+
+                       ivb->dma_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+                       is->is_p_region->shared[32 + buf_index] =
+                                                       ivb->dma_addr[i];
+
+                       isp_dbg(2, &video->ve.vdev,
+                               "dma_buf %d (%d/%d/%d) addr: %#x\n",
+                               buf_index, ivb->index, i, vb->v4l2_buf.index,
+                               ivb->dma_addr[i]);
+               }
+
+               if (++video->buf_count < video->reqbufs_count)
+                       return;
+
+               video->buf_mask = (1UL << video->buf_count) - 1;
+               set_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state);
+       }
+
+       if (!test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state))
+               isp_video_capture_start_streaming(vb->vb2_queue, 0);
+}
+
+/*
+ * FIMC-IS ISP input and output DMA interface interrupt handler.
+ * Locking: called with is->slock spinlock held.
+ */
+void fimc_isp_video_irq_handler(struct fimc_is *is)
+{
+       struct fimc_is_video *video = &is->isp.video_capture;
+       struct vb2_buffer *vb;
+       int buf_index;
+
+       /* TODO: Ensure the DMA is really stopped in stop_streaming callback */
+       if (!test_bit(ST_ISP_VID_CAP_STREAMING, &is->isp.state))
+               return;
+
+       buf_index = (is->i2h_cmd.args[1] - 1) % video->buf_count;
+       vb = &video->buffers[buf_index]->vb;
+
+       v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
+       vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+
+       video->buf_mask &= ~BIT(buf_index);
+       fimc_is_hw_set_isp_buf_mask(is, video->buf_mask);
+}
+
+static const struct vb2_ops isp_video_capture_qops = {
+       .queue_setup     = isp_video_capture_queue_setup,
+       .buf_prepare     = isp_video_capture_buffer_prepare,
+       .buf_queue       = isp_video_capture_buffer_queue,
+       .wait_prepare    = vb2_ops_wait_prepare,
+       .wait_finish     = vb2_ops_wait_finish,
+       .start_streaming = isp_video_capture_start_streaming,
+       .stop_streaming  = isp_video_capture_stop_streaming,
+};
+
+static int isp_video_open(struct file *file)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+       struct exynos_video_entity *ve = &isp->video_capture.ve;
+       struct media_entity *me = &ve->vdev.entity;
+       int ret;
+
+       if (mutex_lock_interruptible(&isp->video_lock))
+               return -ERESTARTSYS;
+
+       ret = v4l2_fh_open(file);
+       if (ret < 0)
+               goto unlock;
+
+       ret = pm_runtime_get_sync(&isp->pdev->dev);
+       if (ret < 0)
+               goto rel_fh;
+
+       if (v4l2_fh_is_singular_file(file)) {
+               mutex_lock(&me->parent->graph_mutex);
+
+               ret = fimc_pipeline_call(ve, open, me, true);
+
+               /* Mark the video pipeline as in use. */
+               if (ret == 0)
+                       me->use_count++;
+
+               mutex_unlock(&me->parent->graph_mutex);
+       }
+       if (!ret)
+               goto unlock;
+rel_fh:
+       v4l2_fh_release(file);
+unlock:
+       mutex_unlock(&isp->video_lock);
+       return ret;
+}
+
+static int isp_video_release(struct file *file)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+       struct fimc_is_video *ivc = &isp->video_capture;
+       struct media_entity *entity = &ivc->ve.vdev.entity;
+       struct media_device *mdev = entity->parent;
+       int ret = 0;
+
+       mutex_lock(&isp->video_lock);
+
+       if (v4l2_fh_is_singular_file(file) && ivc->streaming) {
+               media_entity_pipeline_stop(entity);
+               ivc->streaming = 0;
+       }
+
+       vb2_fop_release(file);
+
+       if (v4l2_fh_is_singular_file(file)) {
+               fimc_pipeline_call(&ivc->ve, close);
+
+               mutex_lock(&mdev->graph_mutex);
+               entity->use_count--;
+               mutex_unlock(&mdev->graph_mutex);
+       }
+
+       pm_runtime_put(&isp->pdev->dev);
+       mutex_unlock(&isp->video_lock);
+
+       return ret;
+}
+
+static const struct v4l2_file_operations isp_video_fops = {
+       .owner          = THIS_MODULE,
+       .open           = isp_video_open,
+       .release        = isp_video_release,
+       .poll           = vb2_fop_poll,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap           = vb2_fop_mmap,
+};
+
+/*
+ * Video node ioctl operations
+ */
+static int isp_video_querycap(struct file *file, void *priv,
+                                       struct v4l2_capability *cap)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+
+       __fimc_vidioc_querycap(&isp->pdev->dev, cap, V4L2_CAP_STREAMING);
+       return 0;
+}
+
+static int isp_video_enum_fmt_mplane(struct file *file, void *priv,
+                                       struct v4l2_fmtdesc *f)
+{
+       const struct fimc_fmt *fmt;
+
+       if (f->index >= FIMC_ISP_NUM_FORMATS)
+               return -EINVAL;
+
+       fmt = fimc_isp_find_format(NULL, NULL, f->index);
+       if (WARN_ON(fmt == NULL))
+               return -EINVAL;
+
+       strlcpy(f->description, fmt->name, sizeof(f->description));
+       f->pixelformat = fmt->fourcc;
+
+       return 0;
+}
+
+static int isp_video_g_fmt_mplane(struct file *file, void *fh,
+                                       struct v4l2_format *f)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+
+       f->fmt.pix_mp = isp->video_capture.pixfmt;
+       return 0;
+}
+
+static void __isp_video_try_fmt(struct fimc_isp *isp,
+                               struct v4l2_pix_format_mplane *pixm,
+                               const struct fimc_fmt **fmt)
+{
+       *fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, 2);
+
+       pixm->colorspace = V4L2_COLORSPACE_SRGB;
+       pixm->field = V4L2_FIELD_NONE;
+       pixm->num_planes = (*fmt)->memplanes;
+       pixm->pixelformat = (*fmt)->fourcc;
+       /*
+        * TODO: double check with the docmentation these width/height
+        * constraints are correct.
+        */
+       v4l_bound_align_image(&pixm->width, FIMC_ISP_SOURCE_WIDTH_MIN,
+                             FIMC_ISP_SOURCE_WIDTH_MAX, 3,
+                             &pixm->height, FIMC_ISP_SOURCE_HEIGHT_MIN,
+                             FIMC_ISP_SOURCE_HEIGHT_MAX, 0, 0);
+}
+
+static int isp_video_try_fmt_mplane(struct file *file, void *fh,
+                                       struct v4l2_format *f)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+
+       __isp_video_try_fmt(isp, &f->fmt.pix_mp, NULL);
+       return 0;
+}
+
+static int isp_video_s_fmt_mplane(struct file *file, void *priv,
+                                       struct v4l2_format *f)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+       struct fimc_is *is = fimc_isp_to_is(isp);
+       struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
+       const struct fimc_fmt *ifmt = NULL;
+       struct param_dma_output *dma = __get_isp_dma2(is);
+
+       __isp_video_try_fmt(isp, pixm, &ifmt);
+
+       if (WARN_ON(ifmt == NULL))
+               return -EINVAL;
+
+       dma->format = DMA_OUTPUT_FORMAT_BAYER;
+       dma->order = DMA_OUTPUT_ORDER_GB_BG;
+       dma->plane = ifmt->memplanes;
+       dma->bitwidth = ifmt->depth[0];
+       dma->width = pixm->width;
+       dma->height = pixm->height;
+
+       fimc_is_mem_barrier();
+
+       isp->video_capture.format = ifmt;
+       isp->video_capture.pixfmt = *pixm;
+
+       return 0;
+}
+
+/*
+ * Check for source/sink format differences at each link.
+ * Return 0 if the formats match or -EPIPE otherwise.
+ */
+static int isp_video_pipeline_validate(struct fimc_isp *isp)
+{
+       struct v4l2_subdev *sd = &isp->subdev;
+       struct v4l2_subdev_format sink_fmt, src_fmt;
+       struct media_pad *pad;
+       int ret;
+
+       while (1) {
+               /* Retrieve format at the sink pad */
+               pad = &sd->entity.pads[0];
+               if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                       break;
+               sink_fmt.pad = pad->index;
+               sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+               ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
+               if (ret < 0 && ret != -ENOIOCTLCMD)
+                       return -EPIPE;
+
+               /* Retrieve format at the source pad */
+               pad = media_entity_remote_pad(pad);
+               if (pad == NULL ||
+                   media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+                       break;
+
+               sd = media_entity_to_v4l2_subdev(pad->entity);
+               src_fmt.pad = pad->index;
+               src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+               ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
+               if (ret < 0 && ret != -ENOIOCTLCMD)
+                       return -EPIPE;
+
+               if (src_fmt.format.width != sink_fmt.format.width ||
+                   src_fmt.format.height != sink_fmt.format.height ||
+                   src_fmt.format.code != sink_fmt.format.code)
+                       return -EPIPE;
+       }
+
+       return 0;
+}
+
+static int isp_video_streamon(struct file *file, void *priv,
+                                     enum v4l2_buf_type type)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+       struct exynos_video_entity *ve = &isp->video_capture.ve;
+       struct media_entity *me = &ve->vdev.entity;
+       int ret;
+
+       ret = media_entity_pipeline_start(me, &ve->pipe->mp);
+       if (ret < 0)
+               return ret;
+
+       ret = isp_video_pipeline_validate(isp);
+       if (ret < 0)
+               goto p_stop;
+
+       ret = vb2_ioctl_streamon(file, priv, type);
+       if (ret < 0)
+               goto p_stop;
+
+       isp->video_capture.streaming = 1;
+       return 0;
+p_stop:
+       media_entity_pipeline_stop(me);
+       return ret;
+}
+
+static int isp_video_streamoff(struct file *file, void *priv,
+                                       enum v4l2_buf_type type)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+       struct fimc_is_video *video = &isp->video_capture;
+       int ret;
+
+       ret = vb2_ioctl_streamoff(file, priv, type);
+       if (ret < 0)
+               return ret;
+
+       media_entity_pipeline_stop(&video->ve.vdev.entity);
+       video->streaming = 0;
+       return 0;
+}
+
+static int isp_video_reqbufs(struct file *file, void *priv,
+                               struct v4l2_requestbuffers *rb)
+{
+       struct fimc_isp *isp = video_drvdata(file);
+       int ret;
+
+       ret = vb2_ioctl_reqbufs(file, priv, rb);
+       if (ret < 0)
+               return ret;
+
+       if (rb->count && rb->count < FIMC_ISP_REQ_BUFS_MIN) {
+               rb->count = 0;
+               vb2_ioctl_reqbufs(file, priv, rb);
+               ret = -ENOMEM;
+       }
+
+       isp->video_capture.reqbufs_count = rb->count;
+       return ret;
+}
+
+static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
+       .vidioc_querycap                = isp_video_querycap,
+       .vidioc_enum_fmt_vid_cap_mplane = isp_video_enum_fmt_mplane,
+       .vidioc_try_fmt_vid_cap_mplane  = isp_video_try_fmt_mplane,
+       .vidioc_s_fmt_vid_cap_mplane    = isp_video_s_fmt_mplane,
+       .vidioc_g_fmt_vid_cap_mplane    = isp_video_g_fmt_mplane,
+       .vidioc_reqbufs                 = isp_video_reqbufs,
+       .vidioc_querybuf                = vb2_ioctl_querybuf,
+       .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
+       .vidioc_create_bufs             = vb2_ioctl_create_bufs,
+       .vidioc_qbuf                    = vb2_ioctl_qbuf,
+       .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
+       .vidioc_streamon                = isp_video_streamon,
+       .vidioc_streamoff               = isp_video_streamoff,
+};
+
+int fimc_isp_video_device_register(struct fimc_isp *isp,
+                                  struct v4l2_device *v4l2_dev,
+                                  enum v4l2_buf_type type)
+{
+       struct vb2_queue *q = &isp->video_capture.vb_queue;
+       struct fimc_is_video *iv;
+       struct video_device *vdev;
+       int ret;
+
+       if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               iv = &isp->video_capture;
+       else
+               return -ENOSYS;
+
+       mutex_init(&isp->video_lock);
+       INIT_LIST_HEAD(&iv->pending_buf_q);
+       INIT_LIST_HEAD(&iv->active_buf_q);
+       iv->format = fimc_isp_find_format(NULL, NULL, 0);
+       iv->pixfmt.width = IS_DEFAULT_WIDTH;
+       iv->pixfmt.height = IS_DEFAULT_HEIGHT;
+       iv->pixfmt.pixelformat = iv->format->fourcc;
+       iv->pixfmt.colorspace = V4L2_COLORSPACE_SRGB;
+       iv->reqbufs_count = 0;
+
+       memset(q, 0, sizeof(*q));
+       q->type = type;
+       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->ops = &isp_video_capture_qops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->buf_struct_size = sizeof(struct isp_video_buf);
+       q->drv_priv = isp;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->lock = &isp->video_lock;
+
+       ret = vb2_queue_init(q);
+       if (ret < 0)
+               return ret;
+
+       vdev = &iv->ve.vdev;
+       memset(vdev, 0, sizeof(*vdev));
+       snprintf(vdev->name, sizeof(vdev->name), "fimc-is-isp.%s",
+                       type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
+                       "capture" : "output");
+       vdev->queue = q;
+       vdev->fops = &isp_video_fops;
+       vdev->ioctl_ops = &isp_video_ioctl_ops;
+       vdev->v4l2_dev = v4l2_dev;
+       vdev->minor = -1;
+       vdev->release = video_device_release_empty;
+       vdev->lock = &isp->video_lock;
+
+       iv->pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0);
+       if (ret < 0)
+               return ret;
+
+       video_set_drvdata(vdev, isp);
+
+       ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+       if (ret < 0) {
+               media_entity_cleanup(&vdev->entity);
+               return ret;
+       }
+
+       v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
+                 vdev->name, video_device_node_name(vdev));
+
+       return 0;
+}
+
+void fimc_isp_video_device_unregister(struct fimc_isp *isp,
+                                     enum v4l2_buf_type type)
+{
+       struct exynos_video_entity *ve;
+
+       if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               ve = &isp->video_capture.ve;
+       else
+               return;
+
+       mutex_lock(&isp->video_lock);
+
+       if (video_is_registered(&ve->vdev)) {
+               video_unregister_device(&ve->vdev);
+               media_entity_cleanup(&ve->vdev.entity);
+               ve->pipe = NULL;
+       }
+
+       mutex_unlock(&isp->video_lock);
+}
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.h b/drivers/media/platform/exynos4-is/fimc-isp-video.h
new file mode 100644 (file)
index 0000000..98c6626
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef FIMC_ISP_VIDEO__
+#define FIMC_ISP_VIDEO__
+
+#include <media/videobuf2-core.h>
+#include "fimc-isp.h"
+
+#ifdef CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE
+int fimc_isp_video_device_register(struct fimc_isp *isp,
+                               struct v4l2_device *v4l2_dev,
+                               enum v4l2_buf_type type);
+
+void fimc_isp_video_device_unregister(struct fimc_isp *isp,
+                               enum v4l2_buf_type type);
+
+void fimc_isp_video_irq_handler(struct fimc_is *is);
+#else
+static inline void fimc_isp_video_irq_handler(struct fimc_is *is)
+{
+}
+
+static inline int fimc_isp_video_device_register(struct fimc_isp *isp,
+                                               struct v4l2_device *v4l2_dev,
+                                               enum v4l2_buf_type type)
+{
+       return 0;
+}
+
+void fimc_isp_video_device_unregister(struct fimc_isp *isp,
+                               enum v4l2_buf_type type)
+{
+}
+#endif /* !CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE */
+
+#endif /* FIMC_ISP_VIDEO__ */
index f3c6136aa5b4767af56e4de4078af6cddfa48735..be62d6b9ac481c666bf2b3cf0894532cc9edb291 100644 (file)
@@ -25,6 +25,7 @@
 #include <media/v4l2-device.h>
 
 #include "media-dev.h"
+#include "fimc-isp-video.h"
 #include "fimc-is-command.h"
 #include "fimc-is-param.h"
 #include "fimc-is-regs.h"
@@ -93,8 +94,8 @@ void fimc_isp_irq_handler(struct fimc_is *is)
        is->i2h_cmd.args[1] = mcuctl_read(is, MCUCTL_REG_ISSR(21));
 
        fimc_is_fw_clear_irq1(is, FIMC_IS_INT_FRAME_DONE_ISP);
+       fimc_isp_video_irq_handler(is);
 
-       /* TODO: Complete ISP DMA interrupt handler */
        wake_up(&is->irq_queue);
 }
 
@@ -388,7 +389,33 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int fimc_isp_subdev_registered(struct v4l2_subdev *sd)
+{
+       struct fimc_isp *isp = v4l2_get_subdevdata(sd);
+       int ret;
+
+       /* Use pipeline object allocated by the media device. */
+       isp->video_capture.ve.pipe = v4l2_get_subdev_hostdata(sd);
+
+       ret = fimc_isp_video_device_register(isp, sd->v4l2_dev,
+                       V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+       if (ret < 0)
+               isp->video_capture.ve.pipe = NULL;
+
+       return ret;
+}
+
+static void fimc_isp_subdev_unregistered(struct v4l2_subdev *sd)
+{
+       struct fimc_isp *isp = v4l2_get_subdevdata(sd);
+
+       fimc_isp_video_device_unregister(isp,
+                       V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+}
+
 static const struct v4l2_subdev_internal_ops fimc_is_subdev_internal_ops = {
+       .registered = fimc_isp_subdev_registered,
+       .unregistered = fimc_isp_subdev_unregistered,
        .open = fimc_isp_subdev_open,
 };
 
index 03bf95ab017bce6be66f07a98141e562f1b64abb..4dc55a18d9786d1d479cb5e7cfb9b96433e1c556 100644 (file)
@@ -35,17 +35,18 @@ extern int fimc_isp_debug;
 #define FIMC_ISP_SINK_WIDTH_MIN                (16 + 8)
 #define FIMC_ISP_SINK_HEIGHT_MIN       (12 + 8)
 #define FIMC_ISP_SOURCE_WIDTH_MIN      8
-#define FIMC_ISP_SOURC_HEIGHT_MIN      8
+#define FIMC_ISP_SOURCE_HEIGHT_MIN     8
 #define FIMC_ISP_CAC_MARGIN_WIDTH      16
 #define FIMC_ISP_CAC_MARGIN_HEIGHT     12
 
 #define FIMC_ISP_SINK_WIDTH_MAX                (4000 - 16)
 #define FIMC_ISP_SINK_HEIGHT_MAX       (4000 + 12)
 #define FIMC_ISP_SOURCE_WIDTH_MAX      4000
-#define FIMC_ISP_SOURC_HEIGHT_MAX      4000
+#define FIMC_ISP_SOURCE_HEIGHT_MAX     4000
 
 #define FIMC_ISP_NUM_FORMATS           3
 #define FIMC_ISP_REQ_BUFS_MIN          2
+#define FIMC_ISP_REQ_BUFS_MAX          32
 
 #define FIMC_ISP_SD_PAD_SINK           0
 #define FIMC_ISP_SD_PAD_SRC_FIFO       1
@@ -100,6 +101,16 @@ struct fimc_isp_ctrls {
        struct v4l2_ctrl *colorfx;
 };
 
+struct isp_video_buf {
+       struct vb2_buffer vb;
+       dma_addr_t dma_addr[FIMC_ISP_MAX_PLANES];
+       unsigned int index;
+};
+
+#define to_isp_video_buf(_b) container_of(_b, struct isp_video_buf, vb)
+
+#define FIMC_ISP_MAX_BUFS      4
+
 /**
  * struct fimc_is_video - fimc-is video device structure
  * @vdev: video_device structure
@@ -114,18 +125,26 @@ struct fimc_isp_ctrls {
  * @format: current pixel format
  */
 struct fimc_is_video {
-       struct video_device     vdev;
+       struct exynos_video_entity ve;
        enum v4l2_buf_type      type;
        struct media_pad        pad;
        struct list_head        pending_buf_q;
        struct list_head        active_buf_q;
        struct vb2_queue        vb_queue;
-       unsigned int            frame_count;
        unsigned int            reqbufs_count;
+       unsigned int            buf_count;
+       unsigned int            buf_mask;
+       unsigned int            frame_count;
        int                     streaming;
+       struct isp_video_buf    *buffers[FIMC_ISP_MAX_BUFS];
        const struct fimc_fmt   *format;
+       struct v4l2_pix_format_mplane pixfmt;
 };
 
+/* struct fimc_isp:state bit definitions */
+#define ST_ISP_VID_CAP_BUF_PREP                0
+#define ST_ISP_VID_CAP_STREAMING       1
+
 /**
  * struct fimc_isp - FIMC-IS ISP data structure
  * @pdev: pointer to FIMC-IS platform device
index 779ec3cd259dad43bee5ec151bfcc51a6fde0c15..3ad660b55b6bdc948ecd97623eccce05f79efcbb 100644 (file)
@@ -1313,7 +1313,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct flite_buffer);
        q->drv_priv = fimc;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        q->lock = &fimc->lock;
 
        ret = vb2_queue_init(q);
index 9da95bd148200d5a4406aa6f80a09bf1364d7c65..36971d915b530ac3ee284ec80d892459ef7e7333 100644 (file)
@@ -134,6 +134,9 @@ static void fimc_device_run(void *priv)
                goto dma_unlock;
 
        dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
+       dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       dst_vb->v4l2_buf.flags |=
+               src_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 
        /* Reconfigure hardware if the context has changed. */
        if (fimc->m2m.ctx != ctx) {
@@ -557,7 +560,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->ops = &fimc_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        src_vq->lock = &ctx->fimc_dev->lock;
 
        ret = vb2_queue_init(src_vq);
@@ -570,7 +573,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->ops = &fimc_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        dst_vq->lock = &ctx->fimc_dev->lock;
 
        return vb2_queue_init(dst_vq);
index 04d6ecdd314cb10014c696ec296e329b291e0ea3..e62211a80f0e8bc20d8a01cac85a130c555b8f04 100644 (file)
@@ -11,6 +11,8 @@
  */
 
 #include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
@@ -25,6 +27,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <media/v4l2-async.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-of.h>
 #include <media/media-device.h>
@@ -219,6 +222,7 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
                if (ret < 0)
                        return ret;
        }
+
        ret = fimc_md_set_camclk(sd, true);
        if (ret < 0)
                goto err_wbclk;
@@ -379,77 +383,18 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct i2c_adapter *adapter;
 
-       if (!client)
+       if (!client || client->dev.of_node)
                return;
 
        v4l2_device_unregister_subdev(sd);
 
-       if (!client->dev.of_node) {
-               adapter = client->adapter;
-               i2c_unregister_device(client);
-               if (adapter)
-                       i2c_put_adapter(adapter);
-       }
+       adapter = client->adapter;
+       i2c_unregister_device(client);
+       if (adapter)
+               i2c_put_adapter(adapter);
 }
 
 #ifdef CONFIG_OF
-/* Register I2C client subdev associated with @node. */
-static int fimc_md_of_add_sensor(struct fimc_md *fmd,
-                                struct device_node *node, int index)
-{
-       struct fimc_sensor_info *si;
-       struct i2c_client *client;
-       struct v4l2_subdev *sd;
-       int ret;
-
-       if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor)))
-               return -EINVAL;
-       si = &fmd->sensor[index];
-
-       client = of_find_i2c_device_by_node(node);
-       if (!client)
-               return -EPROBE_DEFER;
-
-       device_lock(&client->dev);
-
-       if (!client->dev.driver ||
-           !try_module_get(client->dev.driver->owner)) {
-               ret = -EPROBE_DEFER;
-               v4l2_info(&fmd->v4l2_dev, "No driver found for %s\n",
-                                               node->full_name);
-               goto dev_put;
-       }
-
-       /* Enable sensor's master clock */
-       ret = __fimc_md_set_camclk(fmd, &si->pdata, true);
-       if (ret < 0)
-               goto mod_put;
-       sd = i2c_get_clientdata(client);
-
-       ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
-       __fimc_md_set_camclk(fmd, &si->pdata, false);
-       if (ret < 0)
-               goto mod_put;
-
-       v4l2_set_subdev_hostdata(sd, &si->pdata);
-       if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
-               sd->grp_id = GRP_ID_FIMC_IS_SENSOR;
-       else
-               sd->grp_id = GRP_ID_SENSOR;
-
-       si->subdev = sd;
-       v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
-                 sd->name, fmd->num_sensors);
-       fmd->num_sensors++;
-
-mod_put:
-       module_put(client->dev.driver->owner);
-dev_put:
-       device_unlock(&client->dev);
-       put_device(&client->dev);
-       return ret;
-}
-
 /* Parse port node and register as a sub-device any sensor specified there. */
 static int fimc_md_parse_port_node(struct fimc_md *fmd,
                                   struct device_node *port,
@@ -458,7 +403,6 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
        struct device_node *rem, *ep, *np;
        struct fimc_source_info *pd;
        struct v4l2_of_endpoint endpoint;
-       int ret;
        u32 val;
 
        pd = &fmd->sensor[index].pdata;
@@ -486,6 +430,8 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 
        if (!of_property_read_u32(rem, "clock-frequency", &val))
                pd->clk_frequency = val;
+       else
+               pd->clk_frequency = DEFAULT_SENSOR_CLK_FREQ;
 
        if (pd->clk_frequency == 0) {
                v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n",
@@ -525,10 +471,17 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
        else
                pd->fimc_bus_type = pd->sensor_bus_type;
 
-       ret = fimc_md_of_add_sensor(fmd, rem, index);
-       of_node_put(rem);
+       if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor)))
+               return -EINVAL;
 
-       return ret;
+       fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_OF;
+       fmd->sensor[index].asd.match.of.node = rem;
+       fmd->async_subdevs[index] = &fmd->sensor[index].asd;
+
+       fmd->num_sensors++;
+
+       of_node_put(rem);
+       return 0;
 }
 
 /* Register all SoC external sub-devices */
@@ -732,8 +685,16 @@ static int register_csis_entity(struct fimc_md *fmd,
 static int register_fimc_is_entity(struct fimc_md *fmd, struct fimc_is *is)
 {
        struct v4l2_subdev *sd = &is->isp.subdev;
+       struct exynos_media_pipeline *ep;
        int ret;
 
+       /* Allocate pipeline object for the ISP capture video node. */
+       ep = fimc_md_pipeline_create(fmd);
+       if (!ep)
+               return -ENOMEM;
+
+       v4l2_set_subdev_hostdata(sd, ep);
+
        ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
        if (ret) {
                v4l2_err(&fmd->v4l2_dev,
@@ -884,11 +845,13 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
                v4l2_device_unregister_subdev(fmd->csis[i].sd);
                fmd->csis[i].sd = NULL;
        }
-       for (i = 0; i < fmd->num_sensors; i++) {
-               if (fmd->sensor[i].subdev == NULL)
-                       continue;
-               fimc_md_unregister_sensor(fmd->sensor[i].subdev);
-               fmd->sensor[i].subdev = NULL;
+       if (fmd->pdev->dev.of_node == NULL) {
+               for (i = 0; i < fmd->num_sensors; i++) {
+                       if (fmd->sensor[i].subdev == NULL)
+                               continue;
+                       fimc_md_unregister_sensor(fmd->sensor[i].subdev);
+                       fmd->sensor[i].subdev = NULL;
+               }
        }
 
        if (fmd->fimc_is)
@@ -1005,16 +968,17 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 /* Create FIMC-IS links */
 static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 {
+       struct fimc_isp *isp = &fmd->fimc_is->isp;
        struct media_entity *source, *sink;
        int i, ret;
 
-       source = &fmd->fimc_is->isp.subdev.entity;
+       source = &isp->subdev.entity;
 
        for (i = 0; i < FIMC_MAX_DEVS; i++) {
                if (fmd->fimc[i] == NULL)
                        continue;
 
-               /* Link from IS-ISP subdev to FIMC */
+               /* Link from FIMC-IS-ISP subdev to FIMC */
                sink = &fmd->fimc[i]->vid_cap.subdev.entity;
                ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
                                               sink, FIMC_SD_PAD_SINK_FIFO, 0);
@@ -1022,7 +986,15 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
                        return ret;
        }
 
-       return ret;
+       /* Link from FIMC-IS-ISP subdev to fimc-is-isp.capture video node */
+       sink = &isp->video_capture.ve.vdev.entity;
+
+       /* Skip this link if the fimc-is-isp video node driver isn't built-in */
+       if (sink->num_pads == 0)
+               return 0;
+
+       return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+                                       sink, 0, 0);
 }
 
 /**
@@ -1223,6 +1195,14 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
        struct fimc_camclk_info *camclk;
        int ret = 0;
 
+       /*
+        * When device tree is used the sensor drivers are supposed to
+        * control the clock themselves. This whole function will be
+        * removed once S5PV210 platform is converted to the device tree.
+        */
+       if (fmd->pdev->dev.of_node)
+               return 0;
+
        if (WARN_ON(si->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf)
                return -EINVAL;
 
@@ -1277,6 +1257,14 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
        struct fimc_source_info *si = v4l2_get_subdev_hostdata(sd);
        struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
 
+       /*
+        * If there is a clock provider registered the sensors will
+        * handle their clock themselves, no need to control it on
+        * the host interface side.
+        */
+       if (fmd->clk_provider.num_clocks > 0)
+               return 0;
+
        return __fimc_md_set_camclk(fmd, si, on);
 }
 
@@ -1438,6 +1426,153 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static int cam_clk_prepare(struct clk_hw *hw)
+{
+       struct cam_clk *camclk = to_cam_clk(hw);
+       int ret;
+
+       if (camclk->fmd->pmf == NULL)
+               return -ENODEV;
+
+       ret = pm_runtime_get_sync(camclk->fmd->pmf);
+       return ret < 0 ? ret : 0;
+}
+
+static void cam_clk_unprepare(struct clk_hw *hw)
+{
+       struct cam_clk *camclk = to_cam_clk(hw);
+
+       if (camclk->fmd->pmf == NULL)
+               return;
+
+       pm_runtime_put_sync(camclk->fmd->pmf);
+}
+
+static const struct clk_ops cam_clk_ops = {
+       .prepare = cam_clk_prepare,
+       .unprepare = cam_clk_unprepare,
+};
+
+static void fimc_md_unregister_clk_provider(struct fimc_md *fmd)
+{
+       struct cam_clk_provider *cp = &fmd->clk_provider;
+       unsigned int i;
+
+       if (cp->of_node)
+               of_clk_del_provider(cp->of_node);
+
+       for (i = 0; i < cp->num_clocks; i++)
+               clk_unregister(cp->clks[i]);
+}
+
+static int fimc_md_register_clk_provider(struct fimc_md *fmd)
+{
+       struct cam_clk_provider *cp = &fmd->clk_provider;
+       struct device *dev = &fmd->pdev->dev;
+       int i, ret;
+
+       for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
+               struct cam_clk *camclk = &cp->camclk[i];
+               struct clk_init_data init;
+               const char *p_name;
+
+               ret = of_property_read_string_index(dev->of_node,
+                                       "clock-output-names", i, &init.name);
+               if (ret < 0)
+                       break;
+
+               p_name = __clk_get_name(fmd->camclk[i].clock);
+
+               /* It's safe since clk_register() will duplicate the string. */
+               init.parent_names = &p_name;
+               init.num_parents = 1;
+               init.ops = &cam_clk_ops;
+               init.flags = CLK_SET_RATE_PARENT;
+               camclk->hw.init = &init;
+               camclk->fmd = fmd;
+
+               cp->clks[i] = clk_register(NULL, &camclk->hw);
+               if (IS_ERR(cp->clks[i])) {
+                       dev_err(dev, "failed to register clock: %s (%ld)\n",
+                                       init.name, PTR_ERR(cp->clks[i]));
+                       ret = PTR_ERR(cp->clks[i]);
+                       goto err;
+               }
+               cp->num_clocks++;
+       }
+
+       if (cp->num_clocks == 0) {
+               dev_warn(dev, "clk provider not registered\n");
+               return 0;
+       }
+
+       cp->clk_data.clks = cp->clks;
+       cp->clk_data.clk_num = cp->num_clocks;
+       cp->of_node = dev->of_node;
+       ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
+                                 &cp->clk_data);
+       if (ret == 0)
+               return 0;
+err:
+       fimc_md_unregister_clk_provider(fmd);
+       return ret;
+}
+#else
+#define fimc_md_register_clk_provider(fmd) (0)
+#define fimc_md_unregister_clk_provider(fmd) (0)
+#endif
+
+static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+                                struct v4l2_subdev *subdev,
+                                struct v4l2_async_subdev *asd)
+{
+       struct fimc_md *fmd = notifier_to_fimc_md(notifier);
+       struct fimc_sensor_info *si = NULL;
+       int i;
+
+       /* Find platform data for this sensor subdev */
+       for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
+               if (fmd->sensor[i].asd.match.of.node == subdev->dev->of_node)
+                       si = &fmd->sensor[i];
+
+       if (si == NULL)
+               return -EINVAL;
+
+       v4l2_set_subdev_hostdata(subdev, &si->pdata);
+
+       if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
+               subdev->grp_id = GRP_ID_FIMC_IS_SENSOR;
+       else
+               subdev->grp_id = GRP_ID_SENSOR;
+
+       si->subdev = subdev;
+
+       v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
+                 subdev->name, fmd->num_sensors);
+
+       fmd->num_sensors++;
+
+       return 0;
+}
+
+static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+       struct fimc_md *fmd = notifier_to_fimc_md(notifier);
+       int ret;
+
+       mutex_lock(&fmd->media_dev.graph_mutex);
+
+       ret = fimc_md_create_links(fmd);
+       if (ret < 0)
+               goto unlock;
+
+       ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
+unlock:
+       mutex_unlock(&fmd->media_dev.graph_mutex);
+       return ret;
+}
+
 static int fimc_md_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -1470,63 +1605,91 @@ static int fimc_md_probe(struct platform_device *pdev)
                v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
                return ret;
        }
+
        ret = media_device_register(&fmd->media_dev);
        if (ret < 0) {
                v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
-               goto err_md;
+               goto err_v4l2_dev;
        }
+
        ret = fimc_md_get_clocks(fmd);
        if (ret)
-               goto err_clk;
+               goto err_md;
 
        fmd->user_subdev_api = (dev->of_node != NULL);
 
-       /* Protect the media graph while we're registering entities */
-       mutex_lock(&fmd->media_dev.graph_mutex);
-
        ret = fimc_md_get_pinctrl(fmd);
        if (ret < 0) {
                if (ret != EPROBE_DEFER)
                        dev_err(dev, "Failed to get pinctrl: %d\n", ret);
-               goto err_unlock;
+               goto err_clk;
        }
 
+       platform_set_drvdata(pdev, fmd);
+
+       /* Protect the media graph while we're registering entities */
+       mutex_lock(&fmd->media_dev.graph_mutex);
+
        if (dev->of_node)
                ret = fimc_md_register_of_platform_entities(fmd, dev->of_node);
        else
                ret = bus_for_each_dev(&platform_bus_type, NULL, fmd,
                                                fimc_md_pdev_match);
-       if (ret)
-               goto err_unlock;
+       if (ret) {
+               mutex_unlock(&fmd->media_dev.graph_mutex);
+               goto err_clk;
+       }
 
        if (dev->platform_data || dev->of_node) {
                ret = fimc_md_register_sensor_entities(fmd);
-               if (ret)
-                       goto err_unlock;
+               if (ret) {
+                       mutex_unlock(&fmd->media_dev.graph_mutex);
+                       goto err_m_ent;
+               }
        }
 
-       ret = fimc_md_create_links(fmd);
-       if (ret)
-               goto err_unlock;
-       ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
-       if (ret)
-               goto err_unlock;
+       mutex_unlock(&fmd->media_dev.graph_mutex);
 
        ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
        if (ret)
-               goto err_unlock;
+               goto err_m_ent;
+       /*
+        * FIMC platform devices need to be registered before the sclk_cam
+        * clocks provider, as one of these devices needs to be activated
+        * to enable the clock.
+        */
+       ret = fimc_md_register_clk_provider(fmd);
+       if (ret < 0) {
+               v4l2_err(v4l2_dev, "clock provider registration failed\n");
+               goto err_attr;
+       }
+
+       if (fmd->num_sensors > 0) {
+               fmd->subdev_notifier.subdevs = fmd->async_subdevs;
+               fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
+               fmd->subdev_notifier.bound = subdev_notifier_bound;
+               fmd->subdev_notifier.complete = subdev_notifier_complete;
+               fmd->num_sensors = 0;
+
+               ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
+                                               &fmd->subdev_notifier);
+               if (ret)
+                       goto err_clk_p;
+       }
 
-       platform_set_drvdata(pdev, fmd);
-       mutex_unlock(&fmd->media_dev.graph_mutex);
        return 0;
 
-err_unlock:
-       mutex_unlock(&fmd->media_dev.graph_mutex);
+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_m_ent:
        fimc_md_unregister_entities(fmd);
-       media_device_unregister(&fmd->media_dev);
 err_md:
+       media_device_unregister(&fmd->media_dev);
+err_v4l2_dev:
        v4l2_device_unregister(&fmd->v4l2_dev);
        return ret;
 }
@@ -1538,12 +1701,16 @@ static int fimc_md_remove(struct platform_device *pdev)
        if (!fmd)
                return 0;
 
+       fimc_md_unregister_clk_provider(fmd);
+       v4l2_async_notifier_unregister(&fmd->subdev_notifier);
+
        v4l2_device_unregister(&fmd->v4l2_dev);
        device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
        fimc_md_unregister_entities(fmd);
        fimc_md_pipelines_free(fmd);
        media_device_unregister(&fmd->media_dev);
        fimc_md_put_clocks(fmd);
+
        return 0;
 }
 
index 62599fd7756f5ce05c4a4ba23d9beb3f70abea2b..ee1e2519f7283c9882854366d29a411b64d26fb7 100644 (file)
@@ -10,6 +10,7 @@
 #define FIMC_MDEVICE_H_
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
@@ -31,8 +32,9 @@
 
 #define PINCTRL_STATE_IDLE     "idle"
 
-#define FIMC_MAX_SENSORS       8
+#define FIMC_MAX_SENSORS       4
 #define FIMC_MAX_CAMCLKS       2
+#define DEFAULT_SENSOR_CLK_FREQ        24000000U
 
 /* LCD/ISP Writeback clocks (PIXELASYNCMx) */
 enum {
@@ -78,6 +80,7 @@ struct fimc_camclk_info {
 /**
  * struct fimc_sensor_info - image data source subdev information
  * @pdata: sensor's atrributes passed as media device's platform data
+ * @asd: asynchronous subdev registration data structure
  * @subdev: image sensor v4l2 subdev
  * @host: fimc device the sensor is currently linked to
  *
@@ -85,10 +88,17 @@ struct fimc_camclk_info {
  */
 struct fimc_sensor_info {
        struct fimc_source_info pdata;
+       struct v4l2_async_subdev asd;
        struct v4l2_subdev *subdev;
        struct fimc_dev *host;
 };
 
+struct cam_clk {
+       struct clk_hw hw;
+       struct fimc_md *fmd;
+};
+#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)
+
 /**
  * struct fimc_md - fimc media device information
  * @csis: MIPI CSIS subdevs data
@@ -105,6 +115,7 @@ struct fimc_sensor_info {
  * @pinctrl: camera port pinctrl handle
  * @state_default: pinctrl default state handle
  * @state_idle: pinctrl idle state handle
+ * @cam_clk_provider: CAMCLK clock provider structure
  * @user_subdev_api: true if subdevs are not configured by the host driver
  * @slock: spinlock protecting @sensor array
  */
@@ -122,13 +133,25 @@ struct fimc_md {
        struct media_device media_dev;
        struct v4l2_device v4l2_dev;
        struct platform_device *pdev;
+
        struct fimc_pinctrl {
                struct pinctrl *pinctrl;
                struct pinctrl_state *state_default;
                struct pinctrl_state *state_idle;
        } pinctl;
-       bool user_subdev_api;
 
+       struct cam_clk_provider {
+               struct clk *clks[FIMC_MAX_CAMCLKS];
+               struct clk_onecell_data clk_data;
+               struct device_node *of_node;
+               struct cam_clk camclk[FIMC_MAX_CAMCLKS];
+               int num_clocks;
+       } clk_provider;
+
+       struct v4l2_async_notifier subdev_notifier;
+       struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS];
+
+       bool user_subdev_api;
        spinlock_t slock;
        struct list_head pipelines;
 };
@@ -145,6 +168,11 @@ static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
                container_of(me->parent, struct fimc_md, media_dev);
 }
 
+static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
+{
+       return container_of(n, struct fimc_md, subdev_notifier);
+}
+
 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
        mutex_lock(&ve->vdev.entity.parent->graph_mutex);
index 6bb86b581a34e43f0fe34cc44f5a2132b1589e7b..c21d14fd61db1a00aece5c6b38250d7c9336159c 100644 (file)
@@ -207,8 +207,11 @@ static void dma_callback(void *data)
        src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
        dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
 
-       src_vb->v4l2_buf.timestamp = dst_vb->v4l2_buf.timestamp;
-       src_vb->v4l2_buf.timecode = dst_vb->v4l2_buf.timecode;
+       dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
+       dst_vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       dst_vb->v4l2_buf.flags |=
+               src_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
 
        v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
        v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
@@ -868,7 +871,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &deinterlace_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        q_data[V4L2_M2M_SRC].fmt = &formats[0];
        q_data[V4L2_M2M_SRC].width = 640;
        q_data[V4L2_M2M_SRC].height = 480;
@@ -885,7 +888,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &deinterlace_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        q_data[V4L2_M2M_DST].fmt = &formats[0];
        q_data[V4L2_M2M_DST].width = 640;
        q_data[V4L2_M2M_DST].height = 480;
index 32fab30a910590ba290ef987aaad8ed1df78e74f..8b34c485be799b8f0b2dc4c2e2fadc7de342874a 100644 (file)
@@ -1238,7 +1238,7 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
        return 0;
 }
 
-static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
+static void mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
 {
        struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
        struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
@@ -1246,7 +1246,6 @@ static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
        if (sg_table)
                dma_unmap_sg(cam->dev, sg_table->sgl,
                                sg_table->nents, DMA_FROM_DEVICE);
-       return 0;
 }
 
 static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb)
index 08e24379b7949af3a71f67123dd8749ce831c7aa..4f3096b170665e15329c25035248b207d3b7d276 100644 (file)
@@ -60,9 +60,7 @@ MODULE_PARM_DESC(debug, "activates debug info");
 #define MEM2MEM_VID_MEM_LIMIT  (16 * 1024 * 1024)
 
 /* Default transaction time in msec */
-#define MEM2MEM_DEF_TRANSTIME  1000
-/* Default number of buffers per transaction */
-#define MEM2MEM_DEF_TRANSLEN   1
+#define MEM2MEM_DEF_TRANSTIME  40
 #define MEM2MEM_COLOR_STEP     (0xff >> 4)
 #define MEM2MEM_NUM_TILES      8
 
@@ -114,6 +112,7 @@ struct m2mtest_q_data {
        unsigned int            width;
        unsigned int            height;
        unsigned int            sizeimage;
+       unsigned int            sequence;
        struct m2mtest_fmt      *fmt;
 };
 
@@ -236,9 +235,21 @@ static int device_process(struct m2mtest_ctx *ctx,
        bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
        w = 0;
 
+       out_vb->v4l2_buf.sequence = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
+       in_vb->v4l2_buf.sequence = q_data->sequence++;
        memcpy(&out_vb->v4l2_buf.timestamp,
                        &in_vb->v4l2_buf.timestamp,
                        sizeof(struct timeval));
+       if (in_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TIMECODE)
+               memcpy(&out_vb->v4l2_buf.timecode, &in_vb->v4l2_buf.timecode,
+                       sizeof(struct v4l2_timecode));
+       out_vb->v4l2_buf.field = in_vb->v4l2_buf.field;
+       out_vb->v4l2_buf.flags = in_vb->v4l2_buf.flags &
+               (V4L2_BUF_FLAG_TIMECODE |
+                V4L2_BUF_FLAG_KEYFRAME |
+                V4L2_BUF_FLAG_PFRAME |
+                V4L2_BUF_FLAG_BFRAME |
+                V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
 
        switch (ctx->mode) {
        case MEM2MEM_HFLIP | MEM2MEM_VFLIP:
@@ -505,19 +516,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 
 static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
 {
-       enum v4l2_field field;
-
-       field = f->fmt.pix.field;
-
-       if (field == V4L2_FIELD_ANY)
-               field = V4L2_FIELD_NONE;
-       else if (V4L2_FIELD_NONE != field)
-               return -EINVAL;
-
        /* V4L2 specification suggests the driver corrects the format struct
         * if any of the dimensions is unsupported */
-       f->fmt.pix.field = field;
-
        if (f->fmt.pix.height < MIN_H)
                f->fmt.pix.height = MIN_H;
        else if (f->fmt.pix.height > MAX_H)
@@ -531,6 +531,8 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
        f->fmt.pix.width &= ~DIM_ALIGN_MASK;
        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+       f->fmt.pix.field = V4L2_FIELD_NONE;
+       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -542,7 +544,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        struct m2mtest_ctx *ctx = file2ctx(file);
 
        fmt = find_format(f);
-       if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
+       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);
@@ -560,7 +566,11 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
        struct m2mtest_ctx *ctx = file2ctx(file);
 
        fmt = find_format(f);
-       if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
+       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);
@@ -740,6 +750,15 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb)
        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 (vb->v4l2_buf.field == V4L2_FIELD_ANY)
+                       vb->v4l2_buf.field = V4L2_FIELD_NONE;
+               if (vb->v4l2_buf.field != V4L2_FIELD_NONE) {
+                       dprintk(ctx->dev, "%s field isn't supported\n",
+                                       __func__);
+                       return -EINVAL;
+               }
+       }
 
        if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
                dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
@@ -755,13 +774,45 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb)
 static void m2mtest_buf_queue(struct vb2_buffer *vb)
 {
        struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
        v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
 }
 
+static int m2mtest_start_streaming(struct vb2_queue *q, unsigned count)
+{
+       struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
+       struct m2mtest_q_data *q_data = get_q_data(ctx, q->type);
+
+       q_data->sequence = 0;
+       return 0;
+}
+
+static int m2mtest_stop_streaming(struct vb2_queue *q)
+{
+       struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
+       struct vb2_buffer *vb;
+       unsigned long flags;
+
+       for (;;) {
+               if (V4L2_TYPE_IS_OUTPUT(q->type))
+                       vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+               else
+                       vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+               if (vb == NULL)
+                       return 0;
+               spin_lock_irqsave(&ctx->dev->irqlock, flags);
+               v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+               spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+       }
+       return 0;
+}
+
 static struct vb2_ops m2mtest_qops = {
        .queue_setup     = m2mtest_queue_setup,
        .buf_prepare     = m2mtest_buf_prepare,
        .buf_queue       = m2mtest_buf_queue,
+       .start_streaming = m2mtest_start_streaming,
+       .stop_streaming  = m2mtest_stop_streaming,
        .wait_prepare    = vb2_ops_wait_prepare,
        .wait_finish     = vb2_ops_wait_finish,
 };
@@ -772,12 +823,12 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
        int ret;
 
        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-       src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+       src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        src_vq->drv_priv = ctx;
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &m2mtest_qops;
        src_vq->mem_ops = &vb2_vmalloc_memops;
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        src_vq->lock = &ctx->dev->dev_mutex;
 
        ret = vb2_queue_init(src_vq);
@@ -785,12 +836,12 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
                return ret;
 
        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+       dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        dst_vq->drv_priv = ctx;
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &m2mtest_qops;
        dst_vq->mem_ops = &vb2_vmalloc_memops;
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        dst_vq->lock = &ctx->dev->dev_mutex;
 
        return vb2_queue_init(dst_vq);
@@ -801,10 +852,10 @@ static const struct v4l2_ctrl_config m2mtest_ctrl_trans_time_msec = {
        .id = V4L2_CID_TRANS_TIME_MSEC,
        .name = "Transaction Time (msec)",
        .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 1001,
+       .def = MEM2MEM_DEF_TRANSTIME,
        .min = 1,
        .max = 10001,
-       .step = 100,
+       .step = 1,
 };
 
 static const struct v4l2_ctrl_config m2mtest_ctrl_trans_num_bufs = {
index c690435853bdaf69f80d79567cb8f2ec8af967b8..0b7480e821423898c8b6f80d849fda1d0cd57997 100644 (file)
@@ -377,8 +377,13 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data)
                        src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
                        dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
 
-                       src_vb->v4l2_buf.timestamp = dst_vb->v4l2_buf.timestamp;
-                       src_vb->v4l2_buf.timecode = dst_vb->v4l2_buf.timecode;
+                       dst_vb->v4l2_buf.timestamp = src_vb->v4l2_buf.timestamp;
+                       dst_vb->v4l2_buf.flags &=
+                               ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+                       dst_vb->v4l2_buf.flags |=
+                               src_vb->v4l2_buf.flags
+                               & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+                       dst_vb->v4l2_buf.timecode = src_vb->v4l2_buf.timecode;
 
                        spin_lock_irqsave(&pcdev->irqlock, flags);
                        v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
@@ -766,7 +771,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &emmaprp_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        ret = vb2_queue_init(src_vq);
        if (ret)
@@ -778,7 +783,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &emmaprp_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        return vb2_queue_init(dst_vq);
 }
index dfd0a21a06588b26ee7ccc290e59e9f853175ea2..9a726eacb29be8dcaef7c41cfdebd8e07c9c8443 100644 (file)
@@ -601,6 +601,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
        switch (cur_display->type) {
        case OMAP_DISPLAY_TYPE_DSI:
        case OMAP_DISPLAY_TYPE_DPI:
+       case OMAP_DISPLAY_TYPE_DVI:
                if (mgr_id == OMAP_DSS_CHANNEL_LCD)
                        irq = DISPC_IRQ_VSYNC;
                else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
index cf1c437a868794362b3dc0d2e121ee28f52a8eb2..62e7e5783ce809c52f8905d482bb7aa232a3c287 100644 (file)
@@ -270,7 +270,8 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
        omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
 
        omap_start_dma(tx->dma_ch);
-       interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
+       wait_event_interruptible_timeout(tx->wait, tx->tx_status == 1,
+                                        VRFB_TX_TIMEOUT);
 
        if (tx->tx_status == 0) {
                omap_stop_dma(tx->dma_ch);
index 5807185262fef29a20dbb2cd5380da6887b182b7..06a0df434249a7f9e658d5cae51960d6b4e965d3 100644 (file)
@@ -391,7 +391,7 @@ static void isp_disable_interrupts(struct isp_device *isp)
  * @isp: OMAP3 ISP device
  * @idle: Consider idle state.
  *
- * Set the power settings for the ISP and SBL bus and cConfigure the HS/VS
+ * Set the power settings for the ISP and SBL bus and configure the HS/VS
  * interrupt source.
  *
  * We need to configure the HS/VS interrupt source before interrupts get
@@ -588,9 +588,6 @@ static void isp_isr_sbl(struct isp_device *isp)
  * @_isp: Pointer to the OMAP3 ISP device
  *
  * Handles the corresponding callback if plugged in.
- *
- * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
- * IRQ wasn't handled.
  */
 static irqreturn_t isp_isr(int irq, void *_isp)
 {
@@ -1420,7 +1417,7 @@ int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
 }
 
 /*
- * omap3isp_module_sync_is_stopped - Helper to verify if module was stopping
+ * omap3isp_module_sync_is_stopping - Helper to verify if module was stopping
  * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
  * @stopping: flag which tells module wants to stop
  *
index 081f5ec5a663c014e1ab270d463ed9b6e63efee0..6d5e69711907e655175ffe943fa5e2602582b556 100644 (file)
@@ -265,7 +265,7 @@ void omap3isp_unregister_entities(struct platform_device *pdev);
 
 /*
  * isp_reg_readl - Read value of an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @isp_mmio_range: Range to which the register offset refers to.
  * @reg_offset: Register offset to read from.
  *
@@ -280,7 +280,7 @@ u32 isp_reg_readl(struct isp_device *isp, enum isp_mem_resources isp_mmio_range,
 
 /*
  * isp_reg_writel - Write value to an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @reg_value: 32 bit value to write to the register.
  * @isp_mmio_range: Range to which the register offset refers to.
  * @reg_offset: Register offset to write into.
@@ -293,8 +293,8 @@ void isp_reg_writel(struct isp_device *isp, u32 reg_value,
 }
 
 /*
- * isp_reg_and - Clear individual bits in an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * isp_reg_clr - Clear individual bits in an OMAP3 ISP register
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @mmio_range: Range to which the register offset refers to.
  * @reg: Register offset to work on.
  * @clr_bits: 32 bit value which would be cleared in the register.
@@ -310,7 +310,7 @@ void isp_reg_clr(struct isp_device *isp, enum isp_mem_resources mmio_range,
 
 /*
  * isp_reg_set - Set individual bits in an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @mmio_range: Range to which the register offset refers to.
  * @reg: Register offset to work on.
  * @set_bits: 32 bit value which would be set in the register.
@@ -326,7 +326,7 @@ void isp_reg_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
 
 /*
  * isp_reg_clr_set - Clear and set invidial bits in an OMAP3 ISP register
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @mmio_range: Range to which the register offset refers to.
  * @reg: Register offset to work on.
  * @clr_bits: 32 bit value which would be cleared in the register.
index 5db2c88b9ad8caf810e6de514fef552cb80b929d..4d920c800ff5fc1e863199b332acadb57294210b 100644 (file)
@@ -293,7 +293,7 @@ static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
                        isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC,
                                    ISPCCDC_LSC_CONFIG, ISPCCDC_LSC_ENABLE);
                        ccdc->lsc.state = LSC_STATE_STOPPED;
-                       dev_warn(to_device(ccdc), "LSC prefecth timeout\n");
+                       dev_warn(to_device(ccdc), "LSC prefetch timeout\n");
                        return -ETIMEDOUT;
                }
                ccdc->lsc.state = LSC_STATE_RUNNING;
@@ -674,7 +674,7 @@ static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
 /*
  * ccdc_config - Set CCDC configuration from userspace
  * @ccdc: Pointer to ISP CCDC device.
- * @userspace_add: Structure containing CCDC configuration sent from userspace.
+ * @ccdc_struct: Structure containing CCDC configuration sent from userspace.
  *
  * Returns 0 if successful, -EINVAL if the pointer to the configuration
  * structure is null, or the copy_from_user function fails to copy user space
@@ -793,7 +793,7 @@ static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
 
 /*
  * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
- * @dev: Pointer to ISP device
+ * @isp: Pointer to ISP device
  */
 void omap3isp_ccdc_restore_context(struct isp_device *isp)
 {
@@ -2525,7 +2525,7 @@ error_video:
 
 /*
  * omap3isp_ccdc_init - CCDC module initialization.
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  *
  * TODO: Get the initialisation values from platform data.
  *
@@ -2564,7 +2564,7 @@ int omap3isp_ccdc_init(struct isp_device *isp)
 
 /*
  * omap3isp_ccdc_cleanup - CCDC module cleanup.
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  */
 void omap3isp_ccdc_cleanup(struct isp_device *isp)
 {
index a5da9e19edbf632e5e22bb1920944cec66157b27..9d24e4107864fc4905cbc13f8b2787634a27a24c 100644 (file)
@@ -63,12 +63,6 @@ struct ispccdc_lsc_config_req {
 
 /*
  * ispccdc_lsc - CCDC LSC parameters
- * @update_config: Set when user changes config
- * @request_enable: Whether LSC is requested to be enabled
- * @config: LSC config set by user
- * @update_table: Set when user provides a new LSC table to table_new
- * @table_new: LSC table set by user, ISP address
- * @table_inuse: LSC table currently in use, ISP address
  */
 struct ispccdc_lsc {
        enum ispccdc_lsc_state state;
index e84fe0543e4719424c3224895ed7b5a218ea8904..b30b67d22a58cfb83990b589926be86c95d8c2bc 100644 (file)
@@ -211,7 +211,7 @@ static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
 /*
  * ccp2_phyif_config - Initialize CCP2 phy interface config
  * @ccp2: Pointer to ISP CCP2 device
- * @config: CCP2 platform data
+ * @pdata: CCP2 platform data
  *
  * Configure the CCP2 physical interface module from platform data.
  *
@@ -518,7 +518,7 @@ static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,
                       ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,
                       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);
 
-       /* Enable LCM interupts */
+       /* Enable LCM interrupts */
        isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,
                    ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |
                    ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);
@@ -1096,7 +1096,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
         * implementation we use a fixed 32 bytes alignment regardless of the
         * input format and width. If strict 128 bits alignment support is
         * required ispvideo will need to be made aware of this special dual
-        * alignement requirements.
+        * alignment requirements.
         */
        ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
        ccp2->video_in.bpl_alignment = 32;
index e070c24048efb8456e717a5056a52665c82b1ea3..06a5f8164eaa0a4e5aa9b3e8b64674d83a5f3042 100644 (file)
@@ -299,7 +299,7 @@ static u32 hist_get_buf_size(struct omap3isp_hist_config *conf)
 
 /*
  * hist_validate_params - Helper function to check user given params.
- * @user_cfg: Pointer to user configuration structure.
+ * @new_conf: Pointer to user configuration structure.
  *
  * Returns 0 on success configuration.
  */
@@ -351,7 +351,7 @@ static int hist_validate_params(struct ispstat *hist, void *new_conf)
 
        buf_size = hist_get_buf_size(user_cfg);
        if (buf_size > user_cfg->buf_size)
-               /* User's buf_size request wasn't enoght */
+               /* User's buf_size request wasn't enough */
                user_cfg->buf_size = buf_size;
        else if (user_cfg->buf_size > OMAP3ISP_HIST_MAX_BUF_SIZE)
                user_cfg->buf_size = OMAP3ISP_HIST_MAX_BUF_SIZE;
index 1c776c1186f1b9ff4a4ddbb79b6cb48c88e196f4..395b2b068c7553eb27a544dab4953040563a7119 100644 (file)
@@ -122,7 +122,7 @@ static struct omap3isp_prev_csc flr_prev_csc = {
 #define PREV_MAX_OUT_WIDTH_REV_15      4096
 
 /*
- * Coeficient Tables for the submodules in Preview.
+ * Coefficient Tables for the submodules in Preview.
  * Array is initialised with the values from.the tables text file.
  */
 
@@ -971,7 +971,8 @@ static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
 
 /*
  * preview_config_ycpos - Configure byte layout of YUV image.
- * @mode: Indicates the required byte layout.
+ * @prev: pointer to previewer private structure
+ * @pixelcode: pixel code
  */
 static void
 preview_config_ycpos(struct isp_prev_device *prev,
@@ -1079,6 +1080,7 @@ static void preview_config_input_format(struct isp_prev_device *prev,
  */
 static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
 {
+       const struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
        struct isp_device *isp = to_isp_device(prev);
        unsigned int sph = prev->crop.left;
        unsigned int eph = prev->crop.left + prev->crop.width - 1;
@@ -1086,6 +1088,14 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
        unsigned int elv = prev->crop.top + prev->crop.height - 1;
        u32 features;
 
+       if (format->code != V4L2_MBUS_FMT_Y8_1X8 &&
+           format->code != V4L2_MBUS_FMT_Y10_1X10) {
+               sph -= 2;
+               eph += 2;
+               slv -= 2;
+               elv += 2;
+       }
+
        features = (prev->params.params[0].features & active)
                 | (prev->params.params[1].features & ~active);
 
@@ -1363,8 +1373,8 @@ static void preview_init_params(struct isp_prev_device *prev)
 }
 
 /*
- * preview_max_out_width - Handle previewer hardware ouput limitations
- * @isp_revision : ISP revision
+ * preview_max_out_width - Handle previewer hardware output limitations
+ * @prev: pointer to previewer private structure
  * returns maximum width output for current isp revision
  */
 static unsigned int preview_max_out_width(struct isp_prev_device *prev)
@@ -1610,7 +1620,7 @@ static const struct v4l2_ctrl_ops preview_ctrl_ops = {
 
 /*
  * preview_ioctl - Handle preview module private ioctl's
- * @prev: pointer to preview context structure
+ * @sd: pointer to v4l2 subdev structure
  * @cmd: configuration command
  * @arg: configuration argument
  * return -EINVAL or zero on success
@@ -2341,7 +2351,7 @@ error_video_in:
 
 /*
  * omap3isp_preview_init - Previewer initialization.
- * @dev : Pointer to ISP device
+ * @isp : Pointer to ISP device
  * return -ENOMEM or zero on success
  */
 int omap3isp_preview_init(struct isp_device *isp)
index 5f0f8fab1d1736440b66c0a3cef3755ce70dfb22..a5e65858e7991b5f961ff671d1a8e36f4657ecad 100644 (file)
@@ -597,7 +597,7 @@ static int isp_video_buffer_wait(struct isp_video_buffer *buf, int nonblocking)
  * isp_video_queue_free - Free video buffers memory
  *
  * Buffers can only be freed if the queue isn't streaming and if no buffer is
- * mapped to userspace. Return -EBUSY if those conditions aren't statisfied.
+ * mapped to userspace. Return -EBUSY if those conditions aren't satisfied.
  *
  * This function must be called with the queue lock held.
  */
index 0d36b8bc9f9806b1360d0a7482f2fe446fc70e4e..86369df81d7481fbcdece03d1653baa3fe8b6d43 100644 (file)
@@ -206,7 +206,7 @@ static void resizer_set_bilinear(struct isp_res_device *res,
 /*
  * resizer_set_ycpos - Luminance and chrominance order
  * @res: Device context.
- * @order: order type.
+ * @pixelcode: pixel code.
  */
 static void resizer_set_ycpos(struct isp_res_device *res,
                              enum v4l2_mbus_pixelcode pixelcode)
@@ -918,8 +918,8 @@ static void resizer_calc_ratios(struct isp_res_device *res,
 /*
  * resizer_set_crop_params - Setup hardware with cropping parameters
  * @res : resizer private structure
- * @crop_rect : current crop rectangle
- * @ratio : resizer ratios
+ * @input : format on sink pad
+ * @output : format on source pad
  * return none
  */
 static void resizer_set_crop_params(struct isp_res_device *res,
index 70c1c0e1bbdf687594c5ac26baa5361bd3b16a18..9b01e9047c15d8ce98d177760ff82a3f588c3071 100644 (file)
 #include <linux/types.h>
 
 /*
- * Constants for filter coefficents count
+ * Constants for filter coefficients count
  */
 #define COEFF_CNT              32
 
 /*
- * struct isprsz_coef - Structure for resizer filter coeffcients.
+ * struct isprsz_coef - Structure for resizer filter coefficients.
  * @h_filter_coef_4tap: Horizontal filter coefficients for 8-phase/4-tap
  *                     mode (.5x-4x)
  * @v_filter_coef_4tap: Vertical filter coefficients for 8-phase/4-tap
index a75407c3a726217981d40193b89919332a7919bf..5707f85c4cc4cba883e6107e892ba864fe8bc4f5 100644 (file)
@@ -144,7 +144,7 @@ static int isp_stat_buf_check_magic(struct ispstat *stat,
        for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
             w < end; w++) {
                if (unlikely(*w != MAGIC_NUM)) {
-                       dev_dbg(stat->isp->dev, "%s: endding magic check does "
+                       dev_dbg(stat->isp->dev, "%s: ending magic check does "
                                "not match.\n", stat->subdev.name);
                        return -EINVAL;
                }
@@ -841,7 +841,7 @@ int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable)
        if (enable) {
                /*
                 * Only set enable PCR bit if the module was previously
-                * enabled through ioct.
+                * enabled through ioctl.
                 */
                isp_stat_try_enable(stat);
        } else {
index 856fdf55403580c996493b03b811b3c4ef6ac5b0..85b4036ba5e43296ce647c4f857e8484b430846c 100644 (file)
@@ -333,7 +333,7 @@ isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
 
 /*
  * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @sglist: Pointer to source Scatter gather list to allocate.
  * @sglen: Number of elements of the scatter-gatter list.
  *
@@ -363,7 +363,7 @@ ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
 
 /*
  * ispmmu_vunmap - Unmap a device address from the ISP MMU
- * @dev: Device pointer specific to the OMAP3 ISP.
+ * @isp: Device pointer specific to the OMAP3 ISP.
  * @da: Device address generated from a ispmmu_vmap call.
  */
 static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
@@ -886,7 +886,11 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
        struct v4l2_ext_controls ctrls;
        struct v4l2_ext_control ctrl;
        unsigned int i;
-       int ret = 0;
+       int ret;
+
+       /* Memory-to-memory pipelines have no external subdev. */
+       if (pipe->input != NULL)
+               return 0;
 
        for (i = 0; i < ARRAY_SIZE(ents); i++) {
                /* Is the entity part of the pipeline? */
@@ -905,7 +909,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
 
        if (!source) {
                dev_warn(isp->dev, "can't find source, failing now\n");
-               return ret;
+               return -EINVAL;
        }
 
        if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
index 40b298ab87f1669682aea3c68c70b57703af043d..4e4d1631e0423659bd3d7c6bc18852058c8193b3 100644 (file)
@@ -1160,7 +1160,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct camif_buffer);
        q->drv_priv = vp;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        ret = vb2_queue_init(q);
        if (ret)
@@ -1592,26 +1592,27 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
                        ARRAY_SIZE(s3c_camif_test_pattern_menu) - 1, 0, 0,
                        s3c_camif_test_pattern_menu);
 
-       camif->ctrl_colorfx = v4l2_ctrl_new_std_menu(handler,
+       if (camif->variant->has_img_effect) {
+               camif->ctrl_colorfx = v4l2_ctrl_new_std_menu(handler,
                                &s3c_camif_subdev_ctrl_ops,
                                V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
                                ~0x981f, V4L2_COLORFX_NONE);
 
-       camif->ctrl_colorfx_cbcr = v4l2_ctrl_new_std(handler,
+               camif->ctrl_colorfx_cbcr = v4l2_ctrl_new_std(handler,
                                &s3c_camif_subdev_ctrl_ops,
                                V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
+       }
+
        if (handler->error) {
                v4l2_ctrl_handler_free(handler);
                media_entity_cleanup(&sd->entity);
                return handler->error;
        }
 
-       v4l2_ctrl_auto_cluster(2, &camif->ctrl_colorfx,
+       if (camif->variant->has_img_effect)
+               v4l2_ctrl_auto_cluster(2, &camif->ctrl_colorfx,
                               V4L2_COLORFX_SET_CBCR, false);
-       if (!camif->variant->has_img_effect) {
-               camif->ctrl_colorfx->flags |= V4L2_CTRL_FLAG_DISABLED;
-               camif->ctrl_colorfx_cbcr->flags |= V4L2_CTRL_FLAG_DISABLED;
-       }
+
        sd->ctrl_handler = handler;
        v4l2_set_subdevdata(sd, camif);
 
index 0fcf7d75e841b550d24df8faa9d247ce846d2044..357af1ebaeda2791667e8f5c32b12fe7f45bf18a 100644 (file)
@@ -157,7 +157,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->ops = &g2d_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        src_vq->lock = &ctx->dev->mutex;
 
        ret = vb2_queue_init(src_vq);
@@ -170,7 +170,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->ops = &g2d_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        dst_vq->lock = &ctx->dev->mutex;
 
        return vb2_queue_init(dst_vq);
@@ -560,6 +560,9 @@ static irqreturn_t g2d_isr(int irq, void *prv)
 
        dst->v4l2_buf.timecode = src->v4l2_buf.timecode;
        dst->v4l2_buf.timestamp = src->v4l2_buf.timestamp;
+       dst->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       dst->v4l2_buf.flags |=
+               src->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 
        v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
        v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
index 7d68d0b9966aa7774edfa1ccce40100768632bab..8a18972012f7e00562c061cad66514e2588df876 100644 (file)
@@ -1701,7 +1701,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &s5p_jpeg_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        src_vq->lock = &ctx->jpeg->lock;
 
        ret = vb2_queue_init(src_vq);
@@ -1714,7 +1714,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &s5p_jpeg_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        dst_vq->lock = &ctx->jpeg->lock;
 
        return vb2_queue_init(dst_vq);
@@ -1766,6 +1766,9 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
 
        dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
        dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
+       dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       dst_buf->v4l2_buf.flags |=
+               src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 
        v4l2_m2m_buf_done(src_buf, state);
        if (curr_ctx->mode == S5P_JPEG_ENCODE)
index 33f2c7374cfd955c55f31637697bd7af210d657e..57fb05bb8c7742fccf24a5e0d9f4ad1181055de7 100644 (file)
 
 /* JPEG CNTL Register bit */
 #define EXYNOS4_ENC_DEC_MODE_MASK      (0xfffffffc << 0)
-#define EXYNOS4_DEC_MODE                       (1 << 0)
-#define EXYNOS4_ENC_MODE                       (1 << 1)
+#define EXYNOS4_DEC_MODE               (1 << 0)
+#define EXYNOS4_ENC_MODE               (1 << 1)
 #define EXYNOS4_AUTO_RST_MARKER                (1 << 2)
 #define EXYNOS4_RST_INTERVAL_SHIFT     3
 #define EXYNOS4_RST_INTERVAL(x)                (((x) & 0xffff) \
                                                << EXYNOS4_RST_INTERVAL_SHIFT)
 #define EXYNOS4_HUF_TBL_EN             (1 << 19)
 #define EXYNOS4_HOR_SCALING_SHIFT      20
-#define EXYNOS4_HOR_SCALING_MASK               (3 << EXYNOS4_HOR_SCALING_SHIFT)
+#define EXYNOS4_HOR_SCALING_MASK       (3 << EXYNOS4_HOR_SCALING_SHIFT)
 #define EXYNOS4_HOR_SCALING(x)         (((x) & 0x3) \
                                                << EXYNOS4_HOR_SCALING_SHIFT)
 #define EXYNOS4_VER_SCALING_SHIFT      22
-#define EXYNOS4_VER_SCALING_MASK               (3 << EXYNOS4_VER_SCALING_SHIFT)
+#define EXYNOS4_VER_SCALING_MASK       (3 << EXYNOS4_VER_SCALING_SHIFT)
 #define EXYNOS4_VER_SCALING(x)         (((x) & 0x3) \
                                                << EXYNOS4_VER_SCALING_SHIFT)
 #define EXYNOS4_PADDING                        (1 << 27)
 #define EXYNOS4_FRAME_ERR_EN           (1 << 4)
 #define EXYNOS4_INT_EN_ALL             (0x1f << 0)
 
-#define EXYNOS4_MOD_REG_PROC_ENC               (0 << 3)
-#define EXYNOS4_MOD_REG_PROC_DEC               (1 << 3)
+#define EXYNOS4_MOD_REG_PROC_ENC       (0 << 3)
+#define EXYNOS4_MOD_REG_PROC_DEC       (1 << 3)
 
 #define EXYNOS4_MOD_REG_SUBSAMPLE_444  (0 << 0)
 #define EXYNOS4_MOD_REG_SUBSAMPLE_422  (1 << 0)
 #define EXYNOS4_DEC_YUV_420_IMG                (4 << 0)
 
 #define EXYNOS4_GRAY_IMG_IP_SHIFT      3
-#define EXYNOS4_GRAY_IMG_IP_MASK               (7 << EXYNOS4_GRAY_IMG_IP_SHIFT)
+#define EXYNOS4_GRAY_IMG_IP_MASK       (7 << EXYNOS4_GRAY_IMG_IP_SHIFT)
 #define EXYNOS4_GRAY_IMG_IP            (4 << EXYNOS4_GRAY_IMG_IP_SHIFT)
 
 #define EXYNOS4_RGB_IP_SHIFT           6
 #define EXYNOS4_RGB_IP_RGB_16BIT_IMG   (4 << EXYNOS4_RGB_IP_SHIFT)
 #define EXYNOS4_RGB_IP_RGB_32BIT_IMG   (5 << EXYNOS4_RGB_IP_SHIFT)
 
-#define EXYNOS4_YUV_444_IP_SHIFT                       9
+#define EXYNOS4_YUV_444_IP_SHIFT               9
 #define EXYNOS4_YUV_444_IP_MASK                        (7 << EXYNOS4_YUV_444_IP_SHIFT)
 #define EXYNOS4_YUV_444_IP_YUV_444_2P_IMG      (4 << EXYNOS4_YUV_444_IP_SHIFT)
 #define EXYNOS4_YUV_444_IP_YUV_444_3P_IMG      (5 << EXYNOS4_YUV_444_IP_SHIFT)
 
-#define EXYNOS4_YUV_422_IP_SHIFT                       12
+#define EXYNOS4_YUV_422_IP_SHIFT               12
 #define EXYNOS4_YUV_422_IP_MASK                        (7 << EXYNOS4_YUV_422_IP_SHIFT)
 #define EXYNOS4_YUV_422_IP_YUV_422_1P_IMG      (4 << EXYNOS4_YUV_422_IP_SHIFT)
 #define EXYNOS4_YUV_422_IP_YUV_422_2P_IMG      (5 << EXYNOS4_YUV_422_IP_SHIFT)
 #define EXYNOS4_YUV_422_IP_YUV_422_3P_IMG      (6 << EXYNOS4_YUV_422_IP_SHIFT)
 
-#define EXYNOS4_YUV_420_IP_SHIFT                       15
+#define EXYNOS4_YUV_420_IP_SHIFT               15
 #define EXYNOS4_YUV_420_IP_MASK                        (7 << EXYNOS4_YUV_420_IP_SHIFT)
 #define EXYNOS4_YUV_420_IP_YUV_420_2P_IMG      (4 << EXYNOS4_YUV_420_IP_SHIFT)
 #define EXYNOS4_YUV_420_IP_YUV_420_3P_IMG      (5 << EXYNOS4_YUV_420_IP_SHIFT)
 
 #define EXYNOS4_JPEG_DECODED_IMG_FMT_MASK      0x03
 
-#define EXYNOS4_SWAP_CHROMA_CRCB                       (1 << 26)
-#define EXYNOS4_SWAP_CHROMA_CBCR                       (0 << 26)
+#define EXYNOS4_SWAP_CHROMA_CRCB               (1 << 26)
+#define EXYNOS4_SWAP_CHROMA_CBCR               (0 << 26)
 
 /* JPEG HUFF count Register bit */
 #define EXYNOS4_HUFF_COUNT_MASK                        0xffff
index 2398cdf613412dfc85c4ed45ca2ab0eef68220b2..8d0b686d9adbeecbe26c41352fe79f75cf04ff98 100644 (file)
 #define S5P_FIMV_E_PADDING_CTRL_V6             0xf7a4
 #define S5P_FIMV_E_MV_HOR_RANGE_V6             0xf7ac
 #define S5P_FIMV_E_MV_VER_RANGE_V6             0xf7b0
+#define S5P_FIMV_E_MV_RANGE_V6_MASK            0x3fff
 
 #define S5P_FIMV_E_VBV_BUFFER_SIZE_V6          0xf84c
 #define S5P_FIMV_E_VBV_INIT_DELAY_V6           0xf850
index e2aac592d29f6a3be2ec81ade46a89cb7e9727ee..89356ae90238689a21de6f73344dd5336a96696d 100644 (file)
@@ -232,6 +232,11 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
                                                src_buf->b->v4l2_buf.timecode;
                        dst_buf->b->v4l2_buf.timestamp =
                                                src_buf->b->v4l2_buf.timestamp;
+                       dst_buf->b->v4l2_buf.flags &=
+                               ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+                       dst_buf->b->v4l2_buf.flags |=
+                               src_buf->b->v4l2_buf.flags
+                               & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
                        switch (frame_type) {
                        case S5P_FIMV_DECODE_FRAME_I_FRAME:
                                dst_buf->b->v4l2_buf.flags |=
@@ -794,7 +799,7 @@ static int s5p_mfc_open(struct file *file)
                goto err_queue_init;
        }
        q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        ret = vb2_queue_init(q);
        if (ret) {
                mfc_err("Failed to initialize videobuf2 queue(capture)\n");
@@ -816,7 +821,7 @@ static int s5p_mfc_open(struct file *file)
                goto err_queue_init;
        }
        q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        ret = vb2_queue_init(q);
        if (ret) {
                mfc_err("Failed to initialize videobuf2 queue(output)\n");
@@ -1147,9 +1152,9 @@ static int s5p_mfc_probe(struct platform_device *pdev)
                ret = -ENOMEM;
                goto err_dec_alloc;
        }
-       vfd->fops       = &s5p_mfc_fops,
+       vfd->fops       = &s5p_mfc_fops;
        vfd->ioctl_ops  = get_dec_v4l2_ioctl_ops();
-       vfd->release    = video_device_release,
+       vfd->release    = video_device_release;
        vfd->lock       = &dev->mfc_mutex;
        vfd->v4l2_dev   = &dev->v4l2_dev;
        vfd->vfl_dir    = VFL_DIR_M2M;
@@ -1172,9 +1177,9 @@ static int s5p_mfc_probe(struct platform_device *pdev)
                ret = -ENOMEM;
                goto err_enc_alloc;
        }
-       vfd->fops       = &s5p_mfc_fops,
+       vfd->fops       = &s5p_mfc_fops;
        vfd->ioctl_ops  = get_enc_v4l2_ioctl_ops();
-       vfd->release    = video_device_release,
+       vfd->release    = video_device_release;
        vfd->lock       = &dev->mfc_mutex;
        vfd->v4l2_dev   = &dev->v4l2_dev;
        vfd->vfl_dir    = VFL_DIR_M2M;
index f723f1f2f5784e4501e7b39dcb027c507523cb07..5c28cc3e699b4809238a6e6ed53efee3a253548d 100644 (file)
@@ -426,6 +426,8 @@ struct s5p_mfc_vp8_enc_params {
 struct s5p_mfc_enc_params {
        u16 width;
        u16 height;
+       u32 mv_h_range;
+       u32 mv_v_range;
 
        u16 gop_size;
        enum v4l2_mpeg_video_multi_slice_mode slice_mode;
index 2475a3c9a0a62ab27330a347865530466d209e0d..ee05f2dd439b1017a7f8a59158d06fc6626a5d9d 100644 (file)
@@ -44,8 +44,6 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
                return -ENOMEM;
        }
 
-       dev->bank1 = dev->bank1;
-
        if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
                bank2_virt = dma_alloc_coherent(dev->mem_dev_r, 1 << MFC_BASE_ALIGN_ORDER,
                                        &bank2_dma_addr, GFP_KERNEL);
index 91b6e020ddf3ec05d5255574f71be3b2dc86fc23..df83cd157babf953b15b4dd323f87e08e5ccb6d4 100644 (file)
@@ -207,6 +207,24 @@ static struct mfc_control controls[] = {
                .step = 1,
                .default_value = 0,
        },
+       {
+               .id = V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE,
+               .type = V4L2_CTRL_TYPE_INTEGER,
+               .name = "Horizontal MV Search Range",
+               .minimum = 16,
+               .maximum = 128,
+               .step = 16,
+               .default_value = 32,
+       },
+       {
+               .id = V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE,
+               .type = V4L2_CTRL_TYPE_INTEGER,
+               .name = "Vertical MV Search Range",
+               .minimum = 16,
+               .maximum = 128,
+               .step = 16,
+               .default_value = 32,
+       },
        {
                .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
                .type = V4L2_CTRL_TYPE_INTEGER,
@@ -1417,6 +1435,12 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
        case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
                p->vbv_size = ctrl->val;
                break;
+       case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
+               p->mv_h_range = ctrl->val;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
+               p->mv_v_range = ctrl->val;
+               break;
        case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
                p->codec.h264.cpb_size = ctrl->val;
                break;
index f6ff2dbf3a1d5d700ad18ab74f4e89be437baf17..f64621ae9b5a563d90a23f855c837d14f30f36fb 100644 (file)
@@ -727,14 +727,10 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
        WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
 
        /* setting for MV range [16, 256] */
-       reg = 0;
-       reg &= ~(0x3FFF);
-       reg = 256;
+       reg = (p->mv_h_range & S5P_FIMV_E_MV_RANGE_V6_MASK);
        WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE_V6);
 
-       reg = 0;
-       reg &= ~(0x3FFF);
-       reg = 256;
+       reg = (p->mv_v_range & S5P_FIMV_E_MV_RANGE_V6_MASK);
        WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE_V6);
 
        WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION_V6);
index c5059ba0d733d9f819a6af1b55f57c47c31fe756..a1ce55fd30f360cb77a4c98a324f027cb7136c09 100644 (file)
@@ -946,11 +946,6 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
 
        mxr_dbg(mdev, "%s\n", __func__);
 
-       if (count == 0) {
-               mxr_dbg(mdev, "no output buffers queued\n");
-               return -ENOBUFS;
-       }
-
        /* block any changes in output configuration */
        mxr_output_get(mdev);
 
@@ -1124,6 +1119,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
                .drv_priv = layer,
                .buf_struct_size = sizeof(struct mxr_buffer),
                .ops = &mxr_video_qops,
+               .min_buffers_needed = 1,
                .mem_ops = &vb2_dma_contig_memops,
        };
 
index 4835173d7f80fd651848a9feca1f779face352d3..f0b6c900034d9c25092abebdc0f48ee2a3a8328d 100644 (file)
@@ -472,7 +472,7 @@ static int isi_camera_init_videobuf(struct vb2_queue *q,
        q->buf_struct_size = sizeof(struct frame_buffer);
        q->ops = &isi_video_qops;
        q->mem_ops = &vb2_dma_contig_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        return vb2_queue_init(q);
 }
index d73abca9c6eeda21028dbddcab4410492ec28ae4..3e844803bdca113d215ac0c68e7ab109ea7452ad 100644 (file)
@@ -794,7 +794,7 @@ static int mx2_camera_init_videobuf(struct vb2_queue *q,
        q->ops = &mx2_videobuf_ops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct mx2_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        return vb2_queue_init(q);
 }
index f975b70086922c866dc415f9eca4506aef3c19ea..9ed81ac6881c44d9fe53b545bded42e828363377 100644 (file)
@@ -453,7 +453,7 @@ static int mx3_camera_init_videobuf(struct vb2_queue *q,
        q->ops = &mx3_videobuf_ops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct mx3_camera_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        return vb2_queue_init(q);
 }
index 3b1c05a72d00cf16ab7a5f070aa09da12b35d00a..704eee766487394a815bbc049c018e45f6269860 100644 (file)
@@ -68,6 +68,8 @@
 #define VNMC_YCAL              (1 << 19)
 #define VNMC_INF_YUV8_BT656    (0 << 16)
 #define VNMC_INF_YUV8_BT601    (1 << 16)
+#define VNMC_INF_YUV10_BT656   (2 << 16)
+#define VNMC_INF_YUV10_BT601   (3 << 16)
 #define VNMC_INF_YUV16         (5 << 16)
 #define VNMC_VUP               (1 << 10)
 #define VNMC_IM_ODD            (0 << 3)
@@ -275,6 +277,12 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
                /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
                vnmc |= priv->pdata->flags & RCAR_VIN_BT656 ?
                        VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
+               break;
+       case V4L2_MBUS_FMT_YUYV10_2X10:
+               /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
+               vnmc |= priv->pdata->flags & RCAR_VIN_BT656 ?
+                       VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
+               break;
        default:
                break;
        }
@@ -1003,6 +1011,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
        switch (code) {
        case V4L2_MBUS_FMT_YUYV8_1X16:
        case V4L2_MBUS_FMT_YUYV8_2X8:
+       case V4L2_MBUS_FMT_YUYV10_2X10:
                if (cam->extra_fmt)
                        break;
 
@@ -1360,7 +1369,7 @@ static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
        vq->ops = &rcar_vin_vb2_ops;
        vq->mem_ops = &vb2_dma_contig_memops;
        vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
-       vq->timestamp_type  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       vq->timestamp_flags  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        return vb2_queue_init(vq);
 }
index 150bd4df413c321ca5f48a5514213ed1c1c306a4..3e75a469cd49ff64d7301c9854dd4ac451b57e04 100644 (file)
@@ -1665,7 +1665,7 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
        q->ops = &sh_mobile_ceu_videobuf_ops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        return vb2_queue_init(q);
 }
index 1296c5386231e25700a0f95e05a6f0a97d72e5fa..7a77a5b7a0754edcdb04eb59aa7e15345e10c2b3 100644 (file)
@@ -1278,6 +1278,8 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
        d_buf = &d_vb->v4l2_buf;
 
        d_buf->timestamp = s_buf->timestamp;
+       d_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       d_buf->flags |= s_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
        if (s_buf->flags & V4L2_BUF_FLAG_TIMECODE) {
                d_buf->flags |= V4L2_BUF_FLAG_TIMECODE;
                d_buf->timecode = s_buf->timecode;
@@ -1770,7 +1772,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &vpe_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
-       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        ret = vb2_queue_init(src_vq);
        if (ret)
@@ -1783,7 +1785,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &vpe_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
-       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
        return vb2_queue_init(dst_vq);
 }
index 2d4e73b45c5e3b05d7e4615f6f6fd0d46bd56656..3890f4f42a78af6f3cf29042fcf1c00b22297023 100644 (file)
@@ -70,10 +70,6 @@ static unsigned debug;
 module_param(debug, uint, 0644);
 MODULE_PARM_DESC(debug, "activates debug info");
 
-static unsigned int vid_limit = 16;
-module_param(vid_limit, uint, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
-
 /* Global font descriptor */
 static const u8 *font8x16;
 
@@ -191,7 +187,6 @@ struct vivi_buffer {
        /* common v4l buffer stuff -- must be first */
        struct vb2_buffer       vb;
        struct list_head        list;
-       const struct vivi_fmt  *fmt;
 };
 
 struct vivi_dmaqueue {
@@ -254,7 +249,7 @@ struct vivi_dev {
        struct v4l2_fract          timeperframe;
        unsigned int               width, height;
        struct vb2_queue           vb_vidq;
-       unsigned int               field_count;
+       unsigned int               seq_count;
 
        u8                         bars[9][3];
        u8                         line[MAX_WIDTH * 8] __attribute__((__aligned__(4)));
@@ -675,8 +670,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
        dev->mv_count += 2;
 
        buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
-       dev->field_count++;
-       buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
+       buf->vb.v4l2_buf.sequence = dev->seq_count++;
        v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
 }
 
@@ -818,19 +812,15 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
        struct vivi_dev *dev = vb2_get_drv_priv(vq);
        unsigned long size;
 
-       if (fmt)
+       size = dev->width * dev->height * dev->pixelsize;
+       if (fmt) {
+               if (fmt->fmt.pix.sizeimage < size)
+                       return -EINVAL;
                size = fmt->fmt.pix.sizeimage;
-       else
-               size = dev->width * dev->height * dev->pixelsize;
-
-       if (size == 0)
-               return -EINVAL;
-
-       if (0 == *nbuffers)
-               *nbuffers = 32;
-
-       while (size * *nbuffers > vid_limit * 1024 * 1024)
-               (*nbuffers)--;
+               /* check against insane over 8K resolution buffers */
+               if (size > 7680 * 4320 * dev->pixelsize)
+                       return -EINVAL;
+       }
 
        *nplanes = 1;
 
@@ -876,8 +866,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
 
        vb2_set_plane_payload(&buf->vb, 0, size);
 
-       buf->fmt = dev->fmt;
-
        precalculate_bars(dev);
        precalculate_line(dev);
 
@@ -901,8 +889,20 @@ static void buffer_queue(struct vb2_buffer *vb)
 static int start_streaming(struct vb2_queue *vq, unsigned int count)
 {
        struct vivi_dev *dev = vb2_get_drv_priv(vq);
+       int err;
+
        dprintk(dev, 1, "%s\n", __func__);
-       return vivi_start_generating(dev);
+       dev->seq_count = 0;
+       err = vivi_start_generating(dev);
+       if (err) {
+               struct vivi_buffer *buf, *tmp;
+
+               list_for_each_entry_safe(buf, tmp, &dev->vidq.active, list) {
+                       list_del(&buf->list);
+                       vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+               }
+       }
+       return err;
 }
 
 /* abort streaming and wait for last buffer */
@@ -1121,7 +1121,11 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
        if (!fmt)
                return -EINVAL;
 
-       /* regarding width & height - we support any */
+       /* check for valid width/height */
+       if (fival->width < 48 || fival->width > MAX_WIDTH || (fival->width & 3))
+               return -EINVAL;
+       if (fival->height < 32 || fival->height > MAX_HEIGHT)
+               return -EINVAL;
 
        fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
 
@@ -1439,7 +1443,7 @@ static int __init vivi_create_instance(int inst)
        q->buf_struct_size = sizeof(struct vivi_buffer);
        q->ops = &vivi_video_qops;
        q->mem_ops = &vb2_vmalloc_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        ret = vb2_queue_init(q);
        if (ret)
index 94d1b02680c57e0b4b544cd5cef90a59485bdc92..0313210c6e9e4d9d47a19b12505aae7b5d5ded8c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1.h  --  R-Car VSP1 Driver
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 0df0a994e575c4b1e83c121fee0f4dcdec70b46c..2f74f0e0ddf598ac9b7a5daf905b6485448bc566 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_drv.c  --  R-Car VSP1 Driver
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 0226e47df6d94d53358ff310dc46c1d73ac59096..3fc9e4266caf48c26102768790258315ac7c4542 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_entity.c  --  R-Car VSP1 Base Entity
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index e152798d7f38e859ccf8fc0d87bd77e5680e91de..f6fd6988aeb0913ac6c023bcb38e487709269587 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_entity.h  --  R-Car VSP1 Base Entity
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 74a32e69ef10324fd401713effdd48e0484e5a56..135a78957014d38d52fc4a816611fded79d8e269 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_lif.c  --  R-Car VSP1 LCD Controller Interface
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 89b93af56fdc7e35e831b67f7fa89fc2a7c00c2a..7b35879028de0436b3b9a58e0e444ecdfcbd51ad 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_lif.h  --  R-Car VSP1 LCD Controller Interface
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index bce2be5466b9133df3afdf1495fe94f7438a532b..2b04d0f95c62e553a4d20c667678eeb3e67dc213 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_rpf.c  --  R-Car VSP1 Read Pixel Formatter
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 782f770daee5e58fb2757b1589c21d5c61375088..ec3dab6a9b9bc8e22093b5ac3b7f6c7ec338a326 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_rwpf.c  --  R-Car VSP1 Read and Write Pixel Formatters
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 6cbdb547470bb7f49e511e50afcd706a0acaaa72..5c5ee81bbeae6dd913b605f30c6be01b78f59111 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_rwpf.h  --  R-Car VSP1 Read and Write Pixel Formatters
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 0e50b37f060de8a6d9486c42df2158acc04aaea3..622342ac77700bb7d2d6f52944a627fd55a09e2c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_uds.c  --  R-Car VSP1 Up and Down Scaler
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 972a285abdb9e8cef877c719ee4fd91cfddeca02..479d12df118057df4edc10bf11e8d973894aacdb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_uds.h  --  R-Car VSP1 Up and Down Scaler
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index b4687a834f851c41412b6f9dc6c9e73569e3161d..b48f135ffc014e802d7b90e860f12285b9025c73 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_video.c  --  R-Car VSP1 Video Node
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -1051,7 +1051,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
        video->queue.buf_struct_size = sizeof(struct vsp1_video_buffer);
        video->queue.ops = &vsp1_video_queue_qops;
        video->queue.mem_ops = &vb2_dma_contig_memops;
-       video->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       video->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        ret = vb2_queue_init(&video->queue);
        if (ret < 0) {
                dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n");
index d8612a378345e27f540c47be9e49db51186f234b..53e4b374594015726af077a863ff0f0731b9cba0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_video.h  --  R-Car VSP1 Video Node
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 7baed81ff0051b7df9799aa47d9aa47f5dde4730..11a61c601da0cfa9e6702ed480ef19acc098b196 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * vsp1_wpf.c  --  R-Car VSP1 Write Pixel Formatter
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 545c04cf722623851977b535cff71eac3e79f22f..d719e59e21790a5ea4353ca4ea9cc28350cb155d 100644 (file)
@@ -270,6 +270,16 @@ reset_rds:
        outb(inb(dev->io + 1) & 0x7f, dev->io + 1);
 }
 
+static bool cadet_has_rds_data(struct cadet *dev)
+{
+       bool result;
+
+       mutex_lock(&dev->lock);
+       result = dev->rdsin != dev->rdsout;
+       mutex_unlock(&dev->lock);
+       return result;
+}
+
 
 static void cadet_handler(unsigned long data)
 {
@@ -279,13 +289,12 @@ static void cadet_handler(unsigned long data)
        if (mutex_trylock(&dev->lock)) {
                outb(0x3, dev->io);       /* Select RDS Decoder Control */
                if ((inb(dev->io + 1) & 0x20) != 0)
-                       printk(KERN_CRIT "cadet: RDS fifo overflow\n");
+                       pr_err("cadet: RDS fifo overflow\n");
                outb(0x80, dev->io);      /* Select RDS fifo */
+
                while ((inb(dev->io) & 0x80) != 0) {
                        dev->rdsbuf[dev->rdsin] = inb(dev->io + 1);
-                       if (dev->rdsin + 1 == dev->rdsout)
-                               printk(KERN_WARNING "cadet: RDS buffer overflow\n");
-                       else
+                       if (dev->rdsin + 1 != dev->rdsout)
                                dev->rdsin++;
                }
                mutex_unlock(&dev->lock);
@@ -294,7 +303,7 @@ static void cadet_handler(unsigned long data)
        /*
         * Service pending read
         */
-       if (dev->rdsin != dev->rdsout)
+       if (cadet_has_rds_data(dev))
                wake_up_interruptible(&dev->read_queue);
 
        /*
@@ -327,22 +336,21 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
        mutex_lock(&dev->lock);
        if (dev->rdsstat == 0)
                cadet_start_rds(dev);
-       if (dev->rdsin == dev->rdsout) {
-               if (file->f_flags & O_NONBLOCK) {
-                       i = -EWOULDBLOCK;
-                       goto unlock;
-               }
-               mutex_unlock(&dev->lock);
-               interruptible_sleep_on(&dev->read_queue);
-               mutex_lock(&dev->lock);
-       }
+       mutex_unlock(&dev->lock);
+
+       if (!cadet_has_rds_data(dev) && (file->f_flags & O_NONBLOCK))
+               return -EWOULDBLOCK;
+       i = wait_event_interruptible(dev->read_queue, cadet_has_rds_data(dev));
+       if (i)
+               return i;
+
+       mutex_lock(&dev->lock);
        while (i < count && dev->rdsin != dev->rdsout)
                readbuf[i++] = dev->rdsbuf[dev->rdsout++];
+       mutex_unlock(&dev->lock);
 
        if (i && copy_to_user(data, readbuf, i))
-               i = -EFAULT;
-unlock:
-       mutex_unlock(&dev->lock);
+               return -EFAULT;
        return i;
 }
 
@@ -352,7 +360,7 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        strlcpy(v->driver, "ADS Cadet", sizeof(v->driver));
        strlcpy(v->card, "ADS Cadet", sizeof(v->card));
-       strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
+       strlcpy(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;
@@ -491,7 +499,7 @@ static unsigned int cadet_poll(struct file *file, struct poll_table_struct *wait
                        cadet_start_rds(dev);
                mutex_unlock(&dev->lock);
        }
-       if (dev->rdsin != dev->rdsout)
+       if (cadet_has_rds_data(dev))
                res |= POLLIN | POLLRDNORM;
        return res;
 }
index fa3964022b96d939a3c222b90d81bd5bb2822255..3d127825eceb7a06d95938a031dcaea8d696162a 100644 (file)
@@ -416,22 +416,5 @@ static struct usb_driver usb_keene_driver = {
        .reset_resume           = usb_keene_resume,
 };
 
-static int __init keene_init(void)
-{
-       int retval = usb_register(&usb_keene_driver);
-
-       if (retval)
-               pr_err(KBUILD_MODNAME
-                       ": usb_register failed. Error number %d\n", retval);
-
-       return retval;
-}
-
-static void __exit keene_exit(void)
-{
-       usb_deregister(&usb_keene_driver);
-}
-
-module_init(keene_init);
-module_exit(keene_exit);
+module_usb_driver(usb_keene_driver);
 
index a7c3ba85d12b8875086ba9f405e802a381249298..9c8b887cff7501bc04ce77f76b42b6cafa805787 100644 (file)
@@ -1,7 +1,7 @@
 config USB_SI4713
        tristate "Silicon Labs Si4713 FM Radio Transmitter support with USB"
-       depends on USB && RADIO_SI4713
-       select SI4713
+       depends on USB && I2C && RADIO_SI4713
+       select I2C_SI4713
        ---help---
          This is a driver for USB devices with the Silicon Labs SI4713
          chip. Currently these devices are known to work.
@@ -16,7 +16,7 @@ config USB_SI4713
 config PLATFORM_SI4713
        tristate "Silicon Labs Si4713 FM Radio Transmitter support with I2C"
        depends on I2C && RADIO_SI4713
-       select SI4713
+       select I2C_SI4713
        ---help---
          This is a driver for I2C devices with the Silicon Labs SI4713
          chip.
index 779855b74bcdeea53b5370cf30338d0a9a1b79cd..86502b2786d06cd9abef8fcbe104fbde881439a3 100644 (file)
@@ -223,7 +223,7 @@ struct si4713_start_seq_table {
  * (0x03): Get serial number of the board (Response : CB000-00-00)
  * (0x06, 0x03, 0x03, 0x08, 0x01, 0x0f) : Get Component revision
  */
-static struct si4713_start_seq_table start_seq[] = {
+static const struct si4713_start_seq_table start_seq[] = {
 
        { 1, { 0x03 } },
        { 2, { 0x32, 0x7f } },
@@ -261,7 +261,7 @@ static int si4713_start_seq(struct si4713_usb_device *radio)
 
        for (i = 0; i < ARRAY_SIZE(start_seq); i++) {
                int len = start_seq[i].len;
-               u8 *payload = start_seq[i].payload;
+               const u8 *payload = start_seq[i].payload;
 
                memcpy(radio->buffer + 1, payload, len);
                memset(radio->buffer + len + 1, 0, BUFFER_LENGTH - 1 - len);
index 904f11367c2992fc502c4632c5d4a8617cbde839..8fbd377e6311460d77e32a962c8724b30b31d656 100644 (file)
@@ -106,6 +106,15 @@ config IR_SANYO_DECODER
           uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes),
           and you need software decoding support.
 
+config IR_SHARP_DECODER
+       tristate "Enable IR raw decoder for the Sharp protocol"
+       depends on RC_CORE
+       default y
+
+       ---help---
+          Enable this option if you have an infrared remote control which
+          uses the Sharp protocol, and you need software decoding support.
+
 config IR_MCE_KBD_DECODER
        tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol"
        depends on RC_CORE
@@ -300,6 +309,8 @@ config IR_RX51
           The driver uses omap DM timers for generating the carrier
           wave and pulses.
 
+source "drivers/media/rc/img-ir/Kconfig"
+
 config RC_LOOPBACK
        tristate "Remote Control Loopback Driver"
        depends on RC_CORE
index f4eb32c0a455e04058bdf52fb2158d1dbe7ac479..f8b54ff4660128503221325fdaddd2445f59e66f 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
 obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
 obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
 obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
+obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
 obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 
@@ -31,3 +32,4 @@ obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
 obj-$(CONFIG_IR_IGUANA) += iguanair.o
 obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
 obj-$(CONFIG_RC_ST) += st_rc.o
+obj-$(CONFIG_IR_IMG) += img-ir/
index 4d6a63fe6c5e210f878b132c6f6ea386e185fa66..2df7c5516013bd079d39bf5b248cf8270dbabaff 100644 (file)
@@ -784,7 +784,7 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote)
 
        rdev->priv = ati_remote;
        rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protos = RC_BIT_OTHER;
+       rc_set_allowed_protocols(rdev, RC_BIT_OTHER);
        rdev->driver_name = "ati_remote";
 
        rdev->open = ati_remote_rc_open;
index c1444f84717d725a7dd3e93048b6ff7a7b7e5831..fc9d23f2ed3f4c9922fd3ee57df56d47ee73a19f 100644 (file)
@@ -1059,7 +1059,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
                learning_mode_force = false;
 
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        rdev->priv = dev;
        rdev->open = ene_open;
        rdev->close = ene_close;
index d6fa441655d29de5945133c0e383cc4a29176c98..46b66e59438f51cc910f54ce8b659247a766cca5 100644 (file)
@@ -541,7 +541,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
        /* Set up the rc device */
        rdev->priv = fintek;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        rdev->open = fintek_open;
        rdev->close = fintek_close;
        rdev->input_name = FINTEK_DESCRIPTION;
index 80c611c2e8c28fabd83b0383d19670cf1cbe0faf..29b5f89813b4692a58e1dde5793bbef8902175a4 100644 (file)
@@ -145,9 +145,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
        rcdev->dev.parent = &pdev->dev;
        rcdev->driver_name = GPIO_IR_DRIVER_NAME;
        if (pdata->allowed_protos)
-               rcdev->allowed_protos = pdata->allowed_protos;
+               rc_set_allowed_protocols(rcdev, pdata->allowed_protos);
        else
-               rcdev->allowed_protos = RC_BIT_ALL;
+               rc_set_allowed_protocols(rcdev, RC_BIT_ALL);
        rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
 
        gpio_dev->rcdev = rcdev;
index fdae05c4f3775d7f54050c8776f0b882ac2fe630..627ddfd61980b5738219d8d1454784b53fdd6750 100644 (file)
@@ -286,10 +286,10 @@ static int iguanair_receiver(struct iguanair *ir, bool enable)
 }
 
 /*
- * The iguana ir creates the carrier by busy spinning after each pulse or
- * space. This is counted in CPU cycles, with the CPU running at 24MHz. It is
+ * The iguanair creates the carrier by busy spinning after each half period.
+ * This is counted in CPU cycles, with the CPU running at 24MHz. It is
  * broken down into 7-cycles and 4-cyles delays, with a preference for
- * 4-cycle delays.
+ * 4-cycle delays, minus the overhead of the loop itself (cycle_overhead).
  */
 static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier)
 {
@@ -316,7 +316,14 @@ static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier)
                sevens = (4 - cycles) & 3;
                fours = (cycles - sevens * 7) / 4;
 
-               /* magic happens here */
+               /*
+                * The firmware interprets these values as a relative offset
+                * for a branch. Immediately following the branches, there
+                * 4 instructions of 7 cycles (2 bytes each) and 110
+                * instructions of 4 cycles (1 byte each). A relative branch
+                * of 0 will execute all of them, branch further for less
+                * cycle burning.
+                */
                ir->packet->busy7 = (4 - sevens) * 2;
                ir->packet->busy4 = 110 - fours;
        }
@@ -357,20 +364,14 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
                        rc = -EINVAL;
                        goto out;
                }
-               while (periods > 127) {
-                       ir->packet->payload[size++] = 127 | space;
-                       periods -= 127;
+               while (periods) {
+                       unsigned p = min(periods, 127u);
+                       ir->packet->payload[size++] = p | space;
+                       periods -= p;
                }
-
-               ir->packet->payload[size++] = periods | space;
                space ^= 0x80;
        }
 
-       if (count == 0) {
-               rc = -EINVAL;
-               goto out;
-       }
-
        ir->packet->header.start = 0;
        ir->packet->header.direction = DIR_OUT;
        ir->packet->header.cmd = CMD_SEND;
@@ -494,7 +495,7 @@ static int iguanair_probe(struct usb_interface *intf,
        usb_to_input_id(ir->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rc, RC_BIT_ALL);
        rc->priv = ir;
        rc->open = iguanair_open;
        rc->close = iguanair_close;
diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig
new file mode 100644 (file)
index 0000000..03ba9fc
--- /dev/null
@@ -0,0 +1,61 @@
+config IR_IMG
+       tristate "ImgTec IR Decoder"
+       depends on RC_CORE
+       select IR_IMG_HW if !IR_IMG_RAW
+       help
+          Say Y or M here if you want to use the ImgTec infrared decoder
+          functionality found in SoCs such as TZ1090.
+
+config IR_IMG_RAW
+       bool "Raw decoder"
+       depends on IR_IMG
+       help
+          Say Y here to enable the raw mode driver which passes raw IR signal
+          changes to the IR raw decoders for software decoding. This is much
+          less reliable (due to lack of timestamps) and consumes more
+          processing power than using hardware decode, but can be useful for
+          testing, debug, and to make more protocols available.
+
+config IR_IMG_HW
+       bool "Hardware decoder"
+       depends on IR_IMG
+       help
+          Say Y here to enable the hardware decode driver which decodes the IR
+          signals in hardware. This is more reliable, consumes less processing
+          power since only a single interrupt is received for each scancode,
+          and allows an IR scancode to be used as a wake event.
+
+config IR_IMG_NEC
+       bool "NEC protocol support"
+       depends on IR_IMG_HW
+       help
+          Say Y here to enable support for the NEC, extended NEC, and 32-bit
+          NEC protocols in the ImgTec infrared decoder block.
+
+config IR_IMG_JVC
+       bool "JVC protocol support"
+       depends on IR_IMG_HW
+       help
+          Say Y here to enable support for the JVC protocol in the ImgTec
+          infrared decoder block.
+
+config IR_IMG_SONY
+       bool "Sony protocol support"
+       depends on IR_IMG_HW
+       help
+          Say Y here to enable support for the Sony protocol in the ImgTec
+          infrared decoder block.
+
+config IR_IMG_SHARP
+       bool "Sharp protocol support"
+       depends on IR_IMG_HW
+       help
+          Say Y here to enable support for the Sharp protocol in the ImgTec
+          infrared decoder block.
+
+config IR_IMG_SANYO
+       bool "Sanyo protocol support"
+       depends on IR_IMG_HW
+       help
+          Say Y here to enable support for the Sanyo protocol (used by Sanyo,
+          Aiwa, Chinon remotes) in the ImgTec infrared decoder block.
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile
new file mode 100644 (file)
index 0000000..92a459d
--- /dev/null
@@ -0,0 +1,11 @@
+img-ir-y                       := img-ir-core.o
+img-ir-$(CONFIG_IR_IMG_RAW)    += img-ir-raw.o
+img-ir-$(CONFIG_IR_IMG_HW)     += img-ir-hw.o
+img-ir-$(CONFIG_IR_IMG_NEC)    += img-ir-nec.o
+img-ir-$(CONFIG_IR_IMG_JVC)    += img-ir-jvc.o
+img-ir-$(CONFIG_IR_IMG_SONY)   += img-ir-sony.o
+img-ir-$(CONFIG_IR_IMG_SHARP)  += img-ir-sharp.o
+img-ir-$(CONFIG_IR_IMG_SANYO)  += img-ir-sanyo.o
+img-ir-objs                    := $(img-ir-y)
+
+obj-$(CONFIG_IR_IMG)           += img-ir.o
diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c
new file mode 100644 (file)
index 0000000..6b78348
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * ImgTec IR Decoder found in PowerDown Controller.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * This contains core img-ir code for setting up the driver. The two interfaces
+ * (raw and hardware decode) are handled separately.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "img-ir.h"
+
+static irqreturn_t img_ir_isr(int irq, void *dev_id)
+{
+       struct img_ir_priv *priv = dev_id;
+       u32 irq_status;
+
+       spin_lock(&priv->lock);
+       /* we have to clear irqs before reading */
+       irq_status = img_ir_read(priv, IMG_IR_IRQ_STATUS);
+       img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_status);
+
+       /* don't handle valid data irqs if we're only interested in matches */
+       irq_status &= img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+
+       /* hand off edge interrupts to raw decode handler */
+       if (irq_status & IMG_IR_IRQ_EDGE && img_ir_raw_enabled(&priv->raw))
+               img_ir_isr_raw(priv, irq_status);
+
+       /* hand off hardware match interrupts to hardware decode handler */
+       if (irq_status & (IMG_IR_IRQ_DATA_MATCH |
+                         IMG_IR_IRQ_DATA_VALID |
+                         IMG_IR_IRQ_DATA2_VALID) &&
+           img_ir_hw_enabled(&priv->hw))
+               img_ir_isr_hw(priv, irq_status);
+
+       spin_unlock(&priv->lock);
+       return IRQ_HANDLED;
+}
+
+static void img_ir_setup(struct img_ir_priv *priv)
+{
+       /* start off with interrupts disabled */
+       img_ir_write(priv, IMG_IR_IRQ_ENABLE, 0);
+
+       img_ir_setup_raw(priv);
+       img_ir_setup_hw(priv);
+
+       if (!IS_ERR(priv->clk))
+               clk_prepare_enable(priv->clk);
+}
+
+static void img_ir_ident(struct img_ir_priv *priv)
+{
+       u32 core_rev = img_ir_read(priv, IMG_IR_CORE_REV);
+
+       dev_info(priv->dev,
+                "IMG IR Decoder (%d.%d.%d.%d) probed successfully\n",
+                (core_rev & IMG_IR_DESIGNER) >> IMG_IR_DESIGNER_SHIFT,
+                (core_rev & IMG_IR_MAJOR_REV) >> IMG_IR_MAJOR_REV_SHIFT,
+                (core_rev & IMG_IR_MINOR_REV) >> IMG_IR_MINOR_REV_SHIFT,
+                (core_rev & IMG_IR_MAINT_REV) >> IMG_IR_MAINT_REV_SHIFT);
+       dev_info(priv->dev, "Modes:%s%s\n",
+                img_ir_hw_enabled(&priv->hw) ? " hardware" : "",
+                img_ir_raw_enabled(&priv->raw) ? " raw" : "");
+}
+
+static int img_ir_probe(struct platform_device *pdev)
+{
+       struct img_ir_priv *priv;
+       struct resource *res_regs;
+       int irq, error, error2;
+
+       /* Get resources from platform device */
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "cannot find IRQ resource\n");
+               return irq;
+       }
+
+       /* Private driver data */
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(&pdev->dev, "cannot allocate device data\n");
+               return -ENOMEM;
+       }
+       platform_set_drvdata(pdev, priv);
+       priv->dev = &pdev->dev;
+       spin_lock_init(&priv->lock);
+
+       /* Ioremap the registers */
+       res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->reg_base = devm_ioremap_resource(&pdev->dev, res_regs);
+       if (IS_ERR(priv->reg_base))
+               return PTR_ERR(priv->reg_base);
+
+       /* Get core clock */
+       priv->clk = devm_clk_get(&pdev->dev, "core");
+       if (IS_ERR(priv->clk))
+               dev_warn(&pdev->dev, "cannot get core clock resource\n");
+       /*
+        * The driver doesn't need to know about the system ("sys") or power
+        * modulation ("mod") clocks yet
+        */
+
+       /* Set up raw & hw decoder */
+       error = img_ir_probe_raw(priv);
+       error2 = img_ir_probe_hw(priv);
+       if (error && error2)
+               return (error == -ENODEV) ? error2 : error;
+
+       /* Get the IRQ */
+       priv->irq = irq;
+       error = request_irq(priv->irq, img_ir_isr, 0, "img-ir", priv);
+       if (error) {
+               dev_err(&pdev->dev, "cannot register IRQ %u\n",
+                       priv->irq);
+               error = -EIO;
+               goto err_irq;
+       }
+
+       img_ir_ident(priv);
+       img_ir_setup(priv);
+
+       return 0;
+
+err_irq:
+       img_ir_remove_hw(priv);
+       img_ir_remove_raw(priv);
+       return error;
+}
+
+static int img_ir_remove(struct platform_device *pdev)
+{
+       struct img_ir_priv *priv = platform_get_drvdata(pdev);
+
+       free_irq(priv->irq, img_ir_isr);
+       img_ir_remove_hw(priv);
+       img_ir_remove_raw(priv);
+
+       if (!IS_ERR(priv->clk))
+               clk_disable_unprepare(priv->clk);
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(img_ir_pmops, img_ir_suspend, img_ir_resume);
+
+static const struct of_device_id img_ir_match[] = {
+       { .compatible = "img,ir-rev1" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, img_ir_match);
+
+static struct platform_driver img_ir_driver = {
+       .driver = {
+               .name = "img-ir",
+               .owner  = THIS_MODULE,
+               .of_match_table = img_ir_match,
+               .pm = &img_ir_pmops,
+       },
+       .probe = img_ir_probe,
+       .remove = img_ir_remove,
+};
+
+module_platform_driver(img_ir_driver);
+
+MODULE_AUTHOR("Imagination Technologies Ltd.");
+MODULE_DESCRIPTION("ImgTec IR");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
new file mode 100644 (file)
index 0000000..579a52b
--- /dev/null
@@ -0,0 +1,1053 @@
+/*
+ * ImgTec IR Hardware Decoder found in PowerDown Controller.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * This ties into the input subsystem using the RC-core. Protocol support is
+ * provided in separate modules which provide the parameters and scancode
+ * translation functions to set up the hardware decoder and interpret the
+ * resulting input.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <media/rc-core.h>
+#include "img-ir.h"
+
+/* Decoders lock (only modified to preprocess them) */
+static DEFINE_SPINLOCK(img_ir_decoders_lock);
+
+extern struct img_ir_decoder img_ir_nec;
+extern struct img_ir_decoder img_ir_jvc;
+extern struct img_ir_decoder img_ir_sony;
+extern struct img_ir_decoder img_ir_sharp;
+extern struct img_ir_decoder img_ir_sanyo;
+
+static bool img_ir_decoders_preprocessed;
+static struct img_ir_decoder *img_ir_decoders[] = {
+#ifdef CONFIG_IR_IMG_NEC
+       &img_ir_nec,
+#endif
+#ifdef CONFIG_IR_IMG_JVC
+       &img_ir_jvc,
+#endif
+#ifdef CONFIG_IR_IMG_SONY
+       &img_ir_sony,
+#endif
+#ifdef CONFIG_IR_IMG_SHARP
+       &img_ir_sharp,
+#endif
+#ifdef CONFIG_IR_IMG_SANYO
+       &img_ir_sanyo,
+#endif
+       NULL
+};
+
+#define IMG_IR_F_FILTER                BIT(RC_FILTER_NORMAL)   /* enable filtering */
+#define IMG_IR_F_WAKE          BIT(RC_FILTER_WAKEUP)   /* enable waking */
+
+/* code type quirks */
+
+#define IMG_IR_QUIRK_CODE_BROKEN       0x1     /* Decode is broken */
+#define IMG_IR_QUIRK_CODE_LEN_INCR     0x2     /* Bit length needs increment */
+
+/* functions for preprocessing timings, ensuring max is set */
+
+static void img_ir_timing_preprocess(struct img_ir_timing_range *range,
+                                    unsigned int unit)
+{
+       if (range->max < range->min)
+               range->max = range->min;
+       if (unit) {
+               /* multiply by unit and convert to microseconds */
+               range->min = (range->min*unit)/1000;
+               range->max = (range->max*unit + 999)/1000; /* round up */
+       }
+}
+
+static void img_ir_symbol_timing_preprocess(struct img_ir_symbol_timing *timing,
+                                           unsigned int unit)
+{
+       img_ir_timing_preprocess(&timing->pulse, unit);
+       img_ir_timing_preprocess(&timing->space, unit);
+}
+
+static void img_ir_timings_preprocess(struct img_ir_timings *timings,
+                                     unsigned int unit)
+{
+       img_ir_symbol_timing_preprocess(&timings->ldr, unit);
+       img_ir_symbol_timing_preprocess(&timings->s00, unit);
+       img_ir_symbol_timing_preprocess(&timings->s01, unit);
+       img_ir_symbol_timing_preprocess(&timings->s10, unit);
+       img_ir_symbol_timing_preprocess(&timings->s11, unit);
+       /* default s10 and s11 to s00 and s01 if no leader */
+       if (unit)
+               /* multiply by unit and convert to microseconds (round up) */
+               timings->ft.ft_min = (timings->ft.ft_min*unit + 999)/1000;
+}
+
+/* functions for filling empty fields with defaults */
+
+static void img_ir_timing_defaults(struct img_ir_timing_range *range,
+                                  struct img_ir_timing_range *defaults)
+{
+       if (!range->min)
+               range->min = defaults->min;
+       if (!range->max)
+               range->max = defaults->max;
+}
+
+static void img_ir_symbol_timing_defaults(struct img_ir_symbol_timing *timing,
+                                         struct img_ir_symbol_timing *defaults)
+{
+       img_ir_timing_defaults(&timing->pulse, &defaults->pulse);
+       img_ir_timing_defaults(&timing->space, &defaults->space);
+}
+
+static void img_ir_timings_defaults(struct img_ir_timings *timings,
+                                   struct img_ir_timings *defaults)
+{
+       img_ir_symbol_timing_defaults(&timings->ldr, &defaults->ldr);
+       img_ir_symbol_timing_defaults(&timings->s00, &defaults->s00);
+       img_ir_symbol_timing_defaults(&timings->s01, &defaults->s01);
+       img_ir_symbol_timing_defaults(&timings->s10, &defaults->s10);
+       img_ir_symbol_timing_defaults(&timings->s11, &defaults->s11);
+       if (!timings->ft.ft_min)
+               timings->ft.ft_min = defaults->ft.ft_min;
+}
+
+/* functions for converting timings to register values */
+
+/**
+ * img_ir_control() - Convert control struct to control register value.
+ * @control:   Control data
+ *
+ * Returns:    The control register value equivalent of @control.
+ */
+static u32 img_ir_control(const struct img_ir_control *control)
+{
+       u32 ctrl = control->code_type << IMG_IR_CODETYPE_SHIFT;
+       if (control->decoden)
+               ctrl |= IMG_IR_DECODEN;
+       if (control->hdrtog)
+               ctrl |= IMG_IR_HDRTOG;
+       if (control->ldrdec)
+               ctrl |= IMG_IR_LDRDEC;
+       if (control->decodinpol)
+               ctrl |= IMG_IR_DECODINPOL;
+       if (control->bitorien)
+               ctrl |= IMG_IR_BITORIEN;
+       if (control->d1validsel)
+               ctrl |= IMG_IR_D1VALIDSEL;
+       if (control->bitinv)
+               ctrl |= IMG_IR_BITINV;
+       if (control->decodend2)
+               ctrl |= IMG_IR_DECODEND2;
+       if (control->bitoriend2)
+               ctrl |= IMG_IR_BITORIEND2;
+       if (control->bitinvd2)
+               ctrl |= IMG_IR_BITINVD2;
+       return ctrl;
+}
+
+/**
+ * img_ir_timing_range_convert() - Convert microsecond range.
+ * @out:       Output timing range in clock cycles with a shift.
+ * @in:                Input timing range in microseconds.
+ * @tolerance: Tolerance as a fraction of 128 (roughly percent).
+ * @clock_hz:  IR clock rate in Hz.
+ * @shift:     Shift of output units.
+ *
+ * Converts min and max from microseconds to IR clock cycles, applies a
+ * tolerance, and shifts for the register, rounding in the right direction.
+ * Note that in and out can safely be the same object.
+ */
+static void img_ir_timing_range_convert(struct img_ir_timing_range *out,
+                                       const struct img_ir_timing_range *in,
+                                       unsigned int tolerance,
+                                       unsigned long clock_hz,
+                                       unsigned int shift)
+{
+       unsigned int min = in->min;
+       unsigned int max = in->max;
+       /* add a tolerance */
+       min = min - (min*tolerance >> 7);
+       max = max + (max*tolerance >> 7);
+       /* convert from microseconds into clock cycles */
+       min = min*clock_hz / 1000000;
+       max = (max*clock_hz + 999999) / 1000000; /* round up */
+       /* apply shift and copy to output */
+       out->min = min >> shift;
+       out->max = (max + ((1 << shift) - 1)) >> shift; /* round up */
+}
+
+/**
+ * img_ir_symbol_timing() - Convert symbol timing struct to register value.
+ * @timing:    Symbol timing data
+ * @tolerance: Timing tolerance where 0-128 represents 0-100%
+ * @clock_hz:  Frequency of source clock in Hz
+ * @pd_shift:  Shift to apply to symbol period
+ * @w_shift:   Shift to apply to symbol width
+ *
+ * Returns:    Symbol timing register value based on arguments.
+ */
+static u32 img_ir_symbol_timing(const struct img_ir_symbol_timing *timing,
+                               unsigned int tolerance,
+                               unsigned long clock_hz,
+                               unsigned int pd_shift,
+                               unsigned int w_shift)
+{
+       struct img_ir_timing_range hw_pulse, hw_period;
+       /* we calculate period in hw_period, then convert in place */
+       hw_period.min = timing->pulse.min + timing->space.min;
+       hw_period.max = timing->pulse.max + timing->space.max;
+       img_ir_timing_range_convert(&hw_period, &hw_period,
+                       tolerance, clock_hz, pd_shift);
+       img_ir_timing_range_convert(&hw_pulse, &timing->pulse,
+                       tolerance, clock_hz, w_shift);
+       /* construct register value */
+       return  (hw_period.max  << IMG_IR_PD_MAX_SHIFT) |
+               (hw_period.min  << IMG_IR_PD_MIN_SHIFT) |
+               (hw_pulse.max   << IMG_IR_W_MAX_SHIFT)  |
+               (hw_pulse.min   << IMG_IR_W_MIN_SHIFT);
+}
+
+/**
+ * img_ir_free_timing() - Convert free time timing struct to register value.
+ * @timing:    Free symbol timing data
+ * @clock_hz:  Source clock frequency in Hz
+ *
+ * Returns:    Free symbol timing register value.
+ */
+static u32 img_ir_free_timing(const struct img_ir_free_timing *timing,
+                             unsigned long clock_hz)
+{
+       unsigned int minlen, maxlen, ft_min;
+       /* minlen is only 5 bits, and round minlen to multiple of 2 */
+       if (timing->minlen < 30)
+               minlen = timing->minlen & -2;
+       else
+               minlen = 30;
+       /* maxlen has maximum value of 48, and round maxlen to multiple of 2 */
+       if (timing->maxlen < 48)
+               maxlen = (timing->maxlen + 1) & -2;
+       else
+               maxlen = 48;
+       /* convert and shift ft_min, rounding upwards */
+       ft_min = (timing->ft_min*clock_hz + 999999) / 1000000;
+       ft_min = (ft_min + 7) >> 3;
+       /* construct register value */
+       return  (maxlen << IMG_IR_MAXLEN_SHIFT) |
+               (minlen << IMG_IR_MINLEN_SHIFT) |
+               (ft_min << IMG_IR_FT_MIN_SHIFT);
+}
+
+/**
+ * img_ir_free_timing_dynamic() - Update free time register value.
+ * @st_ft:     Static free time register value from img_ir_free_timing.
+ * @filter:    Current filter which may additionally restrict min/max len.
+ *
+ * Returns:    Updated free time register value based on the current filter.
+ */
+static u32 img_ir_free_timing_dynamic(u32 st_ft, struct img_ir_filter *filter)
+{
+       unsigned int minlen, maxlen, newminlen, newmaxlen;
+
+       /* round minlen, maxlen to multiple of 2 */
+       newminlen = filter->minlen & -2;
+       newmaxlen = (filter->maxlen + 1) & -2;
+       /* extract min/max len from register */
+       minlen = (st_ft & IMG_IR_MINLEN) >> IMG_IR_MINLEN_SHIFT;
+       maxlen = (st_ft & IMG_IR_MAXLEN) >> IMG_IR_MAXLEN_SHIFT;
+       /* if the new values are more restrictive, update the register value */
+       if (newminlen > minlen) {
+               st_ft &= ~IMG_IR_MINLEN;
+               st_ft |= newminlen << IMG_IR_MINLEN_SHIFT;
+       }
+       if (newmaxlen < maxlen) {
+               st_ft &= ~IMG_IR_MAXLEN;
+               st_ft |= newmaxlen << IMG_IR_MAXLEN_SHIFT;
+       }
+       return st_ft;
+}
+
+/**
+ * img_ir_timings_convert() - Convert timings to register values
+ * @regs:      Output timing register values
+ * @timings:   Input timing data
+ * @tolerance: Timing tolerance where 0-128 represents 0-100%
+ * @clock_hz:  Source clock frequency in Hz
+ */
+static void img_ir_timings_convert(struct img_ir_timing_regvals *regs,
+                                  const struct img_ir_timings *timings,
+                                  unsigned int tolerance,
+                                  unsigned int clock_hz)
+{
+       /* leader symbol timings are divided by 16 */
+       regs->ldr = img_ir_symbol_timing(&timings->ldr, tolerance, clock_hz,
+                       4, 4);
+       /* other symbol timings, pd fields only are divided by 2 */
+       regs->s00 = img_ir_symbol_timing(&timings->s00, tolerance, clock_hz,
+                       1, 0);
+       regs->s01 = img_ir_symbol_timing(&timings->s01, tolerance, clock_hz,
+                       1, 0);
+       regs->s10 = img_ir_symbol_timing(&timings->s10, tolerance, clock_hz,
+                       1, 0);
+       regs->s11 = img_ir_symbol_timing(&timings->s11, tolerance, clock_hz,
+                       1, 0);
+       regs->ft = img_ir_free_timing(&timings->ft, clock_hz);
+}
+
+/**
+ * img_ir_decoder_preprocess() - Preprocess timings in decoder.
+ * @decoder:   Decoder to be preprocessed.
+ *
+ * Ensures that the symbol timing ranges are valid with respect to ordering, and
+ * does some fixed conversion on them.
+ */
+static void img_ir_decoder_preprocess(struct img_ir_decoder *decoder)
+{
+       /* default tolerance */
+       if (!decoder->tolerance)
+               decoder->tolerance = 10; /* percent */
+       /* and convert tolerance to fraction out of 128 */
+       decoder->tolerance = decoder->tolerance * 128 / 100;
+
+       /* fill in implicit fields */
+       img_ir_timings_preprocess(&decoder->timings, decoder->unit);
+
+       /* do the same for repeat timings if applicable */
+       if (decoder->repeat) {
+               img_ir_timings_preprocess(&decoder->rtimings, decoder->unit);
+               img_ir_timings_defaults(&decoder->rtimings, &decoder->timings);
+       }
+}
+
+/**
+ * img_ir_decoder_convert() - Generate internal timings in decoder.
+ * @decoder:   Decoder to be converted to internal timings.
+ * @timings:   Timing register values.
+ * @clock_hz:  IR clock rate in Hz.
+ *
+ * Fills out the repeat timings and timing register values for a specific clock
+ * rate.
+ */
+static void img_ir_decoder_convert(const struct img_ir_decoder *decoder,
+                                  struct img_ir_reg_timings *reg_timings,
+                                  unsigned int clock_hz)
+{
+       /* calculate control value */
+       reg_timings->ctrl = img_ir_control(&decoder->control);
+
+       /* fill in implicit fields and calculate register values */
+       img_ir_timings_convert(&reg_timings->timings, &decoder->timings,
+                              decoder->tolerance, clock_hz);
+
+       /* do the same for repeat timings if applicable */
+       if (decoder->repeat)
+               img_ir_timings_convert(&reg_timings->rtimings,
+                                      &decoder->rtimings, decoder->tolerance,
+                                      clock_hz);
+}
+
+/**
+ * img_ir_write_timings() - Write timings to the hardware now
+ * @priv:      IR private data
+ * @regs:      Timing register values to write
+ * @type:      RC filter type (RC_FILTER_*)
+ *
+ * Write timing register values @regs to the hardware, taking into account the
+ * current filter which may impose restrictions on the length of the expected
+ * data.
+ */
+static void img_ir_write_timings(struct img_ir_priv *priv,
+                                struct img_ir_timing_regvals *regs,
+                                enum rc_filter_type type)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+
+       /* filter may be more restrictive to minlen, maxlen */
+       u32 ft = regs->ft;
+       if (hw->flags & BIT(type))
+               ft = img_ir_free_timing_dynamic(regs->ft, &hw->filters[type]);
+       /* write to registers */
+       img_ir_write(priv, IMG_IR_LEAD_SYMB_TIMING, regs->ldr);
+       img_ir_write(priv, IMG_IR_S00_SYMB_TIMING, regs->s00);
+       img_ir_write(priv, IMG_IR_S01_SYMB_TIMING, regs->s01);
+       img_ir_write(priv, IMG_IR_S10_SYMB_TIMING, regs->s10);
+       img_ir_write(priv, IMG_IR_S11_SYMB_TIMING, regs->s11);
+       img_ir_write(priv, IMG_IR_FREE_SYMB_TIMING, ft);
+       dev_dbg(priv->dev, "timings: ldr=%#x, s=[%#x, %#x, %#x, %#x], ft=%#x\n",
+               regs->ldr, regs->s00, regs->s01, regs->s10, regs->s11, ft);
+}
+
+static void img_ir_write_filter(struct img_ir_priv *priv,
+                               struct img_ir_filter *filter)
+{
+       if (filter) {
+               dev_dbg(priv->dev, "IR filter=%016llx & %016llx\n",
+                       (unsigned long long)filter->data,
+                       (unsigned long long)filter->mask);
+               img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_LW, (u32)filter->data);
+               img_ir_write(priv, IMG_IR_IRQ_MSG_DATA_UP, (u32)(filter->data
+                                                                       >> 32));
+               img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, (u32)filter->mask);
+               img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, (u32)(filter->mask
+                                                                       >> 32));
+       } else {
+               dev_dbg(priv->dev, "IR clearing filter\n");
+               img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_LW, 0);
+               img_ir_write(priv, IMG_IR_IRQ_MSG_MASK_UP, 0);
+       }
+}
+
+/* caller must have lock */
+static void _img_ir_set_filter(struct img_ir_priv *priv,
+                              struct img_ir_filter *filter)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       u32 irq_en, irq_on;
+
+       irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+       if (filter) {
+               /* Only use the match interrupt */
+               hw->filters[RC_FILTER_NORMAL] = *filter;
+               hw->flags |= IMG_IR_F_FILTER;
+               irq_on = IMG_IR_IRQ_DATA_MATCH;
+               irq_en &= ~(IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID);
+       } else {
+               /* Only use the valid interrupt */
+               hw->flags &= ~IMG_IR_F_FILTER;
+               irq_en &= ~IMG_IR_IRQ_DATA_MATCH;
+               irq_on = IMG_IR_IRQ_DATA_VALID | IMG_IR_IRQ_DATA2_VALID;
+       }
+       irq_en |= irq_on;
+
+       img_ir_write_filter(priv, filter);
+       /* clear any interrupts we're enabling so we don't handle old ones */
+       img_ir_write(priv, IMG_IR_IRQ_CLEAR, irq_on);
+       img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
+}
+
+/* caller must have lock */
+static void _img_ir_set_wake_filter(struct img_ir_priv *priv,
+                                   struct img_ir_filter *filter)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       if (filter) {
+               /* Enable wake, and copy filter for later */
+               hw->filters[RC_FILTER_WAKEUP] = *filter;
+               hw->flags |= IMG_IR_F_WAKE;
+       } else {
+               /* Disable wake */
+               hw->flags &= ~IMG_IR_F_WAKE;
+       }
+}
+
+/* Callback for setting scancode filter */
+static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type,
+                            struct rc_scancode_filter *sc_filter)
+{
+       struct img_ir_priv *priv = dev->priv;
+       struct img_ir_priv_hw *hw = &priv->hw;
+       struct img_ir_filter filter, *filter_ptr = &filter;
+       int ret = 0;
+
+       dev_dbg(priv->dev, "IR scancode %sfilter=%08x & %08x\n",
+               type == RC_FILTER_WAKEUP ? "wake " : "",
+               sc_filter->data,
+               sc_filter->mask);
+
+       spin_lock_irq(&priv->lock);
+
+       /* filtering can always be disabled */
+       if (!sc_filter->mask) {
+               filter_ptr = NULL;
+               goto set_unlock;
+       }
+
+       /* current decoder must support scancode filtering */
+       if (!hw->decoder || !hw->decoder->filter) {
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+       /* convert scancode filter to raw filter */
+       filter.minlen = 0;
+       filter.maxlen = ~0;
+       ret = hw->decoder->filter(sc_filter, &filter, hw->enabled_protocols);
+       if (ret)
+               goto unlock;
+       dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n",
+               type == RC_FILTER_WAKEUP ? "wake " : "",
+               (unsigned long long)filter.data,
+               (unsigned long long)filter.mask);
+
+set_unlock:
+       /* apply raw filters */
+       switch (type) {
+       case RC_FILTER_NORMAL:
+               _img_ir_set_filter(priv, filter_ptr);
+               break;
+       case RC_FILTER_WAKEUP:
+               _img_ir_set_wake_filter(priv, filter_ptr);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+unlock:
+       spin_unlock_irq(&priv->lock);
+       return ret;
+}
+
+/**
+ * img_ir_set_decoder() - Set the current decoder.
+ * @priv:      IR private data.
+ * @decoder:   Decoder to use with immediate effect.
+ * @proto:     Protocol bitmap (or 0 to use decoder->type).
+ */
+static void img_ir_set_decoder(struct img_ir_priv *priv,
+                              const struct img_ir_decoder *decoder,
+                              u64 proto)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       struct rc_dev *rdev = hw->rdev;
+       u32 ir_status, irq_en;
+       spin_lock_irq(&priv->lock);
+
+       /* switch off and disable interrupts */
+       img_ir_write(priv, IMG_IR_CONTROL, 0);
+       irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+       img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en & IMG_IR_IRQ_EDGE);
+       img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_ALL & ~IMG_IR_IRQ_EDGE);
+
+       /* ack any data already detected */
+       ir_status = img_ir_read(priv, IMG_IR_STATUS);
+       if (ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)) {
+               ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
+               img_ir_write(priv, IMG_IR_STATUS, ir_status);
+               img_ir_read(priv, IMG_IR_DATA_LW);
+               img_ir_read(priv, IMG_IR_DATA_UP);
+       }
+
+       /* stop the end timer and switch back to normal mode */
+       del_timer_sync(&hw->end_timer);
+       hw->mode = IMG_IR_M_NORMAL;
+
+       /* clear the wakeup scancode filter */
+       rdev->scancode_filters[RC_FILTER_WAKEUP].data = 0;
+       rdev->scancode_filters[RC_FILTER_WAKEUP].mask = 0;
+
+       /* clear raw filters */
+       _img_ir_set_filter(priv, NULL);
+       _img_ir_set_wake_filter(priv, NULL);
+
+       /* clear the enabled protocols */
+       hw->enabled_protocols = 0;
+
+       /* switch decoder */
+       hw->decoder = decoder;
+       if (!decoder)
+               goto unlock;
+
+       /* set the enabled protocols */
+       if (!proto)
+               proto = decoder->type;
+       hw->enabled_protocols = proto;
+
+       /* write the new timings */
+       img_ir_decoder_convert(decoder, &hw->reg_timings, hw->clk_hz);
+       img_ir_write_timings(priv, &hw->reg_timings.timings, RC_FILTER_NORMAL);
+
+       /* set up and enable */
+       img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
+
+
+unlock:
+       spin_unlock_irq(&priv->lock);
+}
+
+/**
+ * img_ir_decoder_compatable() - Find whether a decoder will work with a device.
+ * @priv:      IR private data.
+ * @dec:       Decoder to check.
+ *
+ * Returns:    true if @dec is compatible with the device @priv refers to.
+ */
+static bool img_ir_decoder_compatible(struct img_ir_priv *priv,
+                                     const struct img_ir_decoder *dec)
+{
+       unsigned int ct;
+
+       /* don't accept decoders using code types which aren't supported */
+       ct = dec->control.code_type;
+       if (priv->hw.ct_quirks[ct] & IMG_IR_QUIRK_CODE_BROKEN)
+               return false;
+
+       return true;
+}
+
+/**
+ * img_ir_allowed_protos() - Get allowed protocols from global decoder list.
+ * @priv:      IR private data.
+ *
+ * Returns:    Mask of protocols supported by the device @priv refers to.
+ */
+static u64 img_ir_allowed_protos(struct img_ir_priv *priv)
+{
+       u64 protos = 0;
+       struct img_ir_decoder **decp;
+
+       for (decp = img_ir_decoders; *decp; ++decp) {
+               const struct img_ir_decoder *dec = *decp;
+               if (img_ir_decoder_compatible(priv, dec))
+                       protos |= dec->type;
+       }
+       return protos;
+}
+
+/* Callback for changing protocol using sysfs */
+static int img_ir_change_protocol(struct rc_dev *dev, u64 *ir_type)
+{
+       struct img_ir_priv *priv = dev->priv;
+       struct img_ir_priv_hw *hw = &priv->hw;
+       struct rc_dev *rdev = hw->rdev;
+       struct img_ir_decoder **decp;
+       u64 wakeup_protocols;
+
+       if (!*ir_type) {
+               /* disable all protocols */
+               img_ir_set_decoder(priv, NULL, 0);
+               goto success;
+       }
+       for (decp = img_ir_decoders; *decp; ++decp) {
+               const struct img_ir_decoder *dec = *decp;
+               if (!img_ir_decoder_compatible(priv, dec))
+                       continue;
+               if (*ir_type & dec->type) {
+                       *ir_type &= dec->type;
+                       img_ir_set_decoder(priv, dec, *ir_type);
+                       goto success;
+               }
+       }
+       return -EINVAL;
+
+success:
+       /*
+        * Only allow matching wakeup protocols for now, and only if filtering
+        * is supported.
+        */
+       wakeup_protocols = *ir_type;
+       if (!hw->decoder || !hw->decoder->filter)
+               wakeup_protocols = 0;
+       rc_set_allowed_wakeup_protocols(rdev, wakeup_protocols);
+       rc_set_enabled_wakeup_protocols(rdev, wakeup_protocols);
+       return 0;
+}
+
+/* Changes ir-core protocol device attribute */
+static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto)
+{
+       struct rc_dev *rdev = priv->hw.rdev;
+
+       spin_lock_irq(&rdev->rc_map.lock);
+       rdev->rc_map.rc_type = __ffs64(proto);
+       spin_unlock_irq(&rdev->rc_map.lock);
+
+       mutex_lock(&rdev->lock);
+       rc_set_enabled_protocols(rdev, proto);
+       rc_set_allowed_wakeup_protocols(rdev, proto);
+       rc_set_enabled_wakeup_protocols(rdev, proto);
+       mutex_unlock(&rdev->lock);
+}
+
+/* Set up IR decoders */
+static void img_ir_init_decoders(void)
+{
+       struct img_ir_decoder **decp;
+
+       spin_lock(&img_ir_decoders_lock);
+       if (!img_ir_decoders_preprocessed) {
+               for (decp = img_ir_decoders; *decp; ++decp)
+                       img_ir_decoder_preprocess(*decp);
+               img_ir_decoders_preprocessed = true;
+       }
+       spin_unlock(&img_ir_decoders_lock);
+}
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * img_ir_enable_wake() - Switch to wake mode.
+ * @priv:      IR private data.
+ *
+ * Returns:    non-zero if the IR can wake the system.
+ */
+static int img_ir_enable_wake(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       int ret = 0;
+
+       spin_lock_irq(&priv->lock);
+       if (hw->flags & IMG_IR_F_WAKE) {
+               /* interrupt only on a match */
+               hw->suspend_irqen = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+               img_ir_write(priv, IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_DATA_MATCH);
+               img_ir_write_filter(priv, &hw->filters[RC_FILTER_WAKEUP]);
+               img_ir_write_timings(priv, &hw->reg_timings.timings,
+                                    RC_FILTER_WAKEUP);
+               hw->mode = IMG_IR_M_WAKE;
+               ret = 1;
+       }
+       spin_unlock_irq(&priv->lock);
+       return ret;
+}
+
+/**
+ * img_ir_disable_wake() - Switch out of wake mode.
+ * @priv:      IR private data
+ *
+ * Returns:    1 if the hardware should be allowed to wake from a sleep state.
+ *             0 otherwise.
+ */
+static int img_ir_disable_wake(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       int ret = 0;
+
+       spin_lock_irq(&priv->lock);
+       if (hw->flags & IMG_IR_F_WAKE) {
+               /* restore normal filtering */
+               if (hw->flags & IMG_IR_F_FILTER) {
+                       img_ir_write(priv, IMG_IR_IRQ_ENABLE,
+                                    (hw->suspend_irqen & IMG_IR_IRQ_EDGE) |
+                                    IMG_IR_IRQ_DATA_MATCH);
+                       img_ir_write_filter(priv,
+                                           &hw->filters[RC_FILTER_NORMAL]);
+               } else {
+                       img_ir_write(priv, IMG_IR_IRQ_ENABLE,
+                                    (hw->suspend_irqen & IMG_IR_IRQ_EDGE) |
+                                    IMG_IR_IRQ_DATA_VALID |
+                                    IMG_IR_IRQ_DATA2_VALID);
+                       img_ir_write_filter(priv, NULL);
+               }
+               img_ir_write_timings(priv, &hw->reg_timings.timings,
+                                    RC_FILTER_NORMAL);
+               hw->mode = IMG_IR_M_NORMAL;
+               ret = 1;
+       }
+       spin_unlock_irq(&priv->lock);
+       return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+/* lock must be held */
+static void img_ir_begin_repeat(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       if (hw->mode == IMG_IR_M_NORMAL) {
+               /* switch to repeat timings */
+               img_ir_write(priv, IMG_IR_CONTROL, 0);
+               hw->mode = IMG_IR_M_REPEATING;
+               img_ir_write_timings(priv, &hw->reg_timings.rtimings,
+                                    RC_FILTER_NORMAL);
+               img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
+       }
+}
+
+/* lock must be held */
+static void img_ir_end_repeat(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       if (hw->mode == IMG_IR_M_REPEATING) {
+               /* switch to normal timings */
+               img_ir_write(priv, IMG_IR_CONTROL, 0);
+               hw->mode = IMG_IR_M_NORMAL;
+               img_ir_write_timings(priv, &hw->reg_timings.timings,
+                                    RC_FILTER_NORMAL);
+               img_ir_write(priv, IMG_IR_CONTROL, hw->reg_timings.ctrl);
+       }
+}
+
+/* lock must be held */
+static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       const struct img_ir_decoder *dec = hw->decoder;
+       int ret = IMG_IR_SCANCODE;
+       int scancode;
+       if (dec->scancode)
+               ret = dec->scancode(len, raw, &scancode, hw->enabled_protocols);
+       else if (len >= 32)
+               scancode = (u32)raw;
+       else if (len < 32)
+               scancode = (u32)raw & ((1 << len)-1);
+       dev_dbg(priv->dev, "data (%u bits) = %#llx\n",
+               len, (unsigned long long)raw);
+       if (ret == IMG_IR_SCANCODE) {
+               dev_dbg(priv->dev, "decoded scan code %#x\n", scancode);
+               rc_keydown(hw->rdev, scancode, 0);
+               img_ir_end_repeat(priv);
+       } else if (ret == IMG_IR_REPEATCODE) {
+               if (hw->mode == IMG_IR_M_REPEATING) {
+                       dev_dbg(priv->dev, "decoded repeat code\n");
+                       rc_repeat(hw->rdev);
+               } else {
+                       dev_dbg(priv->dev, "decoded unexpected repeat code, ignoring\n");
+               }
+       } else {
+               dev_dbg(priv->dev, "decode failed (%d)\n", ret);
+               return;
+       }
+
+
+       if (dec->repeat) {
+               unsigned long interval;
+
+               img_ir_begin_repeat(priv);
+
+               /* update timer, but allowing for 1/8th tolerance */
+               interval = dec->repeat + (dec->repeat >> 3);
+               mod_timer(&hw->end_timer,
+                         jiffies + msecs_to_jiffies(interval));
+       }
+}
+
+/* timer function to end waiting for repeat. */
+static void img_ir_end_timer(unsigned long arg)
+{
+       struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+
+       spin_lock_irq(&priv->lock);
+       img_ir_end_repeat(priv);
+       spin_unlock_irq(&priv->lock);
+}
+
+#ifdef CONFIG_COMMON_CLK
+static void img_ir_change_frequency(struct img_ir_priv *priv,
+                                   struct clk_notifier_data *change)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+
+       dev_dbg(priv->dev, "clk changed %lu HZ -> %lu HZ\n",
+               change->old_rate, change->new_rate);
+
+       spin_lock_irq(&priv->lock);
+       if (hw->clk_hz == change->new_rate)
+               goto unlock;
+       hw->clk_hz = change->new_rate;
+       /* refresh current timings */
+       if (hw->decoder) {
+               img_ir_decoder_convert(hw->decoder, &hw->reg_timings,
+                                      hw->clk_hz);
+               switch (hw->mode) {
+               case IMG_IR_M_NORMAL:
+                       img_ir_write_timings(priv, &hw->reg_timings.timings,
+                                            RC_FILTER_NORMAL);
+                       break;
+               case IMG_IR_M_REPEATING:
+                       img_ir_write_timings(priv, &hw->reg_timings.rtimings,
+                                            RC_FILTER_NORMAL);
+                       break;
+#ifdef CONFIG_PM_SLEEP
+               case IMG_IR_M_WAKE:
+                       img_ir_write_timings(priv, &hw->reg_timings.timings,
+                                            RC_FILTER_WAKEUP);
+                       break;
+#endif
+               }
+       }
+unlock:
+       spin_unlock_irq(&priv->lock);
+}
+
+static int img_ir_clk_notify(struct notifier_block *self, unsigned long action,
+                            void *data)
+{
+       struct img_ir_priv *priv = container_of(self, struct img_ir_priv,
+                                               hw.clk_nb);
+       switch (action) {
+       case POST_RATE_CHANGE:
+               img_ir_change_frequency(priv, data);
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+#endif /* CONFIG_COMMON_CLK */
+
+/* called with priv->lock held */
+void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       u32 ir_status, len, lw, up;
+       unsigned int ct;
+
+       /* use the current decoder */
+       if (!hw->decoder)
+               return;
+
+       ir_status = img_ir_read(priv, IMG_IR_STATUS);
+       if (!(ir_status & (IMG_IR_RXDVAL | IMG_IR_RXDVALD2)))
+               return;
+       ir_status &= ~(IMG_IR_RXDVAL | IMG_IR_RXDVALD2);
+       img_ir_write(priv, IMG_IR_STATUS, ir_status);
+
+       len = (ir_status & IMG_IR_RXDLEN) >> IMG_IR_RXDLEN_SHIFT;
+       /* some versions report wrong length for certain code types */
+       ct = hw->decoder->control.code_type;
+       if (hw->ct_quirks[ct] & IMG_IR_QUIRK_CODE_LEN_INCR)
+               ++len;
+
+       lw = img_ir_read(priv, IMG_IR_DATA_LW);
+       up = img_ir_read(priv, IMG_IR_DATA_UP);
+       img_ir_handle_data(priv, len, (u64)up << 32 | lw);
+}
+
+void img_ir_setup_hw(struct img_ir_priv *priv)
+{
+       struct img_ir_decoder **decp;
+
+       if (!priv->hw.rdev)
+               return;
+
+       /* Use the first available decoder (or disable stuff if NULL) */
+       for (decp = img_ir_decoders; *decp; ++decp) {
+               const struct img_ir_decoder *dec = *decp;
+               if (img_ir_decoder_compatible(priv, dec)) {
+                       img_ir_set_protocol(priv, dec->type);
+                       img_ir_set_decoder(priv, dec, 0);
+                       return;
+               }
+       }
+       img_ir_set_decoder(priv, NULL, 0);
+}
+
+/**
+ * img_ir_probe_hw_caps() - Probe capabilities of the hardware.
+ * @priv:      IR private data.
+ */
+static void img_ir_probe_hw_caps(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       /*
+        * When a version of the block becomes available without these quirks,
+        * they'll have to depend on the core revision.
+        */
+       hw->ct_quirks[IMG_IR_CODETYPE_PULSELEN]
+               |= IMG_IR_QUIRK_CODE_LEN_INCR;
+       hw->ct_quirks[IMG_IR_CODETYPE_BIPHASE]
+               |= IMG_IR_QUIRK_CODE_BROKEN;
+       hw->ct_quirks[IMG_IR_CODETYPE_2BITPULSEPOS]
+               |= IMG_IR_QUIRK_CODE_BROKEN;
+}
+
+int img_ir_probe_hw(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       struct rc_dev *rdev;
+       int error;
+
+       /* Ensure hardware decoders have been preprocessed */
+       img_ir_init_decoders();
+
+       /* Probe hardware capabilities */
+       img_ir_probe_hw_caps(priv);
+
+       /* Set up the end timer */
+       setup_timer(&hw->end_timer, img_ir_end_timer, (unsigned long)priv);
+
+       /* Register a clock notifier */
+       if (!IS_ERR(priv->clk)) {
+               hw->clk_hz = clk_get_rate(priv->clk);
+#ifdef CONFIG_COMMON_CLK
+               hw->clk_nb.notifier_call = img_ir_clk_notify;
+               error = clk_notifier_register(priv->clk, &hw->clk_nb);
+               if (error)
+                       dev_warn(priv->dev,
+                                "failed to register clock notifier\n");
+#endif
+       } else {
+               hw->clk_hz = 32768;
+       }
+
+       /* Allocate hardware decoder */
+       hw->rdev = rdev = rc_allocate_device();
+       if (!rdev) {
+               dev_err(priv->dev, "cannot allocate input device\n");
+               error = -ENOMEM;
+               goto err_alloc_rc;
+       }
+       rdev->priv = priv;
+       rdev->map_name = RC_MAP_EMPTY;
+       rc_set_allowed_protocols(rdev, img_ir_allowed_protos(priv));
+       rdev->input_name = "IMG Infrared Decoder";
+       rdev->s_filter = img_ir_set_filter;
+
+       /* Register hardware decoder */
+       error = rc_register_device(rdev);
+       if (error) {
+               dev_err(priv->dev, "failed to register IR input device\n");
+               goto err_register_rc;
+       }
+
+       /*
+        * Set this after rc_register_device as no protocols have been
+        * registered yet.
+        */
+       rdev->change_protocol = img_ir_change_protocol;
+
+       device_init_wakeup(priv->dev, 1);
+
+       return 0;
+
+err_register_rc:
+       img_ir_set_decoder(priv, NULL, 0);
+       hw->rdev = NULL;
+       rc_free_device(rdev);
+err_alloc_rc:
+#ifdef CONFIG_COMMON_CLK
+       if (!IS_ERR(priv->clk))
+               clk_notifier_unregister(priv->clk, &hw->clk_nb);
+#endif
+       return error;
+}
+
+void img_ir_remove_hw(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_hw *hw = &priv->hw;
+       struct rc_dev *rdev = hw->rdev;
+       if (!rdev)
+               return;
+       img_ir_set_decoder(priv, NULL, 0);
+       hw->rdev = NULL;
+       rc_unregister_device(rdev);
+#ifdef CONFIG_COMMON_CLK
+       if (!IS_ERR(priv->clk))
+               clk_notifier_unregister(priv->clk, &hw->clk_nb);
+#endif
+}
+
+#ifdef CONFIG_PM_SLEEP
+int img_ir_suspend(struct device *dev)
+{
+       struct img_ir_priv *priv = dev_get_drvdata(dev);
+
+       if (device_may_wakeup(dev) && img_ir_enable_wake(priv))
+               enable_irq_wake(priv->irq);
+       return 0;
+}
+
+int img_ir_resume(struct device *dev)
+{
+       struct img_ir_priv *priv = dev_get_drvdata(dev);
+
+       if (device_may_wakeup(dev) && img_ir_disable_wake(priv))
+               disable_irq_wake(priv->irq);
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h b/drivers/media/rc/img-ir/img-ir-hw.h
new file mode 100644 (file)
index 0000000..6c9a94a
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * ImgTec IR Hardware Decoder found in PowerDown Controller.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ */
+
+#ifndef _IMG_IR_HW_H_
+#define _IMG_IR_HW_H_
+
+#include <linux/kernel.h>
+#include <media/rc-core.h>
+
+/* constants */
+
+#define IMG_IR_CODETYPE_PULSELEN       0x0     /* Sony */
+#define IMG_IR_CODETYPE_PULSEDIST      0x1     /* NEC, Toshiba, Micom, Sharp */
+#define IMG_IR_CODETYPE_BIPHASE                0x2     /* RC-5/6 */
+#define IMG_IR_CODETYPE_2BITPULSEPOS   0x3     /* RC-MM */
+
+
+/* Timing information */
+
+/**
+ * struct img_ir_control - Decoder control settings
+ * @decoden:   Primary decoder enable
+ * @code_type: Decode type (see IMG_IR_CODETYPE_*)
+ * @hdrtog:    Detect header toggle symbol after leader symbol
+ * @ldrdec:    Don't discard leader if maximum width reached
+ * @decodinpol:        Decoder input polarity (1=active high)
+ * @bitorien:  Bit orientation (1=MSB first)
+ * @d1validsel:        Decoder 2 takes over if it detects valid data
+ * @bitinv:    Bit inversion switch (1=don't invert)
+ * @decodend2: Secondary decoder enable (no leader symbol)
+ * @bitoriend2:        Bit orientation (1=MSB first)
+ * @bitinvd2:  Secondary decoder bit inversion switch (1=don't invert)
+ */
+struct img_ir_control {
+       unsigned decoden:1;
+       unsigned code_type:2;
+       unsigned hdrtog:1;
+       unsigned ldrdec:1;
+       unsigned decodinpol:1;
+       unsigned bitorien:1;
+       unsigned d1validsel:1;
+       unsigned bitinv:1;
+       unsigned decodend2:1;
+       unsigned bitoriend2:1;
+       unsigned bitinvd2:1;
+};
+
+/**
+ * struct img_ir_timing_range - range of timing values
+ * @min:       Minimum timing value
+ * @max:       Maximum timing value (if < @min, this will be set to @min during
+ *             preprocessing step, so it is normally not explicitly initialised
+ *             and is taken care of by the tolerance)
+ */
+struct img_ir_timing_range {
+       u16 min;
+       u16 max;
+};
+
+/**
+ * struct img_ir_symbol_timing - timing data for a symbol
+ * @pulse:     Timing range for the length of the pulse in this symbol
+ * @space:     Timing range for the length of the space in this symbol
+ */
+struct img_ir_symbol_timing {
+       struct img_ir_timing_range pulse;
+       struct img_ir_timing_range space;
+};
+
+/**
+ * struct img_ir_free_timing - timing data for free time symbol
+ * @minlen:    Minimum number of bits of data
+ * @maxlen:    Maximum number of bits of data
+ * @ft_min:    Minimum free time after message
+ */
+struct img_ir_free_timing {
+       /* measured in bits */
+       u8 minlen;
+       u8 maxlen;
+       u16 ft_min;
+};
+
+/**
+ * struct img_ir_timings - Timing values.
+ * @ldr:       Leader symbol timing data
+ * @s00:       Zero symbol timing data for primary decoder
+ * @s01:       One symbol timing data for primary decoder
+ * @s10:       Zero symbol timing data for secondary (no leader symbol) decoder
+ * @s11:       One symbol timing data for secondary (no leader symbol) decoder
+ * @ft:                Free time symbol timing data
+ */
+struct img_ir_timings {
+       struct img_ir_symbol_timing ldr, s00, s01, s10, s11;
+       struct img_ir_free_timing ft;
+};
+
+/**
+ * struct img_ir_filter - Filter IR events.
+ * @data:      Data to match.
+ * @mask:      Mask of bits to compare.
+ * @minlen:    Additional minimum number of bits.
+ * @maxlen:    Additional maximum number of bits.
+ */
+struct img_ir_filter {
+       u64 data;
+       u64 mask;
+       u8 minlen;
+       u8 maxlen;
+};
+
+/**
+ * struct img_ir_timing_regvals - Calculated timing register values.
+ * @ldr:       Leader symbol timing register value
+ * @s00:       Zero symbol timing register value for primary decoder
+ * @s01:       One symbol timing register value for primary decoder
+ * @s10:       Zero symbol timing register value for secondary decoder
+ * @s11:       One symbol timing register value for secondary decoder
+ * @ft:                Free time symbol timing register value
+ */
+struct img_ir_timing_regvals {
+       u32 ldr, s00, s01, s10, s11, ft;
+};
+
+#define IMG_IR_SCANCODE                0       /* new scancode */
+#define IMG_IR_REPEATCODE      1       /* repeat the previous code */
+
+/**
+ * struct img_ir_decoder - Decoder settings for an IR protocol.
+ * @type:      Protocol types bitmap.
+ * @tolerance: Timing tolerance as a percentage (default 10%).
+ * @unit:      Unit of timings in nanoseconds (default 1 us).
+ * @timings:   Primary timings
+ * @rtimings:  Additional override timings while waiting for repeats.
+ * @repeat:    Maximum repeat interval (always in milliseconds).
+ * @control:   Control flags.
+ *
+ * @scancode:  Pointer to function to convert the IR data into a scancode (it
+ *             must be safe to execute in interrupt context).
+ *             Returns IMG_IR_SCANCODE to emit new scancode.
+ *             Returns IMG_IR_REPEATCODE to repeat previous code.
+ *             Returns -errno (e.g. -EINVAL) on error.
+ * @filter:    Pointer to function to convert scancode filter to raw hardware
+ *             filter. The minlen and maxlen fields will have been initialised
+ *             to the maximum range.
+ */
+struct img_ir_decoder {
+       /* core description */
+       u64                             type;
+       unsigned int                    tolerance;
+       unsigned int                    unit;
+       struct img_ir_timings           timings;
+       struct img_ir_timings           rtimings;
+       unsigned int                    repeat;
+       struct img_ir_control           control;
+
+       /* scancode logic */
+       int (*scancode)(int len, u64 raw, int *scancode, u64 protocols);
+       int (*filter)(const struct rc_scancode_filter *in,
+                     struct img_ir_filter *out, u64 protocols);
+};
+
+/**
+ * struct img_ir_reg_timings - Reg values for decoder timings at clock rate.
+ * @ctrl:      Processed control register value.
+ * @timings:   Processed primary timings.
+ * @rtimings:  Processed repeat timings.
+ */
+struct img_ir_reg_timings {
+       u32                             ctrl;
+       struct img_ir_timing_regvals    timings;
+       struct img_ir_timing_regvals    rtimings;
+};
+
+int img_ir_register_decoder(struct img_ir_decoder *dec);
+void img_ir_unregister_decoder(struct img_ir_decoder *dec);
+
+struct img_ir_priv;
+
+#ifdef CONFIG_IR_IMG_HW
+
+enum img_ir_mode {
+       IMG_IR_M_NORMAL,
+       IMG_IR_M_REPEATING,
+#ifdef CONFIG_PM_SLEEP
+       IMG_IR_M_WAKE,
+#endif
+};
+
+/**
+ * struct img_ir_priv_hw - Private driver data for hardware decoder.
+ * @ct_quirks:         Quirk bits for each code type.
+ * @rdev:              Remote control device
+ * @clk_nb:            Notifier block for clock notify events.
+ * @end_timer:         Timer until repeat timeout.
+ * @decoder:           Current decoder settings.
+ * @enabled_protocols: Currently enabled protocols.
+ * @clk_hz:            Current core clock rate in Hz.
+ * @reg_timings:       Timing reg values for decoder at clock rate.
+ * @flags:             IMG_IR_F_*.
+ * @filters:           HW filters (derived from scancode filters).
+ * @mode:              Current decode mode.
+ * @suspend_irqen:     Saved IRQ enable mask over suspend.
+ */
+struct img_ir_priv_hw {
+       unsigned int                    ct_quirks[4];
+       struct rc_dev                   *rdev;
+       struct notifier_block           clk_nb;
+       struct timer_list               end_timer;
+       const struct img_ir_decoder     *decoder;
+       u64                             enabled_protocols;
+       unsigned long                   clk_hz;
+       struct img_ir_reg_timings       reg_timings;
+       unsigned int                    flags;
+       struct img_ir_filter            filters[RC_FILTER_MAX];
+
+       enum img_ir_mode                mode;
+       u32                             suspend_irqen;
+};
+
+static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw)
+{
+       return hw->rdev;
+};
+
+void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status);
+void img_ir_setup_hw(struct img_ir_priv *priv);
+int img_ir_probe_hw(struct img_ir_priv *priv);
+void img_ir_remove_hw(struct img_ir_priv *priv);
+
+#ifdef CONFIG_PM_SLEEP
+int img_ir_suspend(struct device *dev);
+int img_ir_resume(struct device *dev);
+#else
+#define img_ir_suspend NULL
+#define img_ir_resume NULL
+#endif
+
+#else
+
+struct img_ir_priv_hw {
+};
+
+static inline bool img_ir_hw_enabled(struct img_ir_priv_hw *hw)
+{
+       return false;
+};
+static inline void img_ir_isr_hw(struct img_ir_priv *priv, u32 irq_status)
+{
+}
+static inline void img_ir_setup_hw(struct img_ir_priv *priv)
+{
+}
+static inline int img_ir_probe_hw(struct img_ir_priv *priv)
+{
+       return -ENODEV;
+}
+static inline void img_ir_remove_hw(struct img_ir_priv *priv)
+{
+}
+
+#define img_ir_suspend NULL
+#define img_ir_resume NULL
+
+#endif /* CONFIG_IR_IMG_HW */
+
+#endif /* _IMG_IR_HW_H_ */
diff --git a/drivers/media/rc/img-ir/img-ir-jvc.c b/drivers/media/rc/img-ir/img-ir-jvc.c
new file mode 100644 (file)
index 0000000..10209d2
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * ImgTec IR Decoder setup for JVC protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ */
+
+#include "img-ir-hw.h"
+
+/* Convert JVC data to a scancode */
+static int img_ir_jvc_scancode(int len, u64 raw, int *scancode, u64 protocols)
+{
+       unsigned int cust, data;
+
+       if (len != 16)
+               return -EINVAL;
+
+       cust = (raw >> 0) & 0xff;
+       data = (raw >> 8) & 0xff;
+
+       *scancode = cust << 8 | data;
+       return IMG_IR_SCANCODE;
+}
+
+/* Convert JVC scancode to JVC data filter */
+static int img_ir_jvc_filter(const struct rc_scancode_filter *in,
+                            struct img_ir_filter *out, u64 protocols)
+{
+       unsigned int cust, data;
+       unsigned int cust_m, data_m;
+
+       cust   = (in->data >> 8) & 0xff;
+       cust_m = (in->mask >> 8) & 0xff;
+       data   = (in->data >> 0) & 0xff;
+       data_m = (in->mask >> 0) & 0xff;
+
+       out->data = cust   | data << 8;
+       out->mask = cust_m | data_m << 8;
+
+       return 0;
+}
+
+/*
+ * JVC decoder
+ * See also http://www.sbprojects.com/knowledge/ir/jvc.php
+ *          http://support.jvc.com/consumer/support/documents/RemoteCodes.pdf
+ */
+struct img_ir_decoder img_ir_jvc = {
+       .type = RC_BIT_JVC,
+       .control = {
+               .decoden = 1,
+               .code_type = IMG_IR_CODETYPE_PULSEDIST,
+       },
+       /* main timings */
+       .unit = 527500, /* 527.5 us */
+       .timings = {
+               /* leader symbol */
+               .ldr = {
+                       .pulse = { 16   /* 8.44 ms */ },
+                       .space = { 8    /* 4.22 ms */ },
+               },
+               /* 0 symbol */
+               .s00 = {
+                       .pulse = { 1    /* 527.5 us +-60 us */ },
+                       .space = { 1    /* 527.5 us */ },
+               },
+               /* 1 symbol */
+               .s01 = {
+                       .pulse = { 1    /* 527.5 us +-60 us */ },
+                       .space = { 3    /* 1.5825 ms +-40 us */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 16,
+                       .maxlen = 16,
+                       .ft_min = 10,   /* 5.275 ms */
+               },
+       },
+       /* scancode logic */
+       .scancode = img_ir_jvc_scancode,
+       .filter = img_ir_jvc_filter,
+};
diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c
new file mode 100644 (file)
index 0000000..e7a731b
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * ImgTec IR Decoder setup for NEC protocol.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ */
+
+#include "img-ir-hw.h"
+
+/* Convert NEC data to a scancode */
+static int img_ir_nec_scancode(int len, u64 raw, int *scancode, u64 protocols)
+{
+       unsigned int addr, addr_inv, data, data_inv;
+       /* a repeat code has no data */
+       if (!len)
+               return IMG_IR_REPEATCODE;
+       if (len != 32)
+               return -EINVAL;
+       /* raw encoding: ddDDaaAA */
+       addr     = (raw >>  0) & 0xff;
+       addr_inv = (raw >>  8) & 0xff;
+       data     = (raw >> 16) & 0xff;
+       data_inv = (raw >> 24) & 0xff;
+       if ((data_inv ^ data) != 0xff) {
+               /* 32-bit NEC (used by Apple and TiVo remotes) */
+               /* scan encoding: aaAAddDD */
+               *scancode = addr_inv << 24 |
+                           addr     << 16 |
+                           data_inv <<  8 |
+                           data;
+       } else if ((addr_inv ^ addr) != 0xff) {
+               /* Extended NEC */
+               /* scan encoding: AAaaDD */
+               *scancode = addr     << 16 |
+                           addr_inv <<  8 |
+                           data;
+       } else {
+               /* Normal NEC */
+               /* scan encoding: AADD */
+               *scancode = addr << 8 |
+                           data;
+       }
+       return IMG_IR_SCANCODE;
+}
+
+/* Convert NEC scancode to NEC data filter */
+static int img_ir_nec_filter(const struct rc_scancode_filter *in,
+                            struct img_ir_filter *out, u64 protocols)
+{
+       unsigned int addr, addr_inv, data, data_inv;
+       unsigned int addr_m, addr_inv_m, data_m, data_inv_m;
+
+       data       = in->data & 0xff;
+       data_m     = in->mask & 0xff;
+
+       if ((in->data | in->mask) & 0xff000000) {
+               /* 32-bit NEC (used by Apple and TiVo remotes) */
+               /* scan encoding: aaAAddDD */
+               addr_inv   = (in->data >> 24) & 0xff;
+               addr_inv_m = (in->mask >> 24) & 0xff;
+               addr       = (in->data >> 16) & 0xff;
+               addr_m     = (in->mask >> 16) & 0xff;
+               data_inv   = (in->data >>  8) & 0xff;
+               data_inv_m = (in->mask >>  8) & 0xff;
+       } else if ((in->data | in->mask) & 0x00ff0000) {
+               /* Extended NEC */
+               /* scan encoding AAaaDD */
+               addr       = (in->data >> 16) & 0xff;
+               addr_m     = (in->mask >> 16) & 0xff;
+               addr_inv   = (in->data >>  8) & 0xff;
+               addr_inv_m = (in->mask >>  8) & 0xff;
+               data_inv   = data ^ 0xff;
+               data_inv_m = data_m;
+       } else {
+               /* Normal NEC */
+               /* scan encoding: AADD */
+               addr       = (in->data >>  8) & 0xff;
+               addr_m     = (in->mask >>  8) & 0xff;
+               addr_inv   = addr ^ 0xff;
+               addr_inv_m = addr_m;
+               data_inv   = data ^ 0xff;
+               data_inv_m = data_m;
+       }
+
+       /* raw encoding: ddDDaaAA */
+       out->data = data_inv << 24 |
+                   data     << 16 |
+                   addr_inv <<  8 |
+                   addr;
+       out->mask = data_inv_m << 24 |
+                   data_m     << 16 |
+                   addr_inv_m <<  8 |
+                   addr_m;
+       return 0;
+}
+
+/*
+ * NEC decoder
+ * See also http://www.sbprojects.com/knowledge/ir/nec.php
+ *        http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol
+ */
+struct img_ir_decoder img_ir_nec = {
+       .type = RC_BIT_NEC,
+       .control = {
+               .decoden = 1,
+               .code_type = IMG_IR_CODETYPE_PULSEDIST,
+       },
+       /* main timings */
+       .unit = 562500, /* 562.5 us */
+       .timings = {
+               /* leader symbol */
+               .ldr = {
+                       .pulse = { 16   /* 9ms */ },
+                       .space = { 8    /* 4.5ms */ },
+               },
+               /* 0 symbol */
+               .s00 = {
+                       .pulse = { 1    /* 562.5 us */ },
+                       .space = { 1    /* 562.5 us */ },
+               },
+               /* 1 symbol */
+               .s01 = {
+                       .pulse = { 1    /* 562.5 us */ },
+                       .space = { 3    /* 1687.5 us */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 32,
+                       .maxlen = 32,
+                       .ft_min = 10,   /* 5.625 ms */
+               },
+       },
+       /* repeat codes */
+       .repeat = 108,                  /* 108 ms */
+       .rtimings = {
+               /* leader symbol */
+               .ldr = {
+                       .space = { 4    /* 2.25 ms */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 0,    /* repeat code has no data */
+                       .maxlen = 0,
+               },
+       },
+       /* scancode logic */
+       .scancode = img_ir_nec_scancode,
+       .filter = img_ir_nec_filter,
+};
diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
new file mode 100644 (file)
index 0000000..cfb01d9
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * ImgTec IR Raw Decoder found in PowerDown Controller.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * This ties into the input subsystem using the RC-core in raw mode. Raw IR
+ * signal edges are reported and decoded by generic software decoders.
+ */
+
+#include <linux/spinlock.h>
+#include <media/rc-core.h>
+#include "img-ir.h"
+
+#define ECHO_TIMEOUT_MS 150    /* ms between echos */
+
+/* must be called with priv->lock held */
+static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status)
+{
+       struct img_ir_priv_raw *raw = &priv->raw;
+       struct rc_dev *rc_dev = priv->raw.rdev;
+       int multiple;
+       u32 ir_status;
+
+       /* find whether both rise and fall was detected */
+       multiple = ((irq_status & IMG_IR_IRQ_EDGE) == IMG_IR_IRQ_EDGE);
+       /*
+        * If so, we need to see if the level has actually changed.
+        * If it's just noise that we didn't have time to process,
+        * there's no point reporting it.
+        */
+       ir_status = img_ir_read(priv, IMG_IR_STATUS) & IMG_IR_IRRXD;
+       if (multiple && ir_status == raw->last_status)
+               return;
+       raw->last_status = ir_status;
+
+       /* report the edge to the IR raw decoders */
+       if (ir_status) /* low */
+               ir_raw_event_store_edge(rc_dev, IR_SPACE);
+       else /* high */
+               ir_raw_event_store_edge(rc_dev, IR_PULSE);
+       ir_raw_event_handle(rc_dev);
+}
+
+/* called with priv->lock held */
+void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
+{
+       struct img_ir_priv_raw *raw = &priv->raw;
+
+       /* check not removing */
+       if (!raw->rdev)
+               return;
+
+       img_ir_refresh_raw(priv, irq_status);
+
+       /* start / push back the echo timer */
+       mod_timer(&raw->timer, jiffies + msecs_to_jiffies(ECHO_TIMEOUT_MS));
+}
+
+/*
+ * Echo timer callback function.
+ * The raw decoders expect to get a final sample even if there are no edges, in
+ * order to be assured of the final space. If there are no edges for a certain
+ * time we use this timer to emit a final sample to satisfy them.
+ */
+static void img_ir_echo_timer(unsigned long arg)
+{
+       struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+
+       spin_lock_irq(&priv->lock);
+
+       /* check not removing */
+       if (priv->raw.rdev)
+               /*
+                * It's safe to pass irq_status=0 since it's only used to check
+                * for double edges.
+                */
+               img_ir_refresh_raw(priv, 0);
+
+       spin_unlock_irq(&priv->lock);
+}
+
+void img_ir_setup_raw(struct img_ir_priv *priv)
+{
+       u32 irq_en;
+
+       if (!priv->raw.rdev)
+               return;
+
+       /* clear and enable edge interrupts */
+       spin_lock_irq(&priv->lock);
+       irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+       irq_en |= IMG_IR_IRQ_EDGE;
+       img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
+       img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
+       spin_unlock_irq(&priv->lock);
+}
+
+int img_ir_probe_raw(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_raw *raw = &priv->raw;
+       struct rc_dev *rdev;
+       int error;
+
+       /* Set up the echo timer */
+       setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);
+
+       /* Allocate raw decoder */
+       raw->rdev = rdev = rc_allocate_device();
+       if (!rdev) {
+               dev_err(priv->dev, "cannot allocate raw input device\n");
+               return -ENOMEM;
+       }
+       rdev->priv = priv;
+       rdev->map_name = RC_MAP_EMPTY;
+       rdev->input_name = "IMG Infrared Decoder Raw";
+       rdev->driver_type = RC_DRIVER_IR_RAW;
+
+       /* Register raw decoder */
+       error = rc_register_device(rdev);
+       if (error) {
+               dev_err(priv->dev, "failed to register raw IR input device\n");
+               rc_free_device(rdev);
+               raw->rdev = NULL;
+               return error;
+       }
+
+       return 0;
+}
+
+void img_ir_remove_raw(struct img_ir_priv *priv)
+{
+       struct img_ir_priv_raw *raw = &priv->raw;
+       struct rc_dev *rdev = raw->rdev;
+       u32 irq_en;
+
+       if (!rdev)
+               return;
+
+       /* switch off and disable raw (edge) interrupts */
+       spin_lock_irq(&priv->lock);
+       raw->rdev = NULL;
+       irq_en = img_ir_read(priv, IMG_IR_IRQ_ENABLE);
+       irq_en &= ~IMG_IR_IRQ_EDGE;
+       img_ir_write(priv, IMG_IR_IRQ_ENABLE, irq_en);
+       img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
+       spin_unlock_irq(&priv->lock);
+
+       rc_unregister_device(rdev);
+
+       del_timer_sync(&raw->timer);
+}
diff --git a/drivers/media/rc/img-ir/img-ir-raw.h b/drivers/media/rc/img-ir/img-ir-raw.h
new file mode 100644 (file)
index 0000000..9802ffd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * ImgTec IR Raw Decoder found in PowerDown Controller.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ */
+
+#ifndef _IMG_IR_RAW_H_
+#define _IMG_IR_RAW_H_
+
+struct img_ir_priv;
+
+#ifdef CONFIG_IR_IMG_RAW
+
+/**
+ * struct img_ir_priv_raw - Private driver data for raw decoder.
+ * @rdev:              Raw remote control device
+ * @timer:             Timer to echo samples to keep soft decoders happy.
+ * @last_status:       Last raw status bits.
+ */
+struct img_ir_priv_raw {
+       struct rc_dev           *rdev;
+       struct timer_list       timer;
+       u32                     last_status;
+};
+
+static inline bool img_ir_raw_enabled(struct img_ir_priv_raw *raw)
+{
+       return raw->rdev;
+};
+
+void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status);
+void img_ir_setup_raw(struct img_ir_priv *priv);
+int img_ir_probe_raw(struct img_ir_priv *priv);
+void img_ir_remove_raw(struct img_ir_priv *priv);
+
+#else
+
+struct img_ir_priv_raw {
+};
+static inline bool img_ir_raw_enabled(struct img_ir_priv_raw *raw)
+{
+       return false;
+};
+static inline void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
+{
+}
+static inline void img_ir_setup_raw(struct img_ir_priv *priv)
+{
+}
+static inline int img_ir_probe_raw(struct img_ir_priv *priv)
+{
+       return -ENODEV;
+}
+static inline void img_ir_remove_raw(struct img_ir_priv *priv)
+{
+}
+
+#endif /* CONFIG_IR_IMG_RAW */
+
+#endif /* _IMG_IR_RAW_H_ */
diff --git a/drivers/media/rc/img-ir/img-ir-sanyo.c b/drivers/media/rc/img-ir/img-ir-sanyo.c
new file mode 100644 (file)
index 0000000..c2c763e
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * ImgTec IR Decoder setup for Sanyo protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * From ir-sanyo-decoder.c:
+ *
+ * This protocol uses the NEC protocol timings. However, data is formatted as:
+ *     13 bits Custom Code
+ *     13 bits NOT(Custom Code)
+ *     8 bits Key data
+ *     8 bits NOT(Key data)
+ *
+ * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
+ * Information for this protocol is available at the Sanyo LC7461 datasheet.
+ */
+
+#include "img-ir-hw.h"
+
+/* Convert Sanyo data to a scancode */
+static int img_ir_sanyo_scancode(int len, u64 raw, int *scancode, u64 protocols)
+{
+       unsigned int addr, addr_inv, data, data_inv;
+       /* a repeat code has no data */
+       if (!len)
+               return IMG_IR_REPEATCODE;
+       if (len != 42)
+               return -EINVAL;
+       addr     = (raw >>  0) & 0x1fff;
+       addr_inv = (raw >> 13) & 0x1fff;
+       data     = (raw >> 26) & 0xff;
+       data_inv = (raw >> 34) & 0xff;
+       /* Validate data */
+       if ((data_inv ^ data) != 0xff)
+               return -EINVAL;
+       /* Validate address */
+       if ((addr_inv ^ addr) != 0x1fff)
+               return -EINVAL;
+
+       /* Normal Sanyo */
+       *scancode = addr << 8 | data;
+       return IMG_IR_SCANCODE;
+}
+
+/* Convert Sanyo scancode to Sanyo data filter */
+static int img_ir_sanyo_filter(const struct rc_scancode_filter *in,
+                              struct img_ir_filter *out, u64 protocols)
+{
+       unsigned int addr, addr_inv, data, data_inv;
+       unsigned int addr_m, data_m;
+
+       data = in->data & 0xff;
+       data_m = in->mask & 0xff;
+       data_inv = data ^ 0xff;
+
+       if (in->data & 0xff700000)
+               return -EINVAL;
+
+       addr       = (in->data >> 8) & 0x1fff;
+       addr_m     = (in->mask >> 8) & 0x1fff;
+       addr_inv   = addr ^ 0x1fff;
+
+       out->data = (u64)data_inv << 34 |
+                   (u64)data     << 26 |
+                        addr_inv << 13 |
+                        addr;
+       out->mask = (u64)data_m << 34 |
+                   (u64)data_m << 26 |
+                        addr_m << 13 |
+                        addr_m;
+       return 0;
+}
+
+/* Sanyo decoder */
+struct img_ir_decoder img_ir_sanyo = {
+       .type = RC_BIT_SANYO,
+       .control = {
+               .decoden = 1,
+               .code_type = IMG_IR_CODETYPE_PULSEDIST,
+       },
+       /* main timings */
+       .unit = 562500, /* 562.5 us */
+       .timings = {
+               /* leader symbol */
+               .ldr = {
+                       .pulse = { 16   /* 9ms */ },
+                       .space = { 8    /* 4.5ms */ },
+               },
+               /* 0 symbol */
+               .s00 = {
+                       .pulse = { 1    /* 562.5 us */ },
+                       .space = { 1    /* 562.5 us */ },
+               },
+               /* 1 symbol */
+               .s01 = {
+                       .pulse = { 1    /* 562.5 us */ },
+                       .space = { 3    /* 1687.5 us */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 42,
+                       .maxlen = 42,
+                       .ft_min = 10,   /* 5.625 ms */
+               },
+       },
+       /* repeat codes */
+       .repeat = 108,                  /* 108 ms */
+       .rtimings = {
+               /* leader symbol */
+               .ldr = {
+                       .space = { 4    /* 2.25 ms */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 0,    /* repeat code has no data */
+                       .maxlen = 0,
+               },
+       },
+       /* scancode logic */
+       .scancode = img_ir_sanyo_scancode,
+       .filter = img_ir_sanyo_filter,
+};
diff --git a/drivers/media/rc/img-ir/img-ir-sharp.c b/drivers/media/rc/img-ir/img-ir-sharp.c
new file mode 100644 (file)
index 0000000..3397cc5
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * ImgTec IR Decoder setup for Sharp protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ */
+
+#include "img-ir-hw.h"
+
+/* Convert Sharp data to a scancode */
+static int img_ir_sharp_scancode(int len, u64 raw, int *scancode, u64 protocols)
+{
+       unsigned int addr, cmd, exp, chk;
+
+       if (len != 15)
+               return -EINVAL;
+
+       addr = (raw >>   0) & 0x1f;
+       cmd  = (raw >>   5) & 0xff;
+       exp  = (raw >>  13) &  0x1;
+       chk  = (raw >>  14) &  0x1;
+
+       /* validate data */
+       if (!exp)
+               return -EINVAL;
+       if (chk)
+               /* probably the second half of the message */
+               return -EINVAL;
+
+       *scancode = addr << 8 | cmd;
+       return IMG_IR_SCANCODE;
+}
+
+/* Convert Sharp scancode to Sharp data filter */
+static int img_ir_sharp_filter(const struct rc_scancode_filter *in,
+                              struct img_ir_filter *out, u64 protocols)
+{
+       unsigned int addr, cmd, exp = 0, chk = 0;
+       unsigned int addr_m, cmd_m, exp_m = 0, chk_m = 0;
+
+       addr   = (in->data >> 8) & 0x1f;
+       addr_m = (in->mask >> 8) & 0x1f;
+       cmd    = (in->data >> 0) & 0xff;
+       cmd_m  = (in->mask >> 0) & 0xff;
+       if (cmd_m) {
+               /* if filtering commands, we can only match the first part */
+               exp   = 1;
+               exp_m = 1;
+               chk   = 0;
+               chk_m = 1;
+       }
+
+       out->data = addr        |
+                   cmd   <<  5 |
+                   exp   << 13 |
+                   chk   << 14;
+       out->mask = addr_m      |
+                   cmd_m <<  5 |
+                   exp_m << 13 |
+                   chk_m << 14;
+
+       return 0;
+}
+
+/*
+ * Sharp decoder
+ * See also http://www.sbprojects.com/knowledge/ir/sharp.php
+ */
+struct img_ir_decoder img_ir_sharp = {
+       .type = RC_BIT_SHARP,
+       .control = {
+               .decoden = 0,
+               .decodend2 = 1,
+               .code_type = IMG_IR_CODETYPE_PULSEDIST,
+               .d1validsel = 1,
+       },
+       /* main timings */
+       .tolerance = 20,        /* 20% */
+       .timings = {
+               /* 0 symbol */
+               .s10 = {
+                       .pulse = { 320  /* 320 us */ },
+                       .space = { 680  /* 1 ms period */ },
+               },
+               /* 1 symbol */
+               .s11 = {
+                       .pulse = { 320  /* 320 us */ },
+                       .space = { 1680 /* 2 ms period */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 15,
+                       .maxlen = 15,
+                       .ft_min = 5000, /* 5 ms */
+               },
+       },
+       /* scancode logic */
+       .scancode = img_ir_sharp_scancode,
+       .filter = img_ir_sharp_filter,
+};
diff --git a/drivers/media/rc/img-ir/img-ir-sony.c b/drivers/media/rc/img-ir/img-ir-sony.c
new file mode 100644 (file)
index 0000000..993409a
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * ImgTec IR Decoder setup for Sony (SIRC) protocol.
+ *
+ * Copyright 2012-2014 Imagination Technologies Ltd.
+ */
+
+#include "img-ir-hw.h"
+
+/* Convert Sony data to a scancode */
+static int img_ir_sony_scancode(int len, u64 raw, int *scancode, u64 protocols)
+{
+       unsigned int dev, subdev, func;
+
+       switch (len) {
+       case 12:
+               if (!(protocols & RC_BIT_SONY12))
+                       return -EINVAL;
+               func   = raw & 0x7f;    /* first 7 bits */
+               raw    >>= 7;
+               dev    = raw & 0x1f;    /* next 5 bits */
+               subdev = 0;
+               break;
+       case 15:
+               if (!(protocols & RC_BIT_SONY15))
+                       return -EINVAL;
+               func   = raw & 0x7f;    /* first 7 bits */
+               raw    >>= 7;
+               dev    = raw & 0xff;    /* next 8 bits */
+               subdev = 0;
+               break;
+       case 20:
+               if (!(protocols & RC_BIT_SONY20))
+                       return -EINVAL;
+               func   = raw & 0x7f;    /* first 7 bits */
+               raw    >>= 7;
+               dev    = raw & 0x1f;    /* next 5 bits */
+               raw    >>= 5;
+               subdev = raw & 0xff;    /* next 8 bits */
+               break;
+       default:
+               return -EINVAL;
+       }
+       *scancode = dev << 16 | subdev << 8 | func;
+       return IMG_IR_SCANCODE;
+}
+
+/* Convert NEC scancode to NEC data filter */
+static int img_ir_sony_filter(const struct rc_scancode_filter *in,
+                             struct img_ir_filter *out, u64 protocols)
+{
+       unsigned int dev, subdev, func;
+       unsigned int dev_m, subdev_m, func_m;
+       unsigned int len = 0;
+
+       dev      = (in->data >> 16) & 0xff;
+       dev_m    = (in->mask >> 16) & 0xff;
+       subdev   = (in->data >> 8)  & 0xff;
+       subdev_m = (in->mask >> 8)  & 0xff;
+       func     = (in->data >> 0)  & 0x7f;
+       func_m   = (in->mask >> 0)  & 0x7f;
+
+       if (subdev & subdev_m) {
+               /* can't encode subdev and higher device bits */
+               if (dev & dev_m & 0xe0)
+                       return -EINVAL;
+               /* subdevice (extended) bits only in 20 bit encoding */
+               if (!(protocols & RC_BIT_SONY20))
+                       return -EINVAL;
+               len = 20;
+               dev_m &= 0x1f;
+       } else if (dev & dev_m & 0xe0) {
+               /* upper device bits only in 15 bit encoding */
+               if (!(protocols & RC_BIT_SONY15))
+                       return -EINVAL;
+               len = 15;
+               subdev_m = 0;
+       } else {
+               /*
+                * The hardware mask cannot distinguish high device bits and low
+                * extended bits, so logically AND those bits of the masks
+                * together.
+                */
+               subdev_m &= (dev_m >> 5) | 0xf8;
+               dev_m &= 0x1f;
+       }
+
+       /* ensure there aren't any bits straying between fields */
+       dev &= dev_m;
+       subdev &= subdev_m;
+
+       /* write the hardware filter */
+       out->data = func          |
+                   dev      << 7 |
+                   subdev   << 15;
+       out->mask = func_m        |
+                   dev_m    << 7 |
+                   subdev_m << 15;
+
+       if (len) {
+               out->minlen = len;
+               out->maxlen = len;
+       }
+       return 0;
+}
+
+/*
+ * Sony SIRC decoder
+ * See also http://www.sbprojects.com/knowledge/ir/sirc.php
+ *          http://picprojects.org.uk/projects/sirc/sonysirc.pdf
+ */
+struct img_ir_decoder img_ir_sony = {
+       .type = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
+       .control = {
+               .decoden = 1,
+               .code_type = IMG_IR_CODETYPE_PULSELEN,
+       },
+       /* main timings */
+       .unit = 600000, /* 600 us */
+       .timings = {
+               /* leader symbol */
+               .ldr = {
+                       .pulse = { 4    /* 2.4 ms */ },
+                       .space = { 1    /* 600 us */ },
+               },
+               /* 0 symbol */
+               .s00 = {
+                       .pulse = { 1    /* 600 us */ },
+                       .space = { 1    /* 600 us */ },
+               },
+               /* 1 symbol */
+               .s01 = {
+                       .pulse = { 2    /* 1.2 ms */ },
+                       .space = { 1    /* 600 us */ },
+               },
+               /* free time */
+               .ft = {
+                       .minlen = 12,
+                       .maxlen = 20,
+                       .ft_min = 10,   /* 6 ms */
+               },
+       },
+       /* scancode logic */
+       .scancode = img_ir_sony_scancode,
+       .filter = img_ir_sony_filter,
+};
diff --git a/drivers/media/rc/img-ir/img-ir.h b/drivers/media/rc/img-ir/img-ir.h
new file mode 100644 (file)
index 0000000..afb1893
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * ImgTec IR Decoder found in PowerDown Controller.
+ *
+ * Copyright 2010-2014 Imagination Technologies Ltd.
+ */
+
+#ifndef _IMG_IR_H_
+#define _IMG_IR_H_
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include "img-ir-raw.h"
+#include "img-ir-hw.h"
+
+/* registers */
+
+/* relative to the start of the IR block of registers */
+#define IMG_IR_CONTROL         0x00
+#define IMG_IR_STATUS          0x04
+#define IMG_IR_DATA_LW         0x08
+#define IMG_IR_DATA_UP         0x0c
+#define IMG_IR_LEAD_SYMB_TIMING        0x10
+#define IMG_IR_S00_SYMB_TIMING 0x14
+#define IMG_IR_S01_SYMB_TIMING 0x18
+#define IMG_IR_S10_SYMB_TIMING 0x1c
+#define IMG_IR_S11_SYMB_TIMING 0x20
+#define IMG_IR_FREE_SYMB_TIMING        0x24
+#define IMG_IR_POW_MOD_PARAMS  0x28
+#define IMG_IR_POW_MOD_ENABLE  0x2c
+#define IMG_IR_IRQ_MSG_DATA_LW 0x30
+#define IMG_IR_IRQ_MSG_DATA_UP 0x34
+#define IMG_IR_IRQ_MSG_MASK_LW 0x38
+#define IMG_IR_IRQ_MSG_MASK_UP 0x3c
+#define IMG_IR_IRQ_ENABLE      0x40
+#define IMG_IR_IRQ_STATUS      0x44
+#define IMG_IR_IRQ_CLEAR       0x48
+#define IMG_IR_IRCORE_ID       0xf0
+#define IMG_IR_CORE_REV                0xf4
+#define IMG_IR_CORE_DES1       0xf8
+#define IMG_IR_CORE_DES2       0xfc
+
+
+/* field masks */
+
+/* IMG_IR_CONTROL */
+#define IMG_IR_DECODEN         0x40000000
+#define IMG_IR_CODETYPE                0x30000000
+#define IMG_IR_CODETYPE_SHIFT          28
+#define IMG_IR_HDRTOG          0x08000000
+#define IMG_IR_LDRDEC          0x04000000
+#define IMG_IR_DECODINPOL      0x02000000      /* active high */
+#define IMG_IR_BITORIEN                0x01000000      /* MSB first */
+#define IMG_IR_D1VALIDSEL      0x00008000
+#define IMG_IR_BITINV          0x00000040      /* don't invert */
+#define IMG_IR_DECODEND2       0x00000010
+#define IMG_IR_BITORIEND2      0x00000002      /* MSB first */
+#define IMG_IR_BITINVD2                0x00000001      /* don't invert */
+
+/* IMG_IR_STATUS */
+#define IMG_IR_RXDVALD2                0x00001000
+#define IMG_IR_IRRXD           0x00000400
+#define IMG_IR_TOGSTATE                0x00000200
+#define IMG_IR_RXDVAL          0x00000040
+#define IMG_IR_RXDLEN          0x0000003f
+#define IMG_IR_RXDLEN_SHIFT            0
+
+/* IMG_IR_LEAD_SYMB_TIMING, IMG_IR_Sxx_SYMB_TIMING */
+#define IMG_IR_PD_MAX          0xff000000
+#define IMG_IR_PD_MAX_SHIFT            24
+#define IMG_IR_PD_MIN          0x00ff0000
+#define IMG_IR_PD_MIN_SHIFT            16
+#define IMG_IR_W_MAX           0x0000ff00
+#define IMG_IR_W_MAX_SHIFT             8
+#define IMG_IR_W_MIN           0x000000ff
+#define IMG_IR_W_MIN_SHIFT             0
+
+/* IMG_IR_FREE_SYMB_TIMING */
+#define IMG_IR_MAXLEN          0x0007e000
+#define IMG_IR_MAXLEN_SHIFT            13
+#define IMG_IR_MINLEN          0x00001f00
+#define IMG_IR_MINLEN_SHIFT            8
+#define IMG_IR_FT_MIN          0x000000ff
+#define IMG_IR_FT_MIN_SHIFT            0
+
+/* IMG_IR_POW_MOD_PARAMS */
+#define IMG_IR_PERIOD_LEN      0x3f000000
+#define IMG_IR_PERIOD_LEN_SHIFT                24
+#define IMG_IR_PERIOD_DUTY     0x003f0000
+#define IMG_IR_PERIOD_DUTY_SHIFT       16
+#define IMG_IR_STABLE_STOP     0x00003f00
+#define IMG_IR_STABLE_STOP_SHIFT       8
+#define IMG_IR_STABLE_START    0x0000003f
+#define IMG_IR_STABLE_START_SHIFT      0
+
+/* IMG_IR_POW_MOD_ENABLE */
+#define IMG_IR_POWER_OUT_EN    0x00000002
+#define IMG_IR_POWER_MOD_EN    0x00000001
+
+/* IMG_IR_IRQ_ENABLE, IMG_IR_IRQ_STATUS, IMG_IR_IRQ_CLEAR */
+#define IMG_IR_IRQ_DEC2_ERR    0x00000080
+#define IMG_IR_IRQ_DEC_ERR     0x00000040
+#define IMG_IR_IRQ_ACT_LEVEL   0x00000020
+#define IMG_IR_IRQ_FALL_EDGE   0x00000010
+#define IMG_IR_IRQ_RISE_EDGE   0x00000008
+#define IMG_IR_IRQ_DATA_MATCH  0x00000004
+#define IMG_IR_IRQ_DATA2_VALID 0x00000002
+#define IMG_IR_IRQ_DATA_VALID  0x00000001
+#define IMG_IR_IRQ_ALL         0x000000ff
+#define IMG_IR_IRQ_EDGE                (IMG_IR_IRQ_FALL_EDGE | IMG_IR_IRQ_RISE_EDGE)
+
+/* IMG_IR_CORE_ID */
+#define IMG_IR_CORE_ID         0x00ff0000
+#define IMG_IR_CORE_ID_SHIFT           16
+#define IMG_IR_CORE_CONFIG     0x0000ffff
+#define IMG_IR_CORE_CONFIG_SHIFT       0
+
+/* IMG_IR_CORE_REV */
+#define IMG_IR_DESIGNER                0xff000000
+#define IMG_IR_DESIGNER_SHIFT          24
+#define IMG_IR_MAJOR_REV       0x00ff0000
+#define IMG_IR_MAJOR_REV_SHIFT         16
+#define IMG_IR_MINOR_REV       0x0000ff00
+#define IMG_IR_MINOR_REV_SHIFT         8
+#define IMG_IR_MAINT_REV       0x000000ff
+#define IMG_IR_MAINT_REV_SHIFT         0
+
+struct device;
+struct clk;
+
+/**
+ * struct img_ir_priv - Private driver data.
+ * @dev:               Platform device.
+ * @irq:               IRQ number.
+ * @clk:               Input clock.
+ * @reg_base:          Iomem base address of IR register block.
+ * @lock:              Protects IR registers and variables in this struct.
+ * @raw:               Driver data for raw decoder.
+ * @hw:                        Driver data for hardware decoder.
+ */
+struct img_ir_priv {
+       struct device           *dev;
+       int                     irq;
+       struct clk              *clk;
+       void __iomem            *reg_base;
+       spinlock_t              lock;
+
+       struct img_ir_priv_raw  raw;
+       struct img_ir_priv_hw   hw;
+};
+
+/* Hardware access */
+
+static inline void img_ir_write(struct img_ir_priv *priv,
+                               unsigned int reg_offs, unsigned int data)
+{
+       iowrite32(data, priv->reg_base + reg_offs);
+}
+
+static inline unsigned int img_ir_read(struct img_ir_priv *priv,
+                                      unsigned int reg_offs)
+{
+       return ioread32(priv->reg_base + reg_offs);
+}
+
+#endif /* _IMG_IR_H_ */
index 822b9f47ca729aa6cd769fc262fa98a3fa3616ef..6f24e77b1488aab6073e3f7709e1845918d5fcf1 100644 (file)
@@ -1017,7 +1017,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
        unsigned char ir_proto_packet[] = {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
 
-       if (*rc_type && !(*rc_type & rc->allowed_protos))
+       if (*rc_type && !rc_protocols_allowed(rc, *rc_type))
                dev_warn(dev, "Looks like you're trying to use an IR protocol "
                         "this device does not support\n");
 
@@ -1867,7 +1867,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 
        rdev->priv = ictx;
        rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protos = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
+                                       /* iMON PAD or MCE */
+       rc_set_allowed_protocols(rdev, RC_BIT_OTHER | RC_BIT_RC6_MCE);
        rdev->change_protocol = imon_ir_change_protocol;
        rdev->driver_name = MOD_NAME;
 
@@ -1880,7 +1881,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 
        if (ictx->product == 0xffdc) {
                imon_get_ffdc_type(ictx);
-               rdev->allowed_protos = ictx->rc_type;
+               rc_set_allowed_protocols(rdev, ictx->rc_type);
        }
 
        imon_set_display_type(ictx);
index 3948138ca870cbe21b6638dd5e89fb5574cf5d72..4ea62a1dcfdaebedd61523dd6451bab70445b016 100644 (file)
@@ -47,7 +47,7 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
 {
        struct jvc_dec *data = &dev->raw->jvc;
 
-       if (!(dev->enabled_protocols & RC_BIT_JVC))
+       if (!rc_protocols_enabled(dev, RC_BIT_JVC))
                return 0;
 
        if (!is_timing_event(ev)) {
index ed2c8a1ed8caf39ee9eae20c8ec5b5f534c33c0a..d731da6c414da0a2b7bfc9dde18cd816c8d2f80a 100644 (file)
@@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
        struct lirc_codec *lirc = &dev->raw->lirc;
        int sample;
 
-       if (!(dev->enabled_protocols & RC_BIT_LIRC))
+       if (!rc_protocols_enabled(dev, RC_BIT_LIRC))
                return 0;
 
        if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
index 9f3c9b59f30ccf27bf96b00b9d9142057f5148cf..0c55f794c8cf85b9906f21ddf4194972419aed54 100644 (file)
@@ -216,7 +216,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        unsigned long delay;
 
-       if (!(dev->enabled_protocols & RC_BIT_MCE_KBD))
+       if (!rc_protocols_enabled(dev, RC_BIT_MCE_KBD))
                return 0;
 
        if (!is_timing_event(ev)) {
index 9a9009411439491417016faf7e2169c172a5ab9d..9de1791d24946fcd43f89705b11c7d0f7a90b4bb 100644 (file)
@@ -1,6 +1,6 @@
 /* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
  *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -52,7 +52,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u8 address, not_address, command, not_command;
        bool send_32bits = false;
 
-       if (!(dev->enabled_protocols & RC_BIT_NEC))
+       if (!rc_protocols_enabled(dev, RC_BIT_NEC))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -172,7 +172,10 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
                if (send_32bits) {
                        /* NEC transport, but modified protocol, used by at
                         * least Apple and TiVo remotes */
-                       scancode = data->bits;
+                       scancode = not_address << 24 |
+                                  address     << 16 |
+                                  not_command <<  8 |
+                                  command;
                        IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
                } else if ((address ^ not_address) != 0xff) {
                        /* Extended NEC */
@@ -222,6 +225,6 @@ module_init(ir_nec_decode_init);
 module_exit(ir_nec_decode_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("NEC IR protocol decoder");
index 5c42750c7b7152fc7cb9b3ea886e45798011bb87..763c9d131d0fc6c7573c5c1ee9e8ce2bbe266ef6 100644 (file)
@@ -1,6 +1,6 @@
 /* ir-raw.c - handle IR pulse/space events
  *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -256,7 +256,7 @@ int ir_raw_event_register(struct rc_dev *dev)
                return -ENOMEM;
 
        dev->raw->dev = dev;
-       dev->enabled_protocols = ~0;
+       rc_set_enabled_protocols(dev, ~0);
        rc = kfifo_alloc(&dev->raw->kfifo,
                         sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
                         GFP_KERNEL);
@@ -352,6 +352,7 @@ void ir_raw_init(void)
        load_jvc_decode();
        load_sony_decode();
        load_sanyo_decode();
+       load_sharp_decode();
        load_mce_kbd_decode();
        load_lirc_codec();
 
index 4e53a319c5d84931fa377536494e5728fe55fdfa..4295d9b250c836e23a811675bca15781d338079d 100644 (file)
@@ -1,6 +1,6 @@
 /* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol
  *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -52,7 +52,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u8 toggle;
        u32 scancode;
 
-       if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X)))
+       if (!rc_protocols_enabled(dev, RC_BIT_RC5 | RC_BIT_RC5X))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -128,7 +128,7 @@ again:
                if (data->wanted_bits == RC5X_NBITS) {
                        /* RC5X */
                        u8 xdata, command, system;
-                       if (!(dev->enabled_protocols & RC_BIT_RC5X)) {
+                       if (!rc_protocols_enabled(dev, RC_BIT_RC5X)) {
                                data->state = STATE_INACTIVE;
                                return 0;
                        }
@@ -145,7 +145,7 @@ again:
                } else {
                        /* RC5 */
                        u8 command, system;
-                       if (!(dev->enabled_protocols & RC_BIT_RC5)) {
+                       if (!rc_protocols_enabled(dev, RC_BIT_RC5)) {
                                data->state = STATE_INACTIVE;
                                return 0;
                        }
@@ -193,6 +193,6 @@ module_init(ir_rc5_decode_init);
 module_exit(ir_rc5_decode_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("RC5(x) IR protocol decoder");
index 865fe84fd854c1140c7ab0e7fd75028dacc8d933..dc18b7434db8806c5874a2f1e9b8df1f4a603d4a 100644 (file)
@@ -1,6 +1,6 @@
 /* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
  *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Mauro Carvalho Chehab
  * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -48,7 +48,7 @@ static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u8 toggle, command, system;
        u32 scancode;
 
-       if (!(dev->enabled_protocols & RC_BIT_RC5_SZ))
+       if (!rc_protocols_enabled(dev, RC_BIT_RC5_SZ))
                return 0;
 
        if (!is_timing_event(ev)) {
index 7cba7d33a3fac886b7ba8379275499f9c285f24b..cfbd64e3999c4a5fae91f4b4d4e395eb41f77a5c 100644 (file)
@@ -89,9 +89,9 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        u8 toggle;
 
-       if (!(dev->enabled_protocols &
-             (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 |
-              RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)))
+       if (!rc_protocols_enabled(dev, RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 |
+                                 RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 |
+                                 RC_BIT_RC6_MCE))
                return 0;
 
        if (!is_timing_event(ev)) {
index 0a06205b56771517dc4b53551a03fbe003c29e34..eb715f04dc27954af4bf458bbdcb6bd2a25e3bdc 100644 (file)
@@ -1,6 +1,6 @@
 /* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
  *
- * Copyright (C) 2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2011 by Mauro Carvalho Chehab
  *
  * 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
@@ -58,7 +58,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        u8 address, command, not_command;
 
-       if (!(dev->enabled_protocols & RC_BIT_SANYO))
+       if (!rc_protocols_enabled(dev, RC_BIT_SANYO))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -200,6 +200,6 @@ module_init(ir_sanyo_decode_init);
 module_exit(ir_sanyo_decode_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("SANYO IR protocol decoder");
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c
new file mode 100644 (file)
index 0000000..66d2039
--- /dev/null
@@ -0,0 +1,200 @@
+/* ir-sharp-decoder.c - handle Sharp IR Pulse/Space protocol
+ *
+ * Copyright (C) 2013-2014 Imagination Technologies Ltd.
+ *
+ * Based on NEC decoder:
+ * Copyright (C) 2010 by Mauro Carvalho Chehab
+ *
+ * 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/bitrev.h>
+#include <linux/module.h>
+#include "rc-core-priv.h"
+
+#define SHARP_NBITS            15
+#define SHARP_UNIT             40000  /* ns */
+#define SHARP_BIT_PULSE                (8    * SHARP_UNIT) /* 320us */
+#define SHARP_BIT_0_PERIOD     (25   * SHARP_UNIT) /* 1ms (680us space) */
+#define SHARP_BIT_1_PERIOD     (50   * SHARP_UNIT) /* 2ms (1680ms space) */
+#define SHARP_ECHO_SPACE       (1000 * SHARP_UNIT) /* 40 ms */
+#define SHARP_TRAILER_SPACE    (125  * SHARP_UNIT) /* 5 ms (even longer) */
+
+enum sharp_state {
+       STATE_INACTIVE,
+       STATE_BIT_PULSE,
+       STATE_BIT_SPACE,
+       STATE_TRAILER_PULSE,
+       STATE_ECHO_SPACE,
+       STATE_TRAILER_SPACE,
+};
+
+/**
+ * ir_sharp_decode() - Decode one Sharp pulse or space
+ * @dev:       the struct rc_dev descriptor of the device
+ * @duration:  the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev)
+{
+       struct sharp_dec *data = &dev->raw->sharp;
+       u32 msg, echo, address, command, scancode;
+
+       if (!rc_protocols_enabled(dev, RC_BIT_SHARP))
+               return 0;
+
+       if (!is_timing_event(ev)) {
+               if (ev.reset)
+                       data->state = STATE_INACTIVE;
+               return 0;
+       }
+
+       IR_dprintk(2, "Sharp decode started at state %d (%uus %s)\n",
+                  data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+
+       switch (data->state) {
+
+       case STATE_INACTIVE:
+               if (!ev.pulse)
+                       break;
+
+               if (!eq_margin(ev.duration, SHARP_BIT_PULSE,
+                              SHARP_BIT_PULSE / 2))
+                       break;
+
+               data->count = 0;
+               data->pulse_len = ev.duration;
+               data->state = STATE_BIT_SPACE;
+               return 0;
+
+       case STATE_BIT_PULSE:
+               if (!ev.pulse)
+                       break;
+
+               if (!eq_margin(ev.duration, SHARP_BIT_PULSE,
+                              SHARP_BIT_PULSE / 2))
+                       break;
+
+               data->pulse_len = ev.duration;
+               data->state = STATE_BIT_SPACE;
+               return 0;
+
+       case STATE_BIT_SPACE:
+               if (ev.pulse)
+                       break;
+
+               data->bits <<= 1;
+               if (eq_margin(data->pulse_len + ev.duration, SHARP_BIT_1_PERIOD,
+                             SHARP_BIT_PULSE * 2))
+                       data->bits |= 1;
+               else if (!eq_margin(data->pulse_len + ev.duration,
+                                   SHARP_BIT_0_PERIOD, SHARP_BIT_PULSE * 2))
+                       break;
+               data->count++;
+
+               if (data->count == SHARP_NBITS ||
+                   data->count == SHARP_NBITS * 2)
+                       data->state = STATE_TRAILER_PULSE;
+               else
+                       data->state = STATE_BIT_PULSE;
+
+               return 0;
+
+       case STATE_TRAILER_PULSE:
+               if (!ev.pulse)
+                       break;
+
+               if (!eq_margin(ev.duration, SHARP_BIT_PULSE,
+                              SHARP_BIT_PULSE / 2))
+                       break;
+
+               if (data->count == SHARP_NBITS) {
+                       /* exp,chk bits should be 1,0 */
+                       if ((data->bits & 0x3) != 0x2)
+                               break;
+                       data->state = STATE_ECHO_SPACE;
+               } else {
+                       data->state = STATE_TRAILER_SPACE;
+               }
+               return 0;
+
+       case STATE_ECHO_SPACE:
+               if (ev.pulse)
+                       break;
+
+               if (!eq_margin(ev.duration, SHARP_ECHO_SPACE,
+                              SHARP_ECHO_SPACE / 4))
+                       break;
+
+               data->state = STATE_BIT_PULSE;
+
+               return 0;
+
+       case STATE_TRAILER_SPACE:
+               if (ev.pulse)
+                       break;
+
+               if (!geq_margin(ev.duration, SHARP_TRAILER_SPACE,
+                               SHARP_BIT_PULSE / 2))
+                       break;
+
+               /* Validate - command, ext, chk should be inverted in 2nd */
+               msg = (data->bits >> 15) & 0x7fff;
+               echo = data->bits & 0x7fff;
+               if ((msg ^ echo) != 0x3ff) {
+                       IR_dprintk(1,
+                                  "Sharp checksum error: received 0x%04x, 0x%04x\n",
+                                  msg, echo);
+                       break;
+               }
+
+               address = bitrev8((msg >> 7) & 0xf8);
+               command = bitrev8((msg >> 2) & 0xff);
+
+               scancode = address << 8 | command;
+               IR_dprintk(1, "Sharp scancode 0x%04x\n", scancode);
+
+               rc_keydown(dev, scancode, 0);
+               data->state = STATE_INACTIVE;
+               return 0;
+       }
+
+       IR_dprintk(1, "Sharp decode failed at count %d state %d (%uus %s)\n",
+                  data->count, data->state, TO_US(ev.duration),
+                  TO_STR(ev.pulse));
+       data->state = STATE_INACTIVE;
+       return -EINVAL;
+}
+
+static struct ir_raw_handler sharp_handler = {
+       .protocols      = RC_BIT_SHARP,
+       .decode         = ir_sharp_decode,
+};
+
+static int __init ir_sharp_decode_init(void)
+{
+       ir_raw_handler_register(&sharp_handler);
+
+       pr_info("IR Sharp protocol handler initialized\n");
+       return 0;
+}
+
+static void __exit ir_sharp_decode_exit(void)
+{
+       ir_raw_handler_unregister(&sharp_handler);
+}
+
+module_init(ir_sharp_decode_init);
+module_exit(ir_sharp_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Hogan <james.hogan@imgtec.com>");
+MODULE_DESCRIPTION("Sharp IR protocol decoder");
index 29ab9c2db060c6831536579d4cbc50fad33120d5..599c19a7336041eef4622563f99cbd3341915a2a 100644 (file)
@@ -45,8 +45,8 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        u8 device, subdevice, function;
 
-       if (!(dev->enabled_protocols &
-             (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20)))
+       if (!rc_protocols_enabled(dev, RC_BIT_SONY12 | RC_BIT_SONY15 |
+                                 RC_BIT_SONY20))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -124,7 +124,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
 
                switch (data->count) {
                case 12:
-                       if (!(dev->enabled_protocols & RC_BIT_SONY12)) {
+                       if (!rc_protocols_enabled(dev, RC_BIT_SONY12)) {
                                data->state = STATE_INACTIVE;
                                return 0;
                        }
@@ -133,7 +133,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
                        function  = bitrev8((data->bits >>  4) & 0xFE);
                        break;
                case 15:
-                       if (!(dev->enabled_protocols & RC_BIT_SONY15)) {
+                       if (!rc_protocols_enabled(dev, RC_BIT_SONY15)) {
                                data->state = STATE_INACTIVE;
                                return 0;
                        }
@@ -142,7 +142,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
                        function  = bitrev8((data->bits >>  7) & 0xFE);
                        break;
                case 20:
-                       if (!(dev->enabled_protocols & RC_BIT_SONY20)) {
+                       if (!rc_protocols_enabled(dev, RC_BIT_SONY20)) {
                                data->state = STATE_INACTIVE;
                                return 0;
                        }
index 63b42252166a744fc2275b0b538a69bd4232f98d..ab24cc6d365560778a2ded716b5a0d1d978fb3d3 100644 (file)
@@ -1563,7 +1563,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
        /* set up ir-core props */
        rdev->priv = itdev;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        rdev->open = ite_open;
        rdev->close = ite_close;
        rdev->s_idle = ite_s_idle;
index b0e42df7ff82a27eda82468a51766dbbcb4a5867..01d901fbfc8b28a46248055d6477c952f8ded162 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -87,4 +87,4 @@ module_init(init_rc_map_adstech_dvb_t_pci)
 module_exit(exit_rc_map_adstech_dvb_t_pci)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 8c92ff95f94d11eeadd24a38880a387d98ad8b89..bf9efa007e1c98e4b2d1b5dfc7db1faa465a1459 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -78,4 +78,4 @@ module_init(init_rc_map_apac_viewcomp)
 module_exit(exit_rc_map_apac_viewcomp)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2caf2117759b2be2307faa63d3d6d293975d3b60..9e674ba5dd4fb4e11d49b764aa6929b30bc91fcf 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -89,4 +89,4 @@ module_init(init_rc_map_asus_pc39)
 module_exit(exit_rc_map_asus_pc39)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index ba76609c5936ac4aec078a4f9f60449a23af05aa..e45de35f528fda1a98e5c0ef9c9acc086f1f9c84 100644 (file)
@@ -1,6 +1,6 @@
 /* asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
  *
- * Copyright (c) 2012 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2012 by Mauro Carvalho Chehab
  *
  * Based on a previous patch from Remi Schwartz <remi.schwartz@gmail.com>
  *
@@ -88,4 +88,4 @@ module_init(init_rc_map_asus_ps3_100)
 module_exit(exit_rc_map_asus_ps3_100)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2031224a20279c6d0882a40908f6bbcc6cdb299b..91392d4cfd6d8184bd6daac934e8952ce68c0803 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -67,4 +67,4 @@ module_init(init_rc_map_ati_tv_wonder_hd_600)
 module_exit(exit_rc_map_ati_tv_wonder_hd_600)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 894939ac17f2c47b8998b9d8b480371b9c130754..ff30a71d623e3acd2d927d7d5a6f7c9a9f3f8c05 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -73,4 +73,4 @@ module_init(init_rc_map_avermedia_a16d)
 module_exit(exit_rc_map_avermedia_a16d)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index d2aaf5b9e39f074c51d160cfddb0c1bb1a627d1e..d7471a6de9b40488cd3d42eb905e3c75e6d50d5a 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -95,4 +95,4 @@ module_init(init_rc_map_avermedia_cardbus)
 module_exit(exit_rc_map_avermedia_cardbus)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index dc2baf062398e5352e129ffba2574ce1f94b8073..e2417d6331fe716ada7c9609d5a47bed6695b344 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -76,4 +76,4 @@ module_init(init_rc_map_avermedia_dvbt)
 module_exit(exit_rc_map_avermedia_dvbt)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 04269d31fa193781f9f817117cba420fc2c903a6..843598a5f1b5eed846f4990e9f123d9315d326c3 100644 (file)
@@ -1,6 +1,6 @@
 /* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -145,4 +145,4 @@ module_init(init_rc_map_avermedia_m135a)
 module_exit(exit_rc_map_avermedia_m135a)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index e83b1a1939bfe49c05908ebef4c5b3d2548154ef..b24e7481ac210a0dbf8ce727403414cd839d5288 100644 (file)
@@ -93,4 +93,4 @@ module_init(init_rc_map_avermedia_m733a_rm_k6)
 module_exit(exit_rc_map_avermedia_m733a_rm_k6)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index c6063dfcd507ab46efd726fe7658d2334367b196..3f68fbecc188bdb5f78c9c236cee7a1d079ebeeb 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -84,4 +84,4 @@ module_init(init_rc_map_avermedia)
 module_exit(exit_rc_map_avermedia)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 14f78451e64e2a3bf6c0ed5e477709b0acc875df..c35bc5b835c41ec7c82d3caaf1ba4bb9d6065234 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -83,4 +83,4 @@ module_init(init_rc_map_avertv_303)
 module_exit(exit_rc_map_avertv_303)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 086b4b1f19e1da6f30477301feb53e768552ff9c..1fc344e9daa7ae69706368fb49157b4a3d661293 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -106,4 +106,4 @@ module_init(init_rc_map_behold_columbus)
 module_exit(exit_rc_map_behold_columbus)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 0877e348094134ba9e1061ae137ea6580ef03e2c..d6519f8ac95a62af73972225e094d8764b0d81e7 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -139,4 +139,4 @@ module_init(init_rc_map_behold)
 module_exit(exit_rc_map_behold)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 8311e092c0984ce22a92c7b093fd739963d2fa27..b196a5f436a3d4b9399a5db67fa3ab60c904b896 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -91,4 +91,4 @@ module_init(init_rc_map_budget_ci_old)
 module_exit(exit_rc_map_budget_ci_old)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 0c87fbaf99ab7752e31cc03cb6332345657496fd..a099c080bf8c8e91e60808ef36aac478793330d5 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -82,4 +82,4 @@ module_init(init_rc_map_cinergy_1400)
 module_exit(exit_rc_map_cinergy_1400)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 309e9e3fb6f30b9d5e2ad3ae9967d84728917bf2..b0f4328bdd6fe4f9e5e3af8a30dbc20ba945ed1d 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -76,4 +76,4 @@ module_init(init_rc_map_cinergy)
 module_exit(exit_rc_map_cinergy)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 492a05ade7e190b3d3c874f7b2942b3138a796cd..a0fa543c9f9e7180bf7ab9ff6aa74afe069808ec 100644 (file)
@@ -1,6 +1,6 @@
 /* rc-dvb0700-big.c - Keytable for devices in dvb0700
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * TODO: This table is a real mess, as it merges RC codes from several
  * devices into a big table. It also has both RC-5 and NEC codes inside.
@@ -122,4 +122,4 @@ module_init(init_rc_map)
 module_exit(exit_rc_map)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 454ea596a7eef89fdabbcf1dccfef4dfbd0f9ce8..907941145eb711c28904530d330e4a3188a10f38 100644 (file)
@@ -1,6 +1,6 @@
 /* rc-dvb0700-big.c - Keytable for devices in dvb0700
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * TODO: This table is a real mess, as it merges RC codes from several
  * devices into a big table. It also has both RC-5 and NEC codes inside.
@@ -233,4 +233,4 @@ module_init(init_rc_map)
 module_exit(exit_rc_map)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 67fc9fb0c007ceac45539911c1c51cf8217f07bd..46e7ae414cc82cd40139f85563945787d4082777 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -74,4 +74,4 @@ module_init(init_rc_map_dm1105_nec)
 module_exit(exit_rc_map_dm1105_nec)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 91ea91de91794af1c5fd69ed8ce6628d28ca5271..d2826b46fea2244d1f56a59a08a6abfeb89385d7 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -76,4 +76,4 @@ module_init(init_rc_map_dntv_live_dvb_t)
 module_exit(exit_rc_map_dntv_live_dvb_t)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index fd680d4d3eb69a2ecb36693f2b76d7ac7b51a003..0d74769467b5b05e2eb5b19c8a51a56e6a28bc93 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -95,4 +95,4 @@ module_init(init_rc_map_dntv_live_dvbt_pro)
 module_exit(exit_rc_map_dntv_live_dvbt_pro)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index d1fcd64c0f90360f344155e6d7ef1b84ecba3109..7f1e06be175b37667cc75d10f890a2b5683392c0 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -67,4 +67,4 @@ module_init(init_rc_map_em_terratec)
 module_exit(exit_rc_map_em_terratec)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2fe45e41fe49afad6840e128ef6f08bed2adff60..4fc3904daf061e73a517a4c2d1fd20b29f775ad9 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -79,4 +79,4 @@ module_init(init_rc_map_encore_enltv_fm53)
 module_exit(exit_rc_map_encore_enltv_fm53)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 223de75a6d1c7cddc51110eccd96e92d34db3346..f1914e23d203879ed377fcee50eaadab277539e6 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -110,4 +110,4 @@ module_init(init_rc_map_encore_enltv)
 module_exit(exit_rc_map_encore_enltv)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 669cbff22b7e11b7d625e87232474a3c4cf5840e..9c6c55240d18865abda9f4a2969d1c4f68f126f8 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -88,4 +88,4 @@ module_init(init_rc_map_encore_enltv2)
 module_exit(exit_rc_map_encore_enltv2)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2c647fc2591606195cd9cb21128b4f48b950d191..2370d2a3deb660b2075cddd2df8f909cda249f7d 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -59,4 +59,4 @@ module_init(init_rc_map_evga_indtube)
 module_exit(exit_rc_map_evga_indtube)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 76921445c1d9822ab75aa6bfb8ff5bffa4ecd843..b5c96ed84376d1dab82d95590764db63b2d01b7d 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -94,4 +94,4 @@ module_init(init_rc_map_eztv)
 module_exit(exit_rc_map_eztv)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 3a6bba311b08ad0d4b60663a3e9c54b4d50c2a0d..25cb89fac03c984f01794517bd473c1ffe09294e 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -75,4 +75,4 @@ module_init(init_rc_map_flydvb)
 module_exit(exit_rc_map_flydvb)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index bf9da584643b34da608995ff4ac55b5d56d0bbe3..e71377dd0534455b0ba4400b39fd1f9690c56f5c 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -68,4 +68,4 @@ module_init(init_rc_map_flyvideo)
 module_exit(exit_rc_map_flyvideo)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2f0970fe78326710ca541e97d41d700e34d57306..cf0608dc83d50a82490ef746e4705d75deca6d17 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -96,4 +96,4 @@ module_init(init_rc_map_fusionhdtv_mce)
 module_exit(exit_rc_map_fusionhdtv_mce)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 0e98ec467c34b47d4b576ec798459b4361c4987d..03575bdb2ecad444ed710f1827c4252a31751dbe 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -79,4 +79,4 @@ module_init(init_rc_map_gadmei_rm008z)
 module_exit(exit_rc_map_gadmei_rm008z)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index a2e2faa1d1b3708ec7b454d0eebb9e137a890735..b2ab13b0dcb1d1e6357a4f9c6d117978f6a5fe27 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -82,4 +82,4 @@ module_init(init_rc_map_genius_tvgo_a11mce)
 module_exit(exit_rc_map_genius_tvgo_a11mce)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 864614e19314fd7e555392dc17ca7c835ab493b8..229a36ac7f0ab3b877cf23e73da95daeb4ed3495 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -77,4 +77,4 @@ module_init(init_rc_map_gotview7135)
 module_exit(exit_rc_map_gotview7135)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 929bbbc163931ca9e9883b471d293754d0f75e33..36d57f7c532b1802afeef07fb061d3dc0950a5c5 100644 (file)
@@ -8,7 +8,7 @@
  *     - Hauppauge Black;
  *     - DSR-0112 remote bundled with Haupauge MiniStick.
  *
- * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab
  *
  * 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
@@ -290,4 +290,4 @@ module_init(init_rc_map_rc5_hauppauge_new)
 module_exit(exit_rc_map_rc5_hauppauge_new)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 34540dfc3df543d4c94baad09f2cfb87f1e35e00..9ee154cb0c6bac3ecbe08f38c5831a2fdb91982b 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -86,4 +86,4 @@ module_init(init_rc_map_iodata_bctv7e)
 module_exit(exit_rc_map_iodata_bctv7e)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 4264a787c150d304f4de50454eba753d3e9ed3ec..60803a732c0866ddcb24a5d1f81728dc3caac512 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -85,4 +85,4 @@ module_init(init_rc_map_kaiomy)
 module_exit(exit_rc_map_kaiomy)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index e48cd267dda69cf69256a720b6f904065eef42e4..ba087eed1ed9b0b6d4a039edc3a5f81947d009a5 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -81,4 +81,4 @@ module_init(init_rc_map_kworld_315u)
 module_exit(exit_rc_map_kworld_315u)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 233bb5ee087f3412771a4c437de6951cd3957b88..b92e571f4defa600a82db2b5b64ba39a215cd0a8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 2010 by Kyle Strickland
  *   (based on kworld-plus-tv-analog.c by
- *    Mauro Carvalho Chehab <mchehab@redhat.com>)
+ *    Mauro Carvalho Chehab)
  *
  * 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
index 32998d6b787d50f260c4e93d82c4a39d87741d95..edc868564f99ef30dedb69214ab196bbb1416170 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -97,4 +97,4 @@ module_init(init_rc_map_kworld_plus_tv_analog)
 module_exit(exit_rc_map_kworld_plus_tv_analog)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index e7038bb71bf6e8207c3dedd2c859c68b033bce47..92424ef2aaa6482d74fbbadf87da7fedc7cedae2 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -132,4 +132,4 @@ module_init(init_rc_map_manli)
 module_exit(exit_rc_map_manli)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index c393d8a50bcaad13ad33b8c96dae1c0ab4356e19..fd7a55c561671b5764546bc4fce88503d3b88081 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -121,4 +121,4 @@ module_init(init_rc_map_msi_tvanywhere_plus)
 module_exit(exit_rc_map_msi_tvanywhere_plus)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index a7003d3a3c8ac9c26cca0ab853826e0578aebb2f..4233a8d4d63ef4388ac4993ce80452874bae434d 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -67,4 +67,4 @@ module_init(init_rc_map_msi_tvanywhere)
 module_exit(exit_rc_map_msi_tvanywhere)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 3f0ddd7afd30bb6e804622a8657a293a09534534..8ec881adb7cfb52e90f0448478b38ae569b78937 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -94,4 +94,4 @@ module_init(init_rc_map_nebula)
 module_exit(exit_rc_map_nebula)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 8d4dae2e2ece720c1073875dadef5177aba330a3..292bbad35d210902a966e66e420b997e9577f304 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 
 /* Terratec Cinergy Hybrid T USB XS FM
-   Mauro Carvalho Chehab <mchehab@redhat.com>
+   Mauro Carvalho Chehab
  */
 
 static struct rc_map_table nec_terratec_cinergy_xs[] = {
@@ -155,4 +155,4 @@ module_init(init_rc_map_nec_terratec_cinergy_xs)
 module_exit(exit_rc_map_nec_terratec_cinergy_xs)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 9e65f07157abcb0745bce5c3a21ada596cab51f9..ca1b82a2c54f5f6ff65e3510ce321c8edd0bd0da 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -83,4 +83,4 @@ module_init(init_rc_map_norwood)
 module_exit(exit_rc_map_norwood)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 65d0cfc3c33b62be70040f11691d1d28a1410343..1fb946024512a06e500cf18a7e8ecacddd11e650 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -78,4 +78,4 @@ module_init(init_rc_map_npgtech)
 module_exit(exit_rc_map_npgtech)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index bf2cbdfe2e32f7c9645d8ff7fd26099f21c269a4..5ef01ab3fd500e44ae7b7c9748340b37182284fb 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -78,4 +78,4 @@ module_init(init_rc_map_pctv_sedna)
 module_exit(exit_rc_map_pctv_sedna)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index b46cd8fe64383d7216ffc8901234f2b1eff2ab77..a218b471a4caeab76d3a9a0eec73abf7106d67cf 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -92,4 +92,4 @@ module_init(init_rc_map_pinnacle_color)
 module_exit(exit_rc_map_pinnacle_color)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index d525df9ad868b9b9a6f6143b4f300897219ecc50..4a3f467a47a249b6da0eb4d9ba2e7cb2365ad6af 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -87,4 +87,4 @@ module_init(init_rc_map_pinnacle_grey)
 module_exit(exit_rc_map_pinnacle_grey)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index a4603d035374e31ff58e3e892118a647904f3036..e89cc10b68bf33149b566427402ff5d871a4ba70 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -68,4 +68,4 @@ module_init(init_rc_map_pinnacle_pctv_hd)
 module_exit(exit_rc_map_pinnacle_pctv_hd)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 33eb64333c6f738fdc4673cb6b85b3ca4eebde02..d967c3816fdc9b9b88fb39dbd7a024a9e89ccc11 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -75,4 +75,4 @@ module_init(init_rc_map_pixelview)
 module_exit(exit_rc_map_pixelview)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 21f4dd25c2ec872c4bb6be49cdca4ea8e88d7089..224d0efaa6e5504915bf40dc21b8920748cfc8c8 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -81,4 +81,4 @@ module_init(init_rc_map_pixelview)
 module_exit(exit_rc_map_pixelview)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index f944ad2cac2b8697bd33e8acc5aa17c129c46773..781d788d6b6d8c37fafc409707d0ae2c4a94a6fb 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -81,4 +81,4 @@ module_init(init_rc_map_pixelview_new)
 module_exit(exit_rc_map_pixelview_new)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index a6020eea7b951b9e091433ba238616dd66e492bf..39e6feaa35a3217c5bf7668dfdd4c6df9cde7949 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -80,4 +80,4 @@ module_init(init_rc_map_pixelview)
 module_exit(exit_rc_map_pixelview)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index e74c571a5e44a34f46d7fe832b75a35c22e7621c..e96fa3ab9f4bf4e3996794bae83202aa17f28dd6 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -79,4 +79,4 @@ module_init(init_rc_map_powercolor_real_angel)
 module_exit(exit_rc_map_powercolor_real_angel)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index adee8035ce9624c102ca9f6c893ba85eced8d9a1..eef626ee02dff0b1174087d73ce62d54151152f9 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -67,4 +67,4 @@ module_init(init_rc_map_proteus_2309)
 module_exit(exit_rc_map_proteus_2309)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 722597a20e4ac708a9e2b8d8aa56f6ebae32a605..cec6fe46682906f1befe0e3b24f2136fb176542a 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -79,4 +79,4 @@ module_init(init_rc_map_purpletv)
 module_exit(exit_rc_map_purpletv)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 0105d63c07a90bb02e6e45d09b91d66a685aecc4..5ac89ce8c053c29067f8ffba4e820fded39f2f8d 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -76,4 +76,4 @@ module_init(init_rc_map_pv951)
 module_exit(exit_rc_map_pv951)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 073694d50f49e6e6faa2874e3a8733ba0a210983..9f778bd091db3d51def174993a416b31b1cd4e83 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -76,4 +76,4 @@ module_init(init_rc_map_real_audio_220_32_keys)
 module_exit(exit_rc_map_real_audio_220_32_keys)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 5039be782bc595068f66cd5c16b814f48f178718..24ce2a252502bd37c3cb17c30722dd31f68c7925 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -73,4 +73,4 @@ module_init(init_rc_map_tbs_nec)
 module_exit(exit_rc_map_tbs_nec)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 53629fb0151f98293de5044f13537c13487581b8..97eb83ab5a351d95c9405679d75ff29b6005aaa0 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -90,4 +90,4 @@ module_init(init_rc_map_terratec_cinergy_xs)
 module_exit(exit_rc_map_terratec_cinergy_xs)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index f2c3b75d85800e1cca63bd50bcaaa34167f6178a..38e0c0875596d17b8df2c39d4a3f8d1a7dc50aec 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -86,4 +86,4 @@ module_init(init_rc_map_tevii_nec)
 module_exit(exit_rc_map_tevii_nec)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 454e062956925ee6b82ad195f10ca6bca82d4516..5cc1b456e3299893b37e27f92310453cfc0e898f 100644 (file)
  * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle,
  * which also ships with a TiVo-branded IR transceiver, supported by the mceusb
  * driver. Note that the remote uses an NEC-ish protocol, but instead of having
- * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the
+ * a command/not_command pair, it has a vendor ID of 0x3085, but some keys, the
  * NEC extended checksums do pass, so the table presently has the intended
  * values and the checksum-passed versions for those keys.
  */
 static struct rc_map_table tivo[] = {
-       { 0xa10c900f, KEY_MEDIA },      /* TiVo Button */
-       { 0xa10c0807, KEY_POWER2 },     /* TV Power */
-       { 0xa10c8807, KEY_TV },         /* Live TV/Swap */
-       { 0xa10c2c03, KEY_VIDEO_NEXT }, /* TV Input */
-       { 0xa10cc807, KEY_INFO },
-       { 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */
+       { 0x3085f009, KEY_MEDIA },      /* TiVo Button */
+       { 0x3085e010, KEY_POWER2 },     /* TV Power */
+       { 0x3085e011, KEY_TV },         /* Live TV/Swap */
+       { 0x3085c034, KEY_VIDEO_NEXT }, /* TV Input */
+       { 0x3085e013, KEY_INFO },
+       { 0x3085a05f, KEY_CYCLEWINDOWS }, /* Window */
        { 0x0085305f, KEY_CYCLEWINDOWS },
-       { 0xa10c6c03, KEY_EPG },        /* Guide */
+       { 0x3085c036, KEY_EPG },        /* Guide */
 
-       { 0xa10c2807, KEY_UP },
-       { 0xa10c6807, KEY_DOWN },
-       { 0xa10ce807, KEY_LEFT },
-       { 0xa10ca807, KEY_RIGHT },
+       { 0x3085e014, KEY_UP },
+       { 0x3085e016, KEY_DOWN },
+       { 0x3085e017, KEY_LEFT },
+       { 0x3085e015, KEY_RIGHT },
 
-       { 0xa10c1807, KEY_SCROLLDOWN }, /* Red Thumbs Down */
-       { 0xa10c9807, KEY_SELECT },
-       { 0xa10c5807, KEY_SCROLLUP },   /* Green Thumbs Up */
+       { 0x3085e018, KEY_SCROLLDOWN }, /* Red Thumbs Down */
+       { 0x3085e019, KEY_SELECT },
+       { 0x3085e01a, KEY_SCROLLUP },   /* Green Thumbs Up */
 
-       { 0xa10c3807, KEY_VOLUMEUP },
-       { 0xa10cb807, KEY_VOLUMEDOWN },
-       { 0xa10cd807, KEY_MUTE },
-       { 0xa10c040b, KEY_RECORD },
-       { 0xa10c7807, KEY_CHANNELUP },
-       { 0xa10cf807, KEY_CHANNELDOWN },
+       { 0x3085e01c, KEY_VOLUMEUP },
+       { 0x3085e01d, KEY_VOLUMEDOWN },
+       { 0x3085e01b, KEY_MUTE },
+       { 0x3085d020, KEY_RECORD },
+       { 0x3085e01e, KEY_CHANNELUP },
+       { 0x3085e01f, KEY_CHANNELDOWN },
        { 0x0085301f, KEY_CHANNELDOWN },
 
-       { 0xa10c840b, KEY_PLAY },
-       { 0xa10cc40b, KEY_PAUSE },
-       { 0xa10ca40b, KEY_SLOW },
-       { 0xa10c440b, KEY_REWIND },
-       { 0xa10c240b, KEY_FASTFORWARD },
-       { 0xa10c640b, KEY_PREVIOUS },
-       { 0xa10ce40b, KEY_NEXT },       /* ->| */
+       { 0x3085d021, KEY_PLAY },
+       { 0x3085d023, KEY_PAUSE },
+       { 0x3085d025, KEY_SLOW },
+       { 0x3085d022, KEY_REWIND },
+       { 0x3085d024, KEY_FASTFORWARD },
+       { 0x3085d026, KEY_PREVIOUS },
+       { 0x3085d027, KEY_NEXT },       /* ->| */
 
-       { 0xa10c220d, KEY_ZOOM },       /* Aspect */
-       { 0xa10c120d, KEY_STOP },
-       { 0xa10c520d, KEY_DVD },        /* DVD Menu */
+       { 0x3085b044, KEY_ZOOM },       /* Aspect */
+       { 0x3085b048, KEY_STOP },
+       { 0x3085b04a, KEY_DVD },        /* DVD Menu */
 
-       { 0xa10c140b, KEY_NUMERIC_1 },
-       { 0xa10c940b, KEY_NUMERIC_2 },
-       { 0xa10c540b, KEY_NUMERIC_3 },
-       { 0xa10cd40b, KEY_NUMERIC_4 },
-       { 0xa10c340b, KEY_NUMERIC_5 },
-       { 0xa10cb40b, KEY_NUMERIC_6 },
-       { 0xa10c740b, KEY_NUMERIC_7 },
-       { 0xa10cf40b, KEY_NUMERIC_8 },
+       { 0x3085d028, KEY_NUMERIC_1 },
+       { 0x3085d029, KEY_NUMERIC_2 },
+       { 0x3085d02a, KEY_NUMERIC_3 },
+       { 0x3085d02b, KEY_NUMERIC_4 },
+       { 0x3085d02c, KEY_NUMERIC_5 },
+       { 0x3085d02d, KEY_NUMERIC_6 },
+       { 0x3085d02e, KEY_NUMERIC_7 },
+       { 0x3085d02f, KEY_NUMERIC_8 },
        { 0x0085302f, KEY_NUMERIC_8 },
-       { 0xa10c0c03, KEY_NUMERIC_9 },
-       { 0xa10c8c03, KEY_NUMERIC_0 },
-       { 0xa10ccc03, KEY_ENTER },
-       { 0xa10c4c03, KEY_CLEAR },
+       { 0x3085c030, KEY_NUMERIC_9 },
+       { 0x3085c031, KEY_NUMERIC_0 },
+       { 0x3085c033, KEY_ENTER },
+       { 0x3085c032, KEY_CLEAR },
 };
 
 static struct rc_map_list tivo_map = {
index 80217ffc91db39738e2936136444f353e447979e..c766d3b2b6b00c51907156d96184d0c91584098e 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -80,4 +80,4 @@ module_init(init_rc_map_tt_1500)
 module_exit(exit_rc_map_tt_1500)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 8bfc3e8d909d61e2abda64dc58dea019e719de9a..8a354775a2d8c711f94c57308118c9c0d64a099f 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -83,4 +83,4 @@ module_init(init_rc_map_videomate_s350)
 module_exit(exit_rc_map_videomate_s350)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 390ce9431b35aa43ac676d6765e5c0282dbe8a10..eb0cda7766c4f829ba0db0264ff7d9729d86a0cf 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -85,4 +85,4 @@ module_init(init_rc_map_videomate_tv_pvr)
 module_exit(exit_rc_map_videomate_tv_pvr)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2852bf705064f8cfd794a35aece5baf5c1d3d616..c1dd598e828ef7c9a2ba19fb093cd98fbb43396c 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -80,4 +80,4 @@ module_init(init_rc_map_winfast_usbii_deluxe)
 module_exit(exit_rc_map_winfast_usbii_deluxe)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index 2df1cba236002c601a18c89357f1f2fc2f1f9333..8a779da1e97330d7fdca209858c62ce2d55c82b6 100644 (file)
@@ -2,7 +2,7 @@
  *
  * keymap imported from ir-keymaps.c
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -100,4 +100,4 @@ module_init(init_rc_map_winfast)
 module_exit(exit_rc_map_winfast)
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
index a25bb1581e4662fa1807ab6bc8b86499ca17a595..5d8f3d40d820ba4059ad97291cf06904074b0381 100644 (file)
@@ -84,7 +84,7 @@
 #define MCE_PORT_IR            0x4     /* (0x4 << 5) | MCE_CMD = 0x9f */
 #define MCE_PORT_SYS           0x7     /* (0x7 << 5) | MCE_CMD = 0xff */
 #define MCE_PORT_SER           0x6     /* 0xc0 thru 0xdf flush & 0x1f bytes */
-#define MCE_PORT_MASK  0xe0    /* Mask out command bits */
+#define MCE_PORT_MASK          0xe0    /* Mask out command bits */
 
 /* Command port headers */
 #define MCE_CMD_PORT_IR                0x9f    /* IR-related cmd/rsp */
 #define MCE_COMMAND_IRDATA     0x80
 #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
 
-/* module parameters */
-#ifdef CONFIG_USB_DEBUG
-static bool debug = 1;
-#else
-static bool debug;
-#endif
-
-#define mce_dbg(dev, fmt, ...)                                 \
-       do {                                                    \
-               if (debug)                                      \
-                       dev_info(dev, fmt, ## __VA_ARGS__);     \
-       } while (0)
-
 /* general constants */
 #define SEND_FLAG_IN_PROGRESS  1
 #define SEND_FLAG_COMPLETE     2
@@ -541,16 +528,13 @@ static int mceusb_cmd_datasize(u8 cmd, u8 subcmd)
 static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
                                 int offset, int len, bool out)
 {
-       char codes[USB_BUFLEN * 3 + 1];
-       char inout[9];
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+       char *inout;
        u8 cmd, subcmd, data1, data2, data3, data4;
        struct device *dev = ir->dev;
-       int i, start, skip = 0;
+       int start, skip = 0;
        u32 carrier, period;
 
-       if (!debug)
-               return;
-
        /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
        if (ir->flags.microsoft_gen1 && !out && !offset)
                skip = 2;
@@ -558,16 +542,10 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
        if (len <= skip)
                return;
 
-       for (i = 0; i < len && i < USB_BUFLEN; i++)
-               snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff);
-
-       dev_info(dev, "%sx data: %s(length=%d)\n",
-                (out ? "t" : "r"), codes, len);
+       dev_dbg(dev, "%cx data: %*ph (length=%d)",
+               (out ? 't' : 'r'), min(len, USB_BUFLEN), buf, len);
 
-       if (out)
-               strcpy(inout, "Request\0");
-       else
-               strcpy(inout, "Got\0");
+       inout = out ? "Request" : "Got";
 
        start  = offset + skip;
        cmd    = buf[start] & 0xff;
@@ -583,50 +561,50 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
                        break;
                if ((subcmd == MCE_CMD_PORT_SYS) &&
                    (data1 == MCE_CMD_RESUME))
-                       dev_info(dev, "Device resume requested\n");
+                       dev_dbg(dev, "Device resume requested");
                else
-                       dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
+                       dev_dbg(dev, "Unknown command 0x%02x 0x%02x",
                                 cmd, subcmd);
                break;
        case MCE_CMD_PORT_SYS:
                switch (subcmd) {
                case MCE_RSP_EQEMVER:
                        if (!out)
-                               dev_info(dev, "Emulator interface version %x\n",
+                               dev_dbg(dev, "Emulator interface version %x",
                                         data1);
                        break;
                case MCE_CMD_G_REVISION:
                        if (len == 2)
-                               dev_info(dev, "Get hw/sw rev?\n");
+                               dev_dbg(dev, "Get hw/sw rev?");
                        else
-                               dev_info(dev, "hw/sw rev 0x%02x 0x%02x "
-                                        "0x%02x 0x%02x\n", data1, data2,
+                               dev_dbg(dev, "hw/sw rev 0x%02x 0x%02x 0x%02x 0x%02x",
+                                        data1, data2,
                                         buf[start + 4], buf[start + 5]);
                        break;
                case MCE_CMD_RESUME:
-                       dev_info(dev, "Device resume requested\n");
+                       dev_dbg(dev, "Device resume requested");
                        break;
                case MCE_RSP_CMD_ILLEGAL:
-                       dev_info(dev, "Illegal PORT_SYS command\n");
+                       dev_dbg(dev, "Illegal PORT_SYS command");
                        break;
                case MCE_RSP_EQWAKEVERSION:
                        if (!out)
-                               dev_info(dev, "Wake version, proto: 0x%02x, "
+                               dev_dbg(dev, "Wake version, proto: 0x%02x, "
                                         "payload: 0x%02x, address: 0x%02x, "
-                                        "version: 0x%02x\n",
+                                        "version: 0x%02x",
                                         data1, data2, data3, data4);
                        break;
                case MCE_RSP_GETPORTSTATUS:
                        if (!out)
                                /* We use data1 + 1 here, to match hw labels */
-                               dev_info(dev, "TX port %d: blaster is%s connected\n",
+                               dev_dbg(dev, "TX port %d: blaster is%s connected",
                                         data1 + 1, data4 ? " not" : "");
                        break;
                case MCE_CMD_FLASHLED:
-                       dev_info(dev, "Attempting to flash LED\n");
+                       dev_dbg(dev, "Attempting to flash LED");
                        break;
                default:
-                       dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
+                       dev_dbg(dev, "Unknown command 0x%02x 0x%02x",
                                 cmd, subcmd);
                        break;
                }
@@ -634,13 +612,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
        case MCE_CMD_PORT_IR:
                switch (subcmd) {
                case MCE_CMD_SIG_END:
-                       dev_info(dev, "End of signal\n");
+                       dev_dbg(dev, "End of signal");
                        break;
                case MCE_CMD_PING:
-                       dev_info(dev, "Ping\n");
+                       dev_dbg(dev, "Ping");
                        break;
                case MCE_CMD_UNKNOWN:
-                       dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
+                       dev_dbg(dev, "Resp to 9f 05 of 0x%02x 0x%02x",
                                 data1, data2);
                        break;
                case MCE_RSP_EQIRCFS:
@@ -649,51 +627,51 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
                        if (!period)
                                break;
                        carrier = (1000 * 1000) / period;
-                       dev_info(dev, "%s carrier of %u Hz (period %uus)\n",
+                       dev_dbg(dev, "%s carrier of %u Hz (period %uus)",
                                 inout, carrier, period);
                        break;
                case MCE_CMD_GETIRCFS:
-                       dev_info(dev, "Get carrier mode and freq\n");
+                       dev_dbg(dev, "Get carrier mode and freq");
                        break;
                case MCE_RSP_EQIRTXPORTS:
-                       dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
+                       dev_dbg(dev, "%s transmit blaster mask of 0x%02x",
                                 inout, data1);
                        break;
                case MCE_RSP_EQIRTIMEOUT:
                        /* value is in units of 50us, so x*50/1000 ms */
                        period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000;
-                       dev_info(dev, "%s receive timeout of %d ms\n",
+                       dev_dbg(dev, "%s receive timeout of %d ms",
                                 inout, period);
                        break;
                case MCE_CMD_GETIRTIMEOUT:
-                       dev_info(dev, "Get receive timeout\n");
+                       dev_dbg(dev, "Get receive timeout");
                        break;
                case MCE_CMD_GETIRTXPORTS:
-                       dev_info(dev, "Get transmit blaster mask\n");
+                       dev_dbg(dev, "Get transmit blaster mask");
                        break;
                case MCE_RSP_EQIRRXPORTEN:
-                       dev_info(dev, "%s %s-range receive sensor in use\n",
+                       dev_dbg(dev, "%s %s-range receive sensor in use",
                                 inout, data1 == 0x02 ? "short" : "long");
                        break;
                case MCE_CMD_GETIRRXPORTEN:
                /* aka MCE_RSP_EQIRRXCFCNT */
                        if (out)
-                               dev_info(dev, "Get receive sensor\n");
+                               dev_dbg(dev, "Get receive sensor");
                        else if (ir->learning_enabled)
-                               dev_info(dev, "RX pulse count: %d\n",
+                               dev_dbg(dev, "RX pulse count: %d",
                                         ((data1 << 8) | data2));
                        break;
                case MCE_RSP_EQIRNUMPORTS:
                        if (out)
                                break;
-                       dev_info(dev, "Num TX ports: %x, num RX ports: %x\n",
+                       dev_dbg(dev, "Num TX ports: %x, num RX ports: %x",
                                 data1, data2);
                        break;
                case MCE_RSP_CMD_ILLEGAL:
-                       dev_info(dev, "Illegal PORT_IR command\n");
+                       dev_dbg(dev, "Illegal PORT_IR command");
                        break;
                default:
-                       dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
+                       dev_dbg(dev, "Unknown command 0x%02x 0x%02x",
                                 cmd, subcmd);
                        break;
                }
@@ -703,10 +681,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
        }
 
        if (cmd == MCE_IRDATA_TRAILER)
-               dev_info(dev, "End of raw IR data\n");
+               dev_dbg(dev, "End of raw IR data");
        else if ((cmd != MCE_CMD_PORT_IR) &&
                 ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA))
-               dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem);
+               dev_dbg(dev, "Raw IR data, %d pulse/space samples", ir->rem);
+#endif
 }
 
 static void mce_async_callback(struct urb *urb)
@@ -718,10 +697,25 @@ static void mce_async_callback(struct urb *urb)
                return;
 
        ir = urb->context;
-       if (ir) {
+
+       switch (urb->status) {
+       /* success */
+       case 0:
                len = urb->actual_length;
 
                mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
+               break;
+
+       case -ECONNRESET:
+       case -ENOENT:
+       case -EILSEQ:
+       case -ESHUTDOWN:
+               break;
+
+       case -EPIPE:
+       default:
+               dev_err(ir->dev, "Error: request urb status = %d", urb->status);
+               break;
        }
 
        /* the transfer buffer and urb were allocated in mce_request_packet */
@@ -770,17 +764,17 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
                return;
        }
 
-       mce_dbg(dev, "receive request called (size=%#x)\n", size);
+       dev_dbg(dev, "receive request called (size=%#x)", size);
 
        async_urb->transfer_buffer_length = size;
        async_urb->dev = ir->usbdev;
 
        res = usb_submit_urb(async_urb, GFP_ATOMIC);
        if (res) {
-               mce_dbg(dev, "receive request FAILED! (res=%d)\n", res);
+               dev_err(dev, "receive request FAILED! (res=%d)", res);
                return;
        }
-       mce_dbg(dev, "receive request complete (res=%d)\n", res);
+       dev_dbg(dev, "receive request complete (res=%d)", res);
 }
 
 static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
@@ -895,8 +889,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
                        ir->carrier = carrier;
                        cmdbuf[2] = MCE_CMD_SIG_END;
                        cmdbuf[3] = MCE_IRDATA_TRAILER;
-                       mce_dbg(ir->dev, "%s: disabling carrier "
-                               "modulation\n", __func__);
+                       dev_dbg(ir->dev, "disabling carrier modulation");
                        mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
                        return carrier;
                }
@@ -907,8 +900,8 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
                                ir->carrier = carrier;
                                cmdbuf[2] = prescaler;
                                cmdbuf[3] = divisor;
-                               mce_dbg(ir->dev, "%s: requesting %u HZ "
-                                       "carrier\n", __func__, carrier);
+                               dev_dbg(ir->dev, "requesting %u HZ carrier",
+                                                               carrier);
 
                                /* Transmit new carrier to mce device */
                                mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
@@ -998,7 +991,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                        rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
                                         * US_TO_NS(MCE_TIME_UNIT);
 
-                       mce_dbg(ir->dev, "Storing %s with duration %d\n",
+                       dev_dbg(ir->dev, "Storing %s with duration %d",
                                rawir.pulse ? "pulse" : "space",
                                rawir.duration);
 
@@ -1032,7 +1025,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                        ir->parser_state = CMD_HEADER;
        }
        if (event) {
-               mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
+               dev_dbg(ir->dev, "processed IR data");
                ir_raw_event_handle(ir->rc);
        }
 }
@@ -1055,7 +1048,7 @@ static void mceusb_dev_recv(struct urb *urb)
 
        if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
                ir->send_flags = SEND_FLAG_COMPLETE;
-               mce_dbg(ir->dev, "setup answer received %d bytes\n",
+               dev_dbg(ir->dev, "setup answer received %d bytes\n",
                        buf_len);
        }
 
@@ -1067,13 +1060,14 @@ static void mceusb_dev_recv(struct urb *urb)
 
        case -ECONNRESET:
        case -ENOENT:
+       case -EILSEQ:
        case -ESHUTDOWN:
                usb_unlink_urb(urb);
                return;
 
        case -EPIPE:
        default:
-               mce_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
+               dev_err(ir->dev, "Error: urb status = %d", urb->status);
                break;
        }
 
@@ -1095,7 +1089,7 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
 
        data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL);
        if (!data) {
-               dev_err(dev, "%s: memory allocation failed!\n", __func__);
+               dev_err(dev, "%s: memory allocation failed!", __func__);
                return;
        }
 
@@ -1106,28 +1100,28 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
        ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
                              USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
                              data, USB_CTRL_MSG_SZ, HZ * 3);
-       mce_dbg(dev, "%s - ret = %d\n", __func__, ret);
-       mce_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
-               __func__, data[0], data[1]);
+       dev_dbg(dev, "set address - ret = %d", ret);
+       dev_dbg(dev, "set address - data[0] = %d, data[1] = %d",
+                                               data[0], data[1]);
 
        /* set feature: bit rate 38400 bps */
        ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
                              USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
                              0xc04e, 0x0000, NULL, 0, HZ * 3);
 
-       mce_dbg(dev, "%s - ret = %d\n", __func__, ret);
+       dev_dbg(dev, "set feature - ret = %d", ret);
 
        /* bRequest 4: set char length to 8 bits */
        ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
                              4, USB_TYPE_VENDOR,
                              0x0808, 0x0000, NULL, 0, HZ * 3);
-       mce_dbg(dev, "%s - retB = %d\n", __func__, ret);
+       dev_dbg(dev, "set char length - retB = %d", ret);
 
        /* bRequest 2: set handshaking to use DTR/DSR */
        ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
                              2, USB_TYPE_VENDOR,
                              0x0000, 0x0100, NULL, 0, HZ * 3);
-       mce_dbg(dev, "%s - retC = %d\n", __func__, ret);
+       dev_dbg(dev, "set handshake  - retC = %d", ret);
 
        /* device resume */
        mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
@@ -1198,7 +1192,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
 
        rc = rc_allocate_device();
        if (!rc) {
-               dev_err(dev, "remote dev allocation failed\n");
+               dev_err(dev, "remote dev allocation failed");
                goto out;
        }
 
@@ -1217,7 +1211,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
        rc->dev.parent = dev;
        rc->priv = ir;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rc, RC_BIT_ALL);
        rc->timeout = MS_TO_NS(100);
        if (!ir->flags.no_tx) {
                rc->s_tx_mask = mceusb_set_tx_mask;
@@ -1230,7 +1224,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
 
        ret = rc_register_device(rc);
        if (ret < 0) {
-               dev_err(dev, "remote dev registration failed\n");
+               dev_err(dev, "remote dev registration failed");
                goto out;
        }
 
@@ -1258,7 +1252,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
        bool tx_mask_normal;
        int ir_intfnum;
 
-       mce_dbg(&intf->dev, "%s called\n", __func__);
+       dev_dbg(&intf->dev, "%s called", __func__);
 
        idesc  = intf->cur_altsetting;
 
@@ -1286,8 +1280,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
                        ep_in = ep;
                        ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
                        ep_in->bInterval = 1;
-                       mce_dbg(&intf->dev, "acceptable inbound endpoint "
-                               "found\n");
+                       dev_dbg(&intf->dev, "acceptable inbound endpoint found");
                }
 
                if ((ep_out == NULL)
@@ -1301,12 +1294,11 @@ static int mceusb_dev_probe(struct usb_interface *intf,
                        ep_out = ep;
                        ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
                        ep_out->bInterval = 1;
-                       mce_dbg(&intf->dev, "acceptable outbound endpoint "
-                               "found\n");
+                       dev_dbg(&intf->dev, "acceptable outbound endpoint found");
                }
        }
        if (ep_in == NULL) {
-               mce_dbg(&intf->dev, "inbound and/or endpoint not found\n");
+               dev_dbg(&intf->dev, "inbound and/or endpoint not found");
                return -ENODEV;
        }
 
@@ -1357,7 +1349,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
        ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        /* flush buffers on the device */
-       mce_dbg(&intf->dev, "Flushing receive buffers\n");
+       dev_dbg(&intf->dev, "Flushing receive buffers\n");
        mce_flush_rx_buffer(ir, maxp);
 
        /* figure out which firmware/emulator version this hardware has */
@@ -1382,10 +1374,9 @@ static int mceusb_dev_probe(struct usb_interface *intf,
        device_set_wakeup_capable(ir->dev, true);
        device_set_wakeup_enable(ir->dev, true);
 
-       dev_info(&intf->dev, "Registered %s with mce emulator interface "
-                "version %x\n", name, ir->emver);
-       dev_info(&intf->dev, "%x tx ports (0x%x cabled) and "
-                "%x rx sensors (0x%x active)\n",
+       dev_info(&intf->dev, "Registered %s with mce emulator interface version %x",
+               name, ir->emver);
+       dev_info(&intf->dev, "%x tx ports (0x%x cabled) and %x rx sensors (0x%x active)",
                 ir->num_txports, ir->txports_cabled,
                 ir->num_rxports, ir->rxports_active);
 
@@ -1399,7 +1390,7 @@ urb_in_alloc_fail:
 buf_in_alloc_fail:
        kfree(ir);
 mem_alloc_fail:
-       dev_err(&intf->dev, "%s: device setup failed!\n", __func__);
+       dev_err(&intf->dev, "%s: device setup failed!", __func__);
 
        return -ENOMEM;
 }
@@ -1427,7 +1418,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf)
 static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct mceusb_dev *ir = usb_get_intfdata(intf);
-       dev_info(ir->dev, "suspend\n");
+       dev_info(ir->dev, "suspend");
        usb_kill_urb(ir->urb_in);
        return 0;
 }
@@ -1435,7 +1426,7 @@ static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message)
 static int mceusb_dev_resume(struct usb_interface *intf)
 {
        struct mceusb_dev *ir = usb_get_intfdata(intf);
-       dev_info(ir->dev, "resume\n");
+       dev_info(ir->dev, "resume");
        if (usb_submit_urb(ir->urb_in, GFP_ATOMIC))
                return -EIO;
        return 0;
@@ -1457,6 +1448,3 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(usb, mceusb_dev_table);
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
index 21ee0dc1b7ec041826bf7d3dfd7f0634258bf965..d244e1a83f43f67f9c2f77156a920a42af591e9a 100644 (file)
@@ -330,9 +330,6 @@ static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt)
        /* Enable CIR Wake via PSOUT# (Pin60) */
        nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE);
 
-       /* enable cir interrupt of mouse/keyboard IRQ event */
-       nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS);
-
        /* enable pme interrupt of cir wakeup event */
        nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2);
 
@@ -456,7 +453,6 @@ static void nvt_enable_wake(struct nvt_dev *nvt)
 
        nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI);
        nvt_set_reg_bit(nvt, CIR_WAKE_ENABLE_BIT, CR_ACPI_CIR_WAKE);
-       nvt_set_reg_bit(nvt, CIR_INTR_MOUSE_IRQ_BIT, CR_ACPI_IRQ_EVENTS);
        nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2);
 
        nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE);
@@ -989,6 +985,12 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
                goto exit_free_dev_rdev;
 
        ret = -ENODEV;
+       /* activate pnp device */
+       if (pnp_activate_dev(pdev) < 0) {
+               dev_err(&pdev->dev, "Could not activate PNP device!\n");
+               goto exit_free_dev_rdev;
+       }
+
        /* validate pnp resources */
        if (!pnp_port_valid(pdev, 0) ||
            pnp_port_len(pdev, 0) < CIR_IOREG_LENGTH) {
@@ -1042,7 +1044,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
        /* Set up the rc device */
        rdev->priv = nvt;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        rdev->open = nvt_open;
        rdev->close = nvt_close;
        rdev->tx_ir = nvt_tx_ir;
index 07e83108df0f6834681887c1902c6742212324ed..e1cf23c3875b16ead52464d4e6ad3c479fd1e951 100644 (file)
@@ -363,7 +363,6 @@ struct nvt_dev {
 #define LOGICAL_DEV_ENABLE     0x01
 
 #define CIR_WAKE_ENABLE_BIT    0x08
-#define CIR_INTR_MOUSE_IRQ_BIT 0x80
 #define PME_INTR_CIR_PASS_BIT  0x08
 
 /* w83677hg CIR pin config */
index 70a180bb0bd090a3b089b58bc7fdc334f89c2c81..da536c93c978b7645c4e90b9151c46fd95f6a318 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Remote Controller core raw events header
  *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -88,6 +88,12 @@ struct ir_raw_event_ctrl {
                unsigned count;
                u64 bits;
        } sanyo;
+       struct sharp_dec {
+               int state;
+               unsigned count;
+               u32 bits;
+               unsigned int pulse_len;
+       } sharp;
        struct mce_kbd_dec {
                struct input_dev *idev;
                struct timer_list rx_timeout;
@@ -204,6 +210,13 @@ static inline void load_sony_decode(void) { }
 static inline void load_sanyo_decode(void) { }
 #endif
 
+/* from ir-sharp-decoder.c */
+#ifdef CONFIG_IR_SHARP_DECODER_MODULE
+#define load_sharp_decode()    request_module_nowait("ir-sharp-decoder")
+#else
+static inline void load_sharp_decode(void) { }
+#endif
+
 /* from ir-mce_kbd-decoder.c */
 #ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE
 #define load_mce_kbd_decode()  request_module_nowait("ir-mce_kbd-decoder")
index 53d02827a4724f8e5dfeb1eeea19895f42b7fbba..0a88e0cf964f945f26c6515f7540a5b1c9174700 100644 (file)
@@ -195,7 +195,7 @@ static int __init loop_init(void)
        rc->map_name            = RC_MAP_EMPTY;
        rc->priv                = &loopdev;
        rc->driver_type         = RC_DRIVER_IR_RAW;
-       rc->allowed_protos      = RC_BIT_ALL;
+       rc_set_allowed_protocols(rc, RC_BIT_ALL);
        rc->timeout             = 100 * 1000 * 1000; /* 100 ms */
        rc->min_timeout         = 1;
        rc->max_timeout         = UINT_MAX;
index 02e2f38c9c8505121edda2f0e3c46007c887dc8d..99697aae92ff7eac40b880aa937944d6771aec5f 100644 (file)
@@ -1,6 +1,6 @@
 /* rc-main.c - Remote Controller core module
  *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -24,7 +24,7 @@
 
 /* Bitmap to store allocated device numbers from 0 to IRRCV_NUM_DEVICES - 1 */
 #define IRRCV_NUM_DEVICES      256
-DECLARE_BITMAP(ir_core_dev_number, IRRCV_NUM_DEVICES);
+static DECLARE_BITMAP(ir_core_dev_number, IRRCV_NUM_DEVICES);
 
 /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
 #define IR_TAB_MIN_SIZE        256
@@ -62,7 +62,7 @@ struct rc_map *rc_map_get(const char *name)
        map = seek_rc_map(name);
 #ifdef MODULE
        if (!map) {
-               int rc = request_module(name);
+               int rc = request_module("%s", name);
                if (rc < 0) {
                        printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
                        return NULL;
@@ -633,6 +633,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);
 static void ir_do_keydown(struct rc_dev *dev, int scancode,
                          u32 keycode, u8 toggle)
 {
+       struct rc_scancode_filter *filter;
        bool new_event = !dev->keypressed ||
                         dev->last_scancode != scancode ||
                         dev->last_toggle != toggle;
@@ -640,6 +641,11 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
        if (new_event && dev->keypressed)
                ir_do_keyup(dev, false);
 
+       /* Generic scancode filtering */
+       filter = &dev->scancode_filters[RC_FILTER_NORMAL];
+       if (filter->mask && ((scancode ^ filter->data) & filter->mask))
+               return;
+
        input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
 
        if (new_event && keycode != KEY_RESERVED) {
@@ -653,9 +659,10 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
                           "key 0x%04x, scancode 0x%04x\n",
                           dev->input_name, keycode, scancode);
                input_report_key(dev->input_dev, keycode, 1);
+
+               led_trigger_event(led_feedback, LED_FULL);
        }
 
-       led_trigger_event(led_feedback, LED_FULL);
        input_sync(dev->input_dev);
 }
 
@@ -790,18 +797,44 @@ static struct {
          RC_BIT_SONY20,        "sony"          },
        { RC_BIT_RC5_SZ,        "rc-5-sz"       },
        { RC_BIT_SANYO,         "sanyo"         },
+       { RC_BIT_SHARP,         "sharp"         },
        { RC_BIT_MCE_KBD,       "mce_kbd"       },
        { RC_BIT_LIRC,          "lirc"          },
 };
 
 /**
- * show_protocols() - shows the current IR protocol(s)
+ * struct rc_filter_attribute - Device attribute relating to a filter type.
+ * @attr:      Device attribute.
+ * @type:      Filter type.
+ * @mask:      false for filter value, true for filter mask.
+ */
+struct rc_filter_attribute {
+       struct device_attribute         attr;
+       enum rc_filter_type             type;
+       bool                            mask;
+};
+#define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr)
+
+#define RC_PROTO_ATTR(_name, _mode, _show, _store, _type)              \
+       struct rc_filter_attribute dev_attr_##_name = {                 \
+               .attr = __ATTR(_name, _mode, _show, _store),            \
+               .type = (_type),                                        \
+       }
+#define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask)      \
+       struct rc_filter_attribute dev_attr_##_name = {                 \
+               .attr = __ATTR(_name, _mode, _show, _store),            \
+               .type = (_type),                                        \
+               .mask = (_mask),                                        \
+       }
+
+/**
+ * show_protocols() - shows the current/wakeup IR protocol(s)
  * @device:    the device descriptor
  * @mattr:     the device attribute struct (unused)
  * @buf:       a pointer to the output buffer
  *
  * This routine is a callback routine for input read the IR protocol type(s).
- * it is trigged by reading /sys/class/rc/rc?/protocols.
+ * it is trigged by reading /sys/class/rc/rc?/[wakeup_]protocols.
  * It returns the protocol names of supported protocols.
  * Enabled protocols are printed in brackets.
  *
@@ -812,6 +845,7 @@ static ssize_t show_protocols(struct device *device,
                              struct device_attribute *mattr, char *buf)
 {
        struct rc_dev *dev = to_rc_dev(device);
+       struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
        u64 allowed, enabled;
        char *tmp = buf;
        int i;
@@ -822,9 +856,10 @@ static ssize_t show_protocols(struct device *device,
 
        mutex_lock(&dev->lock);
 
-       enabled = dev->enabled_protocols;
-       if (dev->driver_type == RC_DRIVER_SCANCODE)
-               allowed = dev->allowed_protos;
+       enabled = dev->enabled_protocols[fattr->type];
+       if (dev->driver_type == RC_DRIVER_SCANCODE ||
+           fattr->type == RC_FILTER_WAKEUP)
+               allowed = dev->allowed_protocols[fattr->type];
        else if (dev->raw)
                allowed = ir_raw_get_allowed_protocols();
        else {
@@ -856,14 +891,14 @@ static ssize_t show_protocols(struct device *device,
 }
 
 /**
- * store_protocols() - changes the current IR protocol(s)
+ * store_protocols() - changes the current/wakeup IR protocol(s)
  * @device:    the device descriptor
  * @mattr:     the device attribute struct (unused)
  * @buf:       a pointer to the input buffer
  * @len:       length of the input buffer
  *
  * This routine is for changing the IR protocol type.
- * It is trigged by writing to /sys/class/rc/rc?/protocols.
+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols.
  * Writing "+proto" will add a protocol to the list of enabled protocols.
  * Writing "-proto" will remove a protocol from the list of enabled protocols.
  * Writing "proto" will enable only "proto".
@@ -880,12 +915,15 @@ static ssize_t store_protocols(struct device *device,
                               size_t len)
 {
        struct rc_dev *dev = to_rc_dev(device);
+       struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
        bool enable, disable;
        const char *tmp;
-       u64 type;
+       u64 old_type, type;
        u64 mask;
        int rc, i, count = 0;
        ssize_t ret;
+       int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
+       struct rc_scancode_filter local_filter, *filter;
 
        /* Device is being removed */
        if (!dev)
@@ -898,7 +936,8 @@ static ssize_t store_protocols(struct device *device,
                ret = -EINVAL;
                goto out;
        }
-       type = dev->enabled_protocols;
+       old_type = dev->enabled_protocols[fattr->type];
+       type = old_type;
 
        while ((tmp = strsep((char **) &data, " \n")) != NULL) {
                if (!*tmp)
@@ -946,8 +985,10 @@ static ssize_t store_protocols(struct device *device,
                goto out;
        }
 
-       if (dev->change_protocol) {
-               rc = dev->change_protocol(dev, &type);
+       change_protocol = (fattr->type == RC_FILTER_NORMAL)
+               ? dev->change_protocol : dev->change_wakeup_protocol;
+       if (change_protocol) {
+               rc = change_protocol(dev, &type);
                if (rc < 0) {
                        IR_dprintk(1, "Error setting protocols to 0x%llx\n",
                                   (long long)type);
@@ -956,10 +997,40 @@ static ssize_t store_protocols(struct device *device,
                }
        }
 
-       dev->enabled_protocols = type;
+       dev->enabled_protocols[fattr->type] = type;
        IR_dprintk(1, "Current protocol(s): 0x%llx\n",
                   (long long)type);
 
+       /*
+        * If the protocol is changed the filter needs updating.
+        * Try setting the same filter with the new protocol (if any).
+        * Fall back to clearing the filter.
+        */
+       filter = &dev->scancode_filters[fattr->type];
+       if (old_type != type && filter->mask) {
+               local_filter = *filter;
+               if (!type) {
+                       /* no protocol => clear filter */
+                       ret = -1;
+               } else if (!dev->s_filter) {
+                       /* generic filtering => accept any filter */
+                       ret = 0;
+               } else {
+                       /* hardware filtering => try setting, otherwise clear */
+                       ret = dev->s_filter(dev, fattr->type, &local_filter);
+               }
+               if (ret < 0) {
+                       /* clear the filter */
+                       local_filter.data = 0;
+                       local_filter.mask = 0;
+                       if (dev->s_filter)
+                               dev->s_filter(dev, fattr->type, &local_filter);
+               }
+
+               /* commit the new filter */
+               *filter = local_filter;
+       }
+
        ret = len;
 
 out:
@@ -967,6 +1038,115 @@ out:
        return ret;
 }
 
+/**
+ * show_filter() - shows the current scancode filter value or mask
+ * @device:    the device descriptor
+ * @attr:      the device attribute struct
+ * @buf:       a pointer to the output buffer
+ *
+ * This routine is a callback routine to read a scancode filter value or mask.
+ * It is trigged by reading /sys/class/rc/rc?/[wakeup_]filter[_mask].
+ * It prints the current scancode filter value or mask of the appropriate filter
+ * type in hexadecimal into @buf and returns the size of the buffer.
+ *
+ * Bits of the filter value corresponding to set bits in the filter mask are
+ * compared against input scancodes and non-matching scancodes are discarded.
+ *
+ * dev->lock is taken to guard against races between device registration,
+ * store_filter and show_filter.
+ */
+static ssize_t show_filter(struct device *device,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       struct rc_dev *dev = to_rc_dev(device);
+       struct rc_filter_attribute *fattr = to_rc_filter_attr(attr);
+       u32 val;
+
+       /* Device is being removed */
+       if (!dev)
+               return -EINVAL;
+
+       mutex_lock(&dev->lock);
+       if (fattr->mask)
+               val = dev->scancode_filters[fattr->type].mask;
+       else
+               val = dev->scancode_filters[fattr->type].data;
+       mutex_unlock(&dev->lock);
+
+       return sprintf(buf, "%#x\n", val);
+}
+
+/**
+ * store_filter() - changes the scancode filter value
+ * @device:    the device descriptor
+ * @attr:      the device attribute struct
+ * @buf:       a pointer to the input buffer
+ * @len:       length of the input buffer
+ *
+ * This routine is for changing a scancode filter value or mask.
+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask].
+ * Returns -EINVAL if an invalid filter value for the current protocol was
+ * specified or if scancode filtering is not supported by the driver, otherwise
+ * returns @len.
+ *
+ * Bits of the filter value corresponding to set bits in the filter mask are
+ * compared against input scancodes and non-matching scancodes are discarded.
+ *
+ * dev->lock is taken to guard against races between device registration,
+ * store_filter and show_filter.
+ */
+static ssize_t store_filter(struct device *device,
+                           struct device_attribute *attr,
+                           const char *buf,
+                           size_t count)
+{
+       struct rc_dev *dev = to_rc_dev(device);
+       struct rc_filter_attribute *fattr = to_rc_filter_attr(attr);
+       struct rc_scancode_filter local_filter, *filter;
+       int ret;
+       unsigned long val;
+
+       /* Device is being removed */
+       if (!dev)
+               return -EINVAL;
+
+       ret = kstrtoul(buf, 0, &val);
+       if (ret < 0)
+               return ret;
+
+       /* Scancode filter not supported (but still accept 0) */
+       if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL)
+               return val ? -EINVAL : count;
+
+       mutex_lock(&dev->lock);
+
+       /* Tell the driver about the new filter */
+       filter = &dev->scancode_filters[fattr->type];
+       local_filter = *filter;
+       if (fattr->mask)
+               local_filter.mask = val;
+       else
+               local_filter.data = val;
+       if (!dev->enabled_protocols[fattr->type] && local_filter.mask) {
+               /* refuse to set a filter unless a protocol is enabled */
+               ret = -EINVAL;
+               goto unlock;
+       }
+       if (dev->s_filter) {
+               ret = dev->s_filter(dev, fattr->type, &local_filter);
+               if (ret < 0)
+                       goto unlock;
+       }
+
+       /* Success, commit the new filter */
+       *filter = local_filter;
+
+unlock:
+       mutex_unlock(&dev->lock);
+       return (ret < 0) ? ret : count;
+}
+
 static void rc_dev_release(struct device *device)
 {
 }
@@ -996,11 +1176,26 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
 /*
  * Static device attribute struct with the sysfs attributes for IR's
  */
-static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
-                  show_protocols, store_protocols);
+static RC_PROTO_ATTR(protocols, S_IRUGO | S_IWUSR,
+                    show_protocols, store_protocols, RC_FILTER_NORMAL);
+static RC_PROTO_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR,
+                    show_protocols, store_protocols, RC_FILTER_WAKEUP);
+static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR,
+                     show_filter, store_filter, RC_FILTER_NORMAL, false);
+static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR,
+                     show_filter, store_filter, RC_FILTER_NORMAL, true);
+static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR,
+                     show_filter, store_filter, RC_FILTER_WAKEUP, false);
+static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR,
+                     show_filter, store_filter, RC_FILTER_WAKEUP, true);
 
 static struct attribute *rc_dev_attrs[] = {
-       &dev_attr_protocols.attr,
+       &dev_attr_protocols.attr.attr,
+       &dev_attr_wakeup_protocols.attr.attr,
+       &dev_attr_filter.attr.attr,
+       &dev_attr_filter_mask.attr.attr,
+       &dev_attr_wakeup_filter.attr.attr,
+       &dev_attr_wakeup_filter_mask.attr.attr,
        NULL,
 };
 
@@ -1091,14 +1286,6 @@ int rc_register_device(struct rc_dev *dev)
        if (dev->close)
                dev->input_dev->close = ir_close;
 
-       /*
-        * Take the lock here, as the device sysfs node will appear
-        * when device_add() is called, which may trigger an ir-keytable udev
-        * rule, which will in turn call show_protocols and access
-        * dev->enabled_protocols before it has been initialized.
-        */
-       mutex_lock(&dev->lock);
-
        do {
                devno = find_first_zero_bit(ir_core_dev_number,
                                            IRRCV_NUM_DEVICES);
@@ -1107,6 +1294,14 @@ int rc_register_device(struct rc_dev *dev)
                        return -ENOMEM;
        } while (test_and_set_bit(devno, ir_core_dev_number));
 
+       /*
+        * Take the lock here, as the device sysfs node will appear
+        * when device_add() is called, which may trigger an ir-keytable udev
+        * rule, which will in turn call show_protocols and access
+        * dev->enabled_protocols before it has been initialized.
+        */
+       mutex_lock(&dev->lock);
+
        dev->devno = devno;
        dev_set_name(&dev->dev, "rc%ld", dev->devno);
        dev_set_drvdata(&dev->dev, dev);
@@ -1172,7 +1367,7 @@ int rc_register_device(struct rc_dev *dev)
                rc = dev->change_protocol(dev, &rc_type);
                if (rc < 0)
                        goto out_raw;
-               dev->enabled_protocols = rc_type;
+               dev->enabled_protocols[RC_FILTER_NORMAL] = rc_type;
        }
 
        mutex_unlock(&dev->lock);
@@ -1260,5 +1455,5 @@ int rc_core_debug;    /* ir_debug level (0,1,2) */
 EXPORT_SYMBOL_GPL(rc_core_debug);
 module_param_named(debug, rc_core_debug, int, 0644);
 
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
index a5d4f883d053a7b0ebca0543ac82d29d216ec26a..47cd373e2295a3550f09e1b5643f58205abead92 100644 (file)
@@ -922,7 +922,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
        rc->dev.parent = dev;
        rc->priv = rr3;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rc, RC_BIT_ALL);
        rc->timeout = US_TO_NS(2750);
        rc->tx_ir = redrat3_transmit_ir;
        rc->s_tx_carrier = redrat3_set_tx_carrier;
index 8f0cddb9e8f2f4ce0076a9f7a4d4ba0cada0d7b4..22e4c1f28ab414b6cea761e0be22013bd6d4f08a 100644 (file)
@@ -287,7 +287,7 @@ static int st_rc_probe(struct platform_device *pdev)
        st_rc_hardware_init(rc_dev);
 
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        /* rx sampling rate is 10Mhz */
        rdev->rx_resolution = 100;
        rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
index d7b11e6a998253dd362654ed468edcb11cfef103..f4e0bc3d382ce92d65f7876ad4101a579e157762 100644 (file)
@@ -322,7 +322,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
        rdev->dev.parent = dev;
        rdev->priv = sz;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rdev, RC_BIT_ALL);
        rdev->driver_name = DRIVER_NAME;
        rdev->map_name = RC_MAP_STREAMZAP;
 
index d8de2056a4f69cedc179c2dfa206595909f3458f..c5be38e2a2fea7454c7e80a0cb312772d867d8aa 100644 (file)
@@ -318,7 +318,7 @@ static int ttusbir_probe(struct usb_interface *intf,
        usb_to_input_id(tt->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(rc, RC_BIT_ALL);
        rc->priv = tt;
        rc->driver_name = DRIVER_NAME;
        rc->map_name = RC_MAP_TT_1500;
index 904baf4eec28ac902731d90bb78ae6f73632c4cc..a8b981f5ce2ea13aa7f44635fe30ba5171bd3af9 100644 (file)
@@ -1082,7 +1082,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
        data->dev->dev.parent = &device->dev;
        data->dev->timeout = MS_TO_NS(100);
        data->dev->rx_resolution = US_TO_NS(2);
-       data->dev->allowed_protos = RC_BIT_ALL;
+       rc_set_allowed_protocols(data->dev, RC_BIT_ALL);
 
        err = rc_register_device(data->dev);
        if (err)
index ba2e365296cf9a0271d50234522b62a8ae194bc1..a1284889cd1537ad7f16d32b74300d7021be080a 100644 (file)
@@ -204,6 +204,7 @@ config MEDIA_TUNER_TDA18212
 config MEDIA_TUNER_E4000
        tristate "Elonics E4000 silicon tuner"
        depends on MEDIA_SUPPORT && I2C
+       select REGMAP_I2C
        default m if !MEDIA_SUBDRV_AUTOSELECT
        help
          Elonics E4000 silicon tuner driver.
index 40c1da707d15ce86a094adcc25c7d4765f4ed00c..90d93348f20c5f111aea684ba15b798bc683c6b1 100644 (file)
 #include "e4000_priv.h"
 #include <linux/math64.h>
 
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  64
-
-/* write multiple registers */
-static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[MAX_XFER_SIZE];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg->i2c_addr,
-                       .flags = 0,
-                       .len = 1 + len,
-                       .buf = buf,
-               }
-       };
-
-       if (1 + len > sizeof(buf)) {
-               dev_warn(&priv->i2c->dev,
-                        "%s: i2c wr reg=%04x: len=%d is too big!\n",
-                        KBUILD_MODNAME, reg, len);
-               return -EINVAL;
-       }
-
-       buf[0] = reg;
-       memcpy(&buf[1], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev,
-                               "%s: i2c wr failed=%d reg=%02x len=%d\n",
-                               KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple registers */
-static int e4000_rd_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[MAX_XFER_SIZE];
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg->i2c_addr,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg,
-               }, {
-                       .addr = priv->cfg->i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = buf,
-               }
-       };
-
-       if (len > sizeof(buf)) {
-               dev_warn(&priv->i2c->dev,
-                        "%s: i2c rd reg=%04x: len=%d is too big!\n",
-                        KBUILD_MODNAME, reg, len);
-               return -EINVAL;
-       }
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               memcpy(val, buf, len);
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev,
-                               "%s: i2c rd failed=%d reg=%02x len=%d\n",
-                               KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* write single register */
-static int e4000_wr_reg(struct e4000_priv *priv, u8 reg, u8 val)
-{
-       return e4000_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-static int e4000_rd_reg(struct e4000_priv *priv, u8 reg, u8 *val)
-{
-       return e4000_rd_regs(priv, reg, val, 1);
-}
-
 static int e4000_init(struct dvb_frontend *fe)
 {
-       struct e4000_priv *priv = fe->tuner_priv;
+       struct e4000 *s = fe->tuner_priv;
        int ret;
 
-       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
+       dev_dbg(&s->client->dev, "%s:\n", __func__);
 
        /* dummy I2C to ensure I2C wakes up */
-       ret = e4000_wr_reg(priv, 0x02, 0x40);
+       ret = regmap_write(s->regmap, 0x02, 0x40);
 
        /* reset */
-       ret = e4000_wr_reg(priv, 0x00, 0x01);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x00, 0x01);
+       if (ret)
                goto err;
 
        /* disable output clock */
-       ret = e4000_wr_reg(priv, 0x06, 0x00);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x06, 0x00);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_reg(priv, 0x7a, 0x96);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x7a, 0x96);
+       if (ret)
                goto err;
 
        /* configure gains */
-       ret = e4000_wr_regs(priv, 0x7e, "\x01\xfe", 2);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x7e, "\x01\xfe", 2);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_reg(priv, 0x82, 0x00);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x82, 0x00);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_reg(priv, 0x24, 0x05);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x24, 0x05);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_regs(priv, 0x87, "\x20\x01", 2);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x87, "\x20\x01", 2);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_regs(priv, 0x9f, "\x7f\x07", 2);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x9f, "\x7f\x07", 2);
+       if (ret)
                goto err;
 
        /* DC offset control */
-       ret = e4000_wr_reg(priv, 0x2d, 0x1f);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x2d, 0x1f);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_regs(priv, 0x70, "\x01\x01", 2);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x70, "\x01\x01", 2);
+       if (ret)
                goto err;
 
        /* gain control */
-       ret = e4000_wr_reg(priv, 0x1a, 0x17);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x1a, 0x17);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_reg(priv, 0x1f, 0x1a);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x1f, 0x1a);
+       if (ret)
                goto err;
 
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
+       s->active = true;
 err:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
 
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
        return ret;
 }
 
 static int e4000_sleep(struct dvb_frontend *fe)
 {
-       struct e4000_priv *priv = fe->tuner_priv;
+       struct e4000 *s = fe->tuner_priv;
        int ret;
 
-       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+       dev_dbg(&s->client->dev, "%s:\n", __func__);
 
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
+       s->active = false;
 
-       ret = e4000_wr_reg(priv, 0x00, 0x00);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x00, 0x00);
+       if (ret)
                goto err;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
 err:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
 
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
        return ret;
 }
 
 static int e4000_set_params(struct dvb_frontend *fe)
 {
-       struct e4000_priv *priv = fe->tuner_priv;
+       struct e4000 *s = fe->tuner_priv;
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        int ret, i, sigma_delta;
-       unsigned int f_vco;
+       unsigned int pll_n, pll_f;
+       u64 f_vco;
        u8 buf[5], i_data[4], q_data[4];
 
-       dev_dbg(&priv->i2c->dev,
-                       "%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
+       dev_dbg(&s->client->dev,
+                       "%s: delivery_system=%d frequency=%u bandwidth_hz=%u\n",
                        __func__, c->delivery_system, c->frequency,
                        c->bandwidth_hz);
 
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
        /* gain control manual */
-       ret = e4000_wr_reg(priv, 0x1a, 0x00);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x1a, 0x00);
+       if (ret)
                goto err;
 
        /* PLL */
@@ -248,23 +141,21 @@ static int e4000_set_params(struct dvb_frontend *fe)
                goto err;
        }
 
-       /*
-        * Note: Currently f_vco overflows when c->frequency is 1 073 741 824 Hz
-        * or more.
-        */
-       f_vco = c->frequency * e4000_pll_lut[i].mul;
-       sigma_delta = div_u64(0x10000ULL * (f_vco % priv->cfg->clock), priv->cfg->clock);
-       buf[0] = f_vco / priv->cfg->clock;
+       f_vco = 1ull * c->frequency * e4000_pll_lut[i].mul;
+       pll_n = div_u64_rem(f_vco, s->clock, &pll_f);
+       sigma_delta = div_u64(0x10000ULL * pll_f, s->clock);
+       buf[0] = pll_n;
        buf[1] = (sigma_delta >> 0) & 0xff;
        buf[2] = (sigma_delta >> 8) & 0xff;
        buf[3] = 0x00;
        buf[4] = e4000_pll_lut[i].div;
 
-       dev_dbg(&priv->i2c->dev, "%s: f_vco=%u pll div=%d sigma_delta=%04x\n",
+       dev_dbg(&s->client->dev,
+                       "%s: f_vco=%llu pll div=%d sigma_delta=%04x\n",
                        __func__, f_vco, buf[0], sigma_delta);
 
-       ret = e4000_wr_regs(priv, 0x09, buf, 5);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x09, buf, 5);
+       if (ret)
                goto err;
 
        /* LNA filter (RF filter) */
@@ -278,8 +169,8 @@ static int e4000_set_params(struct dvb_frontend *fe)
                goto err;
        }
 
-       ret = e4000_wr_reg(priv, 0x10, e400_lna_filter_lut[i].val);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x10, e400_lna_filter_lut[i].val);
+       if (ret)
                goto err;
 
        /* IF filters */
@@ -296,8 +187,8 @@ static int e4000_set_params(struct dvb_frontend *fe)
        buf[0] = e4000_if_filter_lut[i].reg11_val;
        buf[1] = e4000_if_filter_lut[i].reg12_val;
 
-       ret = e4000_wr_regs(priv, 0x11, buf, 2);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x11, buf, 2);
+       if (ret)
                goto err;
 
        /* frequency band */
@@ -311,34 +202,34 @@ static int e4000_set_params(struct dvb_frontend *fe)
                goto err;
        }
 
-       ret = e4000_wr_reg(priv, 0x07, e4000_band_lut[i].reg07_val);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x07, e4000_band_lut[i].reg07_val);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_reg(priv, 0x78, e4000_band_lut[i].reg78_val);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x78, e4000_band_lut[i].reg78_val);
+       if (ret)
                goto err;
 
        /* DC offset */
        for (i = 0; i < 4; i++) {
                if (i == 0)
-                       ret = e4000_wr_regs(priv, 0x15, "\x00\x7e\x24", 3);
+                       ret = regmap_bulk_write(s->regmap, 0x15, "\x00\x7e\x24", 3);
                else if (i == 1)
-                       ret = e4000_wr_regs(priv, 0x15, "\x00\x7f", 2);
+                       ret = regmap_bulk_write(s->regmap, 0x15, "\x00\x7f", 2);
                else if (i == 2)
-                       ret = e4000_wr_regs(priv, 0x15, "\x01", 1);
+                       ret = regmap_bulk_write(s->regmap, 0x15, "\x01", 1);
                else
-                       ret = e4000_wr_regs(priv, 0x16, "\x7e", 1);
+                       ret = regmap_bulk_write(s->regmap, 0x16, "\x7e", 1);
 
-               if (ret < 0)
+               if (ret)
                        goto err;
 
-               ret = e4000_wr_reg(priv, 0x29, 0x01);
-               if (ret < 0)
+               ret = regmap_write(s->regmap, 0x29, 0x01);
+               if (ret)
                        goto err;
 
-               ret = e4000_rd_regs(priv, 0x2a, buf, 3);
-               if (ret < 0)
+               ret = regmap_bulk_read(s->regmap, 0x2a, buf, 3);
+               if (ret)
                        goto err;
 
                i_data[i] = (((buf[2] >> 0) & 0x3) << 6) | (buf[0] & 0x3f);
@@ -348,53 +239,226 @@ static int e4000_set_params(struct dvb_frontend *fe)
        swap(q_data[2], q_data[3]);
        swap(i_data[2], i_data[3]);
 
-       ret = e4000_wr_regs(priv, 0x50, q_data, 4);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x50, q_data, 4);
+       if (ret)
                goto err;
 
-       ret = e4000_wr_regs(priv, 0x60, i_data, 4);
-       if (ret < 0)
+       ret = regmap_bulk_write(s->regmap, 0x60, i_data, 4);
+       if (ret)
                goto err;
 
        /* gain control auto */
-       ret = e4000_wr_reg(priv, 0x1a, 0x17);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x1a, 0x17);
+       if (ret)
                goto err;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
 err:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
 
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
        return ret;
 }
 
 static int e4000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
-       struct e4000_priv *priv = fe->tuner_priv;
+       struct e4000 *s = fe->tuner_priv;
 
-       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+       dev_dbg(&s->client->dev, "%s:\n", __func__);
 
        *frequency = 0; /* Zero-IF */
 
        return 0;
 }
 
-static int e4000_release(struct dvb_frontend *fe)
+#if IS_ENABLED(CONFIG_VIDEO_V4L2)
+static int e4000_set_lna_gain(struct dvb_frontend *fe)
 {
-       struct e4000_priv *priv = fe->tuner_priv;
+       struct e4000 *s = fe->tuner_priv;
+       int ret;
+       u8 u8tmp;
+
+       dev_dbg(&s->client->dev, "%s: lna auto=%d->%d val=%d->%d\n",
+                       __func__, s->lna_gain_auto->cur.val,
+                       s->lna_gain_auto->val, s->lna_gain->cur.val,
+                       s->lna_gain->val);
+
+       if (s->lna_gain_auto->val && s->if_gain_auto->cur.val)
+               u8tmp = 0x17;
+       else if (s->lna_gain_auto->val)
+               u8tmp = 0x19;
+       else if (s->if_gain_auto->cur.val)
+               u8tmp = 0x16;
+       else
+               u8tmp = 0x10;
+
+       ret = regmap_write(s->regmap, 0x1a, u8tmp);
+       if (ret)
+               goto err;
+
+       if (s->lna_gain_auto->val == false) {
+               ret = regmap_write(s->regmap, 0x14, s->lna_gain->val);
+               if (ret)
+                       goto err;
+       }
+err:
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
 
-       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+       return ret;
+}
 
-       kfree(fe->tuner_priv);
+static int e4000_set_mixer_gain(struct dvb_frontend *fe)
+{
+       struct e4000 *s = fe->tuner_priv;
+       int ret;
+       u8 u8tmp;
 
-       return 0;
+       dev_dbg(&s->client->dev, "%s: mixer auto=%d->%d val=%d->%d\n",
+                       __func__, s->mixer_gain_auto->cur.val,
+                       s->mixer_gain_auto->val, s->mixer_gain->cur.val,
+                       s->mixer_gain->val);
+
+       if (s->mixer_gain_auto->val)
+               u8tmp = 0x15;
+       else
+               u8tmp = 0x14;
+
+       ret = regmap_write(s->regmap, 0x20, u8tmp);
+       if (ret)
+               goto err;
+
+       if (s->mixer_gain_auto->val == false) {
+               ret = regmap_write(s->regmap, 0x15, s->mixer_gain->val);
+               if (ret)
+                       goto err;
+       }
+err:
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+
+       return ret;
 }
 
+static int e4000_set_if_gain(struct dvb_frontend *fe)
+{
+       struct e4000 *s = fe->tuner_priv;
+       int ret;
+       u8 buf[2];
+       u8 u8tmp;
+
+       dev_dbg(&s->client->dev, "%s: if auto=%d->%d val=%d->%d\n",
+                       __func__, s->if_gain_auto->cur.val,
+                       s->if_gain_auto->val, s->if_gain->cur.val,
+                       s->if_gain->val);
+
+       if (s->if_gain_auto->val && s->lna_gain_auto->cur.val)
+               u8tmp = 0x17;
+       else if (s->lna_gain_auto->cur.val)
+               u8tmp = 0x19;
+       else if (s->if_gain_auto->val)
+               u8tmp = 0x16;
+       else
+               u8tmp = 0x10;
+
+       ret = regmap_write(s->regmap, 0x1a, u8tmp);
+       if (ret)
+               goto err;
+
+       if (s->if_gain_auto->val == false) {
+               buf[0] = e4000_if_gain_lut[s->if_gain->val].reg16_val;
+               buf[1] = e4000_if_gain_lut[s->if_gain->val].reg17_val;
+               ret = regmap_bulk_write(s->regmap, 0x16, buf, 2);
+               if (ret)
+                       goto err;
+       }
+err:
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int e4000_pll_lock(struct dvb_frontend *fe)
+{
+       struct e4000 *s = fe->tuner_priv;
+       int ret;
+       unsigned int utmp;
+
+       ret = regmap_read(s->regmap, 0x07, &utmp);
+       if (ret)
+               goto err;
+
+       s->pll_lock->val = (utmp & 0x01);
+err:
+       if (ret)
+               dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int e4000_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct e4000 *s = container_of(ctrl->handler, struct e4000, hdl);
+       int ret;
+
+       if (s->active == false)
+               return 0;
+
+       switch (ctrl->id) {
+       case  V4L2_CID_RF_TUNER_PLL_LOCK:
+               ret = e4000_pll_lock(s->fe);
+               break;
+       default:
+               dev_dbg(&s->client->dev, "%s: unknown ctrl: id=%d name=%s\n",
+                               __func__, ctrl->id, ctrl->name);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int e4000_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct e4000 *s = container_of(ctrl->handler, struct e4000, hdl);
+       struct dvb_frontend *fe = s->fe;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+
+       if (s->active == false)
+               return 0;
+
+       switch (ctrl->id) {
+       case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
+       case V4L2_CID_RF_TUNER_BANDWIDTH:
+               c->bandwidth_hz = s->bandwidth->val;
+               ret = e4000_set_params(s->fe);
+               break;
+       case  V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:
+       case  V4L2_CID_RF_TUNER_LNA_GAIN:
+               ret = e4000_set_lna_gain(s->fe);
+               break;
+       case  V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO:
+       case  V4L2_CID_RF_TUNER_MIXER_GAIN:
+               ret = e4000_set_mixer_gain(s->fe);
+               break;
+       case  V4L2_CID_RF_TUNER_IF_GAIN_AUTO:
+       case  V4L2_CID_RF_TUNER_IF_GAIN:
+               ret = e4000_set_if_gain(s->fe);
+               break;
+       default:
+               dev_dbg(&s->client->dev, "%s: unknown ctrl: id=%d name=%s\n",
+                               __func__, ctrl->id, ctrl->name);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops e4000_ctrl_ops = {
+       .g_volatile_ctrl = e4000_g_volatile_ctrl,
+       .s_ctrl = e4000_s_ctrl,
+};
+#endif
+
 static const struct dvb_tuner_ops e4000_tuner_ops = {
        .info = {
                .name           = "Elonics E4000",
@@ -402,8 +466,6 @@ static const struct dvb_tuner_ops e4000_tuner_ops = {
                .frequency_max  = 862000000,
        },
 
-       .release = e4000_release,
-
        .init = e4000_init,
        .sleep = e4000_sleep,
        .set_params = e4000_set_params,
@@ -411,62 +473,148 @@ static const struct dvb_tuner_ops e4000_tuner_ops = {
        .get_if_frequency = e4000_get_if_frequency,
 };
 
-struct dvb_frontend *e4000_attach(struct dvb_frontend *fe,
-               struct i2c_adapter *i2c, const struct e4000_config *cfg)
+/*
+ * Use V4L2 subdev to carry V4L2 control handler, even we don't implement
+ * subdev itself, just to avoid reinventing the wheel.
+ */
+static int e4000_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
 {
-       struct e4000_priv *priv;
+       struct e4000_config *cfg = client->dev.platform_data;
+       struct dvb_frontend *fe = cfg->fe;
+       struct e4000 *s;
        int ret;
-       u8 chip_id;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
+       unsigned int utmp;
+       static const struct regmap_config regmap_config = {
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       };
 
-       priv = kzalloc(sizeof(struct e4000_priv), GFP_KERNEL);
-       if (!priv) {
+       s = kzalloc(sizeof(struct e4000), GFP_KERNEL);
+       if (!s) {
                ret = -ENOMEM;
-               dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+               dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
                goto err;
        }
 
-       priv->cfg = cfg;
-       priv->i2c = i2c;
+       s->clock = cfg->clock;
+       s->client = client;
+       s->fe = cfg->fe;
+       s->regmap = devm_regmap_init_i2c(client, &regmap_config);
+       if (IS_ERR(s->regmap)) {
+               ret = PTR_ERR(s->regmap);
+               goto err;
+       }
 
        /* check if the tuner is there */
-       ret = e4000_rd_reg(priv, 0x02, &chip_id);
-       if (ret < 0)
+       ret = regmap_read(s->regmap, 0x02, &utmp);
+       if (ret)
                goto err;
 
-       dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
+       dev_dbg(&s->client->dev, "%s: chip id=%02x\n", __func__, utmp);
 
-       if (chip_id != 0x40)
+       if (utmp != 0x40) {
+               ret = -ENODEV;
                goto err;
+       }
 
        /* put sleep as chip seems to be in normal mode by default */
-       ret = e4000_wr_reg(priv, 0x00, 0x00);
-       if (ret < 0)
+       ret = regmap_write(s->regmap, 0x00, 0x00);
+       if (ret)
                goto err;
 
-       dev_info(&priv->i2c->dev,
+#if IS_ENABLED(CONFIG_VIDEO_V4L2)
+       /* Register controls */
+       v4l2_ctrl_handler_init(&s->hdl, 9);
+       s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
+       s->bandwidth = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_BANDWIDTH, 4300000, 11000000, 100000, 4300000);
+       v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
+       s->lna_gain_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_LNA_GAIN_AUTO, 0, 1, 1, 1);
+       s->lna_gain = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_LNA_GAIN, 0, 15, 1, 10);
+       v4l2_ctrl_auto_cluster(2, &s->lna_gain_auto, 0, false);
+       s->mixer_gain_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO, 0, 1, 1, 1);
+       s->mixer_gain = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1);
+       v4l2_ctrl_auto_cluster(2, &s->mixer_gain_auto, 0, false);
+       s->if_gain_auto = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_IF_GAIN_AUTO, 0, 1, 1, 1);
+       s->if_gain = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_IF_GAIN, 0, 54, 1, 0);
+       v4l2_ctrl_auto_cluster(2, &s->if_gain_auto, 0, false);
+       s->pll_lock = v4l2_ctrl_new_std(&s->hdl, &e4000_ctrl_ops,
+                       V4L2_CID_RF_TUNER_PLL_LOCK,  0, 1, 1, 0);
+       if (s->hdl.error) {
+               ret = s->hdl.error;
+               dev_err(&s->client->dev, "Could not initialize controls\n");
+               v4l2_ctrl_handler_free(&s->hdl);
+               goto err;
+       }
+
+       s->sd.ctrl_handler = &s->hdl;
+#endif
+
+       dev_info(&s->client->dev,
                        "%s: Elonics E4000 successfully identified\n",
                        KBUILD_MODNAME);
 
-       fe->tuner_priv = priv;
+       fe->tuner_priv = s;
        memcpy(&fe->ops.tuner_ops, &e4000_tuner_ops,
                        sizeof(struct dvb_tuner_ops));
 
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+       v4l2_set_subdevdata(&s->sd, client);
+       i2c_set_clientdata(client, &s->sd);
 
-       return fe;
+       return 0;
 err:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+       if (ret) {
+               dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
+               kfree(s);
+       }
+
+       return ret;
+}
+
+static int e4000_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct e4000 *s = container_of(sd, struct e4000, sd);
+       struct dvb_frontend *fe = s->fe;
+
+       dev_dbg(&client->dev, "%s:\n", __func__);
 
-       dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
-       kfree(priv);
-       return NULL;
+#if IS_ENABLED(CONFIG_VIDEO_V4L2)
+       v4l2_ctrl_handler_free(&s->hdl);
+#endif
+       memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
+       fe->tuner_priv = NULL;
+       kfree(s);
+
+       return 0;
 }
-EXPORT_SYMBOL(e4000_attach);
+
+static const struct i2c_device_id e4000_id[] = {
+       {"e4000", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, e4000_id);
+
+static struct i2c_driver e4000_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "e4000",
+       },
+       .probe          = e4000_probe,
+       .remove         = e4000_remove,
+       .id_table       = e4000_id,
+};
+
+module_i2c_driver(e4000_driver);
 
 MODULE_DESCRIPTION("Elonics E4000 silicon tuner driver");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
index 25ee7c07abff96132a275eeece0255d5c21f5c39..e74b8b2f2fc395d30edeba4cf9791815259d9ea2 100644 (file)
 #include <linux/kconfig.h>
 #include "dvb_frontend.h"
 
+/*
+ * I2C address
+ * 0x64, 0x65, 0x66, 0x67
+ */
 struct e4000_config {
        /*
-        * I2C address
-        * 0x64, 0x65, 0x66, 0x67
+        * frontend
         */
-       u8 i2c_addr;
+       struct dvb_frontend *fe;
 
        /*
         * clock
@@ -37,16 +40,4 @@ struct e4000_config {
        u32 clock;
 };
 
-#if IS_ENABLED(CONFIG_MEDIA_TUNER_E4000)
-extern struct dvb_frontend *e4000_attach(struct dvb_frontend *fe,
-               struct i2c_adapter *i2c, const struct e4000_config *cfg);
-#else
-static inline struct dvb_frontend *e4000_attach(struct dvb_frontend *fe,
-               struct i2c_adapter *i2c, const struct e4000_config *cfg)
-{
-       dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
 #endif
index a3855053e78f57c7d2f4450b8328c2fac00aeaf6..cb0070483e65964c137c9a553e1c5768ae2b5444 100644 (file)
 #define E4000_PRIV_H
 
 #include "e4000.h"
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <linux/regmap.h>
 
-struct e4000_priv {
-       const struct e4000_config *cfg;
-       struct i2c_adapter *i2c;
+struct e4000 {
+       struct i2c_client *client;
+       struct regmap *regmap;
+       u32 clock;
+       struct dvb_frontend *fe;
+       struct v4l2_subdev sd;
+       bool active;
+
+       /* Controls */
+       struct v4l2_ctrl_handler hdl;
+       struct v4l2_ctrl *bandwidth_auto;
+       struct v4l2_ctrl *bandwidth;
+       struct v4l2_ctrl *lna_gain_auto;
+       struct v4l2_ctrl *lna_gain;
+       struct v4l2_ctrl *mixer_gain_auto;
+       struct v4l2_ctrl *mixer_gain;
+       struct v4l2_ctrl *if_gain_auto;
+       struct v4l2_ctrl *if_gain;
+       struct v4l2_ctrl *pll_lock;
 };
 
 struct e4000_pll {
@@ -144,4 +163,67 @@ static const struct e4000_if_filter e4000_if_filter_lut[] = {
        { 0xffffffff, 0x00, 0x20 },
 };
 
+struct e4000_if_gain {
+       u8 reg16_val;
+       u8 reg17_val;
+};
+
+static const struct e4000_if_gain e4000_if_gain_lut[] = {
+       {0x00, 0x00},
+       {0x20, 0x00},
+       {0x40, 0x00},
+       {0x02, 0x00},
+       {0x22, 0x00},
+       {0x42, 0x00},
+       {0x04, 0x00},
+       {0x24, 0x00},
+       {0x44, 0x00},
+       {0x01, 0x00},
+       {0x21, 0x00},
+       {0x41, 0x00},
+       {0x03, 0x00},
+       {0x23, 0x00},
+       {0x43, 0x00},
+       {0x05, 0x00},
+       {0x25, 0x00},
+       {0x45, 0x00},
+       {0x07, 0x00},
+       {0x27, 0x00},
+       {0x47, 0x00},
+       {0x0f, 0x00},
+       {0x2f, 0x00},
+       {0x4f, 0x00},
+       {0x17, 0x00},
+       {0x37, 0x00},
+       {0x57, 0x00},
+       {0x1f, 0x00},
+       {0x3f, 0x00},
+       {0x5f, 0x00},
+       {0x1f, 0x01},
+       {0x3f, 0x01},
+       {0x5f, 0x01},
+       {0x1f, 0x02},
+       {0x3f, 0x02},
+       {0x5f, 0x02},
+       {0x1f, 0x03},
+       {0x3f, 0x03},
+       {0x5f, 0x03},
+       {0x1f, 0x04},
+       {0x3f, 0x04},
+       {0x5f, 0x04},
+       {0x1f, 0x0c},
+       {0x3f, 0x0c},
+       {0x5f, 0x0c},
+       {0x1f, 0x14},
+       {0x3f, 0x14},
+       {0x5f, 0x14},
+       {0x1f, 0x1c},
+       {0x3f, 0x1c},
+       {0x5f, 0x1c},
+       {0x1f, 0x24},
+       {0x3f, 0x24},
+       {0x5f, 0x24},
+       {0x7f, 0x24},
+};
+
 #endif
index 20cca405bf452c46195ebbbadb37c8a535e85d0b..f640dcf4a81d8a7e204bba0a015f126b9d8756bc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for mt2063 Micronas tuner
  *
- * Copyright (c) 2011 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2011 Mauro Carvalho Chehab
  *
  * This driver came from a driver originally written by:
  *             Henry Wang <Henry.wang@AzureWave.com>
@@ -2298,6 +2298,6 @@ static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
 }
 #endif
 
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_DESCRIPTION("MT2063 Silicon tuner");
 MODULE_LICENSE("GPL");
index d9ee43fae62dee4f7f5cf474d4f74ed21e4c5a01..319adc4f0561a0fff3f671dc38dcc20bf65ca8c2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Rafael Micro R820T driver
  *
- * Copyright (C) 2013 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2013 Mauro Carvalho Chehab
  *
  * This driver was written from scratch, based on an existing driver
  * that it is part of rtl-sdr git tree, released under GPLv2:
@@ -2351,5 +2351,5 @@ err_no_gate:
 EXPORT_SYMBOL_GPL(r820t_attach);
 
 MODULE_DESCRIPTION("Rafael Micro r820t silicon tuner driver");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
index abe256e1f84324d36041fc67af9ca4587f113cb2..05a4ac9edb6b0559eedde3f39273bb958df9cfd8 100644 (file)
@@ -150,6 +150,8 @@ static int tda18212_set_params(struct dvb_frontend *fe)
        #define DVBT2_8  5
        #define DVBC_6   6
        #define DVBC_8   7
+       #define ATSC_VSB 8
+       #define ATSC_QAM 9
        static const u8 bw_params[][3] = {
                     /* reg:   0f    13    23 */
                [DVBT_6]  = { 0xb3, 0x20, 0x03 },
@@ -160,6 +162,8 @@ static int tda18212_set_params(struct dvb_frontend *fe)
                [DVBT2_8] = { 0xbc, 0x22, 0x01 },
                [DVBC_6]  = { 0x92, 0x50, 0x03 },
                [DVBC_8]  = { 0x92, 0x53, 0x03 },
+               [ATSC_VSB] = { 0x7d, 0x20, 0x63 },
+               [ATSC_QAM] = { 0x7d, 0x20, 0x63 },
        };
 
        dev_dbg(&priv->i2c->dev,
@@ -171,6 +175,14 @@ static int tda18212_set_params(struct dvb_frontend *fe)
                fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
 
        switch (c->delivery_system) {
+       case SYS_ATSC:
+               if_khz = priv->cfg->if_atsc_vsb;
+               i = ATSC_VSB;
+               break;
+       case SYS_DVBC_ANNEX_B:
+               if_khz = priv->cfg->if_atsc_qam;
+               i = ATSC_QAM;
+               break;
        case SYS_DVBT:
                switch (c->bandwidth_hz) {
                case 6000000:
index 7e0d503baf05f1d66444001ce798f9b2a4b205c2..c36b49e4b2742a8f8cf12f1dd99e253c69d89ac6 100644 (file)
@@ -35,6 +35,8 @@ struct tda18212_config {
        u16 if_dvbt2_7;
        u16 if_dvbt2_8;
        u16 if_dvbc;
+       u16 if_atsc_vsb;
+       u16 if_atsc_qam;
 };
 
 #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA18212)
index cca508d4aafb1545037b7972d06d01c346efeb77..76a816511f2f34f9bd9d5886d549c59e8b6b5d96 100644 (file)
@@ -1107,6 +1107,9 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
                                offset += 200000;
                }
 #endif
+       default:
+               tuner_err("Unsupported tuner type %d.\n", new_type);
+               break;
        }
 
        div = (freq - offset + DIV / 2) / DIV;
index dd32decb237d3d5979c36a0a72fd478b57f1855c..7fdadf9bc90bf30c259ae3359789e816adfcb6c8 100644 (file)
@@ -108,7 +108,7 @@ struct au0828_board au0828_boards[] = {
                .name   = "DViCO FusionHDTV USB",
                .tuner_type = UNSET,
                .tuner_addr = ADDR_UNSET,
-               .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
+               .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
        },
        [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
                .name = "Hauppauge Woodbury",
@@ -270,18 +270,25 @@ void au0828_gpio_setup(struct au0828_dev *dev)
                 * 9 - XC5000 Tuner
                 */
 
-               /* Into reset */
+               /* Set relevant GPIOs as outputs (leave the EEPROM W/P
+                  as an input since we will never touch it and it has
+                  a pullup) */
                au0828_write(dev, REG_003, 0x02);
                au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
+
+               /* Into reset */
                au0828_write(dev, REG_001, 0x0);
                au0828_write(dev, REG_000, 0x0);
-               msleep(100);
+               msleep(50);
 
-               /* Out of reset (leave the cs5340 in reset until needed) */
-               au0828_write(dev, REG_003, 0x02);
-               au0828_write(dev, REG_001, 0x02);
-               au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
-               au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
+               /* Bring power supply out of reset */
+               au0828_write(dev, REG_000, 0x80);
+               msleep(50);
+
+               /* Bring xc5000 and au8522 out of reset (leave the
+                  cs5340 in reset until needed) */
+               au0828_write(dev, REG_001, 0x02); /* xc5000 */
+               au0828_write(dev, REG_000, 0x80 | 0x20); /* PS + au8522 */
 
                msleep(250);
                break;
index 0f7b42446826b5922a2deea2b9ebb6a5f1ffbd79..46d52fac868034c23a1566922ea6519775a42c1d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   cx231xx IR glue driver
  *
- *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2010 Mauro Carvalho Chehab
  *
  *   Polaris (cx231xx) has its support for IR's with a design close to MCE.
  *   however, a few designs are using an external I2C chip for IR, instead
index 2059d0c86ad3ad4b91da3c84543bd8fdf74ec213..037e519bbaa2f80bb014dfadb8c3f4983cd51ab1 100644 (file)
@@ -100,13 +100,6 @@ config DVB_USB_GL861
          Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
          receiver with USB ID 0db0:5581.
 
-config DVB_USB_IT913X
-       tristate "ITE IT913X DVB-T USB2.0 support"
-       depends on DVB_USB_V2
-       select DVB_IT913X_FE
-       help
-         Say Y here to support the ITE IT913X DVB-T USB2.0
-
 config DVB_USB_LME2510
        tristate "LME DM04/QQBOX DVB-S USB2.0 support"
        depends on DVB_USB_V2
@@ -133,7 +126,7 @@ config DVB_USB_MXL111SF
 
 config DVB_USB_RTL28XXU
        tristate "Realtek RTL28xxU DVB USB support"
-       depends on DVB_USB_V2
+       depends on DVB_USB_V2 && I2C_MUX
        select DVB_RTL2830
        select DVB_RTL2832
        select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
index 2c06714b9ef03ef733923179879acbb1e988f0b9..7407b8338ccfa33ce6a4179e5b9e99632a3f6ebf 100644 (file)
@@ -22,9 +22,6 @@ obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
 dvb-usb-ec168-objs := ec168.o
 obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
 
-dvb-usb-it913x-objs := it913x.o
-obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
-
 dvb-usb-lmedm04-objs := lmedm04.o
 obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
 
@@ -44,3 +41,4 @@ ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/tuners
 ccflags-y += -I$(srctree)/drivers/media/common
+ccflags-y += -I$(srctree)/drivers/staging/media/rtl2832u_sdr
index 8ede8ea762e601a773dd49c1ae397f016d533338..021e4d35e4d7d5f65311c13bb70c33df07b40d3f 100644 (file)
@@ -575,6 +575,10 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
                if (ret < 0)
                        goto err;
 
+               /* use default I2C address if eeprom has no address set */
+               if (!tmp)
+                       tmp = 0x3a;
+
                if (state->chip_type == 0x9135) {
                        ret = af9035_wr_reg(d, 0x004bfb, tmp);
                        if (ret < 0)
@@ -637,6 +641,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
 
        /* demod I2C "address" */
        state->af9033_config[0].i2c_addr = 0x38;
+       state->af9033_config[1].i2c_addr = 0x3a;
        state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
        state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
        state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
@@ -684,7 +689,9 @@ static int af9035_read_config(struct dvb_usb_device *d)
                if (ret < 0)
                        goto err;
 
-               state->af9033_config[1].i2c_addr = tmp;
+               if (tmp)
+                       state->af9033_config[1].i2c_addr = tmp;
+
                dev_dbg(&d->udev->dev, "%s: 2nd demod I2C addr=%02x\n",
                                __func__, tmp);
        }
@@ -938,12 +945,7 @@ static int af9035_frontend_callback(void *adapter_priv, int component,
 static int af9035_get_adapter_count(struct dvb_usb_device *d)
 {
        struct state *state = d_to_priv(d);
-
-       /* disable 2nd adapter as we don't have PID filters implemented */
-       if (d->udev->speed == USB_SPEED_FULL)
-               return 1;
-       else
-               return state->dual_mode + 1;
+       return state->dual_mode + 1;
 }
 
 static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
@@ -961,7 +963,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
 
        /* attach demodulator */
        adap->fe[0] = dvb_attach(af9033_attach, &state->af9033_config[adap->id],
-                       &d->i2c_adap);
+                       &d->i2c_adap, &state->ops);
        if (adap->fe[0] == NULL) {
                ret = -ENODEV;
                goto err;
@@ -1369,58 +1371,19 @@ static int af9035_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
        return 0;
 }
 
-/*
- * FIXME: PID filter is property of demodulator and should be moved to the
- * correct driver. Also we support only adapter #0 PID filter and will
- * disable adapter #1 if USB1.1 is used.
- */
 static int af9035_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-
-       dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
-
-       ret = af9035_wr_reg_mask(d, 0x80f993, onoff, 0x01);
-       if (ret < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       struct state *state = adap_to_priv(adap);
 
-       return ret;
+       return state->ops.pid_filter_ctrl(adap->fe[0], onoff);
 }
 
 static int af9035_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
                int onoff)
 {
-       struct dvb_usb_device *d = adap_to_d(adap);
-       int ret;
-       u8 wbuf[2] = {(pid >> 0) & 0xff, (pid >> 8) & 0xff};
-
-       dev_dbg(&d->udev->dev, "%s: index=%d pid=%04x onoff=%d\n",
-                       __func__, index, pid, onoff);
-
-       ret = af9035_wr_regs(d, 0x80f996, wbuf, 2);
-       if (ret < 0)
-               goto err;
-
-       ret = af9035_wr_reg(d, 0x80f994, onoff);
-       if (ret < 0)
-               goto err;
-
-       ret = af9035_wr_reg(d, 0x80f995, index);
-       if (ret < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+       struct state *state = adap_to_priv(adap);
 
-       return ret;
+       return state->ops.pid_filter(adap->fe[0], index, pid, onoff);
 }
 
 static int af9035_probe(struct usb_interface *intf,
@@ -1494,6 +1457,13 @@ static const struct dvb_usb_device_properties af9035_props = {
 
                        .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
                }, {
+                       .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+                       .pid_filter_count = 32,
+                       .pid_filter_ctrl = af9035_pid_filter_ctrl,
+                       .pid_filter = af9035_pid_filter,
+
                        .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
                },
        },
@@ -1528,12 +1498,30 @@ static const struct usb_device_id af9035_id_table[] = {
        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
                &af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) },
        /* IT9135 devices */
-#if 0
-       { DVB_USB_DEVICE(0x048d, 0x9135,
-               &af9035_props, "IT9135 reference design", NULL) },
-       { DVB_USB_DEVICE(0x048d, 0x9006,
-               &af9035_props, "IT9135 reference design", NULL) },
-#endif
+       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
+               &af9035_props, "ITE 9135 Generic", RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
+               &af9035_props, "ITE 9135(9005) Generic", RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
+               &af9035_props, "ITE 9135(9006) Generic", RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_1835,
+               &af9035_props, "Avermedia A835B(1835)", RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_2835,
+               &af9035_props, "Avermedia A835B(2835)", RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_3835,
+               &af9035_props, "Avermedia A835B(3835)", RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
+               &af9035_props, "Avermedia A835B(4835)", RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
+               &af9035_props, "Avermedia H335", RC_MAP_IT913X_V2) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
+               &af9035_props, "Kworld UB499-2T T09", RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
+               &af9035_props, "Sveon STV22 Dual DVB-T HDTV",
+                                                       RC_MAP_IT913X_V1) },
+       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
+               &af9035_props, "Digital Dual TV Receiver CTVDIGDUAL_V2",
+                                                       RC_MAP_IT913X_V1) },
        /* XXX: that same ID [0ccd:0099] is used by af9015 driver too */
        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099,
                &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) },
index a1c68d829b8ce7be68542ad1085dad46ce636b49..c21902fdd4c44e8d04ecce5962487921f4a92c16 100644 (file)
@@ -62,6 +62,8 @@ struct state {
        u8 dual_mode:1;
        u16 eeprom_addr;
        struct af9033_config af9033_config[2];
+
+       struct af9033_ops ops;
 };
 
 static const u32 clock_lut_af9035[] = {
index c1051c3477442bc1b98bb0f1ce514d788499057c..c3c4b98733bf5dec923f7c164eb87e95f880efdb 100644 (file)
@@ -7,7 +7,7 @@
  *     http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
  * The original driver's license is GPL, as declared with MODULE_LICENSE()
  *
- * Copyright (c) 2010-2012 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010-2012 Mauro Carvalho Chehab
  *     Driver modified by in order to work with upstream drxk driver, and
  *     tons of bugs got fixed, and converted to use dvb-usb-v2.
  *
@@ -975,7 +975,7 @@ static struct usb_driver az6007_usb_driver = {
 module_usb_driver(az6007_usb_driver);
 
 MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
 MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 8a054d66e708449ce6417135eaf4e20e675ac3aa..de02db802acea6bc47caacab100d6481eb639f8f 100644 (file)
@@ -164,7 +164,7 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
        dev->driver_name = (char *) d->props->driver_name;
        dev->map_name = d->rc.map_name;
        dev->driver_type = d->rc.driver_type;
-       dev->allowed_protos = d->rc.allowed_protos;
+       rc_set_allowed_protocols(dev, d->rc.allowed_protos);
        dev->change_protocol = d->rc.change_protocol;
        dev->priv = d;
 
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
deleted file mode 100644 (file)
index fe95a58..0000000
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * DVB USB compliant linux driver for ITE IT9135 and IT9137
- *
- * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
- * IT9135 (C) ITE Tech Inc.
- * IT9137 (C) ITE Tech Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * see Documentation/dvb/README.dvb-usb for more information
- * see Documentation/dvb/it9137.txt for firmware information
- *
- */
-#define DVB_USB_LOG_PREFIX "it913x"
-
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <media/rc-core.h>
-
-#include "dvb_usb.h"
-#include "it913x-fe.h"
-
-/* debug */
-static int dvb_usb_it913x_debug;
-#define it_debug(var, level, args...) \
-       do { if ((var & level)) pr_debug(DVB_USB_LOG_PREFIX": " args); \
-} while (0)
-#define deb_info(level, args...) it_debug(dvb_usb_it913x_debug, level, args)
-#define info(args...) pr_info(DVB_USB_LOG_PREFIX": " args)
-
-module_param_named(debug, dvb_usb_it913x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-static int dvb_usb_it913x_firmware;
-module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set firmware 0=auto "\
-       "1=IT9137 2=IT9135 V1 3=IT9135 V2");
-#define FW_IT9137 "dvb-usb-it9137-01.fw"
-#define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
-#define FW_IT9135_V2 "dvb-usb-it9135-02.fw"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct it913x_state {
-       struct ite_config it913x_config;
-       u8 pid_filter_onoff;
-       bool proprietary_ir;
-       int cmd_counter;
-};
-
-static u16 check_sum(u8 *p, u8 len)
-{
-       u16 sum = 0;
-       u8 i = 1;
-       while (i < len)
-               sum += (i++ & 1) ? (*p++) << 8 : *p++;
-       return ~sum;
-}
-
-static int it913x_io(struct dvb_usb_device *d, u8 mode, u8 pro,
-                       u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
-{
-       struct it913x_state *st = d->priv;
-       int ret = 0, i, buf_size = 1;
-       u8 *buff;
-       u8 rlen;
-       u16 chk_sum;
-
-       buff = kzalloc(256, GFP_KERNEL);
-       if (!buff) {
-               info("USB Buffer Failed");
-               return -ENOMEM;
-       }
-
-       buff[buf_size++] = pro;
-       buff[buf_size++] = cmd;
-       buff[buf_size++] = st->cmd_counter;
-
-       switch (mode) {
-       case READ_LONG:
-       case WRITE_LONG:
-               buff[buf_size++] = len;
-               buff[buf_size++] = 2;
-               buff[buf_size++] = (reg >> 24);
-               buff[buf_size++] = (reg >> 16) & 0xff;
-               buff[buf_size++] = (reg >> 8) & 0xff;
-               buff[buf_size++] = reg & 0xff;
-       break;
-       case READ_SHORT:
-               buff[buf_size++] = addr;
-               break;
-       case WRITE_SHORT:
-               buff[buf_size++] = len;
-               buff[buf_size++] = addr;
-               buff[buf_size++] = (reg >> 8) & 0xff;
-               buff[buf_size++] = reg & 0xff;
-       break;
-       case READ_DATA:
-       case WRITE_DATA:
-               break;
-       case WRITE_CMD:
-               mode = 7;
-               break;
-       default:
-               kfree(buff);
-               return -EINVAL;
-       }
-
-       if (mode & 1) {
-               for (i = 0; i < len ; i++)
-                       buff[buf_size++] = data[i];
-       }
-       chk_sum = check_sum(&buff[1], buf_size);
-
-       buff[buf_size++] = chk_sum >> 8;
-       buff[0] = buf_size;
-       buff[buf_size++] = (chk_sum & 0xff);
-
-       ret = dvb_usbv2_generic_rw(d, buff, buf_size, buff, (mode & 1) ?
-                       5 : len + 5);
-       if (ret < 0)
-               goto error;
-
-       rlen = (mode & 0x1) ? 0x1 : len;
-
-       if (mode & 1)
-               ret = buff[2];
-       else
-               memcpy(data, &buff[3], rlen);
-
-       st->cmd_counter++;
-
-error: kfree(buff);
-
-       return ret;
-}
-
-static int it913x_wr_reg(struct dvb_usb_device *d, u8 pro, u32 reg , u8 data)
-{
-       int ret;
-       u8 b[1];
-       b[0] = data;
-       ret = it913x_io(d, WRITE_LONG, pro,
-                       CMD_DEMOD_WRITE, reg, 0, b, sizeof(b));
-
-       return ret;
-}
-
-static int it913x_read_reg(struct dvb_usb_device *d, u32 reg)
-{
-       int ret;
-       u8 data[1];
-
-       ret = it913x_io(d, READ_LONG, DEV_0,
-                       CMD_DEMOD_READ, reg, 0, &data[0], sizeof(data));
-
-       return (ret < 0) ? ret : data[0];
-}
-
-static int it913x_query(struct dvb_usb_device *d, u8 pro)
-{
-       struct it913x_state *st = d->priv;
-       int ret, i;
-       u8 data[4];
-       u8 ver;
-
-       for (i = 0; i < 5; i++) {
-               ret = it913x_io(d, READ_LONG, pro, CMD_DEMOD_READ,
-                       0x1222, 0, &data[0], 3);
-               ver = data[0];
-               if (ver > 0 && ver < 3)
-                       break;
-               msleep(100);
-       }
-
-       if (ver < 1 || ver > 2) {
-               info("Failed to identify chip version applying 1");
-               st->it913x_config.chip_ver = 0x1;
-               st->it913x_config.chip_type = 0x9135;
-               return 0;
-       }
-
-       st->it913x_config.chip_ver = ver;
-       st->it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
-
-       info("Chip Version=%02x Chip Type=%04x", st->it913x_config.chip_ver,
-               st->it913x_config.chip_type);
-
-       ret = it913x_io(d, READ_SHORT, pro,
-                       CMD_QUERYINFO, 0, 0x1, &data[0], 4);
-
-       st->it913x_config.firmware = (data[0] << 24) | (data[1] << 16) |
-                       (data[2] << 8) | data[3];
-
-       return ret;
-}
-
-static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = adap_to_priv(adap);
-       int ret;
-       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
-       mutex_lock(&d->i2c_mutex);
-
-       deb_info(1, "PID_C  (%02x)", onoff);
-
-       st->pid_filter_onoff = adap->pid_filtering;
-       ret = it913x_wr_reg(d, pro, PID_EN, st->pid_filter_onoff);
-
-       mutex_unlock(&d->i2c_mutex);
-       return ret;
-}
-
-static int it913x_pid_filter(struct dvb_usb_adapter *adap,
-               int index, u16 pid, int onoff)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = adap_to_priv(adap);
-       int ret;
-       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
-       mutex_lock(&d->i2c_mutex);
-
-       deb_info(1, "PID_F  (%02x)", onoff);
-
-       ret = it913x_wr_reg(d, pro, PID_LSB, (u8)(pid & 0xff));
-
-       ret |= it913x_wr_reg(d, pro, PID_MSB, (u8)(pid >> 8));
-
-       ret |= it913x_wr_reg(d, pro, PID_INX_EN, (u8)onoff);
-
-       ret |= it913x_wr_reg(d, pro, PID_INX, (u8)(index & 0x1f));
-
-       if (d->udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
-                       ret |= it913x_wr_reg(d , pro, PID_EN, !onoff);
-                       st->pid_filter_onoff = !onoff;
-       } else
-               st->pid_filter_onoff =
-                       adap->pid_filtering;
-
-       mutex_unlock(&d->i2c_mutex);
-       return 0;
-}
-
-
-static int it913x_return_status(struct dvb_usb_device *d)
-{
-       struct it913x_state *st = d->priv;
-       int ret = it913x_query(d, DEV_0);
-       if (st->it913x_config.firmware > 0)
-               info("Firmware Version %d", st->it913x_config.firmware);
-
-       return ret;
-}
-
-static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                                int num)
-{
-       struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       static u8 data[256];
-       int ret;
-       u32 reg;
-       u8 pro;
-
-       mutex_lock(&d->i2c_mutex);
-
-       deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
-
-       pro = (msg[0].addr & 0x2) ?  DEV_0_DMOD : 0x0;
-       pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0;
-       memcpy(data, msg[0].buf, msg[0].len);
-       reg = (data[0] << 24) + (data[1] << 16) +
-                       (data[2] << 8) + data[3];
-       if (num == 2) {
-               ret = it913x_io(d, READ_LONG, pro,
-                       CMD_DEMOD_READ, reg, 0, data, msg[1].len);
-               memcpy(msg[1].buf, data, msg[1].len);
-       } else
-               ret = it913x_io(d, WRITE_LONG, pro, CMD_DEMOD_WRITE,
-                       reg, 0, &data[4], msg[0].len - 4);
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static u32 it913x_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm it913x_i2c_algo = {
-       .master_xfer   = it913x_i2c_xfer,
-       .functionality = it913x_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-#if IS_ENABLED(CONFIG_RC_CORE)
-static int it913x_rc_query(struct dvb_usb_device *d)
-{
-       u8 ibuf[4];
-       int ret;
-       u32 key;
-       /* Avoid conflict with frontends*/
-       mutex_lock(&d->i2c_mutex);
-
-       ret = it913x_io(d, READ_LONG, PRO_LINK, CMD_IR_GET,
-               0, 0, &ibuf[0], sizeof(ibuf));
-
-       if ((ibuf[2] + ibuf[3]) == 0xff) {
-               key = ibuf[2];
-               key += ibuf[0] << 16;
-               key += ibuf[1] << 8;
-               deb_info(1, "NEC Extended Key =%08x", key);
-               if (d->rc_dev != NULL)
-                       rc_keydown(d->rc_dev, key, 0);
-       }
-
-       mutex_unlock(&d->i2c_mutex);
-
-       return ret;
-}
-
-static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
-{
-       struct it913x_state *st = d->priv;
-
-       if (st->proprietary_ir == false) {
-               rc->map_name = NULL;
-               return 0;
-       }
-
-       rc->allowed_protos = RC_BIT_NEC;
-       rc->query = it913x_rc_query;
-       rc->interval = 250;
-
-       return 0;
-}
-#else
-       #define it913x_get_rc_config NULL
-#endif
-
-/* Firmware sets raw */
-static const char fw_it9135_v1[] = FW_IT9135_V1;
-static const char fw_it9135_v2[] = FW_IT9135_V2;
-static const char fw_it9137[] = FW_IT9137;
-
-static void ite_get_firmware_name(struct dvb_usb_device *d,
-       const char **name)
-{
-       struct it913x_state *st = d->priv;
-       int sw;
-       /* auto switch */
-       if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_KWORLD_2)
-               sw = IT9137_FW;
-       else if (st->it913x_config.chip_ver == 1)
-               sw = IT9135_V1_FW;
-       else
-               sw = IT9135_V2_FW;
-
-       /* force switch */
-       if (dvb_usb_it913x_firmware != IT9135_AUTO)
-               sw = dvb_usb_it913x_firmware;
-
-       switch (sw) {
-       case IT9135_V1_FW:
-               st->it913x_config.firmware_ver = 1;
-               st->it913x_config.adc_x2 = 1;
-               st->it913x_config.read_slevel = false;
-               *name = fw_it9135_v1;
-               break;
-       case IT9135_V2_FW:
-               st->it913x_config.firmware_ver = 1;
-               st->it913x_config.adc_x2 = 1;
-               st->it913x_config.read_slevel = false;
-               *name = fw_it9135_v2;
-               switch (st->it913x_config.tuner_id_0) {
-               case IT9135_61:
-               case IT9135_62:
-                       break;
-               default:
-                       info("Unknown tuner ID applying default 0x60");
-               case IT9135_60:
-                       st->it913x_config.tuner_id_0 = IT9135_60;
-               }
-               break;
-       case IT9137_FW:
-       default:
-               st->it913x_config.firmware_ver = 0;
-               st->it913x_config.adc_x2 = 0;
-               st->it913x_config.read_slevel = true;
-               *name = fw_it9137;
-       }
-
-       return;
-}
-
-#define TS_MPEG_PKT_SIZE       188
-#define EP_LOW                 21
-#define TS_BUFFER_SIZE_PID     (EP_LOW*TS_MPEG_PKT_SIZE)
-#define EP_HIGH                        348
-#define TS_BUFFER_SIZE_MAX     (EP_HIGH*TS_MPEG_PKT_SIZE)
-
-static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
-               struct usb_data_stream_properties *stream)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       if (adap->pid_filtering)
-               stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID;
-       else
-               stream->u.bulk.buffersize = TS_BUFFER_SIZE_MAX;
-
-       return 0;
-}
-
-static int it913x_select_config(struct dvb_usb_device *d)
-{
-       struct it913x_state *st = d->priv;
-       int ret, reg;
-
-       ret = it913x_return_status(d);
-       if (ret < 0)
-               return ret;
-
-       if (st->it913x_config.chip_ver == 0x02
-                       && st->it913x_config.chip_type == 0x9135)
-               reg = it913x_read_reg(d, 0x461d);
-       else
-               reg = it913x_read_reg(d, 0x461b);
-
-       if (reg < 0)
-               return reg;
-
-       if (reg == 0) {
-               st->it913x_config.dual_mode = 0;
-               st->it913x_config.tuner_id_0 = IT9135_38;
-               st->proprietary_ir = true;
-       } else {
-               /* TS mode */
-               reg =  it913x_read_reg(d, 0x49c5);
-               if (reg < 0)
-                       return reg;
-               st->it913x_config.dual_mode = reg;
-
-               /* IR mode type */
-               reg = it913x_read_reg(d, 0x49ac);
-               if (reg < 0)
-                       return reg;
-               if (reg == 5) {
-                       info("Remote propriety (raw) mode");
-                       st->proprietary_ir = true;
-               } else if (reg == 1) {
-                       info("Remote HID mode NOT SUPPORTED");
-                       st->proprietary_ir = false;
-               }
-
-               /* Tuner_id */
-               reg = it913x_read_reg(d, 0x49d0);
-               if (reg < 0)
-                       return reg;
-               st->it913x_config.tuner_id_0 = reg;
-       }
-
-       info("Dual mode=%x Tuner Type=%x", st->it913x_config.dual_mode,
-               st->it913x_config.tuner_id_0);
-
-       return ret;
-}
-
-static int it913x_streaming_ctrl(struct dvb_frontend *fe, int onoff)
-{
-       struct dvb_usb_adapter *adap = fe_to_adap(fe);
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = fe_to_priv(fe);
-       int ret = 0;
-       u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
-       deb_info(1, "STM  (%02x)", onoff);
-
-       if (!onoff) {
-               mutex_lock(&d->i2c_mutex);
-
-               ret = it913x_wr_reg(d, pro, PID_RST, 0x1);
-
-               mutex_unlock(&d->i2c_mutex);
-               st->pid_filter_onoff =
-                       adap->pid_filtering;
-
-       }
-
-       return ret;
-}
-
-static int it913x_identify_state(struct dvb_usb_device *d, const char **name)
-{
-       struct it913x_state *st = d->priv;
-       int ret;
-       u8 reg;
-
-       /* Read and select config */
-       ret = it913x_select_config(d);
-       if (ret < 0)
-               return ret;
-
-       ite_get_firmware_name(d, name);
-
-       if (st->it913x_config.firmware > 0)
-               return WARM;
-
-       if (st->it913x_config.dual_mode) {
-               st->it913x_config.tuner_id_1 = it913x_read_reg(d, 0x49e0);
-               ret = it913x_wr_reg(d, DEV_0, GPIOH1_EN, 0x1);
-               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_ON, 0x1);
-               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
-               msleep(50);
-               ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x0);
-               msleep(50);
-               reg = it913x_read_reg(d, GPIOH1_O);
-               if (reg == 0) {
-                       ret |= it913x_wr_reg(d, DEV_0,  GPIOH1_O, 0x1);
-                       ret |= it913x_return_status(d);
-                       if (ret != 0)
-                               ret = it913x_wr_reg(d, DEV_0,
-                                       GPIOH1_O, 0x0);
-               }
-       }
-
-       reg = it913x_read_reg(d, IO_MUX_POWER_CLK);
-
-       if (st->it913x_config.dual_mode) {
-               ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
-               if (st->it913x_config.firmware_ver == 1)
-                       ret |= it913x_wr_reg(d, DEV_0,  0xcfff, 0x1);
-               else
-                       ret |= it913x_wr_reg(d, DEV_0,  CLK_O_EN, 0x1);
-       } else {
-               ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, 0x0);
-               if (st->it913x_config.firmware_ver == 1)
-                       ret |= it913x_wr_reg(d, DEV_0,  0xcfff, 0x0);
-               else
-                       ret |= it913x_wr_reg(d, DEV_0,  CLK_O_EN, 0x0);
-       }
-
-       ret |= it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_100);
-
-       return (ret < 0) ? ret : COLD;
-}
-
-static int it913x_download_firmware(struct dvb_usb_device *d,
-                                       const struct firmware *fw)
-{
-       struct it913x_state *st = d->priv;
-       int ret = 0, i = 0, pos = 0;
-       u8 packet_size, min_pkt;
-       u8 *fw_data;
-
-       ret = it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_100);
-
-       info("FRM Starting Firmware Download");
-
-       /* Multi firmware loader */
-       /* This uses scatter write firmware headers */
-       /* The firmware must start with 03 XX 00 */
-       /* and be the extact firmware length */
-
-       if (st->it913x_config.chip_ver == 2)
-               min_pkt = 0x11;
-       else
-               min_pkt = 0x19;
-
-       while (i <= fw->size) {
-               if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
-                       || (i == fw->size)) {
-                       packet_size = i - pos;
-                       if ((packet_size > min_pkt) || (i == fw->size)) {
-                               fw_data = (u8 *)(fw->data + pos);
-                               pos += packet_size;
-                               if (packet_size > 0) {
-                                       ret = it913x_io(d, WRITE_DATA,
-                                               DEV_0, CMD_SCATTER_WRITE, 0,
-                                               0, fw_data, packet_size);
-                                       if (ret < 0)
-                                               break;
-                               }
-                               udelay(1000);
-                       }
-               }
-               i++;
-       }
-
-       if (ret < 0)
-               info("FRM Firmware Download Failed (%d)" , ret);
-       else
-               info("FRM Firmware Download Completed - Resetting Device");
-
-       msleep(30);
-
-       ret = it913x_io(d, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
-       if (ret < 0)
-               info("FRM Device not responding to reboot");
-
-       ret = it913x_return_status(d);
-       if (st->it913x_config.firmware == 0) {
-               info("FRM Failed to reboot device");
-               return -ENODEV;
-       }
-
-       msleep(30);
-
-       ret = it913x_wr_reg(d, DEV_0,  I2C_CLK, I2C_CLK_400);
-
-       msleep(30);
-
-       /* Tuner function */
-       if (st->it913x_config.dual_mode)
-               ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0xa0);
-       else
-               ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0x68);
-
-       if ((st->it913x_config.chip_ver == 1) &&
-               (st->it913x_config.chip_type == 0x9135)) {
-               ret |= it913x_wr_reg(d, DEV_0,  PADODPU, 0x0);
-               ret |= it913x_wr_reg(d, DEV_0,  AGC_O_D, 0x0);
-               if (st->it913x_config.dual_mode) {
-                       ret |= it913x_wr_reg(d, DEV_1,  PADODPU, 0x0);
-                       ret |= it913x_wr_reg(d, DEV_1,  AGC_O_D, 0x0);
-               }
-       }
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_name(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       const char *desc = d->name;
-       char *fe_name[] = {"_1", "_2", "_3", "_4"};
-       char *name = adap->fe[0]->ops.info.name;
-
-       strlcpy(name, desc, 128);
-       strlcat(name, fe_name[adap->id], 128);
-
-       return 0;
-}
-
-static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
-{
-       struct dvb_usb_device *d = adap_to_d(adap);
-       struct it913x_state *st = d->priv;
-       int ret = 0;
-       u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
-       u16 ep_size = (adap->pid_filtering) ? TS_BUFFER_SIZE_PID / 4 :
-               TS_BUFFER_SIZE_MAX / 4;
-       u8 pkt_size = 0x80;
-
-       if (d->udev->speed != USB_SPEED_HIGH)
-               pkt_size = 0x10;
-
-       st->it913x_config.adf = it913x_read_reg(d, IO_MUX_POWER_CLK);
-
-       adap->fe[0] = dvb_attach(it913x_fe_attach,
-               &d->i2c_adap, adap_addr, &st->it913x_config);
-
-       if (adap->id == 0 && adap->fe[0]) {
-               it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x1);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
-               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f);
-               it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b);
-               if (st->proprietary_ir == false) /* Enable endpoint 3 */
-                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x3f);
-               else
-                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
-               it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB,
-                                       ep_size & 0xff);
-               it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
-               ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size);
-       } else if (adap->id == 1 && adap->fe[0]) {
-               if (st->proprietary_ir == false)
-                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x7f);
-               else
-                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
-               it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB,
-                                       ep_size & 0xff);
-               it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
-               it913x_wr_reg(d, DEV_0, EP5_MAX_PKT, pkt_size);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_EN, 0x1);
-               it913x_wr_reg(d, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
-               it913x_wr_reg(d, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
-               it913x_wr_reg(d, DEV_0_DMOD, TSIS_ENABLE, 0x1);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x0);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x0);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0);
-               it913x_wr_reg(d, DEV_0_DMOD, MP2IF_STOP_EN, 0x1);
-               it913x_wr_reg(d, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0);
-               ret = it913x_wr_reg(d, DEV_1_DMOD, MP2IF_STOP_EN, 0x0);
-       } else
-               return -ENODEV;
-
-       ret |= it913x_name(adap);
-
-       return ret;
-}
-
-/* DVB USB Driver */
-static int it913x_get_adapter_count(struct dvb_usb_device *d)
-{
-       struct it913x_state *st = d->priv;
-       if (st->it913x_config.dual_mode)
-               return 2;
-       return 1;
-}
-
-static struct dvb_usb_device_properties it913x_properties = {
-       .driver_name = KBUILD_MODNAME,
-       .owner = THIS_MODULE,
-       .bInterfaceNumber = 0,
-       .generic_bulk_ctrl_endpoint = 0x02,
-       .generic_bulk_ctrl_endpoint_response = 0x81,
-
-       .adapter_nr = adapter_nr,
-       .size_of_priv = sizeof(struct it913x_state),
-
-       .identify_state = it913x_identify_state,
-       .i2c_algo = &it913x_i2c_algo,
-
-       .download_firmware = it913x_download_firmware,
-
-       .frontend_attach  = it913x_frontend_attach,
-       .get_rc_config = it913x_get_rc_config,
-       .get_stream_config = it913x_get_stream_config,
-       .get_adapter_count = it913x_get_adapter_count,
-       .streaming_ctrl   = it913x_streaming_ctrl,
-
-
-       .adapter = {
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .pid_filter = it913x_pid_filter,
-                       .pid_filter_ctrl  = it913x_pid_filter_ctrl,
-                       .stream =
-                       DVB_USB_STREAM_BULK(0x84, 10, TS_BUFFER_SIZE_MAX),
-               },
-               {
-                       .caps = DVB_USB_ADAP_HAS_PID_FILTER|
-                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-                       .pid_filter_count = 32,
-                       .pid_filter = it913x_pid_filter,
-                       .pid_filter_ctrl  = it913x_pid_filter_ctrl,
-                       .stream =
-                       DVB_USB_STREAM_BULK(0x85, 10, TS_BUFFER_SIZE_MAX),
-               }
-       }
-};
-
-static const struct usb_device_id it913x_id_table[] = {
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
-               &it913x_properties, "Kworld UB499-2T T09(IT9137)",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
-               &it913x_properties, "ITE 9135 Generic",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
-               &it913x_properties, "Sveon STV22 Dual DVB-T HDTV(IT9137)",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
-               &it913x_properties, "ITE 9135(9005) Generic",
-                       RC_MAP_IT913X_V2) },
-       { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
-               &it913x_properties, "ITE 9135(9006) Generic",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_1835,
-               &it913x_properties, "Avermedia A835B(1835)",
-                       RC_MAP_IT913X_V2) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_2835,
-               &it913x_properties, "Avermedia A835B(2835)",
-                       RC_MAP_IT913X_V2) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_3835,
-               &it913x_properties, "Avermedia A835B(3835)",
-                       RC_MAP_IT913X_V2) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
-               &it913x_properties, "Avermedia A835B(4835)",
-                       RC_MAP_IT913X_V2) },
-       { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
-               &it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2",
-                       RC_MAP_IT913X_V1) },
-       { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
-               &it913x_properties, "Avermedia H335",
-                       RC_MAP_IT913X_V2) },
-       {}              /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, it913x_id_table);
-
-static struct usb_driver it913x_driver = {
-       .name           = KBUILD_MODNAME,
-       .probe          = dvb_usbv2_probe,
-       .disconnect     = dvb_usbv2_disconnect,
-       .suspend        = dvb_usbv2_suspend,
-       .resume         = dvb_usbv2_resume,
-       .id_table       = it913x_id_table,
-};
-
-module_usb_driver(it913x_driver);
-
-MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
-MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.33");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(FW_IT9135_V1);
-MODULE_FIRMWARE(FW_IT9135_V2);
-MODULE_FIRMWARE(FW_IT9137);
-
index fda5c64ba0e8220f0876e56ad3bf0d328361edf5..c83c16cece01632a128ebcfac7a8d3eed94eb05e 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "rtl2830.h"
 #include "rtl2832.h"
+#include "rtl2832_sdr.h"
 
 #include "qt1010.h"
 #include "mt2060.h"
@@ -35,6 +36,9 @@
 #include "tua9001.h"
 #include "r820t.h"
 
+static int rtl28xxu_disable_rc;
+module_param_named(disable_rc, rtl28xxu_disable_rc, int, 0644);
+MODULE_PARM_DESC(disable_rc, "disable RTL2832U remote controller");
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
@@ -513,7 +517,7 @@ err:
        return ret;
 }
 
-static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
+static const struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
        .ts_mode = 0,
@@ -524,7 +528,7 @@ static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
 
 };
 
-static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
+static const struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
        .ts_mode = 0,
@@ -534,7 +538,7 @@ static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
        .agc_targ_val = 0x2d,
 };
 
-static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
+static const struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
        .ts_mode = 0,
@@ -548,7 +552,7 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
 {
        struct dvb_usb_device *d = adap_to_d(adap);
        struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct rtl2830_config *rtl2830_config;
+       const struct rtl2830_config *rtl2830_config;
        int ret;
 
        dev_dbg(&d->udev->dev, "%s:\n", __func__);
@@ -583,33 +587,31 @@ err:
        return ret;
 }
 
-static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
-       .if_dvbt = 0,
        .tuner = TUNER_RTL2832_FC0012
 };
 
-static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
-       .if_dvbt = 0,
        .tuner = TUNER_RTL2832_FC0013
 };
 
-static struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
        .tuner = TUNER_RTL2832_TUA9001,
 };
 
-static struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
        .i2c_addr = 0x10, /* 0x20 */
        .xtal = 28800000,
        .tuner = TUNER_RTL2832_E4000,
 };
 
-static struct rtl2832_config rtl28xxu_rtl2832_r820t_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_r820t_config = {
        .i2c_addr = 0x10,
        .xtal = 28800000,
        .tuner = TUNER_RTL2832_R820T,
@@ -733,7 +735,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
        int ret;
        struct dvb_usb_device *d = adap_to_d(adap);
        struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct rtl2832_config *rtl2832_config;
+       const struct rtl2832_config *rtl2832_config;
 
        dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
@@ -772,6 +774,9 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
                goto err;
        }
 
+       /* RTL2832 I2C repeater */
+       priv->demod_i2c_adapter = rtl2832_get_i2c_adapter(adap->fe[0]);
+
        /* set fe callback */
        adap->fe[0]->callback = rtl2832u_frontend_callback;
 
@@ -851,11 +856,6 @@ err:
        return ret;
 }
 
-static const struct e4000_config rtl2832u_e4000_config = {
-       .i2c_addr = 0x64,
-       .clock = 28800000,
-};
-
 static const struct fc2580_config rtl2832u_fc2580_config = {
        .i2c_addr = 0x56,
        .clock = 16384000,
@@ -889,10 +889,14 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
        int ret;
        struct dvb_usb_device *d = adap_to_d(adap);
        struct rtl28xxu_priv *priv = d_to_priv(d);
-       struct dvb_frontend *fe;
+       struct dvb_frontend *fe = NULL;
+       struct i2c_board_info info;
+       struct i2c_client *client;
 
        dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
+       memset(&info, 0, sizeof(struct i2c_board_info));
+
        switch (priv->tuner) {
        case TUNER_RTL2832_FC0012:
                fe = dvb_attach(fc0012_attach, adap->fe[0],
@@ -902,7 +906,10 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                 * that to the tuner driver */
                adap->fe[0]->ops.read_signal_strength =
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
-               return 0;
+
+               /* attach SDR */
+               dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+                               &rtl28xxu_rtl2832_fc0012_config, NULL);
                break;
        case TUNER_RTL2832_FC0013:
                fe = dvb_attach(fc0013_attach, adap->fe[0],
@@ -911,10 +918,43 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                /* fc0013 also supports signal strength reading */
                adap->fe[0]->ops.read_signal_strength =
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
-               return 0;
-       case TUNER_RTL2832_E4000:
-               fe = dvb_attach(e4000_attach, adap->fe[0], &d->i2c_adap,
-                               &rtl2832u_e4000_config);
+
+               /* attach SDR */
+               dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+                               &rtl28xxu_rtl2832_fc0013_config, NULL);
+               break;
+       case TUNER_RTL2832_E4000: {
+                       struct v4l2_subdev *sd;
+                       struct i2c_adapter *i2c_adap_internal =
+                                       rtl2832_get_private_i2c_adapter(adap->fe[0]);
+                       struct e4000_config e4000_config = {
+                               .fe = adap->fe[0],
+                               .clock = 28800000,
+                       };
+
+                       strlcpy(info.type, "e4000", I2C_NAME_SIZE);
+                       info.addr = 0x64;
+                       info.platform_data = &e4000_config;
+
+                       request_module(info.type);
+                       client = i2c_new_device(priv->demod_i2c_adapter, &info);
+                       if (client == NULL || client->dev.driver == NULL)
+                               break;
+
+                       if (!try_module_get(client->dev.driver->owner)) {
+                               i2c_unregister_device(client);
+                               break;
+                       }
+
+                       priv->client = client;
+                       sd = i2c_get_clientdata(client);
+                       i2c_set_adapdata(i2c_adap_internal, d);
+
+                       /* attach SDR */
+                       dvb_attach(rtl2832_sdr_attach, adap->fe[0],
+                                       i2c_adap_internal,
+                                       &rtl28xxu_rtl2832_e4000_config, sd);
+               }
                break;
        case TUNER_RTL2832_FC2580:
                fe = dvb_attach(fc2580_attach, adap->fe[0], &d->i2c_adap,
@@ -940,6 +980,10 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                /* Use tuner to get the signal strength */
                adap->fe[0]->ops.read_signal_strength =
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
+
+               /* attach SDR */
+               dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+                               &rtl28xxu_rtl2832_r820t_config, NULL);
                break;
        case TUNER_RTL2832_R828D:
                /* power off mn88472 demod on GPIO0 */
@@ -963,12 +1007,11 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                                adap->fe[0]->ops.tuner_ops.get_rf_strength;
                break;
        default:
-               fe = NULL;
                dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
                                priv->tuner);
        }
 
-       if (fe == NULL) {
+       if (fe == NULL && priv->client == NULL) {
                ret = -ENODEV;
                goto err;
        }
@@ -1013,6 +1056,22 @@ err:
        return ret;
 }
 
+static void rtl28xxu_exit(struct dvb_usb_device *d)
+{
+       struct rtl28xxu_priv *priv = d->priv;
+       struct i2c_client *client = priv->client;
+
+       dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+       /* remove I2C tuner */
+       if (client) {
+               module_put(client->dev.driver->owner);
+               i2c_unregister_device(client);
+       }
+
+       return;
+}
+
 static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
        int ret;
@@ -1322,6 +1381,10 @@ err:
 static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
                struct dvb_usb_rc *rc)
 {
+       /* disable IR interrupts in order to avoid SDR sample loss */
+       if (rtl28xxu_disable_rc)
+               return rtl28xx_wr_reg(d, IR_RX_IE, 0x00);
+
        /* load empty to enable rc */
        if (!rc->map_name)
                rc->map_name = RC_MAP_EMPTY;
@@ -1371,6 +1434,7 @@ static const struct dvb_usb_device_properties rtl2832u_props = {
        .frontend_attach = rtl2832u_frontend_attach,
        .tuner_attach = rtl2832u_tuner_attach,
        .init = rtl28xxu_init,
+       .exit = rtl28xxu_exit,
        .get_rc_config = rtl2832u_get_rc_config,
 
        .num_adapters = 1,
@@ -1382,6 +1446,7 @@ static const struct dvb_usb_device_properties rtl2832u_props = {
 };
 
 static const struct usb_device_id rtl28xxu_id_table[] = {
+       /* RTL2831U devices: */
        { DVB_USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U,
                &rtl2831u_props, "Realtek RTL2831U reference design", NULL) },
        { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT,
@@ -1389,6 +1454,7 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
        { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2,
                &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
 
+       /* RTL2832U devices: */
        { DVB_USB_DEVICE(USB_VID_REALTEK, 0x2832,
                &rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
        { DVB_USB_DEVICE(USB_VID_REALTEK, 0x2838,
@@ -1401,6 +1467,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
                &rtl2832u_props, "TerraTec NOXON DAB Stick", NULL) },
        { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK_REV2,
                &rtl2832u_props, "TerraTec NOXON DAB Stick (rev 2)", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK_REV3,
+               &rtl2832u_props, "TerraTec NOXON DAB Stick (rev 3)", NULL) },
        { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TREKSTOR_TERRES_2_0,
                &rtl2832u_props, "Trekstor DVB-T Stick Terres 2.0", NULL) },
        { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1101,
@@ -1429,9 +1497,14 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
                &rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) },
        { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A,
                &rtl2832u_props, "Crypto ReDi PC 50 A", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KYE, 0x707f,
+               &rtl2832u_props, "Genius TVGo DVB-T03", NULL) },
 
+       /* RTL2832P devices: */
        { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131,
                &rtl2832u_props, "Astrometa DVB-T2", NULL) },
+       { DVB_USB_DEVICE(USB_VID_KYE, 0x707f,
+               &rtl2832u_props, "Genius TVGo DVB-T03", NULL) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
index 2142bcb41b414b42a45774babef70529c3658d97..a26cab10f382289db1f9e7801b10c482d187a7f1 100644 (file)
@@ -55,7 +55,9 @@ struct rtl28xxu_priv {
        u8 tuner;
        char *tuner_name;
        u8 page; /* integrated demod active register page */
+       struct i2c_adapter *demod_i2c_adapter;
        bool rc_active;
+       struct i2c_client *client;
 };
 
 enum rtl28xxu_chip_id {
index 41bacff24960b7b7262d435ac575a147fac8c511..4058aea9272faad2667961776ca7a42957e639fc 100644 (file)
@@ -272,7 +272,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
        dev->driver_name = d->props.rc.core.module_name;
        dev->map_name = d->props.rc.core.rc_codes;
        dev->change_protocol = d->props.rc.core.change_protocol;
-       dev->allowed_protos = d->props.rc.core.allowed_protos;
+       rc_set_allowed_protocols(dev, d->props.rc.core.allowed_protos);
        dev->driver_type = d->props.rc.core.driver_type;
        usb_to_input_id(d->udev, &dev->input_id);
        dev->input_name = "IR-receiver inside an USB DVB receiver";
index a1fccf3096de7825097383c427e5471e2ceb40b8..d23a912096f7b7a67a1521992c68d06cb717b873 100644 (file)
@@ -53,8 +53,10 @@ config VIDEO_EM28XX_DVB
        select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
        select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
        select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+       select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT
        select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
        select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
+       select DVB_DRX39XYJ if MEDIA_SUBDRV_AUTOSELECT
        ---help---
          This adds support for DVB cards based on the
          Empiatech em28xx chips.
index 1a28897af1831d1ebfc8e101a25e71e5732ba1a3..342490f44ed27555ab8320558965e82a52b408d1 100644 (file)
@@ -252,7 +252,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
 {
        struct em28xx *dev = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
-       int ret = 0;
+       int nonblock, ret = 0;
 
        if (!dev) {
                em28xx_err("BUG: em28xx can't find device struct."
@@ -265,45 +265,48 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
 
        dprintk("opening device and trying to acquire exclusive lock\n");
 
+       nonblock = !!(substream->f_flags & O_NONBLOCK);
+       if (nonblock) {
+               if (!mutex_trylock(&dev->lock))
+               return -EAGAIN;
+       } else
+               mutex_lock(&dev->lock);
+
        runtime->hw = snd_em28xx_hw_capture;
-       if ((dev->alt == 0 || dev->is_audio_only) && dev->adev.users == 0) {
-               int nonblock = !!(substream->f_flags & O_NONBLOCK);
-
-               if (nonblock) {
-                       if (!mutex_trylock(&dev->lock))
-                               return -EAGAIN;
-               } else
-                       mutex_lock(&dev->lock);
-               if (dev->is_audio_only)
-                       /* vendor audio is on a separate interface */
-                       dev->alt = 1;
-               else
-                       /* vendor audio is on the same interface as video */
-                       dev->alt = 7;
-                       /*
-                        * FIXME: The intention seems to be to select the alt
-                        * setting with the largest wMaxPacketSize for the video
-                        * endpoint.
-                        * At least dev->alt should be used instead, but we
-                        * should probably not touch it at all if it is
-                        * already >0, because wMaxPacketSize of the audio
-                        * endpoints seems to be the same for all.
-                        */
-
-               dprintk("changing alternate number on interface %d to %d\n",
-                       dev->ifnum, dev->alt);
-               usb_set_interface(dev->udev, dev->ifnum, dev->alt);
+
+       if (dev->adev.users == 0) {
+               if (dev->alt == 0 || dev->is_audio_only) {
+                       if (dev->is_audio_only)
+                               /* audio is on a separate interface */
+                               dev->alt = 1;
+                       else
+                               /* audio is on the same interface as video */
+                               dev->alt = 7;
+                               /*
+                                * FIXME: The intention seems to be to select
+                                * the alt setting with the largest
+                                * wMaxPacketSize for the video endpoint.
+                                * At least dev->alt should be used instead, but
+                                * we should probably not touch it at all if it
+                                * is already >0, because wMaxPacketSize of the
+                                * audio endpoints seems to be the same for all.
+                                */
+                       dprintk("changing alternate number on interface %d to %d\n",
+                               dev->ifnum, dev->alt);
+                       usb_set_interface(dev->udev, dev->ifnum, dev->alt);
+               }
 
                /* Sets volume, mute, etc */
                dev->mute = 0;
                ret = em28xx_audio_analog_set(dev);
                if (ret < 0)
                        goto err;
-
-               dev->adev.users++;
-               mutex_unlock(&dev->lock);
        }
 
+       kref_get(&dev->ref);
+       dev->adev.users++;
+       mutex_unlock(&dev->lock);
+
        /* Dynamically adjust the period size */
        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
@@ -341,6 +344,7 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
                substream->runtime->dma_area = NULL;
        }
        mutex_unlock(&dev->lock);
+       kref_put(&dev->ref, em28xx_free_device);
 
        return 0;
 }
@@ -895,6 +899,8 @@ static int em28xx_audio_init(struct em28xx *dev)
 
        em28xx_info("Binding audio extension\n");
 
+       kref_get(&dev->ref);
+
        printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
                         "Rechberger\n");
        printk(KERN_INFO
@@ -966,7 +972,7 @@ static int em28xx_audio_fini(struct em28xx *dev)
        if (dev == NULL)
                return 0;
 
-       if (dev->has_alsa_audio != 1) {
+       if (!dev->has_alsa_audio) {
                /* This device does not support the extension (in this case
                   the device is expecting the snd-usb-audio module or
                   doesn't have analog audio support at all) */
@@ -985,6 +991,35 @@ static int em28xx_audio_fini(struct em28xx *dev)
                dev->adev.sndcard = NULL;
        }
 
+       kref_put(&dev->ref, em28xx_free_device);
+       return 0;
+}
+
+static int em28xx_audio_suspend(struct em28xx *dev)
+{
+       if (dev == NULL)
+               return 0;
+
+       if (!dev->has_alsa_audio)
+               return 0;
+
+       em28xx_info("Suspending audio extension");
+       em28xx_deinit_isoc_audio(dev);
+       atomic_set(&dev->stream_started, 0);
+       return 0;
+}
+
+static int em28xx_audio_resume(struct em28xx *dev)
+{
+       if (dev == NULL)
+               return 0;
+
+       if (!dev->has_alsa_audio)
+               return 0;
+
+       em28xx_info("Resuming audio extension");
+       /* Nothing to do other than schedule_work() ?? */
+       schedule_work(&dev->wq_trigger);
        return 0;
 }
 
@@ -993,6 +1028,8 @@ static struct em28xx_ops audio_ops = {
        .name = "Em28xx Audio Extension",
        .init = em28xx_audio_init,
        .fini = em28xx_audio_fini,
+       .suspend = em28xx_audio_suspend,
+       .resume = em28xx_audio_resume,
 };
 
 static int __init em28xx_alsa_register(void)
@@ -1007,7 +1044,7 @@ static void __exit em28xx_alsa_unregister(void)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_DESCRIPTION(DRIVER_DESC " - audio interface");
 MODULE_VERSION(EM28XX_VERSION);
 
index c29f5c4e7b4074858503d0ef876540a0ede66db1..505e0505be040caf5b90c0273409cb089ee20e19 100644 (file)
@@ -120,7 +120,7 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev)
                reg = 0x00;
                ret = i2c_master_send(&client, &reg, 1);
                if (ret < 0) {
-                       if (ret != -ENODEV)
+                       if (ret != -ENXIO)
                                em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n",
                                              client.addr << 1, ret);
                        continue;
@@ -218,7 +218,7 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev)
                reg = 0x1c;
                ret = i2c_smbus_read_byte_data(&client, reg);
                if (ret < 0) {
-                       if (ret != -ENODEV)
+                       if (ret != -ENXIO)
                                em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n",
                                              client.addr << 1, ret);
                        continue;
index 4d97a76cc3b085cd20b274a90db73e4049218439..50aa5a5317f236ca1e6344b7194361cb2518cee6 100644 (file)
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(usb_xfer_mode,
 
 
 /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
-DECLARE_BITMAP(em28xx_devused, EM28XX_MAXBOARDS);
+static DECLARE_BITMAP(em28xx_devused, EM28XX_MAXBOARDS);
 
 struct em28xx_hash_table {
        unsigned long hash;
@@ -189,6 +189,14 @@ static struct em28xx_reg_seq kworld_a340_digital[] = {
        {       -1,             -1,     -1,             -1},
 };
 
+static struct em28xx_reg_seq kworld_ub435q_v3_digital[] = {
+       {EM2874_R80_GPIO_P0_CTRL,       0xff,   0xff,   100},
+       {EM2874_R80_GPIO_P0_CTRL,       0xfe,   0xff,   100},
+       {EM2874_R80_GPIO_P0_CTRL,       0xbe,   0xff,   100},
+       {EM2874_R80_GPIO_P0_CTRL,       0xfe,   0xff,   100},
+       {       -1,                     -1,     -1,     -1},
+};
+
 /* Pinnacle Hybrid Pro eb1a:2881 */
 static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
        {EM2820_R08_GPIO_CTRL,  0xfd,   ~EM_GPIO_4,     10},
@@ -214,6 +222,17 @@ static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
        {       -1,             -1,     -1,             -1},
 };
 
+/* PCTV HD Mini (80e) GPIOs
+   0-5: not used
+   6:   demod reset, active low
+   7:   LED on, active high */
+static struct em28xx_reg_seq em2874_pctv_80e_digital[] = {
+       {EM28XX_R06_I2C_CLK,    0x45,   0xff,             10}, /*400 KHz*/
+       {EM2874_R80_GPIO_P0_CTRL, 0x00,   0xff,           100},/*Demod reset*/
+       {EM2874_R80_GPIO_P0_CTRL, 0x40,   0xff,           10},
+       {  -1,                  -1,     -1,               -1},
+};
+
 /* eb1a:2868 Reddo DVB-C USB TV Box
    GPIO4 - CU1216L NIM
    Other GPIOs seems to be don't care. */
@@ -497,6 +516,27 @@ static struct em28xx_led speedlink_vad_laplace_leds[] = {
        {-1, 0, 0, 0},
 };
 
+static struct em28xx_led kworld_ub435q_v3_leds[] = {
+       {
+               .role      = EM28XX_LED_DIGITAL_CAPTURING,
+               .gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
+               .gpio_mask = 0x80,
+               .inverted  = 1,
+       },
+       {-1, 0, 0, 0},
+};
+
+static struct em28xx_led pctv_80e_leds[] = {
+       {
+               .role      = EM28XX_LED_DIGITAL_CAPTURING,
+               .gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
+               .gpio_mask = 0x80,
+               .inverted  = 0,
+       },
+       {-1, 0, 0, 0},
+};
+
+
 /*
  *  Board definitions
  */
@@ -2128,6 +2168,29 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_gpio     = default_tuner_gpio,
                .def_i2c_bus    = 1,
        },
+       /*
+        * 1b80:e34c KWorld USB ATSC TV Stick UB435-Q V3
+        * Empia EM2874B + LG DT3305 + NXP TDA18271HDC2
+        */
+       [EM2874_BOARD_KWORLD_UB435Q_V3] = {
+               .name           = "KWorld USB ATSC TV Stick UB435-Q V3",
+               .tuner_type     = TUNER_ABSENT,
+               .has_dvb        = 1,
+               .tuner_gpio     = kworld_ub435q_v3_digital,
+               .def_i2c_bus    = 1,
+               .i2c_speed      = EM28XX_I2C_CLK_WAIT_ENABLE |
+                                 EM28XX_I2C_FREQ_100_KHZ,
+               .leds = kworld_ub435q_v3_leds,
+       },
+       [EM2874_BOARD_PCTV_HD_MINI_80E] = {
+               .name         = "Pinnacle PCTV HD Mini",
+               .tuner_type   = TUNER_ABSENT,
+               .has_dvb      = 1,
+               .dvb_gpio     = em2874_pctv_80e_digital,
+               .decoder      = EM28XX_NODECODER,
+               .ir_codes     = RC_MAP_PINNACLE_PCTV_HD,
+               .leds         = pctv_80e_leds,
+       },
        /* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
         * Empia EM2765 + OmniVision OV2640 */
        [EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = {
@@ -2290,6 +2353,8 @@ struct usb_device_id em28xx_id_table[] = {
                        .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
        { USB_DEVICE(0x2304, 0x0227),
                        .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
+       { USB_DEVICE(0x2304, 0x023f),
+                       .driver_info = EM2874_BOARD_PCTV_HD_MINI_80E },
        { USB_DEVICE(0x0413, 0x6023),
                        .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
        { USB_DEVICE(0x093b, 0xa003),
@@ -2304,6 +2369,8 @@ struct usb_device_id em28xx_id_table[] = {
                        .driver_info = EM2870_BOARD_KWORLD_A340 },
        { USB_DEVICE(0x1b80, 0xe346),
                        .driver_info = EM2874_BOARD_KWORLD_UB435Q_V2 },
+       { USB_DEVICE(0x1b80, 0xe34c),
+                       .driver_info = EM2874_BOARD_KWORLD_UB435Q_V3 },
        { USB_DEVICE(0x2013, 0x024f),
                        .driver_info = EM28174_BOARD_PCTV_290E },
        { USB_DEVICE(0x2013, 0x024c),
@@ -2872,7 +2939,7 @@ static void flush_request_modules(struct em28xx *dev)
  * unregisters the v4l2,i2c and usb devices
  * called when the device gets disconnected or at module unload
 */
-void em28xx_release_resources(struct em28xx *dev)
+static void em28xx_release_resources(struct em28xx *dev)
 {
        /*FIXME: I2C IR should be disconnected */
 
@@ -2889,7 +2956,27 @@ void em28xx_release_resources(struct em28xx *dev)
 
        mutex_unlock(&dev->lock);
 };
-EXPORT_SYMBOL_GPL(em28xx_release_resources);
+
+/**
+ * em28xx_free_device() - Free em28xx device
+ *
+ * @ref: struct kref for em28xx device
+ *
+ * This is called when all extensions and em28xx core unregisters a device
+ */
+void em28xx_free_device(struct kref *ref)
+{
+       struct em28xx *dev = kref_to_dev(ref);
+
+       em28xx_info("Freeing device\n");
+
+       if (!dev->disconnected)
+               em28xx_release_resources(dev);
+
+       kfree(dev->alt_max_pkt_size_isoc);
+       kfree(dev);
+}
+EXPORT_SYMBOL_GPL(em28xx_free_device);
 
 /*
  * em28xx_init_dev()
@@ -3331,8 +3418,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        if (has_video) {
            if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk))
                dev->analog_xfer_bulk = 1;
-               em28xx_info("analog set to %s mode.\n",
-                           dev->analog_xfer_bulk ? "bulk" : "isoc");
+           em28xx_info("analog set to %s mode.\n",
+                       dev->analog_xfer_bulk ? "bulk" : "isoc");
        }
        if (has_dvb) {
            if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk))
@@ -3342,6 +3429,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                            dev->dvb_xfer_bulk ? "bulk" : "isoc");
        }
 
+       kref_init(&dev->ref);
+
        request_modules(dev);
 
        /* Should be the last thing to do, to avoid newer udev's to
@@ -3386,17 +3475,39 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
        em28xx_close_extension(dev);
 
        em28xx_release_resources(dev);
+       kref_put(&dev->ref, em28xx_free_device);
+}
 
-       if (!dev->users) {
-               kfree(dev->alt_max_pkt_size_isoc);
-               kfree(dev);
-       }
+static int em28xx_usb_suspend(struct usb_interface *interface,
+                               pm_message_t message)
+{
+       struct em28xx *dev;
+
+       dev = usb_get_intfdata(interface);
+       if (!dev)
+               return 0;
+       em28xx_suspend_extension(dev);
+       return 0;
+}
+
+static int em28xx_usb_resume(struct usb_interface *interface)
+{
+       struct em28xx *dev;
+
+       dev = usb_get_intfdata(interface);
+       if (!dev)
+               return 0;
+       em28xx_resume_extension(dev);
+       return 0;
 }
 
 static struct usb_driver em28xx_usb_driver = {
        .name = "em28xx",
        .probe = em28xx_usb_probe,
        .disconnect = em28xx_usb_disconnect,
+       .suspend = em28xx_usb_suspend,
+       .resume = em28xx_usb_resume,
+       .reset_resume = em28xx_usb_resume,
        .id_table = em28xx_id_table,
 };
 
index 898fb9bd88a279db1cec20f44dc952eb4a721254..523d7e92bf47b7974515a1d9acd2fc19ab131b51 100644 (file)
@@ -619,6 +619,7 @@ EXPORT_SYMBOL_GPL(em28xx_find_led);
 int em28xx_capture_start(struct em28xx *dev, int start)
 {
        int rc;
+       const struct em28xx_led *led = NULL;
 
        if (dev->chip_id == CHIP_ID_EM2874 ||
            dev->chip_id == CHIP_ID_EM2884 ||
@@ -643,6 +644,8 @@ int em28xx_capture_start(struct em28xx *dev, int start)
 
                        /* Enable video capture */
                        rc = em28xx_write_reg(dev, 0x48, 0x00);
+                       if (rc < 0)
+                               return rc;
 
                        if (dev->mode == EM28XX_ANALOG_MODE)
                                rc = em28xx_write_reg(dev,
@@ -650,6 +653,8 @@ int em28xx_capture_start(struct em28xx *dev, int start)
                        else
                                rc = em28xx_write_reg(dev,
                                                    EM28XX_R12_VINENABLE, 0x37);
+                       if (rc < 0)
+                               return rc;
 
                        msleep(6);
                } else {
@@ -658,19 +663,16 @@ int em28xx_capture_start(struct em28xx *dev, int start)
                }
        }
 
-       if (rc < 0)
-               return rc;
-
-       /* Switch (explicitly controlled) analog capturing LED on/off */
-       if (dev->mode == EM28XX_ANALOG_MODE) {
-               const struct em28xx_led *led;
+       if (dev->mode == EM28XX_ANALOG_MODE)
                led = em28xx_find_led(dev, EM28XX_LED_ANALOG_CAPTURING);
-               if (led)
-                       em28xx_write_reg_bits(dev, led->gpio_reg,
-                                             (!start ^ led->inverted) ?
-                                             ~led->gpio_mask : led->gpio_mask,
-                                             led->gpio_mask);
-       }
+       else
+               led = em28xx_find_led(dev, EM28XX_LED_DIGITAL_CAPTURING);
+
+       if (led)
+               em28xx_write_reg_bits(dev, led->gpio_reg,
+                                     (!start ^ led->inverted) ?
+                                     ~led->gpio_mask : led->gpio_mask,
+                                     led->gpio_mask);
 
        return rc;
 }
@@ -1106,3 +1108,31 @@ void em28xx_close_extension(struct em28xx *dev)
        list_del(&dev->devlist);
        mutex_unlock(&em28xx_devlist_mutex);
 }
+
+int em28xx_suspend_extension(struct em28xx *dev)
+{
+       const struct em28xx_ops *ops = NULL;
+
+       em28xx_info("Suspending extensions");
+       mutex_lock(&em28xx_devlist_mutex);
+       list_for_each_entry(ops, &em28xx_extension_devlist, next) {
+               if (ops->suspend)
+                       ops->suspend(dev);
+       }
+       mutex_unlock(&em28xx_devlist_mutex);
+       return 0;
+}
+
+int em28xx_resume_extension(struct em28xx *dev)
+{
+       const struct em28xx_ops *ops = NULL;
+
+       em28xx_info("Resuming extensions");
+       mutex_lock(&em28xx_devlist_mutex);
+       list_for_each_entry(ops, &em28xx_extension_devlist, next) {
+               if (ops->resume)
+                       ops->resume(dev);
+       }
+       mutex_unlock(&em28xx_devlist_mutex);
+       return 0;
+}
index a0a669e81362956878755eea3cbf1a134905a303..f599b18ef7ca16bbd85b6acccfb93269cac3f574 100644 (file)
@@ -41,6 +41,7 @@
 #include "mt352.h"
 #include "mt352_priv.h" /* FIXME */
 #include "tda1002x.h"
+#include "drx39xyj/drx39xxj.h"
 #include "tda18271.h"
 #include "s921.h"
 #include "drxd.h"
@@ -48,6 +49,7 @@
 #include "tda18271c2dd.h"
 #include "drxk.h"
 #include "tda10071.h"
+#include "tda18212.h"
 #include "a8293.h"
 #include "qt1010.h"
 #include "mb86a20s.h"
@@ -161,6 +163,8 @@ static inline int em28xx_dvb_urb_data_copy(struct em28xx *dev, struct urb *urb)
                                if (urb->status != -EPROTO)
                                        continue;
                        }
+                       if (!urb->actual_length)
+                               continue;
                        dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
                                        urb->actual_length);
                } else {
@@ -170,6 +174,8 @@ static inline int em28xx_dvb_urb_data_copy(struct em28xx *dev, struct urb *urb)
                                if (urb->iso_frame_desc[i].status != -EPROTO)
                                        continue;
                        }
+                       if (!urb->iso_frame_desc[i].actual_length)
+                               continue;
                        dvb_dmx_swfilter(&dev->dvb->demux,
                                         urb->transfer_buffer +
                                         urb->iso_frame_desc[i].offset,
@@ -208,10 +214,10 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb)
        if (rc < 0)
                return rc;
 
-       dprintk(1, "Using %d buffers each with %d x %d bytes\n",
+       dprintk(1, "Using %d buffers each with %d x %d bytes, alternate %d\n",
                EM28XX_DVB_NUM_BUFS,
                packet_multiplier,
-               dvb_max_packet_size);
+               dvb_max_packet_size, dvb_alt);
 
        return em28xx_init_usb_xfer(dev, EM28XX_DIGITAL_MODE,
                                    dev->dvb_xfer_bulk,
@@ -315,6 +321,18 @@ static struct lgdt3305_config em2874_lgdt3305_dev = {
        .qam_if_khz         = 4000,
 };
 
+static struct lgdt3305_config em2874_lgdt3305_nogate_dev = {
+       .i2c_addr           = 0x0e,
+       .demod_chip         = LGDT3305,
+       .spectral_inversion = 1,
+       .deny_i2c_rptr      = 1,
+       .mpeg_mode          = LGDT3305_MPEG_SERIAL,
+       .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
+       .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
+       .vsb_if_khz         = 3600,
+       .qam_if_khz         = 3600,
+};
+
 static struct s921_config sharp_isdbt = {
        .demod_address = 0x30 >> 1
 };
@@ -351,6 +369,12 @@ static struct tda18271_config kworld_ub435q_v2_config = {
        .gate           = TDA18271_GATE_DIGITAL,
 };
 
+static struct tda18212_config kworld_ub435q_v3_config = {
+       .i2c_address    = 0x60,
+       .if_atsc_vsb    = 3600,
+       .if_atsc_qam    = 3600,
+};
+
 static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
        .demod_address = (0x1e >> 1),
        .no_tuner = 1,
@@ -693,7 +717,8 @@ static void pctv_520e_init(struct em28xx *dev)
 static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe)
 {
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct em28xx *dev = fe->dvb->priv;
+       struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv;
+       struct em28xx *dev = i2c_bus->dev;
 #ifdef CONFIG_GPIOLIB
        struct em28xx_dvb *dvb = dev->dvb;
        int ret;
@@ -817,6 +842,20 @@ static const struct m88ds3103_config pctv_461e_m88ds3103_config = {
        .agc = 0x99,
 };
 
+
+static struct tda18271_std_map drx_j_std_map = {
+       .atsc_6   = { .if_freq = 5000, .agc_mode = 3, .std = 0, .if_lvl = 1,
+                     .rfagc_top = 0x37, },
+       .qam_6    = { .if_freq = 5380, .agc_mode = 3, .std = 3, .if_lvl = 1,
+                     .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config pinnacle_80e_dvb_config = {
+       .std_map = &drx_j_std_map,
+       .gate    = TDA18271_GATE_DIGITAL,
+       .role    = TDA18271_MASTER,
+};
+
 /* ------------------------------------------------------------------ */
 
 static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
@@ -1005,7 +1044,6 @@ static int em28xx_dvb_init(struct em28xx *dev)
        em28xx_info("Binding DVB extension\n");
 
        dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
-
        if (dvb == NULL) {
                em28xx_info("em28xx_dvb: memory allocation failed\n");
                return -ENOMEM;
@@ -1370,10 +1408,40 @@ static int em28xx_dvb_init(struct em28xx *dev)
                        goto out_free;
                }
                break;
+       case EM2874_BOARD_KWORLD_UB435Q_V3:
+               dvb->fe[0] = dvb_attach(lgdt3305_attach,
+                                       &em2874_lgdt3305_nogate_dev,
+                                       &dev->i2c_adap[dev->def_i2c_bus]);
+               if (!dvb->fe[0]) {
+                       result = -EINVAL;
+                       goto out_free;
+               }
+
+               /* Attach the demodulator. */
+               if (!dvb_attach(tda18212_attach, dvb->fe[0],
+                               &dev->i2c_adap[dev->def_i2c_bus],
+                               &kworld_ub435q_v3_config)) {
+                       result = -EINVAL;
+                       goto out_free;
+               }
+               break;
+       case EM2874_BOARD_PCTV_HD_MINI_80E:
+               dvb->fe[0] = dvb_attach(drx39xxj_attach, &dev->i2c_adap[dev->def_i2c_bus]);
+               if (dvb->fe[0] != NULL) {
+                       dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
+                                               &dev->i2c_adap[dev->def_i2c_bus],
+                                               &pinnacle_80e_dvb_config);
+                       if (!dvb->fe[0]) {
+                               result = -EINVAL;
+                               goto out_free;
+                       }
+               }
+               break;
        case EM28178_BOARD_PCTV_461E:
                {
                        /* demod I2C adapter */
                        struct i2c_adapter *i2c_adapter;
+                       struct i2c_client *client;
                        struct i2c_board_info info;
                        struct m88ts2022_config m88ts2022_config = {
                                .clock = 27000000,
@@ -1396,7 +1464,19 @@ static int em28xx_dvb_init(struct em28xx *dev)
                        info.addr = 0x60;
                        info.platform_data = &m88ts2022_config;
                        request_module("m88ts2022");
-                       dvb->i2c_client_tuner = i2c_new_device(i2c_adapter, &info);
+                       client = i2c_new_device(i2c_adapter, &info);
+                       if (client == NULL || client->dev.driver == NULL) {
+                               dvb_frontend_detach(dvb->fe[0]);
+                               result = -ENODEV;
+                               goto out_free;
+                       }
+
+                       if (!try_module_get(client->dev.driver->owner)) {
+                               i2c_unregister_device(client);
+                               dvb_frontend_detach(dvb->fe[0]);
+                               result = -ENODEV;
+                               goto out_free;
+                       }
 
                        /* delegate signal strength measurement to tuner */
                        dvb->fe[0]->ops.read_signal_strength =
@@ -1406,10 +1486,14 @@ static int em28xx_dvb_init(struct em28xx *dev)
                        if (!dvb_attach(a8293_attach, dvb->fe[0],
                                        &dev->i2c_adap[dev->def_i2c_bus],
                                        &em28xx_a8293_config)) {
+                               module_put(client->dev.driver->owner);
+                               i2c_unregister_device(client);
                                dvb_frontend_detach(dvb->fe[0]);
                                result = -ENODEV;
                                goto out_free;
                        }
+
+                       dvb->i2c_client_tuner = client;
                }
                break;
        default:
@@ -1437,6 +1521,9 @@ static int em28xx_dvb_init(struct em28xx *dev)
        dvb->adapter.mfe_shared = mfe_shared;
 
        em28xx_info("DVB extension successfully initialized\n");
+
+       kref_get(&dev->ref);
+
 ret:
        em28xx_set_mode(dev, EM28XX_SUSPEND);
        mutex_unlock(&dev->lock);
@@ -1457,6 +1544,9 @@ static inline void prevent_sleep(struct dvb_frontend_ops *ops)
 
 static int em28xx_dvb_fini(struct em28xx *dev)
 {
+       struct em28xx_dvb *dvb;
+       struct i2c_client *client;
+
        if (dev->is_audio_only) {
                /* Shouldn't initialize IR for this interface */
                return 0;
@@ -1467,23 +1557,96 @@ static int em28xx_dvb_fini(struct em28xx *dev)
                return 0;
        }
 
+       if (!dev->dvb)
+               return 0;
+
        em28xx_info("Closing DVB extension");
 
+       dvb = dev->dvb;
+       client = dvb->i2c_client_tuner;
+
+       em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
+
+       if (dev->disconnected) {
+               /* We cannot tell the device to sleep
+                * once it has been unplugged. */
+               if (dvb->fe[0])
+                       prevent_sleep(&dvb->fe[0]->ops);
+               if (dvb->fe[1])
+                       prevent_sleep(&dvb->fe[1]->ops);
+       }
+
+       /* remove I2C tuner */
+       if (client) {
+               module_put(client->dev.driver->owner);
+               i2c_unregister_device(client);
+       }
+
+       em28xx_unregister_dvb(dvb);
+       kfree(dvb);
+       dev->dvb = NULL;
+       kref_put(&dev->ref, em28xx_free_device);
+
+       return 0;
+}
+
+static int em28xx_dvb_suspend(struct em28xx *dev)
+{
+       int ret = 0;
+
+       if (dev->is_audio_only)
+               return 0;
+
+       if (!dev->board.has_dvb)
+               return 0;
+
+       em28xx_info("Suspending DVB extension");
        if (dev->dvb) {
                struct em28xx_dvb *dvb = dev->dvb;
 
-               em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
+               if (dvb->fe[0]) {
+                       ret = dvb_frontend_suspend(dvb->fe[0]);
+                       em28xx_info("fe0 suspend %d", ret);
+               }
+               if (dvb->fe[1]) {
+                       dvb_frontend_suspend(dvb->fe[1]);
+                       em28xx_info("fe1 suspend %d", ret);
+               }
+       }
+
+       return 0;
+}
+
+static int em28xx_dvb_resume(struct em28xx *dev)
+{
+       int ret = 0;
 
-               if (dev->disconnected) {
-                       /* We cannot tell the device to sleep
-                        * once it has been unplugged. */
-                       if (dvb->fe[0])
-                               prevent_sleep(&dvb->fe[0]->ops);
-                       if (dvb->fe[1])
-                               prevent_sleep(&dvb->fe[1]->ops);
+       if (dev->is_audio_only)
+               return 0;
+
+       if (!dev->board.has_dvb)
+               return 0;
+
+       em28xx_info("Resuming DVB extension");
+       if (dev->dvb) {
+               struct em28xx_dvb *dvb = dev->dvb;
+               struct i2c_client *client = dvb->i2c_client_tuner;
+
+               if (dvb->fe[0]) {
+                       ret = dvb_frontend_resume(dvb->fe[0]);
+                       em28xx_info("fe0 resume %d", ret);
+               }
+
+               if (dvb->fe[1]) {
+                       ret = dvb_frontend_resume(dvb->fe[1]);
+                       em28xx_info("fe1 resume %d", ret);
+               }
+               /* remove I2C tuner */
+               if (client) {
+                       module_put(client->dev.driver->owner);
+                       i2c_unregister_device(client);
                }
 
-               i2c_release_client(dvb->i2c_client_tuner);
                em28xx_unregister_dvb(dvb);
                kfree(dvb);
                dev->dvb = NULL;
@@ -1497,6 +1660,8 @@ static struct em28xx_ops dvb_ops = {
        .name = "Em28xx dvb Extension",
        .init = em28xx_dvb_init,
        .fini = em28xx_dvb_fini,
+       .suspend = em28xx_dvb_suspend,
+       .resume = em28xx_dvb_resume,
 };
 
 static int __init em28xx_dvb_register(void)
index 7e1724076ac462b8b7e715bee8c53ec55119f83f..ba6433c3a6431833cba13751c8e1929b97f3b072 100644 (file)
@@ -81,7 +81,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
                        return len;
                if (ret == 0x94 + len - 1) {
                        if (i2c_debug == 1)
-                               em28xx_warn("R05 returned 0x%02x: I2C timeout",
+                               em28xx_warn("R05 returned 0x%02x: I2C ACK error\n",
                                            ret);
                        return -ENXIO;
                }
@@ -128,7 +128,7 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
                        break;
                if (ret == 0x94 + len - 1) {
                        if (i2c_debug == 1)
-                               em28xx_warn("R05 returned 0x%02x: I2C timeout",
+                               em28xx_warn("R05 returned 0x%02x: I2C ACK error\n",
                                            ret);
                        return -ENXIO;
                }
@@ -210,7 +210,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
                        return len;
                if (ret == 0x10) {
                        if (i2c_debug == 1)
-                               em28xx_warn("I2C transfer timeout on writing to addr 0x%02x",
+                               em28xx_warn("I2C ACK error on writing to addr 0x%02x\n",
                                            addr);
                        return -ENXIO;
                }
@@ -226,10 +226,18 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
                 * (even with high payload) ...
                 */
        }
-       if (i2c_debug)
-               em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n",
-                           addr, ret);
-       return -ETIMEDOUT;
+
+       if (ret == 0x02 || ret == 0x04) {
+               /* NOTE: these errors seem to be related to clock stretching */
+               if (i2c_debug)
+                       em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n",
+                                   addr, ret);
+               return -ETIMEDOUT;
+       }
+
+       em28xx_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n",
+                   addr, ret);
+       return -EIO;
 }
 
 /*
@@ -274,13 +282,22 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
        }
        if (ret == 0x10) {
                if (i2c_debug == 1)
-                       em28xx_warn("I2C transfer timeout on writing to addr 0x%02x",
+                       em28xx_warn("I2C ACK error on writing to addr 0x%02x\n",
                                    addr);
                return -ENXIO;
        }
 
-       em28xx_warn("unknown i2c error (status=%i)\n", ret);
-       return -ETIMEDOUT;
+       if (ret == 0x02 || ret == 0x04) {
+               /* NOTE: these errors seem to be related to clock stretching */
+               if (i2c_debug)
+                       em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n",
+                                   addr, ret);
+               return -ETIMEDOUT;
+       }
+
+       em28xx_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n",
+                   addr, ret);
+       return -EIO;
 }
 
 /*
@@ -337,7 +354,7 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
                return len;
        else if (ret > 0) {
                if (i2c_debug == 1)
-                       em28xx_warn("Bus B R08 returned 0x%02x: I2C timeout",
+                       em28xx_warn("Bus B R08 returned 0x%02x: I2C ACK error\n",
                                    ret);
                return -ENXIO;
        }
@@ -392,7 +409,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
                return len;
        else if (ret > 0) {
                if (i2c_debug == 1)
-                       em28xx_warn("Bus B R08 returned 0x%02x: I2C timeout",
+                       em28xx_warn("Bus B R08 returned 0x%02x: I2C ACK error\n",
                                    ret);
                return -ENXIO;
        }
index 18f65d89d4bc783a5005fc7b3aaa2b196c1c9904..56ef49df4f8d65e2df5d52abf547bcc63cc42ff2 100644 (file)
@@ -676,6 +676,8 @@ static int em28xx_ir_init(struct em28xx *dev)
                return 0;
        }
 
+       kref_get(&dev->ref);
+
        if (dev->board.buttons)
                em28xx_init_buttons(dev);
 
@@ -725,7 +727,7 @@ static int em28xx_ir_init(struct em28xx *dev)
                case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
                        rc->map_name = RC_MAP_HAUPPAUGE;
                        ir->get_key_i2c = em28xx_get_key_em_haup;
-                       rc->allowed_protos = RC_BIT_RC5;
+                       rc_set_allowed_protocols(rc, RC_BIT_RC5);
                        break;
                case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
                        rc->map_name = RC_MAP_WINFAST_USBII_DELUXE;
@@ -741,7 +743,7 @@ static int em28xx_ir_init(struct em28xx *dev)
                switch (dev->chip_id) {
                case CHIP_ID_EM2860:
                case CHIP_ID_EM2883:
-                       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
+                       rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC);
                        ir->get_key = default_polling_getkey;
                        break;
                case CHIP_ID_EM2884:
@@ -749,8 +751,8 @@ static int em28xx_ir_init(struct em28xx *dev)
                case CHIP_ID_EM28174:
                case CHIP_ID_EM28178:
                        ir->get_key = em2874_polling_getkey;
-                       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC |
-                                            RC_BIT_RC6_0;
+                       rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC |
+                                                RC_BIT_RC6_0);
                        break;
                default:
                        err = -ENODEV;
@@ -816,7 +818,7 @@ static int em28xx_ir_fini(struct em28xx *dev)
 
        /* skip detach on non attached boards */
        if (!ir)
-               return 0;
+               goto ref_put;
 
        if (ir->rc)
                rc_unregister_device(ir->rc);
@@ -824,6 +826,45 @@ static int em28xx_ir_fini(struct em28xx *dev)
        /* done */
        kfree(ir);
        dev->ir = NULL;
+
+ref_put:
+       kref_put(&dev->ref, em28xx_free_device);
+
+       return 0;
+}
+
+static int em28xx_ir_suspend(struct em28xx *dev)
+{
+       struct em28xx_IR *ir = dev->ir;
+
+       if (dev->is_audio_only)
+               return 0;
+
+       em28xx_info("Suspending input extension");
+       if (ir)
+               cancel_delayed_work_sync(&ir->work);
+       cancel_delayed_work_sync(&dev->buttons_query_work);
+       /* is canceling delayed work sufficient or does the rc event
+          kthread needs stopping? kthread is stopped in
+          ir_raw_event_unregister() */
+       return 0;
+}
+
+static int em28xx_ir_resume(struct em28xx *dev)
+{
+       struct em28xx_IR *ir = dev->ir;
+
+       if (dev->is_audio_only)
+               return 0;
+
+       em28xx_info("Resuming input extension");
+       /* if suspend calls ir_raw_event_unregister(), the should call
+          ir_raw_event_register() */
+       if (ir)
+               schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+       if (dev->num_button_polling_addresses)
+               schedule_delayed_work(&dev->buttons_query_work,
+                              msecs_to_jiffies(dev->button_polling_interval));
        return 0;
 }
 
@@ -832,6 +873,8 @@ static struct em28xx_ops rc_ops = {
        .name = "Em28xx Input Extension",
        .init = em28xx_ir_init,
        .fini = em28xx_ir_fini,
+       .suspend = em28xx_ir_suspend,
+       .resume = em28xx_ir_resume,
 };
 
 static int __init em28xx_rc_register(void)
@@ -845,7 +888,7 @@ static void __exit em28xx_rc_unregister(void)
 }
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_DESCRIPTION(DRIVER_DESC " - input interface");
 MODULE_VERSION(EM28XX_VERSION);
 
index c3c928937dcd800172bf959cae5fd2d73ad34f81..0856e5d367b6d9a7c495dfd9223eb7acf527ed05 100644 (file)
@@ -1029,7 +1029,7 @@ static int em28xx_vb2_setup(struct em28xx *dev)
        q = &dev->vb_vidq;
        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        q->drv_priv = dev;
        q->buf_struct_size = sizeof(struct em28xx_buffer);
        q->ops = &em28xx_video_qops;
@@ -1043,7 +1043,7 @@ static int em28xx_vb2_setup(struct em28xx *dev)
        q = &dev->vb_vbiq;
        q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
        q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        q->drv_priv = dev;
        q->buf_struct_size = sizeof(struct em28xx_buffer);
        q->ops = &em28xx_vbi_qops;
@@ -1837,7 +1837,6 @@ static int em28xx_v4l2_open(struct file *filp)
                        video_device_node_name(vdev), v4l2_type_names[fh_type],
                        dev->users);
 
-
        if (mutex_lock_interruptible(&dev->lock))
                return -ERESTARTSYS;
        fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
@@ -1869,6 +1868,7 @@ static int em28xx_v4l2_open(struct file *filp)
                v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
        }
 
+       kref_get(&dev->ref);
        dev->users++;
 
        mutex_unlock(&dev->lock);
@@ -1918,18 +1918,43 @@ static int em28xx_v4l2_fini(struct em28xx *dev)
                video_unregister_device(dev->vdev);
        }
 
+       v4l2_ctrl_handler_free(&dev->ctrl_handler);
+       v4l2_device_unregister(&dev->v4l2_dev);
+
        if (dev->clk) {
                v4l2_clk_unregister_fixed(dev->clk);
                dev->clk = NULL;
        }
 
-       v4l2_ctrl_handler_free(&dev->ctrl_handler);
-       v4l2_device_unregister(&dev->v4l2_dev);
-
-       if (dev->users)
-               em28xx_warn("Device is open ! Memory deallocation is deferred on last close.\n");
        mutex_unlock(&dev->lock);
+       kref_put(&dev->ref, em28xx_free_device);
+
+       return 0;
+}
+
+static int em28xx_v4l2_suspend(struct em28xx *dev)
+{
+       if (dev->is_audio_only)
+               return 0;
 
+       if (!dev->has_video)
+               return 0;
+
+       em28xx_info("Suspending video extension");
+       em28xx_stop_urbs(dev);
+       return 0;
+}
+
+static int em28xx_v4l2_resume(struct em28xx *dev)
+{
+       if (dev->is_audio_only)
+               return 0;
+
+       if (!dev->has_video)
+               return 0;
+
+       em28xx_info("Resuming video extension");
+       /* what do we do here */
        return 0;
 }
 
@@ -1950,11 +1975,9 @@ static int em28xx_v4l2_close(struct file *filp)
        mutex_lock(&dev->lock);
 
        if (dev->users == 1) {
-               /* free the remaining resources if device is disconnected */
-               if (dev->disconnected) {
-                       kfree(dev->alt_max_pkt_size_isoc);
+               /* No sense to try to write to the device */
+               if (dev->disconnected)
                        goto exit;
-               }
 
                /* Save some power by putting tuner to sleep */
                v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
@@ -1975,6 +1998,8 @@ static int em28xx_v4l2_close(struct file *filp)
 exit:
        dev->users--;
        mutex_unlock(&dev->lock);
+       kref_put(&dev->ref, em28xx_free_device);
+
        return 0;
 }
 
@@ -2273,7 +2298,8 @@ static int em28xx_v4l2_init(struct em28xx *dev)
        }
 
        em28xx_tuner_setup(dev);
-       em28xx_init_camera(dev);
+       if (dev->em28xx_sensor != EM28XX_NOSENSOR)
+               em28xx_init_camera(dev);
 
        /* Configure audio */
        ret = em28xx_audio_setup(dev);
@@ -2488,6 +2514,8 @@ static int em28xx_v4l2_init(struct em28xx *dev)
 
        em28xx_info("V4L2 extension successfully initialized\n");
 
+       kref_get(&dev->ref);
+
        mutex_unlock(&dev->lock);
        return 0;
 
@@ -2504,6 +2532,8 @@ static struct em28xx_ops v4l2_ops = {
        .name = "Em28xx v4l2 Extension",
        .init = em28xx_v4l2_init,
        .fini = em28xx_v4l2_fini,
+       .suspend = em28xx_v4l2_suspend,
+       .resume = em28xx_v4l2_resume,
 };
 
 static int __init em28xx_video_register(void)
index 32d8a4bb79613c8016d0209160af122532d072d5..2051fc9fb932a836ff8677e01b80fb7fb16967f6 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/workqueue.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
+#include <linux/kref.h>
 #include <linux/videodev2.h>
 
 #include <media/videobuf2-vmalloc.h>
 #define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E    56
 #define EM2883_BOARD_KWORLD_HYBRID_330U                  57
 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU     58
+#define EM2874_BOARD_PCTV_HD_MINI_80E            59
 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850     60
 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2    61
 #define EM2820_BOARD_GADMEI_TVR200               62
 #define EM2874_BOARD_KWORLD_UB435Q_V2            90
 #define EM2765_BOARD_SPEEDLINK_VAD_LAPLACE       91
 #define EM28178_BOARD_PCTV_461E                   92
+#define EM2874_BOARD_KWORLD_UB435Q_V3            93
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -399,6 +402,7 @@ enum em28xx_adecoder {
 
 enum em28xx_led_role {
        EM28XX_LED_ANALOG_CAPTURING = 0,
+       EM28XX_LED_DIGITAL_CAPTURING,
        EM28XX_LED_ILLUMINATION,
        EM28XX_NUM_LED_ROLES, /* must be the last */
 };
@@ -533,9 +537,10 @@ struct em28xx_i2c_bus {
        enum em28xx_i2c_algo_type algo_type;
 };
 
-
 /* main device struct */
 struct em28xx {
+       struct kref ref;
+
        /* generic device properties */
        char name[30];          /* name (including minor) of the device */
        int model;              /* index in the device_data struct */
@@ -707,12 +712,16 @@ struct em28xx {
        struct em28xx_dvb *dvb;
 };
 
+#define kref_to_dev(d) container_of(d, struct em28xx, ref)
+
 struct em28xx_ops {
        struct list_head next;
        char *name;
        int id;
        int (*init)(struct em28xx *);
        int (*fini)(struct em28xx *);
+       int (*suspend)(struct em28xx *);
+       int (*resume)(struct em28xx *);
 };
 
 /* Provided by em28xx-i2c.c */
@@ -758,13 +767,15 @@ int em28xx_register_extension(struct em28xx_ops *dev);
 void em28xx_unregister_extension(struct em28xx_ops *dev);
 void em28xx_init_extension(struct em28xx *dev);
 void em28xx_close_extension(struct em28xx *dev);
+int em28xx_suspend_extension(struct em28xx *dev);
+int em28xx_resume_extension(struct em28xx *dev);
 
 /* Provided by em28xx-cards.c */
 extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];
 int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
 void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl);
-void em28xx_release_resources(struct em28xx *dev);
+void em28xx_free_device(struct kref *ref);
 
 /* Provided by em28xx-camera.c */
 int em28xx_detect_sensor(struct em28xx *dev);
index 3773a8a745df9323719d4aaeb6dd949fa0e61cad..081f05162809b27edc1f92ba4c58a875e7e04bee 100644 (file)
@@ -155,10 +155,11 @@ static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
        do {
                actual_len = kinect_read(udev, ibuf, 0x200);
        } while (actual_len == 0);
-       PDEBUG(D_USBO, "Control reply: %d", res);
+       PDEBUG(D_USBO, "Control reply: %d", actual_len);
        if (actual_len < sizeof(*rhdr)) {
-               pr_err("send_cmd: Input control transfer failed (%d)\n", res);
-               return res;
+               pr_err("send_cmd: Input control transfer failed (%d)\n",
+                      actual_len);
+               return actual_len < 0 ? actual_len : -EREMOTEIO;
        }
        actual_len -= sizeof(*rhdr);
 
index 2a38621cf7188d1f8cdfe03e7d1fede7ffcad566..41a9a892f79c546c4a6b54edbee1ac09408897f6 100644 (file)
@@ -2359,6 +2359,7 @@ static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
        {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
        {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
+       {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
        {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
        {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
        {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
index bf3e5c317a26f68273b54db5a4b271012e039cef..e60cbb3aa60950675add7e332fe86cf53a847d39 100644 (file)
@@ -178,7 +178,7 @@ static int vv6410_stop(struct sd *sd)
 
        PDEBUG(D_STREAM, "Halting stream");
 
-       return (err < 0) ? err : 0;
+       return 0;
 }
 
 static int vv6410_dump(struct sd *sd)
index 640c2fe760b3c4e13c687eefbde34e156025d648..5fcd1eec2004ae97b1ed61df808cf3e97bc1adf4 100644 (file)
@@ -4631,8 +4631,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                }
                data++;
                len--;
+               if (len < 2) {
+                       gspca_dev->last_packet_type = DISCARD_PACKET;
+                       return;
+               }
                if (*data == 0xff && data[1] == 0xd8) {
 /*fixme: there may be information in the 4 high bits*/
+                       if (len < 7) {
+                               gspca_dev->last_packet_type = DISCARD_PACKET;
+                               return;
+                       }
                        if ((data[6] & 0x0f) != sd->quality)
                                set_dqt(gspca_dev, data[6] & 0x0f);
                        gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -4672,7 +4680,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                gspca_dev->last_packet_type = DISCARD_PACKET;
                break;
        case 0xcc:
-               if (data[1] != 0xff || data[2] != 0xd8)
+               if (len >= 3 && (data[1] != 0xff || data[2] != 0xd8))
                        gspca_frame_add(gspca_dev, INTER_PACKET,
                                        data + 1, len - 1);
                else
index abf365ab025da5a92d432c06b61bf223642b0a37..84a6720b1d00064c55be2f9f2cdd0a112be35df3 100644 (file)
@@ -614,17 +614,20 @@ static int buffer_prepare(struct vb2_buffer *vb)
        return 0;
 }
 
-static int buffer_finish(struct vb2_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
 {
        struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
        struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
 
-       /*
-        * Application has called dqbuf and is getting back a buffer we've
-        * filled, take the pwc data we've stored in buf->data and decompress
-        * it into a usable format, storing the result in the vb2_buffer
-        */
-       return pwc_decompress(pdev, buf);
+       if (vb->state == VB2_BUF_STATE_DONE) {
+               /*
+                * Application has called dqbuf and is getting back a buffer
+                * we've filled, take the pwc data we've stored in buf->data
+                * and decompress it into a usable format, storing the result
+                * in the vb2_buffer.
+                */
+               pwc_decompress(pdev, buf);
+       }
 }
 
 static void buffer_cleanup(struct vb2_buffer *vb)
@@ -1001,7 +1004,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
        pdev->vb_queue.ops = &pwc_vb_queue_ops;
        pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
-       pdev->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       pdev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        rc = vb2_queue_init(&pdev->vb_queue);
        if (rc < 0) {
                PWC_ERROR("Oops, could not initialize vb2 queue.\n");
index 7e8ee1f864ab7fd561b8a5a1d2d7fc75a3957c2a..8c3fceef9a09a2b95c01c4a87b21f724997c8ee9 100644 (file)
@@ -1,7 +1,7 @@
 config USB_S2255
        tristate "USB Sensoray 2255 video capture device"
        depends on VIDEO_V4L2
-       select VIDEOBUF_VMALLOC
+       select VIDEOBUF2_VMALLOC
        default n
        help
          Say Y here if you want support for the Sensoray 2255 USB device.
index 6bc9b8e19e20d889d225fdc1864f15b881b18184..1d4ba2b804908f9373de73100ccca4289032295b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  s2255drv.c - a driver for the Sensoray 2255 USB video capture device
  *
- *   Copyright (C) 2007-2013 by Sensoray Company Inc.
+ *   Copyright (C) 2007-2014 by Sensoray Company Inc.
  *                              Dean Anderson
  *
  * Some video buffer code based on vivi driver:
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/usb.h>
-#include <media/videobuf-vmalloc.h>
+#include <media/videobuf2-vmalloc.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-event.h>
 
-#define S2255_VERSION          "1.23.1"
+#define S2255_VERSION          "1.25.1"
 #define FIRMWARE_FILE_NAME "f2255usb.bin"
 
 /* default JPEG quality */
@@ -69,7 +69,7 @@
 #define S2255_DSP_BOOTTIME      800
 /* maximum time to wait for firmware to load (ms) */
 #define S2255_LOAD_TIMEOUT      (5000 + S2255_DSP_BOOTTIME)
-#define S2255_DEF_BUFS          16
+#define S2255_MIN_BUFS          2
 #define S2255_SETMODE_TIMEOUT   500
 #define S2255_VIDSTATUS_TIMEOUT 350
 #define S2255_MARKER_FRAME     cpu_to_le32(0x2255DA4AL)
@@ -178,11 +178,6 @@ struct s2255_bufferi {
                        DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
                        DEF_HUE, 0, DEF_USB_BLOCK, 0}
 
-struct s2255_dmaqueue {
-       struct list_head        active;
-       struct s2255_dev        *dev;
-};
-
 /* for firmware loading, fw_state */
 #define S2255_FW_NOTLOADED     0
 #define S2255_FW_LOADED_DSPWAIT        1
@@ -217,12 +212,14 @@ struct s2255_pipeinfo {
 struct s2255_fmt; /*forward declaration */
 struct s2255_dev;
 
-struct s2255_channel {
+/* 2255 video channel */
+struct s2255_vc {
+       struct s2255_dev        *dev;
        struct video_device     vdev;
        struct v4l2_ctrl_handler hdl;
        struct v4l2_ctrl        *jpegqual_ctrl;
        int                     resources;
-       struct s2255_dmaqueue   vidq;
+       struct list_head        buf_list;
        struct s2255_bufferi    buffer;
        struct s2255_mode       mode;
        v4l2_std_id             std;
@@ -232,8 +229,6 @@ struct s2255_channel {
        struct v4l2_captureparm cap_parm;
        int                     cur_frame;
        int                     last_frame;
-
-       int                     b_acquire;
        /* allocated image size */
        unsigned long           req_image_size;
        /* received packet size */
@@ -252,17 +247,22 @@ struct s2255_channel {
        int                     vidstatus_ready;
        unsigned int            width;
        unsigned int            height;
+       enum v4l2_field         field;
        const struct s2255_fmt  *fmt;
        int idx; /* channel number on device, 0-3 */
+       struct vb2_queue vb_vidq;
+       struct mutex vb_lock; /* streaming lock */
+       spinlock_t qlock;
 };
 
 
 struct s2255_dev {
-       struct s2255_channel    channel[MAX_CHANNELS];
-       struct v4l2_device      v4l2_dev;
+       struct s2255_vc         vc[MAX_CHANNELS];
+       struct v4l2_device      v4l2_dev;
        atomic_t                num_channels;
        int                     frames;
        struct mutex            lock;   /* channels[].vdev.lock */
+       struct mutex            cmdlock; /* protects cmdbuf */
        struct usb_device       *udev;
        struct usb_interface    *interface;
        u8                      read_endpoint;
@@ -272,10 +272,11 @@ struct s2255_dev {
        u32                     cc;     /* current channel */
        int                     frame_ready;
        int                     chn_ready;
-       spinlock_t              slock;
        /* dsp firmware version (f2255usb.bin) */
        int                     dsp_fw_ver;
        u16                     pid; /* product id */
+#define S2255_CMDBUF_SIZE 512
+       __le32                  *cmdbuf;
 };
 
 static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
@@ -292,19 +293,10 @@ struct s2255_fmt {
 /* buffer for one video frame */
 struct s2255_buffer {
        /* common v4l buffer stuff -- must be first */
-       struct videobuf_buffer vb;
-       const struct s2255_fmt *fmt;
+       struct vb2_buffer vb;
+       struct list_head list;
 };
 
-struct s2255_fh {
-       /* this must be the first field in this struct */
-       struct v4l2_fh          fh;
-       struct s2255_dev        *dev;
-       struct videobuf_queue   vb_vidq;
-       enum v4l2_buf_type      type;
-       struct s2255_channel    *channel;
-       int                     resources;
-};
 
 /* current cypress EEPROM firmware version */
 #define S2255_CUR_USB_FWVER    ((3 << 8) | 12)
@@ -352,15 +344,14 @@ struct s2255_fh {
 static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
 
 static int debug;
-static int *s2255_debug = &debug;
 
 static int s2255_start_readpipe(struct s2255_dev *dev);
 static void s2255_stop_readpipe(struct s2255_dev *dev);
-static int s2255_start_acquire(struct s2255_channel *channel);
-static int s2255_stop_acquire(struct s2255_channel *channel);
-static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
+static int s2255_start_acquire(struct s2255_vc *vc);
+static int s2255_stop_acquire(struct s2255_vc *vc);
+static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
                           int jpgsize);
-static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
+static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
 static int s2255_board_shutdown(struct s2255_dev *dev);
 static void s2255_fwload_start(struct s2255_dev *dev, int reset);
 static void s2255_destroy(struct s2255_dev *dev);
@@ -373,19 +364,11 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
 #define s2255_dev_err(dev, fmt, arg...)                                        \
                dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
 
-#define dprintk(level, fmt, arg...)                                    \
-       do {                                                            \
-               if (*s2255_debug >= (level)) {                          \
-                       printk(KERN_DEBUG S2255_DRIVER_NAME             \
-                               ": " fmt, ##arg);                       \
-               }                                                       \
-       } while (0)
+#define dprintk(dev, level, fmt, arg...) \
+       v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
 
 static struct usb_driver s2255_driver;
 
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16;    /* Video memory limit, in Mb */
-
 /* start video number */
 static int video_nr = -1;      /* /dev/videoN, -1 for autodetect */
 
@@ -394,8 +377,6 @@ static int jpeg_enable = 1;
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
 module_param(video_nr, int, 0644);
 MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
 module_param(jpeg_enable, int, 0644);
@@ -444,27 +425,27 @@ static const struct s2255_fmt formats[] = {
        }
 };
 
-static int norm_maxw(struct s2255_channel *channel)
+static int norm_maxw(struct s2255_vc *vc)
 {
-       return (channel->std & V4L2_STD_525_60) ?
+       return (vc->std & V4L2_STD_525_60) ?
            LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
 }
 
-static int norm_maxh(struct s2255_channel *channel)
+static int norm_maxh(struct s2255_vc *vc)
 {
-       return (channel->std & V4L2_STD_525_60) ?
+       return (vc->std & V4L2_STD_525_60) ?
            (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
 }
 
-static int norm_minw(struct s2255_channel *channel)
+static int norm_minw(struct s2255_vc *vc)
 {
-       return (channel->std & V4L2_STD_525_60) ?
+       return (vc->std & V4L2_STD_525_60) ?
            LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
 }
 
-static int norm_minh(struct s2255_channel *channel)
+static int norm_minh(struct s2255_vc *vc)
 {
-       return (channel->std & V4L2_STD_525_60) ?
+       return (vc->std & V4L2_STD_525_60) ?
            (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
 }
 
@@ -498,7 +479,7 @@ static void planar422p_to_yuv_packed(const unsigned char *in,
 static void s2255_reset_dsppower(struct s2255_dev *dev)
 {
        s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
-       msleep(10);
+       msleep(20);
        s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
        msleep(600);
        s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
@@ -510,9 +491,8 @@ static void s2255_reset_dsppower(struct s2255_dev *dev)
 static void s2255_timer(unsigned long user_data)
 {
        struct s2255_fw *data = (struct s2255_fw *)user_data;
-       dprintk(100, "%s\n", __func__);
        if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
-               printk(KERN_ERR "s2255: can't submit urb\n");
+               pr_err("s2255: can't submit urb\n");
                atomic_set(&data->fw_state, S2255_FW_FAILED);
                /* wake up anything waiting for the firmware */
                wake_up(&data->wait_fw);
@@ -532,7 +512,6 @@ static void s2255_fwchunk_complete(struct urb *urb)
        struct s2255_fw *data = urb->context;
        struct usb_device *udev = urb->dev;
        int len;
-       dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
        if (urb->status) {
                dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
                atomic_set(&data->fw_state, S2255_FW_FAILED);
@@ -559,9 +538,6 @@ static void s2255_fwchunk_complete(struct urb *urb)
                if (len < CHUNK_SIZE)
                        memset(data->pfw_data, 0, CHUNK_SIZE);
 
-               dprintk(100, "completed len %d, loaded %d \n", len,
-                       data->fw_loaded);
-
                memcpy(data->pfw_data,
                       (char *) data->fw->data + data->fw_loaded, len);
 
@@ -576,36 +552,32 @@ static void s2255_fwchunk_complete(struct urb *urb)
                        return;
                }
                data->fw_loaded += len;
-       } else {
+       } else
                atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
-               dprintk(100, "%s: firmware upload complete\n", __func__);
-       }
        return;
 
 }
 
-static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
+static int s2255_got_frame(struct s2255_vc *vc, int jpgsize)
 {
-       struct s2255_dmaqueue *dma_q = &channel->vidq;
        struct s2255_buffer *buf;
-       struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
+       struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
        unsigned long flags = 0;
        int rc = 0;
-       spin_lock_irqsave(&dev->slock, flags);
-       if (list_empty(&dma_q->active)) {
-               dprintk(1, "No active queue to serve\n");
+       spin_lock_irqsave(&vc->qlock, flags);
+       if (list_empty(&vc->buf_list)) {
+               dprintk(dev, 1, "No active queue to serve\n");
                rc = -1;
                goto unlock;
        }
-       buf = list_entry(dma_q->active.next,
-                        struct s2255_buffer, vb.queue);
-       list_del(&buf->vb.queue);
-       v4l2_get_timestamp(&buf->vb.ts);
-       s2255_fillbuff(channel, buf, jpgsize);
-       wake_up(&buf->vb.done);
-       dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
+       buf = list_entry(vc->buf_list.next,
+                        struct s2255_buffer, list);
+       list_del(&buf->list);
+       v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+       s2255_fillbuff(vc, buf, jpgsize);
+       dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
 unlock:
-       spin_unlock_irqrestore(&dev->slock, flags);
+       spin_unlock_irqrestore(&vc->qlock, flags);
        return rc;
 }
 
@@ -615,9 +587,9 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)
        for (i = 0; i < ARRAY_SIZE(formats); i++) {
                if (-1 == formats[i].fourcc)
                        continue;
-       if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
-                            (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
-           continue;
+               if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
+                                    (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
+                       continue;
                if (formats[i].fourcc == fourcc)
                        return formats + i;
        }
@@ -632,56 +604,56 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)
  *                  http://v4l.videotechnology.com/
  *
  */
-static void s2255_fillbuff(struct s2255_channel *channel,
+static void s2255_fillbuff(struct s2255_vc *vc,
                           struct s2255_buffer *buf, int jpgsize)
 {
        int pos = 0;
        const char *tmpbuf;
-       char *vbuf = videobuf_to_vmalloc(&buf->vb);
+       char *vbuf = vb2_plane_vaddr(&buf->vb, 0);
        unsigned long last_frame;
+       struct s2255_dev *dev = vc->dev;
 
        if (!vbuf)
                return;
-       last_frame = channel->last_frame;
+       last_frame = vc->last_frame;
        if (last_frame != -1) {
                tmpbuf =
-                   (const char *)channel->buffer.frame[last_frame].lpvbits;
-               switch (buf->fmt->fourcc) {
+                   (const char *)vc->buffer.frame[last_frame].lpvbits;
+               switch (vc->fmt->fourcc) {
                case V4L2_PIX_FMT_YUYV:
                case V4L2_PIX_FMT_UYVY:
                        planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
-                                                vbuf, buf->vb.width,
-                                                buf->vb.height,
-                                                buf->fmt->fourcc);
+                                                vbuf, vc->width,
+                                                vc->height,
+                                                vc->fmt->fourcc);
                        break;
                case V4L2_PIX_FMT_GREY:
-                       memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
+                       memcpy(vbuf, tmpbuf, vc->width * vc->height);
                        break;
                case V4L2_PIX_FMT_JPEG:
                case V4L2_PIX_FMT_MJPEG:
-                       buf->vb.size = jpgsize;
-                       memcpy(vbuf, tmpbuf, buf->vb.size);
+                       buf->vb.v4l2_buf.length = jpgsize;
+                       memcpy(vbuf, tmpbuf, jpgsize);
                        break;
                case V4L2_PIX_FMT_YUV422P:
                        memcpy(vbuf, tmpbuf,
-                              buf->vb.width * buf->vb.height * 2);
+                              vc->width * vc->height * 2);
                        break;
                default:
-                       printk(KERN_DEBUG "s2255: unknown format?\n");
+                       pr_info("s2255: unknown format?\n");
                }
-               channel->last_frame = -1;
+               vc->last_frame = -1;
        } else {
-               printk(KERN_ERR "s2255: =======no frame\n");
+               pr_err("s2255: =======no frame\n");
                return;
-
        }
-       dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
+       dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n",
                (unsigned long)vbuf, pos);
        /* tell v4l buffer was filled */
-
-       buf->vb.field_count = channel->frame_count * 2;
-       v4l2_get_timestamp(&buf->vb.ts);
-       buf->vb.state = VIDEOBUF_DONE;
+       buf->vb.v4l2_buf.field = vc->field;
+       buf->vb.v4l2_buf.sequence = vc->frame_count;
+       v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+       vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
 }
 
 
@@ -689,144 +661,82 @@ static void s2255_fillbuff(struct s2255_channel *channel,
    Videobuf operations
    ------------------------------------------------------------------*/
 
-static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
-                       unsigned int *size)
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                      unsigned int *nbuffers, unsigned int *nplanes,
+                      unsigned int sizes[], void *alloc_ctxs[])
 {
-       struct s2255_fh *fh = vq->priv_data;
-       struct s2255_channel *channel = fh->channel;
-       *size = channel->width * channel->height * (channel->fmt->depth >> 3);
-
-       if (0 == *count)
-               *count = S2255_DEF_BUFS;
-
-       if (*size * *count > vid_limit * 1024 * 1024)
-               *count = (vid_limit * 1024 * 1024) / *size;
-
+       struct s2255_vc *vc = vb2_get_drv_priv(vq);
+       if (*nbuffers < S2255_MIN_BUFS)
+               *nbuffers = S2255_MIN_BUFS;
+       *nplanes = 1;
+       sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
        return 0;
 }
 
-static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
-{
-       dprintk(4, "%s\n", __func__);
-
-       videobuf_vmalloc_free(&buf->vb);
-       buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
-                         enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb)
 {
-       struct s2255_fh *fh = vq->priv_data;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
        struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
-       int rc;
-       int w = channel->width;
-       int h = channel->height;
-       dprintk(4, "%s, field=%d\n", __func__, field);
-       if (channel->fmt == NULL)
+       int w = vc->width;
+       int h = vc->height;
+       unsigned long size;
+
+       dprintk(vc->dev, 4, "%s\n", __func__);
+       if (vc->fmt == NULL)
                return -EINVAL;
 
-       if ((w < norm_minw(channel)) ||
-           (w > norm_maxw(channel)) ||
-           (h < norm_minh(channel)) ||
-           (h > norm_maxh(channel))) {
-               dprintk(4, "invalid buffer prepare\n");
+       if ((w < norm_minw(vc)) ||
+           (w > norm_maxw(vc)) ||
+           (h < norm_minh(vc)) ||
+           (h > norm_maxh(vc))) {
+               dprintk(vc->dev, 4, "invalid buffer prepare\n");
                return -EINVAL;
        }
-       buf->vb.size = w * h * (channel->fmt->depth >> 3);
-       if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
-               dprintk(4, "invalid buffer prepare\n");
+       size = w * h * (vc->fmt->depth >> 3);
+       if (vb2_plane_size(vb, 0) < size) {
+               dprintk(vc->dev, 4, "invalid buffer prepare\n");
                return -EINVAL;
        }
 
-       buf->fmt = channel->fmt;
-       buf->vb.width = w;
-       buf->vb.height = h;
-       buf->vb.field = field;
-
-       if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-               rc = videobuf_iolock(vq, &buf->vb, NULL);
-               if (rc < 0)
-                       goto fail;
-       }
-
-       buf->vb.state = VIDEOBUF_PREPARED;
+       vb2_set_plane_payload(&buf->vb, 0, size);
        return 0;
-fail:
-       free_buffer(vq, buf);
-       return rc;
 }
 
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+static void buffer_queue(struct vb2_buffer *vb)
 {
        struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
-       struct s2255_fh *fh = vq->priv_data;
-       struct s2255_channel *channel = fh->channel;
-       struct s2255_dmaqueue *vidq = &channel->vidq;
-       dprintk(1, "%s\n", __func__);
-       buf->vb.state = VIDEOBUF_QUEUED;
-       list_add_tail(&buf->vb.queue, &vidq->active);
+       struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
+       unsigned long flags = 0;
+       dprintk(vc->dev, 1, "%s\n", __func__);
+       spin_lock_irqsave(&vc->qlock, flags);
+       list_add_tail(&buf->list, &vc->buf_list);
+       spin_unlock_irqrestore(&vc->qlock, flags);
 }
 
-static void buffer_release(struct videobuf_queue *vq,
-                          struct videobuf_buffer *vb)
-{
-       struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
-       struct s2255_fh *fh = vq->priv_data;
-       dprintk(4, "%s %d\n", __func__, fh->channel->idx);
-       free_buffer(vq, buf);
-}
+static int start_streaming(struct vb2_queue *vq, unsigned int count);
+static int stop_streaming(struct vb2_queue *vq);
 
-static struct videobuf_queue_ops s2255_video_qops = {
-       .buf_setup = buffer_setup,
+static struct vb2_ops s2255_video_qops = {
+       .queue_setup = queue_setup,
        .buf_prepare = buffer_prepare,
        .buf_queue = buffer_queue,
-       .buf_release = buffer_release,
+       .start_streaming = start_streaming,
+       .stop_streaming = stop_streaming,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
 };
 
-
-static int res_get(struct s2255_fh *fh)
-{
-       struct s2255_channel *channel = fh->channel;
-       /* is it free? */
-       if (channel->resources)
-               return 0; /* no, someone else uses it */
-       /* it's free, grab it */
-       channel->resources = 1;
-       fh->resources = 1;
-       dprintk(1, "s2255: res: get\n");
-       return 1;
-}
-
-static int res_locked(struct s2255_fh *fh)
-{
-       return fh->channel->resources;
-}
-
-static int res_check(struct s2255_fh *fh)
-{
-       return fh->resources;
-}
-
-
-static void res_free(struct s2255_fh *fh)
-{
-       struct s2255_channel *channel = fh->channel;
-       channel->resources = 0;
-       fh->resources = 0;
-       dprintk(1, "res: put\n");
-}
-
 static int vidioc_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
-       struct s2255_fh *fh = file->private_data;
-       struct s2255_dev *dev = fh->dev;
+       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));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
-       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+               V4L2_CAP_READWRITE;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
        return 0;
 }
@@ -841,7 +751,6 @@ 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;
-       dprintk(4, "name %s\n", formats[index].name);
        strlcpy(f->description, formats[index].name, sizeof(f->description));
        f->pixelformat = formats[index].fourcc;
        return 0;
@@ -850,19 +759,18 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
                            struct v4l2_format *f)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
-       int is_ntsc = channel->std & V4L2_STD_525_60;
+       struct s2255_vc *vc = video_drvdata(file);
+       int is_ntsc = vc->std & V4L2_STD_525_60;
 
-       f->fmt.pix.width = channel->width;
-       f->fmt.pix.height = channel->height;
+       f->fmt.pix.width = vc->width;
+       f->fmt.pix.height = vc->height;
        if (f->fmt.pix.height >=
            (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
                f->fmt.pix.field = V4L2_FIELD_INTERLACED;
        else
                f->fmt.pix.field = V4L2_FIELD_TOP;
-       f->fmt.pix.pixelformat = channel->fmt->fourcc;
-       f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
+       f->fmt.pix.pixelformat = vc->fmt->fourcc;
+       f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
        f->fmt.pix.priv = 0;
@@ -874,9 +782,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 {
        const struct s2255_fmt *fmt;
        enum v4l2_field field;
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
-       int is_ntsc = channel->std & V4L2_STD_525_60;
+       struct s2255_vc *vc = video_drvdata(file);
+       int is_ntsc = vc->std & V4L2_STD_525_60;
 
        fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 
@@ -885,7 +792,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 
        field = f->fmt.pix.field;
 
-       dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
+       dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
                __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
        if (is_ntsc) {
                /* NTSC */
@@ -927,7 +834,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
        f->fmt.pix.priv = 0;
-       dprintk(50, "%s: set width %d height %d field %d\n", __func__,
+       dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
                f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
        return 0;
 }
@@ -935,14 +842,13 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
                            struct v4l2_format *f)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
        const struct s2255_fmt *fmt;
-       struct videobuf_queue *q = &fh->vb_vidq;
+       struct vb2_queue *q = &vc->vb_vidq;
        struct s2255_mode mode;
        int ret;
 
-       ret = vidioc_try_fmt_vid_cap(file, fh, f);
+       ret = vidioc_try_fmt_vid_cap(file, vc, f);
 
        if (ret < 0)
                return ret;
@@ -952,28 +858,19 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        if (fmt == NULL)
                return -EINVAL;
 
-       mutex_lock(&q->vb_lock);
-
-       if (videobuf_queue_is_busy(&fh->vb_vidq)) {
-               dprintk(1, "queue busy\n");
-               ret = -EBUSY;
-               goto out_s_fmt;
+       if (vb2_is_busy(q)) {
+               dprintk(vc->dev, 1, "queue busy\n");
+               return -EBUSY;
        }
 
-       if (res_locked(fh)) {
-               dprintk(1, "%s: channel busy\n", __func__);
-               ret = -EBUSY;
-               goto out_s_fmt;
-       }
-       mode = channel->mode;
-       channel->fmt = fmt;
-       channel->width = f->fmt.pix.width;
-       channel->height = f->fmt.pix.height;
-       fh->vb_vidq.field = f->fmt.pix.field;
-       fh->type = f->type;
-       if (channel->width > norm_minw(channel)) {
-               if (channel->height > norm_minh(channel)) {
-                       if (channel->cap_parm.capturemode &
+       mode = vc->mode;
+       vc->fmt = fmt;
+       vc->width = f->fmt.pix.width;
+       vc->height = f->fmt.pix.height;
+       vc->field = f->fmt.pix.field;
+       if (vc->width > norm_minw(vc)) {
+               if (vc->height > norm_minh(vc)) {
+                       if (vc->cap_parm.capturemode &
                            V4L2_MODE_HIGHQUALITY)
                                mode.scale = SCALE_4CIFSI;
                        else
@@ -985,7 +882,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
                mode.scale = SCALE_1CIFS;
        }
        /* color mode */
-       switch (channel->fmt->fourcc) {
+       switch (vc->fmt->fourcc) {
        case V4L2_PIX_FMT_GREY:
                mode.color &= ~MASK_COLOR;
                mode.color |= COLOR_Y8;
@@ -994,7 +891,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        case V4L2_PIX_FMT_MJPEG:
                mode.color &= ~MASK_COLOR;
                mode.color |= COLOR_JPG;
-               mode.color |= (channel->jpegqual << 8);
+               mode.color |= (vc->jpegqual << 8);
                break;
        case V4L2_PIX_FMT_YUV422P:
                mode.color &= ~MASK_COLOR;
@@ -1007,52 +904,17 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
                mode.color |= COLOR_YUVPK;
                break;
        }
-       if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
+       if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
                mode.restart = 1;
-       else if (mode.scale != channel->mode.scale)
+       else if (mode.scale != vc->mode.scale)
                mode.restart = 1;
-       else if (mode.format != channel->mode.format)
+       else if (mode.format != vc->mode.format)
                mode.restart = 1;
-       channel->mode = mode;
-       (void) s2255_set_mode(channel, &mode);
-       ret = 0;
-out_s_fmt:
-       mutex_unlock(&q->vb_lock);
-       return ret;
-}
-
-static int vidioc_reqbufs(struct file *file, void *priv,
-                         struct v4l2_requestbuffers *p)
-{
-       int rc;
-       struct s2255_fh *fh = priv;
-       rc = videobuf_reqbufs(&fh->vb_vidq, p);
-       return rc;
-}
-
-static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-       int rc;
-       struct s2255_fh *fh = priv;
-       rc = videobuf_querybuf(&fh->vb_vidq, p);
-       return rc;
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-       int rc;
-       struct s2255_fh *fh = priv;
-       rc = videobuf_qbuf(&fh->vb_vidq, p);
-       return rc;
+       vc->mode = mode;
+       (void) s2255_set_mode(vc, &mode);
+       return 0;
 }
 
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-       int rc;
-       struct s2255_fh *fh = priv;
-       rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
-       return rc;
-}
 
 /* write to the configuration pipe, synchronously */
 static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
@@ -1150,201 +1012,166 @@ static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
  * When the restart parameter is set, we sleep for ONE frame to allow the
  * DSP time to get the new frame
  */
-static int s2255_set_mode(struct s2255_channel *channel,
+static int s2255_set_mode(struct s2255_vc *vc,
                          struct s2255_mode *mode)
 {
        int res;
-       __le32 *buffer;
        unsigned long chn_rev;
-       struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
+       struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
        int i;
+       __le32 *buffer = dev->cmdbuf;
 
-       chn_rev = G_chnmap[channel->idx];
-       dprintk(3, "%s channel: %d\n", __func__, channel->idx);
+       mutex_lock(&dev->cmdlock);
+       chn_rev = G_chnmap[vc->idx];
+       dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
        /* if JPEG, set the quality */
        if ((mode->color & MASK_COLOR) == COLOR_JPG) {
                mode->color &= ~MASK_COLOR;
                mode->color |= COLOR_JPG;
                mode->color &= ~MASK_JPG_QUALITY;
-               mode->color |= (channel->jpegqual << 8);
+               mode->color |= (vc->jpegqual << 8);
        }
        /* save the mode */
-       channel->mode = *mode;
-       channel->req_image_size = get_transfer_size(mode);
-       dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
-       buffer = kzalloc(512, GFP_KERNEL);
-       if (buffer == NULL) {
-               dev_err(&dev->udev->dev, "out of mem\n");
-               return -ENOMEM;
-       }
+       vc->mode = *mode;
+       vc->req_image_size = get_transfer_size(mode);
+       dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
        /* set the mode */
        buffer[0] = IN_DATA_TOKEN;
        buffer[1] = (__le32) cpu_to_le32(chn_rev);
        buffer[2] = CMD_SET_MODE;
        for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
-               buffer[3 + i] = cpu_to_le32(((u32 *)&channel->mode)[i]);
-       channel->setmode_ready = 0;
+               buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
+       vc->setmode_ready = 0;
        res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
        if (debug)
                s2255_print_cfg(dev, mode);
-       kfree(buffer);
        /* wait at least 3 frames before continuing */
        if (mode->restart) {
-               wait_event_timeout(channel->wait_setmode,
-                                  (channel->setmode_ready != 0),
+               wait_event_timeout(vc->wait_setmode,
+                                  (vc->setmode_ready != 0),
                                   msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
-               if (channel->setmode_ready != 1) {
-                       printk(KERN_DEBUG "s2255: no set mode response\n");
+               if (vc->setmode_ready != 1) {
+                       dprintk(dev, 0, "s2255: no set mode response\n");
                        res = -EFAULT;
                }
        }
        /* clear the restart flag */
-       channel->mode.restart = 0;
-       dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
+       vc->mode.restart = 0;
+       dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
+       mutex_unlock(&dev->cmdlock);
        return res;
 }
 
-static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
+static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
 {
        int res;
-       __le32 *buffer;
        u32 chn_rev;
-       struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
-       chn_rev = G_chnmap[channel->idx];
-       dprintk(4, "%s chan %d\n", __func__, channel->idx);
-       buffer = kzalloc(512, GFP_KERNEL);
-       if (buffer == NULL) {
-               dev_err(&dev->udev->dev, "out of mem\n");
-               return -ENOMEM;
-       }
+       struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
+       __le32 *buffer = dev->cmdbuf;
+
+       mutex_lock(&dev->cmdlock);
+       chn_rev = G_chnmap[vc->idx];
+       dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
        /* form the get vid status command */
        buffer[0] = IN_DATA_TOKEN;
        buffer[1] = (__le32) cpu_to_le32(chn_rev);
        buffer[2] = CMD_STATUS;
        *pstatus = 0;
-       channel->vidstatus_ready = 0;
+       vc->vidstatus_ready = 0;
        res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
-       kfree(buffer);
-       wait_event_timeout(channel->wait_vidstatus,
-                          (channel->vidstatus_ready != 0),
+       wait_event_timeout(vc->wait_vidstatus,
+                          (vc->vidstatus_ready != 0),
                           msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
-       if (channel->vidstatus_ready != 1) {
-               printk(KERN_DEBUG "s2255: no vidstatus response\n");
+       if (vc->vidstatus_ready != 1) {
+               dprintk(dev, 0, "s2255: no vidstatus response\n");
                res = -EFAULT;
        }
-       *pstatus = channel->vidstatus;
-       dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
+       *pstatus = vc->vidstatus;
+       dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
+       mutex_unlock(&dev->cmdlock);
        return res;
 }
 
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+static int start_streaming(struct vb2_queue *vq, unsigned int count)
 {
-       int res;
-       struct s2255_fh *fh = priv;
-       struct s2255_dev *dev = fh->dev;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = vb2_get_drv_priv(vq);
        int j;
-       dprintk(4, "%s\n", __func__);
-       if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               dev_err(&dev->udev->dev, "invalid fh type0\n");
-               return -EINVAL;
-       }
-       if (i != fh->type) {
-               dev_err(&dev->udev->dev, "invalid fh type1\n");
-               return -EINVAL;
-       }
 
-       if (!res_get(fh)) {
-               s2255_dev_err(&dev->udev->dev, "stream busy\n");
-               return -EBUSY;
-       }
-       channel->last_frame = -1;
-       channel->bad_payload = 0;
-       channel->cur_frame = 0;
-       channel->frame_count = 0;
+       vc->last_frame = -1;
+       vc->bad_payload = 0;
+       vc->cur_frame = 0;
+       vc->frame_count = 0;
        for (j = 0; j < SYS_FRAMES; j++) {
-               channel->buffer.frame[j].ulState = S2255_READ_IDLE;
-               channel->buffer.frame[j].cur_size = 0;
+               vc->buffer.frame[j].ulState = S2255_READ_IDLE;
+               vc->buffer.frame[j].cur_size = 0;
        }
-       res = videobuf_streamon(&fh->vb_vidq);
-       if (res == 0) {
-               s2255_start_acquire(channel);
-               channel->b_acquire = 1;
-       } else
-               res_free(fh);
-
-       return res;
+       return s2255_start_acquire(vc);
 }
 
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+/* abort streaming and wait for last buffer */
+static int stop_streaming(struct vb2_queue *vq)
 {
-       struct s2255_fh *fh = priv;
-       dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
-       if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               printk(KERN_ERR "invalid fh type0\n");
-               return -EINVAL;
+       struct s2255_vc *vc = vb2_get_drv_priv(vq);
+       struct s2255_buffer *buf, *node;
+       unsigned long flags;
+       (void) s2255_stop_acquire(vc);
+       spin_lock_irqsave(&vc->qlock, flags);
+       list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+               dprintk(vc->dev, 2, "[%p/%d] done\n",
+                       buf, buf->vb.v4l2_buf.index);
        }
-       if (i != fh->type) {
-               printk(KERN_ERR "invalid type i\n");
-               return -EINVAL;
-       }
-       s2255_stop_acquire(fh->channel);
-       videobuf_streamoff(&fh->vb_vidq);
-       res_free(fh);
+       spin_unlock_irqrestore(&vc->qlock, flags);
        return 0;
 }
 
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
 {
-       struct s2255_fh *fh = priv;
+       struct s2255_vc *vc = video_drvdata(file);
        struct s2255_mode mode;
-       struct videobuf_queue *q = &fh->vb_vidq;
-       struct s2255_channel *channel = fh->channel;
-       int ret = 0;
+       struct vb2_queue *q = &vc->vb_vidq;
 
-       mutex_lock(&q->vb_lock);
-       if (res_locked(fh)) {
-               dprintk(1, "can't change standard after started\n");
-               ret = -EBUSY;
-               goto out_s_std;
-       }
-       mode = fh->channel->mode;
+       /*
+        * Changing the standard implies a format change, which is not allowed
+        * while buffers for use with streaming have already been allocated.
+        */
+       if (vb2_is_busy(q))
+               return -EBUSY;
+
+       mode = vc->mode;
        if (i & V4L2_STD_525_60) {
-               dprintk(4, "%s 60 Hz\n", __func__);
+               dprintk(vc->dev, 4, "%s 60 Hz\n", __func__);
                /* if changing format, reset frame decimation/intervals */
                if (mode.format != FORMAT_NTSC) {
                        mode.restart = 1;
                        mode.format = FORMAT_NTSC;
                        mode.fdec = FDEC_1;
-                       channel->width = LINE_SZ_4CIFS_NTSC;
-                       channel->height = NUM_LINES_4CIFS_NTSC * 2;
+                       vc->width = LINE_SZ_4CIFS_NTSC;
+                       vc->height = NUM_LINES_4CIFS_NTSC * 2;
                }
        } else if (i & V4L2_STD_625_50) {
-               dprintk(4, "%s 50 Hz\n", __func__);
+               dprintk(vc->dev, 4, "%s 50 Hz\n", __func__);
                if (mode.format != FORMAT_PAL) {
                        mode.restart = 1;
                        mode.format = FORMAT_PAL;
                        mode.fdec = FDEC_1;
-                       channel->width = LINE_SZ_4CIFS_PAL;
-                       channel->height = NUM_LINES_4CIFS_PAL * 2;
+                       vc->width = LINE_SZ_4CIFS_PAL;
+                       vc->height = NUM_LINES_4CIFS_PAL * 2;
                }
-       } else {
-               ret = -EINVAL;
-               goto out_s_std;
-       }
-       fh->channel->std = i;
+       } else
+               return -EINVAL;
+       vc->std = i;
        if (mode.restart)
-               s2255_set_mode(fh->channel, &mode);
-out_s_std:
-       mutex_unlock(&q->vb_lock);
-       return ret;
+               s2255_set_mode(vc, &mode);
+       return 0;
 }
 
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
 {
-       struct s2255_fh *fh = priv;
+       struct s2255_vc *vc = video_drvdata(file);
 
-       *i = fh->channel->std;
+       *i = vc->std;
        return 0;
 }
 
@@ -1358,10 +1185,10 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
 static int vidioc_enum_input(struct file *file, void *priv,
                             struct v4l2_input *inp)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_dev *dev = fh->dev;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
+       struct s2255_dev *dev = vc->dev;
        u32 status = 0;
+
        if (inp->index != 0)
                return -EINVAL;
        inp->type = V4L2_INPUT_TYPE_CAMERA;
@@ -1369,8 +1196,9 @@ static int vidioc_enum_input(struct file *file, void *priv,
        inp->status = 0;
        if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
                int rc;
-               rc = s2255_cmd_status(fh->channel, &status);
-               dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
+               rc = s2255_cmd_status(vc, &status);
+               dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
+                       rc, status);
                if (rc == 0)
                        inp->status =  (status & 0x01) ? 0
                                : V4L2_IN_ST_NO_SIGNAL;
@@ -1381,7 +1209,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
                strlcpy(inp->name, "Composite", sizeof(inp->name));
                break;
        case 0x2257:
-               strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
+               strlcpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
                        sizeof(inp->name));
                break;
        }
@@ -1402,13 +1230,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 
 static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-       struct s2255_channel *channel =
-               container_of(ctrl->handler, struct s2255_channel, hdl);
+       struct s2255_vc *vc =
+               container_of(ctrl->handler, struct s2255_vc, hdl);
        struct s2255_mode mode;
-
-       mode = channel->mode;
-       dprintk(4, "%s\n", __func__);
-
+       mode = vc->mode;
        /* update the mode to the corresponding value */
        switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
@@ -1428,7 +1253,7 @@ static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
                mode.color |= !ctrl->val << 16;
                break;
        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
-               channel->jpegqual = ctrl->val;
+               vc->jpegqual = ctrl->val;
                return 0;
        default:
                return -EINVAL;
@@ -1438,48 +1263,48 @@ static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
           some V4L programs restart stream unnecessarily
           after a s_crtl.
        */
-       s2255_set_mode(channel, &mode);
+       s2255_set_mode(vc, &mode);
        return 0;
 }
 
 static int vidioc_g_jpegcomp(struct file *file, void *priv,
                         struct v4l2_jpegcompression *jc)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
 
        memset(jc, 0, sizeof(*jc));
-       jc->quality = channel->jpegqual;
-       dprintk(2, "%s: quality %d\n", __func__, jc->quality);
+       jc->quality = vc->jpegqual;
+       dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
        return 0;
 }
 
 static int vidioc_s_jpegcomp(struct file *file, void *priv,
                         const struct v4l2_jpegcompression *jc)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
+
        if (jc->quality < 0 || jc->quality > 100)
                return -EINVAL;
-       v4l2_ctrl_s_ctrl(channel->jpegqual_ctrl, jc->quality);
-       dprintk(2, "%s: quality %d\n", __func__, jc->quality);
+       v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
+       dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
        return 0;
 }
 
 static int vidioc_g_parm(struct file *file, void *priv,
                         struct v4l2_streamparm *sp)
 {
-       struct s2255_fh *fh = priv;
        __u32 def_num, def_dem;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
+
        if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
        sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
-       sp->parm.capture.capturemode = channel->cap_parm.capturemode;
-       def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
-       def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
+       sp->parm.capture.capturemode = vc->cap_parm.capturemode;
+       sp->parm.capture.readbuffers = S2255_MIN_BUFS;
+       def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
+       def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
        sp->parm.capture.timeperframe.denominator = def_dem;
-       switch (channel->mode.fdec) {
+       switch (vc->mode.fdec) {
        default:
        case FDEC_1:
                sp->parm.capture.timeperframe.numerator = def_num;
@@ -1494,7 +1319,8 @@ static int vidioc_g_parm(struct file *file, void *priv,
                sp->parm.capture.timeperframe.numerator = def_num * 5;
                break;
        }
-       dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
+       dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
+               __func__,
                sp->parm.capture.capturemode,
                sp->parm.capture.timeperframe.numerator,
                sp->parm.capture.timeperframe.denominator);
@@ -1504,17 +1330,16 @@ static int vidioc_g_parm(struct file *file, void *priv,
 static int vidioc_s_parm(struct file *file, void *priv,
                         struct v4l2_streamparm *sp)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
        struct s2255_mode mode;
        int fdec = FDEC_1;
        __u32 def_num, def_dem;
        if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
-       mode = channel->mode;
+       mode = vc->mode;
        /* high quality capture mode requires a stream restart */
-       if (channel->cap_parm.capturemode
-           != sp->parm.capture.capturemode && res_locked(fh))
+       if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
+           && vb2_is_streaming(&vc->vb_vidq))
                return -EBUSY;
        def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
        def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
@@ -1534,8 +1359,9 @@ static int vidioc_s_parm(struct file *file, void *priv,
        }
        mode.fdec = fdec;
        sp->parm.capture.timeperframe.denominator = def_dem;
-       s2255_set_mode(channel, &mode);
-       dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
+       sp->parm.capture.readbuffers = S2255_MIN_BUFS;
+       s2255_set_mode(vc, &mode);
+       dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
                __func__,
                sp->parm.capture.capturemode,
                sp->parm.capture.timeperframe.numerator,
@@ -1558,9 +1384,8 @@ static const struct v4l2_frmsize_discrete pal_sizes[] = {
 static int vidioc_enum_framesizes(struct file *file, void *priv,
                            struct v4l2_frmsizeenum *fe)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
-       int is_ntsc = channel->std & V4L2_STD_525_60;
+       struct s2255_vc *vc = video_drvdata(file);
+       int is_ntsc = vc->std & V4L2_STD_525_60;
        const struct s2255_fmt *fmt;
 
        if (fe->index >= NUM_SIZE_ENUMS)
@@ -1577,11 +1402,10 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 static int vidioc_enum_frameintervals(struct file *file, void *priv,
                            struct v4l2_frmivalenum *fe)
 {
-       struct s2255_fh *fh = priv;
-       struct s2255_channel *channel = fh->channel;
+       struct s2255_vc *vc = video_drvdata(file);
        const struct s2255_fmt *fmt;
        const struct v4l2_frmsize_discrete *sizes;
-       int is_ntsc = channel->std & V4L2_STD_525_60;
+       int is_ntsc = vc->std & V4L2_STD_525_60;
 #define NUM_FRAME_ENUMS 4
        int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
        int i;
@@ -1604,21 +1428,24 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
        fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
        fe->discrete.denominator = is_ntsc ? 30000 : 25000;
        fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
-       dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
+       dprintk(vc->dev, 4, "%s discrete %d/%d\n", __func__,
+               fe->discrete.numerator,
                fe->discrete.denominator);
        return 0;
 }
 
-static int __s2255_open(struct file *file)
+static int s2255_open(struct file *file)
 {
-       struct video_device *vdev = video_devdata(file);
-       struct s2255_channel *channel = video_drvdata(file);
-       struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
-       struct s2255_fh *fh;
-       enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       struct s2255_vc *vc = video_drvdata(file);
+       struct s2255_dev *dev = vc->dev;
        int state;
-       dprintk(1, "s2255: open called (dev=%s)\n",
-               video_device_node_name(vdev));
+       int rc = 0;
+
+       rc = v4l2_fh_open(file);
+       if (rc != 0)
+               return rc;
+
+       dprintk(dev, 1, "s2255: %s\n", __func__);
        state = atomic_read(&dev->fw_data->fw_state);
        switch (state) {
        case S2255_FW_DISCONNECTING:
@@ -1640,7 +1467,7 @@ static int __s2255_open(struct file *file)
        case S2255_FW_LOADED_DSPWAIT:
                /* give S2255_LOAD_TIMEOUT time for firmware to load in case
                   driver loaded and then device immediately opened */
-               printk(KERN_INFO "%s waiting for firmware load\n", __func__);
+               pr_info("%s waiting for firmware load\n", __func__);
                wait_event_timeout(dev->fw_data->wait_fw,
                                   ((atomic_read(&dev->fw_data->fw_state)
                                     == S2255_FW_SUCCESS) ||
@@ -1659,16 +1486,15 @@ static int __s2255_open(struct file *file)
        case S2255_FW_SUCCESS:
                break;
        case S2255_FW_FAILED:
-               printk(KERN_INFO "2255 firmware load failed.\n");
+               pr_info("2255 firmware load failed.\n");
                return -ENODEV;
        case S2255_FW_DISCONNECTING:
-               printk(KERN_INFO "%s: disconnecting\n", __func__);
+               pr_info("%s: disconnecting\n", __func__);
                return -ENODEV;
        case S2255_FW_LOADED_DSPWAIT:
        case S2255_FW_NOTLOADED:
-               printk(KERN_INFO "%s: firmware not loaded yet"
-                      "please try again later\n",
-                      __func__);
+               pr_info("%s: firmware not loaded, please retry\n",
+                       __func__);
                /*
                 * Timeout on firmware load means device unusable.
                 * Set firmware failure state.
@@ -1678,71 +1504,21 @@ static int __s2255_open(struct file *file)
                           S2255_FW_FAILED);
                return -EAGAIN;
        default:
-               printk(KERN_INFO "%s: unknown state\n", __func__);
+               pr_info("%s: unknown state\n", __func__);
                return -EFAULT;
        }
-       /* allocate + initialize per filehandle data */
-       fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-       if (NULL == fh)
-               return -ENOMEM;
-       v4l2_fh_init(&fh->fh, vdev);
-       v4l2_fh_add(&fh->fh);
-       file->private_data = &fh->fh;
-       fh->dev = dev;
-       fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       fh->channel = channel;
-       if (!channel->configured) {
+       if (!vc->configured) {
                /* configure channel to default state */
-               channel->fmt = &formats[0];
-               s2255_set_mode(channel, &channel->mode);
-               channel->configured = 1;
-       }
-       dprintk(1, "%s: dev=%s type=%s\n", __func__,
-               video_device_node_name(vdev), v4l2_type_names[type]);
-       dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
-               (unsigned long)fh, (unsigned long)dev,
-               (unsigned long)&channel->vidq);
-       dprintk(4, "%s: list_empty active=%d\n", __func__,
-               list_empty(&channel->vidq.active));
-       videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
-                                   NULL, &dev->slock,
-                                   fh->type,
-                                   V4L2_FIELD_INTERLACED,
-                                   sizeof(struct s2255_buffer),
-                                   fh, vdev->lock);
+               vc->fmt = &formats[0];
+               s2255_set_mode(vc, &vc->mode);
+               vc->configured = 1;
+       }
        return 0;
 }
 
-static int s2255_open(struct file *file)
-{
-       struct video_device *vdev = video_devdata(file);
-       int ret;
-
-       if (mutex_lock_interruptible(vdev->lock))
-               return -ERESTARTSYS;
-       ret = __s2255_open(file);
-       mutex_unlock(vdev->lock);
-       return ret;
-}
-
-static unsigned int s2255_poll(struct file *file,
-                              struct poll_table_struct *wait)
-{
-       struct s2255_fh *fh = file->private_data;
-       struct s2255_dev *dev = fh->dev;
-       int rc = v4l2_ctrl_poll(file, wait);
-
-       dprintk(100, "%s\n", __func__);
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
-               return POLLERR;
-       mutex_lock(&dev->lock);
-       rc |= videobuf_poll_stream(file, &fh->vb_vidq, wait);
-       mutex_unlock(&dev->lock);
-       return rc;
-}
-
 static void s2255_destroy(struct s2255_dev *dev)
 {
+       dprintk(dev, 1, "%s", __func__);
        /* board shutdown stops the read pipe if it is running */
        s2255_board_shutdown(dev);
        /* make sure firmware still not trying to load */
@@ -1760,62 +1536,18 @@ static void s2255_destroy(struct s2255_dev *dev)
        mutex_destroy(&dev->lock);
        usb_put_dev(dev->udev);
        v4l2_device_unregister(&dev->v4l2_dev);
-       dprintk(1, "%s", __func__);
+       kfree(dev->cmdbuf);
        kfree(dev);
 }
 
-static int s2255_release(struct file *file)
-{
-       struct s2255_fh *fh = file->private_data;
-       struct s2255_dev *dev = fh->dev;
-       struct video_device *vdev = video_devdata(file);
-       struct s2255_channel *channel = fh->channel;
-       if (!dev)
-               return -ENODEV;
-       mutex_lock(&dev->lock);
-       /* turn off stream */
-       if (res_check(fh)) {
-               if (channel->b_acquire)
-                       s2255_stop_acquire(fh->channel);
-               videobuf_streamoff(&fh->vb_vidq);
-               res_free(fh);
-       }
-       videobuf_mmap_free(&fh->vb_vidq);
-       mutex_unlock(&dev->lock);
-       dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
-       v4l2_fh_del(&fh->fh);
-       v4l2_fh_exit(&fh->fh);
-       kfree(fh);
-       return 0;
-}
-
-static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
-{
-       struct s2255_fh *fh = file->private_data;
-       struct s2255_dev *dev;
-       int ret;
-
-       if (!fh)
-               return -ENODEV;
-       dev = fh->dev;
-       dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
-       if (mutex_lock_interruptible(&dev->lock))
-               return -ERESTARTSYS;
-       ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
-       mutex_unlock(&dev->lock);
-       dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
-               (unsigned long)vma->vm_start,
-               (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
-       return ret;
-}
-
 static const struct v4l2_file_operations s2255_fops_v4l = {
        .owner = THIS_MODULE,
        .open = s2255_open,
-       .release = s2255_release,
-       .poll = s2255_poll,
+       .release = vb2_fop_release,
+       .poll = vb2_fop_poll,
        .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
-       .mmap = s2255_mmap_v4l,
+       .mmap = vb2_fop_mmap,
+       .read = vb2_fop_read,
 };
 
 static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
@@ -1824,17 +1556,17 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
        .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
        .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
        .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
-       .vidioc_reqbufs = vidioc_reqbufs,
-       .vidioc_querybuf = vidioc_querybuf,
-       .vidioc_qbuf = vidioc_qbuf,
-       .vidioc_dqbuf = vidioc_dqbuf,
+       .vidioc_reqbufs = vb2_ioctl_reqbufs,
+       .vidioc_querybuf = vb2_ioctl_querybuf,
+       .vidioc_qbuf = vb2_ioctl_qbuf,
+       .vidioc_dqbuf = vb2_ioctl_dqbuf,
        .vidioc_s_std = vidioc_s_std,
        .vidioc_g_std = vidioc_g_std,
        .vidioc_enum_input = vidioc_enum_input,
        .vidioc_g_input = vidioc_g_input,
        .vidioc_s_input = vidioc_s_input,
-       .vidioc_streamon = vidioc_streamon,
-       .vidioc_streamoff = vidioc_streamoff,
+       .vidioc_streamon = vb2_ioctl_streamon,
+       .vidioc_streamoff = vb2_ioctl_streamoff,
        .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
        .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
        .vidioc_s_parm = vidioc_s_parm,
@@ -1849,13 +1581,14 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
 static void s2255_video_device_release(struct video_device *vdev)
 {
        struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
-       struct s2255_channel *channel =
-               container_of(vdev, struct s2255_channel, vdev);
+       struct s2255_vc *vc =
+               container_of(vdev, struct s2255_vc, vdev);
 
-       v4l2_ctrl_handler_free(&channel->hdl);
-       dprintk(4, "%s, chnls: %d\n", __func__,
+       dprintk(dev, 4, "%s, chnls: %d\n", __func__,
                atomic_read(&dev->num_channels));
 
+       v4l2_ctrl_handler_free(&vc->hdl);
+
        if (atomic_dec_and_test(&dev->num_channels))
                s2255_destroy(dev);
        return;
@@ -1888,52 +1621,70 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
        int ret;
        int i;
        int cur_nr = video_nr;
-       struct s2255_channel *channel;
+       struct s2255_vc *vc;
+       struct vb2_queue *q;
+
        ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
        if (ret)
                return ret;
        /* initialize all video 4 linux */
        /* register 4 video devices */
        for (i = 0; i < MAX_CHANNELS; i++) {
-               channel = &dev->channel[i];
-               INIT_LIST_HEAD(&channel->vidq.active);
+               vc = &dev->vc[i];
+               INIT_LIST_HEAD(&vc->buf_list);
 
-               v4l2_ctrl_handler_init(&channel->hdl, 6);
-               v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
+               v4l2_ctrl_handler_init(&vc->hdl, 6);
+               v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
                                V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
-               v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
+               v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
                                V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
-               v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
+               v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
                                V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
-               v4l2_ctrl_new_std(&channel->hdl, &s2255_ctrl_ops,
+               v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
                                V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
-               channel->jpegqual_ctrl = v4l2_ctrl_new_std(&channel->hdl,
+               vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
                                &s2255_ctrl_ops,
                                V4L2_CID_JPEG_COMPRESSION_QUALITY,
                                0, 100, 1, S2255_DEF_JPEG_QUAL);
                if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
-                   (dev->pid != 0x2257 || channel->idx <= 1))
-                       v4l2_ctrl_new_custom(&channel->hdl, &color_filter_ctrl, NULL);
-               if (channel->hdl.error) {
-                       ret = channel->hdl.error;
-                       v4l2_ctrl_handler_free(&channel->hdl);
+                   (dev->pid != 0x2257 || vc->idx <= 1))
+                       v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
+                                            NULL);
+               if (vc->hdl.error) {
+                       ret = vc->hdl.error;
+                       v4l2_ctrl_handler_free(&vc->hdl);
                        dev_err(&dev->udev->dev, "couldn't register control\n");
                        break;
                }
-               channel->vidq.dev = dev;
-               /* register 4 video devices */
-               channel->vdev = template;
-               channel->vdev.ctrl_handler = &channel->hdl;
-               channel->vdev.lock = &dev->lock;
-               channel->vdev.v4l2_dev = &dev->v4l2_dev;
-               set_bit(V4L2_FL_USE_FH_PRIO, &channel->vdev.flags);
-               video_set_drvdata(&channel->vdev, channel);
+               q = &vc->vb_vidq;
+               q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               q->io_modes = VB2_MMAP | VB2_READ | VB2_USERPTR;
+               q->drv_priv = vc;
+               q->lock = &vc->vb_lock;
+               q->buf_struct_size = sizeof(struct s2255_buffer);
+               q->mem_ops = &vb2_vmalloc_memops;
+               q->ops = &s2255_video_qops;
+               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+               ret = vb2_queue_init(q);
+               if (ret != 0) {
+                       dev_err(&dev->udev->dev,
+                               "%s vb2_queue_init 0x%x\n", __func__, ret);
+                       break;
+               }
+               /* register video devices */
+               vc->vdev = template;
+               vc->vdev.queue = q;
+               vc->vdev.ctrl_handler = &vc->hdl;
+               vc->vdev.lock = &dev->lock;
+               vc->vdev.v4l2_dev = &dev->v4l2_dev;
+               set_bit(V4L2_FL_USE_FH_PRIO, &vc->vdev.flags);
+               video_set_drvdata(&vc->vdev, vc);
                if (video_nr == -1)
-                       ret = video_register_device(&channel->vdev,
+                       ret = video_register_device(&vc->vdev,
                                                    VFL_TYPE_GRABBER,
                                                    video_nr);
                else
-                       ret = video_register_device(&channel->vdev,
+                       ret = video_register_device(&vc->vdev,
                                                    VFL_TYPE_GRABBER,
                                                    cur_nr + i);
 
@@ -1944,18 +1695,18 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
                }
                atomic_inc(&dev->num_channels);
                v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
-                         video_device_node_name(&channel->vdev));
+                         video_device_node_name(&vc->vdev));
 
        }
-       printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %s\n",
-              S2255_VERSION);
+       pr_info("Sensoray 2255 V4L driver Revision: %s\n",
+               S2255_VERSION);
        /* if no channels registered, return error and probe will fail*/
        if (atomic_read(&dev->num_channels) == 0) {
                v4l2_device_unregister(&dev->v4l2_dev);
                return ret;
        }
        if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
-               printk(KERN_WARNING "s2255: Not all channels available.\n");
+               pr_warn("s2255: Not all channels available.\n");
        return 0;
 }
 
@@ -1981,11 +1732,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
        s32 idx = -1;
        struct s2255_framei *frm;
        unsigned char *pdata;
-       struct s2255_channel *channel;
-       dprintk(100, "buffer to user\n");
-       channel = &dev->channel[dev->cc];
-       idx = channel->cur_frame;
-       frm = &channel->buffer.frame[idx];
+       struct s2255_vc *vc;
+       dprintk(dev, 100, "buffer to user\n");
+       vc = &dev->vc[dev->cc];
+       idx = vc->cur_frame;
+       frm = &vc->buffer.frame[idx];
        if (frm->ulState == S2255_READ_IDLE) {
                int jj;
                unsigned int cc;
@@ -1997,28 +1748,27 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
                for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
                        switch (*pdword) {
                        case S2255_MARKER_FRAME:
-                               dprintk(4, "found frame marker at offset:"
-                                       " %d [%x %x]\n", jj, pdata[0],
-                                       pdata[1]);
+                               dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
+                                       jj, pdata[0], pdata[1]);
                                offset = jj + PREFIX_SIZE;
                                bframe = 1;
                                cc = le32_to_cpu(pdword[1]);
                                if (cc >= MAX_CHANNELS) {
-                                       printk(KERN_ERR
-                                              "bad channel\n");
+                                       dprintk(dev, 0,
+                                               "bad channel\n");
                                        return -EINVAL;
                                }
                                /* reverse it */
                                dev->cc = G_chnmap[cc];
-                               channel = &dev->channel[dev->cc];
+                               vc = &dev->vc[dev->cc];
                                payload =  le32_to_cpu(pdword[3]);
-                               if (payload > channel->req_image_size) {
-                                       channel->bad_payload++;
+                               if (payload > vc->req_image_size) {
+                                       vc->bad_payload++;
                                        /* discard the bad frame */
                                        return -EINVAL;
                                }
-                               channel->pkt_size = payload;
-                               channel->jpg_size = le32_to_cpu(pdword[4]);
+                               vc->pkt_size = payload;
+                               vc->jpg_size = le32_to_cpu(pdword[4]);
                                break;
                        case S2255_MARKER_RESPONSE:
 
@@ -2029,34 +1779,34 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
                                cc = G_chnmap[le32_to_cpu(pdword[1])];
                                if (cc >= MAX_CHANNELS)
                                        break;
-                               channel = &dev->channel[cc];
+                               vc = &dev->vc[cc];
                                switch (pdword[2]) {
                                case S2255_RESPONSE_SETMODE:
                                        /* check if channel valid */
                                        /* set mode ready */
-                                       channel->setmode_ready = 1;
-                                       wake_up(&channel->wait_setmode);
-                                       dprintk(5, "setmode ready %d\n", cc);
+                                       vc->setmode_ready = 1;
+                                       wake_up(&vc->wait_setmode);
+                                       dprintk(dev, 5, "setmode rdy %d\n", cc);
                                        break;
                                case S2255_RESPONSE_FW:
                                        dev->chn_ready |= (1 << cc);
                                        if ((dev->chn_ready & 0x0f) != 0x0f)
                                                break;
                                        /* all channels ready */
-                                       printk(KERN_INFO "s2255: fw loaded\n");
+                                       pr_info("s2255: fw loaded\n");
                                        atomic_set(&dev->fw_data->fw_state,
                                                   S2255_FW_SUCCESS);
                                        wake_up(&dev->fw_data->wait_fw);
                                        break;
                                case S2255_RESPONSE_STATUS:
-                                       channel->vidstatus = le32_to_cpu(pdword[3]);
-                                       channel->vidstatus_ready = 1;
-                                       wake_up(&channel->wait_vidstatus);
-                                       dprintk(5, "got vidstatus %x chan %d\n",
+                                       vc->vidstatus = le32_to_cpu(pdword[3]);
+                                       vc->vidstatus_ready = 1;
+                                       wake_up(&vc->wait_vidstatus);
+                                       dprintk(dev, 5, "vstat %x chan %d\n",
                                                le32_to_cpu(pdword[3]), cc);
                                        break;
                                default:
-                                       printk(KERN_INFO "s2255 unknown resp\n");
+                                       pr_info("s2255 unknown resp\n");
                                }
                        default:
                                pdata++;
@@ -2068,11 +1818,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
                if (!bframe)
                        return -EINVAL;
        }
-       channel = &dev->channel[dev->cc];
-       idx = channel->cur_frame;
-       frm = &channel->buffer.frame[idx];
+       vc = &dev->vc[dev->cc];
+       idx = vc->cur_frame;
+       frm = &vc->buffer.frame[idx];
        /* search done.  now find out if should be acquiring on this channel */
-       if (!channel->b_acquire) {
+       if (!vb2_is_streaming(&vc->vb_vidq)) {
                /* we found a frame, but this channel is turned off */
                frm->ulState = S2255_READ_IDLE;
                return -EINVAL;
@@ -2088,7 +1838,7 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
 
 
        if (frm->lpvbits == NULL) {
-               dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
+               dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
                        frm, dev, dev->cc, idx);
                return -ENOMEM;
        }
@@ -2097,28 +1847,28 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
 
        copy_size = (pipe_info->cur_transfer_size - offset);
 
-       size = channel->pkt_size - PREFIX_SIZE;
+       size = vc->pkt_size - PREFIX_SIZE;
 
        /* sanity check on pdest */
-       if ((copy_size + frm->cur_size) < channel->req_image_size)
+       if ((copy_size + frm->cur_size) < vc->req_image_size)
                memcpy(pdest, psrc, copy_size);
 
        frm->cur_size += copy_size;
-       dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
+       dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
 
        if (frm->cur_size >= size) {
-               dprintk(2, "****************[%d]Buffer[%d]full*************\n",
+               dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
                        dev->cc, idx);
-               channel->last_frame = channel->cur_frame;
-               channel->cur_frame++;
+               vc->last_frame = vc->cur_frame;
+               vc->cur_frame++;
                /* end of system frame ring buffer, start at zero */
-               if ((channel->cur_frame == SYS_FRAMES) ||
-                   (channel->cur_frame == channel->buffer.dwFrames))
-                       channel->cur_frame = 0;
+               if ((vc->cur_frame == SYS_FRAMES) ||
+                   (vc->cur_frame == vc->buffer.dwFrames))
+                       vc->cur_frame = 0;
                /* frame ready */
-               if (channel->b_acquire)
-                       s2255_got_frame(channel, channel->jpg_size);
-               channel->frame_count++;
+               if (vb2_is_streaming(&vc->vb_vidq))
+                       s2255_got_frame(vc, vc->jpg_size);
+               vc->frame_count++;
                frm->ulState = S2255_READ_IDLE;
                frm->cur_size = 0;
 
@@ -2131,7 +1881,7 @@ static void s2255_read_video_callback(struct s2255_dev *dev,
                                      struct s2255_pipeinfo *pipe_info)
 {
        int res;
-       dprintk(50, "callback read video \n");
+       dprintk(dev, 50, "callback read video\n");
 
        if (dev->cc >= MAX_CHANNELS) {
                dev->cc = 0;
@@ -2141,9 +1891,9 @@ static void s2255_read_video_callback(struct s2255_dev *dev,
        /* otherwise copy to the system buffers */
        res = save_frame(dev, pipe_info);
        if (res != 0)
-               dprintk(4, "s2255: read callback failed\n");
+               dprintk(dev, 4, "s2255: read callback failed\n");
 
-       dprintk(50, "callback read video done\n");
+       dprintk(dev, 50, "callback read video done\n");
        return;
 }
 
@@ -2181,9 +1931,9 @@ static int s2255_get_fx2fw(struct s2255_dev *dev)
        ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
                               S2255_VR_IN);
        if (ret < 0)
-               dprintk(2, "get fw error: %x\n", ret);
+               dprintk(dev, 2, "get fw error: %x\n", ret);
        fw = transBuffer[0] + (transBuffer[1] << 8);
-       dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
+       dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
        return fw;
 }
 
@@ -2191,12 +1941,11 @@ static int s2255_get_fx2fw(struct s2255_dev *dev)
  * Create the system ring buffer to copy frames into from the
  * usb read pipe.
  */
-static int s2255_create_sys_buffers(struct s2255_channel *channel)
+static int s2255_create_sys_buffers(struct s2255_vc *vc)
 {
        unsigned long i;
        unsigned long reqsize;
-       dprintk(1, "create sys buffers\n");
-       channel->buffer.dwFrames = SYS_FRAMES;
+       vc->buffer.dwFrames = SYS_FRAMES;
        /* always allocate maximum size(PAL) for system buffers */
        reqsize = SYS_FRAMES_MAXSIZE;
 
@@ -2205,40 +1954,33 @@ static int s2255_create_sys_buffers(struct s2255_channel *channel)
 
        for (i = 0; i < SYS_FRAMES; i++) {
                /* allocate the frames */
-               channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
-               dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
-                       &channel->buffer.frame[i], channel->idx, i,
-                       channel->buffer.frame[i].lpvbits);
-               channel->buffer.frame[i].size = reqsize;
-               if (channel->buffer.frame[i].lpvbits == NULL) {
-                       printk(KERN_INFO "out of memory.  using less frames\n");
-                       channel->buffer.dwFrames = i;
+               vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
+               vc->buffer.frame[i].size = reqsize;
+               if (vc->buffer.frame[i].lpvbits == NULL) {
+                       pr_info("out of memory.  using less frames\n");
+                       vc->buffer.dwFrames = i;
                        break;
                }
        }
 
        /* make sure internal states are set */
        for (i = 0; i < SYS_FRAMES; i++) {
-               channel->buffer.frame[i].ulState = 0;
-               channel->buffer.frame[i].cur_size = 0;
+               vc->buffer.frame[i].ulState = 0;
+               vc->buffer.frame[i].cur_size = 0;
        }
 
-       channel->cur_frame = 0;
-       channel->last_frame = -1;
+       vc->cur_frame = 0;
+       vc->last_frame = -1;
        return 0;
 }
 
-static int s2255_release_sys_buffers(struct s2255_channel *channel)
+static int s2255_release_sys_buffers(struct s2255_vc *vc)
 {
        unsigned long i;
-       dprintk(1, "release sys buffers\n");
        for (i = 0; i < SYS_FRAMES; i++) {
-               if (channel->buffer.frame[i].lpvbits) {
-                       dprintk(1, "vfree %p\n",
-                               channel->buffer.frame[i].lpvbits);
-                       vfree(channel->buffer.frame[i].lpvbits);
-               }
-               channel->buffer.frame[i].lpvbits = NULL;
+               if (vc->buffer.frame[i].lpvbits)
+                       vfree(vc->buffer.frame[i].lpvbits);
+               vc->buffer.frame[i].lpvbits = NULL;
        }
        return 0;
 }
@@ -2249,7 +1991,7 @@ static int s2255_board_init(struct s2255_dev *dev)
        int fw_ver;
        int j;
        struct s2255_pipeinfo *pipe = &dev->pipe;
-       dprintk(4, "board init: %p", dev);
+       dprintk(dev, 4, "board init: %p", dev);
        memset(pipe, 0, sizeof(*pipe));
        pipe->dev = dev;
        pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
@@ -2258,54 +2000,53 @@ static int s2255_board_init(struct s2255_dev *dev)
        pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
                                        GFP_KERNEL);
        if (pipe->transfer_buffer == NULL) {
-               dprintk(1, "out of memory!\n");
+               dprintk(dev, 1, "out of memory!\n");
                return -ENOMEM;
        }
        /* query the firmware */
        fw_ver = s2255_get_fx2fw(dev);
 
-       printk(KERN_INFO "s2255: usb firmware version %d.%d\n",
-              (fw_ver >> 8) & 0xff,
-              fw_ver & 0xff);
+       pr_info("s2255: usb firmware version %d.%d\n",
+               (fw_ver >> 8) & 0xff,
+               fw_ver & 0xff);
 
        if (fw_ver < S2255_CUR_USB_FWVER)
-               printk(KERN_INFO "s2255: newer USB firmware available\n");
+               pr_info("s2255: newer USB firmware available\n");
 
        for (j = 0; j < MAX_CHANNELS; j++) {
-               struct s2255_channel *channel = &dev->channel[j];
-               channel->b_acquire = 0;
-               channel->mode = mode_def;
+               struct s2255_vc *vc = &dev->vc[j];
+               vc->mode = mode_def;
                if (dev->pid == 0x2257 && j > 1)
-                       channel->mode.color |= (1 << 16);
-               channel->jpegqual = S2255_DEF_JPEG_QUAL;
-               channel->width = LINE_SZ_4CIFS_NTSC;
-               channel->height = NUM_LINES_4CIFS_NTSC * 2;
-               channel->std = V4L2_STD_NTSC_M;
-               channel->fmt = &formats[0];
-               channel->mode.restart = 1;
-               channel->req_image_size = get_transfer_size(&mode_def);
-               channel->frame_count = 0;
+                       vc->mode.color |= (1 << 16);
+               vc->jpegqual = S2255_DEF_JPEG_QUAL;
+               vc->width = LINE_SZ_4CIFS_NTSC;
+               vc->height = NUM_LINES_4CIFS_NTSC * 2;
+               vc->std = V4L2_STD_NTSC_M;
+               vc->fmt = &formats[0];
+               vc->mode.restart = 1;
+               vc->req_image_size = get_transfer_size(&mode_def);
+               vc->frame_count = 0;
                /* create the system buffers */
-               s2255_create_sys_buffers(channel);
+               s2255_create_sys_buffers(vc);
        }
        /* start read pipe */
        s2255_start_readpipe(dev);
-       dprintk(1, "%s: success\n", __func__);
+       dprintk(dev, 1, "%s: success\n", __func__);
        return 0;
 }
 
 static int s2255_board_shutdown(struct s2255_dev *dev)
 {
        u32 i;
-       dprintk(1, "%s: dev: %p", __func__,  dev);
+       dprintk(dev, 1, "%s: dev: %p", __func__,  dev);
 
        for (i = 0; i < MAX_CHANNELS; i++) {
-               if (dev->channel[i].b_acquire)
-                       s2255_stop_acquire(&dev->channel[i]);
+               if (vb2_is_streaming(&dev->vc[i].vb_vidq))
+                       s2255_stop_acquire(&dev->vc[i]);
        }
        s2255_stop_readpipe(dev);
        for (i = 0; i < MAX_CHANNELS; i++)
-               s2255_release_sys_buffers(&dev->channel[i]);
+               s2255_release_sys_buffers(&dev->vc[i]);
        /* release transfer buffer */
        kfree(dev->pipe.transfer_buffer);
        return 0;
@@ -2318,13 +2059,10 @@ static void read_pipe_completion(struct urb *purb)
        int status;
        int pipe;
        pipe_info = purb->context;
-       dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
-               purb->status);
        if (pipe_info == NULL) {
                dev_err(&purb->dev->dev, "no context!\n");
                return;
        }
-
        dev = pipe_info->dev;
        if (dev == NULL) {
                dev_err(&purb->dev->dev, "no context!\n");
@@ -2333,13 +2071,13 @@ static void read_pipe_completion(struct urb *purb)
        status = purb->status;
        /* if shutting down, do not resubmit, exit immediately */
        if (status == -ESHUTDOWN) {
-               dprintk(2, "%s: err shutdown\n", __func__);
+               dprintk(dev, 2, "%s: err shutdown\n", __func__);
                pipe_info->err_count++;
                return;
        }
 
        if (pipe_info->state == 0) {
-               dprintk(2, "%s: exiting USB pipe", __func__);
+               dprintk(dev, 2, "%s: exiting USB pipe", __func__);
                return;
        }
 
@@ -2347,7 +2085,7 @@ static void read_pipe_completion(struct urb *purb)
                s2255_read_video_callback(dev, pipe_info);
        else {
                pipe_info->err_count++;
-               dprintk(1, "%s: failed URB %d\n", __func__, status);
+               dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
        }
 
        pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
@@ -2359,11 +2097,10 @@ static void read_pipe_completion(struct urb *purb)
                          read_pipe_completion, pipe_info);
 
        if (pipe_info->state != 0) {
-               if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
+               if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
                        dev_err(&dev->udev->dev, "error submitting urb\n");
-               }
        } else {
-               dprintk(2, "%s :complete state 0\n", __func__);
+               dprintk(dev, 2, "%s :complete state 0\n", __func__);
        }
        return;
 }
@@ -2374,7 +2111,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
        int retval;
        struct s2255_pipeinfo *pipe_info = &dev->pipe;
        pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
-       dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
+       dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
        pipe_info->state = 1;
        pipe_info->err_count = 0;
        pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -2391,70 +2128,64 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
                          read_pipe_completion, pipe_info);
        retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
        if (retval) {
-               printk(KERN_ERR "s2255: start read pipe failed\n");
+               pr_err("s2255: start read pipe failed\n");
                return retval;
        }
        return 0;
 }
 
 /* starts acquisition process */
-static int s2255_start_acquire(struct s2255_channel *channel)
+static int s2255_start_acquire(struct s2255_vc *vc)
 {
-       unsigned char *buffer;
        int res;
        unsigned long chn_rev;
        int j;
-       struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
-       chn_rev = G_chnmap[channel->idx];
-       buffer = kzalloc(512, GFP_KERNEL);
-       if (buffer == NULL) {
-               dev_err(&dev->udev->dev, "out of mem\n");
-               return -ENOMEM;
-       }
-
-       channel->last_frame = -1;
-       channel->bad_payload = 0;
-       channel->cur_frame = 0;
+       struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
+       __le32 *buffer = dev->cmdbuf;
+
+       mutex_lock(&dev->cmdlock);
+       chn_rev = G_chnmap[vc->idx];
+       vc->last_frame = -1;
+       vc->bad_payload = 0;
+       vc->cur_frame = 0;
        for (j = 0; j < SYS_FRAMES; j++) {
-               channel->buffer.frame[j].ulState = 0;
-               channel->buffer.frame[j].cur_size = 0;
+               vc->buffer.frame[j].ulState = 0;
+               vc->buffer.frame[j].cur_size = 0;
        }
 
        /* send the start command */
-       *(__le32 *) buffer = IN_DATA_TOKEN;
-       *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
-       *((__le32 *) buffer + 2) = CMD_START;
+       buffer[0] = IN_DATA_TOKEN;
+       buffer[1] = (__le32) cpu_to_le32(chn_rev);
+       buffer[2] = CMD_START;
        res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
        if (res != 0)
                dev_err(&dev->udev->dev, "CMD_START error\n");
 
-       dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
-       kfree(buffer);
-       return 0;
+       dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
+       mutex_unlock(&dev->cmdlock);
+       return res;
 }
 
-static int s2255_stop_acquire(struct s2255_channel *channel)
+static int s2255_stop_acquire(struct s2255_vc *vc)
 {
-       unsigned char *buffer;
        int res;
        unsigned long chn_rev;
-       struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
-       chn_rev = G_chnmap[channel->idx];
-       buffer = kzalloc(512, GFP_KERNEL);
-       if (buffer == NULL) {
-               dev_err(&dev->udev->dev, "out of mem\n");
-               return -ENOMEM;
-       }
+       struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
+       __le32 *buffer = dev->cmdbuf;
+
+       mutex_lock(&dev->cmdlock);
+       chn_rev = G_chnmap[vc->idx];
        /* send the stop command */
-       *(__le32 *) buffer = IN_DATA_TOKEN;
-       *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
-       *((__le32 *) buffer + 2) = CMD_STOP;
+       buffer[0] = IN_DATA_TOKEN;
+       buffer[1] = (__le32) cpu_to_le32(chn_rev);
+       buffer[2] = CMD_STOP;
+
        res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
        if (res != 0)
                dev_err(&dev->udev->dev, "CMD_STOP error\n");
-       kfree(buffer);
-       channel->b_acquire = 0;
-       dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
+
+       dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
+       mutex_unlock(&dev->cmdlock);
        return res;
 }
 
@@ -2469,7 +2200,7 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
                usb_free_urb(pipe->stream_urb);
                pipe->stream_urb = NULL;
        }
-       dprintk(4, "%s", __func__);
+       dprintk(dev, 4, "%s", __func__);
        return;
 }
 
@@ -2501,19 +2232,27 @@ static int s2255_probe(struct usb_interface *interface,
        int retval = -ENOMEM;
        __le32 *pdata;
        int fw_size;
-       dprintk(2, "%s\n", __func__);
+
        /* allocate memory for our device state and initialize it to zero */
        dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
        if (dev == NULL) {
                s2255_dev_err(&interface->dev, "out of memory\n");
                return -ENOMEM;
        }
+
+       dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
+       if (dev->cmdbuf == NULL) {
+               s2255_dev_err(&interface->dev, "out of memory\n");
+               return -ENOMEM;
+       }
+
        atomic_set(&dev->num_channels, 0);
        dev->pid = le16_to_cpu(id->idProduct);
        dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
        if (!dev->fw_data)
                goto errorFWDATA1;
        mutex_init(&dev->lock);
+       mutex_init(&dev->cmdlock);
        /* grab usb_device and save it */
        dev->udev = usb_get_dev(interface_to_usbdev(interface));
        if (dev->udev == NULL) {
@@ -2521,12 +2260,13 @@ static int s2255_probe(struct usb_interface *interface,
                retval = -ENODEV;
                goto errorUDEV;
        }
-       dprintk(1, "dev: %p, udev %p interface %p\n", dev,
-               dev->udev, interface);
+       dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
+               dev, dev->udev, interface);
        dev->interface = interface;
        /* set up the endpoint information  */
        iface_desc = interface->cur_altsetting;
-       dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
+       dev_dbg(&interface->dev, "num EP: %d\n",
+               iface_desc->desc.bNumEndpoints);
        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
                endpoint = &iface_desc->endpoint[i].desc;
                if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
@@ -2544,10 +2284,13 @@ static int s2255_probe(struct usb_interface *interface,
        dev->timer.data = (unsigned long)dev->fw_data;
        init_waitqueue_head(&dev->fw_data->wait_fw);
        for (i = 0; i < MAX_CHANNELS; i++) {
-               struct s2255_channel *channel = &dev->channel[i];
-               dev->channel[i].idx = i;
-               init_waitqueue_head(&channel->wait_setmode);
-               init_waitqueue_head(&channel->wait_vidstatus);
+               struct s2255_vc *vc = &dev->vc[i];
+               vc->idx = i;
+               vc->dev = dev;
+               init_waitqueue_head(&vc->wait_setmode);
+               init_waitqueue_head(&vc->wait_vidstatus);
+               spin_lock_init(&vc->qlock);
+               mutex_init(&vc->vb_lock);
        }
 
        dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -2564,7 +2307,7 @@ static int s2255_probe(struct usb_interface *interface,
        /* load the first chunk */
        if (request_firmware(&dev->fw_data->fw,
                             FIRMWARE_FILE_NAME, &dev->udev->dev)) {
-               printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
+               dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
                goto errorREQFW;
        }
        /* check the firmware is valid */
@@ -2572,28 +2315,27 @@ static int s2255_probe(struct usb_interface *interface,
        pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
 
        if (*pdata != S2255_FW_MARKER) {
-               printk(KERN_INFO "Firmware invalid.\n");
+               dev_err(&interface->dev, "Firmware invalid.\n");
                retval = -ENODEV;
                goto errorFWMARKER;
        } else {
                /* make sure firmware is the latest */
                __le32 *pRel;
                pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
-               printk(KERN_INFO "s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
+               pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
                dev->dsp_fw_ver = le32_to_cpu(*pRel);
                if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
-                       printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
+                       pr_info("s2255: f2255usb.bin out of date.\n");
                if (dev->pid == 0x2257 &&
                                dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
-                       printk(KERN_WARNING "s2255: 2257 requires firmware %d"
-                              " or above.\n", S2255_MIN_DSP_COLORFILTER);
+                       pr_warn("2257 needs firmware %d or above.\n",
+                               S2255_MIN_DSP_COLORFILTER);
        }
        usb_reset_device(dev->udev);
        /* load 2255 board specific */
        retval = s2255_board_init(dev);
        if (retval)
                goto errorBOARDINIT;
-       spin_lock_init(&dev->slock);
        s2255_fwload_start(dev, 0);
        /* loads v4l specific */
        retval = s2255_probe_v4l(dev);
@@ -2617,8 +2359,9 @@ errorUDEV:
        kfree(dev->fw_data);
        mutex_destroy(&dev->lock);
 errorFWDATA1:
+       kfree(dev->cmdbuf);
        kfree(dev);
-       printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
+       pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
        return retval;
 }
 
@@ -2635,15 +2378,15 @@ static void s2255_disconnect(struct usb_interface *interface)
        atomic_inc(&dev->num_channels);
        /* unregister each video device. */
        for (i = 0; i < channels; i++)
-               video_unregister_device(&dev->channel[i].vdev);
+               video_unregister_device(&dev->vc[i].vdev);
        /* wake up any of our timers */
        atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
        wake_up(&dev->fw_data->wait_fw);
        for (i = 0; i < MAX_CHANNELS; i++) {
-               dev->channel[i].setmode_ready = 1;
-               wake_up(&dev->channel[i].wait_setmode);
-               dev->channel[i].vidstatus_ready = 1;
-               wake_up(&dev->channel[i].wait_vidstatus);
+               dev->vc[i].setmode_ready = 1;
+               wake_up(&dev->vc[i].wait_setmode);
+               dev->vc[i].vidstatus_ready = 1;
+               wake_up(&dev->vc[i].wait_vidstatus);
        }
        if (atomic_dec_and_test(&dev->num_channels))
                s2255_destroy(dev);
index 05bd91a60c09fe91d535aad8323cf0a49b48fe16..1836a416d80646151e80c67d8896f96fa6fd1fe2 100644 (file)
@@ -653,6 +653,8 @@ static const struct usb_device_id smsusb_id_table[] = {
                .driver_info = SMS1XXX_BOARD_ZTE_DVB_DATA_CARD },
        { USB_DEVICE(0x19D2, 0x0078),
                .driver_info = SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD },
+       { USB_DEVICE(0x3275, 0x0080),
+               .driver_info = SMS1XXX_BOARD_SIANO_RIO },
        { } /* Terminating entry */
        };
 
index c45c9881bb5f4fdad89cf9ffe45c1c05cf8d946c..37bc00f418f1db47272238d90830ed2a7ac1f872 100644 (file)
@@ -641,7 +641,7 @@ int stk1160_vb2_setup(struct stk1160 *dev)
        q->buf_struct_size = sizeof(struct stk1160_buffer);
        q->ops = &stk1160_video_qops;
        q->mem_ops = &vb2_vmalloc_memops;
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        rc = vb2_queue_init(q);
        if (rc < 0)
index 3239cd62e4529e57d1af2fbf074fffd0539bc2d9..74e5697d8678b248f75b2ca1b6f09f2423144f64 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *
  *  Support for audio capture for tm5600/6000/6010
- *    (c) 2007-2008 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *    (c) 2007-2008 Mauro Carvalho Chehab
  *
  *  Based on cx88-alsa.c
  *
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s).");
  ****************************************************************************/
 
 MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},"
                        "{{Trident,tm6000},"
index 9fc1e940a82b6684e3a16192b0f5ffbcc7b89b00..095f5db1a790f90ddc1307e3aa5572e289ecfcbc 100644 (file)
@@ -32,7 +32,7 @@
 #include "xc5000.h"
 
 MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 
 MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
index 8a6bbf1d80e1a484956bf655c9a1df75752a3b63..d1af5438c16859ba29db75b91e83dc9cb89e180f 100644 (file)
@@ -422,7 +422,7 @@ int tm6000_ir_init(struct tm6000_core *dev)
        ir->rc = rc;
 
        /* input setup */
-       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
+       rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC);
        /* Neded, in order to support NEC remotes with 24 or 32 bits */
        rc->scanmask = 0xffff;
        rc->priv = ir;
index 5e28d6a2412f1fbe6121532ab08984460804ff64..93a4b2434b6eb8bd7f5bad852a353f0ddef10ebe 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
  *
- *  Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *  Copyright (C) 2007 Mauro Carvalho Chehab
  *
  *  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
index 28b872fa94e139d9ae23bd5b191cbf3ca8740f83..775316a88ea6953210befcabf71e4a005c67bc15 100644 (file)
@@ -1 +1,4 @@
+usbtv-y := usbtv-core.o \
+       usbtv-video.o
+
 obj-$(CONFIG_VIDEO_USBTV) += usbtv.o
diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c
new file mode 100644 (file)
index 0000000..2f87ddf
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Fushicai USBTV007 Video Grabber Driver
+ *
+ * Product web site:
+ * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
+ *
+ * Following LWN articles were very useful in construction of this driver:
+ * Video4Linux2 API series: http://lwn.net/Articles/203924/
+ * videobuf2 API explanation: http://lwn.net/Articles/447435/
+ * Thanks go to Jonathan Corbet for providing this quality documentation.
+ * He is awesome.
+ *
+ * Copyright (c) 2013 Lubomir Rintel
+ * All rights reserved.
+ * No physical hardware was harmed running Windows during the
+ * reverse-engineering activity
+ *
+ * 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. The name of the author 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").
+ */
+
+#include "usbtv.h"
+
+int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size)
+{
+       int ret;
+       int pipe = usb_rcvctrlpipe(usbtv->udev, 0);
+       int i;
+
+       for (i = 0; i < size; i++) {
+               u16 index = regs[i][0];
+               u16 value = regs[i][1];
+
+               ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
+                       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                       value, index, NULL, 0, 0);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int usbtv_probe(struct usb_interface *intf,
+       const struct usb_device_id *id)
+{
+       int ret;
+       int size;
+       struct device *dev = &intf->dev;
+       struct usbtv *usbtv;
+
+       /* Checks that the device is what we think it is. */
+       if (intf->num_altsetting != 2)
+               return -ENODEV;
+       if (intf->altsetting[1].desc.bNumEndpoints != 4)
+               return -ENODEV;
+
+       /* Packet size is split into 11 bits of base size and count of
+        * extra multiplies of it.*/
+       size = usb_endpoint_maxp(&intf->altsetting[1].endpoint[0].desc);
+       size = (size & 0x07ff) * (((size & 0x1800) >> 11) + 1);
+
+       /* Device structure */
+       usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
+       if (usbtv == NULL)
+               return -ENOMEM;
+       usbtv->dev = dev;
+       usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
+
+       usbtv->iso_size = size;
+
+       usb_set_intfdata(intf, usbtv);
+
+       ret = usbtv_video_init(usbtv);
+       if (ret < 0)
+               goto usbtv_video_fail;
+
+       /* for simplicity we exploit the v4l2_device reference counting */
+       v4l2_device_get(&usbtv->v4l2_dev);
+
+       dev_info(dev, "Fushicai USBTV007 Video Grabber\n");
+       return 0;
+
+usbtv_video_fail:
+       kfree(usbtv);
+
+       return ret;
+}
+
+static void usbtv_disconnect(struct usb_interface *intf)
+{
+       struct usbtv *usbtv = usb_get_intfdata(intf);
+       usb_set_intfdata(intf, NULL);
+
+       if (!usbtv)
+               return;
+
+       usbtv_video_free(usbtv);
+
+       usb_put_dev(usbtv->udev);
+       usbtv->udev = NULL;
+
+       /* the usbtv structure will be deallocated when v4l2 will be
+          done using it */
+       v4l2_device_put(&usbtv->v4l2_dev);
+}
+
+static struct usb_device_id usbtv_id_table[] = {
+       { USB_DEVICE(0x1b71, 0x3002) },
+       {}
+};
+MODULE_DEVICE_TABLE(usb, usbtv_id_table);
+
+MODULE_AUTHOR("Lubomir Rintel");
+MODULE_DESCRIPTION("Fushicai USBTV007 Video Grabber Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static struct usb_driver usbtv_usb_driver = {
+       .name = "usbtv",
+       .id_table = usbtv_id_table,
+       .probe = usbtv_probe,
+       .disconnect = usbtv_disconnect,
+};
+
+module_usb_driver(usbtv_usb_driver);
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
new file mode 100644 (file)
index 0000000..20365bd
--- /dev/null
@@ -0,0 +1,738 @@
+/*
+ * Fushicai USBTV007 Video Grabber Driver
+ *
+ * Product web site:
+ * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
+ *
+ * Following LWN articles were very useful in construction of this driver:
+ * Video4Linux2 API series: http://lwn.net/Articles/203924/
+ * videobuf2 API explanation: http://lwn.net/Articles/447435/
+ * Thanks go to Jonathan Corbet for providing this quality documentation.
+ * He is awesome.
+ *
+ * Copyright (c) 2013 Lubomir Rintel
+ * All rights reserved.
+ * No physical hardware was harmed running Windows during the
+ * reverse-engineering activity
+ *
+ * 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. The name of the author 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").
+ */
+
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+
+#include "usbtv.h"
+
+static struct usbtv_norm_params norm_params[] = {
+       {
+               .norm = V4L2_STD_525_60,
+               .cap_width = 720,
+               .cap_height = 480,
+       },
+       {
+               .norm = V4L2_STD_PAL,
+               .cap_width = 720,
+               .cap_height = 576,
+       }
+};
+
+static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm)
+{
+       int i, ret = 0;
+       struct usbtv_norm_params *params = NULL;
+
+       for (i = 0; i < ARRAY_SIZE(norm_params); i++) {
+               if (norm_params[i].norm & norm) {
+                       params = &norm_params[i];
+                       break;
+               }
+       }
+
+       if (params) {
+               usbtv->width = params->cap_width;
+               usbtv->height = params->cap_height;
+               usbtv->n_chunks = usbtv->width * usbtv->height
+                                               / 4 / USBTV_CHUNK;
+               usbtv->norm = params->norm;
+       } else
+               ret = -EINVAL;
+
+       return ret;
+}
+
+static int usbtv_select_input(struct usbtv *usbtv, int input)
+{
+       int ret;
+
+       static const u16 composite[][2] = {
+               { USBTV_BASE + 0x0105, 0x0060 },
+               { USBTV_BASE + 0x011f, 0x00f2 },
+               { USBTV_BASE + 0x0127, 0x0060 },
+               { USBTV_BASE + 0x00ae, 0x0010 },
+               { USBTV_BASE + 0x0284, 0x00aa },
+               { USBTV_BASE + 0x0239, 0x0060 },
+       };
+
+       static const u16 svideo[][2] = {
+               { USBTV_BASE + 0x0105, 0x0010 },
+               { USBTV_BASE + 0x011f, 0x00ff },
+               { USBTV_BASE + 0x0127, 0x0060 },
+               { USBTV_BASE + 0x00ae, 0x0030 },
+               { USBTV_BASE + 0x0284, 0x0088 },
+               { USBTV_BASE + 0x0239, 0x0060 },
+       };
+
+       switch (input) {
+       case USBTV_COMPOSITE_INPUT:
+               ret = usbtv_set_regs(usbtv, composite, ARRAY_SIZE(composite));
+               break;
+       case USBTV_SVIDEO_INPUT:
+               ret = usbtv_set_regs(usbtv, svideo, ARRAY_SIZE(svideo));
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       if (!ret)
+               usbtv->input = input;
+
+       return ret;
+}
+
+static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm)
+{
+       int ret;
+       static const u16 pal[][2] = {
+               { USBTV_BASE + 0x001a, 0x0068 },
+               { USBTV_BASE + 0x010e, 0x0072 },
+               { USBTV_BASE + 0x010f, 0x00a2 },
+               { USBTV_BASE + 0x0112, 0x00b0 },
+               { USBTV_BASE + 0x0117, 0x0001 },
+               { USBTV_BASE + 0x0118, 0x002c },
+               { USBTV_BASE + 0x012d, 0x0010 },
+               { USBTV_BASE + 0x012f, 0x0020 },
+               { USBTV_BASE + 0x024f, 0x0002 },
+               { USBTV_BASE + 0x0254, 0x0059 },
+               { USBTV_BASE + 0x025a, 0x0016 },
+               { USBTV_BASE + 0x025b, 0x0035 },
+               { USBTV_BASE + 0x0263, 0x0017 },
+               { USBTV_BASE + 0x0266, 0x0016 },
+               { USBTV_BASE + 0x0267, 0x0036 }
+       };
+
+       static const u16 ntsc[][2] = {
+               { USBTV_BASE + 0x001a, 0x0079 },
+               { USBTV_BASE + 0x010e, 0x0068 },
+               { USBTV_BASE + 0x010f, 0x009c },
+               { USBTV_BASE + 0x0112, 0x00f0 },
+               { USBTV_BASE + 0x0117, 0x0000 },
+               { USBTV_BASE + 0x0118, 0x00fc },
+               { USBTV_BASE + 0x012d, 0x0004 },
+               { USBTV_BASE + 0x012f, 0x0008 },
+               { USBTV_BASE + 0x024f, 0x0001 },
+               { USBTV_BASE + 0x0254, 0x005f },
+               { USBTV_BASE + 0x025a, 0x0012 },
+               { USBTV_BASE + 0x025b, 0x0001 },
+               { USBTV_BASE + 0x0263, 0x001c },
+               { USBTV_BASE + 0x0266, 0x0011 },
+               { USBTV_BASE + 0x0267, 0x0005 }
+       };
+
+       ret = usbtv_configure_for_norm(usbtv, norm);
+
+       if (!ret) {
+               if (norm & V4L2_STD_525_60)
+                       ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc));
+               else if (norm & V4L2_STD_PAL)
+                       ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal));
+       }
+
+       return ret;
+}
+
+static int usbtv_setup_capture(struct usbtv *usbtv)
+{
+       int ret;
+       static const u16 setup[][2] = {
+               /* These seem to enable the device. */
+               { USBTV_BASE + 0x0008, 0x0001 },
+               { USBTV_BASE + 0x01d0, 0x00ff },
+               { USBTV_BASE + 0x01d9, 0x0002 },
+
+               /* These seem to influence color parameters, such as
+                * brightness, etc. */
+               { USBTV_BASE + 0x0239, 0x0040 },
+               { USBTV_BASE + 0x0240, 0x0000 },
+               { USBTV_BASE + 0x0241, 0x0000 },
+               { USBTV_BASE + 0x0242, 0x0002 },
+               { USBTV_BASE + 0x0243, 0x0080 },
+               { USBTV_BASE + 0x0244, 0x0012 },
+               { USBTV_BASE + 0x0245, 0x0090 },
+               { USBTV_BASE + 0x0246, 0x0000 },
+
+               { USBTV_BASE + 0x0278, 0x002d },
+               { USBTV_BASE + 0x0279, 0x000a },
+               { USBTV_BASE + 0x027a, 0x0032 },
+               { 0xf890, 0x000c },
+               { 0xf894, 0x0086 },
+
+               { USBTV_BASE + 0x00ac, 0x00c0 },
+               { USBTV_BASE + 0x00ad, 0x0000 },
+               { USBTV_BASE + 0x00a2, 0x0012 },
+               { USBTV_BASE + 0x00a3, 0x00e0 },
+               { USBTV_BASE + 0x00a4, 0x0028 },
+               { USBTV_BASE + 0x00a5, 0x0082 },
+               { USBTV_BASE + 0x00a7, 0x0080 },
+               { USBTV_BASE + 0x0000, 0x0014 },
+               { USBTV_BASE + 0x0006, 0x0003 },
+               { USBTV_BASE + 0x0090, 0x0099 },
+               { USBTV_BASE + 0x0091, 0x0090 },
+               { USBTV_BASE + 0x0094, 0x0068 },
+               { USBTV_BASE + 0x0095, 0x0070 },
+               { USBTV_BASE + 0x009c, 0x0030 },
+               { USBTV_BASE + 0x009d, 0x00c0 },
+               { USBTV_BASE + 0x009e, 0x00e0 },
+               { USBTV_BASE + 0x0019, 0x0006 },
+               { USBTV_BASE + 0x008c, 0x00ba },
+               { USBTV_BASE + 0x0101, 0x00ff },
+               { USBTV_BASE + 0x010c, 0x00b3 },
+               { USBTV_BASE + 0x01b2, 0x0080 },
+               { USBTV_BASE + 0x01b4, 0x00a0 },
+               { USBTV_BASE + 0x014c, 0x00ff },
+               { USBTV_BASE + 0x014d, 0x00ca },
+               { USBTV_BASE + 0x0113, 0x0053 },
+               { USBTV_BASE + 0x0119, 0x008a },
+               { USBTV_BASE + 0x013c, 0x0003 },
+               { USBTV_BASE + 0x0150, 0x009c },
+               { USBTV_BASE + 0x0151, 0x0071 },
+               { USBTV_BASE + 0x0152, 0x00c6 },
+               { USBTV_BASE + 0x0153, 0x0084 },
+               { USBTV_BASE + 0x0154, 0x00bc },
+               { USBTV_BASE + 0x0155, 0x00a0 },
+               { USBTV_BASE + 0x0156, 0x00a0 },
+               { USBTV_BASE + 0x0157, 0x009c },
+               { USBTV_BASE + 0x0158, 0x001f },
+               { USBTV_BASE + 0x0159, 0x0006 },
+               { USBTV_BASE + 0x015d, 0x0000 },
+
+               { USBTV_BASE + 0x0284, 0x0088 },
+               { USBTV_BASE + 0x0003, 0x0004 },
+               { USBTV_BASE + 0x0100, 0x00d3 },
+               { USBTV_BASE + 0x0115, 0x0015 },
+               { USBTV_BASE + 0x0220, 0x002e },
+               { USBTV_BASE + 0x0225, 0x0008 },
+               { USBTV_BASE + 0x024e, 0x0002 },
+               { USBTV_BASE + 0x024e, 0x0002 },
+               { USBTV_BASE + 0x024f, 0x0002 },
+       };
+
+       ret = usbtv_set_regs(usbtv, setup, ARRAY_SIZE(setup));
+       if (ret)
+               return ret;
+
+       ret = usbtv_select_norm(usbtv, usbtv->norm);
+       if (ret)
+               return ret;
+
+       ret = usbtv_select_input(usbtv, usbtv->input);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+/* Copy data from chunk into a frame buffer, deinterlacing the data
+ * into every second line. Unfortunately, they don't align nicely into
+ * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels.
+ * Therefore, we break down the chunk into two halves before copyting,
+ * so that we can interleave a line if needed. */
+static void usbtv_chunk_to_vbuf(u32 *frame, u32 *src, int chunk_no, int odd)
+{
+       int half;
+
+       for (half = 0; half < 2; half++) {
+               int part_no = chunk_no * 2 + half;
+               int line = part_no / 3;
+               int part_index = (line * 2 + !odd) * 3 + (part_no % 3);
+
+               u32 *dst = &frame[part_index * USBTV_CHUNK/2];
+               memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src));
+               src += USBTV_CHUNK/2;
+       }
+}
+
+/* Called for each 256-byte image chunk.
+ * First word identifies the chunk, followed by 240 words of image
+ * data and padding. */
+static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
+{
+       int frame_id, odd, chunk_no;
+       u32 *frame;
+       struct usbtv_buf *buf;
+       unsigned long flags;
+
+       /* Ignore corrupted lines. */
+       if (!USBTV_MAGIC_OK(chunk))
+               return;
+       frame_id = USBTV_FRAME_ID(chunk);
+       odd = USBTV_ODD(chunk);
+       chunk_no = USBTV_CHUNK_NO(chunk);
+       if (chunk_no >= usbtv->n_chunks)
+               return;
+
+       /* Beginning of a frame. */
+       if (chunk_no == 0) {
+               usbtv->frame_id = frame_id;
+               usbtv->chunks_done = 0;
+       }
+
+       if (usbtv->frame_id != frame_id)
+               return;
+
+       spin_lock_irqsave(&usbtv->buflock, flags);
+       if (list_empty(&usbtv->bufs)) {
+               /* No free buffers. Userspace likely too slow. */
+               spin_unlock_irqrestore(&usbtv->buflock, flags);
+               return;
+       }
+
+       /* First available buffer. */
+       buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
+       frame = vb2_plane_vaddr(&buf->vb, 0);
+
+       /* Copy the chunk data. */
+       usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
+       usbtv->chunks_done++;
+
+       /* Last chunk in a frame, signalling an end */
+       if (odd && chunk_no == usbtv->n_chunks-1) {
+               int size = vb2_plane_size(&buf->vb, 0);
+               enum vb2_buffer_state state = usbtv->chunks_done ==
+                                               usbtv->n_chunks ?
+                                               VB2_BUF_STATE_DONE :
+                                               VB2_BUF_STATE_ERROR;
+
+               buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
+               buf->vb.v4l2_buf.sequence = usbtv->sequence++;
+               v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+               vb2_set_plane_payload(&buf->vb, 0, size);
+               vb2_buffer_done(&buf->vb, state);
+               list_del(&buf->list);
+       }
+
+       spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+/* Got image data. Each packet contains a number of 256-word chunks we
+ * compose the image from. */
+static void usbtv_iso_cb(struct urb *ip)
+{
+       int ret;
+       int i;
+       struct usbtv *usbtv = (struct usbtv *)ip->context;
+
+       switch (ip->status) {
+       /* All fine. */
+       case 0:
+               break;
+       /* Device disconnected or capture stopped? */
+       case -ENODEV:
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               return;
+       /* Unknown error. Retry. */
+       default:
+               dev_warn(usbtv->dev, "Bad response for ISO request.\n");
+               goto resubmit;
+       }
+
+       for (i = 0; i < ip->number_of_packets; i++) {
+               int size = ip->iso_frame_desc[i].actual_length;
+               unsigned char *data = ip->transfer_buffer +
+                               ip->iso_frame_desc[i].offset;
+               int offset;
+
+               for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++)
+                       usbtv_image_chunk(usbtv,
+                               (u32 *)&data[USBTV_CHUNK_SIZE * offset]);
+       }
+
+resubmit:
+       ret = usb_submit_urb(ip, GFP_ATOMIC);
+       if (ret < 0)
+               dev_warn(usbtv->dev, "Could not resubmit ISO URB\n");
+}
+
+static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)
+{
+       struct urb *ip;
+       int size = usbtv->iso_size;
+       int i;
+
+       ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL);
+       if (ip == NULL)
+               return NULL;
+
+       ip->dev = usbtv->udev;
+       ip->context = usbtv;
+       ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP);
+       ip->interval = 1;
+       ip->transfer_flags = URB_ISO_ASAP;
+       ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS,
+                                               GFP_KERNEL);
+       ip->complete = usbtv_iso_cb;
+       ip->number_of_packets = USBTV_ISOC_PACKETS;
+       ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;
+       for (i = 0; i < USBTV_ISOC_PACKETS; i++) {
+               ip->iso_frame_desc[i].offset = size * i;
+               ip->iso_frame_desc[i].length = size;
+       }
+
+       return ip;
+}
+
+static void usbtv_stop(struct usbtv *usbtv)
+{
+       int i;
+       unsigned long flags;
+
+       /* Cancel running transfers. */
+       for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+               struct urb *ip = usbtv->isoc_urbs[i];
+               if (ip == NULL)
+                       continue;
+               usb_kill_urb(ip);
+               kfree(ip->transfer_buffer);
+               usb_free_urb(ip);
+               usbtv->isoc_urbs[i] = NULL;
+       }
+
+       /* Return buffers to userspace. */
+       spin_lock_irqsave(&usbtv->buflock, flags);
+       while (!list_empty(&usbtv->bufs)) {
+               struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,
+                                               struct usbtv_buf, list);
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+               list_del(&buf->list);
+       }
+       spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start(struct usbtv *usbtv)
+{
+       int i;
+       int ret;
+
+       ret = usb_set_interface(usbtv->udev, 0, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = usbtv_setup_capture(usbtv);
+       if (ret < 0)
+               return ret;
+
+       ret = usb_set_interface(usbtv->udev, 0, 1);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+               struct urb *ip;
+
+               ip = usbtv_setup_iso_transfer(usbtv);
+               if (ip == NULL) {
+                       ret = -ENOMEM;
+                       goto start_fail;
+               }
+               usbtv->isoc_urbs[i] = ip;
+
+               ret = usb_submit_urb(ip, GFP_KERNEL);
+               if (ret < 0)
+                       goto start_fail;
+       }
+
+       return 0;
+
+start_fail:
+       usbtv_stop(usbtv);
+       return ret;
+}
+
+static int usbtv_querycap(struct file *file, void *priv,
+                               struct v4l2_capability *cap)
+{
+       struct usbtv *dev = video_drvdata(file);
+
+       strlcpy(cap->driver, "usbtv", sizeof(cap->driver));
+       strlcpy(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;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       return 0;
+}
+
+static int usbtv_enum_input(struct file *file, void *priv,
+                                       struct v4l2_input *i)
+{
+       struct usbtv *dev = video_drvdata(file);
+
+       switch (i->index) {
+       case USBTV_COMPOSITE_INPUT:
+               strlcpy(i->name, "Composite", sizeof(i->name));
+               break;
+       case USBTV_SVIDEO_INPUT:
+               strlcpy(i->name, "S-Video", sizeof(i->name));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       i->type = V4L2_INPUT_TYPE_CAMERA;
+       i->std = dev->vdev.tvnorms;
+       return 0;
+}
+
+static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
+                                       struct v4l2_fmtdesc *f)
+{
+       if (f->index > 0)
+               return -EINVAL;
+
+       strlcpy(f->description, "16 bpp YUY2, 4:2:2, packed",
+                                       sizeof(f->description));
+       f->pixelformat = V4L2_PIX_FMT_YUYV;
+       return 0;
+}
+
+static int usbtv_fmt_vid_cap(struct file *file, void *priv,
+                                       struct v4l2_format *f)
+{
+       struct usbtv *usbtv = video_drvdata(file);
+
+       f->fmt.pix.width = usbtv->width;
+       f->fmt.pix.height = usbtv->height;
+       f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+       f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       f->fmt.pix.bytesperline = usbtv->width * 2;
+       f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
+       f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+       return 0;
+}
+
+static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+       struct usbtv *usbtv = video_drvdata(file);
+       *norm = usbtv->norm;
+       return 0;
+}
+
+static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
+{
+       int ret = -EINVAL;
+       struct usbtv *usbtv = video_drvdata(file);
+
+       if ((norm & V4L2_STD_525_60) || (norm & V4L2_STD_PAL))
+               ret = usbtv_select_norm(usbtv, norm);
+
+       return ret;
+}
+
+static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
+{
+       struct usbtv *usbtv = video_drvdata(file);
+       *i = usbtv->input;
+       return 0;
+}
+
+static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
+{
+       struct usbtv *usbtv = video_drvdata(file);
+       return usbtv_select_input(usbtv, i);
+}
+
+static struct v4l2_ioctl_ops usbtv_ioctl_ops = {
+       .vidioc_querycap = usbtv_querycap,
+       .vidioc_enum_input = usbtv_enum_input,
+       .vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap,
+       .vidioc_g_std = usbtv_g_std,
+       .vidioc_s_std = usbtv_s_std,
+       .vidioc_g_input = usbtv_g_input,
+       .vidioc_s_input = usbtv_s_input,
+
+       .vidioc_reqbufs = vb2_ioctl_reqbufs,
+       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+       .vidioc_querybuf = vb2_ioctl_querybuf,
+       .vidioc_create_bufs = vb2_ioctl_create_bufs,
+       .vidioc_qbuf = vb2_ioctl_qbuf,
+       .vidioc_dqbuf = vb2_ioctl_dqbuf,
+       .vidioc_streamon = vb2_ioctl_streamon,
+       .vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+static struct v4l2_file_operations usbtv_fops = {
+       .owner = THIS_MODULE,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap = vb2_fop_mmap,
+       .open = v4l2_fh_open,
+       .release = vb2_fop_release,
+       .read = vb2_fop_read,
+       .poll = vb2_fop_poll,
+};
+
+static int usbtv_queue_setup(struct vb2_queue *vq,
+       const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
+       unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+       struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+       if (*nbuffers < 2)
+               *nbuffers = 2;
+       *nplanes = 1;
+       sizes[0] = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);
+
+       return 0;
+}
+
+static void usbtv_buf_queue(struct vb2_buffer *vb)
+{
+       struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);
+       struct usbtv_buf *buf = container_of(vb, struct usbtv_buf, vb);
+       unsigned long flags;
+
+       if (usbtv->udev == NULL) {
+               vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+               return;
+       }
+
+       spin_lock_irqsave(&usbtv->buflock, flags);
+       list_add_tail(&buf->list, &usbtv->bufs);
+       spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+       if (usbtv->udev == NULL)
+               return -ENODEV;
+
+       return usbtv_start(usbtv);
+}
+
+static int usbtv_stop_streaming(struct vb2_queue *vq)
+{
+       struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+       if (usbtv->udev == NULL)
+               return -ENODEV;
+
+       usbtv_stop(usbtv);
+       return 0;
+}
+
+static struct vb2_ops usbtv_vb2_ops = {
+       .queue_setup = usbtv_queue_setup,
+       .buf_queue = usbtv_buf_queue,
+       .start_streaming = usbtv_start_streaming,
+       .stop_streaming = usbtv_stop_streaming,
+};
+
+static void usbtv_release(struct v4l2_device *v4l2_dev)
+{
+       struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev);
+
+       v4l2_device_unregister(&usbtv->v4l2_dev);
+       vb2_queue_release(&usbtv->vb2q);
+       kfree(usbtv);
+}
+
+int usbtv_video_init(struct usbtv *usbtv)
+{
+       int ret;
+
+       (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60);
+
+       spin_lock_init(&usbtv->buflock);
+       mutex_init(&usbtv->v4l2_lock);
+       mutex_init(&usbtv->vb2q_lock);
+       INIT_LIST_HEAD(&usbtv->bufs);
+
+       /* videobuf2 structure */
+       usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+       usbtv->vb2q.drv_priv = usbtv;
+       usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf);
+       usbtv->vb2q.ops = &usbtv_vb2_ops;
+       usbtv->vb2q.mem_ops = &vb2_vmalloc_memops;
+       usbtv->vb2q.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       usbtv->vb2q.lock = &usbtv->vb2q_lock;
+       ret = vb2_queue_init(&usbtv->vb2q);
+       if (ret < 0) {
+               dev_warn(usbtv->dev, "Could not initialize videobuf2 queue\n");
+               return ret;
+       }
+
+       /* v4l2 structure */
+       usbtv->v4l2_dev.release = usbtv_release;
+       ret = v4l2_device_register(usbtv->dev, &usbtv->v4l2_dev);
+       if (ret < 0) {
+               dev_warn(usbtv->dev, "Could not register v4l2 device\n");
+               goto v4l2_fail;
+       }
+
+       /* Video structure */
+       strlcpy(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;
+       usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
+       usbtv->vdev.tvnorms = USBTV_TV_STD;
+       usbtv->vdev.queue = &usbtv->vb2q;
+       usbtv->vdev.lock = &usbtv->v4l2_lock;
+       set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
+       video_set_drvdata(&usbtv->vdev, usbtv);
+       ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);
+       if (ret < 0) {
+               dev_warn(usbtv->dev, "Could not register video device\n");
+               goto vdev_fail;
+       }
+
+       return 0;
+
+vdev_fail:
+       v4l2_device_unregister(&usbtv->v4l2_dev);
+v4l2_fail:
+       vb2_queue_release(&usbtv->vb2q);
+
+       return ret;
+}
+
+void usbtv_video_free(struct usbtv *usbtv)
+{
+       mutex_lock(&usbtv->vb2q_lock);
+       mutex_lock(&usbtv->v4l2_lock);
+
+       usbtv_stop(usbtv);
+       video_unregister_device(&usbtv->vdev);
+       v4l2_device_disconnect(&usbtv->v4l2_dev);
+
+       mutex_unlock(&usbtv->v4l2_lock);
+       mutex_unlock(&usbtv->vb2q_lock);
+
+       v4l2_device_put(&usbtv->v4l2_dev);
+}
diff --git a/drivers/media/usb/usbtv/usbtv.c b/drivers/media/usb/usbtv/usbtv.c
deleted file mode 100644 (file)
index 6222a4a..0000000
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
- * Fushicai USBTV007 Video Grabber Driver
- *
- * Product web site:
- * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
- *
- * Following LWN articles were very useful in construction of this driver:
- * Video4Linux2 API series: http://lwn.net/Articles/203924/
- * videobuf2 API explanation: http://lwn.net/Articles/447435/
- * Thanks go to Jonathan Corbet for providing this quality documentation.
- * He is awesome.
- *
- * Copyright (c) 2013 Lubomir Rintel
- * All rights reserved.
- * No physical hardware was harmed running Windows during the
- * reverse-engineering activity
- *
- * 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. The name of the author 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").
- */
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h>
-
-/* Hardware. */
-#define USBTV_VIDEO_ENDP       0x81
-#define USBTV_BASE             0xc000
-#define USBTV_REQUEST_REG      12
-
-/* Number of concurrent isochronous urbs submitted.
- * Higher numbers was seen to overly saturate the USB bus. */
-#define USBTV_ISOC_TRANSFERS   16
-#define USBTV_ISOC_PACKETS     8
-
-#define USBTV_CHUNK_SIZE       256
-#define USBTV_CHUNK            240
-
-/* Chunk header. */
-#define USBTV_MAGIC_OK(chunk)  ((be32_to_cpu(chunk[0]) & 0xff000000) \
-                                                       == 0x88000000)
-#define USBTV_FRAME_ID(chunk)  ((be32_to_cpu(chunk[0]) & 0x00ff0000) >> 16)
-#define USBTV_ODD(chunk)       ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
-#define USBTV_CHUNK_NO(chunk)  (be32_to_cpu(chunk[0]) & 0x00000fff)
-
-#define USBTV_TV_STD  (V4L2_STD_525_60 | V4L2_STD_PAL)
-
-/* parameters for supported TV norms */
-struct usbtv_norm_params {
-       v4l2_std_id norm;
-       int cap_width, cap_height;
-};
-
-static struct usbtv_norm_params norm_params[] = {
-       {
-               .norm = V4L2_STD_525_60,
-               .cap_width = 720,
-               .cap_height = 480,
-       },
-       {
-               .norm = V4L2_STD_PAL,
-               .cap_width = 720,
-               .cap_height = 576,
-       }
-};
-
-/* A single videobuf2 frame buffer. */
-struct usbtv_buf {
-       struct vb2_buffer vb;
-       struct list_head list;
-};
-
-/* Per-device structure. */
-struct usbtv {
-       struct device *dev;
-       struct usb_device *udev;
-       struct v4l2_device v4l2_dev;
-       struct video_device vdev;
-       struct vb2_queue vb2q;
-       struct mutex v4l2_lock;
-       struct mutex vb2q_lock;
-
-       /* List of videobuf2 buffers protected by a lock. */
-       spinlock_t buflock;
-       struct list_head bufs;
-
-       /* Number of currently processed frame, useful find
-        * out when a new one begins. */
-       u32 frame_id;
-       int chunks_done;
-
-       enum {
-               USBTV_COMPOSITE_INPUT,
-               USBTV_SVIDEO_INPUT,
-       } input;
-       v4l2_std_id norm;
-       int width, height;
-       int n_chunks;
-       int iso_size;
-       unsigned int sequence;
-       struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
-};
-
-static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm)
-{
-       int i, ret = 0;
-       struct usbtv_norm_params *params = NULL;
-
-       for (i = 0; i < ARRAY_SIZE(norm_params); i++) {
-               if (norm_params[i].norm & norm) {
-                       params = &norm_params[i];
-                       break;
-               }
-       }
-
-       if (params) {
-               usbtv->width = params->cap_width;
-               usbtv->height = params->cap_height;
-               usbtv->n_chunks = usbtv->width * usbtv->height
-                                               / 4 / USBTV_CHUNK;
-               usbtv->norm = params->norm;
-       } else
-               ret = -EINVAL;
-
-       return ret;
-}
-
-static int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size)
-{
-       int ret;
-       int pipe = usb_rcvctrlpipe(usbtv->udev, 0);
-       int i;
-
-       for (i = 0; i < size; i++) {
-               u16 index = regs[i][0];
-               u16 value = regs[i][1];
-
-               ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
-                       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                       value, index, NULL, 0, 0);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int usbtv_select_input(struct usbtv *usbtv, int input)
-{
-       int ret;
-
-       static const u16 composite[][2] = {
-               { USBTV_BASE + 0x0105, 0x0060 },
-               { USBTV_BASE + 0x011f, 0x00f2 },
-               { USBTV_BASE + 0x0127, 0x0060 },
-               { USBTV_BASE + 0x00ae, 0x0010 },
-               { USBTV_BASE + 0x0284, 0x00aa },
-               { USBTV_BASE + 0x0239, 0x0060 },
-       };
-
-       static const u16 svideo[][2] = {
-               { USBTV_BASE + 0x0105, 0x0010 },
-               { USBTV_BASE + 0x011f, 0x00ff },
-               { USBTV_BASE + 0x0127, 0x0060 },
-               { USBTV_BASE + 0x00ae, 0x0030 },
-               { USBTV_BASE + 0x0284, 0x0088 },
-               { USBTV_BASE + 0x0239, 0x0060 },
-       };
-
-       switch (input) {
-       case USBTV_COMPOSITE_INPUT:
-               ret = usbtv_set_regs(usbtv, composite, ARRAY_SIZE(composite));
-               break;
-       case USBTV_SVIDEO_INPUT:
-               ret = usbtv_set_regs(usbtv, svideo, ARRAY_SIZE(svideo));
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       if (!ret)
-               usbtv->input = input;
-
-       return ret;
-}
-
-static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm)
-{
-       int ret;
-       static const u16 pal[][2] = {
-               { USBTV_BASE + 0x001a, 0x0068 },
-               { USBTV_BASE + 0x010e, 0x0072 },
-               { USBTV_BASE + 0x010f, 0x00a2 },
-               { USBTV_BASE + 0x0112, 0x00b0 },
-               { USBTV_BASE + 0x0117, 0x0001 },
-               { USBTV_BASE + 0x0118, 0x002c },
-               { USBTV_BASE + 0x012d, 0x0010 },
-               { USBTV_BASE + 0x012f, 0x0020 },
-               { USBTV_BASE + 0x024f, 0x0002 },
-               { USBTV_BASE + 0x0254, 0x0059 },
-               { USBTV_BASE + 0x025a, 0x0016 },
-               { USBTV_BASE + 0x025b, 0x0035 },
-               { USBTV_BASE + 0x0263, 0x0017 },
-               { USBTV_BASE + 0x0266, 0x0016 },
-               { USBTV_BASE + 0x0267, 0x0036 }
-       };
-
-       static const u16 ntsc[][2] = {
-               { USBTV_BASE + 0x001a, 0x0079 },
-               { USBTV_BASE + 0x010e, 0x0068 },
-               { USBTV_BASE + 0x010f, 0x009c },
-               { USBTV_BASE + 0x0112, 0x00f0 },
-               { USBTV_BASE + 0x0117, 0x0000 },
-               { USBTV_BASE + 0x0118, 0x00fc },
-               { USBTV_BASE + 0x012d, 0x0004 },
-               { USBTV_BASE + 0x012f, 0x0008 },
-               { USBTV_BASE + 0x024f, 0x0001 },
-               { USBTV_BASE + 0x0254, 0x005f },
-               { USBTV_BASE + 0x025a, 0x0012 },
-               { USBTV_BASE + 0x025b, 0x0001 },
-               { USBTV_BASE + 0x0263, 0x001c },
-               { USBTV_BASE + 0x0266, 0x0011 },
-               { USBTV_BASE + 0x0267, 0x0005 }
-       };
-
-       ret = usbtv_configure_for_norm(usbtv, norm);
-
-       if (!ret) {
-               if (norm & V4L2_STD_525_60)
-                       ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc));
-               else if (norm & V4L2_STD_PAL)
-                       ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal));
-       }
-
-       return ret;
-}
-
-static int usbtv_setup_capture(struct usbtv *usbtv)
-{
-       int ret;
-       static const u16 setup[][2] = {
-               /* These seem to enable the device. */
-               { USBTV_BASE + 0x0008, 0x0001 },
-               { USBTV_BASE + 0x01d0, 0x00ff },
-               { USBTV_BASE + 0x01d9, 0x0002 },
-
-               /* These seem to influence color parameters, such as
-                * brightness, etc. */
-               { USBTV_BASE + 0x0239, 0x0040 },
-               { USBTV_BASE + 0x0240, 0x0000 },
-               { USBTV_BASE + 0x0241, 0x0000 },
-               { USBTV_BASE + 0x0242, 0x0002 },
-               { USBTV_BASE + 0x0243, 0x0080 },
-               { USBTV_BASE + 0x0244, 0x0012 },
-               { USBTV_BASE + 0x0245, 0x0090 },
-               { USBTV_BASE + 0x0246, 0x0000 },
-
-               { USBTV_BASE + 0x0278, 0x002d },
-               { USBTV_BASE + 0x0279, 0x000a },
-               { USBTV_BASE + 0x027a, 0x0032 },
-               { 0xf890, 0x000c },
-               { 0xf894, 0x0086 },
-
-               { USBTV_BASE + 0x00ac, 0x00c0 },
-               { USBTV_BASE + 0x00ad, 0x0000 },
-               { USBTV_BASE + 0x00a2, 0x0012 },
-               { USBTV_BASE + 0x00a3, 0x00e0 },
-               { USBTV_BASE + 0x00a4, 0x0028 },
-               { USBTV_BASE + 0x00a5, 0x0082 },
-               { USBTV_BASE + 0x00a7, 0x0080 },
-               { USBTV_BASE + 0x0000, 0x0014 },
-               { USBTV_BASE + 0x0006, 0x0003 },
-               { USBTV_BASE + 0x0090, 0x0099 },
-               { USBTV_BASE + 0x0091, 0x0090 },
-               { USBTV_BASE + 0x0094, 0x0068 },
-               { USBTV_BASE + 0x0095, 0x0070 },
-               { USBTV_BASE + 0x009c, 0x0030 },
-               { USBTV_BASE + 0x009d, 0x00c0 },
-               { USBTV_BASE + 0x009e, 0x00e0 },
-               { USBTV_BASE + 0x0019, 0x0006 },
-               { USBTV_BASE + 0x008c, 0x00ba },
-               { USBTV_BASE + 0x0101, 0x00ff },
-               { USBTV_BASE + 0x010c, 0x00b3 },
-               { USBTV_BASE + 0x01b2, 0x0080 },
-               { USBTV_BASE + 0x01b4, 0x00a0 },
-               { USBTV_BASE + 0x014c, 0x00ff },
-               { USBTV_BASE + 0x014d, 0x00ca },
-               { USBTV_BASE + 0x0113, 0x0053 },
-               { USBTV_BASE + 0x0119, 0x008a },
-               { USBTV_BASE + 0x013c, 0x0003 },
-               { USBTV_BASE + 0x0150, 0x009c },
-               { USBTV_BASE + 0x0151, 0x0071 },
-               { USBTV_BASE + 0x0152, 0x00c6 },
-               { USBTV_BASE + 0x0153, 0x0084 },
-               { USBTV_BASE + 0x0154, 0x00bc },
-               { USBTV_BASE + 0x0155, 0x00a0 },
-               { USBTV_BASE + 0x0156, 0x00a0 },
-               { USBTV_BASE + 0x0157, 0x009c },
-               { USBTV_BASE + 0x0158, 0x001f },
-               { USBTV_BASE + 0x0159, 0x0006 },
-               { USBTV_BASE + 0x015d, 0x0000 },
-
-               { USBTV_BASE + 0x0284, 0x0088 },
-               { USBTV_BASE + 0x0003, 0x0004 },
-               { USBTV_BASE + 0x0100, 0x00d3 },
-               { USBTV_BASE + 0x0115, 0x0015 },
-               { USBTV_BASE + 0x0220, 0x002e },
-               { USBTV_BASE + 0x0225, 0x0008 },
-               { USBTV_BASE + 0x024e, 0x0002 },
-               { USBTV_BASE + 0x024e, 0x0002 },
-               { USBTV_BASE + 0x024f, 0x0002 },
-       };
-
-       ret = usbtv_set_regs(usbtv, setup, ARRAY_SIZE(setup));
-       if (ret)
-               return ret;
-
-       ret = usbtv_select_norm(usbtv, usbtv->norm);
-       if (ret)
-               return ret;
-
-       ret = usbtv_select_input(usbtv, usbtv->input);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-/* Copy data from chunk into a frame buffer, deinterlacing the data
- * into every second line. Unfortunately, they don't align nicely into
- * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels.
- * Therefore, we break down the chunk into two halves before copyting,
- * so that we can interleave a line if needed. */
-static void usbtv_chunk_to_vbuf(u32 *frame, u32 *src, int chunk_no, int odd)
-{
-       int half;
-
-       for (half = 0; half < 2; half++) {
-               int part_no = chunk_no * 2 + half;
-               int line = part_no / 3;
-               int part_index = (line * 2 + !odd) * 3 + (part_no % 3);
-
-               u32 *dst = &frame[part_index * USBTV_CHUNK/2];
-               memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src));
-               src += USBTV_CHUNK/2;
-       }
-}
-
-/* Called for each 256-byte image chunk.
- * First word identifies the chunk, followed by 240 words of image
- * data and padding. */
-static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
-{
-       int frame_id, odd, chunk_no;
-       u32 *frame;
-       struct usbtv_buf *buf;
-       unsigned long flags;
-
-       /* Ignore corrupted lines. */
-       if (!USBTV_MAGIC_OK(chunk))
-               return;
-       frame_id = USBTV_FRAME_ID(chunk);
-       odd = USBTV_ODD(chunk);
-       chunk_no = USBTV_CHUNK_NO(chunk);
-       if (chunk_no >= usbtv->n_chunks)
-               return;
-
-       /* Beginning of a frame. */
-       if (chunk_no == 0) {
-               usbtv->frame_id = frame_id;
-               usbtv->chunks_done = 0;
-       }
-
-       if (usbtv->frame_id != frame_id)
-               return;
-
-       spin_lock_irqsave(&usbtv->buflock, flags);
-       if (list_empty(&usbtv->bufs)) {
-               /* No free buffers. Userspace likely too slow. */
-               spin_unlock_irqrestore(&usbtv->buflock, flags);
-               return;
-       }
-
-       /* First available buffer. */
-       buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
-       frame = vb2_plane_vaddr(&buf->vb, 0);
-
-       /* Copy the chunk data. */
-       usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
-       usbtv->chunks_done++;
-
-       /* Last chunk in a frame, signalling an end */
-       if (odd && chunk_no == usbtv->n_chunks-1) {
-               int size = vb2_plane_size(&buf->vb, 0);
-               enum vb2_buffer_state state = usbtv->chunks_done ==
-                                               usbtv->n_chunks ?
-                                               VB2_BUF_STATE_DONE :
-                                               VB2_BUF_STATE_ERROR;
-
-               buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
-               buf->vb.v4l2_buf.sequence = usbtv->sequence++;
-               v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
-               vb2_set_plane_payload(&buf->vb, 0, size);
-               vb2_buffer_done(&buf->vb, state);
-               list_del(&buf->list);
-       }
-
-       spin_unlock_irqrestore(&usbtv->buflock, flags);
-}
-
-/* Got image data. Each packet contains a number of 256-word chunks we
- * compose the image from. */
-static void usbtv_iso_cb(struct urb *ip)
-{
-       int ret;
-       int i;
-       struct usbtv *usbtv = (struct usbtv *)ip->context;
-
-       switch (ip->status) {
-       /* All fine. */
-       case 0:
-               break;
-       /* Device disconnected or capture stopped? */
-       case -ENODEV:
-       case -ENOENT:
-       case -ECONNRESET:
-       case -ESHUTDOWN:
-               return;
-       /* Unknown error. Retry. */
-       default:
-               dev_warn(usbtv->dev, "Bad response for ISO request.\n");
-               goto resubmit;
-       }
-
-       for (i = 0; i < ip->number_of_packets; i++) {
-               int size = ip->iso_frame_desc[i].actual_length;
-               unsigned char *data = ip->transfer_buffer +
-                               ip->iso_frame_desc[i].offset;
-               int offset;
-
-               for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++)
-                       usbtv_image_chunk(usbtv,
-                               (u32 *)&data[USBTV_CHUNK_SIZE * offset]);
-       }
-
-resubmit:
-       ret = usb_submit_urb(ip, GFP_ATOMIC);
-       if (ret < 0)
-               dev_warn(usbtv->dev, "Could not resubmit ISO URB\n");
-}
-
-static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)
-{
-       struct urb *ip;
-       int size = usbtv->iso_size;
-       int i;
-
-       ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL);
-       if (ip == NULL)
-               return NULL;
-
-       ip->dev = usbtv->udev;
-       ip->context = usbtv;
-       ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP);
-       ip->interval = 1;
-       ip->transfer_flags = URB_ISO_ASAP;
-       ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS,
-                                               GFP_KERNEL);
-       ip->complete = usbtv_iso_cb;
-       ip->number_of_packets = USBTV_ISOC_PACKETS;
-       ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;
-       for (i = 0; i < USBTV_ISOC_PACKETS; i++) {
-               ip->iso_frame_desc[i].offset = size * i;
-               ip->iso_frame_desc[i].length = size;
-       }
-
-       return ip;
-}
-
-static void usbtv_stop(struct usbtv *usbtv)
-{
-       int i;
-       unsigned long flags;
-
-       /* Cancel running transfers. */
-       for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
-               struct urb *ip = usbtv->isoc_urbs[i];
-               if (ip == NULL)
-                       continue;
-               usb_kill_urb(ip);
-               kfree(ip->transfer_buffer);
-               usb_free_urb(ip);
-               usbtv->isoc_urbs[i] = NULL;
-       }
-
-       /* Return buffers to userspace. */
-       spin_lock_irqsave(&usbtv->buflock, flags);
-       while (!list_empty(&usbtv->bufs)) {
-               struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,
-                                               struct usbtv_buf, list);
-               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
-               list_del(&buf->list);
-       }
-       spin_unlock_irqrestore(&usbtv->buflock, flags);
-}
-
-static int usbtv_start(struct usbtv *usbtv)
-{
-       int i;
-       int ret;
-
-       ret = usb_set_interface(usbtv->udev, 0, 0);
-       if (ret < 0)
-               return ret;
-
-       ret = usbtv_setup_capture(usbtv);
-       if (ret < 0)
-               return ret;
-
-       ret = usb_set_interface(usbtv->udev, 0, 1);
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
-               struct urb *ip;
-
-               ip = usbtv_setup_iso_transfer(usbtv);
-               if (ip == NULL) {
-                       ret = -ENOMEM;
-                       goto start_fail;
-               }
-               usbtv->isoc_urbs[i] = ip;
-
-               ret = usb_submit_urb(ip, GFP_KERNEL);
-               if (ret < 0)
-                       goto start_fail;
-       }
-
-       return 0;
-
-start_fail:
-       usbtv_stop(usbtv);
-       return ret;
-}
-
-struct usb_device_id usbtv_id_table[] = {
-       { USB_DEVICE(0x1b71, 0x3002) },
-       {}
-};
-MODULE_DEVICE_TABLE(usb, usbtv_id_table);
-
-static int usbtv_querycap(struct file *file, void *priv,
-                               struct v4l2_capability *cap)
-{
-       struct usbtv *dev = video_drvdata(file);
-
-       strlcpy(cap->driver, "usbtv", sizeof(cap->driver));
-       strlcpy(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;
-       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-       return 0;
-}
-
-static int usbtv_enum_input(struct file *file, void *priv,
-                                       struct v4l2_input *i)
-{
-       struct usbtv *dev = video_drvdata(file);
-
-       switch (i->index) {
-       case USBTV_COMPOSITE_INPUT:
-               strlcpy(i->name, "Composite", sizeof(i->name));
-               break;
-       case USBTV_SVIDEO_INPUT:
-               strlcpy(i->name, "S-Video", sizeof(i->name));
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       i->type = V4L2_INPUT_TYPE_CAMERA;
-       i->std = dev->vdev.tvnorms;
-       return 0;
-}
-
-static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
-                                       struct v4l2_fmtdesc *f)
-{
-       if (f->index > 0)
-               return -EINVAL;
-
-       strlcpy(f->description, "16 bpp YUY2, 4:2:2, packed",
-                                       sizeof(f->description));
-       f->pixelformat = V4L2_PIX_FMT_YUYV;
-       return 0;
-}
-
-static int usbtv_fmt_vid_cap(struct file *file, void *priv,
-                                       struct v4l2_format *f)
-{
-       struct usbtv *usbtv = video_drvdata(file);
-
-       f->fmt.pix.width = usbtv->width;
-       f->fmt.pix.height = usbtv->height;
-       f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-       f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       f->fmt.pix.bytesperline = usbtv->width * 2;
-       f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
-       f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
-       return 0;
-}
-
-static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
-{
-       struct usbtv *usbtv = video_drvdata(file);
-       *norm = usbtv->norm;
-       return 0;
-}
-
-static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
-{
-       int ret = -EINVAL;
-       struct usbtv *usbtv = video_drvdata(file);
-
-       if ((norm & V4L2_STD_525_60) || (norm & V4L2_STD_PAL))
-               ret = usbtv_select_norm(usbtv, norm);
-
-       return ret;
-}
-
-static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
-{
-       struct usbtv *usbtv = video_drvdata(file);
-       *i = usbtv->input;
-       return 0;
-}
-
-static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
-{
-       struct usbtv *usbtv = video_drvdata(file);
-       return usbtv_select_input(usbtv, i);
-}
-
-struct v4l2_ioctl_ops usbtv_ioctl_ops = {
-       .vidioc_querycap = usbtv_querycap,
-       .vidioc_enum_input = usbtv_enum_input,
-       .vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap,
-       .vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap,
-       .vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap,
-       .vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap,
-       .vidioc_g_std = usbtv_g_std,
-       .vidioc_s_std = usbtv_s_std,
-       .vidioc_g_input = usbtv_g_input,
-       .vidioc_s_input = usbtv_s_input,
-
-       .vidioc_reqbufs = vb2_ioctl_reqbufs,
-       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-       .vidioc_querybuf = vb2_ioctl_querybuf,
-       .vidioc_create_bufs = vb2_ioctl_create_bufs,
-       .vidioc_qbuf = vb2_ioctl_qbuf,
-       .vidioc_dqbuf = vb2_ioctl_dqbuf,
-       .vidioc_streamon = vb2_ioctl_streamon,
-       .vidioc_streamoff = vb2_ioctl_streamoff,
-};
-
-struct v4l2_file_operations usbtv_fops = {
-       .owner = THIS_MODULE,
-       .unlocked_ioctl = video_ioctl2,
-       .mmap = vb2_fop_mmap,
-       .open = v4l2_fh_open,
-       .release = vb2_fop_release,
-       .read = vb2_fop_read,
-       .poll = vb2_fop_poll,
-};
-
-static int usbtv_queue_setup(struct vb2_queue *vq,
-       const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
-       unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
-{
-       struct usbtv *usbtv = vb2_get_drv_priv(vq);
-
-       if (*nbuffers < 2)
-               *nbuffers = 2;
-       *nplanes = 1;
-       sizes[0] = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);
-
-       return 0;
-}
-
-static void usbtv_buf_queue(struct vb2_buffer *vb)
-{
-       struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);
-       struct usbtv_buf *buf = container_of(vb, struct usbtv_buf, vb);
-       unsigned long flags;
-
-       if (usbtv->udev == NULL) {
-               vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
-               return;
-       }
-
-       spin_lock_irqsave(&usbtv->buflock, flags);
-       list_add_tail(&buf->list, &usbtv->bufs);
-       spin_unlock_irqrestore(&usbtv->buflock, flags);
-}
-
-static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-       struct usbtv *usbtv = vb2_get_drv_priv(vq);
-
-       if (usbtv->udev == NULL)
-               return -ENODEV;
-
-       return usbtv_start(usbtv);
-}
-
-static int usbtv_stop_streaming(struct vb2_queue *vq)
-{
-       struct usbtv *usbtv = vb2_get_drv_priv(vq);
-
-       if (usbtv->udev == NULL)
-               return -ENODEV;
-
-       usbtv_stop(usbtv);
-       return 0;
-}
-
-struct vb2_ops usbtv_vb2_ops = {
-       .queue_setup = usbtv_queue_setup,
-       .buf_queue = usbtv_buf_queue,
-       .start_streaming = usbtv_start_streaming,
-       .stop_streaming = usbtv_stop_streaming,
-};
-
-static void usbtv_release(struct v4l2_device *v4l2_dev)
-{
-       struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev);
-
-       v4l2_device_unregister(&usbtv->v4l2_dev);
-       vb2_queue_release(&usbtv->vb2q);
-       kfree(usbtv);
-}
-
-static int usbtv_probe(struct usb_interface *intf,
-       const struct usb_device_id *id)
-{
-       int ret;
-       int size;
-       struct device *dev = &intf->dev;
-       struct usbtv *usbtv;
-
-       /* Checks that the device is what we think it is. */
-       if (intf->num_altsetting != 2)
-               return -ENODEV;
-       if (intf->altsetting[1].desc.bNumEndpoints != 4)
-               return -ENODEV;
-
-       /* Packet size is split into 11 bits of base size and count of
-        * extra multiplies of it.*/
-       size = usb_endpoint_maxp(&intf->altsetting[1].endpoint[0].desc);
-       size = (size & 0x07ff) * (((size & 0x1800) >> 11) + 1);
-
-       /* Device structure */
-       usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
-       if (usbtv == NULL)
-               return -ENOMEM;
-       usbtv->dev = dev;
-       usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
-
-       usbtv->iso_size = size;
-
-       (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60);
-
-       spin_lock_init(&usbtv->buflock);
-       mutex_init(&usbtv->v4l2_lock);
-       mutex_init(&usbtv->vb2q_lock);
-       INIT_LIST_HEAD(&usbtv->bufs);
-
-       /* videobuf2 structure */
-       usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
-       usbtv->vb2q.drv_priv = usbtv;
-       usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf);
-       usbtv->vb2q.ops = &usbtv_vb2_ops;
-       usbtv->vb2q.mem_ops = &vb2_vmalloc_memops;
-       usbtv->vb2q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       usbtv->vb2q.lock = &usbtv->vb2q_lock;
-       ret = vb2_queue_init(&usbtv->vb2q);
-       if (ret < 0) {
-               dev_warn(dev, "Could not initialize videobuf2 queue\n");
-               goto usbtv_fail;
-       }
-
-       /* v4l2 structure */
-       usbtv->v4l2_dev.release = usbtv_release;
-       ret = v4l2_device_register(dev, &usbtv->v4l2_dev);
-       if (ret < 0) {
-               dev_warn(dev, "Could not register v4l2 device\n");
-               goto v4l2_fail;
-       }
-
-       usb_set_intfdata(intf, usbtv);
-
-       /* Video structure */
-       strlcpy(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;
-       usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
-       usbtv->vdev.tvnorms = USBTV_TV_STD;
-       usbtv->vdev.queue = &usbtv->vb2q;
-       usbtv->vdev.lock = &usbtv->v4l2_lock;
-       set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
-       video_set_drvdata(&usbtv->vdev, usbtv);
-       ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);
-       if (ret < 0) {
-               dev_warn(dev, "Could not register video device\n");
-               goto vdev_fail;
-       }
-
-       dev_info(dev, "Fushicai USBTV007 Video Grabber\n");
-       return 0;
-
-vdev_fail:
-       v4l2_device_unregister(&usbtv->v4l2_dev);
-v4l2_fail:
-       vb2_queue_release(&usbtv->vb2q);
-usbtv_fail:
-       kfree(usbtv);
-
-       return ret;
-}
-
-static void usbtv_disconnect(struct usb_interface *intf)
-{
-       struct usbtv *usbtv = usb_get_intfdata(intf);
-
-       mutex_lock(&usbtv->vb2q_lock);
-       mutex_lock(&usbtv->v4l2_lock);
-
-       usbtv_stop(usbtv);
-       usb_set_intfdata(intf, NULL);
-       video_unregister_device(&usbtv->vdev);
-       v4l2_device_disconnect(&usbtv->v4l2_dev);
-       usb_put_dev(usbtv->udev);
-       usbtv->udev = NULL;
-
-       mutex_unlock(&usbtv->v4l2_lock);
-       mutex_unlock(&usbtv->vb2q_lock);
-
-       v4l2_device_put(&usbtv->v4l2_dev);
-}
-
-MODULE_AUTHOR("Lubomir Rintel");
-MODULE_DESCRIPTION("Fushicai USBTV007 Video Grabber Driver");
-MODULE_LICENSE("Dual BSD/GPL");
-
-struct usb_driver usbtv_usb_driver = {
-       .name = "usbtv",
-       .id_table = usbtv_id_table,
-       .probe = usbtv_probe,
-       .disconnect = usbtv_disconnect,
-};
-
-module_usb_driver(usbtv_usb_driver);
diff --git a/drivers/media/usb/usbtv/usbtv.h b/drivers/media/usb/usbtv/usbtv.h
new file mode 100644 (file)
index 0000000..cb1d388
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Fushicai USBTV007 Video Grabber Driver
+ *
+ * Copyright (c) 2013 Lubomir Rintel
+ * All rights reserved.
+ * No physical hardware was harmed running Windows during the
+ * reverse-engineering activity
+ *
+ * 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. The name of the author 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").
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include <media/v4l2-device.h>
+#include <media/videobuf2-vmalloc.h>
+
+/* Hardware. */
+#define USBTV_VIDEO_ENDP       0x81
+#define USBTV_BASE             0xc000
+#define USBTV_REQUEST_REG      12
+
+/* Number of concurrent isochronous urbs submitted.
+ * Higher numbers was seen to overly saturate the USB bus. */
+#define USBTV_ISOC_TRANSFERS   16
+#define USBTV_ISOC_PACKETS     8
+
+#define USBTV_CHUNK_SIZE       256
+#define USBTV_CHUNK            240
+
+/* Chunk header. */
+#define USBTV_MAGIC_OK(chunk)  ((be32_to_cpu(chunk[0]) & 0xff000000) \
+                                                       == 0x88000000)
+#define USBTV_FRAME_ID(chunk)  ((be32_to_cpu(chunk[0]) & 0x00ff0000) >> 16)
+#define USBTV_ODD(chunk)       ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
+#define USBTV_CHUNK_NO(chunk)  (be32_to_cpu(chunk[0]) & 0x00000fff)
+
+#define USBTV_TV_STD  (V4L2_STD_525_60 | V4L2_STD_PAL)
+
+/* parameters for supported TV norms */
+struct usbtv_norm_params {
+       v4l2_std_id norm;
+       int cap_width, cap_height;
+};
+
+/* A single videobuf2 frame buffer. */
+struct usbtv_buf {
+       struct vb2_buffer vb;
+       struct list_head list;
+};
+
+/* Per-device structure. */
+struct usbtv {
+       struct device *dev;
+       struct usb_device *udev;
+
+       /* video */
+       struct v4l2_device v4l2_dev;
+       struct video_device vdev;
+       struct vb2_queue vb2q;
+       struct mutex v4l2_lock;
+       struct mutex vb2q_lock;
+
+       /* List of videobuf2 buffers protected by a lock. */
+       spinlock_t buflock;
+       struct list_head bufs;
+
+       /* Number of currently processed frame, useful find
+        * out when a new one begins. */
+       u32 frame_id;
+       int chunks_done;
+
+       enum {
+               USBTV_COMPOSITE_INPUT,
+               USBTV_SVIDEO_INPUT,
+       } input;
+       v4l2_std_id norm;
+       int width, height;
+       int n_chunks;
+       int iso_size;
+       unsigned int sequence;
+       struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
+};
+
+int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size);
+
+int usbtv_video_init(struct usbtv *usbtv);
+void usbtv_video_free(struct usbtv *usbtv);
index 8a25876d72c601eaca1b820319129810daf9f313..a0c73cf1517c7ef06c4702a8827f8cff96ca2afa 100644 (file)
@@ -203,14 +203,6 @@ enum {
        mr = LIMIT_RGB(mm_r); \
 }
 
-/* Debugging aid */
-#define USBVISION_SAY_AND_WAIT(what) { \
-       wait_queue_head_t wq; \
-       init_waitqueue_head(&wq); \
-       printk(KERN_INFO "Say: %s\n", what); \
-       interruptible_sleep_on_timeout(&wq, HZ * 3); \
-}
-
 /*
  * This macro checks if usbvision is still operational. The 'usbvision'
  * pointer must be valid, usbvision->dev must be valid, we are not
index c3bb2502225bc6c8932d4aca36de62f1fd1daee2..ad47c5cb539a6f56ce070180079267711c375df3 100644 (file)
@@ -108,10 +108,30 @@ static struct uvc_format_desc uvc_fmts[] = {
                .fcc            = V4L2_PIX_FMT_Y16,
        },
        {
-               .name           = "RGB Bayer",
+               .name           = "BGGR Bayer (BY8 )",
                .guid           = UVC_GUID_FORMAT_BY8,
                .fcc            = V4L2_PIX_FMT_SBGGR8,
        },
+       {
+               .name           = "BGGR Bayer (BA81)",
+               .guid           = UVC_GUID_FORMAT_BA81,
+               .fcc            = V4L2_PIX_FMT_SBGGR8,
+       },
+       {
+               .name           = "GBRG Bayer (GBRG)",
+               .guid           = UVC_GUID_FORMAT_GBRG,
+               .fcc            = V4L2_PIX_FMT_SGBRG8,
+       },
+       {
+               .name           = "GRBG Bayer (GRBG)",
+               .guid           = UVC_GUID_FORMAT_GRBG,
+               .fcc            = V4L2_PIX_FMT_SGRBG8,
+       },
+       {
+               .name           = "RGGB Bayer (RGGB)",
+               .guid           = UVC_GUID_FORMAT_RGGB,
+               .fcc            = V4L2_PIX_FMT_SRGGB8,
+       },
        {
                .name           = "RGB565",
                .guid           = UVC_GUID_FORMAT_RGBP,
@@ -925,7 +945,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
        case UVC_VC_HEADER:
                n = buflen >= 12 ? buffer[11] : 0;
 
-               if (buflen < 12 || buflen < 12 + n) {
+               if (buflen < 12 + n) {
                        uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
                                "interface %d HEADER error\n", udev->devnum,
                                alts->desc.bInterfaceNumber);
index cd962be860ca3ac14d87dfca467cce021cfa8f4f..6e92d2080255f0353fa6006c210553bb0209ee8d 100644 (file)
@@ -48,12 +48,14 @@ static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
        struct uvc_streaming *stream =
                        container_of(queue, struct uvc_streaming, queue);
 
-       if (*nbuffers > UVC_MAX_VIDEO_BUFFERS)
-               *nbuffers = UVC_MAX_VIDEO_BUFFERS;
+       /* Make sure the image size is large enough. */
+       if (fmt && fmt->fmt.pix.sizeimage < stream->ctrl.dwMaxVideoFrameSize)
+               return -EINVAL;
 
        *nplanes = 1;
 
-       sizes[0] = stream->ctrl.dwMaxVideoFrameSize;
+       sizes[0] = fmt ? fmt->fmt.pix.sizeimage
+                : stream->ctrl.dwMaxVideoFrameSize;
 
        return 0;
 }
@@ -104,15 +106,15 @@ static void uvc_buffer_queue(struct vb2_buffer *vb)
        spin_unlock_irqrestore(&queue->irqlock, flags);
 }
 
-static int uvc_buffer_finish(struct vb2_buffer *vb)
+static void uvc_buffer_finish(struct vb2_buffer *vb)
 {
        struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
        struct uvc_streaming *stream =
                        container_of(queue, struct uvc_streaming, queue);
        struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
 
-       uvc_video_clock_update(stream, &vb->v4l2_buf, buf);
-       return 0;
+       if (vb->state == VB2_BUF_STATE_DONE)
+               uvc_video_clock_update(stream, &vb->v4l2_buf, buf);
 }
 
 static void uvc_wait_prepare(struct vb2_queue *vq)
@@ -149,7 +151,8 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
        queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
        queue->queue.ops = &uvc_queue_qops;
        queue->queue.mem_ops = &vb2_vmalloc_memops;
-       queue->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
+               | V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
        ret = vb2_queue_init(&queue->queue);
        if (ret)
                return ret;
@@ -196,6 +199,18 @@ int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
        return ret;
 }
 
+int uvc_create_buffers(struct uvc_video_queue *queue,
+                      struct v4l2_create_buffers *cb)
+{
+       int ret;
+
+       mutex_lock(&queue->mutex);
+       ret = vb2_create_bufs(&queue->queue, cb);
+       mutex_unlock(&queue->mutex);
+
+       return ret;
+}
+
 int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
 {
        int ret;
index 3afff92804d3c003b986237e385bf4d7c04596ef..378ae02e593b93a19bb9010a23f62175029bbefd 100644 (file)
@@ -1000,6 +1000,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                return uvc_query_buffer(&stream->queue, buf);
        }
 
+       case VIDIOC_CREATE_BUFS:
+       {
+               struct v4l2_create_buffers *cb = arg;
+
+               ret = uvc_acquire_privileges(handle);
+               if (ret < 0)
+                       return ret;
+
+               return uvc_create_buffers(&stream->queue, cb);
+       }
+
        case VIDIOC_QBUF:
                if (!uvc_has_privileges(handle))
                        return -EBUSY;
index 898c208889cd2d55dd5a22522a2d06340eb0891d..8d52baf5952b88ca2529d9b5602c969cd17e5147 100644 (file)
@@ -1453,6 +1453,9 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
        case USB_SPEED_HIGH:
                psize = usb_endpoint_maxp(&ep->desc);
                return (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+       case USB_SPEED_WIRELESS:
+               psize = usb_endpoint_maxp(&ep->desc);
+               return psize;
        default:
                psize = usb_endpoint_maxp(&ep->desc);
                return psize & 0x07ff;
@@ -1847,7 +1850,25 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
 
        if (!enable) {
                uvc_uninit_video(stream, 1);
-               usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+               if (stream->intf->num_altsetting > 1) {
+                       usb_set_interface(stream->dev->udev,
+                                         stream->intfnum, 0);
+               } else {
+                       /* UVC doesn't specify how to inform a bulk-based device
+                        * when the video stream is stopped. Windows sends a
+                        * CLEAR_FEATURE(HALT) request to the video streaming
+                        * bulk endpoint, mimic the same behaviour.
+                        */
+                       unsigned int epnum = stream->header.bEndpointAddress
+                                          & USB_ENDPOINT_NUMBER_MASK;
+                       unsigned int dir = stream->header.bEndpointAddress
+                                        & USB_ENDPOINT_DIR_MASK;
+                       unsigned int pipe;
+
+                       pipe = usb_sndbulkpipe(stream->dev->udev, epnum) | dir;
+                       usb_clear_halt(stream->dev->udev, pipe);
+               }
+
                uvc_queue_enable(&stream->queue, 0);
                uvc_video_clock_cleanup(stream);
                return 0;
index 9e35982d099af2e41ec762e1f16b36506ac5d176..b1f69a6d4068f1c64aec057142efcf02b9b6f82e 100644 (file)
 #define UVC_GUID_FORMAT_BY8 \
        { 'B',  'Y',  '8',  ' ', 0x00, 0x00, 0x10, 0x00, \
         0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_BA81 \
+       { 'B',  'A',  '8',  '1', 0x00, 0x00, 0x10, 0x00, \
+        0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_GBRG \
+       { 'G',  'B',  'R',  'G', 0x00, 0x00, 0x10, 0x00, \
+        0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_GRBG \
+       { 'G',  'R',  'B',  'G', 0x00, 0x00, 0x10, 0x00, \
+        0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_RGGB \
+       { 'R',  'G',  'G',  'B', 0x00, 0x00, 0x10, 0x00, \
+        0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
 #define UVC_GUID_FORMAT_RGBP \
        { 'R',  'G',  'B',  'P', 0x00, 0x00, 0x10, 0x00, \
         0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
 #define UVC_URBS               5
 /* Maximum number of packets per URB. */
 #define UVC_MAX_PACKETS                32
-/* Maximum number of video buffers. */
-#define UVC_MAX_VIDEO_BUFFERS  32
 /* Maximum status buffer size in bytes of interrupt URB. */
 #define UVC_MAX_STATUS_SIZE    16
 
@@ -616,6 +626,8 @@ extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
 extern void uvc_free_buffers(struct uvc_video_queue *queue);
 extern int uvc_query_buffer(struct uvc_video_queue *queue,
                struct v4l2_buffer *v4l2_buf);
+extern int uvc_create_buffers(struct uvc_video_queue *queue,
+               struct v4l2_create_buffers *v4l2_cb);
 extern int uvc_queue_buffer(struct uvc_video_queue *queue,
                struct v4l2_buffer *v4l2_buf);
 extern int uvc_dequeue_buffer(struct uvc_video_queue *queue,
index 6191968db8fa6c0458996ce394e324ba2427c4f6..04b2daf567bec232d384337491543151d890c69a 100644 (file)
@@ -740,7 +740,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
        return 0;
 }
 
-struct v4l2_subdev_edid32 {
+struct v4l2_edid32 {
        __u32 pad;
        __u32 start_block;
        __u32 blocks;
@@ -748,11 +748,11 @@ struct v4l2_subdev_edid32 {
        compat_caddr_t edid;
 };
 
-static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up)
+static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
 {
        u32 tmp;
 
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_subdev_edid32)) ||
+       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) ||
                get_user(kp->pad, &up->pad) ||
                get_user(kp->start_block, &up->start_block) ||
                get_user(kp->blocks, &up->blocks) ||
@@ -763,11 +763,11 @@ static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
        return 0;
 }
 
-static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up)
+static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
 {
        u32 tmp = (u32)((unsigned long)kp->edid);
 
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_subdev_edid32)) ||
+       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) ||
                put_user(kp->pad, &up->pad) ||
                put_user(kp->start_block, &up->start_block) ||
                put_user(kp->blocks, &up->blocks) ||
@@ -787,8 +787,8 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
 #define VIDIOC_DQBUF32         _IOWR('V', 17, struct v4l2_buffer32)
 #define VIDIOC_ENUMSTD32       _IOWR('V', 25, struct v4l2_standard32)
 #define VIDIOC_ENUMINPUT32     _IOWR('V', 26, struct v4l2_input32)
-#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 63, struct v4l2_subdev_edid32)
-#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 64, struct v4l2_subdev_edid32)
+#define VIDIOC_G_EDID32                _IOWR('V', 40, struct v4l2_edid32)
+#define VIDIOC_S_EDID32                _IOWR('V', 41, struct v4l2_edid32)
 #define VIDIOC_TRY_FMT32       _IOWR('V', 64, struct v4l2_format32)
 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
@@ -816,7 +816,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
                struct v4l2_ext_controls v2ecs;
                struct v4l2_event v2ev;
                struct v4l2_create_buffers v2crt;
-               struct v4l2_subdev_edid v2edid;
+               struct v4l2_edid v2edid;
                unsigned long vx;
                int vi;
        } karg;
@@ -849,8 +849,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
        case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
        case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
        case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
-       case VIDIOC_SUBDEV_G_EDID32: cmd = VIDIOC_SUBDEV_G_EDID; break;
-       case VIDIOC_SUBDEV_S_EDID32: cmd = VIDIOC_SUBDEV_S_EDID; break;
+       case VIDIOC_G_EDID32: cmd = VIDIOC_G_EDID; break;
+       case VIDIOC_S_EDID32: cmd = VIDIOC_S_EDID; break;
        }
 
        switch (cmd) {
@@ -868,9 +868,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
                compatible_arg = 0;
                break;
 
-       case VIDIOC_SUBDEV_G_EDID:
-       case VIDIOC_SUBDEV_S_EDID:
-               err = get_v4l2_subdev_edid32(&karg.v2edid, up);
+       case VIDIOC_G_EDID:
+       case VIDIOC_S_EDID:
+               err = get_v4l2_edid32(&karg.v2edid, up);
                compatible_arg = 0;
                break;
 
@@ -966,9 +966,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
                err = put_v4l2_event32(&karg.v2ev, up);
                break;
 
-       case VIDIOC_SUBDEV_G_EDID:
-       case VIDIOC_SUBDEV_S_EDID:
-               err = put_v4l2_subdev_edid32(&karg.v2edid, up);
+       case VIDIOC_G_EDID:
+       case VIDIOC_S_EDID:
+               err = put_v4l2_edid32(&karg.v2edid, up);
                break;
 
        case VIDIOC_G_FMT:
@@ -1006,103 +1006,14 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
        if (!file->f_op->unlocked_ioctl)
                return ret;
 
-       switch (cmd) {
-       case VIDIOC_QUERYCAP:
-       case VIDIOC_RESERVED:
-       case VIDIOC_ENUM_FMT:
-       case VIDIOC_G_FMT32:
-       case VIDIOC_S_FMT32:
-       case VIDIOC_REQBUFS:
-       case VIDIOC_QUERYBUF32:
-       case VIDIOC_G_FBUF32:
-       case VIDIOC_S_FBUF32:
-       case VIDIOC_OVERLAY32:
-       case VIDIOC_QBUF32:
-       case VIDIOC_EXPBUF:
-       case VIDIOC_DQBUF32:
-       case VIDIOC_STREAMON32:
-       case VIDIOC_STREAMOFF32:
-       case VIDIOC_G_PARM:
-       case VIDIOC_S_PARM:
-       case VIDIOC_G_STD:
-       case VIDIOC_S_STD:
-       case VIDIOC_ENUMSTD32:
-       case VIDIOC_ENUMINPUT32:
-       case VIDIOC_G_CTRL:
-       case VIDIOC_S_CTRL:
-       case VIDIOC_G_TUNER:
-       case VIDIOC_S_TUNER:
-       case VIDIOC_G_AUDIO:
-       case VIDIOC_S_AUDIO:
-       case VIDIOC_QUERYCTRL:
-       case VIDIOC_QUERYMENU:
-       case VIDIOC_G_INPUT32:
-       case VIDIOC_S_INPUT32:
-       case VIDIOC_G_OUTPUT32:
-       case VIDIOC_S_OUTPUT32:
-       case VIDIOC_ENUMOUTPUT:
-       case VIDIOC_G_AUDOUT:
-       case VIDIOC_S_AUDOUT:
-       case VIDIOC_G_MODULATOR:
-       case VIDIOC_S_MODULATOR:
-       case VIDIOC_S_FREQUENCY:
-       case VIDIOC_G_FREQUENCY:
-       case VIDIOC_CROPCAP:
-       case VIDIOC_G_CROP:
-       case VIDIOC_S_CROP:
-       case VIDIOC_G_SELECTION:
-       case VIDIOC_S_SELECTION:
-       case VIDIOC_G_JPEGCOMP:
-       case VIDIOC_S_JPEGCOMP:
-       case VIDIOC_QUERYSTD:
-       case VIDIOC_TRY_FMT32:
-       case VIDIOC_ENUMAUDIO:
-       case VIDIOC_ENUMAUDOUT:
-       case VIDIOC_G_PRIORITY:
-       case VIDIOC_S_PRIORITY:
-       case VIDIOC_G_SLICED_VBI_CAP:
-       case VIDIOC_LOG_STATUS:
-       case VIDIOC_G_EXT_CTRLS32:
-       case VIDIOC_S_EXT_CTRLS32:
-       case VIDIOC_TRY_EXT_CTRLS32:
-       case VIDIOC_ENUM_FRAMESIZES:
-       case VIDIOC_ENUM_FRAMEINTERVALS:
-       case VIDIOC_G_ENC_INDEX:
-       case VIDIOC_ENCODER_CMD:
-       case VIDIOC_TRY_ENCODER_CMD:
-       case VIDIOC_DECODER_CMD:
-       case VIDIOC_TRY_DECODER_CMD:
-       case VIDIOC_DBG_S_REGISTER:
-       case VIDIOC_DBG_G_REGISTER:
-       case VIDIOC_S_HW_FREQ_SEEK:
-       case VIDIOC_S_DV_TIMINGS:
-       case VIDIOC_G_DV_TIMINGS:
-       case VIDIOC_DQEVENT:
-       case VIDIOC_DQEVENT32:
-       case VIDIOC_SUBSCRIBE_EVENT:
-       case VIDIOC_UNSUBSCRIBE_EVENT:
-       case VIDIOC_CREATE_BUFS32:
-       case VIDIOC_PREPARE_BUF32:
-       case VIDIOC_ENUM_DV_TIMINGS:
-       case VIDIOC_QUERY_DV_TIMINGS:
-       case VIDIOC_DV_TIMINGS_CAP:
-       case VIDIOC_ENUM_FREQ_BANDS:
-       case VIDIOC_SUBDEV_G_EDID32:
-       case VIDIOC_SUBDEV_S_EDID32:
+       if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
                ret = do_video_ioctl(file, cmd, arg);
-               break;
+       else if (vdev->fops->compat_ioctl32)
+               ret = vdev->fops->compat_ioctl32(file, cmd, arg);
 
-       default:
-               if (vdev->fops->compat_ioctl32)
-                       ret = vdev->fops->compat_ioctl32(file, cmd, arg);
-
-               if (ret == -ENOIOCTLCMD)
-                       printk(KERN_WARNING "compat_ioctl32: "
-                               "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
-                               _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
-                               cmd);
-               break;
-       }
+       if (ret == -ENOIOCTLCMD)
+               pr_warn("compat_ioctl32: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
+                       _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd);
        return ret;
 }
 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
index 6ff002bd5909045e97ed56d51ecb3813877583cb..55c68325410205c68b7f54c3353bc143625814de 100644 (file)
@@ -735,6 +735,8 @@ const char *v4l2_ctrl_get_name(u32 id)
        case V4L2_CID_MPEG_VIDEO_DEC_PTS:                       return "Video Decoder PTS";
        case V4L2_CID_MPEG_VIDEO_DEC_FRAME:                     return "Video Decoder Frame Count";
        case V4L2_CID_MPEG_VIDEO_VBV_DELAY:                     return "Initial Delay for VBV Control";
+       case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:             return "Horizontal MV Search Range";
+       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";
 
        /* VPX controls */
@@ -857,6 +859,17 @@ const char *v4l2_ctrl_get_name(u32 id)
        case V4L2_CID_FM_RX_CLASS:              return "FM Radio Receiver Controls";
        case V4L2_CID_TUNE_DEEMPHASIS:          return "De-Emphasis";
        case V4L2_CID_RDS_RECEPTION:            return "RDS Reception";
+
+       case V4L2_CID_RF_TUNER_CLASS:           return "RF Tuner Controls";
+       case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:   return "LNA Gain, Auto";
+       case V4L2_CID_RF_TUNER_LNA_GAIN:        return "LNA Gain";
+       case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto";
+       case V4L2_CID_RF_TUNER_MIXER_GAIN:      return "Mixer Gain";
+       case V4L2_CID_RF_TUNER_IF_GAIN_AUTO:    return "IF Gain, Auto";
+       case V4L2_CID_RF_TUNER_IF_GAIN:         return "IF Gain";
+       case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:  return "Bandwidth, Auto";
+       case V4L2_CID_RF_TUNER_BANDWIDTH:       return "Bandwidth";
+       case V4L2_CID_RF_TUNER_PLL_LOCK:        return "PLL Lock";
        default:
                return NULL;
        }
@@ -906,10 +919,19 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
        case V4L2_CID_WIDE_DYNAMIC_RANGE:
        case V4L2_CID_IMAGE_STABILIZATION:
        case V4L2_CID_RDS_RECEPTION:
+       case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:
+       case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO:
+       case V4L2_CID_RF_TUNER_IF_GAIN_AUTO:
+       case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
+       case V4L2_CID_RF_TUNER_PLL_LOCK:
                *type = V4L2_CTRL_TYPE_BOOLEAN;
                *min = 0;
                *max = *step = 1;
                break;
+       case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
+       case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
+               *type = V4L2_CTRL_TYPE_INTEGER;
+               break;
        case V4L2_CID_PAN_RESET:
        case V4L2_CID_TILT_RESET:
        case V4L2_CID_FLASH_STROBE:
@@ -991,6 +1013,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
        case V4L2_CID_IMAGE_PROC_CLASS:
        case V4L2_CID_DV_CLASS:
        case V4L2_CID_FM_RX_CLASS:
+       case V4L2_CID_RF_TUNER_CLASS:
                *type = V4L2_CTRL_TYPE_CTRL_CLASS;
                /* You can neither read not write these */
                *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -1063,6 +1086,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
        case V4L2_CID_PILOT_TONE_FREQUENCY:
        case V4L2_CID_TUNE_POWER_LEVEL:
        case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+       case V4L2_CID_RF_TUNER_LNA_GAIN:
+       case V4L2_CID_RF_TUNER_MIXER_GAIN:
+       case V4L2_CID_RF_TUNER_IF_GAIN:
+       case V4L2_CID_RF_TUNER_BANDWIDTH:
                *flags |= V4L2_CTRL_FLAG_SLIDER;
                break;
        case V4L2_CID_PAN_RELATIVE:
@@ -1081,6 +1108,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
        case V4L2_CID_DV_RX_POWER_PRESENT:
                *flags |= V4L2_CTRL_FLAG_READ_ONLY;
                break;
+       case V4L2_CID_RF_TUNER_PLL_LOCK:
+               *flags |= V4L2_CTRL_FLAG_VOLATILE;
+               break;
        }
 }
 EXPORT_SYMBOL(v4l2_ctrl_fill);
@@ -1921,7 +1951,8 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
        int i;
 
        /* The first control is the master control and it must not be NULL */
-       BUG_ON(ncontrols == 0 || controls[0] == NULL);
+       if (WARN_ON(ncontrols == 0 || controls[0] == NULL))
+               return;
 
        for (i = 0; i < ncontrols; i++) {
                if (controls[i]) {
index 0a30dbf3d05c8c1c26086df64ac8382118643d84..634d863c05b4d341cb5453abcedf449d3657eba8 100644 (file)
@@ -554,6 +554,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
        bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER;
        bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
        bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
+       bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
        bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
        bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
 
@@ -662,9 +663,20 @@ static void determine_valid_ioctls(struct video_device *vdev)
                               ops->vidioc_try_fmt_sliced_vbi_out)))
                        set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
                SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
+       } else if (is_sdr) {
+               /* SDR specific ioctls */
+               if (ops->vidioc_enum_fmt_sdr_cap)
+                       set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
+               if (ops->vidioc_g_fmt_sdr_cap)
+                       set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
+               if (ops->vidioc_s_fmt_sdr_cap)
+                       set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
+               if (ops->vidioc_try_fmt_sdr_cap)
+                       set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
        }
-       if (!is_radio) {
-               /* ioctls valid for video or vbi */
+
+       if (is_vid || is_vbi || is_sdr) {
+               /* ioctls valid for video, vbi or sdr */
                SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
                SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
                SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
@@ -672,6 +684,10 @@ static void determine_valid_ioctls(struct video_device *vdev)
                SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
                SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs);
                SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
+       }
+
+       if (is_vid || is_vbi) {
+               /* ioctls valid for video or vbi */
                if (ops->vidioc_s_std)
                        set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
                SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
@@ -685,6 +701,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
                        SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
                        SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
                        SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings);
+                       SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid);
                }
                if (is_tx) {
                        SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
@@ -710,9 +727,10 @@ static void determine_valid_ioctls(struct video_device *vdev)
                SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings);
                SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
                SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
+               SET_VALID_IOCTL(ops, VIDIOC_G_EDID, vidioc_g_edid);
        }
-       if (is_tx) {
-               /* transmitter only ioctls */
+       if (is_tx && (is_radio || is_sdr)) {
+               /* radio transmitter only ioctls */
                SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
                SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
        }
@@ -758,6 +776,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
  *     %VFL_TYPE_RADIO - A radio card
  *
  *     %VFL_TYPE_SUBDEV - A subdevice
+ *
+ *     %VFL_TYPE_SDR - Software Defined Radio
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
                int warn_if_nr_in_use, struct module *owner)
@@ -797,6 +817,10 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
        case VFL_TYPE_SUBDEV:
                name_base = "v4l-subdev";
                break;
+       case VFL_TYPE_SDR:
+               /* Use device name 'swradio' because 'sdr' was already taken. */
+               name_base = "swradio";
+               break;
        default:
                printk(KERN_ERR "%s called with unknown type: %d\n",
                       __func__, type);
index f7902fe8a5267972aa7d2e9daa0b66e81d6727e3..48b20dfcc4d08a59538cb8e7548a3e235f49fe4d 100644 (file)
 #include <linux/v4l2-dv-timings.h>
 #include <media/v4l2-dv-timings.h>
 
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
+MODULE_LICENSE("GPL");
+
 const struct v4l2_dv_timings v4l2_dv_timings_presets[] = {
        V4L2_DV_BT_CEA_640X480P59_94,
        V4L2_DV_BT_CEA_720X480I59_94,
@@ -324,6 +328,10 @@ EXPORT_SYMBOL_GPL(v4l2_print_dv_timings);
  * This function will attempt to detect if the given values correspond to a
  * valid CVT format. If so, then it will return true, and fmt will be filled
  * in with the found CVT timings.
+ *
+ * TODO: VESA defined a new version 2 of their reduced blanking
+ * formula. Support for that is currently missing in this CVT
+ * detection function.
  */
 bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
                u32 polarities, struct v4l2_dv_timings *fmt)
index 707aef705a475bd49fac2cdcf78e06f5e30c5ccd..d9113cc71c7707a391e19246b208ee2e53751ebe 100644 (file)
@@ -152,6 +152,7 @@ const char *v4l2_type_names[] = {
        [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
        [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
        [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
+       [V4L2_BUF_TYPE_SDR_CAPTURE]        = "sdr-cap",
 };
 EXPORT_SYMBOL(v4l2_type_names);
 
@@ -245,6 +246,7 @@ static void v4l_print_format(const void *arg, bool write_only)
        const struct v4l2_vbi_format *vbi;
        const struct v4l2_sliced_vbi_format *sliced;
        const struct v4l2_window *win;
+       const struct v4l2_sdr_format *sdr;
        unsigned i;
 
        pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
@@ -318,6 +320,14 @@ static void v4l_print_format(const void *arg, bool write_only)
                                sliced->service_lines[0][i],
                                sliced->service_lines[1][i]);
                break;
+       case V4L2_BUF_TYPE_SDR_CAPTURE:
+               sdr = &p->fmt.sdr;
+               pr_cont(", pixelformat=%c%c%c%c\n",
+                       (sdr->pixelformat >>  0) & 0xff,
+                       (sdr->pixelformat >>  8) & 0xff,
+                       (sdr->pixelformat >> 16) & 0xff,
+                       (sdr->pixelformat >> 24) & 0xff);
+               break;
        }
 }
 
@@ -834,6 +844,14 @@ static void v4l_print_freq_band(const void *arg, bool write_only)
                        p->rangehigh, p->modulation);
 }
 
+static void v4l_print_edid(const void *arg, bool write_only)
+{
+       const struct v4l2_edid *p = arg;
+
+       pr_cont("pad=%u, start_block=%u, blocks=%u\n",
+               p->pad, p->start_block, p->blocks);
+}
+
 static void v4l_print_u32(const void *arg, bool write_only)
 {
        pr_cont("value=%u\n", *(const u32 *)arg);
@@ -881,6 +899,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
        const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
        bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
+       bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
@@ -930,6 +949,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
                if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
                        return 0;
                break;
+       case V4L2_BUF_TYPE_SDR_CAPTURE:
+               if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
+                       return 0;
+               break;
        default:
                break;
        }
@@ -1049,6 +1072,10 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
                if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane))
                        break;
                return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
+       case V4L2_BUF_TYPE_SDR_CAPTURE:
+               if (unlikely(!is_rx || !ops->vidioc_enum_fmt_sdr_cap))
+                       break;
+               return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
        }
        return -EINVAL;
 }
@@ -1059,6 +1086,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        struct v4l2_format *p = arg;
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+       bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
@@ -1103,6 +1131,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
                if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
                        break;
                return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
+       case V4L2_BUF_TYPE_SDR_CAPTURE:
+               if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
+                       break;
+               return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
        }
        return -EINVAL;
 }
@@ -1113,6 +1145,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
        struct v4l2_format *p = arg;
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+       bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
@@ -1167,6 +1200,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
                        break;
                CLEAR_AFTER_FIELD(p, fmt.sliced);
                return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
+       case V4L2_BUF_TYPE_SDR_CAPTURE:
+               if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
+                       break;
+               CLEAR_AFTER_FIELD(p, fmt.sdr);
+               return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
        }
        return -EINVAL;
 }
@@ -1177,6 +1215,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
        struct v4l2_format *p = arg;
        struct video_device *vfd = video_devdata(file);
        bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+       bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
@@ -1231,6 +1270,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
                        break;
                CLEAR_AFTER_FIELD(p, fmt.sliced);
                return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
+       case V4L2_BUF_TYPE_SDR_CAPTURE:
+               if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
+                       break;
+               CLEAR_AFTER_FIELD(p, fmt.sdr);
+               return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
        }
        return -EINVAL;
 }
@@ -1291,8 +1335,11 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
        struct video_device *vfd = video_devdata(file);
        struct v4l2_frequency *p = arg;
 
-       p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
-                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+       if (vfd->vfl_type == VFL_TYPE_SDR)
+               p->type = V4L2_TUNER_ADC;
+       else
+               p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                               V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        return ops->vidioc_g_frequency(file, fh, p);
 }
 
@@ -1303,10 +1350,15 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
        const struct v4l2_frequency *p = arg;
        enum v4l2_tuner_type type;
 
-       type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
-                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
-       if (p->type != type)
-               return -EINVAL;
+       if (vfd->vfl_type == VFL_TYPE_SDR) {
+               if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+                       return -EINVAL;
+       } else {
+               type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                               V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+               if (type != p->type)
+                       return -EINVAL;
+       }
        return ops->vidioc_s_frequency(file, fh, p);
 }
 
@@ -1386,6 +1438,10 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
        struct v4l2_hw_freq_seek *p = arg;
        enum v4l2_tuner_type type;
 
+       /* s_hw_freq_seek is not supported for SDR for now */
+       if (vfd->vfl_type == VFL_TYPE_SDR)
+               return -EINVAL;
+
        type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
                V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        if (p->type != type)
@@ -1885,11 +1941,16 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
        enum v4l2_tuner_type type;
        int err;
 
-       type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
-                       V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
-
-       if (type != p->type)
-               return -EINVAL;
+       if (vfd->vfl_type == VFL_TYPE_SDR) {
+               if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+                       return -EINVAL;
+               type = p->type;
+       } else {
+               type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+                               V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+               if (type != p->type)
+                       return -EINVAL;
+       }
        if (ops->vidioc_enum_freq_bands)
                return ops->vidioc_enum_freq_bands(file, fh, p);
        if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
@@ -2009,6 +2070,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
        IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
        IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
        IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
+       IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, INFO_FL_CLEAR(v4l2_edid, edid)),
+       IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_edid, edid)),
        IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
        IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
        IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
@@ -2221,9 +2284,9 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
                break;
        }
 
-       case VIDIOC_SUBDEV_G_EDID:
-       case VIDIOC_SUBDEV_S_EDID: {
-               struct v4l2_subdev_edid *edid = parg;
+       case VIDIOC_G_EDID:
+       case VIDIOC_S_EDID: {
+               struct v4l2_edid *edid = parg;
 
                if (edid->blocks) {
                        if (edid->blocks > 256) {
index 996c248dea42bc501497b2b6328321c456373d3b..aea84ac5688a8067c0bcf2088e1e67e2dd1fb5d3 100644 (file)
@@ -349,10 +349,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                        sd, pad, set_selection, subdev_fh, sel);
        }
 
-       case VIDIOC_SUBDEV_G_EDID:
+       case VIDIOC_G_EDID:
                return v4l2_subdev_call(sd, pad, get_edid, arg);
 
-       case VIDIOC_SUBDEV_S_EDID:
+       case VIDIOC_S_EDID:
                return v4l2_subdev_call(sd, pad, set_edid, arg);
 #endif
        default:
@@ -368,6 +368,17 @@ static long subdev_ioctl(struct file *file, unsigned int cmd,
        return video_usercopy(file, cmd, arg, subdev_do_ioctl);
 }
 
+#ifdef CONFIG_COMPAT
+static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,
+       unsigned long arg)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+
+       return v4l2_subdev_call(sd, core, compat_ioctl32, cmd, arg);
+}
+#endif
+
 static unsigned int subdev_poll(struct file *file, poll_table *wait)
 {
        struct video_device *vdev = video_devdata(file);
@@ -389,6 +400,9 @@ const struct v4l2_file_operations v4l2_subdev_fops = {
        .owner = THIS_MODULE,
        .open = subdev_open,
        .unlocked_ioctl = subdev_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl32 = subdev_compat_ioctl32,
+#endif
        .release = subdev_close,
        .poll = subdev_poll,
 };
index a127925c9d61da6f92a93fb49d6e6f01f03e0e25..f9059bb73840acb8ebed02e9099ce445fc932d3d 100644 (file)
@@ -33,17 +33,74 @@ module_param(debug, int, 0644);
                        printk(KERN_DEBUG "vb2: " fmt, ## arg);         \
        } while (0)
 
-#define call_memop(q, op, args...)                                     \
-       (((q)->mem_ops->op) ?                                           \
-               ((q)->mem_ops->op(args)) : 0)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+/*
+ * If advanced debugging is on, then count how often each op is called,
+ * which can either be per-buffer or per-queue.
+ *
+ * If the op failed then the 'fail_' variant is called to decrease the
+ * counter. That makes it easy to check that the 'init' and 'cleanup'
+ * (and variations thereof) stay balanced.
+ */
+
+#define call_memop(vb, op, args...)                                    \
+({                                                                     \
+       struct vb2_queue *_q = (vb)->vb2_queue;                         \
+       dprintk(2, "call_memop(%p, %d, %s)%s\n",                        \
+               _q, (vb)->v4l2_buf.index, #op,                          \
+               _q->mem_ops->op ? "" : " (nop)");                       \
+       (vb)->cnt_mem_ ## op++;                                         \
+       _q->mem_ops->op ? _q->mem_ops->op(args) : 0;                    \
+})
+#define fail_memop(vb, op) ((vb)->cnt_mem_ ## op--)
+
+#define call_qop(q, op, args...)                                       \
+({                                                                     \
+       dprintk(2, "call_qop(%p, %s)%s\n", q, #op,                      \
+               (q)->ops->op ? "" : " (nop)");                          \
+       (q)->cnt_ ## op++;                                              \
+       (q)->ops->op ? (q)->ops->op(args) : 0;                          \
+})
+#define fail_qop(q, op) ((q)->cnt_ ## op--)
+
+#define call_vb_qop(vb, op, args...)                                   \
+({                                                                     \
+       struct vb2_queue *_q = (vb)->vb2_queue;                         \
+       dprintk(2, "call_vb_qop(%p, %d, %s)%s\n",                       \
+               _q, (vb)->v4l2_buf.index, #op,                          \
+               _q->ops->op ? "" : " (nop)");                           \
+       (vb)->cnt_ ## op++;                                             \
+       _q->ops->op ? _q->ops->op(args) : 0;                            \
+})
+#define fail_vb_qop(vb, op) ((vb)->cnt_ ## op--)
+
+#else
+
+#define call_memop(vb, op, args...)                                    \
+       ((vb)->vb2_queue->mem_ops->op ? (vb)->vb2_queue->mem_ops->op(args) : 0)
+#define fail_memop(vb, op)
 
 #define call_qop(q, op, args...)                                       \
-       (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
+       ((q)->ops->op ? (q)->ops->op(args) : 0)
+#define fail_qop(q, op)
 
+#define call_vb_qop(vb, op, args...)                                   \
+       ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
+#define fail_vb_qop(vb, op)
+
+#endif
+
+/* Flags that are set by the vb2 core */
 #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_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 | \
+                                V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
+
+static void __vb2_queue_cancel(struct vb2_queue *q);
 
 /**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
@@ -61,7 +118,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
        for (plane = 0; plane < vb->num_planes; ++plane) {
                unsigned long size = PAGE_ALIGN(q->plane_sizes[plane]);
 
-               mem_priv = call_memop(q, alloc, q->alloc_ctx[plane],
+               mem_priv = call_memop(vb, alloc, q->alloc_ctx[plane],
                                      size, q->gfp_flags);
                if (IS_ERR_OR_NULL(mem_priv))
                        goto free;
@@ -73,9 +130,10 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
 
        return 0;
 free:
+       fail_memop(vb, alloc);
        /* Free already allocated memory if one of the allocations failed */
        for (; plane > 0; --plane) {
-               call_memop(q, put, vb->planes[plane - 1].mem_priv);
+               call_memop(vb, put, vb->planes[plane - 1].mem_priv);
                vb->planes[plane - 1].mem_priv = NULL;
        }
 
@@ -87,11 +145,10 @@ free:
  */
 static void __vb2_buf_mem_free(struct vb2_buffer *vb)
 {
-       struct vb2_queue *q = vb->vb2_queue;
        unsigned int plane;
 
        for (plane = 0; plane < vb->num_planes; ++plane) {
-               call_memop(q, put, vb->planes[plane].mem_priv);
+               call_memop(vb, put, vb->planes[plane].mem_priv);
                vb->planes[plane].mem_priv = NULL;
                dprintk(3, "Freed plane %d of buffer %d\n", plane,
                        vb->v4l2_buf.index);
@@ -104,12 +161,11 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb)
  */
 static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 {
-       struct vb2_queue *q = vb->vb2_queue;
        unsigned int plane;
 
        for (plane = 0; plane < vb->num_planes; ++plane) {
                if (vb->planes[plane].mem_priv)
-                       call_memop(q, put_userptr, vb->planes[plane].mem_priv);
+                       call_memop(vb, put_userptr, vb->planes[plane].mem_priv);
                vb->planes[plane].mem_priv = NULL;
        }
 }
@@ -118,15 +174,15 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
  * __vb2_plane_dmabuf_put() - release memory associated with
  * a DMABUF shared plane
  */
-static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p)
 {
        if (!p->mem_priv)
                return;
 
        if (p->dbuf_mapped)
-               call_memop(q, unmap_dmabuf, p->mem_priv);
+               call_memop(vb, unmap_dmabuf, p->mem_priv);
 
-       call_memop(q, detach_dmabuf, p->mem_priv);
+       call_memop(vb, detach_dmabuf, p->mem_priv);
        dma_buf_put(p->dbuf);
        memset(p, 0, sizeof(*p));
 }
@@ -137,11 +193,10 @@ static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
  */
 static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
 {
-       struct vb2_queue *q = vb->vb2_queue;
        unsigned int plane;
 
        for (plane = 0; plane < vb->num_planes; ++plane)
-               __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+               __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
 }
 
 /**
@@ -246,10 +301,11 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
                         * callback, if given. An error in initialization
                         * results in queue setup failure.
                         */
-                       ret = call_qop(q, buf_init, vb);
+                       ret = call_vb_qop(vb, buf_init, vb);
                        if (ret) {
                                dprintk(1, "Buffer %d %p initialization"
                                        " failed\n", buffer, vb);
+                               fail_vb_qop(vb, buf_init);
                                __vb2_buf_mem_free(vb);
                                kfree(vb);
                                break;
@@ -321,18 +377,79 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
        }
 
        /* Call driver-provided cleanup function for each buffer, if provided */
-       if (q->ops->buf_cleanup) {
-               for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
-                    ++buffer) {
-                       if (NULL == q->bufs[buffer])
-                               continue;
-                       q->ops->buf_cleanup(q->bufs[buffer]);
-               }
+       for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+            ++buffer) {
+               struct vb2_buffer *vb = q->bufs[buffer];
+
+               if (vb && vb->planes[0].mem_priv)
+                       call_vb_qop(vb, buf_cleanup, vb);
        }
 
        /* Release video buffer memory */
        __vb2_free_mem(q, buffers);
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       /*
+        * Check that all the calls were balances during the life-time of this
+        * queue. If not (or if the debug level is 1 or up), then dump the
+        * counters to the kernel log.
+        */
+       if (q->num_buffers) {
+               bool unbalanced = q->cnt_start_streaming != q->cnt_stop_streaming ||
+                                 q->cnt_wait_prepare != q->cnt_wait_finish;
+
+               if (unbalanced || debug) {
+                       pr_info("vb2: counters for queue %p:%s\n", q,
+                               unbalanced ? " UNBALANCED!" : "");
+                       pr_info("vb2:     setup: %u start_streaming: %u stop_streaming: %u\n",
+                               q->cnt_queue_setup, q->cnt_start_streaming,
+                               q->cnt_stop_streaming);
+                       pr_info("vb2:     wait_prepare: %u wait_finish: %u\n",
+                               q->cnt_wait_prepare, q->cnt_wait_finish);
+               }
+               q->cnt_queue_setup = 0;
+               q->cnt_wait_prepare = 0;
+               q->cnt_wait_finish = 0;
+               q->cnt_start_streaming = 0;
+               q->cnt_stop_streaming = 0;
+       }
+       for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+               struct vb2_buffer *vb = q->bufs[buffer];
+               bool unbalanced = vb->cnt_mem_alloc != vb->cnt_mem_put ||
+                                 vb->cnt_mem_prepare != vb->cnt_mem_finish ||
+                                 vb->cnt_mem_get_userptr != vb->cnt_mem_put_userptr ||
+                                 vb->cnt_mem_attach_dmabuf != vb->cnt_mem_detach_dmabuf ||
+                                 vb->cnt_mem_map_dmabuf != vb->cnt_mem_unmap_dmabuf ||
+                                 vb->cnt_buf_queue != vb->cnt_buf_done ||
+                                 vb->cnt_buf_prepare != vb->cnt_buf_finish ||
+                                 vb->cnt_buf_init != vb->cnt_buf_cleanup;
+
+               if (unbalanced || debug) {
+                       pr_info("vb2:   counters for queue %p, buffer %d:%s\n",
+                               q, buffer, unbalanced ? " UNBALANCED!" : "");
+                       pr_info("vb2:     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("vb2:     buf_queue: %u buf_done: %u\n",
+                               vb->cnt_buf_queue, vb->cnt_buf_done);
+                       pr_info("vb2:     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,
+                               vb->cnt_mem_mmap);
+                       pr_info("vb2:     get_userptr: %u put_userptr: %u\n",
+                               vb->cnt_mem_get_userptr, vb->cnt_mem_put_userptr);
+                       pr_info("vb2:     attach_dmabuf: %u detach_dmabuf: %u map_dmabuf: %u unmap_dmabuf: %u\n",
+                               vb->cnt_mem_attach_dmabuf, vb->cnt_mem_detach_dmabuf,
+                               vb->cnt_mem_map_dmabuf, vb->cnt_mem_unmap_dmabuf);
+                       pr_info("vb2:     get_dmabuf: %u num_users: %u vaddr: %u cookie: %u\n",
+                               vb->cnt_mem_get_dmabuf,
+                               vb->cnt_mem_num_users,
+                               vb->cnt_mem_vaddr,
+                               vb->cnt_mem_cookie);
+               }
+       }
+#endif
+
        /* Free videobuf buffers */
        for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
             ++buffer) {
@@ -341,9 +458,10 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
        }
 
        q->num_buffers -= buffers;
-       if (!q->num_buffers)
+       if (!q->num_buffers) {
                q->memory = 0;
-       INIT_LIST_HEAD(&q->queued_list);
+               INIT_LIST_HEAD(&q->queued_list);
+       }
        return 0;
 }
 
@@ -424,7 +542,7 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
                 * case anyway. If num_users() returns more than 1,
                 * we are not the only user of the plane's memory.
                 */
-               if (mem_priv && call_memop(q, num_users, mem_priv) > 1)
+               if (mem_priv && call_memop(vb, num_users, mem_priv) > 1)
                        return true;
        }
        return false;
@@ -484,7 +602,16 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
         * Clear any buffer state related flags.
         */
        b->flags &= ~V4L2_BUFFER_MASK_FLAGS;
-       b->flags |= q->timestamp_type;
+       b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK;
+       if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
+           V4L2_BUF_FLAG_TIMESTAMP_COPY) {
+               /*
+                * For non-COPY timestamps, drop timestamp source bits
+                * and obtain the timestamp source from the queue.
+                */
+               b->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+               b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       }
 
        switch (vb->state) {
        case VB2_BUF_STATE_QUEUED:
@@ -677,6 +804,12 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
                        return -EBUSY;
                }
 
+               /*
+                * Call queue_cancel to clean up any buffers in the PREPARED or
+                * QUEUED state which is possible if buffers were prepared or
+                * queued without ever calling STREAMON.
+                */
+               __vb2_queue_cancel(q);
                ret = __vb2_queue_free(q, q->num_buffers);
                if (ret)
                        return ret;
@@ -693,6 +826,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
         * Make sure the requested values and current defaults are sane.
         */
        num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
+       num_buffers = max_t(unsigned int, req->count, q->min_buffers_needed);
        memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
        memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
        q->memory = req->memory;
@@ -703,26 +837,35 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
         */
        ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
                       q->plane_sizes, q->alloc_ctx);
-       if (ret)
+       if (ret) {
+               fail_qop(q, queue_setup);
                return ret;
+       }
 
        /* Finally, allocate buffers and video memory */
-       ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes);
-       if (ret == 0) {
+       allocated_buffers = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes);
+       if (allocated_buffers == 0) {
                dprintk(1, "Memory allocation failed\n");
                return -ENOMEM;
        }
 
-       allocated_buffers = ret;
+       /*
+        * There is no point in continuing if we can't allocate the minimum
+        * number of buffers needed by this vb2_queue.
+        */
+       if (allocated_buffers < q->min_buffers_needed)
+               ret = -ENOMEM;
 
        /*
         * Check if driver can handle the allocated number of buffers.
         */
-       if (allocated_buffers < num_buffers) {
+       if (!ret && allocated_buffers < num_buffers) {
                num_buffers = allocated_buffers;
 
                ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
                               &num_planes, q->plane_sizes, q->alloc_ctx);
+               if (ret)
+                       fail_qop(q, queue_setup);
 
                if (!ret && allocated_buffers < num_buffers)
                        ret = -ENOMEM;
@@ -736,6 +879,10 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
        q->num_buffers = allocated_buffers;
 
        if (ret < 0) {
+               /*
+                * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+                * from q->num_buffers.
+                */
                __vb2_queue_free(q, allocated_buffers);
                return ret;
        }
@@ -803,24 +950,24 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
         */
        ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
                       &num_planes, q->plane_sizes, q->alloc_ctx);
-       if (ret)
+       if (ret) {
+               fail_qop(q, queue_setup);
                return ret;
+       }
 
        /* Finally, allocate buffers and video memory */
-       ret = __vb2_queue_alloc(q, create->memory, num_buffers,
+       allocated_buffers = __vb2_queue_alloc(q, create->memory, num_buffers,
                                num_planes);
-       if (ret == 0) {
+       if (allocated_buffers == 0) {
                dprintk(1, "Memory allocation failed\n");
                return -ENOMEM;
        }
 
-       allocated_buffers = ret;
-
        /*
         * Check if driver can handle the so far allocated number of buffers.
         */
-       if (ret < num_buffers) {
-               num_buffers = ret;
+       if (allocated_buffers < num_buffers) {
+               num_buffers = allocated_buffers;
 
                /*
                 * q->num_buffers contains the total number of buffers, that the
@@ -828,6 +975,8 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
                 */
                ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
                               &num_planes, q->plane_sizes, q->alloc_ctx);
+               if (ret)
+                       fail_qop(q, queue_setup);
 
                if (!ret && allocated_buffers < num_buffers)
                        ret = -ENOMEM;
@@ -841,6 +990,10 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
        q->num_buffers += allocated_buffers;
 
        if (ret < 0) {
+               /*
+                * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+                * from q->num_buffers.
+                */
                __vb2_queue_free(q, allocated_buffers);
                return -ENOMEM;
        }
@@ -882,12 +1035,10 @@ EXPORT_SYMBOL_GPL(vb2_create_bufs);
  */
 void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
 {
-       struct vb2_queue *q = vb->vb2_queue;
-
        if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv)
                return NULL;
 
-       return call_memop(q, vaddr, vb->planes[plane_no].mem_priv);
+       return call_memop(vb, vaddr, vb->planes[plane_no].mem_priv);
 
 }
 EXPORT_SYMBOL_GPL(vb2_plane_vaddr);
@@ -905,12 +1056,10 @@ EXPORT_SYMBOL_GPL(vb2_plane_vaddr);
  */
 void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
 {
-       struct vb2_queue *q = vb->vb2_queue;
-
        if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv)
                return NULL;
 
-       return call_memop(q, cookie, vb->planes[plane_no].mem_priv);
+       return call_memop(vb, cookie, vb->planes[plane_no].mem_priv);
 }
 EXPORT_SYMBOL_GPL(vb2_plane_cookie);
 
@@ -918,13 +1067,20 @@ EXPORT_SYMBOL_GPL(vb2_plane_cookie);
  * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
  * @vb:                vb2_buffer returned from the driver
  * @state:     either VB2_BUF_STATE_DONE if the operation finished successfully
- *             or VB2_BUF_STATE_ERROR if the operation finished with an error
+ *             or VB2_BUF_STATE_ERROR if the operation finished with an error.
+ *             If start_streaming fails then it should return buffers with state
+ *             VB2_BUF_STATE_QUEUED to put them back into the queue.
  *
  * This function should be called by the driver after a hardware operation on
  * a buffer is finished and the buffer may be returned to userspace. The driver
  * cannot use this buffer anymore until it is queued back to it by videobuf
  * by the means of buf_queue callback. Only buffers previously queued to the
  * driver by buf_queue can be passed to this function.
+ *
+ * While streaming a buffer can only be returned in state DONE or ERROR.
+ * The start_streaming op can also return them in case the DMA engine cannot
+ * be started for some reason. In that case the buffers should be returned with
+ * state QUEUED.
  */
 void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
 {
@@ -932,26 +1088,43 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
        unsigned long flags;
        unsigned int plane;
 
-       if (vb->state != VB2_BUF_STATE_ACTIVE)
+       if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))
                return;
 
-       if (state != VB2_BUF_STATE_DONE && state != VB2_BUF_STATE_ERROR)
-               return;
+       if (!q->start_streaming_called) {
+               if (WARN_ON(state != VB2_BUF_STATE_QUEUED))
+                       state = VB2_BUF_STATE_QUEUED;
+       } else if (!WARN_ON(!q->start_streaming_called)) {
+               if (WARN_ON(state != VB2_BUF_STATE_DONE &&
+                           state != VB2_BUF_STATE_ERROR))
+                       state = VB2_BUF_STATE_ERROR;
+       }
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       /*
+        * Although this is not a callback, it still does have to balance
+        * with the buf_queue op. So update this counter manually.
+        */
+       vb->cnt_buf_done++;
+#endif
        dprintk(4, "Done processing on buffer %d, state: %d\n",
                        vb->v4l2_buf.index, state);
 
        /* sync buffers */
        for (plane = 0; plane < vb->num_planes; ++plane)
-               call_memop(q, finish, vb->planes[plane].mem_priv);
+               call_memop(vb, finish, vb->planes[plane].mem_priv);
 
        /* Add the buffer to the done buffers list */
        spin_lock_irqsave(&q->done_lock, flags);
        vb->state = state;
-       list_add_tail(&vb->done_entry, &q->done_list);
-       atomic_dec(&q->queued_count);
+       if (state != VB2_BUF_STATE_QUEUED)
+               list_add_tail(&vb->done_entry, &q->done_list);
+       atomic_dec(&q->owned_by_drv_count);
        spin_unlock_irqrestore(&q->done_lock, flags);
 
+       if (state == VB2_BUF_STATE_QUEUED)
+               return;
+
        /* Inform any processes that may be waiting for buffers */
        wake_up(&q->done_wq);
 }
@@ -1025,9 +1198,31 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
 
        }
 
-       vb->v4l2_buf.field = b->field;
-       vb->v4l2_buf.timestamp = b->timestamp;
+       /* Zero flags that the vb2 core handles */
        vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
+       if ((vb->vb2_queue->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
+           V4L2_BUF_FLAG_TIMESTAMP_COPY || !V4L2_TYPE_IS_OUTPUT(b->type)) {
+               /*
+                * Non-COPY timestamps and non-OUTPUT queues will get
+                * their timestamp and timestamp source flags from the
+                * queue.
+                */
+               vb->v4l2_buf.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_internal_qbuf().
+                * The 'field' is valid metadata for this output buffer
+                * and so that needs to be copied here.
+                */
+               vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE;
+               vb->v4l2_buf.field = b->field;
+       } else {
+               /* Zero any output buffer flags as this is a capture buffer */
+               vb->v4l2_buf.flags &= ~V4L2_BUFFER_OUT_FLAGS;
+       }
 }
 
 /**
@@ -1041,6 +1236,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        unsigned int plane;
        int ret;
        int write = !V4L2_TYPE_IS_OUTPUT(q->type);
+       bool reacquired = vb->planes[0].mem_priv == NULL;
 
        /* Copy relevant information provided by the userspace */
        __fill_vb2_buffer(vb, b, planes);
@@ -1066,36 +1262,31 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
                }
 
                /* Release previously acquired memory if present */
-               if (vb->planes[plane].mem_priv)
-                       call_memop(q, put_userptr, vb->planes[plane].mem_priv);
+               if (vb->planes[plane].mem_priv) {
+                       if (!reacquired) {
+                               reacquired = true;
+                               call_vb_qop(vb, buf_cleanup, vb);
+                       }
+                       call_memop(vb, put_userptr, vb->planes[plane].mem_priv);
+               }
 
                vb->planes[plane].mem_priv = NULL;
-               vb->v4l2_planes[plane].m.userptr = 0;
-               vb->v4l2_planes[plane].length = 0;
+               memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
 
                /* Acquire each plane's memory */
-               mem_priv = call_memop(q, get_userptr, q->alloc_ctx[plane],
+               mem_priv = call_memop(vb, get_userptr, q->alloc_ctx[plane],
                                      planes[plane].m.userptr,
                                      planes[plane].length, write);
                if (IS_ERR_OR_NULL(mem_priv)) {
                        dprintk(1, "qbuf: failed acquiring userspace "
                                                "memory for plane %d\n", plane);
+                       fail_memop(vb, get_userptr);
                        ret = mem_priv ? PTR_ERR(mem_priv) : -EINVAL;
                        goto err;
                }
                vb->planes[plane].mem_priv = mem_priv;
        }
 
-       /*
-        * Call driver-specific initialization on the newly acquired buffer,
-        * if provided.
-        */
-       ret = call_qop(q, buf_init, vb);
-       if (ret) {
-               dprintk(1, "qbuf: buffer initialization failed\n");
-               goto err;
-       }
-
        /*
         * Now that everything is in order, copy relevant information
         * provided by userspace.
@@ -1103,12 +1294,34 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        for (plane = 0; plane < vb->num_planes; ++plane)
                vb->v4l2_planes[plane] = planes[plane];
 
+       if (reacquired) {
+               /*
+                * One or more planes changed, so we must call buf_init to do
+                * the driver-specific initialization on the newly acquired
+                * buffer, if provided.
+                */
+               ret = call_vb_qop(vb, buf_init, vb);
+               if (ret) {
+                       dprintk(1, "qbuf: buffer initialization failed\n");
+                       fail_vb_qop(vb, buf_init);
+                       goto err;
+               }
+       }
+
+       ret = call_vb_qop(vb, buf_prepare, vb);
+       if (ret) {
+               dprintk(1, "qbuf: buffer preparation failed\n");
+               fail_vb_qop(vb, buf_prepare);
+               call_vb_qop(vb, buf_cleanup, vb);
+               goto err;
+       }
+
        return 0;
 err:
        /* In case of errors, release planes that were already acquired */
        for (plane = 0; plane < vb->num_planes; ++plane) {
                if (vb->planes[plane].mem_priv)
-                       call_memop(q, put_userptr, vb->planes[plane].mem_priv);
+                       call_memop(vb, put_userptr, vb->planes[plane].mem_priv);
                vb->planes[plane].mem_priv = NULL;
                vb->v4l2_planes[plane].m.userptr = 0;
                vb->v4l2_planes[plane].length = 0;
@@ -1122,8 +1335,13 @@ err:
  */
 static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
+       int ret;
+
        __fill_vb2_buffer(vb, b, vb->v4l2_planes);
-       return 0;
+       ret = call_vb_qop(vb, buf_prepare, vb);
+       if (ret)
+               fail_vb_qop(vb, buf_prepare);
+       return ret;
 }
 
 /**
@@ -1137,6 +1355,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        unsigned int plane;
        int ret;
        int write = !V4L2_TYPE_IS_OUTPUT(q->type);
+       bool reacquired = vb->planes[0].mem_priv == NULL;
 
        /* Copy relevant information provided by the userspace */
        __fill_vb2_buffer(vb, b, planes);
@@ -1172,15 +1391,21 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 
                dprintk(1, "qbuf: buffer for plane %d changed\n", plane);
 
+               if (!reacquired) {
+                       reacquired = true;
+                       call_vb_qop(vb, buf_cleanup, vb);
+               }
+
                /* Release previously acquired memory if present */
-               __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+               __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
                memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
 
                /* Acquire each plane's memory */
-               mem_priv = call_memop(q, attach_dmabuf, q->alloc_ctx[plane],
+               mem_priv = call_memop(vb, attach_dmabuf, q->alloc_ctx[plane],
                        dbuf, planes[plane].length, write);
                if (IS_ERR(mem_priv)) {
                        dprintk(1, "qbuf: failed to attach dmabuf\n");
+                       fail_memop(vb, attach_dmabuf);
                        ret = PTR_ERR(mem_priv);
                        dma_buf_put(dbuf);
                        goto err;
@@ -1195,25 +1420,16 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
         * the buffer(s)..
         */
        for (plane = 0; plane < vb->num_planes; ++plane) {
-               ret = call_memop(q, map_dmabuf, vb->planes[plane].mem_priv);
+               ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
                if (ret) {
                        dprintk(1, "qbuf: failed to map dmabuf for plane %d\n",
                                plane);
+                       fail_memop(vb, map_dmabuf);
                        goto err;
                }
                vb->planes[plane].dbuf_mapped = 1;
        }
 
-       /*
-        * Call driver-specific initialization on the newly acquired buffer,
-        * if provided.
-        */
-       ret = call_qop(q, buf_init, vb);
-       if (ret) {
-               dprintk(1, "qbuf: buffer initialization failed\n");
-               goto err;
-       }
-
        /*
         * Now that everything is in order, copy relevant information
         * provided by userspace.
@@ -1221,6 +1437,27 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        for (plane = 0; plane < vb->num_planes; ++plane)
                vb->v4l2_planes[plane] = planes[plane];
 
+       if (reacquired) {
+               /*
+                * Call driver-specific initialization on the newly acquired buffer,
+                * if provided.
+                */
+               ret = call_vb_qop(vb, buf_init, vb);
+               if (ret) {
+                       dprintk(1, "qbuf: buffer initialization failed\n");
+                       fail_vb_qop(vb, buf_init);
+                       goto err;
+               }
+       }
+
+       ret = call_vb_qop(vb, buf_prepare, vb);
+       if (ret) {
+               dprintk(1, "qbuf: buffer preparation failed\n");
+               fail_vb_qop(vb, buf_prepare);
+               call_vb_qop(vb, buf_cleanup, vb);
+               goto err;
+       }
+
        return 0;
 err:
        /* In case of errors, release planes that were already acquired */
@@ -1238,13 +1475,13 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
        unsigned int plane;
 
        vb->state = VB2_BUF_STATE_ACTIVE;
-       atomic_inc(&q->queued_count);
+       atomic_inc(&q->owned_by_drv_count);
 
        /* sync buffers */
        for (plane = 0; plane < vb->num_planes; ++plane)
-               call_memop(q, prepare, vb->planes[plane].mem_priv);
+               call_memop(vb, prepare, vb->planes[plane].mem_priv);
 
-       q->ops->buf_queue(vb);
+       call_vb_qop(vb, buf_queue, vb);
 }
 
 static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
@@ -1261,6 +1498,10 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        }
 
        vb->state = VB2_BUF_STATE_PREPARING;
+       vb->v4l2_buf.timestamp.tv_sec = 0;
+       vb->v4l2_buf.timestamp.tv_usec = 0;
+       vb->v4l2_buf.sequence = 0;
+
        switch (q->memory) {
        case V4L2_MEMORY_MMAP:
                ret = __qbuf_mmap(vb, b);
@@ -1295,8 +1536,6 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
                ret = -EINVAL;
        }
 
-       if (!ret)
-               ret = call_qop(q, buf_prepare, vb);
        if (ret)
                dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
        vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED;
@@ -1382,32 +1621,49 @@ EXPORT_SYMBOL_GPL(vb2_prepare_buf);
  * vb2_start_streaming() - Attempt to start streaming.
  * @q:         videobuf2 queue
  *
- * If there are not enough buffers, then retry_start_streaming is set to
- * 1 and 0 is returned. The next time a buffer is queued and
- * retry_start_streaming is 1, this function will be called again to
- * retry starting the DMA engine.
+ * Attempt to start streaming. When this function is called there must be
+ * at least q->min_buffers_needed buffers queued up (i.e. the minimum
+ * number of buffers required for the DMA engine to function). If the
+ * @start_streaming op fails it is supposed to return all the driver-owned
+ * buffers back to vb2 in state QUEUED. Check if that happened and if
+ * not warn and reclaim them forcefully.
  */
 static int vb2_start_streaming(struct vb2_queue *q)
 {
+       struct vb2_buffer *vb;
        int ret;
 
-       /* Tell the driver to start streaming */
-       ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
-
        /*
-        * If there are not enough buffers queued to start streaming, then
-        * the start_streaming operation will return -ENOBUFS and you have to
-        * retry when the next buffer is queued.
+        * If any buffers were queued before streamon,
+        * we can now pass them to driver for processing.
         */
-       if (ret == -ENOBUFS) {
-               dprintk(1, "qbuf: not enough buffers, retry when more buffers are queued.\n");
-               q->retry_start_streaming = 1;
+       list_for_each_entry(vb, &q->queued_list, queued_entry)
+               __enqueue_in_driver(vb);
+
+       /* Tell the driver to start streaming */
+       ret = call_qop(q, start_streaming, q,
+                      atomic_read(&q->owned_by_drv_count));
+       q->start_streaming_called = ret == 0;
+       if (!ret)
                return 0;
+
+       fail_qop(q, start_streaming);
+       dprintk(1, "qbuf: driver refused to start streaming\n");
+       if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
+               unsigned i;
+
+               /*
+                * Forcefully reclaim buffers if the driver did not
+                * correctly return them to vb2.
+                */
+               for (i = 0; i < q->num_buffers; ++i) {
+                       vb = q->bufs[i];
+                       if (vb->state == VB2_BUF_STATE_ACTIVE)
+                               vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED);
+               }
+               /* Must be zero now */
+               WARN_ON(atomic_read(&q->owned_by_drv_count));
        }
-       if (ret)
-               dprintk(1, "qbuf: driver refused to start streaming\n");
-       else
-               q->retry_start_streaming = 0;
        return ret;
 }
 
@@ -1420,11 +1676,6 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
                return ret;
 
        vb = q->bufs[b->index];
-       if (vb->state != VB2_BUF_STATE_DEQUEUED) {
-               dprintk(1, "%s(): invalid buffer state %d\n", __func__,
-                       vb->state);
-               return -EINVAL;
-       }
 
        switch (vb->state) {
        case VB2_BUF_STATE_DEQUEUED:
@@ -1438,7 +1689,8 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
                dprintk(1, "qbuf: buffer still being prepared\n");
                return -EINVAL;
        default:
-               dprintk(1, "qbuf: buffer already in use\n");
+               dprintk(1, "%s(): invalid buffer state %d\n", __func__,
+                       vb->state);
                return -EINVAL;
        }
 
@@ -1447,19 +1699,39 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
         * dequeued in dqbuf.
         */
        list_add_tail(&vb->queued_entry, &q->queued_list);
+       q->queued_count++;
        vb->state = VB2_BUF_STATE_QUEUED;
+       if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+               /*
+                * For output buffers copy the timestamp if needed,
+                * and the timecode field and flag if needed.
+                */
+               if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
+                   V4L2_BUF_FLAG_TIMESTAMP_COPY)
+                       vb->v4l2_buf.timestamp = b->timestamp;
+               vb->v4l2_buf.flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
+               if (b->flags & V4L2_BUF_FLAG_TIMECODE)
+                       vb->v4l2_buf.timecode = b->timecode;
+       }
 
        /*
         * If already streaming, give the buffer to driver for processing.
         * If not, the buffer will be given to driver on next streamon.
         */
-       if (q->streaming)
+       if (q->start_streaming_called)
                __enqueue_in_driver(vb);
 
        /* Fill buffer information for the userspace */
        __fill_v4l2_buffer(vb, b);
 
-       if (q->retry_start_streaming) {
+       /*
+        * If streamon has been called, and we haven't yet called
+        * start_streaming() since not enough buffers were queued, and
+        * we now have reached the minimum number of queued buffers,
+        * then we can finally call start_streaming().
+        */
+       if (q->streaming && !q->start_streaming_called &&
+           q->queued_count >= q->min_buffers_needed) {
                ret = vb2_start_streaming(q);
                if (ret)
                        return ret;
@@ -1614,8 +1886,8 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q)
                return -EINVAL;
        }
 
-       if (!q->retry_start_streaming)
-               wait_event(q->done_wq, !atomic_read(&q->queued_count));
+       if (q->start_streaming_called)
+               wait_event(q->done_wq, !atomic_read(&q->owned_by_drv_count));
        return 0;
 }
 EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
@@ -1639,7 +1911,7 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
                for (i = 0; i < vb->num_planes; ++i) {
                        if (!vb->planes[i].dbuf_mapped)
                                continue;
-                       call_memop(q, unmap_dmabuf, vb->planes[i].mem_priv);
+                       call_memop(vb, unmap_dmabuf, vb->planes[i].mem_priv);
                        vb->planes[i].dbuf_mapped = 0;
                }
 }
@@ -1657,12 +1929,6 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
        if (ret < 0)
                return ret;
 
-       ret = call_qop(q, buf_finish, vb);
-       if (ret) {
-               dprintk(1, "dqbuf: buffer finish failed\n");
-               return ret;
-       }
-
        switch (vb->state) {
        case VB2_BUF_STATE_DONE:
                dprintk(3, "dqbuf: Returning done buffer\n");
@@ -1675,10 +1941,13 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
                return -EINVAL;
        }
 
+       call_vb_qop(vb, buf_finish, vb);
+
        /* Fill buffer information for the userspace */
        __fill_v4l2_buffer(vb, b);
        /* Remove from videobuf queue */
        list_del(&vb->queued_entry);
+       q->queued_count--;
        /* go back to dequeued state */
        __vb2_dqbuf(vb);
 
@@ -1729,18 +1998,23 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
 {
        unsigned int i;
 
-       if (q->retry_start_streaming) {
-               q->retry_start_streaming = 0;
-               q->streaming = 0;
-       }
-
        /*
         * Tell driver to stop all transactions and release all queued
         * buffers.
         */
-       if (q->streaming)
+       if (q->start_streaming_called)
                call_qop(q, stop_streaming, q);
        q->streaming = 0;
+       q->start_streaming_called = 0;
+       q->queued_count = 0;
+
+       if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
+               for (i = 0; i < q->num_buffers; ++i)
+                       if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE)
+                               vb2_buffer_done(q->bufs[i], VB2_BUF_STATE_ERROR);
+               /* Must be zero now */
+               WARN_ON(atomic_read(&q->owned_by_drv_count));
+       }
 
        /*
         * Remove all buffers from videobuf's list...
@@ -1751,19 +2025,31 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
         * has not already dequeued before initiating cancel.
         */
        INIT_LIST_HEAD(&q->done_list);
-       atomic_set(&q->queued_count, 0);
+       atomic_set(&q->owned_by_drv_count, 0);
        wake_up_all(&q->done_wq);
 
        /*
         * Reinitialize all buffers for next use.
+        * Make sure to call buf_finish for any queued buffers. Normally
+        * that's done in dqbuf, but that's not going to happen when we
+        * cancel the whole queue. Note: this code belongs here, not in
+        * __vb2_dqbuf() since in vb2_internal_dqbuf() there is a critical
+        * call to __fill_v4l2_buffer() after buf_finish(). That order can't
+        * be changed, so we can't move the buf_finish() to __vb2_dqbuf().
         */
-       for (i = 0; i < q->num_buffers; ++i)
-               __vb2_dqbuf(q->bufs[i]);
+       for (i = 0; i < q->num_buffers; ++i) {
+               struct vb2_buffer *vb = q->bufs[i];
+
+               if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+                       vb->state = VB2_BUF_STATE_PREPARED;
+                       call_vb_qop(vb, buf_finish, vb);
+               }
+               __vb2_dqbuf(vb);
+       }
 }
 
 static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
 {
-       struct vb2_buffer *vb;
        int ret;
 
        if (type != q->type) {
@@ -1781,18 +2067,26 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
                return -EINVAL;
        }
 
+       if (!q->num_buffers) {
+               dprintk(1, "streamon: no buffers have been allocated\n");
+               return -EINVAL;
+       }
+       if (q->num_buffers < q->min_buffers_needed) {
+               dprintk(1, "streamon: need at least %u allocated buffers\n",
+                               q->min_buffers_needed);
+               return -EINVAL;
+       }
+
        /*
-        * If any buffers were queued before streamon,
-        * we can now pass them to driver for processing.
+        * Tell driver to start streaming provided sufficient buffers
+        * are available.
         */
-       list_for_each_entry(vb, &q->queued_list, queued_entry)
-               __enqueue_in_driver(vb);
-
-       /* Tell driver to start streaming. */
-       ret = vb2_start_streaming(q);
-       if (ret) {
-               __vb2_queue_cancel(q);
-               return ret;
+       if (q->queued_count >= q->min_buffers_needed) {
+               ret = vb2_start_streaming(q);
+               if (ret) {
+                       __vb2_queue_cancel(q);
+                       return ret;
+               }
        }
 
        q->streaming = 1;
@@ -1831,14 +2125,14 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
                return -EINVAL;
        }
 
-       if (!q->streaming) {
-               dprintk(3, "streamoff successful: not streaming\n");
-               return 0;
-       }
-
        /*
         * Cancel will pause streaming and remove all buffers from the driver
         * and videobuf, effectively returning control over them to userspace.
+        *
+        * Note that we do this even if q->streaming == 0: if you prepare or
+        * queue buffers, and then call streamoff without ever having called
+        * streamon, you would still expect those buffers to be returned to
+        * their normal dequeued state.
         */
        __vb2_queue_cancel(q);
 
@@ -1950,10 +2244,11 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
 
        vb_plane = &vb->planes[eb->plane];
 
-       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
+       dbuf = call_memop(vb, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE);
        if (IS_ERR_OR_NULL(dbuf)) {
                dprintk(1, "Failed to export buffer %d, plane %d\n",
                        eb->index, eb->plane);
+               fail_memop(vb, get_dmabuf);
                return -EINVAL;
        }
 
@@ -2045,9 +2340,11 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
                return -EINVAL;
        }
 
-       ret = call_memop(q, mmap, vb->planes[plane].mem_priv, vma);
-       if (ret)
+       ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma);
+       if (ret) {
+               fail_memop(vb, mmap);
                return ret;
+       }
 
        dprintk(3, "Buffer %d, plane %d successfully mapped\n", buffer, plane);
        return 0;
@@ -2200,11 +2497,14 @@ int vb2_queue_init(struct vb2_queue *q)
            WARN_ON(!q->io_modes)         ||
            WARN_ON(!q->ops->queue_setup) ||
            WARN_ON(!q->ops->buf_queue)   ||
-           WARN_ON(q->timestamp_type & ~V4L2_BUF_FLAG_TIMESTAMP_MASK))
+           WARN_ON(q->timestamp_flags &
+                   ~(V4L2_BUF_FLAG_TIMESTAMP_MASK |
+                     V4L2_BUF_FLAG_TSTAMP_SRC_MASK)))
                return -EINVAL;
 
        /* Warn that the driver should choose an appropriate timestamp type */
-       WARN_ON(q->timestamp_type == V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN);
+       WARN_ON((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
+               V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN);
 
        INIT_LIST_HEAD(&q->queued_list);
        INIT_LIST_HEAD(&q->done_list);
@@ -2251,6 +2551,22 @@ struct vb2_fileio_buf {
 /**
  * struct vb2_fileio_data - queue context used by file io emulator
  *
+ * @cur_index: the index of the buffer currently being read from or
+ *             written to. If equal to q->num_buffers then a new buffer
+ *             must be dequeued.
+ * @initial_index: in the read() case all buffers are queued up immediately
+ *             in __vb2_init_fileio() and __vb2_perform_fileio() just cycles
+ *             buffers. However, in the write() case no buffers are initially
+ *             queued, instead whenever a buffer is full it is queued up by
+ *             __vb2_perform_fileio(). Only once all available buffers have
+ *             been queued up will __vb2_perform_fileio() start to dequeue
+ *             buffers. This means that initially __vb2_perform_fileio()
+ *             needs to know what buffer index to use when it is queuing up
+ *             the buffers for the first time. That initial index is stored
+ *             in this field. Once it is equal to q->num_buffers all
+ *             available buffers have been queued and __vb2_perform_fileio()
+ *             should start the normal dequeue/queue cycle.
+ *
  * vb2 provides a compatibility layer and emulator of file io (read and
  * write) calls on top of streaming API. For proper operation it required
  * this structure to save the driver state between each call of the read
@@ -2260,7 +2576,8 @@ struct vb2_fileio_data {
        struct v4l2_requestbuffers req;
        struct v4l2_buffer b;
        struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
-       unsigned int index;
+       unsigned int cur_index;
+       unsigned int initial_index;
        unsigned int q_count;
        unsigned int dq_count;
        unsigned int flags;
@@ -2280,9 +2597,9 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
        /*
         * Sanity check
         */
-       if ((read && !(q->io_modes & VB2_READ)) ||
-          (!read && !(q->io_modes & VB2_WRITE)))
-               BUG();
+       if (WARN_ON((read && !(q->io_modes & VB2_READ)) ||
+                   (!read && !(q->io_modes & VB2_WRITE))))
+               return -EINVAL;
 
        /*
         * Check if device supports mapping buffers to kernel virtual space.
@@ -2360,7 +2677,12 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
                                goto err_reqbufs;
                        fileio->bufs[i].queued = 1;
                }
-               fileio->index = q->num_buffers;
+               /*
+                * All buffers have been queued, so mark that by setting
+                * initial_index to q->num_buffers
+                */
+               fileio->initial_index = q->num_buffers;
+               fileio->cur_index = q->num_buffers;
        }
 
        /*
@@ -2439,7 +2761,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
        /*
         * Check if we need to dequeue the buffer.
         */
-       index = fileio->index;
+       index = fileio->cur_index;
        if (index >= q->num_buffers) {
                /*
                 * Call vb2_dqbuf to get buffer back.
@@ -2453,7 +2775,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
                        return ret;
                fileio->dq_count += 1;
 
-               index = fileio->b.index;
+               fileio->cur_index = index = fileio->b.index;
                buf = &fileio->bufs[index];
 
                /*
@@ -2529,8 +2851,20 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
                buf->queued = 1;
                buf->size = vb2_plane_size(q->bufs[index], 0);
                fileio->q_count += 1;
-               if (fileio->index < q->num_buffers)
-                       fileio->index++;
+               /*
+                * If we are queuing up buffers for the first time, then
+                * increase initial_index by one.
+                */
+               if (fileio->initial_index < q->num_buffers)
+                       fileio->initial_index++;
+               /*
+                * The next buffer to use is either a buffer that's going to be
+                * queued for the first time (initial_index < q->num_buffers)
+                * or it is equal to q->num_buffers, meaning that the next
+                * time we need to dequeue a buffer since we've now queued up
+                * all the 'first time' buffers.
+                */
+               fileio->cur_index = fileio->initial_index;
        }
 
        /*
index 7dca1e640970a0dfb7f28ad8909c1f3e4d7d26e4..841717a2842cb05d49429ed36ad0c51608f15148 100644 (file)
@@ -571,7 +571,7 @@ static int pm800_probe(struct i2c_client *client,
        ret = pm800_pages_init(chip);
        if (ret) {
                dev_err(&client->dev, "pm800_pages_init failed!\n");
-               goto err_page_init;
+               goto err_device_init;
        }
 
        ret = device_800_init(chip, pdata);
@@ -587,7 +587,6 @@ static int pm800_probe(struct i2c_client *client,
 
 err_device_init:
        pm800_pages_exit(chip);
-err_page_init:
 err_subchip_alloc:
        pm80x_deinit();
 out_init:
index c9b1f6422941eeaf628a0f7a65fd4e65053a8a14..bcfc9e85b4a0d0a702bef461f81b9fb568e528ff 100644 (file)
@@ -1179,12 +1179,18 @@ static int pm860x_probe(struct i2c_client *client,
                chip->companion_addr = pdata->companion_addr;
                chip->companion = i2c_new_dummy(chip->client->adapter,
                                                chip->companion_addr);
+               if (!chip->companion) {
+                       dev_err(&client->dev,
+                               "Failed to allocate I2C companion device\n");
+                       return -ENODEV;
+               }
                chip->regmap_companion = regmap_init_i2c(chip->companion,
                                                        &pm860x_regmap_config);
                if (IS_ERR(chip->regmap_companion)) {
                        ret = PTR_ERR(chip->regmap_companion);
                        dev_err(&chip->companion->dev,
                                "Failed to allocate register map: %d\n", ret);
+                       i2c_unregister_device(chip->companion);
                        return ret;
                }
                i2c_set_clientdata(chip->companion, chip);
index 49bb445d846aa76e206dfe7fb7d30ad5f24b6b97..33834120d057117f5b98284227ee0e3ec59df371 100644 (file)
@@ -59,6 +59,14 @@ config MFD_AAT2870_CORE
          additional drivers must be enabled in order to use the
          functionality of the device.
 
+config MFD_BCM590XX
+       tristate "Broadcom BCM590xx PMUs"
+       select MFD_CORE
+       select REGMAP_I2C
+       depends on I2C
+       help
+         Support for the BCM590xx PMUs from Broadcom
+
 config MFD_CROS_EC
        tristate "ChromeOS Embedded Controller"
        select MFD_CORE
@@ -100,7 +108,7 @@ config PMIC_DA903X
        bool "Dialog Semiconductor DA9030/DA9034 PMIC Support"
        depends on I2C=y
        help
-         Say yes here to support for Dialog Semiconductor DA9030 (a.k.a
+         Say yes here to add support for Dialog Semiconductor DA9030 (a.k.a
          ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC
          usually found on PXA processors-based platforms. This includes
          the I2C driver and the core APIs _only_, you have to select
@@ -270,13 +278,18 @@ config MFD_KEMPLD
          device may provide functions like watchdog, GPIO, UART and I2C bus.
 
          The following modules are supported:
+               * COMe-bHL6
                * COMe-bIP#
                * COMe-bPC2 (ETXexpress-PC)
                * COMe-bSC# (ETXexpress-SC T#)
+               * COMe-cBT6
                * COMe-cCT6
                * COMe-cDC2 (microETXexpress-DC)
+               * COMe-cHL6
                * COMe-cPC2 (microETXexpress-PC)
+               * COMe-mBT10
                * COMe-mCT10
+               * COMe-mTT10 (nanoETXexpress-TT)
                * ETX-OH
 
          This driver can also be built as a module. If so, the module
@@ -322,9 +335,10 @@ config MFD_MAX14577
        depends on I2C=y
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        select IRQ_DOMAIN
        help
-         Say yes here to support for Maxim Semiconductor MAX14577.
+         Say yes here to add support for Maxim Semiconductor MAX14577.
          This is a Micro-USB IC with Charger controls on chip.
          This driver provides common support for accessing the device;
          additional drivers must be enabled in order to use the functionality
@@ -337,7 +351,7 @@ config MFD_MAX77686
        select REGMAP_I2C
        select IRQ_DOMAIN
        help
-         Say yes here to support for Maxim Semiconductor MAX77686.
+         Say yes here to add support for Maxim Semiconductor MAX77686.
          This is a Power Management IC with RTC on chip.
          This driver provides common support for accessing the device;
          additional drivers must be enabled in order to use the functionality
@@ -349,7 +363,7 @@ config MFD_MAX77693
        select MFD_CORE
        select REGMAP_I2C
        help
-         Say yes here to support for Maxim Semiconductor MAX77693.
+         Say yes here to add support for Maxim Semiconductor MAX77693.
          This is a companion Power Management IC with Flash, Haptic, Charger,
          and MUIC(Micro USB Interface Controller) controls on chip.
          This driver provides common support for accessing the device;
@@ -363,7 +377,7 @@ config MFD_MAX8907
        select REGMAP_I2C
        select REGMAP_IRQ
        help
-         Say yes here to support for Maxim Semiconductor MAX8907. This is
+         Say yes here to add support for Maxim Semiconductor MAX8907. This is
          a Power Management IC. This driver provides common support for
          accessing the device; additional drivers must be enabled in order
          to use the functionality of the device.
@@ -373,7 +387,7 @@ config MFD_MAX8925
        depends on I2C=y
        select MFD_CORE
        help
-         Say yes here to support for Maxim Semiconductor MAX8925. This is
+         Say yes here to add support for Maxim Semiconductor MAX8925. This is
          a Power Management IC. This driver provides common support for
          accessing the device, additional drivers must be enabled in order
          to use the functionality of the device.
@@ -384,7 +398,7 @@ config MFD_MAX8997
        select MFD_CORE
        select IRQ_DOMAIN
        help
-         Say yes here to support for Maxim Semiconductor MAX8997/8966.
+         Say yes here to add support for Maxim Semiconductor MAX8997/8966.
          This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
          MUIC controls on chip.
          This driver provides common support for accessing the device;
@@ -397,7 +411,7 @@ config MFD_MAX8998
        select MFD_CORE
        select IRQ_DOMAIN
        help
-         Say yes here to support for Maxim Semiconductor MAX8998 and
+         Say yes here to add support for Maxim Semiconductor MAX8998 and
          National Semiconductor LP3974. This is a Power Management IC.
          This driver provides common support for accessing the device,
          additional drivers must be enabled in order to use the functionality
@@ -473,10 +487,11 @@ config MFD_PM8XXX
 
 config MFD_PM8921_CORE
        tristate "Qualcomm PM8921 PMIC chip"
-       depends on (ARCH_MSM || HEXAGON)
-       depends on BROKEN
+       depends on (ARM || HEXAGON)
+       select IRQ_DOMAIN
        select MFD_CORE
        select MFD_PM8XXX
+       select REGMAP
        help
          If you say yes to this option, support will be included for the
          built-in PM8921 PMIC chip.
@@ -487,16 +502,6 @@ config MFD_PM8921_CORE
          Say M here if you want to include support for PM8921 chip as a module.
          This will build a module called "pm8921-core".
 
-config MFD_PM8XXX_IRQ
-       bool "Qualcomm PM8xxx IRQ features"
-       depends on MFD_PM8XXX
-       default y if MFD_PM8XXX
-       help
-         This is the IRQ driver for Qualcomm PM 8xxx PMIC chips.
-
-         This is required to use certain other PM 8xxx features, such as GPIO
-         and MPP.
-
 config MFD_RDC321X
        tristate "RDC R-321x southbridge"
        select MFD_CORE
@@ -516,6 +521,16 @@ config MFD_RTSX_PCI
          types of memory cards, such as Memory Stick, Memory Stick Pro,
          Secure Digital and MultiMediaCard.
 
+config MFD_RTSX_USB
+       tristate "Realtek USB card reader"
+       depends on USB
+       select MFD_CORE
+       help
+         Select this option to get support for Realtek USB 2.0 card readers
+         including RTS5129, RTS5139, RTS5179 and RTS5170.
+         Realtek card reader supports access to many types of memory cards,
+         such as Memory Stick Pro, Secure Digital and MultiMediaCard.
+
 config MFD_RC5T583
        bool "Ricoh RC5T583 Power Management system device"
        depends on I2C=y
@@ -774,17 +789,6 @@ config MFD_PALMAS
          If you say yes here you get support for the Palmas
          series of PMIC chips from Texas Instruments.
 
-config MFD_TI_SSP
-       tristate "TI Sequencer Serial Port support"
-       depends on ARCH_DAVINCI_TNETV107X
-       select MFD_CORE
-       ---help---
-         Say Y here if you want support for the Sequencer Serial Port
-         in a Texas Instruments TNETV107X SoC.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ti-ssp.
-
 config TPS6105X
        tristate "TI TPS61050/61052 Boost Converters"
        depends on I2C
@@ -853,6 +857,22 @@ config MFD_TPS65217
          This driver can also be built as a module.  If so, the module
          will be called tps65217.
 
+config MFD_TPS65218
+       tristate "TI TPS65218 Power Management chips"
+       depends on I2C
+       select MFD_CORE
+       select REGMAP_I2C
+       select REGMAP_IRQ
+       help
+         If you say yes here you get support for the TPS65218 series of
+         Power Management chips.
+         These include voltage regulators, gpio and other features
+         that are often used in portable devices. Only regulator
+         component is currently supported.
+
+         This driver can also be built as a module.  If so, the module
+         will be called tps65218.
+
 config MFD_TPS6586X
        bool "TI TPS6586x Power Management chips"
        depends on I2C=y
@@ -935,16 +955,6 @@ config TWL4030_CORE
          high speed USB OTG transceiver, an audio codec (on most
          versions) and many other features.
 
-config TWL4030_MADC
-       tristate "TI TWL4030 MADC"
-       depends on TWL4030_CORE
-       help
-       This driver provides support for triton TWL4030-MADC. The
-       driver supports both RT and SW conversion methods.
-
-       This driver can be built as a module. If so it will be
-       named twl4030-madc
-
 config TWL4030_POWER
        bool "TI TWL4030 power resources"
        depends on TWL4030_CORE && ARM
@@ -1193,9 +1203,6 @@ config MFD_STW481X
          in various ST Microelectronics and ST-Ericsson embedded
          Nomadik series.
 
-endmenu
-endif
-
 menu "Multimedia Capabilities Port drivers"
        depends on ARCH_SA1100
 
@@ -1226,3 +1233,6 @@ config VEXPRESS_CONFIG
        help
          Platform configuration infrastructure for the ARM Ltd.
          Versatile Express.
+
+endmenu
+endif
index 5aea5ef0a62f51eff03a14404569c68a7700262f..2851275e2656f8d1f012fee8a7f740b857c21262 100644 (file)
@@ -8,12 +8,14 @@ obj-$(CONFIG_MFD_88PM800)     += 88pm800.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM805)      += 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_SM501)                += sm501.o
 obj-$(CONFIG_MFD_ASIC3)                += asic3.o tmio_core.o
+obj-$(CONFIG_MFD_BCM590XX)     += bcm590xx.o
 obj-$(CONFIG_MFD_CROS_EC)      += cros_ec.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)  += cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)  += cros_ec_spi.o
 
 rtsx_pci-objs                  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI)     += rtsx_pci.o
+obj-$(CONFIG_MFD_RTSX_USB)     += rtsx_usb.o
 
 obj-$(CONFIG_HTC_EGPIO)                += htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)       += htc-pasic3.o
@@ -21,7 +23,6 @@ obj-$(CONFIG_HTC_I2CPLD)      += htc-i2cpld.o
 
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)   += davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
-obj-$(CONFIG_MFD_TI_SSP)       += ti-ssp.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC)     += ti_am335x_tscadc.o
 
 obj-$(CONFIG_MFD_STA2X11)      += sta2x11-mfd.o
@@ -62,6 +63,7 @@ obj-$(CONFIG_TPS6105X)                += tps6105x.o
 obj-$(CONFIG_TPS65010)         += tps65010.o
 obj-$(CONFIG_TPS6507X)         += tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)     += tps65217.o
+obj-$(CONFIG_MFD_TPS65218)     += tps65218.o
 obj-$(CONFIG_MFD_TPS65910)     += tps65910.o
 tps65912-objs                   := tps65912-core.o tps65912-irq.o
 obj-$(CONFIG_MFD_TPS65912)     += tps65912.o
@@ -71,7 +73,6 @@ obj-$(CONFIG_MFD_TPS80031)    += tps80031.o
 obj-$(CONFIG_MENELAUS)         += menelaus.o
 
 obj-$(CONFIG_TWL4030_CORE)     += twl-core.o twl4030-irq.o twl6030-irq.o
-obj-$(CONFIG_TWL4030_MADC)      += twl4030-madc.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
 obj-$(CONFIG_MFD_TWL4030_AUDIO)        += twl4030-audio.o
 obj-$(CONFIG_TWL6040_CORE)     += twl6040.o
@@ -150,7 +151,6 @@ obj-$(CONFIG_MFD_SI476X_CORE)       += si476x-core.o
 obj-$(CONFIG_MFD_CS5535)       += cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)        += omap-usb-host.o omap-usb-tll.o
 obj-$(CONFIG_MFD_PM8921_CORE)  += pm8921-core.o ssbi.o
-obj-$(CONFIG_MFD_PM8XXX_IRQ)   += pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)      += tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)     += tps65090.o
 obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
index aaff683cd37d43809bb8da6b1cd5c085f1bf664a..a8ee4a36a1d8fd0c63d3ef268d8cc316be1edef4 100644 (file)
@@ -592,7 +592,7 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
 
        /* If ->irq_base is zero this will give a linear mapping */
        ab8500->domain = irq_domain_add_simple(NULL,
-                       num_irqs, ab8500->irq_base,
+                       num_irqs, 0,
                        &ab8500_irq_ops, ab8500);
 
        if (!ab8500->domain) {
@@ -1583,14 +1583,13 @@ static int ab8500_probe(struct platform_device *pdev)
        if (!ab8500)
                return -ENOMEM;
 
-       if (plat)
-               ab8500->irq_base = plat->irq_base;
-
        ab8500->dev = &pdev->dev;
 
        resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!resource)
+       if (!resource) {
+               dev_err(&pdev->dev, "no IRQ resource\n");
                return -ENODEV;
+       }
 
        ab8500->irq = resource->start;
 
@@ -1612,8 +1611,10 @@ static int ab8500_probe(struct platform_device *pdev)
        else {
                ret = get_register_interruptible(ab8500, AB8500_MISC,
                        AB8500_IC_NAME_REG, &value);
-               if (ret < 0)
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "could not probe HW\n");
                        return ret;
+               }
 
                ab8500->version = value;
        }
@@ -1759,30 +1760,30 @@ static int ab8500_probe(struct platform_device *pdev)
        if (is_ab9540(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
                                ARRAY_SIZE(ab9540_devs), NULL,
-                               ab8500->irq_base, ab8500->domain);
+                               0, ab8500->domain);
        else if (is_ab8540(ab8500)) {
                ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
                              ARRAY_SIZE(ab8540_devs), NULL,
-                             ab8500->irq_base, NULL);
+                             0, ab8500->domain);
                if (ret)
                        return ret;
 
                if (is_ab8540_1p2_or_earlier(ab8500))
                        ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
                              ARRAY_SIZE(ab8540_cut1_devs), NULL,
-                             ab8500->irq_base, NULL);
+                             0, ab8500->domain);
                else /* ab8540 >= cut2 */
                        ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
                              ARRAY_SIZE(ab8540_cut2_devs), NULL,
-                             ab8500->irq_base, NULL);
+                             0, ab8500->domain);
        } else if (is_ab8505(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
                              ARRAY_SIZE(ab8505_devs), NULL,
-                             ab8500->irq_base, ab8500->domain);
+                             0, ab8500->domain);
        else
                ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
                                ARRAY_SIZE(ab8500_devs), NULL,
-                               ab8500->irq_base, ab8500->domain);
+                               0, ab8500->domain);
        if (ret)
                return ret;
 
@@ -1790,7 +1791,7 @@ static int ab8500_probe(struct platform_device *pdev)
                /* Add battery management devices */
                ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
                                      ARRAY_SIZE(ab8500_bm_devs), NULL,
-                                     ab8500->irq_base, ab8500->domain);
+                                     0, ab8500->domain);
                if (ret)
                        dev_err(ab8500->dev, "error adding bm devices\n");
        }
index 62501553d63c4f7c2b49da5c73d79141d964179e..f495b8b57dd7b1cb93035018e7270d048d63a783 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
index c71ff0af1547e573aacf17c6317e2e02224813f7..39fa554f13bbfcffc1f13b2bd2e8024371c317fe 100644 (file)
@@ -277,6 +277,7 @@ static const struct regmap_range as3722_readable_ranges[] = {
        regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
        regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
        regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
+       regmap_reg_range(AS3722_FUSE7_REG, AS3722_FUSE7_REG),
 };
 
 static const struct regmap_access_table as3722_readable_table = {
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
new file mode 100644 (file)
index 0000000..e9a33c7
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Broadcom BCM590xx PMU
+ *
+ * Copyright 2014 Linaro Limited
+ * Author: Matt Porter <mporter@linaro.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.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/mfd/bcm590xx.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+static const struct mfd_cell bcm590xx_devs[] = {
+       {
+               .name = "bcm590xx-vregs",
+       },
+};
+
+static const struct regmap_config bcm590xx_regmap_config = {
+       .reg_bits       = 8,
+       .val_bits       = 8,
+       .max_register   = BCM590XX_MAX_REGISTER,
+       .cache_type     = REGCACHE_RBTREE,
+};
+
+static int bcm590xx_i2c_probe(struct i2c_client *i2c,
+                             const struct i2c_device_id *id)
+{
+       struct bcm590xx *bcm590xx;
+       int ret;
+
+       bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL);
+       if (!bcm590xx)
+               return -ENOMEM;
+
+       i2c_set_clientdata(i2c, bcm590xx);
+       bcm590xx->dev = &i2c->dev;
+       bcm590xx->i2c_client = i2c;
+
+       bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config);
+       if (IS_ERR(bcm590xx->regmap)) {
+               ret = PTR_ERR(bcm590xx->regmap);
+               dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
+               return ret;
+       }
+
+       ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs,
+                             ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
+       if (ret < 0)
+               dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret);
+
+       return ret;
+}
+
+static const struct of_device_id bcm590xx_of_match[] = {
+       { .compatible = "brcm,bcm59056" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, bcm590xx_of_match);
+
+static const struct i2c_device_id bcm590xx_i2c_id[] = {
+       { "bcm59056" },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, bcm590xx_i2c_id);
+
+static struct i2c_driver bcm590xx_i2c_driver = {
+       .driver = {
+                  .name = "bcm590xx",
+                  .owner = THIS_MODULE,
+                  .of_match_table = of_match_ptr(bcm590xx_of_match),
+       },
+       .probe = bcm590xx_i2c_probe,
+       .id_table = bcm590xx_i2c_id,
+};
+module_i2c_driver(bcm590xx_i2c_driver);
+
+MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
+MODULE_DESCRIPTION("BCM590xx multi-function driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:bcm590xx");
index 17c13012686af663ba970f4c423a4262aa602b58..be91cb5d6e7860dc789ceb9cb8037524db0969e1 100644 (file)
@@ -23,7 +23,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/pci.h>
index 25838f10b35b2d08c295e18b27ecf4155bb5f4ce..e8af816d73a972e26307810ae38c514e17b9ae42 100644 (file)
@@ -279,6 +279,9 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg)
        case DA9052_EVENT_B_REG:
        case DA9052_EVENT_C_REG:
        case DA9052_EVENT_D_REG:
+       case DA9052_CONTROL_B_REG:
+       case DA9052_CONTROL_D_REG:
+       case DA9052_SUPPLY_REG:
        case DA9052_FAULTLOG_REG:
        case DA9052_CHG_TIME_REG:
        case DA9052_ADC_RES_L_REG:
index c319c4ef5d499c9f59140adf941987ac6d024bb2..6da8ec8ff800fcd5d7de55db28c7c0e77883c7b6 100644 (file)
@@ -75,6 +75,7 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
                                           DA9052_PARK_REGISTER,
                                           &val);
                break;
+       case DA9053_BC:
        default:
                /*
                 * For other chips parking of I2C register
@@ -114,6 +115,7 @@ static const struct i2c_device_id da9052_i2c_id[] = {
        {"da9053-aa", DA9053_AA},
        {"da9053-ba", DA9053_BA},
        {"da9053-bb", DA9053_BB},
+       {"da9053-bc", DA9053_BC},
        {}
 };
 
@@ -121,8 +123,9 @@ static const struct i2c_device_id da9052_i2c_id[] = {
 static const struct of_device_id dialog_dt_ids[] = {
        { .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] },
        { .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] },
-       { .compatible = "dlg,da9053-ab", .data = &da9052_i2c_id[2] },
+       { .compatible = "dlg,da9053-ba", .data = &da9052_i2c_id[2] },
        { .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] },
+       { .compatible = "dlg,da9053-bc", .data = &da9052_i2c_id[4] },
        { /* sentinel */ }
 };
 #endif
index 0680bcbc53def93aec02d2783b19a1e46c377280..17666b40b70c624029fc2a95ccebd71b10b685c6 100644 (file)
@@ -71,6 +71,7 @@ static struct spi_device_id da9052_spi_id[] = {
        {"da9053-aa", DA9053_AA},
        {"da9053-ba", DA9053_BA},
        {"da9053-bb", DA9053_BB},
+       {"da9053-bc", DA9053_BC},
        {}
 };
 
index 8103e4362132a24486961bf3ac6fd80980210107..d4d4c165eb955902dcc56a4cecbe9fa6358ef702 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/mfd/da9055/core.h>
 
@@ -66,6 +68,11 @@ static struct i2c_device_id da9055_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
 
+static const struct of_device_id da9055_of_match[] = {
+       { .compatible = "dlg,da9055-pmic", },
+       { }
+};
+
 static struct i2c_driver da9055_i2c_driver = {
        .probe = da9055_i2c_probe,
        .remove = da9055_i2c_remove,
@@ -73,6 +80,7 @@ static struct i2c_driver da9055_i2c_driver = {
        .driver = {
                .name = "da9055-pmic",
                .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(da9055_of_match),
        },
 };
 
index 26937cd010714b7c1c9e98877603616390b6e952..e70ae315abc775b921c6f4a5c352093867b443ca 100644 (file)
@@ -110,7 +110,7 @@ static const struct mfd_cell da9063_devs[] = {
 int da9063_device_init(struct da9063 *da9063, unsigned int irq)
 {
        struct da9063_pdata *pdata = da9063->dev->platform_data;
-       int model, revision;
+       int model, variant_id, variant_code;
        int ret;
 
        if (pdata) {
@@ -141,23 +141,26 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
                return -ENODEV;
        }
 
-       ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision);
+       ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &variant_id);
        if (ret < 0) {
-               dev_err(da9063->dev, "Cannot read chip revision id.\n");
+               dev_err(da9063->dev, "Cannot read chip variant id.\n");
                return -EIO;
        }
-       revision >>= DA9063_CHIP_VARIANT_SHIFT;
-       if (revision != 3) {
-               dev_err(da9063->dev, "Unknown chip revision: %d\n", revision);
+
+       variant_code = variant_id >> DA9063_CHIP_VARIANT_SHIFT;
+
+       dev_info(da9063->dev,
+                "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n",
+                model, variant_id);
+
+       if (variant_code != PMIC_DA9063_BB) {
+               dev_err(da9063->dev, "Unknown chip variant code: 0x%02X\n",
+                               variant_code);
                return -ENODEV;
        }
 
        da9063->model = model;
-       da9063->revision = revision;
-
-       dev_info(da9063->dev,
-                "Device detected (model-ID: 0x%02X  rev-ID: 0x%02X)\n",
-                model, revision);
+       da9063->variant_code = variant_code;
 
        ret = da9063_irq_init(da9063);
        if (ret) {
index e43e6e821117a01aac56b8e4086fe783056977cd..7694e0700d340329c5696c4ccba0417f9f93486f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/bitops.h>
 #include <linux/fs.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/mfd/core.h>
@@ -2678,16 +2679,12 @@ static struct irq_domain_ops db8500_irq_ops = {
        .xlate  = irq_domain_xlate_twocell,
 };
 
-static int db8500_irq_init(struct device_node *np, int irq_base)
+static int db8500_irq_init(struct device_node *np)
 {
        int i;
 
-       /* In the device tree case, just take some IRQs */
-       if (np)
-               irq_base = 0;
-
        db8500_irq_domain = irq_domain_add_simple(
-               np, NUM_PRCMU_WAKEUPS, irq_base,
+               np, NUM_PRCMU_WAKEUPS, 0,
                &db8500_irq_ops, NULL);
 
        if (!db8500_irq_domain) {
@@ -3114,10 +3111,10 @@ static void db8500_prcmu_update_cpufreq(void)
 }
 
 static int db8500_prcmu_register_ab8500(struct device *parent,
-                                       struct ab8500_platform_data *pdata,
-                                       int irq)
+                                       struct ab8500_platform_data *pdata)
 {
-       struct resource ab8500_resource = DEFINE_RES_IRQ(irq);
+       struct device_node *np;
+       struct resource ab8500_resource;
        struct mfd_cell ab8500_cell = {
                .name = "ab8500-core",
                .of_compatible = "stericsson,ab8500",
@@ -3128,6 +3125,20 @@ static int db8500_prcmu_register_ab8500(struct device *parent,
                .num_resources = 1,
        };
 
+       if (!parent->of_node)
+               return -ENODEV;
+
+       /* Look up the device node, sneak the IRQ out of it */
+       for_each_child_of_node(parent->of_node, np) {
+               if (of_device_is_compatible(np, ab8500_cell.of_compatible))
+                       break;
+       }
+       if (!np) {
+               dev_info(parent, "could not find AB8500 node in the device tree\n");
+               return -ENODEV;
+       }
+       of_irq_to_resource_table(np, &ab8500_resource, 1);
+
        return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL);
 }
 
@@ -3180,7 +3191,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
                goto no_irq_return;
        }
 
-       db8500_irq_init(np, pdata->irq_base);
+       db8500_irq_init(np);
 
        prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
 
@@ -3205,8 +3216,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
                }
        }
 
-       err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata,
-                                          pdata->ab_irq);
+       err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata);
        if (err) {
                mfd_remove_devices(&pdev->dev);
                pr_err("prcmu: Failed to add ab8500 subdevice\n");
index 81b7d88af3135cc7d26bd0e3afb842497b58024c..433f823037dd7a25eceb5a644661aec52d3ea5b7 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
index d3e23278d299021f34bab4aacbb361d117f5a40b..07692604e119123a1f9b311b2611c5d0103daa78 100644 (file)
@@ -322,9 +322,12 @@ static int kempld_detect_device(struct kempld_device_data *pld)
                return -ENODEV;
        }
 
-       /* Release hardware mutex if aquired */
-       if (!(index_reg & KEMPLD_MUTEX_KEY))
+       /* Release hardware mutex if acquired */
+       if (!(index_reg & KEMPLD_MUTEX_KEY)) {
                iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
+               /* PXT and COMe-cPC2 boards may require a second release */
+               iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
+       }
 
        mutex_unlock(&pld->lock);
 
@@ -437,6 +440,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
                },
                .driver_data = (void *)&kempld_platform_data_generic,
                .callback = kempld_create_platform_device,
+       }, {
+               .ident = "CHL6",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+                       DMI_MATCH(DMI_BOARD_NAME, "COMe-cHL6"),
+               },
+               .driver_data = (void *)&kempld_platform_data_generic,
+               .callback = kempld_create_platform_device,
        }, {
                .ident = "CHR2",
                .matches = {
@@ -509,6 +520,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
                },
                .driver_data = (void *)&kempld_platform_data_generic,
                .callback = kempld_create_platform_device,
+       }, {
+               .ident = "CVV6",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+                       DMI_MATCH(DMI_BOARD_NAME, "COMe-cBT"),
+               },
+               .driver_data = (void *)&kempld_platform_data_generic,
+               .callback = kempld_create_platform_device,
        }, {
                .ident = "FRI2",
                .matches = {
@@ -532,6 +551,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
                },
                .driver_data = (void *)&kempld_platform_data_generic,
                .callback = kempld_create_platform_device,
+       }, {
+               .ident = "MVV1",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+                       DMI_MATCH(DMI_BOARD_NAME, "COMe-mBT"),
+               },
+               .driver_data = (void *)&kempld_platform_data_generic,
+               .callback = kempld_create_platform_device,
        }, {
                .ident = "NTC1",
                .matches = {
index be93fa261dedb4c808955c1830932f84a48b7524..3f10ea3f45d1ae672ca5adc6e96cb9fade1662c2 100644 (file)
@@ -58,7 +58,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #define ACPIBASE_GPE_END       0x2f
 #define ACPIBASE_SMI_OFF       0x30
 #define ACPIBASE_SMI_END       0x33
+#define ACPIBASE_PMC_OFF       0x08
+#define ACPIBASE_PMC_END       0x0c
 #define ACPIBASE_TCO_OFF       0x60
 #define ACPIBASE_TCO_END       0x7f
-#define ACPICTRL               0x44
+#define ACPICTRL_PMCBASE       0x44
 
 #define ACPIBASE_GCS_OFF       0x3410
 #define ACPIBASE_GCS_END       0x3414
 #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
 #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
 
-struct lpc_ich_cfg {
-       int base;
-       int ctrl;
-       int save;
-};
-
 struct lpc_ich_priv {
        int chipset;
-       struct lpc_ich_cfg acpi;
-       struct lpc_ich_cfg gpio;
+
+       int abase;              /* ACPI base */
+       int actrl_pbase;        /* ACPI control or PMC base */
+       int gbase;              /* GPIO base */
+       int gctrl;              /* GPIO control */
+
+       int abase_save;         /* Cached ACPI base value */
+       int actrl_pbase_save;           /* Cached ACPI control or PMC base value */
+       int gctrl_save;         /* Cached GPIO control value */
 };
 
 static struct resource wdt_ich_res[] = {
@@ -111,7 +113,7 @@ static struct resource wdt_ich_res[] = {
        {
                .flags = IORESOURCE_IO,
        },
-       /* GCS */
+       /* GCS or PMC */
        {
                .flags = IORESOURCE_MEM,
        },
@@ -211,6 +213,7 @@ enum lpc_chipsets {
        LPC_LPT_LP,     /* Lynx Point-LP */
        LPC_WBG,        /* Wellsburg */
        LPC_AVN,        /* Avoton SoC */
+       LPC_BAYTRAIL,   /* Bay Trail SoC */
        LPC_COLETO,     /* Coleto Creek */
        LPC_WPT_LP,     /* Wildcat Point-LP */
 };
@@ -303,6 +306,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
        [LPC_NM10] = {
                .name = "NM10",
                .iTCO_version = 2,
+               .gpio_version = ICH_V7_GPIO,
        },
        [LPC_ICH8] = {
                .name = "ICH8 or ICH8R",
@@ -499,7 +503,12 @@ static struct lpc_ich_info lpc_chipset_info[] = {
        },
        [LPC_AVN] = {
                .name = "Avoton SoC",
-               .iTCO_version = 1,
+               .iTCO_version = 3,
+               .gpio_version = AVOTON_GPIO,
+       },
+       [LPC_BAYTRAIL] = {
+               .name = "Bay Trail SoC",
+               .iTCO_version = 3,
        },
        [LPC_COLETO] = {
                .name = "Coleto Creek",
@@ -726,6 +735,7 @@ static const struct pci_device_id lpc_ich_ids[] = {
        { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
        { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
        { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
+       { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL},
        { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
        { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP},
        { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP},
@@ -742,14 +752,20 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev)
 {
        struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 
-       if (priv->acpi.save >= 0) {
-               pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save);
-               priv->acpi.save = -1;
+       if (priv->abase_save >= 0) {
+               pci_write_config_byte(dev, priv->abase, priv->abase_save);
+               priv->abase_save = -1;
+       }
+
+       if (priv->actrl_pbase_save >= 0) {
+               pci_write_config_byte(dev, priv->actrl_pbase,
+                       priv->actrl_pbase_save);
+               priv->actrl_pbase_save = -1;
        }
 
-       if (priv->gpio.save >= 0) {
-               pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save);
-               priv->gpio.save = -1;
+       if (priv->gctrl_save >= 0) {
+               pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save);
+               priv->gctrl_save = -1;
        }
 }
 
@@ -758,9 +774,26 @@ static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
        struct lpc_ich_priv *priv = pci_get_drvdata(dev);
        u8 reg_save;
 
-       pci_read_config_byte(dev, priv->acpi.ctrl, &reg_save);
-       pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10);
-       priv->acpi.save = reg_save;
+       switch (lpc_chipset_info[priv->chipset].iTCO_version) {
+       case 3:
+               /*
+                * Some chipsets (eg Avoton) enable the ACPI space in the
+                * ACPI BASE register.
+                */
+               pci_read_config_byte(dev, priv->abase, &reg_save);
+               pci_write_config_byte(dev, priv->abase, reg_save | 0x2);
+               priv->abase_save = reg_save;
+               break;
+       default:
+               /*
+                * Most chipsets enable the ACPI space in the ACPI control
+                * register.
+                */
+               pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
+               pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80);
+               priv->actrl_pbase_save = reg_save;
+               break;
+       }
 }
 
 static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
@@ -768,9 +801,20 @@ static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
        struct lpc_ich_priv *priv = pci_get_drvdata(dev);
        u8 reg_save;
 
-       pci_read_config_byte(dev, priv->gpio.ctrl, &reg_save);
-       pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10);
-       priv->gpio.save = reg_save;
+       pci_read_config_byte(dev, priv->gctrl, &reg_save);
+       pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10);
+       priv->gctrl_save = reg_save;
+}
+
+static void lpc_ich_enable_pmc_space(struct pci_dev *dev)
+{
+       struct lpc_ich_priv *priv = pci_get_drvdata(dev);
+       u8 reg_save;
+
+       pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
+       pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2);
+
+       priv->actrl_pbase_save = reg_save;
 }
 
 static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell)
@@ -815,7 +859,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
        struct resource *res;
 
        /* Setup power management base register */
-       pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
+       pci_read_config_dword(dev, priv->abase, &base_addr_cfg);
        base_addr = base_addr_cfg & 0x0000ff80;
        if (!base_addr) {
                dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
@@ -841,7 +885,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
 
 gpe0_done:
        /* Setup GPIO base register */
-       pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg);
+       pci_read_config_dword(dev, priv->gbase, &base_addr_cfg);
        base_addr = base_addr_cfg & 0x0000ff80;
        if (!base_addr) {
                dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n");
@@ -891,7 +935,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
        struct resource *res;
 
        /* Setup power management base register */
-       pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
+       pci_read_config_dword(dev, priv->abase, &base_addr_cfg);
        base_addr = base_addr_cfg & 0x0000ff80;
        if (!base_addr) {
                dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
@@ -910,14 +954,20 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
        lpc_ich_enable_acpi_space(dev);
 
        /*
+        * iTCO v2:
         * Get the Memory-Mapped GCS register. To get access to it
         * we have to read RCBA from PCI Config space 0xf0 and use
         * it as base. GCS = RCBA + ICH6_GCS(0x3410).
+        *
+        * iTCO v3:
+        * Get the Power Management Configuration register.  To get access
+        * to it we have to read the PMC BASE from config space and address
+        * the register at offset 0x8.
         */
        if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
                /* Don't register iomem for TCO ver 1 */
                lpc_ich_cells[LPC_WDT].num_resources--;
-       } else {
+       } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) {
                pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
                base_addr = base_addr_cfg & 0xffffc000;
                if (!(base_addr_cfg & 1)) {
@@ -926,9 +976,17 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
                        ret = -ENODEV;
                        goto wdt_done;
                }
-               res = wdt_mem_res(ICH_RES_MEM_GCS);
+               res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
                res->start = base_addr + ACPIBASE_GCS_OFF;
                res->end = base_addr + ACPIBASE_GCS_END;
+       } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) {
+               lpc_ich_enable_pmc_space(dev);
+               pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg);
+               base_addr = base_addr_cfg & 0xfffffe00;
+
+               res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
+               res->start = base_addr + ACPIBASE_PMC_OFF;
+               res->end = base_addr + ACPIBASE_PMC_END;
        }
 
        lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
@@ -952,28 +1010,35 @@ static int lpc_ich_probe(struct pci_dev *dev,
                return -ENOMEM;
 
        priv->chipset = id->driver_data;
-       priv->acpi.save = -1;
-       priv->acpi.base = ACPIBASE;
-       priv->acpi.ctrl = ACPICTRL;
 
-       priv->gpio.save = -1;
+       priv->actrl_pbase_save = -1;
+       priv->abase_save = -1;
+
+       priv->abase = ACPIBASE;
+       priv->actrl_pbase = ACPICTRL_PMCBASE;
+
+       priv->gctrl_save = -1;
        if (priv->chipset <= LPC_ICH5) {
-               priv->gpio.base = GPIOBASE_ICH0;
-               priv->gpio.ctrl = GPIOCTRL_ICH0;
+               priv->gbase = GPIOBASE_ICH0;
+               priv->gctrl = GPIOCTRL_ICH0;
        } else {
-               priv->gpio.base = GPIOBASE_ICH6;
-               priv->gpio.ctrl = GPIOCTRL_ICH6;
+               priv->gbase = GPIOBASE_ICH6;
+               priv->gctrl = GPIOCTRL_ICH6;
        }
 
        pci_set_drvdata(dev, priv);
 
-       ret = lpc_ich_init_wdt(dev);
-       if (!ret)
-               cell_added = true;
+       if (lpc_chipset_info[priv->chipset].iTCO_version) {
+               ret = lpc_ich_init_wdt(dev);
+               if (!ret)
+                       cell_added = true;
+       }
 
-       ret = lpc_ich_init_gpio(dev);
-       if (!ret)
-               cell_added = true;
+       if (lpc_chipset_info[priv->chipset].gpio_version) {
+               ret = lpc_ich_init_gpio(dev);
+               if (!ret)
+                       cell_added = true;
+       }
 
        /*
         * We only care if at least one or none of the cells registered
index 3bb05c03c68ded9f3e6c807a1c3559ec66830a94..4ee755034f3b2893899370ec1756d7e69018a8b8 100644 (file)
@@ -23,7 +23,6 @@
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
index 71aa14a6bfbbb4ffd061aeb91df739fc70684446..5f13cefe8defcf73ed33e1c179de6b922f88b1fc 100644 (file)
@@ -18,6 +18,7 @@
  * This driver is based on max8997.c
  */
 
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/max14577-private.h>
 
 static struct mfd_cell max14577_devs[] = {
-       { .name = "max14577-muic", },
+       {
+               .name = "max14577-muic",
+               .of_compatible = "maxim,max14577-muic",
+       },
        {
                .name = "max14577-regulator",
                .of_compatible = "maxim,max14577-regulator",
index f53d5823a3f73f47001cb5e6633e0b76028a8607..e5fce765accbfc763b7b0c9a2bed115755691a61 100644 (file)
@@ -121,6 +121,10 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
                dev_info(max77686->dev, "device found\n");
 
        max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
+       if (!max77686->rtc) {
+               dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n");
+               return -ENODEV;
+       }
        i2c_set_clientdata(max77686->rtc, max77686);
 
        max77686_irq_init(max77686);
index e0859987ab6bc5c078c81f3ce937170bfc8a2bee..c5535f01846684e48120056d9a45483690911c21 100644 (file)
@@ -148,9 +148,18 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
                dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
 
        max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
+       if (!max77693->muic) {
+               dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n");
+               return -ENODEV;
+       }
        i2c_set_clientdata(max77693->muic, max77693);
 
        max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
+       if (!max77693->haptic) {
+               dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n");
+               ret = -ENODEV;
+               goto err_i2c_haptic;
+       }
        i2c_set_clientdata(max77693->haptic, max77693);
 
        /*
@@ -184,8 +193,9 @@ err_mfd:
        max77693_irq_exit(max77693);
 err_irq:
 err_regmap_muic:
-       i2c_unregister_device(max77693->muic);
        i2c_unregister_device(max77693->haptic);
+err_i2c_haptic:
+       i2c_unregister_device(max77693->muic);
        return ret;
 }
 
index 176aa26fc787eae4ba7196edcfae535d22ae50be..a83eed5c15ca8ecfdad73e09e63e7b2e1ac773fe 100644 (file)
@@ -181,9 +181,18 @@ static int max8925_probe(struct i2c_client *client,
        mutex_init(&chip->io_lock);
 
        chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
+       if (!chip->rtc) {
+               dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
+               return -ENODEV;
+       }
        i2c_set_clientdata(chip->rtc, chip);
 
        chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
+       if (!chip->adc) {
+               dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
+               i2c_unregister_device(chip->rtc);
+               return -ENODEV;
+       }
        i2c_set_clientdata(chip->adc, chip);
 
        device_init_wakeup(&client->dev, 1);
index 5adede0fb04c8c5a82f7804d3138ab1f7a74f334..8cf7a015cfe501ddf3ce52c72abd6f45fdde579f 100644 (file)
@@ -208,10 +208,26 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
        mutex_init(&max8997->iolock);
 
        max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
+       if (!max8997->rtc) {
+               dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n");
+               return -ENODEV;
+       }
        i2c_set_clientdata(max8997->rtc, max8997);
+
        max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
+       if (!max8997->haptic) {
+               dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n");
+               ret = -ENODEV;
+               goto err_i2c_haptic;
+       }
        i2c_set_clientdata(max8997->haptic, max8997);
+
        max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
+       if (!max8997->muic) {
+               dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n");
+               ret = -ENODEV;
+               goto err_i2c_muic;
+       }
        i2c_set_clientdata(max8997->muic, max8997);
 
        pm_runtime_set_active(max8997->dev);
@@ -239,7 +255,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 err_mfd:
        mfd_remove_devices(max8997->dev);
        i2c_unregister_device(max8997->muic);
+err_i2c_muic:
        i2c_unregister_device(max8997->haptic);
+err_i2c_haptic:
        i2c_unregister_device(max8997->rtc);
        return ret;
 }
index 5d5e186b5d8bbbfed035725480fb85dc52a0fdb4..592db06098e69eabeb08c506cb3409c6d2ff2ca9 100644 (file)
@@ -215,6 +215,10 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
        mutex_init(&max8998->iolock);
 
        max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+       if (!max8998->rtc) {
+               dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n");
+               return -ENODEV;
+       }
        i2c_set_clientdata(max8998->rtc, max8998);
 
        max8998_irq_init(max8998);
index 38ab67829791b1b8d7b5c2d33d24ac66999f2a3f..702925e242c90597618bb1158faffa653516eae6 100644 (file)
@@ -140,6 +140,11 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
 
        mc13xxx->irq = spi->irq;
 
+       spi->max_speed_hz = spi->max_speed_hz ? : 26000000;
+       ret = spi_setup(spi);
+       if (ret)
+               return ret;
+
        mc13xxx->regmap = devm_regmap_init(&spi->dev, &regmap_mc13xxx_bus,
                                           &spi->dev,
                                           &mc13xxx_regmap_spi_config);
index 41c31b3ac94059e4dacf21565d3d411cd37da371..29d76986b40b83081474d1db946af72d5cdc1eb9 100644 (file)
@@ -12,7 +12,6 @@
  *  MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
  */
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
index 90b630ccc8bc65fa7381439cd190274834c50153..651e249287dc4292a127d30de326323b989c3b17 100644 (file)
@@ -665,55 +665,78 @@ static int usbhs_omap_probe(struct platform_device *pdev)
                goto err_mem;
        }
 
-       need_logic_fck = false;
+       /* Set all clocks as invalid to begin with */
+       omap->ehci_logic_fck = ERR_PTR(-ENODEV);
+       omap->init_60m_fclk = ERR_PTR(-ENODEV);
+       omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
+       omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
+       omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
+       omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
+
        for (i = 0; i < omap->nports; i++) {
-               if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
-                       is_ehci_hsic_mode(i))
-                               need_logic_fck |= true;
+               omap->utmi_clk[i] = ERR_PTR(-ENODEV);
+               omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
+               omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
        }
 
-       omap->ehci_logic_fck = ERR_PTR(-EINVAL);
-       if (need_logic_fck) {
-               omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
-               if (IS_ERR(omap->ehci_logic_fck)) {
-                       ret = PTR_ERR(omap->ehci_logic_fck);
-                       dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
+       /* for OMAP3 i.e. USBHS REV1 */
+       if (omap->usbhs_rev == OMAP_USBHS_REV1) {
+               need_logic_fck = false;
+               for (i = 0; i < omap->nports; i++) {
+                       if (is_ehci_phy_mode(pdata->port_mode[i]) ||
+                           is_ehci_tll_mode(pdata->port_mode[i]) ||
+                           is_ehci_hsic_mode(pdata->port_mode[i]))
+
+                               need_logic_fck |= true;
                }
+
+               if (need_logic_fck) {
+                       omap->ehci_logic_fck = devm_clk_get(dev,
+                                                           "usbhost_120m_fck");
+                       if (IS_ERR(omap->ehci_logic_fck)) {
+                               ret = PTR_ERR(omap->ehci_logic_fck);
+                               dev_err(dev, "usbhost_120m_fck failed:%d\n",
+                                       ret);
+                               goto err_mem;
+                       }
+               }
+               goto initialize;
        }
 
-       omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
+       /* for OMAP4+ i.e. USBHS REV2+ */
+       omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
        if (IS_ERR(omap->utmi_p1_gfclk)) {
                ret = PTR_ERR(omap->utmi_p1_gfclk);
                dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
-               goto err_p1_gfclk;
+               goto err_mem;
        }
 
-       omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
+       omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk");
        if (IS_ERR(omap->utmi_p2_gfclk)) {
                ret = PTR_ERR(omap->utmi_p2_gfclk);
                dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-               goto err_p2_gfclk;
+               goto err_mem;
        }
 
-       omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
+       omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
        if (IS_ERR(omap->xclk60mhsp1_ck)) {
                ret = PTR_ERR(omap->xclk60mhsp1_ck);
-               dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-               goto err_xclk60mhsp1;
+               dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret);
+               goto err_mem;
        }
 
-       omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
+       omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
        if (IS_ERR(omap->xclk60mhsp2_ck)) {
                ret = PTR_ERR(omap->xclk60mhsp2_ck);
-               dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-               goto err_xclk60mhsp2;
+               dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret);
+               goto err_mem;
        }
 
-       omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
+       omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
        if (IS_ERR(omap->init_60m_fclk)) {
                ret = PTR_ERR(omap->init_60m_fclk);
-               dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-               goto err_init60m;
+               dev_err(dev, "refclk_60m_int failed error:%d\n", ret);
+               goto err_mem;
        }
 
        for (i = 0; i < omap->nports; i++) {
@@ -727,55 +750,72 @@ static int usbhs_omap_probe(struct platform_device *pdev)
                 * platforms have all clocks and we can function without
                 * them
                 */
-               omap->utmi_clk[i] = clk_get(dev, clkname);
-               if (IS_ERR(omap->utmi_clk[i]))
-                       dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-                               clkname, PTR_ERR(omap->utmi_clk[i]));
+               omap->utmi_clk[i] = devm_clk_get(dev, clkname);
+               if (IS_ERR(omap->utmi_clk[i])) {
+                       ret = PTR_ERR(omap->utmi_clk[i]);
+                       dev_err(dev, "Failed to get clock : %s : %d\n",
+                               clkname, ret);
+                       goto err_mem;
+               }
 
                snprintf(clkname, sizeof(clkname),
                                "usb_host_hs_hsic480m_p%d_clk", i + 1);
-               omap->hsic480m_clk[i] = clk_get(dev, clkname);
-               if (IS_ERR(omap->hsic480m_clk[i]))
-                       dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-                               clkname, PTR_ERR(omap->hsic480m_clk[i]));
+               omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
+               if (IS_ERR(omap->hsic480m_clk[i])) {
+                       ret = PTR_ERR(omap->hsic480m_clk[i]);
+                       dev_err(dev, "Failed to get clock : %s : %d\n",
+                               clkname, ret);
+                       goto err_mem;
+               }
 
                snprintf(clkname, sizeof(clkname),
                                "usb_host_hs_hsic60m_p%d_clk", i + 1);
-               omap->hsic60m_clk[i] = clk_get(dev, clkname);
-               if (IS_ERR(omap->hsic60m_clk[i]))
-                       dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-                               clkname, PTR_ERR(omap->hsic60m_clk[i]));
+               omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
+               if (IS_ERR(omap->hsic60m_clk[i])) {
+                       ret = PTR_ERR(omap->hsic60m_clk[i]);
+                       dev_err(dev, "Failed to get clock : %s : %d\n",
+                               clkname, ret);
+                       goto err_mem;
+               }
        }
 
        if (is_ehci_phy_mode(pdata->port_mode[0])) {
-               /* for OMAP3, clk_set_parent fails */
                ret = clk_set_parent(omap->utmi_p1_gfclk,
                                        omap->xclk60mhsp1_ck);
-               if (ret != 0)
-                       dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
                ret = clk_set_parent(omap->utmi_p1_gfclk,
                                        omap->init_60m_fclk);
-               if (ret != 0)
-                       dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        }
 
        if (is_ehci_phy_mode(pdata->port_mode[1])) {
                ret = clk_set_parent(omap->utmi_p2_gfclk,
                                        omap->xclk60mhsp2_ck);
-               if (ret != 0)
-                       dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
                ret = clk_set_parent(omap->utmi_p2_gfclk,
                                                omap->init_60m_fclk);
-               if (ret != 0)
-                       dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
-                                       ret);
+               if (ret != 0) {
+                       dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
+                               ret);
+                       goto err_mem;
+               }
        }
 
+initialize:
        omap_usbhs_init(dev);
 
        if (dev->of_node) {
@@ -784,7 +824,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
                if (ret) {
                        dev_err(dev, "Failed to create DT children: %d\n", ret);
-                       goto err_alloc;
+                       goto err_mem;
                }
 
        } else {
@@ -792,40 +832,12 @@ static int usbhs_omap_probe(struct platform_device *pdev)
                if (ret) {
                        dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
                                                ret);
-                       goto err_alloc;
+                       goto err_mem;
                }
        }
 
        return 0;
 
-err_alloc:
-       for (i = 0; i < omap->nports; i++) {
-               if (!IS_ERR(omap->utmi_clk[i]))
-                       clk_put(omap->utmi_clk[i]);
-               if (!IS_ERR(omap->hsic60m_clk[i]))
-                       clk_put(omap->hsic60m_clk[i]);
-               if (!IS_ERR(omap->hsic480m_clk[i]))
-                       clk_put(omap->hsic480m_clk[i]);
-       }
-
-       clk_put(omap->init_60m_fclk);
-
-err_init60m:
-       clk_put(omap->xclk60mhsp2_ck);
-
-err_xclk60mhsp2:
-       clk_put(omap->xclk60mhsp1_ck);
-
-err_xclk60mhsp1:
-       clk_put(omap->utmi_p2_gfclk);
-
-err_p2_gfclk:
-       clk_put(omap->utmi_p1_gfclk);
-
-err_p1_gfclk:
-       if (!IS_ERR(omap->ehci_logic_fck))
-               clk_put(omap->ehci_logic_fck);
-
 err_mem:
        pm_runtime_disable(dev);
 
@@ -847,27 +859,6 @@ static int usbhs_omap_remove_child(struct device *dev, void *data)
  */
 static int usbhs_omap_remove(struct platform_device *pdev)
 {
-       struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
-       int i;
-
-       for (i = 0; i < omap->nports; i++) {
-               if (!IS_ERR(omap->utmi_clk[i]))
-                       clk_put(omap->utmi_clk[i]);
-               if (!IS_ERR(omap->hsic60m_clk[i]))
-                       clk_put(omap->hsic60m_clk[i]);
-               if (!IS_ERR(omap->hsic480m_clk[i]))
-                       clk_put(omap->hsic480m_clk[i]);
-       }
-
-       clk_put(omap->init_60m_fclk);
-       clk_put(omap->utmi_p1_gfclk);
-       clk_put(omap->utmi_p2_gfclk);
-       clk_put(omap->xclk60mhsp2_ck);
-       clk_put(omap->xclk60mhsp1_ck);
-
-       if (!IS_ERR(omap->ehci_logic_fck))
-               clk_put(omap->ehci_logic_fck);
-
        pm_runtime_disable(&pdev->dev);
 
        /* remove children */
index 5ee50f779ef60a86c1ab5e07782186e228054024..532eacab6b46ab78c69c9a73079db89bd462a0c8 100644 (file)
@@ -252,7 +252,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
                break;
        }
 
-       tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
+       tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch,
                                                GFP_KERNEL);
        if (!tll->ch_clk) {
                ret = -ENOMEM;
index b8941a556d7195e884e1f85d3e7017e89275a3f5..c1984b0d1b65273d64651f73e7f9c92fc0ef4e35 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/completion.h>
index 484fe66e6c884e7f32c9c9caca6473bcfc5b81e2..b97a97187ae992ebe9f1b55cb511636b012fde4c 100644 (file)
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/ssbi.h>
+#include <linux/regmap.h>
+#include <linux/of_platform.h>
 #include <linux/mfd/core.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/mfd/pm8xxx/core.h>
 
+#define        SSBI_REG_ADDR_IRQ_BASE          0x1BB
+
+#define        SSBI_REG_ADDR_IRQ_ROOT          (SSBI_REG_ADDR_IRQ_BASE + 0)
+#define        SSBI_REG_ADDR_IRQ_M_STATUS1     (SSBI_REG_ADDR_IRQ_BASE + 1)
+#define        SSBI_REG_ADDR_IRQ_M_STATUS2     (SSBI_REG_ADDR_IRQ_BASE + 2)
+#define        SSBI_REG_ADDR_IRQ_M_STATUS3     (SSBI_REG_ADDR_IRQ_BASE + 3)
+#define        SSBI_REG_ADDR_IRQ_M_STATUS4     (SSBI_REG_ADDR_IRQ_BASE + 4)
+#define        SSBI_REG_ADDR_IRQ_BLK_SEL       (SSBI_REG_ADDR_IRQ_BASE + 5)
+#define        SSBI_REG_ADDR_IRQ_IT_STATUS     (SSBI_REG_ADDR_IRQ_BASE + 6)
+#define        SSBI_REG_ADDR_IRQ_CONFIG        (SSBI_REG_ADDR_IRQ_BASE + 7)
+#define        SSBI_REG_ADDR_IRQ_RT_STATUS     (SSBI_REG_ADDR_IRQ_BASE + 8)
+
+#define        PM_IRQF_LVL_SEL                 0x01    /* level select */
+#define        PM_IRQF_MASK_FE                 0x02    /* mask falling edge */
+#define        PM_IRQF_MASK_RE                 0x04    /* mask rising edge */
+#define        PM_IRQF_CLR                     0x08    /* clear interrupt */
+#define        PM_IRQF_BITS_MASK               0x70
+#define        PM_IRQF_BITS_SHIFT              4
+#define        PM_IRQF_WRITE                   0x80
+
+#define        PM_IRQF_MASK_ALL                (PM_IRQF_MASK_FE | \
+                                       PM_IRQF_MASK_RE)
+
 #define REG_HWREV              0x002  /* PMIC4 revision */
 #define REG_HWREV_2            0x0E8  /* PMIC4 revision 2 */
 
+#define PM8921_NR_IRQS         256
+
+struct pm_irq_chip {
+       struct device           *dev;
+       struct regmap           *regmap;
+       spinlock_t              pm_irq_lock;
+       struct irq_domain       *irqdomain;
+       unsigned int            num_irqs;
+       unsigned int            num_blocks;
+       unsigned int            num_masters;
+       u8                      config[0];
+};
+
 struct pm8921 {
        struct device                   *dev;
        struct pm_irq_chip              *irq_chip;
 };
 
+static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
+                                unsigned int *ip)
+{
+       int     rc;
+
+       spin_lock(&chip->pm_irq_lock);
+       rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+       if (rc) {
+               pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
+               goto bail;
+       }
+
+       rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
+       if (rc)
+               pr_err("Failed Reading Status rc=%d\n", rc);
+bail:
+       spin_unlock(&chip->pm_irq_lock);
+       return rc;
+}
+
+static int
+pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)
+{
+       int     rc;
+
+       spin_lock(&chip->pm_irq_lock);
+       rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+       if (rc) {
+               pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
+               goto bail;
+       }
+
+       cp |= PM_IRQF_WRITE;
+       rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp);
+       if (rc)
+               pr_err("Failed Configuring IRQ rc=%d\n", rc);
+bail:
+       spin_unlock(&chip->pm_irq_lock);
+       return rc;
+}
+
+static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
+{
+       int pmirq, irq, i, ret = 0;
+       unsigned int bits;
+
+       ret = pm8xxx_read_block_irq(chip, block, &bits);
+       if (ret) {
+               pr_err("Failed reading %d block ret=%d", block, ret);
+               return ret;
+       }
+       if (!bits) {
+               pr_err("block bit set in master but no irqs: %d", block);
+               return 0;
+       }
+
+       /* Check IRQ bits */
+       for (i = 0; i < 8; i++) {
+               if (bits & (1 << i)) {
+                       pmirq = block * 8 + i;
+                       irq = irq_find_mapping(chip->irqdomain, pmirq);
+                       generic_handle_irq(irq);
+               }
+       }
+       return 0;
+}
+
+static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
+{
+       unsigned int blockbits;
+       int block_number, i, ret = 0;
+
+       ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master,
+                         &blockbits);
+       if (ret) {
+               pr_err("Failed to read master %d ret=%d\n", master, ret);
+               return ret;
+       }
+       if (!blockbits) {
+               pr_err("master bit set in root but no blocks: %d", master);
+               return 0;
+       }
+
+       for (i = 0; i < 8; i++)
+               if (blockbits & (1 << i)) {
+                       block_number = master * 8 + i;  /* block # */
+                       ret |= pm8xxx_irq_block_handler(chip, block_number);
+               }
+       return ret;
+}
+
+static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
+       struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+       unsigned int root;
+       int     i, ret, masters = 0;
+
+       chained_irq_enter(irq_chip, desc);
+
+       ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root);
+       if (ret) {
+               pr_err("Can't read root status ret=%d\n", ret);
+               return;
+       }
+
+       /* on pm8xxx series masters start from bit 1 of the root */
+       masters = root >> 1;
+
+       /* Read allowed masters for blocks. */
+       for (i = 0; i < chip->num_masters; i++)
+               if (masters & (1 << i))
+                       pm8xxx_irq_master_handler(chip, i);
+
+       chained_irq_exit(irq_chip, desc);
+}
+
+static void pm8xxx_irq_mask_ack(struct irq_data *d)
+{
+       struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+       unsigned int pmirq = irqd_to_hwirq(d);
+       int     irq_bit;
+       u8      block, config;
+
+       block = pmirq / 8;
+       irq_bit = pmirq % 8;
+
+       config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
+       pm8xxx_config_irq(chip, block, config);
+}
+
+static void pm8xxx_irq_unmask(struct irq_data *d)
+{
+       struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+       unsigned int pmirq = irqd_to_hwirq(d);
+       int     irq_bit;
+       u8      block, config;
+
+       block = pmirq / 8;
+       irq_bit = pmirq % 8;
+
+       config = chip->config[pmirq];
+       pm8xxx_config_irq(chip, block, config);
+}
+
+static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+       struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+       unsigned int pmirq = irqd_to_hwirq(d);
+       int irq_bit;
+       u8 block, config;
+
+       block = pmirq / 8;
+       irq_bit  = pmirq % 8;
+
+       chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
+                                                       | PM_IRQF_MASK_ALL;
+       if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+               if (flow_type & IRQF_TRIGGER_RISING)
+                       chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
+               if (flow_type & IRQF_TRIGGER_FALLING)
+                       chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
+       } else {
+               chip->config[pmirq] |= PM_IRQF_LVL_SEL;
+
+               if (flow_type & IRQF_TRIGGER_HIGH)
+                       chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
+               else
+                       chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
+       }
+
+       config = chip->config[pmirq] | PM_IRQF_CLR;
+       return pm8xxx_config_irq(chip, block, config);
+}
+
+static struct irq_chip pm8xxx_irq_chip = {
+       .name           = "pm8xxx",
+       .irq_mask_ack   = pm8xxx_irq_mask_ack,
+       .irq_unmask     = pm8xxx_irq_unmask,
+       .irq_set_type   = pm8xxx_irq_set_type,
+       .flags          = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
+};
+
+/**
+ * pm8xxx_get_irq_stat - get the status of the irq line
+ * @chip: pointer to identify a pmic irq controller
+ * @irq: the irq number
+ *
+ * The pm8xxx gpio and mpp rely on the interrupt block to read
+ * the values on their pins. This function is to facilitate reading
+ * the status of a gpio or an mpp line. The caller has to convert the
+ * gpio number to irq number.
+ *
+ * RETURNS:
+ * an int indicating the value read on that line
+ */
+static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
+{
+       int pmirq, rc;
+       unsigned int  block, bits, bit;
+       unsigned long flags;
+       struct irq_data *irq_data = irq_get_irq_data(irq);
+
+       pmirq = irq_data->hwirq;
+
+       block = pmirq / 8;
+       bit = pmirq % 8;
+
+       spin_lock_irqsave(&chip->pm_irq_lock, flags);
+
+       rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
+       if (rc) {
+               pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
+                       irq, pmirq, block, rc);
+               goto bail_out;
+       }
+
+       rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
+       if (rc) {
+               pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
+                       irq, pmirq, block, rc);
+               goto bail_out;
+       }
+
+       rc = (bits & (1 << bit)) ? 1 : 0;
+
+bail_out:
+       spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
+
+       return rc;
+}
+
+static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq,
+                                  irq_hw_number_t hwirq)
+{
+       struct pm_irq_chip *chip = d->host_data;
+
+       irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq);
+       irq_set_chip_data(irq, chip);
+#ifdef CONFIG_ARM
+       set_irq_flags(irq, IRQF_VALID);
+#else
+       irq_set_noprobe(irq);
+#endif
+       return 0;
+}
+
+static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
+       .xlate = irq_domain_xlate_twocell,
+       .map = pm8xxx_irq_domain_map,
+};
+
 static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
 {
        const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
@@ -81,42 +374,35 @@ static struct pm8xxx_drvdata pm8921_drvdata = {
        .pmic_read_irq_stat     = pm8921_read_irq_stat,
 };
 
-static int pm8921_add_subdevices(const struct pm8921_platform_data
-                                          *pdata,
-                                          struct pm8921 *pmic,
-                                          u32 rev)
-{
-       int ret = 0, irq_base = 0;
-       struct pm_irq_chip *irq_chip;
-
-       if (pdata->irq_pdata) {
-               pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS;
-               pdata->irq_pdata->irq_cdata.rev = rev;
-               irq_base = pdata->irq_pdata->irq_base;
-               irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+static const struct regmap_config ssbi_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 8,
+       .max_register = 0x3ff,
+       .fast_io = true,
+       .reg_read = ssbi_reg_read,
+       .reg_write = ssbi_reg_write
+};
 
-               if (IS_ERR(irq_chip)) {
-                       pr_err("Failed to init interrupts ret=%ld\n",
-                                       PTR_ERR(irq_chip));
-                       return PTR_ERR(irq_chip);
-               }
-               pmic->irq_chip = irq_chip;
-       }
-       return ret;
-}
+static const struct of_device_id pm8921_id_table[] = {
+       { .compatible = "qcom,pm8058", },
+       { .compatible = "qcom,pm8921", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, pm8921_id_table);
 
 static int pm8921_probe(struct platform_device *pdev)
 {
-       const struct pm8921_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct pm8921 *pmic;
-       int rc;
-       u8 val;
+       struct regmap *regmap;
+       int irq, rc;
+       unsigned int val;
        u32 rev;
+       struct pm_irq_chip *chip;
+       unsigned int nirqs = PM8921_NR_IRQS;
 
-       if (!pdata) {
-               pr_err("missing platform data\n");
-               return -EINVAL;
-       }
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
 
        pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
        if (!pmic) {
@@ -124,8 +410,13 @@ static int pm8921_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent,
+                                 &ssbi_regmap_config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
        /* Read PMIC chip revision */
-       rc = ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
+       rc = regmap_read(regmap, REG_HWREV, &val);
        if (rc) {
                pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
                return rc;
@@ -134,7 +425,7 @@ static int pm8921_probe(struct platform_device *pdev)
        rev = val;
 
        /* Read PMIC chip revision 2 */
-       rc = ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
+       rc = regmap_read(regmap, REG_HWREV_2, &val);
        if (rc) {
                pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
                        REG_HWREV_2, rc);
@@ -147,37 +438,56 @@ static int pm8921_probe(struct platform_device *pdev)
        pm8921_drvdata.pm_chip_data = pmic;
        platform_set_drvdata(pdev, &pm8921_drvdata);
 
-       rc = pm8921_add_subdevices(pdata, pmic, rev);
+       chip = devm_kzalloc(&pdev->dev, sizeof(*chip) +
+                                       sizeof(chip->config[0]) * nirqs,
+                                       GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       pmic->irq_chip = chip;
+       chip->dev = &pdev->dev;
+       chip->regmap = regmap;
+       chip->num_irqs = nirqs;
+       chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
+       chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
+       spin_lock_init(&chip->pm_irq_lock);
+
+       chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs,
+                                               &pm8xxx_irq_domain_ops,
+                                               chip);
+       if (!chip->irqdomain)
+               return -ENODEV;
+
+       irq_set_handler_data(irq, chip);
+       irq_set_chained_handler(irq, pm8xxx_irq_handler);
+       irq_set_irq_wake(irq, 1);
+
+       rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
        if (rc) {
-               pr_err("Cannot add subdevices rc=%d\n", rc);
-               goto err;
+               irq_set_chained_handler(irq, NULL);
+               irq_set_handler_data(irq, NULL);
+               irq_domain_remove(chip->irqdomain);
        }
 
-       /* gpio might not work if no irq device is found */
-       WARN_ON(pmic->irq_chip == NULL);
+       return rc;
+}
 
+static int pm8921_remove_child(struct device *dev, void *unused)
+{
+       platform_device_unregister(to_platform_device(dev));
        return 0;
-
-err:
-       mfd_remove_devices(pmic->dev);
-       return rc;
 }
 
 static int pm8921_remove(struct platform_device *pdev)
 {
-       struct pm8xxx_drvdata *drvdata;
-       struct pm8921 *pmic = NULL;
-
-       drvdata = platform_get_drvdata(pdev);
-       if (drvdata)
-               pmic = drvdata->pm_chip_data;
-       if (pmic) {
-               mfd_remove_devices(pmic->dev);
-               if (pmic->irq_chip) {
-                       pm8xxx_irq_exit(pmic->irq_chip);
-                       pmic->irq_chip = NULL;
-               }
-       }
+       int irq = platform_get_irq(pdev, 0);
+       struct pm8921 *pmic = pm8921_drvdata.pm_chip_data;
+       struct pm_irq_chip *chip = pmic->irq_chip;
+
+       device_for_each_child(&pdev->dev, NULL, pm8921_remove_child);
+       irq_set_chained_handler(irq, NULL);
+       irq_set_handler_data(irq, NULL);
+       irq_domain_remove(chip->irqdomain);
 
        return 0;
 }
@@ -188,6 +498,7 @@ static struct platform_driver pm8921_driver = {
        .driver         = {
                .name   = "pm8921-core",
                .owner  = THIS_MODULE,
+               .of_match_table = pm8921_id_table,
        },
 };
 
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c
deleted file mode 100644 (file)
index 1360e20..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (c) 2011, Code Aurora Forum. 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.
- */
-
-#define pr_fmt(fmt)    "%s: " fmt, __func__
-
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/mfd/pm8xxx/core.h>
-#include <linux/mfd/pm8xxx/irq.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* PMIC8xxx IRQ */
-
-#define        SSBI_REG_ADDR_IRQ_BASE          0x1BB
-
-#define        SSBI_REG_ADDR_IRQ_ROOT          (SSBI_REG_ADDR_IRQ_BASE + 0)
-#define        SSBI_REG_ADDR_IRQ_M_STATUS1     (SSBI_REG_ADDR_IRQ_BASE + 1)
-#define        SSBI_REG_ADDR_IRQ_M_STATUS2     (SSBI_REG_ADDR_IRQ_BASE + 2)
-#define        SSBI_REG_ADDR_IRQ_M_STATUS3     (SSBI_REG_ADDR_IRQ_BASE + 3)
-#define        SSBI_REG_ADDR_IRQ_M_STATUS4     (SSBI_REG_ADDR_IRQ_BASE + 4)
-#define        SSBI_REG_ADDR_IRQ_BLK_SEL       (SSBI_REG_ADDR_IRQ_BASE + 5)
-#define        SSBI_REG_ADDR_IRQ_IT_STATUS     (SSBI_REG_ADDR_IRQ_BASE + 6)
-#define        SSBI_REG_ADDR_IRQ_CONFIG        (SSBI_REG_ADDR_IRQ_BASE + 7)
-#define        SSBI_REG_ADDR_IRQ_RT_STATUS     (SSBI_REG_ADDR_IRQ_BASE + 8)
-
-#define        PM_IRQF_LVL_SEL                 0x01    /* level select */
-#define        PM_IRQF_MASK_FE                 0x02    /* mask falling edge */
-#define        PM_IRQF_MASK_RE                 0x04    /* mask rising edge */
-#define        PM_IRQF_CLR                     0x08    /* clear interrupt */
-#define        PM_IRQF_BITS_MASK               0x70
-#define        PM_IRQF_BITS_SHIFT              4
-#define        PM_IRQF_WRITE                   0x80
-
-#define        PM_IRQF_MASK_ALL                (PM_IRQF_MASK_FE | \
-                                       PM_IRQF_MASK_RE)
-
-struct pm_irq_chip {
-       struct device           *dev;
-       spinlock_t              pm_irq_lock;
-       unsigned int            devirq;
-       unsigned int            irq_base;
-       unsigned int            num_irqs;
-       unsigned int            num_blocks;
-       unsigned int            num_masters;
-       u8                      config[0];
-};
-
-static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp)
-{
-       return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp);
-}
-
-static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp)
-{
-       return pm8xxx_readb(chip->dev,
-                       SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp);
-}
-
-static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip)
-{
-       int     rc;
-
-       spin_lock(&chip->pm_irq_lock);
-       rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
-       if (rc) {
-               pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
-               goto bail;
-       }
-
-       rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
-       if (rc)
-               pr_err("Failed Reading Status rc=%d\n", rc);
-bail:
-       spin_unlock(&chip->pm_irq_lock);
-       return rc;
-}
-
-static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp)
-{
-       int     rc;
-
-       spin_lock(&chip->pm_irq_lock);
-       rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
-       if (rc) {
-               pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
-               goto bail;
-       }
-
-       cp |= PM_IRQF_WRITE;
-       rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp);
-       if (rc)
-               pr_err("Failed Configuring IRQ rc=%d\n", rc);
-bail:
-       spin_unlock(&chip->pm_irq_lock);
-       return rc;
-}
-
-static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
-{
-       int pmirq, irq, i, ret = 0;
-       u8 bits;
-
-       ret = pm8xxx_read_block_irq(chip, block, &bits);
-       if (ret) {
-               pr_err("Failed reading %d block ret=%d", block, ret);
-               return ret;
-       }
-       if (!bits) {
-               pr_err("block bit set in master but no irqs: %d", block);
-               return 0;
-       }
-
-       /* Check IRQ bits */
-       for (i = 0; i < 8; i++) {
-               if (bits & (1 << i)) {
-                       pmirq = block * 8 + i;
-                       irq = pmirq + chip->irq_base;
-                       generic_handle_irq(irq);
-               }
-       }
-       return 0;
-}
-
-static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
-{
-       u8 blockbits;
-       int block_number, i, ret = 0;
-
-       ret = pm8xxx_read_master_irq(chip, master, &blockbits);
-       if (ret) {
-               pr_err("Failed to read master %d ret=%d\n", master, ret);
-               return ret;
-       }
-       if (!blockbits) {
-               pr_err("master bit set in root but no blocks: %d", master);
-               return 0;
-       }
-
-       for (i = 0; i < 8; i++)
-               if (blockbits & (1 << i)) {
-                       block_number = master * 8 + i;  /* block # */
-                       ret |= pm8xxx_irq_block_handler(chip, block_number);
-               }
-       return ret;
-}
-
-static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
-       struct irq_chip *irq_chip = irq_desc_get_chip(desc);
-       u8      root;
-       int     i, ret, masters = 0;
-
-       ret = pm8xxx_read_root_irq(chip, &root);
-       if (ret) {
-               pr_err("Can't read root status ret=%d\n", ret);
-               return;
-       }
-
-       /* on pm8xxx series masters start from bit 1 of the root */
-       masters = root >> 1;
-
-       /* Read allowed masters for blocks. */
-       for (i = 0; i < chip->num_masters; i++)
-               if (masters & (1 << i))
-                       pm8xxx_irq_master_handler(chip, i);
-
-       irq_chip->irq_ack(&desc->irq_data);
-}
-
-static void pm8xxx_irq_mask_ack(struct irq_data *d)
-{
-       struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-       unsigned int pmirq = d->irq - chip->irq_base;
-       int     master, irq_bit;
-       u8      block, config;
-
-       block = pmirq / 8;
-       master = block / 8;
-       irq_bit = pmirq % 8;
-
-       config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
-       pm8xxx_config_irq(chip, block, config);
-}
-
-static void pm8xxx_irq_unmask(struct irq_data *d)
-{
-       struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-       unsigned int pmirq = d->irq - chip->irq_base;
-       int     master, irq_bit;
-       u8      block, config;
-
-       block = pmirq / 8;
-       master = block / 8;
-       irq_bit = pmirq % 8;
-
-       config = chip->config[pmirq];
-       pm8xxx_config_irq(chip, block, config);
-}
-
-static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
-       struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-       unsigned int pmirq = d->irq - chip->irq_base;
-       int master, irq_bit;
-       u8 block, config;
-
-       block = pmirq / 8;
-       master = block / 8;
-       irq_bit  = pmirq % 8;
-
-       chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
-                                                       | PM_IRQF_MASK_ALL;
-       if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-               if (flow_type & IRQF_TRIGGER_RISING)
-                       chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
-               if (flow_type & IRQF_TRIGGER_FALLING)
-                       chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
-       } else {
-               chip->config[pmirq] |= PM_IRQF_LVL_SEL;
-
-               if (flow_type & IRQF_TRIGGER_HIGH)
-                       chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
-               else
-                       chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
-       }
-
-       config = chip->config[pmirq] | PM_IRQF_CLR;
-       return pm8xxx_config_irq(chip, block, config);
-}
-
-static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-       return 0;
-}
-
-static struct irq_chip pm8xxx_irq_chip = {
-       .name           = "pm8xxx",
-       .irq_mask_ack   = pm8xxx_irq_mask_ack,
-       .irq_unmask     = pm8xxx_irq_unmask,
-       .irq_set_type   = pm8xxx_irq_set_type,
-       .irq_set_wake   = pm8xxx_irq_set_wake,
-       .flags          = IRQCHIP_MASK_ON_SUSPEND,
-};
-
-/**
- * pm8xxx_get_irq_stat - get the status of the irq line
- * @chip: pointer to identify a pmic irq controller
- * @irq: the irq number
- *
- * The pm8xxx gpio and mpp rely on the interrupt block to read
- * the values on their pins. This function is to facilitate reading
- * the status of a gpio or an mpp line. The caller has to convert the
- * gpio number to irq number.
- *
- * RETURNS:
- * an int indicating the value read on that line
- */
-int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
-{
-       int pmirq, rc;
-       u8  block, bits, bit;
-       unsigned long flags;
-
-       if (chip == NULL || irq < chip->irq_base ||
-                       irq >= chip->irq_base + chip->num_irqs)
-               return -EINVAL;
-
-       pmirq = irq - chip->irq_base;
-
-       block = pmirq / 8;
-       bit = pmirq % 8;
-
-       spin_lock_irqsave(&chip->pm_irq_lock, flags);
-
-       rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
-       if (rc) {
-               pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
-                       irq, pmirq, block, rc);
-               goto bail_out;
-       }
-
-       rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
-       if (rc) {
-               pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
-                       irq, pmirq, block, rc);
-               goto bail_out;
-       }
-
-       rc = (bits & (1 << bit)) ? 1 : 0;
-
-bail_out:
-       spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
-
-       return rc;
-}
-EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat);
-
-struct pm_irq_chip *  pm8xxx_irq_init(struct device *dev,
-                               const struct pm8xxx_irq_platform_data *pdata)
-{
-       struct pm_irq_chip  *chip;
-       int devirq, rc;
-       unsigned int pmirq;
-
-       if (!pdata) {
-               pr_err("No platform data\n");
-               return ERR_PTR(-EINVAL);
-       }
-
-       devirq = pdata->devirq;
-       if (devirq < 0) {
-               pr_err("missing devirq\n");
-               rc = devirq;
-               return ERR_PTR(-EINVAL);
-       }
-
-       chip = kzalloc(sizeof(struct pm_irq_chip)
-                       + sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL);
-       if (!chip) {
-               pr_err("Cannot alloc pm_irq_chip struct\n");
-               return ERR_PTR(-EINVAL);
-       }
-
-       chip->dev = dev;
-       chip->devirq = devirq;
-       chip->irq_base = pdata->irq_base;
-       chip->num_irqs = pdata->irq_cdata.nirqs;
-       chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
-       chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
-       spin_lock_init(&chip->pm_irq_lock);
-
-       for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) {
-               irq_set_chip_and_handler(chip->irq_base + pmirq,
-                               &pm8xxx_irq_chip,
-                               handle_level_irq);
-               irq_set_chip_data(chip->irq_base + pmirq, chip);
-#ifdef CONFIG_ARM
-               set_irq_flags(chip->irq_base + pmirq, IRQF_VALID);
-#else
-               irq_set_noprobe(chip->irq_base + pmirq);
-#endif
-       }
-
-       irq_set_irq_type(devirq, pdata->irq_trigger_flag);
-       irq_set_handler_data(devirq, chip);
-       irq_set_chained_handler(devirq, pm8xxx_irq_handler);
-       set_irq_wake(devirq, 1);
-
-       return chip;
-}
-
-int pm8xxx_irq_exit(struct pm_irq_chip *chip)
-{
-       irq_set_chained_handler(chip->devirq, NULL);
-       kfree(chip);
-       return 0;
-}
index b41db59687065921cf5843b745110f97d93b4ec6..bb85020202741d9328add483133fc212eeaa621c 100644 (file)
@@ -22,7 +22,6 @@
  */
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/mfd/rc5t583.h>
 
index d346146249a2d387dbb5485c8517b5e662fac72a..c79569750be9d1268c81dbfab12ed59573b01a35 100644 (file)
@@ -19,7 +19,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
index c8f345f7e9a2b574c69d5c2d47fa3dbcf1390993..663f8a37aa6b27dd263e1f4d1c1345cff141b782 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
new file mode 100644 (file)
index 0000000..b53b9d4
--- /dev/null
@@ -0,0 +1,760 @@
+/* Driver for Realtek USB card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Roger Tseng <rogerable@realtek.com>
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/usb.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rtsx_usb.h>
+
+static int polling_pipe = 1;
+module_param(polling_pipe, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)");
+
+static struct mfd_cell rtsx_usb_cells[] = {
+       [RTSX_USB_SD_CARD] = {
+               .name = "rtsx_usb_sdmmc",
+               .pdata_size = 0,
+       },
+       [RTSX_USB_MS_CARD] = {
+               .name = "rtsx_usb_ms",
+               .pdata_size = 0,
+       },
+};
+
+static void rtsx_usb_sg_timed_out(unsigned long data)
+{
+       struct rtsx_ucr *ucr = (struct rtsx_ucr *)data;
+
+       dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
+       usb_sg_cancel(&ucr->current_sg);
+
+       /* we know the cancellation is caused by time-out */
+       ucr->current_sg.status = -ETIMEDOUT;
+}
+
+static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
+               unsigned int pipe, struct scatterlist *sg, int num_sg,
+               unsigned int length, unsigned int *act_len, int timeout)
+{
+       int ret;
+
+       dev_dbg(&ucr->pusb_intf->dev, "%s: xfer %u bytes, %d entries\n",
+                       __func__, length, num_sg);
+       ret = usb_sg_init(&ucr->current_sg, ucr->pusb_dev, pipe, 0,
+                       sg, num_sg, length, GFP_NOIO);
+       if (ret)
+               return ret;
+
+       ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
+       add_timer(&ucr->sg_timer);
+       usb_sg_wait(&ucr->current_sg);
+       del_timer(&ucr->sg_timer);
+
+       if (act_len)
+               *act_len = ucr->current_sg.bytes;
+
+       return ucr->current_sg.status;
+}
+
+int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+                             void *buf, unsigned int len, int num_sg,
+                             unsigned int *act_len, int timeout)
+{
+       if (timeout < 600)
+               timeout = 600;
+
+       if (num_sg)
+               return rtsx_usb_bulk_transfer_sglist(ucr, pipe,
+                               (struct scatterlist *)buf, num_sg, len, act_len,
+                               timeout);
+       else
+               return usb_bulk_msg(ucr->pusb_dev, pipe, buf, len, act_len,
+                               timeout);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_transfer_data);
+
+static inline void rtsx_usb_seq_cmd_hdr(struct rtsx_ucr *ucr,
+               u16 addr, u16 len, u8 seq_type)
+{
+       rtsx_usb_cmd_hdr_tag(ucr);
+
+       ucr->cmd_buf[PACKET_TYPE] = seq_type;
+       ucr->cmd_buf[5] = (u8)(len >> 8);
+       ucr->cmd_buf[6] = (u8)len;
+       ucr->cmd_buf[8] = (u8)(addr >> 8);
+       ucr->cmd_buf[9] = (u8)addr;
+
+       if (seq_type == SEQ_WRITE)
+               ucr->cmd_buf[STAGE_FLAG] = 0;
+       else
+               ucr->cmd_buf[STAGE_FLAG] = STAGE_R;
+}
+
+static int rtsx_usb_seq_write_register(struct rtsx_ucr *ucr,
+               u16 addr, u16 len, u8 *data)
+{
+       u16 cmd_len = ALIGN(SEQ_WRITE_DATA_OFFSET + len, 4);
+
+       if (!data)
+               return -EINVAL;
+
+       if (cmd_len > IOBUF_SIZE)
+               return -EINVAL;
+
+       rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_WRITE);
+       memcpy(ucr->cmd_buf + SEQ_WRITE_DATA_OFFSET, data, len);
+
+       return rtsx_usb_transfer_data(ucr,
+                       usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
+                       ucr->cmd_buf, cmd_len, 0, NULL, 100);
+}
+
+static int rtsx_usb_seq_read_register(struct rtsx_ucr *ucr,
+               u16 addr, u16 len, u8 *data)
+{
+       int i, ret;
+       u16 rsp_len = round_down(len, 4);
+       u16 res_len = len - rsp_len;
+
+       if (!data)
+               return -EINVAL;
+
+       /* 4-byte aligned part */
+       if (rsp_len) {
+               rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_READ);
+               ret = rtsx_usb_transfer_data(ucr,
+                               usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
+                               ucr->cmd_buf, 12, 0, NULL, 100);
+               if (ret)
+                       return ret;
+
+               ret = rtsx_usb_transfer_data(ucr,
+                               usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN),
+                               data, rsp_len, 0, NULL, 100);
+               if (ret)
+                       return ret;
+       }
+
+       /* unaligned part */
+       for (i = 0; i < res_len; i++) {
+               ret = rtsx_usb_read_register(ucr, addr + rsp_len + i,
+                               data + rsp_len + i);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len)
+{
+       return rtsx_usb_seq_read_register(ucr, PPBUF_BASE2, (u16)buf_len, buf);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_read_ppbuf);
+
+int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len)
+{
+       return rtsx_usb_seq_write_register(ucr, PPBUF_BASE2, (u16)buf_len, buf);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_write_ppbuf);
+
+int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr,
+               u8 mask, u8 data)
+{
+       u16 value, index;
+
+       addr |= EP0_WRITE_REG_CMD << EP0_OP_SHIFT;
+       value = swab16(addr);
+       index = mask | data << 8;
+
+       return usb_control_msg(ucr->pusb_dev,
+                       usb_sndctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
+                       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                       value, index, NULL, 0, 100);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register);
+
+int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
+{
+       u16 value;
+
+       if (!data)
+               return -EINVAL;
+       *data = 0;
+
+       addr |= EP0_READ_REG_CMD << EP0_OP_SHIFT;
+       value = swab16(addr);
+
+       return usb_control_msg(ucr->pusb_dev,
+                       usb_rcvctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
+                       USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                       value, 0, data, 1, 100);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register);
+
+void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type, u16 reg_addr,
+               u8 mask, u8 data)
+{
+       int i;
+
+       if (ucr->cmd_idx < (IOBUF_SIZE - CMD_OFFSET) / 4) {
+               i = CMD_OFFSET + ucr->cmd_idx * 4;
+
+               ucr->cmd_buf[i++] = ((cmd_type & 0x03) << 6) |
+                       (u8)((reg_addr >> 8) & 0x3F);
+               ucr->cmd_buf[i++] = (u8)reg_addr;
+               ucr->cmd_buf[i++] = mask;
+               ucr->cmd_buf[i++] = data;
+
+               ucr->cmd_idx++;
+       }
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_add_cmd);
+
+int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout)
+{
+       int ret;
+
+       ucr->cmd_buf[CNT_H] = (u8)(ucr->cmd_idx >> 8);
+       ucr->cmd_buf[CNT_L] = (u8)(ucr->cmd_idx);
+       ucr->cmd_buf[STAGE_FLAG] = flag;
+
+       ret = rtsx_usb_transfer_data(ucr,
+                       usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
+                       ucr->cmd_buf, ucr->cmd_idx * 4 + CMD_OFFSET,
+                       0, NULL, timeout);
+       if (ret) {
+               rtsx_usb_clear_fsm_err(ucr);
+               return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_send_cmd);
+
+int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout)
+{
+       if (rsp_len <= 0)
+               return -EINVAL;
+
+       rsp_len = ALIGN(rsp_len, 4);
+
+       return rtsx_usb_transfer_data(ucr,
+                       usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN),
+                       ucr->rsp_buf, rsp_len, 0, NULL, timeout);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_get_rsp);
+
+static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr *ucr, u16 *status)
+{
+       int ret;
+
+       rtsx_usb_init_cmd(ucr);
+       rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_EXIST, 0x00, 0x00);
+       rtsx_usb_add_cmd(ucr, READ_REG_CMD, OCPSTAT, 0x00, 0x00);
+       ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
+       if (ret)
+               return ret;
+
+       ret = rtsx_usb_get_rsp(ucr, 2, 100);
+       if (ret)
+               return ret;
+
+       *status = ((ucr->rsp_buf[0] >> 2) & 0x0f) |
+                 ((ucr->rsp_buf[1] & 0x03) << 4);
+
+       return 0;
+}
+
+int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
+{
+       int ret;
+
+       if (!status)
+               return -EINVAL;
+
+       if (polling_pipe == 0)
+               ret = usb_control_msg(ucr->pusb_dev,
+                               usb_rcvctrlpipe(ucr->pusb_dev, 0),
+                               RTSX_USB_REQ_POLL,
+                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               0, 0, status, 2, 100);
+       else
+               ret = rtsx_usb_get_status_with_bulk(ucr, status);
+
+       /* usb_control_msg may return positive when success */
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_get_card_status);
+
+static int rtsx_usb_write_phy_register(struct rtsx_ucr *ucr, u8 addr, u8 val)
+{
+       dev_dbg(&ucr->pusb_intf->dev, "Write 0x%x to phy register 0x%x\n",
+                       val, addr);
+
+       rtsx_usb_init_cmd(ucr);
+
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VSTAIN, 0xFF, val);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL,
+                       0xFF, (addr >> 4) & 0x0F);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01);
+
+       return rtsx_usb_send_cmd(ucr, MODE_C, 100);
+}
+
+int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask, u8 data)
+{
+       rtsx_usb_init_cmd(ucr);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, addr, mask, data);
+       return rtsx_usb_send_cmd(ucr, MODE_C, 100);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_write_register);
+
+int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
+{
+       int ret;
+
+       if (data != NULL)
+               *data = 0;
+
+       rtsx_usb_init_cmd(ucr);
+       rtsx_usb_add_cmd(ucr, READ_REG_CMD, addr, 0, 0);
+       ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
+       if (ret)
+               return ret;
+
+       ret = rtsx_usb_get_rsp(ucr, 1, 100);
+       if (ret)
+               return ret;
+
+       if (data != NULL)
+               *data = ucr->rsp_buf[0];
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_read_register);
+
+static inline u8 double_ssc_depth(u8 depth)
+{
+       return (depth > 1) ? (depth - 1) : depth;
+}
+
+static u8 revise_ssc_depth(u8 ssc_depth, u8 div)
+{
+       if (div > CLK_DIV_1) {
+               if (ssc_depth > div - 1)
+                       ssc_depth -= (div - 1);
+               else
+                       ssc_depth = SSC_DEPTH_2M;
+       }
+
+       return ssc_depth;
+}
+
+int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock,
+               u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
+{
+       int ret;
+       u8 n, clk_divider, mcu_cnt, div;
+
+       if (!card_clock) {
+               ucr->cur_clk = 0;
+               return 0;
+       }
+
+       if (initial_mode) {
+               /* We use 250k(around) here, in initial stage */
+               clk_divider = SD_CLK_DIVIDE_128;
+               card_clock = 30000000;
+       } else {
+               clk_divider = SD_CLK_DIVIDE_0;
+       }
+
+       ret = rtsx_usb_write_register(ucr, SD_CFG1,
+                       SD_CLK_DIVIDE_MASK, clk_divider);
+       if (ret < 0)
+               return ret;
+
+       card_clock /= 1000000;
+       dev_dbg(&ucr->pusb_intf->dev,
+                       "Switch card clock to %dMHz\n", card_clock);
+
+       if (!initial_mode && double_clk)
+               card_clock *= 2;
+       dev_dbg(&ucr->pusb_intf->dev,
+                       "Internal SSC clock: %dMHz (cur_clk = %d)\n",
+                       card_clock, ucr->cur_clk);
+
+       if (card_clock == ucr->cur_clk)
+               return 0;
+
+       /* Converting clock value into internal settings: n and div */
+       n = card_clock - 2;
+       if ((card_clock <= 2) || (n > MAX_DIV_N))
+               return -EINVAL;
+
+       mcu_cnt = 60/card_clock + 3;
+       if (mcu_cnt > 15)
+               mcu_cnt = 15;
+
+       /* Make sure that the SSC clock div_n is not less than MIN_DIV_N */
+
+       div = CLK_DIV_1;
+       while (n < MIN_DIV_N && div < CLK_DIV_4) {
+               n = (n + 2) * 2 - 2;
+               div++;
+       }
+       dev_dbg(&ucr->pusb_intf->dev, "n = %d, div = %d\n", n, div);
+
+       if (double_clk)
+               ssc_depth = double_ssc_depth(ssc_depth);
+
+       ssc_depth = revise_ssc_depth(ssc_depth, div);
+       dev_dbg(&ucr->pusb_intf->dev, "ssc_depth = %d\n", ssc_depth);
+
+       rtsx_usb_init_cmd(ucr);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV,
+                       0x3F, (div << 4) | mcu_cnt);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL2,
+                       SSC_DEPTH_MASK, ssc_depth);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
+       if (vpclk) {
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+                               PHASE_NOT_RESET, 0);
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+                               PHASE_NOT_RESET, PHASE_NOT_RESET);
+       }
+
+       ret = rtsx_usb_send_cmd(ucr, MODE_C, 2000);
+       if (ret < 0)
+               return ret;
+
+       ret = rtsx_usb_write_register(ucr, SSC_CTL1, 0xff,
+                       SSC_RSTB | SSC_8X_EN | SSC_SEL_4M);
+       if (ret < 0)
+               return ret;
+
+       /* Wait SSC clock stable */
+       usleep_range(100, 1000);
+
+       ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0);
+       if (ret < 0)
+               return ret;
+
+       ucr->cur_clk = card_clock;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_switch_clock);
+
+int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card)
+{
+       int ret;
+       u16 val;
+       u16 cd_mask[] = {
+               [RTSX_USB_SD_CARD] = (CD_MASK & ~SD_CD),
+               [RTSX_USB_MS_CARD] = (CD_MASK & ~MS_CD)
+       };
+
+       ret = rtsx_usb_get_card_status(ucr, &val);
+       /*
+        * If get status fails, return 0 (ok) for the exclusive check
+        * and let the flow fail at somewhere else.
+        */
+       if (ret)
+               return 0;
+
+       if (val & cd_mask[card])
+               return -EIO;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_card_exclusive_check);
+
+static int rtsx_usb_reset_chip(struct rtsx_ucr *ucr)
+{
+       int ret;
+       u8 val;
+
+       rtsx_usb_init_cmd(ucr);
+
+       if (CHECK_PKG(ucr, LQFP48)) {
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
+                               LDO3318_PWR_MASK, LDO_SUSPEND);
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
+                               FORCE_LDO_POWERB, FORCE_LDO_POWERB);
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1,
+                               0x30, 0x10);
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5,
+                               0x03, 0x01);
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6,
+                               0x0C, 0x04);
+       }
+
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SYS_DUMMY0, NYET_MSAK, NYET_EN);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CD_DEGLITCH_WIDTH, 0xFF, 0x08);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
+                       CD_DEGLITCH_EN, XD_CD_DEGLITCH_EN, 0x0);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+                       SD30_DRIVE_MASK, DRIVER_TYPE_D);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
+                       CARD_DRIVE_SEL, SD20_DRIVE_MASK, 0x0);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG, 0xE0, 0x0);
+
+       if (ucr->is_rts5179)
+               rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
+                               CARD_PULL_CTL5, 0x03, 0x01);
+
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DMA1_CTL,
+                      EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL);
+       rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_INT_PEND,
+                       XD_INT | MS_INT | SD_INT,
+                       XD_INT | MS_INT | SD_INT);
+
+       ret = rtsx_usb_send_cmd(ucr, MODE_C, 100);
+       if (ret)
+               return ret;
+
+       /* config non-crystal mode */
+       rtsx_usb_read_register(ucr, CFG_MODE, &val);
+       if ((val & XTAL_FREE) || ((val & CLK_MODE_MASK) == CLK_MODE_NON_XTAL)) {
+               ret = rtsx_usb_write_phy_register(ucr, 0xC2, 0x7C);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int rtsx_usb_init_chip(struct rtsx_ucr *ucr)
+{
+       int ret;
+       u8 val;
+
+       rtsx_usb_clear_fsm_err(ucr);
+
+       /* power on SSC */
+       ret = rtsx_usb_write_register(ucr,
+                       FPDCTL, SSC_POWER_MASK, SSC_POWER_ON);
+       if (ret)
+               return ret;
+
+       usleep_range(100, 1000);
+       ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0x00);
+       if (ret)
+               return ret;
+
+       /* determine IC version */
+       ret = rtsx_usb_read_register(ucr, HW_VERSION, &val);
+       if (ret)
+               return ret;
+
+       ucr->ic_version = val & HW_VER_MASK;
+
+       /* determine package */
+       ret = rtsx_usb_read_register(ucr, CARD_SHARE_MODE, &val);
+       if (ret)
+               return ret;
+
+       if (val & CARD_SHARE_LQFP_SEL) {
+               ucr->package = LQFP48;
+               dev_dbg(&ucr->pusb_intf->dev, "Package: LQFP48\n");
+       } else {
+               ucr->package = QFN24;
+               dev_dbg(&ucr->pusb_intf->dev, "Package: QFN24\n");
+       }
+
+       /* determine IC variations */
+       rtsx_usb_read_register(ucr, CFG_MODE_1, &val);
+       if (val & RTS5179) {
+               ucr->is_rts5179 = true;
+               dev_dbg(&ucr->pusb_intf->dev, "Device is rts5179\n");
+       } else {
+               ucr->is_rts5179 = false;
+       }
+
+       return rtsx_usb_reset_chip(ucr);
+}
+
+static int rtsx_usb_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct usb_device *usb_dev = interface_to_usbdev(intf);
+       struct rtsx_ucr *ucr;
+       int ret;
+
+       dev_dbg(&intf->dev,
+               ": Realtek USB Card Reader found at bus %03d address %03d\n",
+                usb_dev->bus->busnum, usb_dev->devnum);
+
+       ucr = devm_kzalloc(&intf->dev, sizeof(*ucr), GFP_KERNEL);
+       if (!ucr)
+               return -ENOMEM;
+
+       ucr->pusb_dev = usb_dev;
+
+       ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE,
+                       GFP_KERNEL, &ucr->iobuf_dma);
+       if (!ucr->iobuf)
+               return -ENOMEM;
+
+       usb_set_intfdata(intf, ucr);
+
+       ucr->vendor_id = id->idVendor;
+       ucr->product_id = id->idProduct;
+       ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;
+
+       mutex_init(&ucr->dev_mutex);
+
+       ucr->pusb_intf = intf;
+
+       /* initialize */
+       ret = rtsx_usb_init_chip(ucr);
+       if (ret)
+               goto out_init_fail;
+
+       ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells,
+                       ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL);
+       if (ret)
+               goto out_init_fail;
+
+       /* initialize USB SG transfer timer */
+       init_timer(&ucr->sg_timer);
+       setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr);
+#ifdef CONFIG_PM
+       intf->needs_remote_wakeup = 1;
+       usb_enable_autosuspend(usb_dev);
+#endif
+
+       return 0;
+
+out_init_fail:
+       usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
+                       ucr->iobuf_dma);
+       return ret;
+}
+
+static void rtsx_usb_disconnect(struct usb_interface *intf)
+{
+       struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+       dev_dbg(&intf->dev, "%s called\n", __func__);
+
+       mfd_remove_devices(&intf->dev);
+
+       usb_set_intfdata(ucr->pusb_intf, NULL);
+       usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
+                       ucr->iobuf_dma);
+}
+
+#ifdef CONFIG_PM
+static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct rtsx_ucr *ucr =
+               (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+       dev_dbg(&intf->dev, "%s called with pm message 0x%04u\n",
+                       __func__, message.event);
+
+       mutex_lock(&ucr->dev_mutex);
+       rtsx_usb_turn_off_led(ucr);
+       mutex_unlock(&ucr->dev_mutex);
+       return 0;
+}
+
+static int rtsx_usb_resume(struct usb_interface *intf)
+{
+       return 0;
+}
+
+static int rtsx_usb_reset_resume(struct usb_interface *intf)
+{
+       struct rtsx_ucr *ucr =
+               (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+       rtsx_usb_reset_chip(ucr);
+       return 0;
+}
+
+#else /* CONFIG_PM */
+
+#define rtsx_usb_suspend NULL
+#define rtsx_usb_resume NULL
+#define rtsx_usb_reset_resume NULL
+
+#endif /* CONFIG_PM */
+
+
+static int rtsx_usb_pre_reset(struct usb_interface *intf)
+{
+       struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+       mutex_lock(&ucr->dev_mutex);
+       return 0;
+}
+
+static int rtsx_usb_post_reset(struct usb_interface *intf)
+{
+       struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+       mutex_unlock(&ucr->dev_mutex);
+       return 0;
+}
+
+static struct usb_device_id rtsx_usb_usb_ids[] = {
+       { USB_DEVICE(0x0BDA, 0x0129) },
+       { USB_DEVICE(0x0BDA, 0x0139) },
+       { USB_DEVICE(0x0BDA, 0x0140) },
+       { }
+};
+
+static struct usb_driver rtsx_usb_driver = {
+       .name                   = "rtsx_usb",
+       .probe                  = rtsx_usb_probe,
+       .disconnect             = rtsx_usb_disconnect,
+       .suspend                = rtsx_usb_suspend,
+       .resume                 = rtsx_usb_resume,
+       .reset_resume           = rtsx_usb_reset_resume,
+       .pre_reset              = rtsx_usb_pre_reset,
+       .post_reset             = rtsx_usb_post_reset,
+       .id_table               = rtsx_usb_usb_ids,
+       .supports_autosuspend   = 1,
+       .soft_unbind            = 1,
+};
+
+module_usb_driver(rtsx_usb_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Roger Tseng <rogerable@realtek.com>");
+MODULE_DESCRIPTION("Realtek USB Card Reader Driver");
index 281a827472754ad9b79939e67eb11820d70e3eaa..1cf27521fff4f2fe4a2892d651b5d47e4721286e 100644 (file)
@@ -60,6 +60,7 @@ static const struct mfd_cell s5m8767_devs[] = {
                .name = "s5m-rtc",
        }, {
                .name = "s5m8767-clk",
+               .of_compatible = "samsung,s5m8767-clk",
        }
 };
 
@@ -68,6 +69,7 @@ static const struct mfd_cell s2mps11_devs[] = {
                .name = "s2mps11-pmic",
        }, {
                .name = "s2mps11-clk",
+               .of_compatible = "samsung,s2mps11-clk",
        }
 };
 
@@ -78,6 +80,7 @@ static const struct mfd_cell s2mps14_devs[] = {
                .name = "s2mps14-rtc",
        }, {
                .name = "s2mps14-clk",
+               .of_compatible = "samsung,s2mps14-clk",
        }
 };
 
@@ -295,6 +298,13 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        switch (sec_pmic->device_type) {
        case S2MPA01:
                regmap = &s2mpa01_regmap_config;
+               /*
+                * The rtc-s5m driver does not support S2MPA01 and there
+                * is no mfd_cell for S2MPA01 RTC device.
+                * However we must pass something to devm_regmap_init_i2c()
+                * so use S5M-like regmap config even though it wouldn't work.
+                */
+               regmap_rtc = &s5m_rtc_regmap_config;
                break;
        case S2MPS11X:
                regmap = &s2mps11_regmap_config;
@@ -344,7 +354,7 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                ret = PTR_ERR(sec_pmic->regmap_rtc);
                dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
                        ret);
-               return ret;
+               goto err_regmap_rtc;
        }
 
        if (pdata && pdata->cfg_pmic_irq)
@@ -385,14 +395,15 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        }
 
        if (ret)
-               goto err;
+               goto err_mfd;
 
        device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
 
        return ret;
 
-err:
+err_mfd:
        sec_irq_exit(sec_pmic);
+err_regmap_rtc:
        i2c_unregister_device(sec_pmic->rtc);
        return ret;
 }
index 24ae3d8421c5196184d794a76c369eb79051b2ed..90112d4cc9059199ff1d4855bdadb42eb867a8f3 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/gpio.h>
index 42ccd05445133444e52be15c4d380de7b4915539..4a91f6771fb82da541868250a6f85ccd76d24abd 100644 (file)
@@ -706,7 +706,7 @@ static int stmpe1801_reset(struct stmpe *stmpe)
                if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET))
                        return 0;
                usleep_range(100, 200);
-       };
+       }
        return -EIO;
 }
 
index 1243d5c6a448568e2b1166ae34ab7e61b16e78de..7ceb3df09e25b8cda660b9307e9f23c5740433ab 100644 (file)
@@ -167,7 +167,7 @@ static struct mfd_cell stw481x_cells[] = {
        },
 };
 
-const struct regmap_config stw481x_regmap_config = {
+static const struct regmap_config stw481x_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 };
@@ -186,6 +186,12 @@ static int stw481x_probe(struct i2c_client *client,
        i2c_set_clientdata(client, stw481x);
        stw481x->client = client;
        stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config);
+       if (IS_ERR(stw481x->map)) {
+               ret = PTR_ERR(stw481x->map);
+               dev_err(&client->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
 
        ret = stw481x_startup(stw481x);
        if (ret) {
index 71841f9181bd19f4ae6b832898353bc442999c2e..dbea55de4397d5055da2b3fe39283fa36abea1f1 100644 (file)
@@ -69,13 +69,6 @@ EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
 
 static int syscon_match_pdevname(struct device *dev, void *data)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       const struct platform_device_id *id = platform_get_device_id(pdev);
-
-       if (id)
-               if (!strcmp(id->name, (const char *)data))
-                       return 1;
-
        return !strcmp(dev_name(dev), (const char *)data);
 }
 
@@ -152,7 +145,7 @@ static int syscon_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, syscon);
 
-       dev_info(dev, "regmap %pR registered\n", res);
+       dev_dbg(dev, "regmap %pR registered\n", res);
 
        return 0;
 }
index 2cf636c267d9413f77e39d787b6a47496ce1859e..bd83accc0f6dd4d14dd5cafa73da8d41a1086365 100644 (file)
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/tc3589x.h>
+#include <linux/err.h>
 
 /**
  * enum tc3589x_version - indicates the TC3589x version
@@ -160,7 +162,7 @@ static const struct mfd_cell tc3589x_dev_gpio[] = {
                .name           = "tc3589x-gpio",
                .num_resources  = ARRAY_SIZE(gpio_resources),
                .resources      = &gpio_resources[0],
-               .of_compatible  = "tc3589x-gpio",
+               .of_compatible  = "toshiba,tc3589x-gpio",
        },
 };
 
@@ -169,7 +171,7 @@ static const struct mfd_cell tc3589x_dev_keypad[] = {
                .name           = "tc3589x-keypad",
                .num_resources  = ARRAY_SIZE(keypad_resources),
                .resources      = &keypad_resources[0],
-               .of_compatible  = "tc3589x-keypad",
+               .of_compatible  = "toshiba,tc3589x-keypad",
        },
 };
 
@@ -318,45 +320,74 @@ static int tc3589x_device_init(struct tc3589x *tc3589x)
        return ret;
 }
 
-static int tc3589x_of_probe(struct device_node *np,
-                       struct tc3589x_platform_data *pdata)
+#ifdef CONFIG_OF
+static const struct of_device_id tc3589x_match[] = {
+       /* Legacy compatible string */
+       { .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN },
+       { .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 },
+       { .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 },
+       { .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 },
+       { .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 },
+       { .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 },
+       { .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, tc3589x_match);
+
+static struct tc3589x_platform_data *
+tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
 {
+       struct device_node *np = dev->of_node;
+       struct tc3589x_platform_data *pdata;
        struct device_node *child;
+       const struct of_device_id *of_id;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return ERR_PTR(-ENOMEM);
+
+       of_id = of_match_device(tc3589x_match, dev);
+       if (!of_id)
+               return ERR_PTR(-ENODEV);
+       *version = (enum tc3589x_version) of_id->data;
 
        for_each_child_of_node(np, child) {
-               if (!strcmp(child->name, "tc3589x_gpio")) {
+               if (of_device_is_compatible(child, "toshiba,tc3589x-gpio"))
                        pdata->block |= TC3589x_BLOCK_GPIO;
-               }
-               if (!strcmp(child->name, "tc3589x_keypad")) {
+               if (of_device_is_compatible(child, "toshiba,tc3589x-keypad"))
                        pdata->block |= TC3589x_BLOCK_KEYPAD;
-               }
        }
 
-       return 0;
+       return pdata;
 }
+#else
+static inline struct tc3589x_platform_data *
+tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
+{
+       dev_err(dev, "no device tree support\n");
+       return ERR_PTR(-ENODEV);
+}
+#endif
 
 static int tc3589x_probe(struct i2c_client *i2c,
                                   const struct i2c_device_id *id)
 {
-       struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
        struct device_node *np = i2c->dev.of_node;
+       struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
        struct tc3589x *tc3589x;
+       enum tc3589x_version version;
        int ret;
 
        if (!pdata) {
-               if (np) {
-                       pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
-                       if (!pdata)
-                               return -ENOMEM;
-
-                       ret = tc3589x_of_probe(np, pdata);
-                       if (ret)
-                               return ret;
-               }
-               else {
+               pdata = tc3589x_of_probe(&i2c->dev, &version);
+               if (IS_ERR(pdata)) {
                        dev_err(&i2c->dev, "No platform data or DT found\n");
-                       return -EINVAL;
+                       return PTR_ERR(pdata);
                }
+       } else {
+               /* When not probing from device tree we have this ID */
+               version = id->driver_data;
        }
 
        if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
@@ -375,7 +406,7 @@ static int tc3589x_probe(struct i2c_client *i2c,
        tc3589x->pdata = pdata;
        tc3589x->irq_base = pdata->irq_base;
 
-       switch (id->driver_data) {
+       switch (version) {
        case TC3589X_TC35893:
        case TC3589X_TC35895:
        case TC3589X_TC35896:
@@ -471,9 +502,12 @@ static const struct i2c_device_id tc3589x_id[] = {
 MODULE_DEVICE_TABLE(i2c, tc3589x_id);
 
 static struct i2c_driver tc3589x_driver = {
-       .driver.name    = "tc3589x",
-       .driver.owner   = THIS_MODULE,
-       .driver.pm      = &tc3589x_dev_pm_ops,
+       .driver = {
+               .name   = "tc3589x",
+               .owner  = THIS_MODULE,
+               .pm     = &tc3589x_dev_pm_ops,
+               .of_match_table = of_match_ptr(tc3589x_match),
+       },
        .probe          = tc3589x_probe,
        .remove         = tc3589x_remove,
        .id_table       = tc3589x_id,
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c
deleted file mode 100644 (file)
index a542457..0000000
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs
- *
- * Copyright (C) 2010 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/sched.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/ti_ssp.h>
-
-/* Register Offsets */
-#define REG_REV                0x00
-#define REG_IOSEL_1    0x04
-#define REG_IOSEL_2    0x08
-#define REG_PREDIV     0x0c
-#define REG_INTR_ST    0x10
-#define REG_INTR_EN    0x14
-#define REG_TEST_CTRL  0x18
-
-/* Per port registers */
-#define PORT_CFG_2     0x00
-#define PORT_ADDR      0x04
-#define PORT_DATA      0x08
-#define PORT_CFG_1     0x0c
-#define PORT_STATE     0x10
-
-#define SSP_PORT_CONFIG_MASK   (SSP_EARLY_DIN | SSP_DELAY_DOUT)
-#define SSP_PORT_CLKRATE_MASK  0x0f
-
-#define SSP_SEQRAM_WR_EN       BIT(4)
-#define SSP_SEQRAM_RD_EN       BIT(5)
-#define SSP_START              BIT(15)
-#define SSP_BUSY               BIT(10)
-#define SSP_PORT_ASL           BIT(7)
-#define SSP_PORT_CFO1          BIT(6)
-
-#define SSP_PORT_SEQRAM_SIZE   32
-
-static const int ssp_port_base[]   = {0x040, 0x080};
-static const int ssp_port_seqram[] = {0x100, 0x180};
-
-struct ti_ssp {
-       struct resource         *res;
-       struct device           *dev;
-       void __iomem            *regs;
-       spinlock_t              lock;
-       struct clk              *clk;
-       int                     irq;
-       wait_queue_head_t       wqh;
-
-       /*
-        * Some of the iosel2 register bits always read-back as 0, we need to
-        * remember these values so that we don't clobber previously set
-        * values.
-        */
-       u32                     iosel2;
-};
-
-static inline struct ti_ssp *dev_to_ssp(struct device *dev)
-{
-       return dev_get_drvdata(dev->parent);
-}
-
-static inline int dev_to_port(struct device *dev)
-{
-       return to_platform_device(dev)->id;
-}
-
-/* Register Access Helpers, rmw() functions need to run locked */
-static inline u32 ssp_read(struct ti_ssp *ssp, int reg)
-{
-       return __raw_readl(ssp->regs + reg);
-}
-
-static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val)
-{
-       __raw_writel(val, ssp->regs + reg);
-}
-
-static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits)
-{
-       ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~mask) | bits);
-}
-
-static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg)
-{
-       return ssp_read(ssp, ssp_port_base[port] + reg);
-}
-
-static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg,
-                                 u32 val)
-{
-       ssp_write(ssp, ssp_port_base[port] + reg, val);
-}
-
-static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg,
-                               u32 mask, u32 bits)
-{
-       ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits);
-}
-
-static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg,
-                                    u32 bits)
-{
-       ssp_port_rmw(ssp, port, reg, bits, 0);
-}
-
-static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg,
-                                    u32 bits)
-{
-       ssp_port_rmw(ssp, port, reg, 0, bits);
-}
-
-/* Called to setup port clock mode, caller must hold ssp->lock */
-static int __set_mode(struct ti_ssp *ssp, int port, int mode)
-{
-       mode &= SSP_PORT_CONFIG_MASK;
-       ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode);
-
-       return 0;
-}
-
-int ti_ssp_set_mode(struct device *dev, int mode)
-{
-       struct ti_ssp *ssp = dev_to_ssp(dev);
-       int port = dev_to_port(dev);
-       int ret;
-
-       spin_lock(&ssp->lock);
-       ret = __set_mode(ssp, port, mode);
-       spin_unlock(&ssp->lock);
-
-       return ret;
-}
-EXPORT_SYMBOL(ti_ssp_set_mode);
-
-/* Called to setup iosel2, caller must hold ssp->lock */
-static void __set_iosel2(struct ti_ssp *ssp, u32 mask, u32 val)
-{
-       ssp->iosel2 = (ssp->iosel2 & ~mask) | val;
-       ssp_write(ssp, REG_IOSEL_2, ssp->iosel2);
-}
-
-/* Called to setup port iosel, caller must hold ssp->lock */
-static void __set_iosel(struct ti_ssp *ssp, int port, u32 iosel)
-{
-       unsigned val, shift = port ? 16 : 0;
-
-       /* IOSEL1 gets the least significant 16 bits */
-       val = ssp_read(ssp, REG_IOSEL_1);
-       val &= 0xffff << (port ? 0 : 16);
-       val |= (iosel & 0xffff) << (port ? 16 : 0);
-       ssp_write(ssp, REG_IOSEL_1, val);
-
-       /* IOSEL2 gets the most significant 16 bits */
-       val = (iosel >> 16) & 0x7;
-       __set_iosel2(ssp, 0x7 << shift, val << shift);
-}
-
-int ti_ssp_set_iosel(struct device *dev, u32 iosel)
-{
-       struct ti_ssp *ssp = dev_to_ssp(dev);
-       int port = dev_to_port(dev);
-
-       spin_lock(&ssp->lock);
-       __set_iosel(ssp, port, iosel);
-       spin_unlock(&ssp->lock);
-
-       return 0;
-}
-EXPORT_SYMBOL(ti_ssp_set_iosel);
-
-int ti_ssp_load(struct device *dev, int offs, u32* prog, int len)
-{
-       struct ti_ssp *ssp = dev_to_ssp(dev);
-       int port = dev_to_port(dev);
-       int i;
-
-       if (len > SSP_PORT_SEQRAM_SIZE)
-               return -ENOSPC;
-
-       spin_lock(&ssp->lock);
-
-       /* Enable SeqRAM access */
-       ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);
-
-       /* Copy code */
-       for (i = 0; i < len; i++) {
-               __raw_writel(prog[i], ssp->regs + offs + 4*i +
-                            ssp_port_seqram[port]);
-       }
-
-       /* Disable SeqRAM access */
-       ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);
-
-       spin_unlock(&ssp->lock);
-
-       return 0;
-}
-EXPORT_SYMBOL(ti_ssp_load);
-
-int ti_ssp_raw_read(struct device *dev)
-{
-       struct ti_ssp *ssp = dev_to_ssp(dev);
-       int port = dev_to_port(dev);
-       int shift = port ? 27 : 11;
-
-       return (ssp_read(ssp, REG_IOSEL_2) >> shift) & 0xf;
-}
-EXPORT_SYMBOL(ti_ssp_raw_read);
-
-int ti_ssp_raw_write(struct device *dev, u32 val)
-{
-       struct ti_ssp *ssp = dev_to_ssp(dev);
-       int port = dev_to_port(dev), shift;
-
-       spin_lock(&ssp->lock);
-
-       shift = port ? 22 : 6;
-       val &= 0xf;
-       __set_iosel2(ssp, 0xf << shift, val << shift);
-
-       spin_unlock(&ssp->lock);
-
-       return 0;
-}
-EXPORT_SYMBOL(ti_ssp_raw_write);
-
-static inline int __xfer_done(struct ti_ssp *ssp, int port)
-{
-       return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY);
-}
-
-int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output)
-{
-       struct ti_ssp *ssp = dev_to_ssp(dev);
-       int port = dev_to_port(dev);
-       int ret;
-
-       if (pc & ~(0x3f))
-               return -EINVAL;
-
-       /* Grab ssp->lock to serialize rmw on ssp registers */
-       spin_lock(&ssp->lock);
-
-       ssp_port_write(ssp, port, PORT_ADDR, input >> 16);
-       ssp_port_write(ssp, port, PORT_DATA, input & 0xffff);
-       ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc);
-
-       /* grab wait queue head lock to avoid race with the isr */
-       spin_lock_irq(&ssp->wqh.lock);
-
-       /* kick off sequence execution in hardware */
-       ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START);
-
-       /* drop ssp lock; no register writes beyond this */
-       spin_unlock(&ssp->lock);
-
-       ret = wait_event_interruptible_locked_irq(ssp->wqh,
-                                                 __xfer_done(ssp, port));
-       spin_unlock_irq(&ssp->wqh.lock);
-
-       if (ret < 0)
-               return ret;
-
-       if (output) {
-               *output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) |
-                         (ssp_port_read(ssp, port, PORT_DATA) &  0xffff);
-       }
-
-       ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */
-
-       return ret;
-}
-EXPORT_SYMBOL(ti_ssp_run);
-
-static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
-{
-       struct ti_ssp *ssp = dev_data;
-
-       spin_lock(&ssp->wqh.lock);
-
-       ssp_write(ssp, REG_INTR_ST, 0x3);
-       wake_up_locked(&ssp->wqh);
-
-       spin_unlock(&ssp->wqh.lock);
-
-       return IRQ_HANDLED;
-}
-
-static int ti_ssp_probe(struct platform_device *pdev)
-{
-       static struct ti_ssp *ssp;
-       const struct ti_ssp_data *pdata = dev_get_platdata(&pdev->dev);
-       int error = 0, prediv = 0xff, id;
-       unsigned long sysclk;
-       struct device *dev = &pdev->dev;
-       struct mfd_cell cells[2];
-
-       ssp = kzalloc(sizeof(*ssp), GFP_KERNEL);
-       if (!ssp) {
-               dev_err(dev, "cannot allocate device info\n");
-               return -ENOMEM;
-       }
-
-       ssp->dev = dev;
-       dev_set_drvdata(dev, ssp);
-
-       ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!ssp->res) {
-               error = -ENODEV;
-               dev_err(dev, "cannot determine register area\n");
-               goto error_res;
-       }
-
-       if (!request_mem_region(ssp->res->start, resource_size(ssp->res),
-                               pdev->name)) {
-               error = -ENOMEM;
-               dev_err(dev, "cannot claim register memory\n");
-               goto error_res;
-       }
-
-       ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res));
-       if (!ssp->regs) {
-               error = -ENOMEM;
-               dev_err(dev, "cannot map register memory\n");
-               goto error_map;
-       }
-
-       ssp->clk = clk_get(dev, NULL);
-       if (IS_ERR(ssp->clk)) {
-               error = PTR_ERR(ssp->clk);
-               dev_err(dev, "cannot claim device clock\n");
-               goto error_clk;
-       }
-
-       ssp->irq = platform_get_irq(pdev, 0);
-       if (ssp->irq < 0) {
-               error = -ENODEV;
-               dev_err(dev, "unknown irq\n");
-               goto error_irq;
-       }
-
-       error = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0,
-                                    dev_name(dev), ssp);
-       if (error < 0) {
-               dev_err(dev, "cannot acquire irq\n");
-               goto error_irq;
-       }
-
-       spin_lock_init(&ssp->lock);
-       init_waitqueue_head(&ssp->wqh);
-
-       /* Power on and initialize SSP */
-       error = clk_enable(ssp->clk);
-       if (error) {
-               dev_err(dev, "cannot enable device clock\n");
-               goto error_enable;
-       }
-
-       /* Reset registers to a sensible known state */
-       ssp_write(ssp, REG_IOSEL_1, 0);
-       ssp_write(ssp, REG_IOSEL_2, 0);
-       ssp_write(ssp, REG_INTR_EN, 0x3);
-       ssp_write(ssp, REG_INTR_ST, 0x3);
-       ssp_write(ssp, REG_TEST_CTRL, 0);
-       ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL);
-       ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL);
-       ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1);
-       ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1);
-
-       sysclk = clk_get_rate(ssp->clk);
-       if (pdata && pdata->out_clock)
-               prediv = (sysclk / pdata->out_clock) - 1;
-       prediv = clamp(prediv, 0, 0xff);
-       ssp_rmw(ssp, REG_PREDIV, 0xff, prediv);
-
-       memset(cells, 0, sizeof(cells));
-       for (id = 0; id < 2; id++) {
-               const struct ti_ssp_dev_data *data = &pdata->dev_data[id];
-
-               cells[id].id            = id;
-               cells[id].name          = data->dev_name;
-               cells[id].platform_data = data->pdata;
-       }
-
-       error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);
-       if (error < 0) {
-               dev_err(dev, "cannot add mfd cells\n");
-               goto error_enable;
-       }
-
-       return 0;
-
-error_enable:
-       free_irq(ssp->irq, ssp);
-error_irq:
-       clk_put(ssp->clk);
-error_clk:
-       iounmap(ssp->regs);
-error_map:
-       release_mem_region(ssp->res->start, resource_size(ssp->res));
-error_res:
-       kfree(ssp);
-       return error;
-}
-
-static int ti_ssp_remove(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct ti_ssp *ssp = dev_get_drvdata(dev);
-
-       mfd_remove_devices(dev);
-       clk_disable(ssp->clk);
-       free_irq(ssp->irq, ssp);
-       clk_put(ssp->clk);
-       iounmap(ssp->regs);
-       release_mem_region(ssp->res->start, resource_size(ssp->res));
-       kfree(ssp);
-       return 0;
-}
-
-static struct platform_driver ti_ssp_driver = {
-       .probe          = ti_ssp_probe,
-       .remove         = ti_ssp_remove,
-       .driver         = {
-               .name   = "ti-ssp",
-               .owner  = THIS_MODULE,
-       }
-};
-
-module_platform_driver(ti_ssp_driver);
-
-MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver");
-MODULE_AUTHOR("Cyril Chemparathy");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ti-ssp");
index d4e860413bb54e1af55409dd7c8dc29e47747b02..dd4bf5816221a6ed79aed14b16cd42268b98be7d 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/io.h>
@@ -184,12 +183,6 @@ static     int ti_tscadc_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "no memory resource defined.\n");
-               return -EINVAL;
-       }
-
        /* Allocate memory for device */
        tscadc = devm_kzalloc(&pdev->dev,
                        sizeof(struct ti_tscadc_dev), GFP_KERNEL);
@@ -206,19 +199,10 @@ static    int ti_tscadc_probe(struct platform_device *pdev)
        } else
                tscadc->irq = err;
 
-       res = devm_request_mem_region(&pdev->dev,
-                       res->start, resource_size(res), pdev->name);
-       if (!res) {
-               dev_err(&pdev->dev, "failed to reserve registers.\n");
-               return -EBUSY;
-       }
-
-       tscadc->tscadc_base = devm_ioremap(&pdev->dev,
-                       res->start, resource_size(res));
-       if (!tscadc->tscadc_base) {
-               dev_err(&pdev->dev, "failed to map registers.\n");
-               return -ENOMEM;
-       }
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(tscadc->tscadc_base))
+               return PTR_ERR(tscadc->tscadc_base);
 
        tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev,
                        tscadc->tscadc_base, &tscadc_regmap_config);
index 2bc5cfb852042cd5e41e240cb5ce0662ebd0698f..6ce36d6970a4104484d0ac1fa118df96e27dedfe 100644 (file)
@@ -715,7 +715,7 @@ static int timb_probe(struct pci_dev *dev,
        for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
                msix_entries[i].entry = i;
 
-       err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS);
+       err = pci_enable_msix_exact(dev, msix_entries, TIMBERDALE_NR_IRQS);
        if (err) {
                dev_err(&dev->dev,
                        "MSI-X init failed: %d, expected entries: %d\n",
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c
new file mode 100644 (file)
index 0000000..a74bfb5
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Driver for TPS65218 Integrated power management chipsets
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65218.h>
+
+#define TPS65218_PASSWORD_REGS_UNLOCK   0x7D
+
+/**
+ * tps65218_reg_read: Read a single tps65218 register.
+ *
+ * @tps: Device to read from.
+ * @reg: Register to read.
+ * @val: Contians the value
+ */
+int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
+                       unsigned int *val)
+{
+       return regmap_read(tps->regmap, reg, val);
+}
+EXPORT_SYMBOL_GPL(tps65218_reg_read);
+
+/**
+ * tps65218_reg_write: Write a single tps65218 register.
+ *
+ * @tps65218: Device to write to.
+ * @reg: Register to write to.
+ * @val: Value to write.
+ * @level: Password protected level
+ */
+int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
+                       unsigned int val, unsigned int level)
+{
+       int ret;
+       unsigned int xor_reg_val;
+
+       switch (level) {
+       case TPS65218_PROTECT_NONE:
+               return regmap_write(tps->regmap, reg, val);
+       case TPS65218_PROTECT_L1:
+               xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK;
+               ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD,
+                                                       xor_reg_val);
+               if (ret < 0)
+                       return ret;
+
+               return regmap_write(tps->regmap, reg, val);
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL_GPL(tps65218_reg_write);
+
+/**
+ * tps65218_update_bits: Modify bits w.r.t mask, val and level.
+ *
+ * @tps65218: Device to write to.
+ * @reg: Register to read-write to.
+ * @mask: Mask.
+ * @val: Value to write.
+ * @level: Password protected level
+ */
+static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg,
+               unsigned int mask, unsigned int val, unsigned int level)
+{
+       int ret;
+       unsigned int data;
+
+       ret = tps65218_reg_read(tps, reg, &data);
+       if (ret) {
+               dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
+               return ret;
+       }
+
+       data &= ~mask;
+       data |= val & mask;
+
+       mutex_lock(&tps->tps_lock);
+       ret = tps65218_reg_write(tps, reg, data, level);
+       if (ret)
+               dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
+       mutex_unlock(&tps->tps_lock);
+
+       return ret;
+}
+
+int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
+               unsigned int mask, unsigned int val, unsigned int level)
+{
+       return tps65218_update_bits(tps, reg, mask, val, level);
+}
+EXPORT_SYMBOL_GPL(tps65218_set_bits);
+
+int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg,
+               unsigned int mask, unsigned int level)
+{
+       return tps65218_update_bits(tps, reg, mask, 0, level);
+}
+EXPORT_SYMBOL_GPL(tps65218_clear_bits);
+
+static struct regmap_config tps65218_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .cache_type = REGCACHE_RBTREE,
+};
+
+static const struct regmap_irq tps65218_irqs[] = {
+       /* INT1 IRQs */
+       [TPS65218_PRGC_IRQ] = {
+               .mask = TPS65218_INT1_PRGC,
+       },
+       [TPS65218_CC_AQC_IRQ] = {
+               .mask = TPS65218_INT1_CC_AQC,
+       },
+       [TPS65218_HOT_IRQ] = {
+               .mask = TPS65218_INT1_HOT,
+       },
+       [TPS65218_PB_IRQ] = {
+               .mask = TPS65218_INT1_PB,
+       },
+       [TPS65218_AC_IRQ] = {
+               .mask = TPS65218_INT1_AC,
+       },
+       [TPS65218_VPRG_IRQ] = {
+               .mask = TPS65218_INT1_VPRG,
+       },
+       [TPS65218_INVALID1_IRQ] = {
+       },
+       [TPS65218_INVALID2_IRQ] = {
+       },
+       /* INT2 IRQs*/
+       [TPS65218_LS1_I_IRQ] = {
+               .mask = TPS65218_INT2_LS1_I,
+               .reg_offset = 1,
+       },
+       [TPS65218_LS2_I_IRQ] = {
+               .mask = TPS65218_INT2_LS2_I,
+               .reg_offset = 1,
+       },
+       [TPS65218_LS3_I_IRQ] = {
+               .mask = TPS65218_INT2_LS3_I,
+               .reg_offset = 1,
+       },
+       [TPS65218_LS1_F_IRQ] = {
+               .mask = TPS65218_INT2_LS1_F,
+               .reg_offset = 1,
+       },
+       [TPS65218_LS2_F_IRQ] = {
+               .mask = TPS65218_INT2_LS2_F,
+               .reg_offset = 1,
+       },
+       [TPS65218_LS3_F_IRQ] = {
+               .mask = TPS65218_INT2_LS3_F,
+               .reg_offset = 1,
+       },
+       [TPS65218_INVALID3_IRQ] = {
+       },
+       [TPS65218_INVALID4_IRQ] = {
+       },
+};
+
+static struct regmap_irq_chip tps65218_irq_chip = {
+       .name = "tps65218",
+       .irqs = tps65218_irqs,
+       .num_irqs = ARRAY_SIZE(tps65218_irqs),
+
+       .num_regs = 2,
+       .mask_base = TPS65218_REG_INT_MASK1,
+};
+
+static const struct of_device_id of_tps65218_match_table[] = {
+       { .compatible = "ti,tps65218", },
+};
+
+static int tps65218_probe(struct i2c_client *client,
+                               const struct i2c_device_id *ids)
+{
+       struct tps65218 *tps;
+       const struct of_device_id *match;
+       int ret;
+
+       match = of_match_device(of_tps65218_match_table, &client->dev);
+       if (!match) {
+               dev_err(&client->dev,
+                       "Failed to find matching dt id\n");
+               return -EINVAL;
+       }
+
+       tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+       if (!tps)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, tps);
+       tps->dev = &client->dev;
+       tps->irq = client->irq;
+       tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config);
+       if (IS_ERR(tps->regmap)) {
+               ret = PTR_ERR(tps->regmap);
+               dev_err(tps->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
+
+       mutex_init(&tps->tps_lock);
+
+       ret = regmap_add_irq_chip(tps->regmap, tps->irq,
+                       IRQF_ONESHOT, 0, &tps65218_irq_chip,
+                       &tps->irq_data);
+       if (ret < 0)
+               return ret;
+
+       ret = of_platform_populate(client->dev.of_node, NULL, NULL,
+                                  &client->dev);
+       if (ret < 0)
+               goto err_irq;
+
+       return 0;
+
+err_irq:
+       regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+       return ret;
+}
+
+static int tps65218_remove(struct i2c_client *client)
+{
+       struct tps65218 *tps = i2c_get_clientdata(client);
+
+       regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+       return 0;
+}
+
+static const struct i2c_device_id tps65218_id_table[] = {
+       { "tps65218", TPS65218 },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, tps65218_id_table);
+
+static struct i2c_driver tps65218_driver = {
+       .driver         = {
+               .name   = "tps65218",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_tps65218_match_table,
+       },
+       .probe          = tps65218_probe,
+       .remove         = tps65218_remove,
+       .id_table       = tps65218_id_table,
+};
+
+module_i2c_driver(tps65218_driver);
+
+MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
+MODULE_DESCRIPTION("TPS65218 chip family multi-function driver");
+MODULE_LICENSE("GPL v2");
index 1f142d76cbbc6fc03f44ead367c01a9b75f24c86..460a014ca6291fa10468f984123a3e160c4964ea 100644 (file)
@@ -255,8 +255,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
        ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
                IRQF_ONESHOT, pdata->irq_base,
                tps6591x_irqs_chip, &tps65910->irq_data);
-       if (ret < 0)
+       if (ret < 0) {
                dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
+               tps65910->chip_irq = 0;
+       }
        return ret;
 }
 
@@ -509,6 +511,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
                              regmap_irq_get_domain(tps65910->irq_data));
        if (ret < 0) {
                dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
+               tps65910_irq_exit(tps65910);
                return ret;
        }
 
index 27a518e0eec6d04db1310e86f7ed678b4a762065..1f82d60b1d0fe077b735973b58cd34144be1111c 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/mfd/core.h>
index d360a83a2738daab514746692dbe03fee10a81d0..fbecec7f1e3df9f6d3a375714fe741d341bdb43f 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
index ed718328eff1a52f1fff6a8e132f4ba905084422..e87140bef667212af51bb6e02fd0ee06744190dc 100644 (file)
@@ -282,11 +282,11 @@ static struct reg_default twl4030_49_defaults[] = {
 static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
-       case 0:
-       case 3:
-       case 40:
-       case 41:
-       case 42:
+       case 0x00:
+       case 0x03:
+       case 0x40:
+       case 0x41:
+       case 0x42:
                return false;
        default:
                return true;
index 9aa6d1efa24112a6c5f28c37f4c42981e18f87b6..596b1f657e21d5d780cb1286bece2e366a4d1813 100644 (file)
@@ -27,7 +27,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <linux/init.h>
 #include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
deleted file mode 100644 (file)
index 4c583e4..0000000
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- *
- * TWL4030 MADC module driver-This driver monitors the real time
- * conversion of analog signals like battery temperature,
- * battery type, battery level etc.
- *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
- * J Keerthy <j-keerthy@ti.com>
- *
- * Based on twl4030-madc.c
- * Copyright (C) 2008 Nokia Corporation
- * Mikko Ylinen <mikko.k.ylinen@nokia.com>
- *
- * Amit Kucheria <amit.kucheria@canonical.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/i2c/twl.h>
-#include <linux/i2c/twl4030-madc.h>
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/mutex.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/types.h>
-#include <linux/gfp.h>
-#include <linux/err.h>
-
-/*
- * struct twl4030_madc_data - a container for madc info
- * @dev - pointer to device structure for madc
- * @lock - mutex protecting this data structure
- * @requests - Array of request struct corresponding to SW1, SW2 and RT
- * @imr - Interrupt mask register of MADC
- * @isr - Interrupt status register of MADC
- */
-struct twl4030_madc_data {
-       struct device *dev;
-       struct mutex lock;      /* mutex protecting this data structure */
-       struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
-       int imr;
-       int isr;
-};
-
-static struct twl4030_madc_data *twl4030_madc;
-
-struct twl4030_prescale_divider_ratios {
-       s16 numerator;
-       s16 denominator;
-};
-
-static const struct twl4030_prescale_divider_ratios
-twl4030_divider_ratios[16] = {
-       {1, 1},         /* CHANNEL 0 No Prescaler */
-       {1, 1},         /* CHANNEL 1 No Prescaler */
-       {6, 10},        /* CHANNEL 2 */
-       {6, 10},        /* CHANNEL 3 */
-       {6, 10},        /* CHANNEL 4 */
-       {6, 10},        /* CHANNEL 5 */
-       {6, 10},        /* CHANNEL 6 */
-       {6, 10},        /* CHANNEL 7 */
-       {3, 14},        /* CHANNEL 8 */
-       {1, 3},         /* CHANNEL 9 */
-       {1, 1},         /* CHANNEL 10 No Prescaler */
-       {15, 100},      /* CHANNEL 11 */
-       {1, 4},         /* CHANNEL 12 */
-       {1, 1},         /* CHANNEL 13 Reserved channels */
-       {1, 1},         /* CHANNEL 14 Reseved channels */
-       {5, 11},        /* CHANNEL 15 */
-};
-
-
-/*
- * Conversion table from -3 to 55 degree Celcius
- */
-static int therm_tbl[] = {
-30800, 29500,  28300,  27100,
-26000, 24900,  23900,  22900,  22000,  21100,  20300,  19400,  18700,  17900,
-17200, 16500,  15900,  15300,  14700,  14100,  13600,  13100,  12600,  12100,
-11600, 11200,  10800,  10400,  10000,  9630,   9280,   8950,   8620,   8310,
-8020,  7730,   7460,   7200,   6950,   6710,   6470,   6250,   6040,   5830,
-5640,  5450,   5260,   5090,   4920,   4760,   4600,   4450,   4310,   4170,
-4040,  3910,   3790,   3670,   3550
-};
-
-/*
- * Structure containing the registers
- * of different conversion methods supported by MADC.
- * Hardware or RT real time conversion request initiated by external host
- * processor for RT Signal conversions.
- * External host processors can also request for non RT conversions
- * SW1 and SW2 software conversions also called asynchronous or GPC request.
- */
-static
-const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
-       [TWL4030_MADC_RT] = {
-                            .sel = TWL4030_MADC_RTSELECT_LSB,
-                            .avg = TWL4030_MADC_RTAVERAGE_LSB,
-                            .rbase = TWL4030_MADC_RTCH0_LSB,
-                            },
-       [TWL4030_MADC_SW1] = {
-                             .sel = TWL4030_MADC_SW1SELECT_LSB,
-                             .avg = TWL4030_MADC_SW1AVERAGE_LSB,
-                             .rbase = TWL4030_MADC_GPCH0_LSB,
-                             .ctrl = TWL4030_MADC_CTRL_SW1,
-                             },
-       [TWL4030_MADC_SW2] = {
-                             .sel = TWL4030_MADC_SW2SELECT_LSB,
-                             .avg = TWL4030_MADC_SW2AVERAGE_LSB,
-                             .rbase = TWL4030_MADC_GPCH0_LSB,
-                             .ctrl = TWL4030_MADC_CTRL_SW2,
-                             },
-};
-
-/*
- * Function to read a particular channel value.
- * @madc - pointer to struct twl4030_madc_data
- * @reg - lsb of ADC Channel
- * If the i2c read fails it returns an error else returns 0.
- */
-static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
-{
-       u8 msb, lsb;
-       int ret;
-       /*
-        * For each ADC channel, we have MSB and LSB register pair. MSB address
-        * is always LSB address+1. reg parameter is the address of LSB register
-        */
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
-       if (ret) {
-               dev_err(madc->dev, "unable to read MSB register 0x%X\n",
-                       reg + 1);
-               return ret;
-       }
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
-       if (ret) {
-               dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
-               return ret;
-       }
-
-       return (int)(((msb << 8) | lsb) >> 6);
-}
-
-/*
- * Return battery temperature
- * Or < 0 on failure.
- */
-static int twl4030battery_temperature(int raw_volt)
-{
-       u8 val;
-       int temp, curr, volt, res, ret;
-
-       volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
-       /* Getting and calculating the supply current in micro ampers */
-       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
-               REG_BCICTL2);
-       if (ret < 0)
-               return ret;
-       curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
-       /* Getting and calculating the thermistor resistance in ohms */
-       res = volt * 1000 / curr;
-       /* calculating temperature */
-       for (temp = 58; temp >= 0; temp--) {
-               int actual = therm_tbl[temp];
-
-               if ((actual - res) >= 0)
-                       break;
-       }
-
-       return temp + 1;
-}
-
-static int twl4030battery_current(int raw_volt)
-{
-       int ret;
-       u8 val;
-
-       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
-               TWL4030_BCI_BCICTL1);
-       if (ret)
-               return ret;
-       if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
-               return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
-       else /* slope of 0.88 mV/mA */
-               return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
-}
-/*
- * Function to read channel values
- * @madc - pointer to twl4030_madc_data struct
- * @reg_base - Base address of the first channel
- * @Channels - 16 bit bitmap. If the bit is set, channel value is read
- * @buf - The channel values are stored here. if read fails error
- * @raw - Return raw values without conversion
- * value is stored
- * Returns the number of successfully read channels.
- */
-static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
-                                     u8 reg_base, unsigned
-                                     long channels, int *buf,
-                                     bool raw)
-{
-       int count = 0, count_req = 0, i;
-       u8 reg;
-
-       for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
-               reg = reg_base + 2 * i;
-               buf[i] = twl4030_madc_channel_raw_read(madc, reg);
-               if (buf[i] < 0) {
-                       dev_err(madc->dev,
-                               "Unable to read register 0x%X\n", reg);
-                       count_req++;
-                       continue;
-               }
-               if (raw) {
-                       count++;
-                       continue;
-               }
-               switch (i) {
-               case 10:
-                       buf[i] = twl4030battery_current(buf[i]);
-                       if (buf[i] < 0) {
-                               dev_err(madc->dev, "err reading current\n");
-                               count_req++;
-                       } else {
-                               count++;
-                               buf[i] = buf[i] - 750;
-                       }
-                       break;
-               case 1:
-                       buf[i] = twl4030battery_temperature(buf[i]);
-                       if (buf[i] < 0) {
-                               dev_err(madc->dev, "err reading temperature\n");
-                               count_req++;
-                       } else {
-                               buf[i] -= 3;
-                               count++;
-                       }
-                       break;
-               default:
-                       count++;
-                       /* Analog Input (V) = conv_result * step_size / R
-                        * conv_result = decimal value of 10-bit conversion
-                        *               result
-                        * step size = 1.5 / (2 ^ 10 -1)
-                        * R = Prescaler ratio for input channels.
-                        * Result given in mV hence multiplied by 1000.
-                        */
-                       buf[i] = (buf[i] * 3 * 1000 *
-                                twl4030_divider_ratios[i].denominator)
-                               / (2 * 1023 *
-                               twl4030_divider_ratios[i].numerator);
-               }
-       }
-       if (count_req)
-               dev_err(madc->dev, "%d channel conversion failed\n", count_req);
-
-       return count;
-}
-
-/*
- * Enables irq.
- * @madc - pointer to twl4030_madc_data struct
- * @id - irq number to be enabled
- * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
- * corresponding to RT, SW1, SW2 conversion requests.
- * If the i2c read fails it returns an error else returns 0.
- */
-static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
-{
-       u8 val;
-       int ret;
-
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
-       if (ret) {
-               dev_err(madc->dev, "unable to read imr register 0x%X\n",
-                       madc->imr);
-               return ret;
-       }
-       val &= ~(1 << id);
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
-       if (ret) {
-               dev_err(madc->dev,
-                       "unable to write imr register 0x%X\n", madc->imr);
-               return ret;
-
-       }
-
-       return 0;
-}
-
-/*
- * Disables irq.
- * @madc - pointer to twl4030_madc_data struct
- * @id - irq number to be disabled
- * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
- * corresponding to RT, SW1, SW2 conversion requests.
- * Returns error if i2c read/write fails.
- */
-static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
-{
-       u8 val;
-       int ret;
-
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
-       if (ret) {
-               dev_err(madc->dev, "unable to read imr register 0x%X\n",
-                       madc->imr);
-               return ret;
-       }
-       val |= (1 << id);
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
-       if (ret) {
-               dev_err(madc->dev,
-                       "unable to write imr register 0x%X\n", madc->imr);
-               return ret;
-       }
-
-       return 0;
-}
-
-static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
-{
-       struct twl4030_madc_data *madc = _madc;
-       const struct twl4030_madc_conversion_method *method;
-       u8 isr_val, imr_val;
-       int i, len, ret;
-       struct twl4030_madc_request *r;
-
-       mutex_lock(&madc->lock);
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
-       if (ret) {
-               dev_err(madc->dev, "unable to read isr register 0x%X\n",
-                       madc->isr);
-               goto err_i2c;
-       }
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
-       if (ret) {
-               dev_err(madc->dev, "unable to read imr register 0x%X\n",
-                       madc->imr);
-               goto err_i2c;
-       }
-       isr_val &= ~imr_val;
-       for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
-               if (!(isr_val & (1 << i)))
-                       continue;
-               ret = twl4030_madc_disable_irq(madc, i);
-               if (ret < 0)
-                       dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
-               madc->requests[i].result_pending = 1;
-       }
-       for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
-               r = &madc->requests[i];
-               /* No pending results for this method, move to next one */
-               if (!r->result_pending)
-                       continue;
-               method = &twl4030_conversion_methods[r->method];
-               /* Read results */
-               len = twl4030_madc_read_channels(madc, method->rbase,
-                                                r->channels, r->rbuf, r->raw);
-               /* Return results to caller */
-               if (r->func_cb != NULL) {
-                       r->func_cb(len, r->channels, r->rbuf);
-                       r->func_cb = NULL;
-               }
-               /* Free request */
-               r->result_pending = 0;
-               r->active = 0;
-       }
-       mutex_unlock(&madc->lock);
-
-       return IRQ_HANDLED;
-
-err_i2c:
-       /*
-        * In case of error check whichever request is active
-        * and service the same.
-        */
-       for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
-               r = &madc->requests[i];
-               if (r->active == 0)
-                       continue;
-               method = &twl4030_conversion_methods[r->method];
-               /* Read results */
-               len = twl4030_madc_read_channels(madc, method->rbase,
-                                                r->channels, r->rbuf, r->raw);
-               /* Return results to caller */
-               if (r->func_cb != NULL) {
-                       r->func_cb(len, r->channels, r->rbuf);
-                       r->func_cb = NULL;
-               }
-               /* Free request */
-               r->result_pending = 0;
-               r->active = 0;
-       }
-       mutex_unlock(&madc->lock);
-
-       return IRQ_HANDLED;
-}
-
-static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
-                               struct twl4030_madc_request *req)
-{
-       struct twl4030_madc_request *p;
-       int ret;
-
-       p = &madc->requests[req->method];
-       memcpy(p, req, sizeof(*req));
-       ret = twl4030_madc_enable_irq(madc, req->method);
-       if (ret < 0) {
-               dev_err(madc->dev, "enable irq failed!!\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
- * Function which enables the madc conversion
- * by writing to the control register.
- * @madc - pointer to twl4030_madc_data struct
- * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
- * corresponding to RT SW1 or SW2 conversion methods.
- * Returns 0 if succeeds else a negative error value
- */
-static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
-                                        int conv_method)
-{
-       const struct twl4030_madc_conversion_method *method;
-       int ret = 0;
-       method = &twl4030_conversion_methods[conv_method];
-       switch (conv_method) {
-       case TWL4030_MADC_SW1:
-       case TWL4030_MADC_SW2:
-               ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
-                                      TWL4030_MADC_SW_START, method->ctrl);
-               if (ret) {
-                       dev_err(madc->dev,
-                               "unable to write ctrl register 0x%X\n",
-                               method->ctrl);
-                       return ret;
-               }
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-/*
- * Function that waits for conversion to be ready
- * @madc - pointer to twl4030_madc_data struct
- * @timeout_ms - timeout value in milliseconds
- * @status_reg - ctrl register
- * returns 0 if succeeds else a negative error value
- */
-static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
-                                             unsigned int timeout_ms,
-                                             u8 status_reg)
-{
-       unsigned long timeout;
-       int ret;
-
-       timeout = jiffies + msecs_to_jiffies(timeout_ms);
-       do {
-               u8 reg;
-
-               ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
-               if (ret) {
-                       dev_err(madc->dev,
-                               "unable to read status register 0x%X\n",
-                               status_reg);
-                       return ret;
-               }
-               if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
-                       return 0;
-               usleep_range(500, 2000);
-       } while (!time_after(jiffies, timeout));
-       dev_err(madc->dev, "conversion timeout!\n");
-
-       return -EAGAIN;
-}
-
-/*
- * An exported function which can be called from other kernel drivers.
- * @req twl4030_madc_request structure
- * req->rbuf will be filled with read values of channels based on the
- * channel index. If a particular channel reading fails there will
- * be a negative error value in the corresponding array element.
- * returns 0 if succeeds else error value
- */
-int twl4030_madc_conversion(struct twl4030_madc_request *req)
-{
-       const struct twl4030_madc_conversion_method *method;
-       u8 ch_msb, ch_lsb;
-       int ret;
-
-       if (!req || !twl4030_madc)
-               return -EINVAL;
-
-       mutex_lock(&twl4030_madc->lock);
-       if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
-               ret = -EINVAL;
-               goto out;
-       }
-       /* Do we have a conversion request ongoing */
-       if (twl4030_madc->requests[req->method].active) {
-               ret = -EBUSY;
-               goto out;
-       }
-       ch_msb = (req->channels >> 8) & 0xff;
-       ch_lsb = req->channels & 0xff;
-       method = &twl4030_conversion_methods[req->method];
-       /* Select channels to be converted */
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
-       if (ret) {
-               dev_err(twl4030_madc->dev,
-                       "unable to write sel register 0x%X\n", method->sel + 1);
-               goto out;
-       }
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
-       if (ret) {
-               dev_err(twl4030_madc->dev,
-                       "unable to write sel register 0x%X\n", method->sel + 1);
-               goto out;
-       }
-       /* Select averaging for all channels if do_avg is set */
-       if (req->do_avg) {
-               ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
-                                      ch_msb, method->avg + 1);
-               if (ret) {
-                       dev_err(twl4030_madc->dev,
-                               "unable to write avg register 0x%X\n",
-                               method->avg + 1);
-                       goto out;
-               }
-               ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
-                                      ch_lsb, method->avg);
-               if (ret) {
-                       dev_err(twl4030_madc->dev,
-                               "unable to write sel reg 0x%X\n",
-                               method->sel + 1);
-                       goto out;
-               }
-       }
-       if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
-               ret = twl4030_madc_set_irq(twl4030_madc, req);
-               if (ret < 0)
-                       goto out;
-               ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
-               if (ret < 0)
-                       goto out;
-               twl4030_madc->requests[req->method].active = 1;
-               ret = 0;
-               goto out;
-       }
-       /* With RT method we should not be here anymore */
-       if (req->method == TWL4030_MADC_RT) {
-               ret = -EINVAL;
-               goto out;
-       }
-       ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
-       if (ret < 0)
-               goto out;
-       twl4030_madc->requests[req->method].active = 1;
-       /* Wait until conversion is ready (ctrl register returns EOC) */
-       ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
-       if (ret) {
-               twl4030_madc->requests[req->method].active = 0;
-               goto out;
-       }
-       ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
-                                        req->channels, req->rbuf, req->raw);
-       twl4030_madc->requests[req->method].active = 0;
-
-out:
-       mutex_unlock(&twl4030_madc->lock);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
-
-/*
- * Return channel value
- * Or < 0 on failure.
- */
-int twl4030_get_madc_conversion(int channel_no)
-{
-       struct twl4030_madc_request req;
-       int temp = 0;
-       int ret;
-
-       req.channels = (1 << channel_no);
-       req.method = TWL4030_MADC_SW2;
-       req.active = 0;
-       req.func_cb = NULL;
-       ret = twl4030_madc_conversion(&req);
-       if (ret < 0)
-               return ret;
-       if (req.rbuf[channel_no] > 0)
-               temp = req.rbuf[channel_no];
-
-       return temp;
-}
-EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
-
-/*
- * Function to enable or disable bias current for
- * main battery type reading or temperature sensing
- * @madc - pointer to twl4030_madc_data struct
- * @chan - can be one of the two values
- * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
- * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
- * sensing
- * @on - enable or disable chan.
- */
-static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
-                                             int chan, int on)
-{
-       int ret;
-       u8 regval;
-
-       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
-                             &regval, TWL4030_BCI_BCICTL1);
-       if (ret) {
-               dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
-                       TWL4030_BCI_BCICTL1);
-               return ret;
-       }
-       if (on)
-               regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
-       else
-               regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
-       ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
-                              regval, TWL4030_BCI_BCICTL1);
-       if (ret) {
-               dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
-                       TWL4030_BCI_BCICTL1);
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
- * Function that sets MADC software power on bit to enable MADC
- * @madc - pointer to twl4030_madc_data struct
- * @on - Enable or disable MADC software powen on bit.
- * returns error if i2c read/write fails else 0
- */
-static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
-{
-       u8 regval;
-       int ret;
-
-       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
-                             &regval, TWL4030_MADC_CTRL1);
-       if (ret) {
-               dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
-                       TWL4030_MADC_CTRL1);
-               return ret;
-       }
-       if (on)
-               regval |= TWL4030_MADC_MADCON;
-       else
-               regval &= ~TWL4030_MADC_MADCON;
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
-       if (ret) {
-               dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
-                       TWL4030_MADC_CTRL1);
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
- * Initialize MADC and request for threaded irq
- */
-static int twl4030_madc_probe(struct platform_device *pdev)
-{
-       struct twl4030_madc_data *madc;
-       struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
-       int ret;
-       u8 regval;
-
-       if (!pdata) {
-               dev_err(&pdev->dev, "platform_data not available\n");
-               return -EINVAL;
-       }
-       madc = kzalloc(sizeof(*madc), GFP_KERNEL);
-       if (!madc)
-               return -ENOMEM;
-
-       madc->dev = &pdev->dev;
-
-       /*
-        * Phoenix provides 2 interrupt lines. The first one is connected to
-        * the OMAP. The other one can be connected to the other processor such
-        * as modem. Hence two separate ISR and IMR registers.
-        */
-       madc->imr = (pdata->irq_line == 1) ?
-           TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
-       madc->isr = (pdata->irq_line == 1) ?
-           TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
-       ret = twl4030_madc_set_power(madc, 1);
-       if (ret < 0)
-               goto err_power;
-       ret = twl4030_madc_set_current_generator(madc, 0, 1);
-       if (ret < 0)
-               goto err_current_generator;
-
-       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
-                             &regval, TWL4030_BCI_BCICTL1);
-       if (ret) {
-               dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
-                       TWL4030_BCI_BCICTL1);
-               goto err_i2c;
-       }
-       regval |= TWL4030_BCI_MESBAT;
-       ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
-                              regval, TWL4030_BCI_BCICTL1);
-       if (ret) {
-               dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
-                       TWL4030_BCI_BCICTL1);
-               goto err_i2c;
-       }
-
-       /* Check that MADC clock is on */
-       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
-       if (ret) {
-               dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
-                               TWL4030_REG_GPBR1);
-               goto err_i2c;
-       }
-
-       /* If MADC clk is not on, turn it on */
-       if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
-               dev_info(&pdev->dev, "clk disabled, enabling\n");
-               regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
-               ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
-                                      TWL4030_REG_GPBR1);
-               if (ret) {
-                       dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
-                                       TWL4030_REG_GPBR1);
-                       goto err_i2c;
-               }
-       }
-
-       platform_set_drvdata(pdev, madc);
-       mutex_init(&madc->lock);
-       ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
-                                  twl4030_madc_threaded_irq_handler,
-                                  IRQF_TRIGGER_RISING, "twl4030_madc", madc);
-       if (ret) {
-               dev_dbg(&pdev->dev, "could not request irq\n");
-               goto err_i2c;
-       }
-       twl4030_madc = madc;
-       return 0;
-err_i2c:
-       twl4030_madc_set_current_generator(madc, 0, 0);
-err_current_generator:
-       twl4030_madc_set_power(madc, 0);
-err_power:
-       kfree(madc);
-
-       return ret;
-}
-
-static int twl4030_madc_remove(struct platform_device *pdev)
-{
-       struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
-
-       free_irq(platform_get_irq(pdev, 0), madc);
-       twl4030_madc_set_current_generator(madc, 0, 0);
-       twl4030_madc_set_power(madc, 0);
-       kfree(madc);
-
-       return 0;
-}
-
-static struct platform_driver twl4030_madc_driver = {
-       .probe = twl4030_madc_probe,
-       .remove = twl4030_madc_remove,
-       .driver = {
-                  .name = "twl4030_madc",
-                  .owner = THIS_MODULE,
-                  },
-};
-
-module_platform_driver(twl4030_madc_driver);
-
-MODULE_DESCRIPTION("TWL4030 ADC driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("J Keerthy");
-MODULE_ALIAS("platform:twl4030_madc");
index 18a607e2ca0607d5fb80c765a53f5f8c13352b6f..a6bb17d908b8a4fa14267b7ecaf4bca75b704fdc 100644 (file)
@@ -31,7 +31,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <linux/init.h>
 #include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
index 75316fb33448d6041d13e91f1c02c9321cd03818..6e88f25832fb23a13198a1b2f5ca8170b9e04772 100644 (file)
@@ -661,6 +661,11 @@ static int twl6040_probe(struct i2c_client *client,
        init_completion(&twl6040->ready);
 
        twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
+       if (twl6040->rev < 0) {
+               dev_err(&client->dev, "Failed to read revision register: %d\n",
+                       twl6040->rev);
+               goto gpio_err;
+       }
 
        /* ERRATA: Automatic power-up is not possible in ES1.0 */
        if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
@@ -703,7 +708,6 @@ static int twl6040_probe(struct i2c_client *client,
        }
 
        /* dual-access registers controlled by I2C only */
-       twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
        regmap_register_patch(twl6040->regmap, twl6040_patch,
                              ARRAY_SIZE(twl6040_patch));
 
index 0313f839e8fadc32228b9c892edb31a449b53ace..153d595afaacb50306bd017a1893c8f27b1c0ca3 100644 (file)
@@ -742,9 +742,7 @@ static int ucb1x00_resume(struct device *dev)
 }
 #endif
 
-static const struct dev_pm_ops ucb1x00_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
-};
+static SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops, ucb1x00_suspend, ucb1x00_resume);
 
 static struct mcp_driver ucb1x00_driver = {
        .drv            = {
index 84ce6b9daa3dea13b2adf8d07d907fb128d1175c..d0db89d13e0118ff16e97d65dd8672cd5d6ffa3c 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/bitops.h>
 #include <linux/completion.h>
 #include <linux/export.h>
-#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -27,7 +26,7 @@
 
 #define VEXPRESS_CONFIG_MAX_BRIDGES 2
 
-struct vexpress_config_bridge {
+static struct vexpress_config_bridge {
        struct device_node *node;
        struct vexpress_config_bridge_info *info;
        struct list_head transactions;
index 981bef4b7ebcaa60b861d171a57f166a6218837d..35281e804e7ef3879d7c6f18d28d127d7b62338a 100644 (file)
@@ -168,7 +168,7 @@ static void *vexpress_sysreg_config_func_get(struct device *dev,
                struct device_node *node)
 {
        struct vexpress_sysreg_config_func *config_func;
-       u32 site;
+       u32 site = 0;
        u32 position = 0;
        u32 dcc = 0;
        u32 func_device[2];
index bffc584e4a4355f25f565ae6d0aa77244e556238..070f8cfbbd7aa7c5f7d043178948fda4cea852b8 100644 (file)
@@ -73,6 +73,7 @@ static const struct reg_default wm5102_revb_patch[] = {
        { 0x171, 0x0000 },
        { 0x35E, 0x000C },
        { 0x2D4, 0x0000 },
+       { 0x4DC, 0x0900 },
        { 0x80, 0x0000 },
 };
 
@@ -1839,6 +1840,23 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
        case ARIZONA_DSP1_STATUS_3:
+       case ARIZONA_DSP1_WDMA_BUFFER_1:
+       case ARIZONA_DSP1_WDMA_BUFFER_2:
+       case ARIZONA_DSP1_WDMA_BUFFER_3:
+       case ARIZONA_DSP1_WDMA_BUFFER_4:
+       case ARIZONA_DSP1_WDMA_BUFFER_5:
+       case ARIZONA_DSP1_WDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_BUFFER_7:
+       case ARIZONA_DSP1_WDMA_BUFFER_8:
+       case ARIZONA_DSP1_RDMA_BUFFER_1:
+       case ARIZONA_DSP1_RDMA_BUFFER_2:
+       case ARIZONA_DSP1_RDMA_BUFFER_3:
+       case ARIZONA_DSP1_RDMA_BUFFER_4:
+       case ARIZONA_DSP1_RDMA_BUFFER_5:
+       case ARIZONA_DSP1_RDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_CONFIG_1:
+       case ARIZONA_DSP1_WDMA_CONFIG_2:
+       case ARIZONA_DSP1_RDMA_CONFIG_1:
        case ARIZONA_DSP1_SCRATCH_0:
        case ARIZONA_DSP1_SCRATCH_1:
        case ARIZONA_DSP1_SCRATCH_2:
@@ -1894,9 +1912,27 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
        case ARIZONA_AOD_IRQ1:
        case ARIZONA_AOD_IRQ2:
        case ARIZONA_AOD_IRQ_RAW_STATUS:
+       case ARIZONA_DSP1_CLOCKING_1:
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
        case ARIZONA_DSP1_STATUS_3:
+       case ARIZONA_DSP1_WDMA_BUFFER_1:
+       case ARIZONA_DSP1_WDMA_BUFFER_2:
+       case ARIZONA_DSP1_WDMA_BUFFER_3:
+       case ARIZONA_DSP1_WDMA_BUFFER_4:
+       case ARIZONA_DSP1_WDMA_BUFFER_5:
+       case ARIZONA_DSP1_WDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_BUFFER_7:
+       case ARIZONA_DSP1_WDMA_BUFFER_8:
+       case ARIZONA_DSP1_RDMA_BUFFER_1:
+       case ARIZONA_DSP1_RDMA_BUFFER_2:
+       case ARIZONA_DSP1_RDMA_BUFFER_3:
+       case ARIZONA_DSP1_RDMA_BUFFER_4:
+       case ARIZONA_DSP1_RDMA_BUFFER_5:
+       case ARIZONA_DSP1_RDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_CONFIG_1:
+       case ARIZONA_DSP1_WDMA_CONFIG_2:
+       case ARIZONA_DSP1_RDMA_CONFIG_1:
        case ARIZONA_DSP1_SCRATCH_0:
        case ARIZONA_DSP1_SCRATCH_1:
        case ARIZONA_DSP1_SCRATCH_2:
index 11632f135e8c8d7a6f57206b4d09cd8b097815c7..1942b6f231dae3f193e41f618c6ec626ffc28694 100644 (file)
@@ -538,7 +538,7 @@ static const struct reg_default wm5110_reg_default[] = {
        { 0x00000219, 0x01A6 },    /* R537   - Mic Bias Ctrl 2 */
        { 0x0000021A, 0x01A6 },    /* R538   - Mic Bias Ctrl 3 */
        { 0x00000293, 0x0000 },    /* R659   - Accessory Detect Mode 1 */
-       { 0x0000029B, 0x0020 },    /* R667   - Headphone Detect 1 */
+       { 0x0000029B, 0x0028 },    /* R667   - Headphone Detect 1 */
        { 0x0000029C, 0x0000 },    /* R668   - Headphone Detect 2 */
        { 0x000002A2, 0x0000 },    /* R674   - Micd clamp control */
        { 0x000002A3, 0x1102 },    /* R675   - Mic Detect 1 */
@@ -2461,6 +2461,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
        case ARIZONA_DSP1_STATUS_3:
+       case ARIZONA_DSP1_STATUS_4:
+       case ARIZONA_DSP1_WDMA_BUFFER_1:
+       case ARIZONA_DSP1_WDMA_BUFFER_2:
+       case ARIZONA_DSP1_WDMA_BUFFER_3:
+       case ARIZONA_DSP1_WDMA_BUFFER_4:
+       case ARIZONA_DSP1_WDMA_BUFFER_5:
+       case ARIZONA_DSP1_WDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_BUFFER_7:
+       case ARIZONA_DSP1_WDMA_BUFFER_8:
+       case ARIZONA_DSP1_RDMA_BUFFER_1:
+       case ARIZONA_DSP1_RDMA_BUFFER_2:
+       case ARIZONA_DSP1_RDMA_BUFFER_3:
+       case ARIZONA_DSP1_RDMA_BUFFER_4:
+       case ARIZONA_DSP1_RDMA_BUFFER_5:
+       case ARIZONA_DSP1_RDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_CONFIG_1:
+       case ARIZONA_DSP1_WDMA_CONFIG_2:
+       case ARIZONA_DSP1_WDMA_OFFSET_1:
+       case ARIZONA_DSP1_RDMA_CONFIG_1:
+       case ARIZONA_DSP1_RDMA_OFFSET_1:
+       case ARIZONA_DSP1_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP1_SCRATCH_0:
        case ARIZONA_DSP1_SCRATCH_1:
        case ARIZONA_DSP1_SCRATCH_2:
@@ -2470,6 +2491,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP2_STATUS_1:
        case ARIZONA_DSP2_STATUS_2:
        case ARIZONA_DSP2_STATUS_3:
+       case ARIZONA_DSP2_STATUS_4:
+       case ARIZONA_DSP2_WDMA_BUFFER_1:
+       case ARIZONA_DSP2_WDMA_BUFFER_2:
+       case ARIZONA_DSP2_WDMA_BUFFER_3:
+       case ARIZONA_DSP2_WDMA_BUFFER_4:
+       case ARIZONA_DSP2_WDMA_BUFFER_5:
+       case ARIZONA_DSP2_WDMA_BUFFER_6:
+       case ARIZONA_DSP2_WDMA_BUFFER_7:
+       case ARIZONA_DSP2_WDMA_BUFFER_8:
+       case ARIZONA_DSP2_RDMA_BUFFER_1:
+       case ARIZONA_DSP2_RDMA_BUFFER_2:
+       case ARIZONA_DSP2_RDMA_BUFFER_3:
+       case ARIZONA_DSP2_RDMA_BUFFER_4:
+       case ARIZONA_DSP2_RDMA_BUFFER_5:
+       case ARIZONA_DSP2_RDMA_BUFFER_6:
+       case ARIZONA_DSP2_WDMA_CONFIG_1:
+       case ARIZONA_DSP2_WDMA_CONFIG_2:
+       case ARIZONA_DSP2_WDMA_OFFSET_1:
+       case ARIZONA_DSP2_RDMA_CONFIG_1:
+       case ARIZONA_DSP2_RDMA_OFFSET_1:
+       case ARIZONA_DSP2_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP2_SCRATCH_0:
        case ARIZONA_DSP2_SCRATCH_1:
        case ARIZONA_DSP2_SCRATCH_2:
@@ -2479,6 +2521,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP3_STATUS_1:
        case ARIZONA_DSP3_STATUS_2:
        case ARIZONA_DSP3_STATUS_3:
+       case ARIZONA_DSP3_STATUS_4:
+       case ARIZONA_DSP3_WDMA_BUFFER_1:
+       case ARIZONA_DSP3_WDMA_BUFFER_2:
+       case ARIZONA_DSP3_WDMA_BUFFER_3:
+       case ARIZONA_DSP3_WDMA_BUFFER_4:
+       case ARIZONA_DSP3_WDMA_BUFFER_5:
+       case ARIZONA_DSP3_WDMA_BUFFER_6:
+       case ARIZONA_DSP3_WDMA_BUFFER_7:
+       case ARIZONA_DSP3_WDMA_BUFFER_8:
+       case ARIZONA_DSP3_RDMA_BUFFER_1:
+       case ARIZONA_DSP3_RDMA_BUFFER_2:
+       case ARIZONA_DSP3_RDMA_BUFFER_3:
+       case ARIZONA_DSP3_RDMA_BUFFER_4:
+       case ARIZONA_DSP3_RDMA_BUFFER_5:
+       case ARIZONA_DSP3_RDMA_BUFFER_6:
+       case ARIZONA_DSP3_WDMA_CONFIG_1:
+       case ARIZONA_DSP3_WDMA_CONFIG_2:
+       case ARIZONA_DSP3_WDMA_OFFSET_1:
+       case ARIZONA_DSP3_RDMA_CONFIG_1:
+       case ARIZONA_DSP3_RDMA_OFFSET_1:
+       case ARIZONA_DSP3_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP3_SCRATCH_0:
        case ARIZONA_DSP3_SCRATCH_1:
        case ARIZONA_DSP3_SCRATCH_2:
@@ -2488,6 +2551,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP4_STATUS_1:
        case ARIZONA_DSP4_STATUS_2:
        case ARIZONA_DSP4_STATUS_3:
+       case ARIZONA_DSP4_STATUS_4:
+       case ARIZONA_DSP4_WDMA_BUFFER_1:
+       case ARIZONA_DSP4_WDMA_BUFFER_2:
+       case ARIZONA_DSP4_WDMA_BUFFER_3:
+       case ARIZONA_DSP4_WDMA_BUFFER_4:
+       case ARIZONA_DSP4_WDMA_BUFFER_5:
+       case ARIZONA_DSP4_WDMA_BUFFER_6:
+       case ARIZONA_DSP4_WDMA_BUFFER_7:
+       case ARIZONA_DSP4_WDMA_BUFFER_8:
+       case ARIZONA_DSP4_RDMA_BUFFER_1:
+       case ARIZONA_DSP4_RDMA_BUFFER_2:
+       case ARIZONA_DSP4_RDMA_BUFFER_3:
+       case ARIZONA_DSP4_RDMA_BUFFER_4:
+       case ARIZONA_DSP4_RDMA_BUFFER_5:
+       case ARIZONA_DSP4_RDMA_BUFFER_6:
+       case ARIZONA_DSP4_WDMA_CONFIG_1:
+       case ARIZONA_DSP4_WDMA_CONFIG_2:
+       case ARIZONA_DSP4_WDMA_OFFSET_1:
+       case ARIZONA_DSP4_RDMA_CONFIG_1:
+       case ARIZONA_DSP4_RDMA_OFFSET_1:
+       case ARIZONA_DSP4_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP4_SCRATCH_0:
        case ARIZONA_DSP4_SCRATCH_1:
        case ARIZONA_DSP4_SCRATCH_2:
@@ -2543,31 +2627,119 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
        case ARIZONA_DSP1_STATUS_3:
+       case ARIZONA_DSP1_STATUS_4:
+       case ARIZONA_DSP1_WDMA_BUFFER_1:
+       case ARIZONA_DSP1_WDMA_BUFFER_2:
+       case ARIZONA_DSP1_WDMA_BUFFER_3:
+       case ARIZONA_DSP1_WDMA_BUFFER_4:
+       case ARIZONA_DSP1_WDMA_BUFFER_5:
+       case ARIZONA_DSP1_WDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_BUFFER_7:
+       case ARIZONA_DSP1_WDMA_BUFFER_8:
+       case ARIZONA_DSP1_RDMA_BUFFER_1:
+       case ARIZONA_DSP1_RDMA_BUFFER_2:
+       case ARIZONA_DSP1_RDMA_BUFFER_3:
+       case ARIZONA_DSP1_RDMA_BUFFER_4:
+       case ARIZONA_DSP1_RDMA_BUFFER_5:
+       case ARIZONA_DSP1_RDMA_BUFFER_6:
+       case ARIZONA_DSP1_WDMA_CONFIG_1:
+       case ARIZONA_DSP1_WDMA_CONFIG_2:
+       case ARIZONA_DSP1_WDMA_OFFSET_1:
+       case ARIZONA_DSP1_RDMA_CONFIG_1:
+       case ARIZONA_DSP1_RDMA_OFFSET_1:
+       case ARIZONA_DSP1_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP1_SCRATCH_0:
        case ARIZONA_DSP1_SCRATCH_1:
        case ARIZONA_DSP1_SCRATCH_2:
        case ARIZONA_DSP1_SCRATCH_3:
+       case ARIZONA_DSP1_CLOCKING_1:
        case ARIZONA_DSP2_STATUS_1:
        case ARIZONA_DSP2_STATUS_2:
        case ARIZONA_DSP2_STATUS_3:
+       case ARIZONA_DSP2_STATUS_4:
+       case ARIZONA_DSP2_WDMA_BUFFER_1:
+       case ARIZONA_DSP2_WDMA_BUFFER_2:
+       case ARIZONA_DSP2_WDMA_BUFFER_3:
+       case ARIZONA_DSP2_WDMA_BUFFER_4:
+       case ARIZONA_DSP2_WDMA_BUFFER_5:
+       case ARIZONA_DSP2_WDMA_BUFFER_6:
+       case ARIZONA_DSP2_WDMA_BUFFER_7:
+       case ARIZONA_DSP2_WDMA_BUFFER_8:
+       case ARIZONA_DSP2_RDMA_BUFFER_1:
+       case ARIZONA_DSP2_RDMA_BUFFER_2:
+       case ARIZONA_DSP2_RDMA_BUFFER_3:
+       case ARIZONA_DSP2_RDMA_BUFFER_4:
+       case ARIZONA_DSP2_RDMA_BUFFER_5:
+       case ARIZONA_DSP2_RDMA_BUFFER_6:
+       case ARIZONA_DSP2_WDMA_CONFIG_1:
+       case ARIZONA_DSP2_WDMA_CONFIG_2:
+       case ARIZONA_DSP2_WDMA_OFFSET_1:
+       case ARIZONA_DSP2_RDMA_CONFIG_1:
+       case ARIZONA_DSP2_RDMA_OFFSET_1:
+       case ARIZONA_DSP2_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP2_SCRATCH_0:
        case ARIZONA_DSP2_SCRATCH_1:
        case ARIZONA_DSP2_SCRATCH_2:
        case ARIZONA_DSP2_SCRATCH_3:
+       case ARIZONA_DSP2_CLOCKING_1:
        case ARIZONA_DSP3_STATUS_1:
        case ARIZONA_DSP3_STATUS_2:
        case ARIZONA_DSP3_STATUS_3:
+       case ARIZONA_DSP3_STATUS_4:
+       case ARIZONA_DSP3_WDMA_BUFFER_1:
+       case ARIZONA_DSP3_WDMA_BUFFER_2:
+       case ARIZONA_DSP3_WDMA_BUFFER_3:
+       case ARIZONA_DSP3_WDMA_BUFFER_4:
+       case ARIZONA_DSP3_WDMA_BUFFER_5:
+       case ARIZONA_DSP3_WDMA_BUFFER_6:
+       case ARIZONA_DSP3_WDMA_BUFFER_7:
+       case ARIZONA_DSP3_WDMA_BUFFER_8:
+       case ARIZONA_DSP3_RDMA_BUFFER_1:
+       case ARIZONA_DSP3_RDMA_BUFFER_2:
+       case ARIZONA_DSP3_RDMA_BUFFER_3:
+       case ARIZONA_DSP3_RDMA_BUFFER_4:
+       case ARIZONA_DSP3_RDMA_BUFFER_5:
+       case ARIZONA_DSP3_RDMA_BUFFER_6:
+       case ARIZONA_DSP3_WDMA_CONFIG_1:
+       case ARIZONA_DSP3_WDMA_CONFIG_2:
+       case ARIZONA_DSP3_WDMA_OFFSET_1:
+       case ARIZONA_DSP3_RDMA_CONFIG_1:
+       case ARIZONA_DSP3_RDMA_OFFSET_1:
+       case ARIZONA_DSP3_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP3_SCRATCH_0:
        case ARIZONA_DSP3_SCRATCH_1:
        case ARIZONA_DSP3_SCRATCH_2:
        case ARIZONA_DSP3_SCRATCH_3:
+       case ARIZONA_DSP3_CLOCKING_1:
        case ARIZONA_DSP4_STATUS_1:
        case ARIZONA_DSP4_STATUS_2:
        case ARIZONA_DSP4_STATUS_3:
+       case ARIZONA_DSP4_STATUS_4:
+       case ARIZONA_DSP4_WDMA_BUFFER_1:
+       case ARIZONA_DSP4_WDMA_BUFFER_2:
+       case ARIZONA_DSP4_WDMA_BUFFER_3:
+       case ARIZONA_DSP4_WDMA_BUFFER_4:
+       case ARIZONA_DSP4_WDMA_BUFFER_5:
+       case ARIZONA_DSP4_WDMA_BUFFER_6:
+       case ARIZONA_DSP4_WDMA_BUFFER_7:
+       case ARIZONA_DSP4_WDMA_BUFFER_8:
+       case ARIZONA_DSP4_RDMA_BUFFER_1:
+       case ARIZONA_DSP4_RDMA_BUFFER_2:
+       case ARIZONA_DSP4_RDMA_BUFFER_3:
+       case ARIZONA_DSP4_RDMA_BUFFER_4:
+       case ARIZONA_DSP4_RDMA_BUFFER_5:
+       case ARIZONA_DSP4_RDMA_BUFFER_6:
+       case ARIZONA_DSP4_WDMA_CONFIG_1:
+       case ARIZONA_DSP4_WDMA_CONFIG_2:
+       case ARIZONA_DSP4_WDMA_OFFSET_1:
+       case ARIZONA_DSP4_RDMA_CONFIG_1:
+       case ARIZONA_DSP4_RDMA_OFFSET_1:
+       case ARIZONA_DSP4_EXTERNAL_START_SELECT_1:
        case ARIZONA_DSP4_SCRATCH_0:
        case ARIZONA_DSP4_SCRATCH_1:
        case ARIZONA_DSP4_SCRATCH_2:
        case ARIZONA_DSP4_SCRATCH_3:
+       case ARIZONA_DSP4_CLOCKING_1:
                return true;
        default:
                return wm5110_is_adsp_memory(dev, reg);
index 7c1ae24605d936e51e0ae485c59dcbf9c2f5372b..4ab527f5c53b65ff2872ba07fcef30982a390f3a 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/bug.h>
 #include <linux/device.h>
index 624ff90501cde3c5fdf1e79f026db8cfa321eb37..cd01f7962dfdf996e8a4a695ffbd37db64a69da6 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
index d66d256551fb77768fc9d458d5493c976ec25f30..e5eae751aa1b1f22e6747fd94bc85ba62174f8d8 100644 (file)
@@ -161,31 +161,19 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm8400 *wm8400;
-       int ret;
 
        wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL);
-       if (wm8400 == NULL) {
-               ret = -ENOMEM;
-               goto err;
-       }
+       if (!wm8400)
+               return -ENOMEM;
 
        wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
-       if (IS_ERR(wm8400->regmap)) {
-               ret = PTR_ERR(wm8400->regmap);
-               goto err;
-       }
+       if (IS_ERR(wm8400->regmap))
+               return PTR_ERR(wm8400->regmap);
 
        wm8400->dev = &i2c->dev;
        i2c_set_clientdata(i2c, wm8400);
 
-       ret = wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
-       if (ret != 0)
-               goto err;
-
-       return 0;
-
-err:
-       return ret;
+       return wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
 }
 
 static int wm8400_i2c_remove(struct i2c_client *i2c)
index 168bc72f7a94a9b662d7c0a97775c781d4d769aa..84c0e59b792acce9e0508fe038e05d204dd2b2d8 100644 (file)
 #define MCI_CPSM_INTERRUPT     (1 << 8)
 #define MCI_CPSM_PENDING       (1 << 9)
 #define MCI_CPSM_ENABLE                (1 << 10)
-#define MCI_SDIO_SUSP          (1 << 11)
-#define MCI_ENCMD_COMPL                (1 << 12)
-#define MCI_NIEN               (1 << 13)
-#define MCI_CE_ATACMD          (1 << 14)
+/* Argument flag extenstions in the ST Micro versions */
+#define MCI_ST_SDIO_SUSP       (1 << 11)
+#define MCI_ST_ENCMD_COMPL     (1 << 12)
+#define MCI_ST_NIEN            (1 << 13)
+#define MCI_ST_CE_ATACMD       (1 << 14)
 
 #define MMCIRESPCMD            0x010
 #define MMCIRESPONSE0          0x014
index 5ebcda39f55407e146ab06d811edd5825939a41d..5d49a21296187cc1c228d249b16bbbb7d79405f7 100644 (file)
@@ -150,7 +150,7 @@ config MTD_BCM63XX_PARTS
 
 config MTD_BCM47XX_PARTS
        tristate "BCM47XX partitioning support"
-       depends on BCM47XX
+       depends on BCM47XX || ARCH_BCM_5301X
        help
          This provides partitions parser for devices based on BCM47xx
          boards.
index de1eb92e42f57f15f197c3ba21d1831ab6dac06f..adfa74c1bc45077e12fe78c1601b74923834fdec 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <bcm47xx_nvram.h>
 
 /* 10 parts were found on sflash on Netgear WNDR4500 */
 #define BCM47XXPART_MAX_PARTS          12
@@ -30,6 +29,7 @@
 #define BOARD_DATA_MAGIC2              0xBD0D0BBD
 #define CFE_MAGIC                      0x43464531      /* 1EFC */
 #define FACTORY_MAGIC                  0x59544346      /* FCTY */
+#define NVRAM_HEADER                   0x48534C46      /* FLSH */
 #define POT_MAGIC1                     0x54544f50      /* POTT */
 #define POT_MAGIC2                     0x504f          /* OP */
 #define ML_MAGIC1                      0x39685a42
@@ -91,7 +91,7 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                if (offset >= 0x2000000)
                        break;
 
-               if (curr_part > BCM47XXPART_MAX_PARTS) {
+               if (curr_part >= BCM47XXPART_MAX_PARTS) {
                        pr_warn("Reached maximum number of partitions, scanning stopped!\n");
                        break;
                }
@@ -147,6 +147,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 
                /* TRX */
                if (buf[0x000 / 4] == TRX_MAGIC) {
+                       if (BCM47XXPART_MAX_PARTS - curr_part < 4) {
+                               pr_warn("Not enough partitions left to register trx, scanning stopped!\n");
+                               break;
+                       }
+
                        trx = (struct trx_header *)buf;
 
                        trx_part = curr_part;
@@ -212,7 +217,7 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 
        /* Look for NVRAM at the end of the last block. */
        for (i = 0; i < ARRAY_SIZE(possible_nvram_sizes); i++) {
-               if (curr_part > BCM47XXPART_MAX_PARTS) {
+               if (curr_part >= BCM47XXPART_MAX_PARTS) {
                        pr_warn("Reached maximum number of partitions, scanning stopped!\n");
                        break;
                }
index 77514430f1fe57d7156862ac0ef06b45d8fa35ba..e4ec355704a6c94488f57b567c93a75301d8fa7a 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
@@ -69,10 +68,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, s
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
-static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
-                                           struct otp_info *, size_t);
-static int cfi_intelext_get_user_prot_info (struct mtd_info *,
-                                           struct otp_info *, size_t);
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+                                          size_t *, struct otp_info *);
+static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
+                                          size_t *, struct otp_info *);
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
@@ -435,10 +434,8 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
        int i;
 
        mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
-       if (!mtd) {
-               printk(KERN_ERR "Failed to allocate memory for MTD device\n");
+       if (!mtd)
                return NULL;
-       }
        mtd->priv = map;
        mtd->type = MTD_NORFLASH;
 
@@ -564,10 +561,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
        mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
        mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
                        * mtd->numeraseregions, GFP_KERNEL);
-       if (!mtd->eraseregions) {
-               printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
+       if (!mtd->eraseregions)
                goto setup_err;
-       }
 
        for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
                unsigned long ernum, ersize;
@@ -2399,24 +2394,19 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
                                     NULL, do_otp_lock, 1);
 }
 
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
-                                          struct otp_info *buf, size_t len)
-{
-       size_t retlen;
-       int ret;
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+                                          size_t *retlen, struct otp_info *buf)
 
-       ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0);
-       return ret ? : retlen;
+{
+       return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+                                    NULL, 0);
 }
 
-static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
-                                          struct otp_info *buf, size_t len)
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len,
+                                          size_t *retlen, struct otp_info *buf)
 {
-       size_t retlen;
-       int ret;
-
-       ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1);
-       return ret ? : retlen;
+       return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+                                    NULL, 1);
 }
 
 #endif
index 89b9d689153298f3b7a3965adf811a3d9963de7c..e21fde9d4d7e2d07ff8bc5d86bae597e69d1da17 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
@@ -507,10 +506,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
        int i;
 
        mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
-       if (!mtd) {
-               printk(KERN_WARNING "Failed to allocate memory for MTD device\n");
+       if (!mtd)
                return NULL;
-       }
        mtd->priv = map;
        mtd->type = MTD_NORFLASH;
 
@@ -661,10 +658,8 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
        mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
        mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
                                    * mtd->numeraseregions, GFP_KERNEL);
-       if (!mtd->eraseregions) {
-               printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
+       if (!mtd->eraseregions)
                goto setup_err;
-       }
 
        for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
                unsigned long ernum, ersize;
index 096993f9711e1176e907685001260c8aaa39ff5b..6293855fb5ee190b84a23ea0eda4257cdd930344 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
@@ -176,7 +175,6 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
        //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);
 
        if (!mtd) {
-               printk(KERN_ERR "Failed to allocate memory for MTD device\n");
                kfree(cfi->cmdset_priv);
                return NULL;
        }
@@ -189,7 +187,6 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
        mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
                        * mtd->numeraseregions, GFP_KERNEL);
        if (!mtd->eraseregions) {
-               printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
                kfree(cfi->cmdset_priv);
                kfree(mtd);
                return NULL;
index d25535279404a7b7d101692b3f5c3f262cd0626e..e8d0164498b097be6dabe24241e24528712ab3ff 100644 (file)
@@ -168,10 +168,8 @@ static int __xipram cfi_chip_setup(struct map_info *map,
                return 0;
 
        cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
-       if (!cfi->cfiq) {
-               printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
+       if (!cfi->cfiq)
                return 0;
-       }
 
        memset(cfi->cfiq,0,sizeof(struct cfi_ident));
 
index f992418f40a8d074277dd2798cb888bcc7fa404b..08049f6eea60e8fb00ab9fd1bf5a92dd2775afa5 100644 (file)
@@ -116,10 +116,8 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
        printk(KERN_INFO "%s Extended Query Table at 0x%4.4X\n", name, adr);
 
        extp = kmalloc(size, GFP_KERNEL);
-       if (!extp) {
-               printk(KERN_ERR "Failed to allocate memory\n");
+       if (!extp)
                goto out;
-       }
 
 #ifdef CONFIG_MTD_XIP
        local_irq_disable();
index ffb36ba8a6e050e0d8da73a7661cd7734905707d..b57ceea21513acd0e017b994fe2170905f80bf0a 100644 (file)
@@ -114,7 +114,6 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
        mapsize = sizeof(long) * DIV_ROUND_UP(max_chips, BITS_PER_LONG);
        chip_map = kzalloc(mapsize, GFP_KERNEL);
        if (!chip_map) {
-               printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
                kfree(cfi.cfiq);
                return NULL;
        }
@@ -139,7 +138,6 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
        retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);
 
        if (!retcfi) {
-               printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
                kfree(cfi.cfiq);
                kfree(chip_map);
                return NULL;
index 01281382180b4c53182d2b07aa4bdd426de34559..1210bc2923b71386b94fd53bd4440d8df137486b 100644 (file)
@@ -210,6 +210,14 @@ config MTD_DOCG3
          M-Systems and now Sandisk. The support is very experimental,
          and doesn't give access to any write operations.
 
+config MTD_ST_SPI_FSM
+       tristate "ST Microelectronics SPI FSM Serial Flash Controller"
+       depends on ARM || SH
+       help
+         This provides an MTD device driver for the ST Microelectronics
+         SPI Fast Sequence Mode (FSM) Serial Flash Controller and support
+         for a subset of connected Serial Flash devices.
+
 if MTD_DOCG3
 config BCH_CONST_M
        default 14
index d83bd73096f67d916525371a5f51a3dec933877f..c68868f605883cab2d9507179a8fd0f340565ce9 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_NAND_OMAP_BCH)       += elm.o
 obj-$(CONFIG_MTD_SPEAR_SMI)    += spear_smi.o
 obj-$(CONFIG_MTD_SST25L)       += sst25l.o
 obj-$(CONFIG_MTD_BCM47XXSFLASH)        += bcm47xxsflash.o
+obj-$(CONFIG_MTD_ST_SPI_FSM)    += st_spi_fsm.o
 
 
 CFLAGS_docg3.o                 += -I$(src)
index d9fd87a4c8dc08a6b191e4454cf529898c1688c6..66f0405f7e535b33f02f71586ffe4bc13b5f1ee0 100644 (file)
@@ -209,7 +209,6 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
 }
 
 
-/* FIXME: ensure that mtd->size % erase_size == 0 */
 static struct block2mtd_dev *add_device(char *devname, int erase_size)
 {
        const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
@@ -240,13 +239,18 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 
        if (IS_ERR(bdev)) {
                pr_err("error: cannot open device %s\n", devname);
-               goto devinit_err;
+               goto err_free_block2mtd;
        }
        dev->blkdev = bdev;
 
        if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
                pr_err("attempting to use an MTD device as a block device\n");
-               goto devinit_err;
+               goto err_free_block2mtd;
+       }
+
+       if ((long)dev->blkdev->bd_inode->i_size % erase_size) {
+               pr_err("erasesize must be a divisor of device size\n");
+               goto err_free_block2mtd;
        }
 
        mutex_init(&dev->write_mutex);
@@ -255,7 +259,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
        /* make the name contain the block device in */
        name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
        if (!name)
-               goto devinit_err;
+               goto err_destroy_mutex;
 
        dev->mtd.name = name;
 
@@ -274,7 +278,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 
        if (mtd_device_register(&dev->mtd, NULL, 0)) {
                /* Device didn't get added, so free the entry */
-               goto devinit_err;
+               goto err_destroy_mutex;
        }
        list_add(&dev->list, &blkmtd_device_list);
        pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n",
@@ -283,7 +287,9 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
                dev->mtd.erasesize >> 10, dev->mtd.erasesize);
        return dev;
 
-devinit_err:
+err_destroy_mutex:
+       mutex_destroy(&dev->write_mutex);
+err_free_block2mtd:
        block2mtd_free_device(dev);
        return NULL;
 }
@@ -448,6 +454,7 @@ static void block2mtd_exit(void)
                struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
                block2mtd_sync(&dev->mtd);
                mtd_device_unregister(&dev->mtd);
+               mutex_destroy(&dev->write_mutex);
                pr_info("mtd%d: [%s] removed\n",
                        dev->mtd.index,
                        dev->mtd.name + strlen("block2mtd: "));
index d1dd6a33a0500831f78012f9be91afa0161e4574..1fd4a0f779674475513837c4ed18a7e30f3a259d 100644 (file)
@@ -15,6 +15,8 @@
  *
  */
 
+#define DRIVER_NAME    "omap-elm"
+
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -84,6 +86,8 @@ struct elm_info {
        struct list_head list;
        enum bch_ecc bch_type;
        struct elm_registers elm_regs;
+       int ecc_steps;
+       int ecc_syndrome_size;
 };
 
 static LIST_HEAD(elm_devices);
@@ -103,7 +107,8 @@ static u32 elm_read_reg(struct elm_info *info, int offset)
  * @dev:       ELM device
  * @bch_type:  Type of BCH ecc
  */
-int elm_config(struct device *dev, enum bch_ecc bch_type)
+int elm_config(struct device *dev, enum bch_ecc bch_type,
+       int ecc_steps, int ecc_step_size, int ecc_syndrome_size)
 {
        u32 reg_val;
        struct elm_info *info = dev_get_drvdata(dev);
@@ -112,10 +117,22 @@ int elm_config(struct device *dev, enum bch_ecc bch_type)
                dev_err(dev, "Unable to configure elm - device not probed?\n");
                return -ENODEV;
        }
+       /* ELM cannot detect ECC errors for chunks > 1KB */
+       if (ecc_step_size > ((ELM_ECC_SIZE + 1) / 2)) {
+               dev_err(dev, "unsupported config ecc-size=%d\n", ecc_step_size);
+               return -EINVAL;
+       }
+       /* ELM support 8 error syndrome process */
+       if (ecc_steps > ERROR_VECTOR_MAX) {
+               dev_err(dev, "unsupported config ecc-step=%d\n", ecc_steps);
+               return -EINVAL;
+       }
 
        reg_val = (bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
        elm_write_reg(info, ELM_LOCATION_CONFIG, reg_val);
-       info->bch_type = bch_type;
+       info->bch_type          = bch_type;
+       info->ecc_steps         = ecc_steps;
+       info->ecc_syndrome_size = ecc_syndrome_size;
 
        return 0;
 }
@@ -157,17 +174,15 @@ static void elm_load_syndrome(struct elm_info *info,
        int i, offset;
        u32 val;
 
-       for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+       for (i = 0; i < info->ecc_steps; i++) {
 
                /* Check error reported */
                if (err_vec[i].error_reported) {
                        elm_configure_page_mode(info, i, true);
                        offset = ELM_SYNDROME_FRAGMENT_0 +
                                SYNDROME_FRAGMENT_REG_SIZE * i;
-
-                       /* BCH8 */
-                       if (info->bch_type) {
-
+                       switch (info->bch_type) {
+                       case BCH8_ECC:
                                /* syndrome fragment 0 = ecc[9-12B] */
                                val = cpu_to_be32(*(u32 *) &ecc[9]);
                                elm_write_reg(info, offset, val);
@@ -186,7 +201,8 @@ static void elm_load_syndrome(struct elm_info *info,
                                offset += 4;
                                val = ecc[0];
                                elm_write_reg(info, offset, val);
-                       } else {
+                               break;
+                       case BCH4_ECC:
                                /* syndrome fragment 0 = ecc[20-52b] bits */
                                val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) |
                                        ((ecc[2] & 0xf) << 28);
@@ -196,11 +212,14 @@ static void elm_load_syndrome(struct elm_info *info,
                                offset += 4;
                                val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12;
                                elm_write_reg(info, offset, val);
+                               break;
+                       default:
+                               pr_err("invalid config bch_type\n");
                        }
                }
 
                /* Update ecc pointer with ecc byte size */
-               ecc += info->bch_type ? BCH8_SIZE : BCH4_SIZE;
+               ecc += info->ecc_syndrome_size;
        }
 }
 
@@ -223,7 +242,7 @@ static void elm_start_processing(struct elm_info *info,
         * Set syndrome vector valid, so that ELM module
         * will process it for vectors error is reported
         */
-       for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+       for (i = 0; i < info->ecc_steps; i++) {
                if (err_vec[i].error_reported) {
                        offset = ELM_SYNDROME_FRAGMENT_6 +
                                SYNDROME_FRAGMENT_REG_SIZE * i;
@@ -252,7 +271,7 @@ static void elm_error_correction(struct elm_info *info,
        int offset;
        u32 reg_val;
 
-       for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+       for (i = 0; i < info->ecc_steps; i++) {
 
                /* Check error reported */
                if (err_vec[i].error_reported) {
@@ -354,10 +373,8 @@ static int elm_probe(struct platform_device *pdev)
        struct elm_info *info;
 
        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
-       if (!info) {
-               dev_err(&pdev->dev, "failed to allocate memory\n");
+       if (!info)
                return -ENOMEM;
-       }
 
        info->dev = &pdev->dev;
 
@@ -380,7 +397,7 @@ static int elm_probe(struct platform_device *pdev)
        }
 
        pm_runtime_enable(&pdev->dev);
-       if (pm_runtime_get_sync(&pdev->dev)) {
+       if (pm_runtime_get_sync(&pdev->dev) < 0) {
                ret = -EINVAL;
                pm_runtime_disable(&pdev->dev);
                dev_err(&pdev->dev, "can't enable clock\n");
@@ -505,7 +522,7 @@ MODULE_DEVICE_TABLE(of, elm_of_match);
 
 static struct platform_driver elm_driver = {
        .driver = {
-               .name   = "elm",
+               .name   = DRIVER_NAME,
                .owner  = THIS_MODULE,
                .of_match_table = of_match_ptr(elm_of_match),
                .pm     = &elm_pm_ops,
index ad19139097025b97839fb7cbe123a1261e6cf876..524dab3ac9381f4d9efee0bbbfad98cb9171888a 100644 (file)
@@ -15,7 +15,6 @@
  *
  */
 
-#include <linux/init.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/module.h>
@@ -41,7 +40,8 @@
 #define        OPCODE_WRSR             0x01    /* Write status register 1 byte */
 #define        OPCODE_NORM_READ        0x03    /* Read data bytes (low frequency) */
 #define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
-#define        OPCODE_QUAD_READ        0x6b    /* Read data bytes */
+#define        OPCODE_DUAL_READ        0x3b    /* Read data bytes (Dual SPI) */
+#define        OPCODE_QUAD_READ        0x6b    /* Read data bytes (Quad SPI) */
 #define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
 #define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
 #define        OPCODE_BE_4K_PMC        0xd7    /* Erase 4KiB block on PMC chips */
@@ -54,7 +54,8 @@
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define        OPCODE_NORM_READ_4B     0x13    /* Read data bytes (low frequency) */
 #define        OPCODE_FAST_READ_4B     0x0c    /* Read data bytes (high frequency) */
-#define        OPCODE_QUAD_READ_4B     0x6c    /* Read data bytes */
+#define        OPCODE_DUAL_READ_4B     0x3c    /* Read data bytes (Dual SPI) */
+#define        OPCODE_QUAD_READ_4B     0x6c    /* Read data bytes (Quad SPI) */
 #define        OPCODE_PP_4B            0x12    /* Page program (up to 256 bytes) */
 #define        OPCODE_SE_4B            0xdc    /* Sector erase (usually 64KiB) */
 
@@ -95,6 +96,7 @@
 enum read_type {
        M25P80_NORMAL = 0,
        M25P80_FAST,
+       M25P80_DUAL,
        M25P80_QUAD,
 };
 
@@ -479,6 +481,7 @@ static inline int m25p80_dummy_cycles_read(struct m25p *flash)
 {
        switch (flash->flash_read) {
        case M25P80_FAST:
+       case M25P80_DUAL:
        case M25P80_QUAD:
                return 1;
        case M25P80_NORMAL:
@@ -492,6 +495,8 @@ static inline int m25p80_dummy_cycles_read(struct m25p *flash)
 static inline unsigned int m25p80_rx_nbits(const struct m25p *flash)
 {
        switch (flash->flash_read) {
+       case M25P80_DUAL:
+               return 2;
        case M25P80_QUAD:
                return 4;
        default:
@@ -855,7 +860,8 @@ struct flash_info {
 #define        SST_WRITE       0x04            /* use SST byte programming */
 #define        M25P_NO_FR      0x08            /* Can't do fastread */
 #define        SECT_4K_PMC     0x10            /* OPCODE_BE_4K_PMC works uniformly */
-#define        M25P80_QUAD_READ        0x20    /* Flash supports Quad Read */
+#define        M25P80_DUAL_READ        0x20    /* Flash supports Dual Read */
+#define        M25P80_QUAD_READ        0x40    /* Flash supports Quad Read */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)     \
@@ -934,6 +940,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
        { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
+       { "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, M25P80_QUAD_READ) },
 
        /* Micron */
        { "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
@@ -953,8 +960,8 @@ static const struct spi_device_id m25p_ids[] = {
        { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
        { "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
        { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, M25P80_QUAD_READ) },
-       { "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, M25P80_QUAD_READ) },
+       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, M25P80_DUAL_READ | M25P80_QUAD_READ) },
+       { "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, M25P80_DUAL_READ | M25P80_QUAD_READ) },
        { "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
        { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
        { "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
@@ -965,6 +972,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
        { "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
        { "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
+       { "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SECT_4K) },
        { "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
        { "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
 
@@ -1072,9 +1080,8 @@ static const struct spi_device_id *jedec_probe(struct spi_device *spi)
        for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
                info = (void *)m25p_ids[tmp].driver_data;
                if (info->jedec_id == jedec) {
-                       if (info->ext_id != 0 && info->ext_id != ext_jedec)
-                               continue;
-                       return &m25p_ids[tmp];
+                       if (info->ext_id == 0 || info->ext_id == ext_jedec)
+                               return &m25p_ids[tmp];
                }
        }
        dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
@@ -1226,7 +1233,7 @@ static int m25p_probe(struct spi_device *spi)
        if (info->flags & M25P_NO_FR)
                flash->flash_read = M25P80_NORMAL;
 
-       /* Quad-read mode takes precedence over fast/normal */
+       /* Quad/Dual-read mode takes precedence over fast/normal */
        if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
                ret = set_quad_mode(flash, info->jedec_id);
                if (ret) {
@@ -1234,6 +1241,8 @@ static int m25p_probe(struct spi_device *spi)
                        return ret;
                }
                flash->flash_read = M25P80_QUAD;
+       } else if (spi->mode & SPI_RX_DUAL && info->flags & M25P80_DUAL_READ) {
+               flash->flash_read = M25P80_DUAL;
        }
 
        /* Default commands */
@@ -1241,6 +1250,9 @@ static int m25p_probe(struct spi_device *spi)
        case M25P80_QUAD:
                flash->read_opcode = OPCODE_QUAD_READ;
                break;
+       case M25P80_DUAL:
+               flash->read_opcode = OPCODE_DUAL_READ;
+               break;
        case M25P80_FAST:
                flash->read_opcode = OPCODE_FAST_READ;
                break;
@@ -1265,6 +1277,9 @@ static int m25p_probe(struct spi_device *spi)
                        case M25P80_QUAD:
                                flash->read_opcode = OPCODE_QUAD_READ_4B;
                                break;
+                       case M25P80_DUAL:
+                               flash->read_opcode = OPCODE_DUAL_READ_4B;
+                               break;
                        case M25P80_FAST:
                                flash->read_opcode = OPCODE_FAST_READ_4B;
                                break;
index 624069de4f28c067260fc4fec75c35b713fc5c84..dd22ce2cc9ad6a901d85d28215fcdf0825a0550b 100644 (file)
@@ -10,7 +10,6 @@
  * 2 of the License, or (at your option) any later version.
 */
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -440,8 +439,8 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 #ifdef CONFIG_MTD_DATAFLASH_OTP
 
-static int dataflash_get_otp_info(struct mtd_info *mtd,
-               struct otp_info *info, size_t len)
+static int dataflash_get_otp_info(struct mtd_info *mtd, size_t len,
+                                 size_t *retlen, struct otp_info *info)
 {
        /* Report both blocks as identical:  bytes 0..64, locked.
         * Unless the user block changed from all-ones, we can't
@@ -450,7 +449,8 @@ static int dataflash_get_otp_info(struct mtd_info *mtd,
        info->start = 0;
        info->length = 64;
        info->locked = 1;
-       return sizeof(*info);
+       *retlen = sizeof(*info);
+       return 0;
 }
 
 static ssize_t otp_read(struct spi_device *spi, unsigned base,
@@ -542,14 +542,18 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
        struct dataflash        *priv = mtd->priv;
        int                     status;
 
-       if (len > 64)
-               return -EINVAL;
+       if (from >= 64) {
+               /*
+                * Attempting to write beyond the end of OTP memory,
+                * no data can be written.
+                */
+               *retlen = 0;
+               return 0;
+       }
 
-       /* Strictly speaking, we *could* truncate the write ... but
-        * let's not do that for the only write that's ever possible.
-        */
+       /* Truncate the write to fit into OTP memory. */
        if ((from + len) > 64)
-               return -EINVAL;
+               len = 64 - from;
 
        /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
         * IN:  ignore all
index e1f2aebaa48955035f6eef98f31e7640202461f1..2cceebfb251e7b6959758b8c7a6bc19b4c9a6c1e 100644 (file)
@@ -205,6 +205,8 @@ static inline void kill_final_newline(char *str)
        return 1;               \
 } while (0)
 
+#ifndef MODULE
+static int phram_init_called;
 /*
  * This shall contain the module parameter if any. It is of the form:
  * - phram=<device>,<address>,<size> for module case
@@ -213,9 +215,10 @@ static inline void kill_final_newline(char *str)
  * size.
  * Example: phram.phram=rootfs,0xa0000000,512Mi
  */
-static __initdata char phram_paramline[64 + 20 + 20];
+static char phram_paramline[64 + 20 + 20];
+#endif
 
-static int __init phram_setup(const char *val)
+static int phram_setup(const char *val)
 {
        char buf[64 + 20 + 20], *str = buf;
        char *token[3];
@@ -264,17 +267,36 @@ static int __init phram_setup(const char *val)
        return ret;
 }
 
-static int __init phram_param_call(const char *val, struct kernel_param *kp)
+static int phram_param_call(const char *val, struct kernel_param *kp)
 {
+#ifdef MODULE
+       return phram_setup(val);
+#else
        /*
-        * This function is always called before 'init_phram()', whether
-        * built-in or module.
+        * If more parameters are later passed in via
+        * /sys/module/phram/parameters/phram
+        * and init_phram() has already been called,
+        * we can parse the argument now.
         */
+
+       if (phram_init_called)
+               return phram_setup(val);
+
+       /*
+        * During early boot stage, we only save the parameters
+        * here. We must parse them later: if the param passed
+        * from kernel boot command line, phram_param_call() is
+        * called so early that it is not possible to resolve
+        * the device (even kmalloc() fails). Defer that work to
+        * phram_setup().
+        */
+
        if (strlen(val) >= sizeof(phram_paramline))
                return -ENOSPC;
        strcpy(phram_paramline, val);
 
        return 0;
+#endif
 }
 
 module_param_call(phram, phram_param_call, NULL, NULL, 000);
@@ -283,10 +305,15 @@ MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\"
 
 static int __init init_phram(void)
 {
+       int ret = 0;
+
+#ifndef MODULE
        if (phram_paramline[0])
-               return phram_setup(phram_paramline);
+               ret = phram_setup(phram_paramline);
+       phram_init_called = 1;
+#endif
 
-       return 0;
+       return ret;
 }
 
 static void __exit cleanup_phram(void)
index 0c51b988e1f8880af884995540cee3c5ac91dfca..f02603e1bfeb974ca08a101ae8bb58927c1d1f81 100644 (file)
@@ -725,16 +725,11 @@ static int __init init_pmc551(void)
                }
 
                mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
-               if (!mtd) {
-                       printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
-                               "device.\n");
+               if (!mtd)
                        break;
-               }
 
                priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL);
                if (!priv) {
-                       printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
-                               "device.\n");
                        kfree(mtd);
                        break;
                }
diff --git a/drivers/mtd/devices/serial_flash_cmds.h b/drivers/mtd/devices/serial_flash_cmds.h
new file mode 100644 (file)
index 0000000..4f0c2c7
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Generic/SFDP Flash Commands and Device Capabilities
+ *
+ * Copyright (C) 2013 Lee Jones <lee.jones@lianro.org>
+ *
+ * This code is free software; you can 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 _MTD_SERIAL_FLASH_CMDS_H
+#define _MTD_SERIAL_FLASH_CMDS_H
+
+/* Generic Flash Commands/OPCODEs */
+#define FLASH_CMD_WREN         0x06
+#define FLASH_CMD_WRDI         0x04
+#define FLASH_CMD_RDID         0x9f
+#define FLASH_CMD_RDSR         0x05
+#define FLASH_CMD_RDSR2                0x35
+#define FLASH_CMD_WRSR         0x01
+#define FLASH_CMD_SE_4K                0x20
+#define FLASH_CMD_SE_32K       0x52
+#define FLASH_CMD_SE           0xd8
+#define FLASH_CMD_CHIPERASE    0xc7
+#define FLASH_CMD_WRVCR                0x81
+#define FLASH_CMD_RDVCR                0x85
+
+/* JEDEC Standard - Serial Flash Discoverable Parmeters (SFDP) Commands */
+#define FLASH_CMD_READ         0x03    /* READ */
+#define FLASH_CMD_READ_FAST    0x0b    /* FAST READ */
+#define FLASH_CMD_READ_1_1_2   0x3b    /* DUAL OUTPUT READ */
+#define FLASH_CMD_READ_1_2_2   0xbb    /* DUAL I/O READ */
+#define FLASH_CMD_READ_1_1_4   0x6b    /* QUAD OUTPUT READ */
+#define FLASH_CMD_READ_1_4_4   0xeb    /* QUAD I/O READ */
+
+#define FLASH_CMD_WRITE                0x02    /* PAGE PROGRAM */
+#define FLASH_CMD_WRITE_1_1_2  0xa2    /* DUAL INPUT PROGRAM */
+#define FLASH_CMD_WRITE_1_2_2  0xd2    /* DUAL INPUT EXT PROGRAM */
+#define FLASH_CMD_WRITE_1_1_4  0x32    /* QUAD INPUT PROGRAM */
+#define FLASH_CMD_WRITE_1_4_4  0x12    /* QUAD INPUT EXT PROGRAM */
+
+#define FLASH_CMD_EN4B_ADDR    0xb7    /* Enter 4-byte address mode */
+#define FLASH_CMD_EX4B_ADDR    0xe9    /* Exit 4-byte address mode */
+
+/* READ commands with 32-bit addressing */
+#define FLASH_CMD_READ4                0x13
+#define FLASH_CMD_READ4_FAST   0x0c
+#define FLASH_CMD_READ4_1_1_2  0x3c
+#define FLASH_CMD_READ4_1_2_2  0xbc
+#define FLASH_CMD_READ4_1_1_4  0x6c
+#define FLASH_CMD_READ4_1_4_4  0xec
+
+/* Configuration flags */
+#define FLASH_FLAG_SINGLE      0x000000ff
+#define FLASH_FLAG_READ_WRITE  0x00000001
+#define FLASH_FLAG_READ_FAST   0x00000002
+#define FLASH_FLAG_SE_4K       0x00000004
+#define FLASH_FLAG_SE_32K      0x00000008
+#define FLASH_FLAG_CE          0x00000010
+#define FLASH_FLAG_32BIT_ADDR  0x00000020
+#define FLASH_FLAG_RESET       0x00000040
+#define FLASH_FLAG_DYB_LOCKING 0x00000080
+
+#define FLASH_FLAG_DUAL                0x0000ff00
+#define FLASH_FLAG_READ_1_1_2  0x00000100
+#define FLASH_FLAG_READ_1_2_2  0x00000200
+#define FLASH_FLAG_READ_2_2_2  0x00000400
+#define FLASH_FLAG_WRITE_1_1_2 0x00001000
+#define FLASH_FLAG_WRITE_1_2_2 0x00002000
+#define FLASH_FLAG_WRITE_2_2_2 0x00004000
+
+#define FLASH_FLAG_QUAD                0x00ff0000
+#define FLASH_FLAG_READ_1_1_4  0x00010000
+#define FLASH_FLAG_READ_1_4_4  0x00020000
+#define FLASH_FLAG_READ_4_4_4  0x00040000
+#define FLASH_FLAG_WRITE_1_1_4 0x00100000
+#define FLASH_FLAG_WRITE_1_4_4 0x00200000
+#define FLASH_FLAG_WRITE_4_4_4 0x00400000
+
+#endif /* _MTD_SERIAL_FLASH_CMDS_H */
index 42382141206222152d948ecd19f73338e1a30a3f..363da96e6891cea8eecdec0205160d960eff0cd7 100644 (file)
@@ -913,7 +913,6 @@ static int spear_smi_probe(struct platform_device *pdev)
        if (np) {
                pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
                if (!pdata) {
-                       pr_err("%s: ERROR: no memory", __func__);
                        ret = -ENOMEM;
                        goto err;
                }
@@ -943,7 +942,6 @@ static int spear_smi_probe(struct platform_device *pdev)
        dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_ATOMIC);
        if (!dev) {
                ret = -ENOMEM;
-               dev_err(&pdev->dev, "mem alloc fail\n");
                goto err;
        }
 
index 687bf27ec85076c2d735418714c12c537c2dc498..c63ecbcad0b76714c00fbdbc484bccf13b557488 100644 (file)
@@ -15,7 +15,6 @@
  *
  */
 
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
new file mode 100644 (file)
index 0000000..1957d7c
--- /dev/null
@@ -0,0 +1,2108 @@
+/*
+ * st_spi_fsm.c        - ST Fast Sequence Mode (FSM) Serial Flash Controller
+ *
+ * Author: Angus Clark <angus.clark@st.com>
+ *
+ * Copyright (C) 2010-2014 STMicroelectronics Limited
+ *
+ * JEDEC probe based on drivers/mtd/devices/m25p80.c
+ *
+ * This code is free software; you can 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/module.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include "serial_flash_cmds.h"
+
+/*
+ * FSM SPI Controller Registers
+ */
+#define SPI_CLOCKDIV                   0x0010
+#define SPI_MODESELECT                 0x0018
+#define SPI_CONFIGDATA                 0x0020
+#define SPI_STA_MODE_CHANGE            0x0028
+#define SPI_FAST_SEQ_TRANSFER_SIZE     0x0100
+#define SPI_FAST_SEQ_ADD1              0x0104
+#define SPI_FAST_SEQ_ADD2              0x0108
+#define SPI_FAST_SEQ_ADD_CFG           0x010c
+#define SPI_FAST_SEQ_OPC1              0x0110
+#define SPI_FAST_SEQ_OPC2              0x0114
+#define SPI_FAST_SEQ_OPC3              0x0118
+#define SPI_FAST_SEQ_OPC4              0x011c
+#define SPI_FAST_SEQ_OPC5              0x0120
+#define SPI_MODE_BITS                  0x0124
+#define SPI_DUMMY_BITS                 0x0128
+#define SPI_FAST_SEQ_FLASH_STA_DATA    0x012c
+#define SPI_FAST_SEQ_1                 0x0130
+#define SPI_FAST_SEQ_2                 0x0134
+#define SPI_FAST_SEQ_3                 0x0138
+#define SPI_FAST_SEQ_4                 0x013c
+#define SPI_FAST_SEQ_CFG               0x0140
+#define SPI_FAST_SEQ_STA               0x0144
+#define SPI_QUAD_BOOT_SEQ_INIT_1       0x0148
+#define SPI_QUAD_BOOT_SEQ_INIT_2       0x014c
+#define SPI_QUAD_BOOT_READ_SEQ_1       0x0150
+#define SPI_QUAD_BOOT_READ_SEQ_2       0x0154
+#define SPI_PROGRAM_ERASE_TIME         0x0158
+#define SPI_MULT_PAGE_REPEAT_SEQ_1     0x015c
+#define SPI_MULT_PAGE_REPEAT_SEQ_2     0x0160
+#define SPI_STATUS_WR_TIME_REG         0x0164
+#define SPI_FAST_SEQ_DATA_REG          0x0300
+
+/*
+ * Register: SPI_MODESELECT
+ */
+#define SPI_MODESELECT_CONTIG          0x01
+#define SPI_MODESELECT_FASTREAD                0x02
+#define SPI_MODESELECT_DUALIO          0x04
+#define SPI_MODESELECT_FSM             0x08
+#define SPI_MODESELECT_QUADBOOT                0x10
+
+/*
+ * Register: SPI_CONFIGDATA
+ */
+#define SPI_CFG_DEVICE_ST              0x1
+#define SPI_CFG_DEVICE_ATMEL           0x4
+#define SPI_CFG_MIN_CS_HIGH(x)         (((x) & 0xfff) << 4)
+#define SPI_CFG_CS_SETUPHOLD(x)                (((x) & 0xff) << 16)
+#define SPI_CFG_DATA_HOLD(x)           (((x) & 0xff) << 24)
+
+#define SPI_CFG_DEFAULT_MIN_CS_HIGH    SPI_CFG_MIN_CS_HIGH(0x0AA)
+#define SPI_CFG_DEFAULT_CS_SETUPHOLD   SPI_CFG_CS_SETUPHOLD(0xA0)
+#define SPI_CFG_DEFAULT_DATA_HOLD      SPI_CFG_DATA_HOLD(0x00)
+
+/*
+ * Register: SPI_FAST_SEQ_TRANSFER_SIZE
+ */
+#define TRANSFER_SIZE(x)               ((x) * 8)
+
+/*
+ * Register: SPI_FAST_SEQ_ADD_CFG
+ */
+#define ADR_CFG_CYCLES_ADD1(x)         ((x) << 0)
+#define ADR_CFG_PADS_1_ADD1            (0x0 << 6)
+#define ADR_CFG_PADS_2_ADD1            (0x1 << 6)
+#define ADR_CFG_PADS_4_ADD1            (0x3 << 6)
+#define ADR_CFG_CSDEASSERT_ADD1                (1   << 8)
+#define ADR_CFG_CYCLES_ADD2(x)         ((x) << (0+16))
+#define ADR_CFG_PADS_1_ADD2            (0x0 << (6+16))
+#define ADR_CFG_PADS_2_ADD2            (0x1 << (6+16))
+#define ADR_CFG_PADS_4_ADD2            (0x3 << (6+16))
+#define ADR_CFG_CSDEASSERT_ADD2                (1   << (8+16))
+
+/*
+ * Register: SPI_FAST_SEQ_n
+ */
+#define SEQ_OPC_OPCODE(x)              ((x) << 0)
+#define SEQ_OPC_CYCLES(x)              ((x) << 8)
+#define SEQ_OPC_PADS_1                 (0x0 << 14)
+#define SEQ_OPC_PADS_2                 (0x1 << 14)
+#define SEQ_OPC_PADS_4                 (0x3 << 14)
+#define SEQ_OPC_CSDEASSERT             (1   << 16)
+
+/*
+ * Register: SPI_FAST_SEQ_CFG
+ */
+#define SEQ_CFG_STARTSEQ               (1 << 0)
+#define SEQ_CFG_SWRESET                        (1 << 5)
+#define SEQ_CFG_CSDEASSERT             (1 << 6)
+#define SEQ_CFG_READNOTWRITE           (1 << 7)
+#define SEQ_CFG_ERASE                  (1 << 8)
+#define SEQ_CFG_PADS_1                 (0x0 << 16)
+#define SEQ_CFG_PADS_2                 (0x1 << 16)
+#define SEQ_CFG_PADS_4                 (0x3 << 16)
+
+/*
+ * Register: SPI_MODE_BITS
+ */
+#define MODE_DATA(x)                   (x & 0xff)
+#define MODE_CYCLES(x)                 ((x & 0x3f) << 16)
+#define MODE_PADS_1                    (0x0 << 22)
+#define MODE_PADS_2                    (0x1 << 22)
+#define MODE_PADS_4                    (0x3 << 22)
+#define DUMMY_CSDEASSERT               (1   << 24)
+
+/*
+ * Register: SPI_DUMMY_BITS
+ */
+#define DUMMY_CYCLES(x)                        ((x & 0x3f) << 16)
+#define DUMMY_PADS_1                   (0x0 << 22)
+#define DUMMY_PADS_2                   (0x1 << 22)
+#define DUMMY_PADS_4                   (0x3 << 22)
+#define DUMMY_CSDEASSERT               (1   << 24)
+
+/*
+ * Register: SPI_FAST_SEQ_FLASH_STA_DATA
+ */
+#define STA_DATA_BYTE1(x)              ((x & 0xff) << 0)
+#define STA_DATA_BYTE2(x)              ((x & 0xff) << 8)
+#define STA_PADS_1                     (0x0 << 16)
+#define STA_PADS_2                     (0x1 << 16)
+#define STA_PADS_4                     (0x3 << 16)
+#define STA_CSDEASSERT                 (0x1 << 20)
+#define STA_RDNOTWR                    (0x1 << 21)
+
+/*
+ * FSM SPI Instruction Opcodes
+ */
+#define STFSM_OPC_CMD                  0x1
+#define STFSM_OPC_ADD                  0x2
+#define STFSM_OPC_STA                  0x3
+#define STFSM_OPC_MODE                 0x4
+#define STFSM_OPC_DUMMY                0x5
+#define STFSM_OPC_DATA                 0x6
+#define STFSM_OPC_WAIT                 0x7
+#define STFSM_OPC_JUMP                 0x8
+#define STFSM_OPC_GOTO                 0x9
+#define STFSM_OPC_STOP                 0xF
+
+/*
+ * FSM SPI Instructions (== opcode + operand).
+ */
+#define STFSM_INSTR(cmd, op)           ((cmd) | ((op) << 4))
+
+#define STFSM_INST_CMD1                        STFSM_INSTR(STFSM_OPC_CMD,      1)
+#define STFSM_INST_CMD2                        STFSM_INSTR(STFSM_OPC_CMD,      2)
+#define STFSM_INST_CMD3                        STFSM_INSTR(STFSM_OPC_CMD,      3)
+#define STFSM_INST_CMD4                        STFSM_INSTR(STFSM_OPC_CMD,      4)
+#define STFSM_INST_CMD5                        STFSM_INSTR(STFSM_OPC_CMD,      5)
+#define STFSM_INST_ADD1                        STFSM_INSTR(STFSM_OPC_ADD,      1)
+#define STFSM_INST_ADD2                        STFSM_INSTR(STFSM_OPC_ADD,      2)
+
+#define STFSM_INST_DATA_WRITE          STFSM_INSTR(STFSM_OPC_DATA,     1)
+#define STFSM_INST_DATA_READ           STFSM_INSTR(STFSM_OPC_DATA,     2)
+
+#define STFSM_INST_STA_RD1             STFSM_INSTR(STFSM_OPC_STA,      0x1)
+#define STFSM_INST_STA_WR1             STFSM_INSTR(STFSM_OPC_STA,      0x1)
+#define STFSM_INST_STA_RD2             STFSM_INSTR(STFSM_OPC_STA,      0x2)
+#define STFSM_INST_STA_WR1_2           STFSM_INSTR(STFSM_OPC_STA,      0x3)
+
+#define STFSM_INST_MODE                        STFSM_INSTR(STFSM_OPC_MODE,     0)
+#define STFSM_INST_DUMMY               STFSM_INSTR(STFSM_OPC_DUMMY,    0)
+#define STFSM_INST_WAIT                        STFSM_INSTR(STFSM_OPC_WAIT,     0)
+#define STFSM_INST_STOP                        STFSM_INSTR(STFSM_OPC_STOP,     0)
+
+#define STFSM_DEFAULT_EMI_FREQ 100000000UL                        /* 100 MHz */
+#define STFSM_DEFAULT_WR_TIME  (STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
+
+#define STFSM_FLASH_SAFE_FREQ  10000000UL                         /* 10 MHz */
+
+#define STFSM_MAX_WAIT_SEQ_MS  1000     /* FSM execution time */
+
+/* Flash Commands */
+#define FLASH_CMD_WREN         0x06
+#define FLASH_CMD_WRDI         0x04
+#define FLASH_CMD_RDID         0x9f
+#define FLASH_CMD_RDSR         0x05
+#define FLASH_CMD_RDSR2                0x35
+#define FLASH_CMD_WRSR         0x01
+#define FLASH_CMD_SE_4K                0x20
+#define FLASH_CMD_SE_32K       0x52
+#define FLASH_CMD_SE           0xd8
+#define FLASH_CMD_CHIPERASE    0xc7
+#define FLASH_CMD_WRVCR                0x81
+#define FLASH_CMD_RDVCR                0x85
+
+#define FLASH_CMD_READ         0x03    /* READ */
+#define FLASH_CMD_READ_FAST    0x0b    /* FAST READ */
+#define FLASH_CMD_READ_1_1_2   0x3b    /* DUAL OUTPUT READ */
+#define FLASH_CMD_READ_1_2_2   0xbb    /* DUAL I/O READ */
+#define FLASH_CMD_READ_1_1_4   0x6b    /* QUAD OUTPUT READ */
+#define FLASH_CMD_READ_1_4_4   0xeb    /* QUAD I/O READ */
+
+#define FLASH_CMD_WRITE                0x02    /* PAGE PROGRAM */
+#define FLASH_CMD_WRITE_1_1_2  0xa2    /* DUAL INPUT PROGRAM */
+#define FLASH_CMD_WRITE_1_2_2  0xd2    /* DUAL INPUT EXT PROGRAM */
+#define FLASH_CMD_WRITE_1_1_4  0x32    /* QUAD INPUT PROGRAM */
+#define FLASH_CMD_WRITE_1_4_4  0x12    /* QUAD INPUT EXT PROGRAM */
+
+#define FLASH_CMD_EN4B_ADDR    0xb7    /* Enter 4-byte address mode */
+#define FLASH_CMD_EX4B_ADDR    0xe9    /* Exit 4-byte address mode */
+
+/* READ commands with 32-bit addressing (N25Q256 and S25FLxxxS) */
+#define FLASH_CMD_READ4                0x13
+#define FLASH_CMD_READ4_FAST   0x0c
+#define FLASH_CMD_READ4_1_1_2  0x3c
+#define FLASH_CMD_READ4_1_2_2  0xbc
+#define FLASH_CMD_READ4_1_1_4  0x6c
+#define FLASH_CMD_READ4_1_4_4  0xec
+
+/* S25FLxxxS commands */
+#define S25FL_CMD_WRITE4_1_1_4 0x34
+#define S25FL_CMD_SE4          0xdc
+#define S25FL_CMD_CLSR         0x30
+#define S25FL_CMD_DYBWR                0xe1
+#define S25FL_CMD_DYBRD                0xe0
+#define S25FL_CMD_WRITE4       0x12    /* Note, opcode clashes with
+                                       * 'FLASH_CMD_WRITE_1_4_4'
+                                       * as found on N25Qxxx devices! */
+
+/* Status register */
+#define FLASH_STATUS_BUSY      0x01
+#define FLASH_STATUS_WEL       0x02
+#define FLASH_STATUS_BP0       0x04
+#define FLASH_STATUS_BP1       0x08
+#define FLASH_STATUS_BP2       0x10
+#define FLASH_STATUS_SRWP0     0x80
+#define FLASH_STATUS_TIMEOUT   0xff
+/* S25FL Error Flags */
+#define S25FL_STATUS_E_ERR     0x20
+#define S25FL_STATUS_P_ERR     0x40
+
+#define FLASH_PAGESIZE         256                     /* In Bytes    */
+#define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)    /* In uint32_t */
+#define FLASH_MAX_BUSY_WAIT    (300 * HZ)      /* Maximum 'CHIPERASE' time */
+
+/*
+ * Flags to tweak operation of default read/write/erase routines
+ */
+#define CFG_READ_TOGGLE_32BIT_ADDR     0x00000001
+#define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
+#define CFG_WRITE_EX_32BIT_ADDR_DELAY  0x00000004
+#define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
+#define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
+
+struct stfsm_seq {
+       uint32_t data_size;
+       uint32_t addr1;
+       uint32_t addr2;
+       uint32_t addr_cfg;
+       uint32_t seq_opc[5];
+       uint32_t mode;
+       uint32_t dummy;
+       uint32_t status;
+       uint8_t  seq[16];
+       uint32_t seq_cfg;
+} __packed __aligned(4);
+
+struct stfsm {
+       struct device           *dev;
+       void __iomem            *base;
+       struct resource         *region;
+       struct mtd_info         mtd;
+       struct mutex            lock;
+       struct flash_info       *info;
+
+       uint32_t                configuration;
+       uint32_t                fifo_dir_delay;
+       bool                    booted_from_spi;
+       bool                    reset_signal;
+       bool                    reset_por;
+
+       struct stfsm_seq stfsm_seq_read;
+       struct stfsm_seq stfsm_seq_write;
+       struct stfsm_seq stfsm_seq_en_32bit_addr;
+};
+
+/* Parameters to configure a READ or WRITE FSM sequence */
+struct seq_rw_config {
+       uint32_t        flags;          /* flags to support config */
+       uint8_t         cmd;            /* FLASH command */
+       int             write;          /* Write Sequence */
+       uint8_t         addr_pads;      /* No. of addr pads (MODE & DUMMY) */
+       uint8_t         data_pads;      /* No. of data pads */
+       uint8_t         mode_data;      /* MODE data */
+       uint8_t         mode_cycles;    /* No. of MODE cycles */
+       uint8_t         dummy_cycles;   /* No. of DUMMY cycles */
+};
+
+/* SPI Flash Device Table */
+struct flash_info {
+       char            *name;
+       /*
+        * JEDEC id zero means "no ID" (most older chips); otherwise it has
+        * a high byte of zero plus three data bytes: the manufacturer id,
+        * then a two byte device id.
+        */
+       u32             jedec_id;
+       u16             ext_id;
+       /*
+        * The size listed here is what works with FLASH_CMD_SE, which isn't
+        * necessarily called a "sector" by the vendor.
+        */
+       unsigned        sector_size;
+       u16             n_sectors;
+       u32             flags;
+       /*
+        * Note, where FAST_READ is supported, freq_max specifies the
+        * FAST_READ frequency, not the READ frequency.
+        */
+       u32             max_freq;
+       int             (*config)(struct stfsm *);
+};
+
+static int stfsm_n25q_config(struct stfsm *fsm);
+static int stfsm_mx25_config(struct stfsm *fsm);
+static int stfsm_s25fl_config(struct stfsm *fsm);
+static int stfsm_w25q_config(struct stfsm *fsm);
+
+static struct flash_info flash_types[] = {
+       /*
+        * ST Microelectronics/Numonyx --
+        * (newer production versions may have feature updates
+        * (eg faster operating frequency)
+        */
+#define M25P_FLAG (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST)
+       { "m25p40",  0x202013, 0,  64 * 1024,   8, M25P_FLAG, 25, NULL },
+       { "m25p80",  0x202014, 0,  64 * 1024,  16, M25P_FLAG, 25, NULL },
+       { "m25p16",  0x202015, 0,  64 * 1024,  32, M25P_FLAG, 25, NULL },
+       { "m25p32",  0x202016, 0,  64 * 1024,  64, M25P_FLAG, 50, NULL },
+       { "m25p64",  0x202017, 0,  64 * 1024, 128, M25P_FLAG, 50, NULL },
+       { "m25p128", 0x202018, 0, 256 * 1024,  64, M25P_FLAG, 50, NULL },
+
+#define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |       \
+                   FLASH_FLAG_READ_FAST        |       \
+                   FLASH_FLAG_READ_1_1_2       |       \
+                   FLASH_FLAG_WRITE_1_1_2)
+       { "m25px32", 0x207116, 0,  64 * 1024,  64, M25PX_FLAG, 75, NULL },
+       { "m25px64", 0x207117, 0,  64 * 1024, 128, M25PX_FLAG, 75, NULL },
+
+#define MX25_FLAG (FLASH_FLAG_READ_WRITE       |       \
+                  FLASH_FLAG_READ_FAST         |       \
+                  FLASH_FLAG_READ_1_1_2        |       \
+                  FLASH_FLAG_READ_1_2_2        |       \
+                  FLASH_FLAG_READ_1_1_4        |       \
+                  FLASH_FLAG_READ_1_4_4        |       \
+                  FLASH_FLAG_SE_4K             |       \
+                  FLASH_FLAG_SE_32K)
+       { "mx25l25635e", 0xc22019, 0, 64*1024, 512,
+         (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
+         stfsm_mx25_config },
+
+#define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |       \
+                  FLASH_FLAG_READ_FAST         |       \
+                  FLASH_FLAG_READ_1_1_2        |       \
+                  FLASH_FLAG_READ_1_2_2        |       \
+                  FLASH_FLAG_READ_1_1_4        |       \
+                  FLASH_FLAG_READ_1_4_4        |       \
+                  FLASH_FLAG_WRITE_1_1_2       |       \
+                  FLASH_FLAG_WRITE_1_2_2       |       \
+                  FLASH_FLAG_WRITE_1_1_4       |       \
+                  FLASH_FLAG_WRITE_1_4_4)
+       { "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
+         stfsm_n25q_config },
+       { "n25q256", 0x20ba19, 0, 64 * 1024,  512,
+         N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
+
+       /*
+        * Spansion S25FLxxxP
+        *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+        */
+#define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |       \
+                       FLASH_FLAG_READ_1_1_2   |       \
+                       FLASH_FLAG_READ_1_2_2   |       \
+                       FLASH_FLAG_READ_1_1_4   |       \
+                       FLASH_FLAG_READ_1_4_4   |       \
+                       FLASH_FLAG_WRITE_1_1_4  |       \
+                       FLASH_FLAG_READ_FAST)
+       { "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, S25FLXXXP_FLAG, 80,
+         stfsm_s25fl_config },
+       { "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, S25FLXXXP_FLAG, 80,
+         stfsm_s25fl_config },
+
+       /*
+        * Spansion S25FLxxxS
+        *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
+        *     - RESET# signal supported by die but not bristled out on all
+        *       package types.  The package type is a function of board design,
+        *       so this information is captured in the board's flags.
+        *     - Supports 'DYB' sector protection. Depending on variant, sectors
+        *       may default to locked state on power-on.
+        */
+#define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |       \
+                       FLASH_FLAG_RESET        |       \
+                       FLASH_FLAG_DYB_LOCKING)
+       { "s25fl128s0", 0x012018, 0x0300,  256 * 1024, 64, S25FLXXXS_FLAG, 80,
+         stfsm_s25fl_config },
+       { "s25fl128s1", 0x012018, 0x0301,  64 * 1024, 256, S25FLXXXS_FLAG, 80,
+         stfsm_s25fl_config },
+       { "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
+         S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
+       { "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512,
+         S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
+
+       /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+#define W25X_FLAG (FLASH_FLAG_READ_WRITE       |       \
+                  FLASH_FLAG_READ_FAST         |       \
+                  FLASH_FLAG_READ_1_1_2        |       \
+                  FLASH_FLAG_WRITE_1_1_2)
+       { "w25x40",  0xef3013, 0,  64 * 1024,   8, W25X_FLAG, 75, NULL },
+       { "w25x80",  0xef3014, 0,  64 * 1024,  16, W25X_FLAG, 75, NULL },
+       { "w25x16",  0xef3015, 0,  64 * 1024,  32, W25X_FLAG, 75, NULL },
+       { "w25x32",  0xef3016, 0,  64 * 1024,  64, W25X_FLAG, 75, NULL },
+       { "w25x64",  0xef3017, 0,  64 * 1024, 128, W25X_FLAG, 75, NULL },
+
+       /* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
+#define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |       \
+                  FLASH_FLAG_READ_FAST         |       \
+                  FLASH_FLAG_READ_1_1_2        |       \
+                  FLASH_FLAG_READ_1_2_2        |       \
+                  FLASH_FLAG_READ_1_1_4        |       \
+                  FLASH_FLAG_READ_1_4_4        |       \
+                  FLASH_FLAG_WRITE_1_1_4)
+       { "w25q80",  0xef4014, 0,  64 * 1024,  16, W25Q_FLAG, 80,
+         stfsm_w25q_config },
+       { "w25q16",  0xef4015, 0,  64 * 1024,  32, W25Q_FLAG, 80,
+         stfsm_w25q_config },
+       { "w25q32",  0xef4016, 0,  64 * 1024,  64, W25Q_FLAG, 80,
+         stfsm_w25q_config },
+       { "w25q64",  0xef4017, 0,  64 * 1024, 128, W25Q_FLAG, 80,
+         stfsm_w25q_config },
+
+       /* Sentinel */
+       { NULL, 0x000000, 0, 0, 0, 0, 0, NULL },
+};
+
+/*
+ * FSM message sequence configurations:
+ *
+ * All configs are presented in order of preference
+ */
+
+/* Default READ configurations, in order of preference */
+static struct seq_rw_config default_read_configs[] = {
+       {FLASH_FLAG_READ_1_4_4, FLASH_CMD_READ_1_4_4,   0, 4, 4, 0x00, 2, 4},
+       {FLASH_FLAG_READ_1_1_4, FLASH_CMD_READ_1_1_4,   0, 1, 4, 0x00, 4, 0},
+       {FLASH_FLAG_READ_1_2_2, FLASH_CMD_READ_1_2_2,   0, 2, 2, 0x00, 4, 0},
+       {FLASH_FLAG_READ_1_1_2, FLASH_CMD_READ_1_1_2,   0, 1, 2, 0x00, 0, 8},
+       {FLASH_FLAG_READ_FAST,  FLASH_CMD_READ_FAST,    0, 1, 1, 0x00, 0, 8},
+       {FLASH_FLAG_READ_WRITE, FLASH_CMD_READ,         0, 1, 1, 0x00, 0, 0},
+       {0x00,                  0,                      0, 0, 0, 0x00, 0, 0},
+};
+
+/* Default WRITE configurations */
+static struct seq_rw_config default_write_configs[] = {
+       {FLASH_FLAG_WRITE_1_4_4, FLASH_CMD_WRITE_1_4_4, 1, 4, 4, 0x00, 0, 0},
+       {FLASH_FLAG_WRITE_1_1_4, FLASH_CMD_WRITE_1_1_4, 1, 1, 4, 0x00, 0, 0},
+       {FLASH_FLAG_WRITE_1_2_2, FLASH_CMD_WRITE_1_2_2, 1, 2, 2, 0x00, 0, 0},
+       {FLASH_FLAG_WRITE_1_1_2, FLASH_CMD_WRITE_1_1_2, 1, 1, 2, 0x00, 0, 0},
+       {FLASH_FLAG_READ_WRITE,  FLASH_CMD_WRITE,       1, 1, 1, 0x00, 0, 0},
+       {0x00,                   0,                     0, 0, 0, 0x00, 0, 0},
+};
+
+/*
+ * [N25Qxxx] Configuration
+ */
+#define N25Q_VCR_DUMMY_CYCLES(x)       (((x) & 0xf) << 4)
+#define N25Q_VCR_XIP_DISABLED          ((uint8_t)0x1 << 3)
+#define N25Q_VCR_WRAP_CONT             0x3
+
+/* N25Q 3-byte Address READ configurations
+ *     - 'FAST' variants configured for 8 dummy cycles.
+ *
+ * Note, the number of dummy cycles used for 'FAST' READ operations is
+ * configurable and would normally be tuned according to the READ command and
+ * operating frequency.  However, this applies universally to all 'FAST' READ
+ * commands, including those used by the SPIBoot controller, and remains in
+ * force until the device is power-cycled.  Since the SPIBoot controller is
+ * hard-wired to use 8 dummy cycles, we must configure the device to also use 8
+ * cycles.
+ */
+static struct seq_rw_config n25q_read3_configs[] = {
+       {FLASH_FLAG_READ_1_4_4, FLASH_CMD_READ_1_4_4,   0, 4, 4, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_1_4, FLASH_CMD_READ_1_1_4,   0, 1, 4, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_2_2, FLASH_CMD_READ_1_2_2,   0, 2, 2, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_1_2, FLASH_CMD_READ_1_1_2,   0, 1, 2, 0x00, 0, 8},
+       {FLASH_FLAG_READ_FAST,  FLASH_CMD_READ_FAST,    0, 1, 1, 0x00, 0, 8},
+       {FLASH_FLAG_READ_WRITE, FLASH_CMD_READ,         0, 1, 1, 0x00, 0, 0},
+       {0x00,                  0,                      0, 0, 0, 0x00, 0, 0},
+};
+
+/* N25Q 4-byte Address READ configurations
+ *     - use special 4-byte address READ commands (reduces overheads, and
+ *        reduces risk of hitting watchdog reset issues).
+ *     - 'FAST' variants configured for 8 dummy cycles (see note above.)
+ */
+static struct seq_rw_config n25q_read4_configs[] = {
+       {FLASH_FLAG_READ_1_4_4, FLASH_CMD_READ4_1_4_4,  0, 4, 4, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_1_4, FLASH_CMD_READ4_1_1_4,  0, 1, 4, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_2_2, FLASH_CMD_READ4_1_2_2,  0, 2, 2, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_1_2, FLASH_CMD_READ4_1_1_2,  0, 1, 2, 0x00, 0, 8},
+       {FLASH_FLAG_READ_FAST,  FLASH_CMD_READ4_FAST,   0, 1, 1, 0x00, 0, 8},
+       {FLASH_FLAG_READ_WRITE, FLASH_CMD_READ4,        0, 1, 1, 0x00, 0, 0},
+       {0x00,                  0,                      0, 0, 0, 0x00, 0, 0},
+};
+
+/*
+ * [MX25xxx] Configuration
+ */
+#define MX25_STATUS_QE                 (0x1 << 6)
+
+static int stfsm_mx25_en_32bit_addr_seq(struct stfsm_seq *seq)
+{
+       seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
+                          SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(FLASH_CMD_EN4B_ADDR) |
+                          SEQ_OPC_CSDEASSERT);
+
+       seq->seq[0] = STFSM_INST_CMD1;
+       seq->seq[1] = STFSM_INST_WAIT;
+       seq->seq[2] = STFSM_INST_STOP;
+
+       seq->seq_cfg = (SEQ_CFG_PADS_1 |
+                       SEQ_CFG_ERASE |
+                       SEQ_CFG_READNOTWRITE |
+                       SEQ_CFG_CSDEASSERT |
+                       SEQ_CFG_STARTSEQ);
+
+       return 0;
+}
+
+/*
+ * [S25FLxxx] Configuration
+ */
+#define STFSM_S25FL_CONFIG_QE          (0x1 << 1)
+
+/*
+ * S25FLxxxS devices provide three ways of supporting 32-bit addressing: Bank
+ * Register, Extended Address Modes, and a 32-bit address command set.  The
+ * 32-bit address command set is used here, since it avoids any problems with
+ * entering a state that is incompatible with the SPIBoot Controller.
+ */
+static struct seq_rw_config stfsm_s25fl_read4_configs[] = {
+       {FLASH_FLAG_READ_1_4_4,  FLASH_CMD_READ4_1_4_4,  0, 4, 4, 0x00, 2, 4},
+       {FLASH_FLAG_READ_1_1_4,  FLASH_CMD_READ4_1_1_4,  0, 1, 4, 0x00, 0, 8},
+       {FLASH_FLAG_READ_1_2_2,  FLASH_CMD_READ4_1_2_2,  0, 2, 2, 0x00, 4, 0},
+       {FLASH_FLAG_READ_1_1_2,  FLASH_CMD_READ4_1_1_2,  0, 1, 2, 0x00, 0, 8},
+       {FLASH_FLAG_READ_FAST,   FLASH_CMD_READ4_FAST,   0, 1, 1, 0x00, 0, 8},
+       {FLASH_FLAG_READ_WRITE,  FLASH_CMD_READ4,        0, 1, 1, 0x00, 0, 0},
+       {0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
+};
+
+static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
+       {FLASH_FLAG_WRITE_1_1_4, S25FL_CMD_WRITE4_1_1_4, 1, 1, 4, 0x00, 0, 0},
+       {FLASH_FLAG_READ_WRITE,  S25FL_CMD_WRITE4,       1, 1, 1, 0x00, 0, 0},
+       {0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
+};
+
+/*
+ * [W25Qxxx] Configuration
+ */
+#define W25Q_STATUS_QE                 (0x1 << 9)
+
+static struct stfsm_seq stfsm_seq_read_jedec = {
+       .data_size = TRANSFER_SIZE(8),
+       .seq_opc[0] = (SEQ_OPC_PADS_1 |
+                      SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_DATA_READ,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
+static struct stfsm_seq stfsm_seq_read_status_fifo = {
+       .data_size = TRANSFER_SIZE(4),
+       .seq_opc[0] = (SEQ_OPC_PADS_1 |
+                      SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_RDSR)),
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_DATA_READ,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
+static struct stfsm_seq stfsm_seq_erase_sector = {
+       /* 'addr_cfg' configured during initialisation */
+       .seq_opc = {
+               (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
+
+               (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                SEQ_OPC_OPCODE(FLASH_CMD_SE)),
+       },
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_CMD2,
+               STFSM_INST_ADD1,
+               STFSM_INST_ADD2,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
+static struct stfsm_seq stfsm_seq_erase_chip = {
+       .seq_opc = {
+               (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
+
+               (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                SEQ_OPC_OPCODE(FLASH_CMD_CHIPERASE) | SEQ_OPC_CSDEASSERT),
+       },
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_CMD2,
+               STFSM_INST_WAIT,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_ERASE |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
+static struct stfsm_seq stfsm_seq_write_status = {
+       .seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
+       .seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_WRSR)),
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_CMD2,
+               STFSM_INST_STA_WR1,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
+static struct stfsm_seq stfsm_seq_wrvcr = {
+       .seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
+       .seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_WRVCR)),
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_CMD2,
+               STFSM_INST_STA_WR1,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
+static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
+{
+       seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(FLASH_CMD_EN4B_ADDR));
+       seq->seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
+                          SEQ_OPC_CSDEASSERT);
+
+       seq->seq[0] = STFSM_INST_CMD2;
+       seq->seq[1] = STFSM_INST_CMD1;
+       seq->seq[2] = STFSM_INST_WAIT;
+       seq->seq[3] = STFSM_INST_STOP;
+
+       seq->seq_cfg = (SEQ_CFG_PADS_1 |
+                       SEQ_CFG_ERASE |
+                       SEQ_CFG_READNOTWRITE |
+                       SEQ_CFG_CSDEASSERT |
+                       SEQ_CFG_STARTSEQ);
+
+       return 0;
+}
+
+static inline int stfsm_is_idle(struct stfsm *fsm)
+{
+       return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
+}
+
+static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
+{
+       return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
+}
+
+static void stfsm_clear_fifo(struct stfsm *fsm)
+{
+       uint32_t avail;
+
+       for (;;) {
+               avail = stfsm_fifo_available(fsm);
+               if (!avail)
+                       break;
+
+               while (avail) {
+                       readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+                       avail--;
+               }
+       }
+}
+
+static inline void stfsm_load_seq(struct stfsm *fsm,
+                                 const struct stfsm_seq *seq)
+{
+       void __iomem *dst = fsm->base + SPI_FAST_SEQ_TRANSFER_SIZE;
+       const uint32_t *src = (const uint32_t *)seq;
+       int words = sizeof(*seq) / sizeof(*src);
+
+       BUG_ON(!stfsm_is_idle(fsm));
+
+       while (words--) {
+               writel(*src, dst);
+               src++;
+               dst += 4;
+       }
+}
+
+static void stfsm_wait_seq(struct stfsm *fsm)
+{
+       unsigned long deadline;
+       int timeout = 0;
+
+       deadline = jiffies + msecs_to_jiffies(STFSM_MAX_WAIT_SEQ_MS);
+
+       while (!timeout) {
+               if (time_after_eq(jiffies, deadline))
+                       timeout = 1;
+
+               if (stfsm_is_idle(fsm))
+                       return;
+
+               cond_resched();
+       }
+
+       dev_err(fsm->dev, "timeout on sequence completion\n");
+}
+
+static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
+{
+       uint32_t remaining = size >> 2;
+       uint32_t avail;
+       uint32_t words;
+
+       dev_dbg(fsm->dev, "Reading %d bytes from FIFO\n", size);
+
+       BUG_ON((((uint32_t)buf) & 0x3) || (size & 0x3));
+
+       while (remaining) {
+               for (;;) {
+                       avail = stfsm_fifo_available(fsm);
+                       if (avail)
+                               break;
+                       udelay(1);
+               }
+               words = min(avail, remaining);
+               remaining -= words;
+
+               readsl(fsm->base + SPI_FAST_SEQ_DATA_REG, buf, words);
+               buf += words;
+       }
+}
+
+static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
+                           uint32_t size)
+{
+       uint32_t words = size >> 2;
+
+       dev_dbg(fsm->dev, "writing %d bytes to FIFO\n", size);
+
+       BUG_ON((((uint32_t)buf) & 0x3) || (size & 0x3));
+
+       writesl(fsm->base + SPI_FAST_SEQ_DATA_REG, buf, words);
+
+       return size;
+}
+
+static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
+{
+       struct stfsm_seq *seq = &fsm->stfsm_seq_en_32bit_addr;
+       uint32_t cmd = enter ? FLASH_CMD_EN4B_ADDR : FLASH_CMD_EX4B_ADDR;
+
+       seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
+                          SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(cmd) |
+                          SEQ_OPC_CSDEASSERT);
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_wait_seq(fsm);
+
+       return 0;
+}
+
+static uint8_t stfsm_wait_busy(struct stfsm *fsm)
+{
+       struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
+       unsigned long deadline;
+       uint32_t status;
+       int timeout = 0;
+
+       /* Use RDRS1 */
+       seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
+                          SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(FLASH_CMD_RDSR));
+
+       /* Load read_status sequence */
+       stfsm_load_seq(fsm, seq);
+
+       /*
+        * Repeat until busy bit is deasserted, or timeout, or error (S25FLxxxS)
+        */
+       deadline = jiffies + FLASH_MAX_BUSY_WAIT;
+       while (!timeout) {
+               if (time_after_eq(jiffies, deadline))
+                       timeout = 1;
+
+               stfsm_wait_seq(fsm);
+
+               stfsm_read_fifo(fsm, &status, 4);
+
+               if ((status & FLASH_STATUS_BUSY) == 0)
+                       return 0;
+
+               if ((fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS) &&
+                   ((status & S25FL_STATUS_P_ERR) ||
+                    (status & S25FL_STATUS_E_ERR)))
+                       return (uint8_t)(status & 0xff);
+
+               if (!timeout)
+                       /* Restart */
+                       writel(seq->seq_cfg, fsm->base + SPI_FAST_SEQ_CFG);
+
+               cond_resched();
+       }
+
+       dev_err(fsm->dev, "timeout on wait_busy\n");
+
+       return FLASH_STATUS_TIMEOUT;
+}
+
+static int stfsm_read_status(struct stfsm *fsm, uint8_t cmd,
+                          uint8_t *status)
+{
+       struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
+       uint32_t tmp;
+
+       dev_dbg(fsm->dev, "reading STA[%s]\n",
+               (cmd == FLASH_CMD_RDSR) ? "1" : "2");
+
+       seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
+                          SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(cmd)),
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_read_fifo(fsm, &tmp, 4);
+
+       *status = (uint8_t)(tmp >> 24);
+
+       stfsm_wait_seq(fsm);
+
+       return 0;
+}
+
+static int stfsm_write_status(struct stfsm *fsm, uint16_t status,
+                              int sta_bytes)
+{
+       struct stfsm_seq *seq = &stfsm_seq_write_status;
+
+       dev_dbg(fsm->dev, "writing STA[%s] 0x%04x\n",
+               (sta_bytes == 1) ? "1" : "1+2", status);
+
+       seq->status = (uint32_t)status | STA_PADS_1 | STA_CSDEASSERT;
+       seq->seq[2] = (sta_bytes == 1) ?
+               STFSM_INST_STA_WR1 : STFSM_INST_STA_WR1_2;
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_wait_seq(fsm);
+
+       return 0;
+};
+
+static int stfsm_wrvcr(struct stfsm *fsm, uint8_t data)
+{
+       struct stfsm_seq *seq = &stfsm_seq_wrvcr;
+
+       dev_dbg(fsm->dev, "writing VCR 0x%02x\n", data);
+
+       seq->status = (STA_DATA_BYTE1(data) | STA_PADS_1 | STA_CSDEASSERT);
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_wait_seq(fsm);
+
+       return 0;
+}
+
+/*
+ * SoC reset on 'boot-from-spi' systems
+ *
+ * Certain modes of operation cause the Flash device to enter a particular state
+ * for a period of time (e.g. 'Erase Sector', 'Quad Enable', and 'Enter 32-bit
+ * Addr' commands).  On boot-from-spi systems, it is important to consider what
+ * happens if a warm reset occurs during this period.  The SPIBoot controller
+ * assumes that Flash device is in its default reset state, 24-bit address mode,
+ * and ready to accept commands.  This can be achieved using some form of
+ * on-board logic/controller to force a device POR in response to a SoC-level
+ * reset or by making use of the device reset signal if available (limited
+ * number of devices only).
+ *
+ * Failure to take such precautions can cause problems following a warm reset.
+ * For some operations (e.g. ERASE), there is little that can be done.  For
+ * other modes of operation (e.g. 32-bit addressing), options are often
+ * available that can help minimise the window in which a reset could cause a
+ * problem.
+ *
+ */
+static bool stfsm_can_handle_soc_reset(struct stfsm *fsm)
+{
+       /* Reset signal is available on the board and supported by the device */
+       if (fsm->reset_signal && fsm->info->flags & FLASH_FLAG_RESET)
+               return true;
+
+       /* Board-level logic forces a power-on-reset */
+       if (fsm->reset_por)
+               return true;
+
+       /* Reset is not properly handled and may result in failure to reboot */
+       return false;
+}
+
+/* Configure 'addr_cfg' according to addressing mode */
+static void stfsm_prepare_erasesec_seq(struct stfsm *fsm,
+                                      struct stfsm_seq *seq)
+{
+       int addr1_cycles = fsm->info->flags & FLASH_FLAG_32BIT_ADDR ? 16 : 8;
+
+       seq->addr_cfg = (ADR_CFG_CYCLES_ADD1(addr1_cycles) |
+                        ADR_CFG_PADS_1_ADD1 |
+                        ADR_CFG_CYCLES_ADD2(16) |
+                        ADR_CFG_PADS_1_ADD2 |
+                        ADR_CFG_CSDEASSERT_ADD2);
+}
+
+/* Search for preferred configuration based on available flags */
+static struct seq_rw_config *
+stfsm_search_seq_rw_configs(struct stfsm *fsm,
+                           struct seq_rw_config cfgs[])
+{
+       struct seq_rw_config *config;
+       int flags = fsm->info->flags;
+
+       for (config = cfgs; config->cmd != 0; config++)
+               if ((config->flags & flags) == config->flags)
+                       return config;
+
+       return NULL;
+}
+
+/* Prepare a READ/WRITE sequence according to configuration parameters */
+static void stfsm_prepare_rw_seq(struct stfsm *fsm,
+                                struct stfsm_seq *seq,
+                                struct seq_rw_config *cfg)
+{
+       int addr1_cycles, addr2_cycles;
+       int i = 0;
+
+       memset(seq, 0, sizeof(*seq));
+
+       /* Add READ/WRITE OPC  */
+       seq->seq_opc[i++] = (SEQ_OPC_PADS_1 |
+                            SEQ_OPC_CYCLES(8) |
+                            SEQ_OPC_OPCODE(cfg->cmd));
+
+       /* Add WREN OPC for a WRITE sequence */
+       if (cfg->write)
+               seq->seq_opc[i++] = (SEQ_OPC_PADS_1 |
+                                    SEQ_OPC_CYCLES(8) |
+                                    SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
+                                    SEQ_OPC_CSDEASSERT);
+
+       /* Address configuration (24 or 32-bit addresses) */
+       addr1_cycles  = (fsm->info->flags & FLASH_FLAG_32BIT_ADDR) ? 16 : 8;
+       addr1_cycles /= cfg->addr_pads;
+       addr2_cycles  = 16 / cfg->addr_pads;
+       seq->addr_cfg = ((addr1_cycles & 0x3f) << 0 |   /* ADD1 cycles */
+                        (cfg->addr_pads - 1) << 6 |    /* ADD1 pads */
+                        (addr2_cycles & 0x3f) << 16 |  /* ADD2 cycles */
+                        ((cfg->addr_pads - 1) << 22)); /* ADD2 pads */
+
+       /* Data/Sequence configuration */
+       seq->seq_cfg = ((cfg->data_pads - 1) << 16 |
+                       SEQ_CFG_STARTSEQ |
+                       SEQ_CFG_CSDEASSERT);
+       if (!cfg->write)
+               seq->seq_cfg |= SEQ_CFG_READNOTWRITE;
+
+       /* Mode configuration (no. of pads taken from addr cfg) */
+       seq->mode = ((cfg->mode_data & 0xff) << 0 |     /* data */
+                    (cfg->mode_cycles & 0x3f) << 16 |  /* cycles */
+                    (cfg->addr_pads - 1) << 22);       /* pads */
+
+       /* Dummy configuration (no. of pads taken from addr cfg) */
+       seq->dummy = ((cfg->dummy_cycles & 0x3f) << 16 |        /* cycles */
+                     (cfg->addr_pads - 1) << 22);              /* pads */
+
+
+       /* Instruction sequence */
+       i = 0;
+       if (cfg->write)
+               seq->seq[i++] = STFSM_INST_CMD2;
+
+       seq->seq[i++] = STFSM_INST_CMD1;
+
+       seq->seq[i++] = STFSM_INST_ADD1;
+       seq->seq[i++] = STFSM_INST_ADD2;
+
+       if (cfg->mode_cycles)
+               seq->seq[i++] = STFSM_INST_MODE;
+
+       if (cfg->dummy_cycles)
+               seq->seq[i++] = STFSM_INST_DUMMY;
+
+       seq->seq[i++] =
+               cfg->write ? STFSM_INST_DATA_WRITE : STFSM_INST_DATA_READ;
+       seq->seq[i++] = STFSM_INST_STOP;
+}
+
+static int stfsm_search_prepare_rw_seq(struct stfsm *fsm,
+                                      struct stfsm_seq *seq,
+                                      struct seq_rw_config *cfgs)
+{
+       struct seq_rw_config *config;
+
+       config = stfsm_search_seq_rw_configs(fsm, cfgs);
+       if (!config) {
+               dev_err(fsm->dev, "failed to find suitable config\n");
+               return -EINVAL;
+       }
+
+       stfsm_prepare_rw_seq(fsm, seq, config);
+
+       return 0;
+}
+
+/* Prepare a READ/WRITE/ERASE 'default' sequences */
+static int stfsm_prepare_rwe_seqs_default(struct stfsm *fsm)
+{
+       uint32_t flags = fsm->info->flags;
+       int ret;
+
+       /* Configure 'READ' sequence */
+       ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
+                                         default_read_configs);
+       if (ret) {
+               dev_err(fsm->dev,
+                       "failed to prep READ sequence with flags [0x%08x]\n",
+                       flags);
+               return ret;
+       }
+
+       /* Configure 'WRITE' sequence */
+       ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
+                                         default_write_configs);
+       if (ret) {
+               dev_err(fsm->dev,
+                       "failed to prep WRITE sequence with flags [0x%08x]\n",
+                       flags);
+               return ret;
+       }
+
+       /* Configure 'ERASE_SECTOR' sequence */
+       stfsm_prepare_erasesec_seq(fsm, &stfsm_seq_erase_sector);
+
+       return 0;
+}
+
+static int stfsm_mx25_config(struct stfsm *fsm)
+{
+       uint32_t flags = fsm->info->flags;
+       uint32_t data_pads;
+       uint8_t sta;
+       int ret;
+       bool soc_reset;
+
+       /*
+        * Use default READ/WRITE sequences
+        */
+       ret = stfsm_prepare_rwe_seqs_default(fsm);
+       if (ret)
+               return ret;
+
+       /*
+        * Configure 32-bit Address Support
+        */
+       if (flags & FLASH_FLAG_32BIT_ADDR) {
+               /* Configure 'enter_32bitaddr' FSM sequence */
+               stfsm_mx25_en_32bit_addr_seq(&fsm->stfsm_seq_en_32bit_addr);
+
+               soc_reset = stfsm_can_handle_soc_reset(fsm);
+               if (soc_reset || !fsm->booted_from_spi) {
+                       /* If we can handle SoC resets, we enable 32-bit address
+                        * mode pervasively */
+                       stfsm_enter_32bit_addr(fsm, 1);
+
+               } else {
+                       /* Else, enable/disable 32-bit addressing before/after
+                        * each operation */
+                       fsm->configuration = (CFG_READ_TOGGLE_32BIT_ADDR |
+                                             CFG_WRITE_TOGGLE_32BIT_ADDR |
+                                             CFG_ERASESEC_TOGGLE_32BIT_ADDR);
+                       /* It seems a small delay is required after exiting
+                        * 32-bit mode following a write operation.  The issue
+                        * is under investigation.
+                        */
+                       fsm->configuration |= CFG_WRITE_EX_32BIT_ADDR_DELAY;
+               }
+       }
+
+       /* For QUAD mode, set 'QE' STATUS bit */
+       data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
+       if (data_pads == 4) {
+               stfsm_read_status(fsm, FLASH_CMD_RDSR, &sta);
+               sta |= MX25_STATUS_QE;
+               stfsm_write_status(fsm, sta, 1);
+       }
+
+       return 0;
+}
+
+static int stfsm_n25q_config(struct stfsm *fsm)
+{
+       uint32_t flags = fsm->info->flags;
+       uint8_t vcr;
+       int ret = 0;
+       bool soc_reset;
+
+       /* Configure 'READ' sequence */
+       if (flags & FLASH_FLAG_32BIT_ADDR)
+               ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
+                                                 n25q_read4_configs);
+       else
+               ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
+                                                 n25q_read3_configs);
+       if (ret) {
+               dev_err(fsm->dev,
+                       "failed to prepare READ sequence with flags [0x%08x]\n",
+                       flags);
+               return ret;
+       }
+
+       /* Configure 'WRITE' sequence (default configs) */
+       ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
+                                         default_write_configs);
+       if (ret) {
+               dev_err(fsm->dev,
+                       "preparing WRITE sequence using flags [0x%08x] failed\n",
+                       flags);
+               return ret;
+       }
+
+       /* * Configure 'ERASE_SECTOR' sequence */
+       stfsm_prepare_erasesec_seq(fsm, &stfsm_seq_erase_sector);
+
+       /* Configure 32-bit address support */
+       if (flags & FLASH_FLAG_32BIT_ADDR) {
+               stfsm_n25q_en_32bit_addr_seq(&fsm->stfsm_seq_en_32bit_addr);
+
+               soc_reset = stfsm_can_handle_soc_reset(fsm);
+               if (soc_reset || !fsm->booted_from_spi) {
+                       /*
+                        * If we can handle SoC resets, we enable 32-bit
+                        * address mode pervasively
+                        */
+                       stfsm_enter_32bit_addr(fsm, 1);
+               } else {
+                       /*
+                        * If not, enable/disable for WRITE and ERASE
+                        * operations (READ uses special commands)
+                        */
+                       fsm->configuration = (CFG_WRITE_TOGGLE_32BIT_ADDR |
+                                             CFG_ERASESEC_TOGGLE_32BIT_ADDR);
+               }
+       }
+
+       /*
+        * Configure device to use 8 dummy cycles
+        */
+       vcr = (N25Q_VCR_DUMMY_CYCLES(8) | N25Q_VCR_XIP_DISABLED |
+              N25Q_VCR_WRAP_CONT);
+       stfsm_wrvcr(fsm, vcr);
+
+       return 0;
+}
+
+static void stfsm_s25fl_prepare_erasesec_seq_32(struct stfsm_seq *seq)
+{
+       seq->seq_opc[1] = (SEQ_OPC_PADS_1 |
+                          SEQ_OPC_CYCLES(8) |
+                          SEQ_OPC_OPCODE(S25FL_CMD_SE4));
+
+       seq->addr_cfg = (ADR_CFG_CYCLES_ADD1(16) |
+                        ADR_CFG_PADS_1_ADD1 |
+                        ADR_CFG_CYCLES_ADD2(16) |
+                        ADR_CFG_PADS_1_ADD2 |
+                        ADR_CFG_CSDEASSERT_ADD2);
+}
+
+static void stfsm_s25fl_read_dyb(struct stfsm *fsm, uint32_t offs, uint8_t *dby)
+{
+       uint32_t tmp;
+       struct stfsm_seq seq = {
+               .data_size = TRANSFER_SIZE(4),
+               .seq_opc[0] = (SEQ_OPC_PADS_1 |
+                              SEQ_OPC_CYCLES(8) |
+                              SEQ_OPC_OPCODE(S25FL_CMD_DYBRD)),
+               .addr_cfg = (ADR_CFG_CYCLES_ADD1(16) |
+                            ADR_CFG_PADS_1_ADD1 |
+                            ADR_CFG_CYCLES_ADD2(16) |
+                            ADR_CFG_PADS_1_ADD2),
+               .addr1 = (offs >> 16) & 0xffff,
+               .addr2 = offs & 0xffff,
+               .seq = {
+                       STFSM_INST_CMD1,
+                       STFSM_INST_ADD1,
+                       STFSM_INST_ADD2,
+                       STFSM_INST_DATA_READ,
+                       STFSM_INST_STOP,
+               },
+               .seq_cfg = (SEQ_CFG_PADS_1 |
+                           SEQ_CFG_READNOTWRITE |
+                           SEQ_CFG_CSDEASSERT |
+                           SEQ_CFG_STARTSEQ),
+       };
+
+       stfsm_load_seq(fsm, &seq);
+
+       stfsm_read_fifo(fsm, &tmp, 4);
+
+       *dby = (uint8_t)(tmp >> 24);
+
+       stfsm_wait_seq(fsm);
+}
+
+static void stfsm_s25fl_write_dyb(struct stfsm *fsm, uint32_t offs, uint8_t dby)
+{
+       struct stfsm_seq seq = {
+               .seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                              SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
+                              SEQ_OPC_CSDEASSERT),
+               .seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
+                              SEQ_OPC_OPCODE(S25FL_CMD_DYBWR)),
+               .addr_cfg = (ADR_CFG_CYCLES_ADD1(16) |
+                            ADR_CFG_PADS_1_ADD1 |
+                            ADR_CFG_CYCLES_ADD2(16) |
+                            ADR_CFG_PADS_1_ADD2),
+               .status = (uint32_t)dby | STA_PADS_1 | STA_CSDEASSERT,
+               .addr1 = (offs >> 16) & 0xffff,
+               .addr2 = offs & 0xffff,
+               .seq = {
+                       STFSM_INST_CMD1,
+                       STFSM_INST_CMD2,
+                       STFSM_INST_ADD1,
+                       STFSM_INST_ADD2,
+                       STFSM_INST_STA_WR1,
+                       STFSM_INST_STOP,
+               },
+               .seq_cfg = (SEQ_CFG_PADS_1 |
+                           SEQ_CFG_READNOTWRITE |
+                           SEQ_CFG_CSDEASSERT |
+                           SEQ_CFG_STARTSEQ),
+       };
+
+       stfsm_load_seq(fsm, &seq);
+       stfsm_wait_seq(fsm);
+
+       stfsm_wait_busy(fsm);
+}
+
+static int stfsm_s25fl_clear_status_reg(struct stfsm *fsm)
+{
+       struct stfsm_seq seq = {
+               .seq_opc[0] = (SEQ_OPC_PADS_1 |
+                              SEQ_OPC_CYCLES(8) |
+                              SEQ_OPC_OPCODE(S25FL_CMD_CLSR) |
+                              SEQ_OPC_CSDEASSERT),
+               .seq_opc[1] = (SEQ_OPC_PADS_1 |
+                              SEQ_OPC_CYCLES(8) |
+                              SEQ_OPC_OPCODE(FLASH_CMD_WRDI) |
+                              SEQ_OPC_CSDEASSERT),
+               .seq = {
+                       STFSM_INST_CMD1,
+                       STFSM_INST_CMD2,
+                       STFSM_INST_WAIT,
+                       STFSM_INST_STOP,
+               },
+               .seq_cfg = (SEQ_CFG_PADS_1 |
+                           SEQ_CFG_ERASE |
+                           SEQ_CFG_READNOTWRITE |
+                           SEQ_CFG_CSDEASSERT |
+                           SEQ_CFG_STARTSEQ),
+       };
+
+       stfsm_load_seq(fsm, &seq);
+
+       stfsm_wait_seq(fsm);
+
+       return 0;
+}
+
+static int stfsm_s25fl_config(struct stfsm *fsm)
+{
+       struct flash_info *info = fsm->info;
+       uint32_t flags = info->flags;
+       uint32_t data_pads;
+       uint32_t offs;
+       uint16_t sta_wr;
+       uint8_t sr1, cr1, dyb;
+       int ret;
+
+       if (flags & FLASH_FLAG_32BIT_ADDR) {
+               /*
+                * Prepare Read/Write/Erase sequences according to S25FLxxx
+                * 32-bit address command set
+                */
+               ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
+                                                 stfsm_s25fl_read4_configs);
+               if (ret)
+                       return ret;
+
+               ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
+                                                 stfsm_s25fl_write4_configs);
+               if (ret)
+                       return ret;
+
+               stfsm_s25fl_prepare_erasesec_seq_32(&stfsm_seq_erase_sector);
+
+       } else {
+               /* Use default configurations for 24-bit addressing */
+               ret = stfsm_prepare_rwe_seqs_default(fsm);
+               if (ret)
+                       return ret;
+       }
+
+       /*
+        * For devices that support 'DYB' sector locking, check lock status and
+        * unlock sectors if necessary (some variants power-on with sectors
+        * locked by default)
+        */
+       if (flags & FLASH_FLAG_DYB_LOCKING) {
+               offs = 0;
+               for (offs = 0; offs < info->sector_size * info->n_sectors;) {
+                       stfsm_s25fl_read_dyb(fsm, offs, &dyb);
+                       if (dyb == 0x00)
+                               stfsm_s25fl_write_dyb(fsm, offs, 0xff);
+
+                       /* Handle bottom/top 4KiB parameter sectors */
+                       if ((offs < info->sector_size * 2) ||
+                           (offs >= (info->sector_size - info->n_sectors * 4)))
+                               offs += 0x1000;
+                       else
+                               offs += 0x10000;
+               }
+       }
+
+       /* Check status of 'QE' bit */
+       data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
+       stfsm_read_status(fsm, FLASH_CMD_RDSR2, &cr1);
+       if (data_pads == 4) {
+               if (!(cr1 & STFSM_S25FL_CONFIG_QE)) {
+                       /* Set 'QE' */
+                       cr1 |= STFSM_S25FL_CONFIG_QE;
+
+                       stfsm_read_status(fsm, FLASH_CMD_RDSR, &sr1);
+                       sta_wr = ((uint16_t)cr1  << 8) | sr1;
+
+                       stfsm_write_status(fsm, sta_wr, 2);
+
+                       stfsm_wait_busy(fsm);
+               }
+       } else {
+               if ((cr1 & STFSM_S25FL_CONFIG_QE)) {
+                       /* Clear 'QE' */
+                       cr1 &= ~STFSM_S25FL_CONFIG_QE;
+
+                       stfsm_read_status(fsm, FLASH_CMD_RDSR, &sr1);
+                       sta_wr = ((uint16_t)cr1  << 8) | sr1;
+
+                       stfsm_write_status(fsm, sta_wr, 2);
+
+                       stfsm_wait_busy(fsm);
+               }
+
+       }
+
+       /*
+        * S25FLxxx devices support Program and Error error flags.
+        * Configure driver to check flags and clear if necessary.
+        */
+       fsm->configuration |= CFG_S25FL_CHECK_ERROR_FLAGS;
+
+       return 0;
+}
+
+static int stfsm_w25q_config(struct stfsm *fsm)
+{
+       uint32_t data_pads;
+       uint16_t sta_wr;
+       uint8_t sta1, sta2;
+       int ret;
+
+       ret = stfsm_prepare_rwe_seqs_default(fsm);
+       if (ret)
+               return ret;
+
+       /* If using QUAD mode, set QE STATUS bit */
+       data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
+       if (data_pads == 4) {
+               stfsm_read_status(fsm, FLASH_CMD_RDSR, &sta1);
+               stfsm_read_status(fsm, FLASH_CMD_RDSR2, &sta2);
+
+               sta_wr = ((uint16_t)sta2 << 8) | sta1;
+
+               sta_wr |= W25Q_STATUS_QE;
+
+               stfsm_write_status(fsm, sta_wr, 2);
+
+               stfsm_wait_busy(fsm);
+       }
+
+       return 0;
+}
+
+static int stfsm_read(struct stfsm *fsm, uint8_t *buf, uint32_t size,
+                     uint32_t offset)
+{
+       struct stfsm_seq *seq = &fsm->stfsm_seq_read;
+       uint32_t data_pads;
+       uint32_t read_mask;
+       uint32_t size_ub;
+       uint32_t size_lb;
+       uint32_t size_mop;
+       uint32_t tmp[4];
+       uint32_t page_buf[FLASH_PAGESIZE_32];
+       uint8_t *p;
+
+       dev_dbg(fsm->dev, "reading %d bytes from 0x%08x\n", size, offset);
+
+       /* Enter 32-bit address mode, if required */
+       if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR)
+               stfsm_enter_32bit_addr(fsm, 1);
+
+       /* Must read in multiples of 32 cycles (or 32*pads/8 Bytes) */
+       data_pads = ((seq->seq_cfg >> 16) & 0x3) + 1;
+       read_mask = (data_pads << 2) - 1;
+
+       /* Handle non-aligned buf */
+       p = ((uint32_t)buf & 0x3) ? (uint8_t *)page_buf : buf;
+
+       /* Handle non-aligned size */
+       size_ub = (size + read_mask) & ~read_mask;
+       size_lb = size & ~read_mask;
+       size_mop = size & read_mask;
+
+       seq->data_size = TRANSFER_SIZE(size_ub);
+       seq->addr1 = (offset >> 16) & 0xffff;
+       seq->addr2 = offset & 0xffff;
+
+       stfsm_load_seq(fsm, seq);
+
+       if (size_lb)
+               stfsm_read_fifo(fsm, (uint32_t *)p, size_lb);
+
+       if (size_mop) {
+               stfsm_read_fifo(fsm, tmp, read_mask + 1);
+               memcpy(p + size_lb, &tmp, size_mop);
+       }
+
+       /* Handle non-aligned buf */
+       if ((uint32_t)buf & 0x3)
+               memcpy(buf, page_buf, size);
+
+       /* Wait for sequence to finish */
+       stfsm_wait_seq(fsm);
+
+       stfsm_clear_fifo(fsm);
+
+       /* Exit 32-bit address mode, if required */
+       if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR)
+               stfsm_enter_32bit_addr(fsm, 0);
+
+       return 0;
+}
+
+static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
+                      uint32_t size, uint32_t offset)
+{
+       struct stfsm_seq *seq = &fsm->stfsm_seq_write;
+       uint32_t data_pads;
+       uint32_t write_mask;
+       uint32_t size_ub;
+       uint32_t size_lb;
+       uint32_t size_mop;
+       uint32_t tmp[4];
+       uint32_t page_buf[FLASH_PAGESIZE_32];
+       uint8_t *t = (uint8_t *)&tmp;
+       const uint8_t *p;
+       int ret;
+       int i;
+
+       dev_dbg(fsm->dev, "writing %d bytes to 0x%08x\n", size, offset);
+
+       /* Enter 32-bit address mode, if required */
+       if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
+               stfsm_enter_32bit_addr(fsm, 1);
+
+       /* Must write in multiples of 32 cycles (or 32*pads/8 bytes) */
+       data_pads = ((seq->seq_cfg >> 16) & 0x3) + 1;
+       write_mask = (data_pads << 2) - 1;
+
+       /* Handle non-aligned buf */
+       if ((uint32_t)buf & 0x3) {
+               memcpy(page_buf, buf, size);
+               p = (uint8_t *)page_buf;
+       } else {
+               p = buf;
+       }
+
+       /* Handle non-aligned size */
+       size_ub = (size + write_mask) & ~write_mask;
+       size_lb = size & ~write_mask;
+       size_mop = size & write_mask;
+
+       seq->data_size = TRANSFER_SIZE(size_ub);
+       seq->addr1 = (offset >> 16) & 0xffff;
+       seq->addr2 = offset & 0xffff;
+
+       /* Need to set FIFO to write mode, before writing data to FIFO (see
+        * GNBvb79594)
+        */
+       writel(0x00040000, fsm->base + SPI_FAST_SEQ_CFG);
+
+       /*
+        * Before writing data to the FIFO, apply a small delay to allow a
+        * potential change of FIFO direction to complete.
+        */
+       if (fsm->fifo_dir_delay == 0)
+               readl(fsm->base + SPI_FAST_SEQ_CFG);
+       else
+               udelay(fsm->fifo_dir_delay);
+
+
+       /* Write data to FIFO, before starting sequence (see GNBvd79593) */
+       if (size_lb) {
+               stfsm_write_fifo(fsm, (uint32_t *)p, size_lb);
+               p += size_lb;
+       }
+
+       /* Handle non-aligned size */
+       if (size_mop) {
+               memset(t, 0xff, write_mask + 1);        /* fill with 0xff's */
+               for (i = 0; i < size_mop; i++)
+                       t[i] = *p++;
+
+               stfsm_write_fifo(fsm, tmp, write_mask + 1);
+       }
+
+       /* Start sequence */
+       stfsm_load_seq(fsm, seq);
+
+       /* Wait for sequence to finish */
+       stfsm_wait_seq(fsm);
+
+       /* Wait for completion */
+       ret = stfsm_wait_busy(fsm);
+       if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
+               stfsm_s25fl_clear_status_reg(fsm);
+
+       /* Exit 32-bit address mode, if required */
+       if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR) {
+               stfsm_enter_32bit_addr(fsm, 0);
+               if (fsm->configuration & CFG_WRITE_EX_32BIT_ADDR_DELAY)
+                       udelay(1);
+       }
+
+       return 0;
+}
+
+/*
+ * Read an address range from the flash chip. The address range
+ * may be any size provided it is within the physical boundaries.
+ */
+static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+                         size_t *retlen, u_char *buf)
+{
+       struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
+       uint32_t bytes;
+
+       dev_dbg(fsm->dev, "%s from 0x%08x, len %zd\n",
+               __func__, (u32)from, len);
+
+       mutex_lock(&fsm->lock);
+
+       while (len > 0) {
+               bytes = min_t(size_t, len, FLASH_PAGESIZE);
+
+               stfsm_read(fsm, buf, bytes, from);
+
+               buf += bytes;
+               from += bytes;
+               len -= bytes;
+
+               *retlen += bytes;
+       }
+
+       mutex_unlock(&fsm->lock);
+
+       return 0;
+}
+
+static int stfsm_erase_sector(struct stfsm *fsm, uint32_t offset)
+{
+       struct stfsm_seq *seq = &stfsm_seq_erase_sector;
+       int ret;
+
+       dev_dbg(fsm->dev, "erasing sector at 0x%08x\n", offset);
+
+       /* Enter 32-bit address mode, if required */
+       if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
+               stfsm_enter_32bit_addr(fsm, 1);
+
+       seq->addr1 = (offset >> 16) & 0xffff;
+       seq->addr2 = offset & 0xffff;
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_wait_seq(fsm);
+
+       /* Wait for completion */
+       ret = stfsm_wait_busy(fsm);
+       if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
+               stfsm_s25fl_clear_status_reg(fsm);
+
+       /* Exit 32-bit address mode, if required */
+       if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
+               stfsm_enter_32bit_addr(fsm, 0);
+
+       return ret;
+}
+
+static int stfsm_erase_chip(struct stfsm *fsm)
+{
+       const struct stfsm_seq *seq = &stfsm_seq_erase_chip;
+
+       dev_dbg(fsm->dev, "erasing chip\n");
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_wait_seq(fsm);
+
+       return stfsm_wait_busy(fsm);
+}
+
+/*
+ * Write an address range to the flash chip.  Data must be written in
+ * FLASH_PAGESIZE chunks.  The address range may be any size provided
+ * it is within the physical boundaries.
+ */
+static int stfsm_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+                          size_t *retlen, const u_char *buf)
+{
+       struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
+
+       u32 page_offs;
+       u32 bytes;
+       uint8_t *b = (uint8_t *)buf;
+       int ret = 0;
+
+       dev_dbg(fsm->dev, "%s to 0x%08x, len %zd\n", __func__, (u32)to, len);
+
+       /* Offset within page */
+       page_offs = to % FLASH_PAGESIZE;
+
+       mutex_lock(&fsm->lock);
+
+       while (len) {
+               /* Write up to page boundary */
+               bytes = min(FLASH_PAGESIZE - page_offs, len);
+
+               ret = stfsm_write(fsm, b, bytes, to);
+               if (ret)
+                       goto out1;
+
+               b += bytes;
+               len -= bytes;
+               to += bytes;
+
+               /* We are now page-aligned */
+               page_offs = 0;
+
+               *retlen += bytes;
+
+       }
+
+out1:
+       mutex_unlock(&fsm->lock);
+
+       return ret;
+}
+
+/*
+ * Erase an address range on the flash chip. The address range may extend
+ * one or more erase sectors.  Return an error is there is a problem erasing.
+ */
+static int stfsm_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+       struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
+       u32 addr, len;
+       int ret;
+
+       dev_dbg(fsm->dev, "%s at 0x%llx, len %lld\n", __func__,
+               (long long)instr->addr, (long long)instr->len);
+
+       addr = instr->addr;
+       len = instr->len;
+
+       mutex_lock(&fsm->lock);
+
+       /* Whole-chip erase? */
+       if (len == mtd->size) {
+               ret = stfsm_erase_chip(fsm);
+               if (ret)
+                       goto out1;
+       } else {
+               while (len) {
+                       ret = stfsm_erase_sector(fsm, addr);
+                       if (ret)
+                               goto out1;
+
+                       addr += mtd->erasesize;
+                       len -= mtd->erasesize;
+               }
+       }
+
+       mutex_unlock(&fsm->lock);
+
+       instr->state = MTD_ERASE_DONE;
+       mtd_erase_callback(instr);
+
+       return 0;
+
+out1:
+       instr->state = MTD_ERASE_FAILED;
+       mutex_unlock(&fsm->lock);
+
+       return ret;
+}
+
+static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *jedec)
+{
+       const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
+       uint32_t tmp[2];
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_read_fifo(fsm, tmp, 8);
+
+       memcpy(jedec, tmp, 5);
+
+       stfsm_wait_seq(fsm);
+}
+
+static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
+{
+       struct flash_info       *info;
+       u16                     ext_jedec;
+       u32                     jedec;
+       u8                      id[5];
+
+       stfsm_read_jedec(fsm, id);
+
+       jedec     = id[0] << 16 | id[1] << 8 | id[2];
+       /*
+        * JEDEC also defines an optional "extended device information"
+        * string for after vendor-specific data, after the three bytes
+        * we use here. Supporting some chips might require using it.
+        */
+       ext_jedec = id[3] << 8  | id[4];
+
+       dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
+               jedec, id[0], id[1], id[2], id[3], id[4]);
+
+       for (info = flash_types; info->name; info++) {
+               if (info->jedec_id == jedec) {
+                       if (info->ext_id && info->ext_id != ext_jedec)
+                               continue;
+                       return info;
+               }
+       }
+       dev_err(fsm->dev, "Unrecognized JEDEC id %06x\n", jedec);
+
+       return NULL;
+}
+
+static int stfsm_set_mode(struct stfsm *fsm, uint32_t mode)
+{
+       int ret, timeout = 10;
+
+       /* Wait for controller to accept mode change */
+       while (--timeout) {
+               ret = readl(fsm->base + SPI_STA_MODE_CHANGE);
+               if (ret & 0x1)
+                       break;
+               udelay(1);
+       }
+
+       if (!timeout)
+               return -EBUSY;
+
+       writel(mode, fsm->base + SPI_MODESELECT);
+
+       return 0;
+}
+
+static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
+{
+       uint32_t emi_freq;
+       uint32_t clk_div;
+
+       /* TODO: Make this dynamic */
+       emi_freq = STFSM_DEFAULT_EMI_FREQ;
+
+       /*
+        * Calculate clk_div - values between 2 and 128
+        * Multiple of 2, rounded up
+        */
+       clk_div = 2 * DIV_ROUND_UP(emi_freq, 2 * spi_freq);
+       if (clk_div < 2)
+               clk_div = 2;
+       else if (clk_div > 128)
+               clk_div = 128;
+
+       /*
+        * Determine a suitable delay for the IP to complete a change of
+        * direction of the FIFO. The required delay is related to the clock
+        * divider used. The following heuristics are based on empirical tests,
+        * using a 100MHz EMI clock.
+        */
+       if (clk_div <= 4)
+               fsm->fifo_dir_delay = 0;
+       else if (clk_div <= 10)
+               fsm->fifo_dir_delay = 1;
+       else
+               fsm->fifo_dir_delay = DIV_ROUND_UP(clk_div, 10);
+
+       dev_dbg(fsm->dev, "emi_clk = %uHZ, spi_freq = %uHZ, clk_div = %u\n",
+               emi_freq, spi_freq, clk_div);
+
+       writel(clk_div, fsm->base + SPI_CLOCKDIV);
+}
+
+static int stfsm_init(struct stfsm *fsm)
+{
+       int ret;
+
+       /* Perform a soft reset of the FSM controller */
+       writel(SEQ_CFG_SWRESET, fsm->base + SPI_FAST_SEQ_CFG);
+       udelay(1);
+       writel(0, fsm->base + SPI_FAST_SEQ_CFG);
+
+       /* Set clock to 'safe' frequency initially */
+       stfsm_set_freq(fsm, STFSM_FLASH_SAFE_FREQ);
+
+       /* Switch to FSM */
+       ret = stfsm_set_mode(fsm, SPI_MODESELECT_FSM);
+       if (ret)
+               return ret;
+
+       /* Set timing parameters */
+       writel(SPI_CFG_DEVICE_ST            |
+              SPI_CFG_DEFAULT_MIN_CS_HIGH  |
+              SPI_CFG_DEFAULT_CS_SETUPHOLD |
+              SPI_CFG_DEFAULT_DATA_HOLD,
+              fsm->base + SPI_CONFIGDATA);
+       writel(STFSM_DEFAULT_WR_TIME, fsm->base + SPI_STATUS_WR_TIME_REG);
+
+       /* Clear FIFO, just in case */
+       stfsm_clear_fifo(fsm);
+
+       return 0;
+}
+
+static void stfsm_fetch_platform_configs(struct platform_device *pdev)
+{
+       struct stfsm *fsm = platform_get_drvdata(pdev);
+       struct device_node *np = pdev->dev.of_node;
+       struct regmap *regmap;
+       uint32_t boot_device_reg;
+       uint32_t boot_device_spi;
+       uint32_t boot_device;     /* Value we read from *boot_device_reg */
+       int ret;
+
+       /* Booting from SPI NOR Flash is the default */
+       fsm->booted_from_spi = true;
+
+       regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+       if (IS_ERR(regmap))
+               goto boot_device_fail;
+
+       fsm->reset_signal = of_property_read_bool(np, "st,reset-signal");
+
+       fsm->reset_por = of_property_read_bool(np, "st,reset-por");
+
+       /* Where in the syscon the boot device information lives */
+       ret = of_property_read_u32(np, "st,boot-device-reg", &boot_device_reg);
+       if (ret)
+               goto boot_device_fail;
+
+       /* Boot device value when booted from SPI NOR */
+       ret = of_property_read_u32(np, "st,boot-device-spi", &boot_device_spi);
+       if (ret)
+               goto boot_device_fail;
+
+       ret = regmap_read(regmap, boot_device_reg, &boot_device);
+       if (ret)
+               goto boot_device_fail;
+
+       if (boot_device != boot_device_spi)
+               fsm->booted_from_spi = false;
+
+       return;
+
+boot_device_fail:
+       dev_warn(&pdev->dev,
+                "failed to fetch boot device, assuming boot from SPI\n");
+}
+
+static int stfsm_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct mtd_part_parser_data ppdata;
+       struct flash_info *info;
+       struct resource *res;
+       struct stfsm *fsm;
+       int ret;
+
+       if (!np) {
+               dev_err(&pdev->dev, "No DT found\n");
+               return -EINVAL;
+       }
+       ppdata.of_node = np;
+
+       fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL);
+       if (!fsm)
+               return -ENOMEM;
+
+       fsm->dev = &pdev->dev;
+
+       platform_set_drvdata(pdev, fsm);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "Resource not found\n");
+               return -ENODEV;
+       }
+
+       fsm->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(fsm->base)) {
+               dev_err(&pdev->dev,
+                       "Failed to reserve memory region %pR\n", res);
+               return PTR_ERR(fsm->base);
+       }
+
+       mutex_init(&fsm->lock);
+
+       ret = stfsm_init(fsm);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to initialise FSM Controller\n");
+               return ret;
+       }
+
+       stfsm_fetch_platform_configs(pdev);
+
+       /* Detect SPI FLASH device */
+       info = stfsm_jedec_probe(fsm);
+       if (!info)
+               return -ENODEV;
+       fsm->info = info;
+
+       /* Use device size to determine address width */
+       if (info->sector_size * info->n_sectors > 0x1000000)
+               info->flags |= FLASH_FLAG_32BIT_ADDR;
+
+       /*
+        * Configure READ/WRITE/ERASE sequences according to platform and
+        * device flags.
+        */
+       if (info->config) {
+               ret = info->config(fsm);
+               if (ret)
+                       return ret;
+       } else {
+               ret = stfsm_prepare_rwe_seqs_default(fsm);
+               if (ret)
+                       return ret;
+       }
+
+       fsm->mtd.name           = info->name;
+       fsm->mtd.dev.parent     = &pdev->dev;
+       fsm->mtd.type           = MTD_NORFLASH;
+       fsm->mtd.writesize      = 4;
+       fsm->mtd.writebufsize   = fsm->mtd.writesize;
+       fsm->mtd.flags          = MTD_CAP_NORFLASH;
+       fsm->mtd.size           = info->sector_size * info->n_sectors;
+       fsm->mtd.erasesize      = info->sector_size;
+
+       fsm->mtd._read  = stfsm_mtd_read;
+       fsm->mtd._write = stfsm_mtd_write;
+       fsm->mtd._erase = stfsm_mtd_erase;
+
+       dev_info(&pdev->dev,
+               "Found serial flash device: %s\n"
+               " size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n",
+               info->name,
+               (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
+               fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
+
+       return mtd_device_parse_register(&fsm->mtd, NULL, &ppdata, NULL, 0);
+}
+
+static int stfsm_remove(struct platform_device *pdev)
+{
+       struct stfsm *fsm = platform_get_drvdata(pdev);
+
+       return mtd_device_unregister(&fsm->mtd);
+}
+
+static struct of_device_id stfsm_match[] = {
+       { .compatible = "st,spi-fsm", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, stfsm_match);
+
+static struct platform_driver stfsm_driver = {
+       .probe          = stfsm_probe,
+       .remove         = stfsm_remove,
+       .driver         = {
+               .name   = "st-spi-fsm",
+               .owner  = THIS_MODULE,
+               .of_match_table = stfsm_match,
+       },
+};
+module_platform_driver(stfsm_driver);
+
+MODULE_AUTHOR("Angus Clark <angus.clark@st.com>");
+MODULE_DESCRIPTION("ST SPI FSM driver");
+MODULE_LICENSE("GPL");
index 4adc0374fb6b5736ba23cdc77f5f8ebb2bb7117b..487e64f411a5df1ed0a6e971f4d915244a52fdda 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/uaccess.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nftl.h>
 #include <linux/mtd/inftl.h>
index d38b6460d50565c21fa46978d3f2383d13299e6f..018c75faadb3d30c2de119608536b1335d175fa4 100644 (file)
@@ -55,10 +55,8 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
        int i, j;
 
        mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
-       if (!mtd) {
-               printk(KERN_ERR "Failed to allocate memory for MTD device\n");
+       if (!mtd)
                return NULL;
-       }
        mtd->priv = map;
        mtd->type = MTD_NORFLASH;
 
index 45abed67f1ef176da4469ed5f9b78b1c66e874c4..69f2112340b19dc94639ff90bd87114490767168 100644 (file)
@@ -135,11 +135,8 @@ static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr)
 {
 
        lpddr->qinfo = kzalloc(sizeof(struct qinfo_chip), GFP_KERNEL);
-       if (!lpddr->qinfo) {
-               printk(KERN_WARNING "%s: no memory for LPDDR qinfo structure\n",
-                               map->name);
+       if (!lpddr->qinfo)
                return 0;
-       }
 
        /* Get the ManuID */
        lpddr->ManufactId = CMDVAL(map_read(map, map->pfow_base + PFOW_MANUFACTURER_ID));
index 310dc7c93425587095941d76afcc8dacbdb1fc29..fce23fe043f7a4cf1edc998422689d2a45e0982c 100644 (file)
@@ -66,11 +66,11 @@ config MTD_PHYSMAP_BANKWIDTH
          used internally by the CFI drivers.
 
 config MTD_PHYSMAP_OF
-       tristate "Flash device in physical memory map based on OF description"
-       depends on OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM)
+       tristate "Memory device in physical memory map based on OF description"
+       depends on OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM || MTD_RAM)
        help
-         This provides a 'mapping' driver which allows the NOR Flash and
-         ROM driver code to communicate with chips which are mapped
+         This provides a 'mapping' driver which allows the NOR Flash, ROM
+         and RAM driver code to communicate with chips which are mapped
          physically into the CPU's memory. The mapping description here is
          taken from OF device tree.
 
@@ -124,7 +124,7 @@ config MTD_NETSC520
 
 config MTD_TS5500
        tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
-       depends on X86
+       depends on TS5500 || COMPILE_TEST
        select MTD_JEDECPROBE
        select MTD_CFI_AMDSTD
        help
index 5434d8ded015dfca0e8a19199883ce26122fc421..6ea51e549045592072016cb9387981373b0aecc0 100644 (file)
@@ -14,7 +14,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
index 1adba86474a52f7a4fed630bd08f300cf45e3398..a4c477b9fdd600cefc6b48e0dd67472c08d611f5 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/gpio.h>
-#include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 46d195fca94267631887f76d7d98f7d67005f3b7..5ab71f0e1bcd6e3b4ae279aeded4e8c980bc9524 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
-#include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
index d6b2451eab1d9f0db5808c3ad837ac2f6f604499..6a589f1e2880bb32aa7cbc01d202ff8c24d65603 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/slab.h>
index 93c507a6f86245024d6b1e79a54ca2f8ad8d78b1..7aa682cd4d7e74d28677a53c2fc5291452ee3ba4 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
index 98bb5d5375d741e8159497e30b704c0520533f79..cadfbe05187316a93449d69a0fb6773720a3aa06 100644 (file)
@@ -10,7 +10,6 @@
  * kind, whether express or implied.
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
index 36da518915b52b8220e5e6d23ed57acc6738ce0e..eb0242e0b2d9903df922f811e41b9584a39cb212 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
index d11109762ac5ca311a1f9bb90711bca0855ebc83..217c25d7381b7589238833eb3303c9695a10b19d 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 10196f5a897d6b31674232652869cb5617e820ec..d597e89f26925940c4f66bf2a222ad037a1dfa15 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
@@ -138,7 +137,6 @@ static int platram_probe(struct platform_device *pdev)
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (info == NULL) {
-               dev_err(&pdev->dev, "no memory for flash info\n");
                err = -ENOMEM;
                goto exit_error;
        }
index 9aad854fe9121aaa821181bffe64e819ec0e8498..cb4d92eea9feab773be54de8936842c350f5aa66 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 93525121d69dc17876f70f8341e6f69faa251b12..146b6047ed2b0e066ebc5961244993927d7f8387 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
index 3051c4c362404bab5119dcf00d8c1e7321e4dbf3..b7a22a612a4628adfaf647c27a9013fcbdabe85d 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 39cc4181f02538a438b8fc427e00e19c1074fde3..b6f1aac3510cb58a720cb529302126ab9596b3fb 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/errno.h>
-#include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
index 5073cbc796d86c3a04c4f22d83b01c2f01b1d114..0b2ccb68c0d0240efdb9c5de9189f8e89a4ca890 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/blkpg.h>
 #include <linux/spinlock.h>
 #include <linux/hdreg.h>
-#include <linux/init.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
 
index 2147e733533b611a44c88ca3d53efee5ae8f5e01..7d4e7b9da3a1aceef2ea5ea664cea4e0d94752c6 100644 (file)
@@ -324,6 +324,15 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c
                default:
                        ret = mtd_write(mtd, *ppos, len, &retlen, kbuf);
                }
+
+               /*
+                * Return -ENOSPC only if no data could be written at all.
+                * Otherwise just return the number of bytes that actually
+                * have been written.
+                */
+               if ((ret == -ENOSPC) && (total_retlen))
+                       break;
+
                if (!ret) {
                        *ppos += retlen;
                        total_retlen += retlen;
@@ -889,25 +898,26 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
        case OTPGETREGIONINFO:
        {
                struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+               size_t retlen;
                if (!buf)
                        return -ENOMEM;
                switch (mfi->mode) {
                case MTD_FILE_MODE_OTP_FACTORY:
-                       ret = mtd_get_fact_prot_info(mtd, buf, 4096);
+                       ret = mtd_get_fact_prot_info(mtd, 4096, &retlen, buf);
                        break;
                case MTD_FILE_MODE_OTP_USER:
-                       ret = mtd_get_user_prot_info(mtd, buf, 4096);
+                       ret = mtd_get_user_prot_info(mtd, 4096, &retlen, buf);
                        break;
                default:
                        ret = -EINVAL;
                        break;
                }
-               if (ret >= 0) {
+               if (!ret) {
                        if (cmd == OTPGETREGIONCOUNT) {
-                               int nbr = ret / sizeof(struct otp_info);
+                               int nbr = retlen / sizeof(struct otp_info);
                                ret = copy_to_user(argp, &nbr, sizeof(int));
                        } else
-                               ret = copy_to_user(argp, buf, ret);
+                               ret = copy_to_user(argp, buf, retlen);
                        if (ret)
                                ret = -EFAULT;
                }
index 34c0b16aed5c4e2f7d61a22d3fdeaf2ca066a632..d201feeb3ca6dc7ffe1380840fb0f826ddb0ec10 100644 (file)
@@ -883,14 +883,14 @@ EXPORT_SYMBOL_GPL(mtd_read_oob);
  * devices. The user data is one time programmable but the factory data is read
  * only.
  */
-int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-                          size_t len)
+int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+                          struct otp_info *buf)
 {
        if (!mtd->_get_fact_prot_info)
                return -EOPNOTSUPP;
        if (!len)
                return 0;
-       return mtd->_get_fact_prot_info(mtd, buf, len);
+       return mtd->_get_fact_prot_info(mtd, len, retlen, buf);
 }
 EXPORT_SYMBOL_GPL(mtd_get_fact_prot_info);
 
@@ -906,14 +906,14 @@ int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
 }
 EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
 
-int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-                          size_t len)
+int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+                          struct otp_info *buf)
 {
        if (!mtd->_get_user_prot_info)
                return -EOPNOTSUPP;
        if (!len)
                return 0;
-       return mtd->_get_user_prot_info(mtd, buf, len);
+       return mtd->_get_user_prot_info(mtd, len, retlen, buf);
 }
 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);
 
@@ -932,12 +932,22 @@ EXPORT_SYMBOL_GPL(mtd_read_user_prot_reg);
 int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
                            size_t *retlen, u_char *buf)
 {
+       int ret;
+
        *retlen = 0;
        if (!mtd->_write_user_prot_reg)
                return -EOPNOTSUPP;
        if (!len)
                return 0;
-       return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
+       ret = mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
+       if (ret)
+               return ret;
+
+       /*
+        * If no data could be written at all, we are out of memory and
+        * must return -ENOSPC.
+        */
+       return (*retlen) ? 0 : -ENOSPC;
 }
 EXPORT_SYMBOL_GPL(mtd_write_user_prot_reg);
 
index 3c7d6d7623c1cd5557b4dfeb38e80e03fc6e2abc..1ca9aec141ff01fcd90dada11986f25d2fbaae4b 100644 (file)
@@ -150,11 +150,12 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
                                                 retlen, buf);
 }
 
-static int part_get_user_prot_info(struct mtd_info *mtd,
-               struct otp_info *buf, size_t len)
+static int part_get_user_prot_info(struct mtd_info *mtd, size_t len,
+                                  size_t *retlen, struct otp_info *buf)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->_get_user_prot_info(part->master, buf, len);
+       return part->master->_get_user_prot_info(part->master, len, retlen,
+                                                buf);
 }
 
 static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
@@ -165,11 +166,12 @@ static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
                                                 retlen, buf);
 }
 
-static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-               size_t len)
+static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+                                  size_t *retlen, struct otp_info *buf)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->_get_fact_prot_info(part->master, buf, len);
+       return part->master->_get_fact_prot_info(part->master, len, retlen,
+                                                buf);
 }
 
 static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
index a4bee41ad5cb3c191748a04409c81ad5414dd1f4..f1cf503517fdcff3e8743fd3ec2816d85d4fcd80 100644 (file)
@@ -460,6 +460,8 @@ config MTD_NAND_MXC
 config MTD_NAND_SH_FLCTL
        tristate "Support for NAND on Renesas SuperH FLCTL"
        depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
+       depends on HAS_IOMEM
+       depends on HAS_DMA
        help
          Several Renesas SuperH CPU has FLCTL. This option enables support
          for NAND Flash using FLCTL.
index 8611eb4b45fca90e73d84db280b55301640fcd93..4936e9e0002f384701493e0cb823d73ee3f20fb6 100644 (file)
@@ -17,7 +17,6 @@
  */
 
 #include <linux/slab.h>
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
index c36e9b84487cd36b55d96efd1d17c6db9494c0fc..4ce181a35bcd3eedf39c8fd3a5c617306278ef58 100644 (file)
@@ -430,7 +430,7 @@ err_dma:
        dma_unmap_single(dma_dev->dev, phys_addr, len, dir);
 err_buf:
        if (err != 0)
-               dev_warn(host->dev, "Fall back to CPU I/O\n");
+               dev_dbg(host->dev, "Fall back to CPU I/O\n");
        return err;
 }
 
@@ -1220,6 +1220,7 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev,
                goto err;
        }
 
+       nand_chip->options |= NAND_NO_SUBPAGE_WRITE;
        nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
        nand_chip->ecc.write_page = atmel_nand_pmecc_write_page;
 
@@ -1659,8 +1660,8 @@ static void nfc_select_chip(struct mtd_info *mtd, int chip)
                nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_ENABLE);
 }
 
-static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr,
-               unsigned int *addr1234, unsigned int *cycle0)
+static int nfc_make_addr(struct mtd_info *mtd, int command, int column,
+               int page_addr, unsigned int *addr1234, unsigned int *cycle0)
 {
        struct nand_chip *chip = mtd->priv;
 
@@ -1674,7 +1675,8 @@ static int nfc_make_addr(struct mtd_info *mtd, int column, int page_addr,
        *addr1234 = 0;
 
        if (column != -1) {
-               if (chip->options & NAND_BUSWIDTH_16)
+               if (chip->options & NAND_BUSWIDTH_16 &&
+                               !nand_opcode_8bits(command))
                        column >>= 1;
                addr_bytes[acycle++] = column & 0xff;
                if (mtd->writesize > 512)
@@ -1787,8 +1789,8 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command,
        }
 
        if (do_addr)
-               acycle = nfc_make_addr(mtd, column, page_addr, &addr1234,
-                               &cycle0);
+               acycle = nfc_make_addr(mtd, command, column, page_addr,
+                               &addr1234, &cycle0);
 
        nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr;
        nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0);
index 2880d888cfc5c260aefcdd5caba743d05a292ae6..bc5c518828d2bc9edb8796521c0e2e0ebb016497 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/slab.h>
 #include <linux/gpio.h>
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
@@ -308,7 +307,8 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
                /* Serially input address */
                if (column != -1) {
                        /* Adjust columns for 16 bit buswidth */
-                       if (this->options & NAND_BUSWIDTH_16)
+                       if (this->options & NAND_BUSWIDTH_16 &&
+                                       !nand_opcode_8bits(command))
                                column >>= 1;
                        ctx->write_byte(mtd, column);
                }
index 94f55dbde995974213b48158048a92553bfc7475..b7a24946ca26274a291ae99b6d844e586487dd2e 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
index f2f64addb5e87119d8b72e9122565ae3ec9150f9..4e66726da9aa8bc55658bed57a3d56d1849d6793 100644 (file)
@@ -627,6 +627,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
        struct cafe_priv *cafe;
        uint32_t ctrl;
        int err = 0;
+       int old_dma;
+       struct nand_buffers *nbuf;
 
        /* Very old versions shared the same PCI ident for all three
           functions on the chip. Verify the class too... */
@@ -655,13 +657,6 @@ static int cafe_nand_probe(struct pci_dev *pdev,
                err = -ENOMEM;
                goto out_free_mtd;
        }
-       cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev, 2112 + sizeof(struct nand_buffers),
-                                         &cafe->dmaaddr, GFP_KERNEL);
-       if (!cafe->dmabuf) {
-               err = -ENOMEM;
-               goto out_ior;
-       }
-       cafe->nand.buffers = (void *)cafe->dmabuf + 2112;
 
        cafe->rs = init_rs_non_canonical(12, &cafe_mul, 0, 1, 8);
        if (!cafe->rs) {
@@ -721,7 +716,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
                          "CAFE NAND", mtd);
        if (err) {
                dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq);
-               goto out_free_dma;
+               goto out_ior;
        }
 
        /* Disable master reset, enable NAND clock */
@@ -735,6 +730,32 @@ static int cafe_nand_probe(struct pci_dev *pdev,
        cafe_writel(cafe, 0x7006, GLOBAL_CTRL);
        cafe_writel(cafe, 0x700a, GLOBAL_CTRL);
 
+       /* Enable NAND IRQ in global IRQ mask register */
+       cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
+       cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
+               cafe_readl(cafe, GLOBAL_CTRL),
+               cafe_readl(cafe, GLOBAL_IRQ_MASK));
+
+       /* Do not use the DMA for the nand_scan_ident() */
+       old_dma = usedma;
+       usedma = 0;
+
+       /* Scan to find existence of the device */
+       if (nand_scan_ident(mtd, 2, NULL)) {
+               err = -ENXIO;
+               goto out_irq;
+       }
+
+       cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev,
+                               2112 + sizeof(struct nand_buffers) +
+                               mtd->writesize + mtd->oobsize,
+                               &cafe->dmaaddr, GFP_KERNEL);
+       if (!cafe->dmabuf) {
+               err = -ENOMEM;
+               goto out_irq;
+       }
+       cafe->nand.buffers = nbuf = (void *)cafe->dmabuf + 2112;
+
        /* Set up DMA address */
        cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0);
        if (sizeof(cafe->dmaaddr) > 4)
@@ -746,16 +767,13 @@ static int cafe_nand_probe(struct pci_dev *pdev,
        cafe_dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n",
                cafe_readl(cafe, NAND_DMA_ADDR0), cafe->dmabuf);
 
-       /* Enable NAND IRQ in global IRQ mask register */
-       cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
-       cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
-               cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK));
+       /* this driver does not need the @ecccalc and @ecccode */
+       nbuf->ecccalc = NULL;
+       nbuf->ecccode = NULL;
+       nbuf->databuf = (uint8_t *)(nbuf + 1);
 
-       /* Scan to find existence of the device */
-       if (nand_scan_ident(mtd, 2, NULL)) {
-               err = -ENXIO;
-               goto out_irq;
-       }
+       /* Restore the DMA flag */
+       usedma = old_dma;
 
        cafe->ctl2 = 1<<27; /* Reed-Solomon ECC */
        if (mtd->writesize == 2048)
@@ -773,7 +791,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
        } else {
                printk(KERN_WARNING "Unexpected NAND flash writesize %d. Aborting\n",
                       mtd->writesize);
-               goto out_irq;
+               goto out_free_dma;
        }
        cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
        cafe->nand.ecc.size = mtd->writesize;
@@ -790,7 +808,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 
        err = nand_scan_tail(mtd);
        if (err)
-               goto out_irq;
+               goto out_free_dma;
 
        pci_set_drvdata(pdev, mtd);
 
@@ -799,12 +817,15 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 
        goto out;
 
+ out_free_dma:
+       dma_free_coherent(&cafe->pdev->dev,
+                       2112 + sizeof(struct nand_buffers) +
+                       mtd->writesize + mtd->oobsize,
+                       cafe->dmabuf, cafe->dmaaddr);
  out_irq:
        /* Disable NAND IRQ in global IRQ mask register */
        cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
        free_irq(pdev->irq, mtd);
- out_free_dma:
-       dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
  out_ior:
        pci_iounmap(pdev, cafe->mmio);
  out_free_mtd:
@@ -824,7 +845,10 @@ static void cafe_nand_remove(struct pci_dev *pdev)
        nand_release(mtd);
        free_rs(cafe->rs);
        pci_iounmap(pdev, cafe->mmio);
-       dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr);
+       dma_free_coherent(&cafe->pdev->dev,
+                       2112 + sizeof(struct nand_buffers) +
+                       mtd->writesize + mtd->oobsize,
+                       cafe->dmabuf, cafe->dmaaddr);
        kfree(mtd);
 }
 
index a4989ec6292efa0127ba4cc84d13fd07ad09fe4b..4615d79fc93f795c869687117744e01653219478 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
@@ -746,28 +745,6 @@ static int nand_davinci_probe(struct platform_device *pdev)
                goto err_clk_enable;
        }
 
-       /*
-        * Setup Async configuration register in case we did not boot from
-        * NAND and so bootloader did not bother to set it up.
-        */
-       val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4);
-
-       /* Extended Wait is not valid and Select Strobe mode is not used */
-       val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
-       if (info->chip.options & NAND_BUSWIDTH_16)
-               val |= 0x1;
-
-       davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val);
-
-       ret = 0;
-       if (info->timing)
-               ret = davinci_aemif_setup_timing(info->timing, info->base,
-                                                       info->core_chipsel);
-       if (ret < 0) {
-               dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
-               goto err;
-       }
-
        spin_lock_irq(&davinci_nand_lock);
 
        /* put CSxNAND into NAND mode */
index babb02c4b2204ed0c5881a3577084c2ea826d5df..35cb17f57800755fdbf1032cf5c155059f32215f 100644 (file)
@@ -30,24 +30,6 @@ struct denali_dt {
        struct clk              *clk;
 };
 
-static void __iomem *request_and_map(struct device *dev,
-                                    const struct resource *res)
-{
-       void __iomem *ptr;
-
-       if (!devm_request_mem_region(dev, res->start, resource_size(res),
-                                    "denali-dt")) {
-               dev_err(dev, "unable to request %s\n", res->name);
-               return NULL;
-       }
-
-       ptr = devm_ioremap_nocache(dev, res->start, resource_size(res));
-       if (!ptr)
-               dev_err(dev, "ioremap_nocache of %s failed!", res->name);
-
-       return ptr;
-}
-
 static const struct of_device_id denali_nand_dt_ids[] = {
                { .compatible = "denali,denali-nand-dt" },
                { /* sentinel */ }
@@ -78,13 +60,6 @@ static int denali_dt_probe(struct platform_device *ofdev)
                return -ENOMEM;
        denali = &dt->denali;
 
-       denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg");
-       nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data");
-       if (!denali_reg || !nand_data) {
-               dev_err(&ofdev->dev, "resources not completely defined\n");
-               return -EINVAL;
-       }
-
        denali->platform = DT;
        denali->dev = &ofdev->dev;
        denali->irq = platform_get_irq(ofdev, 0);
@@ -93,13 +68,15 @@ static int denali_dt_probe(struct platform_device *ofdev)
                return denali->irq;
        }
 
-       denali->flash_reg = request_and_map(&ofdev->dev, denali_reg);
-       if (!denali->flash_reg)
-               return -ENOMEM;
+       denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg");
+       denali->flash_reg = devm_ioremap_resource(&ofdev->dev, denali_reg);
+       if (IS_ERR(denali->flash_reg))
+               return PTR_ERR(denali->flash_reg);
 
-       denali->flash_mem = request_and_map(&ofdev->dev, nand_data);
-       if (!denali->flash_mem)
-               return -ENOMEM;
+       nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data");
+       denali->flash_mem = devm_ioremap_resource(&ofdev->dev, nand_data);
+       if (IS_ERR(denali->flash_mem))
+               return PTR_ERR(denali->flash_mem);
 
        if (!of_property_read_u32(ofdev->dev.of_node,
                "dma-mask", (u32 *)&denali_dma_mask)) {
index fec31d71b84e03d7a84cbaf15b4558c16d413e0a..f68a7bccecdc65878fac3ed3056ac499099992b7 100644 (file)
@@ -698,7 +698,8 @@ static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int colu
                /* Serially input address */
                if (column != -1) {
                        /* Adjust columns for 16 bit buswidth */
-                       if (this->options & NAND_BUSWIDTH_16)
+                       if (this->options & NAND_BUSWIDTH_16 &&
+                                       !nand_opcode_8bits(command))
                                column >>= 1;
                        WriteDOC(column, docptr, Mplus_FlashAddress);
                }
@@ -1438,7 +1439,7 @@ static int __init doc_probe(unsigned long physadr)
        int reg, len, numchips;
        int ret = 0;
 
-       if (!request_mem_region(physadr, DOC_IOREMAP_LEN, NULL))
+       if (!request_mem_region(physadr, DOC_IOREMAP_LEN, "DiskOnChip"))
                return -EBUSY;
        virtadr = ioremap(physadr, DOC_IOREMAP_LEN);
        if (!virtadr) {
index bcf60800c3ce7f5e0489972ebe7a3e3f83d225df..ec549cd9849fbc426c598240e6fbce6fabf1cd1e 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
index 50d9161c4faf49959174f603efe69db4ed969334..cb45d2f8e208425cdaa8866ebdb96753cb80f999 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
index 8e6148aa4539a290b4b3a4cda8883f1bbba58f92..117ce333fdd48f68525bca9b8da5fdec36649894 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/kernel.h>
 #include <linux/err.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
index ca6369fe91ff31fc89bd382dca62261774310ff0..bb77f750e75a3b1cfee16e5ecbf95efea95ead1a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/of_device.h>
 #include <linux/of_mtd.h>
 #include "gpmi-nand.h"
+#include "bch-regs.h"
 
 /* Resource names for the GPMI NAND driver. */
 #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
@@ -985,7 +986,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
        int           ret;
 
        dev_dbg(this->dev, "page number is : %d\n", page);
-       ret = read_page_prepare(this, buf, mtd->writesize,
+       ret = read_page_prepare(this, buf, nfc_geo->payload_size,
                                        this->payload_virt, this->payload_phys,
                                        nfc_geo->payload_size,
                                        &payload_virt, &payload_phys);
@@ -999,7 +1000,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 
        /* go! */
        ret = gpmi_read_page(this, payload_phys, auxiliary_phys);
-       read_page_end(this, buf, mtd->writesize,
+       read_page_end(this, buf, nfc_geo->payload_size,
                        this->payload_virt, this->payload_phys,
                        nfc_geo->payload_size,
                        payload_virt, payload_phys);
@@ -1041,7 +1042,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
                chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
        }
 
-       read_page_swap_end(this, buf, mtd->writesize,
+       read_page_swap_end(this, buf, nfc_geo->payload_size,
                        this->payload_virt, this->payload_phys,
                        nfc_geo->payload_size,
                        payload_virt, payload_phys);
@@ -1049,6 +1050,90 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
        return max_bitflips;
 }
 
+/* Fake a virtual small page for the subpage read */
+static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+                       uint32_t offs, uint32_t len, uint8_t *buf, int page)
+{
+       struct gpmi_nand_data *this = chip->priv;
+       void __iomem *bch_regs = this->resources.bch_regs;
+       struct bch_geometry old_geo = this->bch_geometry;
+       struct bch_geometry *geo = &this->bch_geometry;
+       int size = chip->ecc.size; /* ECC chunk size */
+       int meta, n, page_size;
+       u32 r1_old, r2_old, r1_new, r2_new;
+       unsigned int max_bitflips;
+       int first, last, marker_pos;
+       int ecc_parity_size;
+       int col = 0;
+
+       /* The size of ECC parity */
+       ecc_parity_size = geo->gf_len * geo->ecc_strength / 8;
+
+       /* Align it with the chunk size */
+       first = offs / size;
+       last = (offs + len - 1) / size;
+
+       /*
+        * Find the chunk which contains the Block Marker. If this chunk is
+        * in the range of [first, last], we have to read out the whole page.
+        * Why? since we had swapped the data at the position of Block Marker
+        * to the metadata which is bound with the chunk 0.
+        */
+       marker_pos = geo->block_mark_byte_offset / size;
+       if (last >= marker_pos && first <= marker_pos) {
+               dev_dbg(this->dev, "page:%d, first:%d, last:%d, marker at:%d\n",
+                               page, first, last, marker_pos);
+               return gpmi_ecc_read_page(mtd, chip, buf, 0, page);
+       }
+
+       meta = geo->metadata_size;
+       if (first) {
+               col = meta + (size + ecc_parity_size) * first;
+               chip->cmdfunc(mtd, NAND_CMD_RNDOUT, col, -1);
+
+               meta = 0;
+               buf = buf + first * size;
+       }
+
+       /* Save the old environment */
+       r1_old = r1_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT0);
+       r2_old = r2_new = readl(bch_regs + HW_BCH_FLASH0LAYOUT1);
+
+       /* change the BCH registers and bch_geometry{} */
+       n = last - first + 1;
+       page_size = meta + (size + ecc_parity_size) * n;
+
+       r1_new &= ~(BM_BCH_FLASH0LAYOUT0_NBLOCKS |
+                       BM_BCH_FLASH0LAYOUT0_META_SIZE);
+       r1_new |= BF_BCH_FLASH0LAYOUT0_NBLOCKS(n - 1)
+                       | BF_BCH_FLASH0LAYOUT0_META_SIZE(meta);
+       writel(r1_new, bch_regs + HW_BCH_FLASH0LAYOUT0);
+
+       r2_new &= ~BM_BCH_FLASH0LAYOUT1_PAGE_SIZE;
+       r2_new |= BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size);
+       writel(r2_new, bch_regs + HW_BCH_FLASH0LAYOUT1);
+
+       geo->ecc_chunk_count = n;
+       geo->payload_size = n * size;
+       geo->page_size = page_size;
+       geo->auxiliary_status_offset = ALIGN(meta, 4);
+
+       dev_dbg(this->dev, "page:%d(%d:%d)%d, chunk:(%d:%d), BCH PG size:%d\n",
+               page, offs, len, col, first, n, page_size);
+
+       /* Read the subpage now */
+       this->swap_block_mark = false;
+       max_bitflips = gpmi_ecc_read_page(mtd, chip, buf, 0, page);
+
+       /* Restore */
+       writel(r1_old, bch_regs + HW_BCH_FLASH0LAYOUT0);
+       writel(r2_old, bch_regs + HW_BCH_FLASH0LAYOUT1);
+       this->bch_geometry = old_geo;
+       this->swap_block_mark = true;
+
+       return max_bitflips;
+}
+
 static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                                const uint8_t *buf, int oob_required)
 {
@@ -1565,6 +1650,17 @@ static int gpmi_init_last(struct gpmi_nand_data *this)
        ecc->strength   = bch_geo->ecc_strength;
        ecc->layout     = &gpmi_hw_ecclayout;
 
+       /*
+        * We only enable the subpage read when:
+        *  (1) the chip is imx6, and
+        *  (2) the size of the ECC parity is byte aligned.
+        */
+       if (GPMI_IS_MX6Q(this) &&
+               ((bch_geo->gf_len * bch_geo->ecc_strength) % 8) == 0) {
+               ecc->read_subpage = gpmi_ecc_read_subpage;
+               chip->options |= NAND_SUBPAGE_READ;
+       }
+
        /*
         * Can we enable the extra features? such as EDO or Sync mode.
         *
index 31ee7cfbc12b628c9599f3d0c78b3de23185dc6c..e78841a2dcc36be4923923f0251b72a6de830809 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/mtd/mtd.h>
index e9a4835c4dd9887f8546c5e95ce298674d5182a3..dba262bf766ff197c3afe9db1c68e11ca12f7a2b 100644 (file)
@@ -1501,6 +1501,8 @@ static int mxcnd_probe(struct platform_device *pdev)
        init_completion(&host->op_completion);
 
        host->irq = platform_get_irq(pdev, 0);
+       if (host->irq < 0)
+               return host->irq;
 
        /*
         * Use host->devtype_data->irq_control() here instead of irq_control()
index 9715a7ba164a042abbba49fd842e9400a677d6fe..9d01c4df838c91000dda6793ae231b0dd0992062 100644 (file)
@@ -589,7 +589,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        /* Serially input address */
        if (column != -1) {
                /* Adjust columns for 16 bit buswidth */
-               if (chip->options & NAND_BUSWIDTH_16)
+               if (chip->options & NAND_BUSWIDTH_16 &&
+                               !nand_opcode_8bits(command))
                        column >>= 1;
                chip->cmd_ctrl(mtd, column, ctrl);
                ctrl &= ~NAND_CTRL_CHANGE;
@@ -680,7 +681,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                /* Serially input address */
                if (column != -1) {
                        /* Adjust columns for 16 bit buswidth */
-                       if (chip->options & NAND_BUSWIDTH_16)
+                       if (chip->options & NAND_BUSWIDTH_16 &&
+                                       !nand_opcode_8bits(command))
                                column >>= 1;
                        chip->cmd_ctrl(mtd, column, ctrl);
                        ctrl &= ~NAND_CTRL_CHANGE;
@@ -1160,9 +1162,11 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @data_offs: offset of requested data within the page
  * @readlen: data length
  * @bufpoi: buffer to store read data
+ * @page: page number to read
  */
 static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
-                       uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
+                       uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
+                       int page)
 {
        int start_step, end_step, num_steps;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -1170,13 +1174,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        int data_col_addr, i, gaps = 0;
        int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
        int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
-       int index = 0;
+       int index;
        unsigned int max_bitflips = 0;
 
        /* Column address within the page aligned to ECC size (256bytes) */
        start_step = data_offs / chip->ecc.size;
        end_step = (data_offs + readlen - 1) / chip->ecc.size;
        num_steps = end_step - start_step + 1;
+       index = start_step * chip->ecc.bytes;
 
        /* Data size aligned to ECC ecc.size */
        datafrag_len = num_steps * chip->ecc.size;
@@ -1213,8 +1218,6 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                 * Send the command to read the particular ECC bytes take care
                 * about buswidth alignment in read_buf.
                 */
-               index = start_step * chip->ecc.bytes;
-
                aligned_pos = eccpos[index] & ~(busw - 1);
                aligned_len = eccfrag_len;
                if (eccpos[index] & (busw - 1))
@@ -1538,7 +1541,8 @@ read_retry:
                        else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
                                 !oob)
                                ret = chip->ecc.read_subpage(mtd, chip,
-                                                       col, bytes, bufpoi);
+                                                       col, bytes, bufpoi,
+                                                       page);
                        else
                                ret = chip->ecc.read_page(mtd, chip, bufpoi,
                                                          oob_required, page);
@@ -2000,7 +2004,7 @@ static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
                        oob += chip->ecc.prepad;
                }
 
-               chip->read_buf(mtd, oob, eccbytes);
+               chip->write_buf(mtd, oob, eccbytes);
                oob += eccbytes;
 
                if (chip->ecc.postpad) {
@@ -3063,7 +3067,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                                        int *busw)
 {
        struct nand_onfi_params *p = &chip->onfi_params;
-       int i;
+       int i, j;
        int val;
 
        /* Try ONFI for unknown chip or LP */
@@ -3072,18 +3076,10 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
                return 0;
 
-       /*
-        * ONFI must be probed in 8-bit mode or with NAND_BUSWIDTH_AUTO, not
-        * with NAND_BUSWIDTH_16
-        */
-       if (chip->options & NAND_BUSWIDTH_16) {
-               pr_err("ONFI cannot be probed in 16-bit mode; aborting\n");
-               return 0;
-       }
-
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
-               chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
+               for (j = 0; j < sizeof(*p); j++)
+                       ((uint8_t *)p)[j] = chip->read_byte(mtd);
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
                        break;
@@ -3168,6 +3164,87 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        return 1;
 }
 
+/*
+ * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise.
+ */
+static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip,
+                                       int *busw)
+{
+       struct nand_jedec_params *p = &chip->jedec_params;
+       struct jedec_ecc_info *ecc;
+       int val;
+       int i, j;
+
+       /* Try JEDEC for unknown chip or LP */
+       chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1);
+       if (chip->read_byte(mtd) != 'J' || chip->read_byte(mtd) != 'E' ||
+               chip->read_byte(mtd) != 'D' || chip->read_byte(mtd) != 'E' ||
+               chip->read_byte(mtd) != 'C')
+               return 0;
+
+       chip->cmdfunc(mtd, NAND_CMD_PARAM, 0x40, -1);
+       for (i = 0; i < 3; i++) {
+               for (j = 0; j < sizeof(*p); j++)
+                       ((uint8_t *)p)[j] = chip->read_byte(mtd);
+
+               if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
+                               le16_to_cpu(p->crc))
+                       break;
+       }
+
+       if (i == 3) {
+               pr_err("Could not find valid JEDEC parameter page; aborting\n");
+               return 0;
+       }
+
+       /* Check version */
+       val = le16_to_cpu(p->revision);
+       if (val & (1 << 2))
+               chip->jedec_version = 10;
+       else if (val & (1 << 1))
+               chip->jedec_version = 1; /* vendor specific version */
+
+       if (!chip->jedec_version) {
+               pr_info("unsupported JEDEC version: %d\n", val);
+               return 0;
+       }
+
+       sanitize_string(p->manufacturer, sizeof(p->manufacturer));
+       sanitize_string(p->model, sizeof(p->model));
+       if (!mtd->name)
+               mtd->name = p->model;
+
+       mtd->writesize = le32_to_cpu(p->byte_per_page);
+
+       /* Please reference to the comment for nand_flash_detect_onfi. */
+       mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
+       mtd->erasesize *= mtd->writesize;
+
+       mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+
+       /* Please reference to the comment for nand_flash_detect_onfi. */
+       chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
+       chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
+       chip->bits_per_cell = p->bits_per_cell;
+
+       if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS)
+               *busw = NAND_BUSWIDTH_16;
+       else
+               *busw = 0;
+
+       /* ECC info */
+       ecc = &p->ecc_info[0];
+
+       if (ecc->codeword_size >= 9) {
+               chip->ecc_strength_ds = ecc->ecc_bits;
+               chip->ecc_step_ds = 1 << ecc->codeword_size;
+       } else {
+               pr_warn("Invalid codeword size\n");
+       }
+
+       return 1;
+}
+
 /*
  * nand_id_has_period - Check if an ID string has a given wraparound period
  * @id_data: the ID string
@@ -3474,10 +3551,10 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
  */
 static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                                                  struct nand_chip *chip,
-                                                 int busw,
                                                  int *maf_id, int *dev_id,
                                                  struct nand_flash_dev *type)
 {
+       int busw;
        int i, maf_idx;
        u8 id_data[8];
 
@@ -3533,6 +3610,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                /* Check is chip is ONFI compliant */
                if (nand_flash_detect_onfi(mtd, chip, &busw))
                        goto ident_done;
+
+               /* Check if the chip is JEDEC compliant */
+               if (nand_flash_detect_jedec(mtd, chip, &busw))
+                       goto ident_done;
        }
 
        if (!type->name)
@@ -3612,8 +3693,17 @@ ident_done:
 
        pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
                *maf_id, *dev_id);
-       pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
-               chip->onfi_version ? chip->onfi_params.model : type->name);
+
+       if (chip->onfi_version)
+               pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
+                               chip->onfi_params.model);
+       else if (chip->jedec_version)
+               pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
+                               chip->jedec_params.model);
+       else
+               pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
+                               type->name);
+
        pr_info("%dMiB, %s, page size: %d, OOB size: %d\n",
                (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
                mtd->writesize, mtd->oobsize);
@@ -3634,18 +3724,16 @@ ident_done:
 int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                    struct nand_flash_dev *table)
 {
-       int i, busw, nand_maf_id, nand_dev_id;
+       int i, nand_maf_id, nand_dev_id;
        struct nand_chip *chip = mtd->priv;
        struct nand_flash_dev *type;
 
-       /* Get buswidth to select the correct functions */
-       busw = chip->options & NAND_BUSWIDTH_16;
        /* Set the default functions */
-       nand_set_defaults(chip, busw);
+       nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
 
        /* Read the flash type */
-       type = nand_get_flash_type(mtd, chip, busw,
-                               &nand_maf_id, &nand_dev_id, table);
+       type = nand_get_flash_type(mtd, chip, &nand_maf_id,
+                                  &nand_dev_id, table);
 
        if (IS_ERR(type)) {
                if (!(chip->options & NAND_SCAN_SILENT_NODEV))
@@ -3696,15 +3784,26 @@ int nand_scan_tail(struct mtd_info *mtd)
        int i;
        struct nand_chip *chip = mtd->priv;
        struct nand_ecc_ctrl *ecc = &chip->ecc;
+       struct nand_buffers *nbuf;
 
        /* New bad blocks should be marked in OOB, flash-based BBT, or both */
        BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
                        !(chip->bbt_options & NAND_BBT_USE_FLASH));
 
-       if (!(chip->options & NAND_OWN_BUFFERS))
-               chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
-       if (!chip->buffers)
-               return -ENOMEM;
+       if (!(chip->options & NAND_OWN_BUFFERS)) {
+               nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
+                               + mtd->oobsize * 3, GFP_KERNEL);
+               if (!nbuf)
+                       return -ENOMEM;
+               nbuf->ecccalc = (uint8_t *)(nbuf + 1);
+               nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
+               nbuf->databuf = nbuf->ecccode + mtd->oobsize;
+
+               chip->buffers = nbuf;
+       } else {
+               if (!chip->buffers)
+                       return -ENOMEM;
+       }
 
        /* Set the internal oob buffer location, just after the page data */
        chip->oob_poi = chip->buffers->databuf + mtd->writesize;
@@ -3825,7 +3924,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
        case NAND_ECC_SOFT_BCH:
                if (!mtd_nand_has_bch()) {
-                       pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
+                       pr_warn("CONFIG_MTD_NAND_ECC_BCH not enabled\n");
                        BUG();
                }
                ecc->calculate = nand_bch_calculate_ecc;
index daa2faacd7d09f99422fa3f64fc6947a7f4f92cc..3d7c89fc1031aa258c513a2e1d299fcbfb358c40 100644 (file)
@@ -43,6 +43,9 @@ struct nand_flash_dev nand_flash_ids[] = {
        {"TC58NVG6D2 64G 3.3V 8-bit",
                { .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
                  SZ_8K, SZ_8K, SZ_2M, 0, 8, 640, NAND_ECC_INFO(40, SZ_1K) },
+       {"SDTNRGAMA 64G 3.3V 8-bit",
+               { .id = {0x45, 0xde, 0x94, 0x93, 0x76, 0x50} },
+                 SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) },
 
        LEGACY_ID_NAND("NAND 4MiB 5V 8-bit",   0x6B, 4, SZ_8K, SP_OPTIONS),
        LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
index 9ee09a8177c67feae055da60dcb033e9bf76f4c4..e8a5fffd6ab248bdf5329eb9fb7bf1674a3b92e9 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/slab.h>
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -152,7 +151,8 @@ static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command,
        if (column != -1 || page_addr != -1) {
 
                if (column != -1) {
-                       if (chip->options & NAND_BUSWIDTH_16)
+                       if (chip->options & NAND_BUSWIDTH_16 &&
+                                       !nand_opcode_8bits(command))
                                column >>= 1;
                        write_addr_reg(nand, column);
                        write_addr_reg(nand, column >> 8 | ENDADDR);
@@ -225,7 +225,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand)
        val = __raw_readl(nand->reg + REG_FMICSR);
 
        if (!(val & NAND_EN))
-               __raw_writel(val | NAND_EN, REG_FMICSR);
+               __raw_writel(val | NAND_EN, nand->reg + REG_FMICSR);
 
        val = __raw_readl(nand->reg + REG_SMCSR);
 
index bf642ceef68172b4575d8e9d3263320e0fc7095a..1ff49b80bdaf7e3a454c02574165d1a59a04a72b 100644 (file)
 
 #define OMAP24XX_DMA_GPMC              4
 
-#define BCH8_MAX_ERROR         8       /* upto 8 bit correctable */
-#define BCH4_MAX_ERROR         4       /* upto 4 bit correctable */
-
 #define SECTOR_BYTES           512
 /* 4 bit padding to make byte aligned, 56 = 52 + 4 */
 #define BCH4_BIT_PAD           4
-#define BCH8_ECC_MAX           ((SECTOR_BYTES + BCH8_ECC_OOB_BYTES) * 8)
-#define BCH4_ECC_MAX           ((SECTOR_BYTES + BCH4_ECC_OOB_BYTES) * 8)
 
 /* GPMC ecc engine settings for read */
 #define BCH_WRAPMODE_1         1       /* BCH wrap mode 1 */
@@ -159,7 +154,7 @@ struct omap_nand_info {
 
        int                             gpmc_cs;
        unsigned long                   phys_base;
-       unsigned long                   mem_size;
+       enum omap_ecc                   ecc_opt;
        struct completion               comp;
        struct dma_chan                 *dma;
        int                             gpmc_irq_fifo;
@@ -172,7 +167,6 @@ struct omap_nand_info {
        int                                     buf_len;
        struct gpmc_nand_regs           reg;
        /* fields specific for BCHx_HW ECC scheme */
-       bool                            is_elm_used;
        struct device                   *elm_dev;
        struct device_node              *of_node;
 };
@@ -1043,9 +1037,8 @@ static int omap_dev_ready(struct mtd_info *mtd)
        }
 }
 
-#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
- * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
+ * omap_enable_hwecc_bch - Program GPMC to perform BCH ECC calculation
  * @mtd: MTD device structure
  * @mode: Read/Write mode
  *
@@ -1056,50 +1049,73 @@ static int omap_dev_ready(struct mtd_info *mtd)
  * eccsize0 = 0  (no additional protected byte in spare area)
  * eccsize1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
  */
-static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
+static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 {
-       int nerrors;
+       unsigned int bch_type;
        unsigned int dev_width, nsectors;
        struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
                                                   mtd);
+       enum omap_ecc ecc_opt = info->ecc_opt;
        struct nand_chip *chip = mtd->priv;
        u32 val, wr_mode;
        unsigned int ecc_size1, ecc_size0;
 
-       /* Using wrapping mode 6 for writing */
-       wr_mode = BCH_WRAPMODE_6;
-
-       /*
-        * ECC engine enabled for valid ecc_size0 nibbles
-        * and disabled for ecc_size1 nibbles.
-        */
-       ecc_size0 = BCH_ECC_SIZE0;
-       ecc_size1 = BCH_ECC_SIZE1;
-
-       /* Perform ecc calculation on 512-byte sector */
-       nsectors = 1;
-
-       /* Update number of error correction */
-       nerrors = info->nand.ecc.strength;
-
-       /* Multi sector reading/writing for NAND flash with page size < 4096 */
-       if (info->is_elm_used && (mtd->writesize <= 4096)) {
+       /* GPMC configurations for calculating ECC */
+       switch (ecc_opt) {
+       case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+               bch_type = 0;
+               nsectors = 1;
+               if (mode == NAND_ECC_READ) {
+                       wr_mode   = BCH_WRAPMODE_6;
+                       ecc_size0 = BCH_ECC_SIZE0;
+                       ecc_size1 = BCH_ECC_SIZE1;
+               } else {
+                       wr_mode   = BCH_WRAPMODE_6;
+                       ecc_size0 = BCH_ECC_SIZE0;
+                       ecc_size1 = BCH_ECC_SIZE1;
+               }
+               break;
+       case OMAP_ECC_BCH4_CODE_HW:
+               bch_type = 0;
+               nsectors = chip->ecc.steps;
                if (mode == NAND_ECC_READ) {
-                       /* Using wrapping mode 1 for reading */
-                       wr_mode = BCH_WRAPMODE_1;
-
-                       /*
-                        * ECC engine enabled for ecc_size0 nibbles
-                        * and disabled for ecc_size1 nibbles.
-                        */
-                       ecc_size0 = (nerrors == 8) ?
-                               BCH8R_ECC_SIZE0 : BCH4R_ECC_SIZE0;
-                       ecc_size1 = (nerrors == 8) ?
-                               BCH8R_ECC_SIZE1 : BCH4R_ECC_SIZE1;
+                       wr_mode   = BCH_WRAPMODE_1;
+                       ecc_size0 = BCH4R_ECC_SIZE0;
+                       ecc_size1 = BCH4R_ECC_SIZE1;
+               } else {
+                       wr_mode   = BCH_WRAPMODE_6;
+                       ecc_size0 = BCH_ECC_SIZE0;
+                       ecc_size1 = BCH_ECC_SIZE1;
                }
-
-               /* Perform ecc calculation for one page (< 4096) */
-               nsectors = info->nand.ecc.steps;
+               break;
+       case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+               bch_type = 1;
+               nsectors = 1;
+               if (mode == NAND_ECC_READ) {
+                       wr_mode   = BCH_WRAPMODE_6;
+                       ecc_size0 = BCH_ECC_SIZE0;
+                       ecc_size1 = BCH_ECC_SIZE1;
+               } else {
+                       wr_mode   = BCH_WRAPMODE_6;
+                       ecc_size0 = BCH_ECC_SIZE0;
+                       ecc_size1 = BCH_ECC_SIZE1;
+               }
+               break;
+       case OMAP_ECC_BCH8_CODE_HW:
+               bch_type = 1;
+               nsectors = chip->ecc.steps;
+               if (mode == NAND_ECC_READ) {
+                       wr_mode   = BCH_WRAPMODE_1;
+                       ecc_size0 = BCH8R_ECC_SIZE0;
+                       ecc_size1 = BCH8R_ECC_SIZE1;
+               } else {
+                       wr_mode   = BCH_WRAPMODE_6;
+                       ecc_size0 = BCH_ECC_SIZE0;
+                       ecc_size1 = BCH_ECC_SIZE1;
+               }
+               break;
+       default:
+               return;
        }
 
        writel(ECC1, info->reg.gpmc_ecc_control);
@@ -1112,7 +1128,7 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 
        /* BCH configuration */
        val = ((1                        << 16) | /* enable BCH */
-              (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
+              (bch_type                 << 12) | /* BCH4/BCH8/BCH16 */
               (wr_mode                  <<  8) | /* wrap mode */
               (dev_width                <<  7) | /* bus width */
               (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
@@ -1124,132 +1140,40 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
        /* Clear ecc and enable bits */
        writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
-#endif
-
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
- * @mtd: MTD device structure
- * @dat: The pointer to data on which ecc is computed
- * @ecc_code: The ecc_code buffer
- */
-static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat,
-                                   u_char *ecc_code)
-{
-       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-                                                  mtd);
-       unsigned long nsectors, val1, val2;
-       int i;
-
-       nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
-
-       for (i = 0; i < nsectors; i++) {
 
-               /* Read hw-computed remainder */
-               val1 = readl(info->reg.gpmc_bch_result0[i]);
-               val2 = readl(info->reg.gpmc_bch_result1[i]);
-
-               /*
-                * Add constant polynomial to remainder, in order to get an ecc
-                * sequence of 0xFFs for a buffer filled with 0xFFs; and
-                * left-justify the resulting polynomial.
-                */
-               *ecc_code++ = 0x28 ^ ((val2 >> 12) & 0xFF);
-               *ecc_code++ = 0x13 ^ ((val2 >>  4) & 0xFF);
-               *ecc_code++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
-               *ecc_code++ = 0x39 ^ ((val1 >> 20) & 0xFF);
-               *ecc_code++ = 0x96 ^ ((val1 >> 12) & 0xFF);
-               *ecc_code++ = 0xac ^ ((val1 >> 4) & 0xFF);
-               *ecc_code++ = 0x7f ^ ((val1 & 0xF) << 4);
-       }
-
-       return 0;
-}
+static u8  bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f};
+static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
+                               0x97, 0x79, 0xe5, 0x24, 0xb5};
 
 /**
- * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes
- * @mtd: MTD device structure
- * @dat: The pointer to data on which ecc is computed
- * @ecc_code: The ecc_code buffer
- */
-static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
-                                   u_char *ecc_code)
-{
-       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-                                                  mtd);
-       unsigned long nsectors, val1, val2, val3, val4;
-       int i;
-
-       nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
-
-       for (i = 0; i < nsectors; i++) {
-
-               /* Read hw-computed remainder */
-               val1 = readl(info->reg.gpmc_bch_result0[i]);
-               val2 = readl(info->reg.gpmc_bch_result1[i]);
-               val3 = readl(info->reg.gpmc_bch_result2[i]);
-               val4 = readl(info->reg.gpmc_bch_result3[i]);
-
-               /*
-                * Add constant polynomial to remainder, in order to get an ecc
-                * sequence of 0xFFs for a buffer filled with 0xFFs.
-                */
-               *ecc_code++ = 0xef ^ (val4 & 0xFF);
-               *ecc_code++ = 0x51 ^ ((val3 >> 24) & 0xFF);
-               *ecc_code++ = 0x2e ^ ((val3 >> 16) & 0xFF);
-               *ecc_code++ = 0x09 ^ ((val3 >> 8) & 0xFF);
-               *ecc_code++ = 0xed ^ (val3 & 0xFF);
-               *ecc_code++ = 0x93 ^ ((val2 >> 24) & 0xFF);
-               *ecc_code++ = 0x9a ^ ((val2 >> 16) & 0xFF);
-               *ecc_code++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
-               *ecc_code++ = 0x97 ^ (val2 & 0xFF);
-               *ecc_code++ = 0x79 ^ ((val1 >> 24) & 0xFF);
-               *ecc_code++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
-               *ecc_code++ = 0x24 ^ ((val1 >> 8) & 0xFF);
-               *ecc_code++ = 0xb5 ^ (val1 & 0xFF);
-       }
-
-       return 0;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-/**
- * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
+ * omap_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:       MTD device structure
  * @dat:       The pointer to data on which ecc is computed
  * @ecc_code:  The ecc_code buffer
  *
  * Support calculating of BCH4/8 ecc vectors for the page
  */
-static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
-                                   u_char *ecc_code)
+static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
+                                       const u_char *dat, u_char *ecc_calc)
 {
        struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
                                                   mtd);
+       int eccbytes    = info->nand.ecc.bytes;
+       struct gpmc_nand_regs   *gpmc_regs = &info->reg;
+       u8 *ecc_code;
        unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4;
-       int i, eccbchtsel;
+       int i;
 
        nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
-       /*
-        * find BCH scheme used
-        * 0 -> BCH4
-        * 1 -> BCH8
-        */
-       eccbchtsel = ((readl(info->reg.gpmc_ecc_config) >> 12) & 0x3);
-
        for (i = 0; i < nsectors; i++) {
-
-               /* Read hw-computed remainder */
-               bch_val1 = readl(info->reg.gpmc_bch_result0[i]);
-               bch_val2 = readl(info->reg.gpmc_bch_result1[i]);
-               if (eccbchtsel) {
-                       bch_val3 = readl(info->reg.gpmc_bch_result2[i]);
-                       bch_val4 = readl(info->reg.gpmc_bch_result3[i]);
-               }
-
-               if (eccbchtsel) {
-                       /* BCH8 ecc scheme */
+               ecc_code = ecc_calc;
+               switch (info->ecc_opt) {
+               case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+               case OMAP_ECC_BCH8_CODE_HW:
+                       bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
+                       bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
+                       bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]);
+                       bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]);
                        *ecc_code++ = (bch_val4 & 0xFF);
                        *ecc_code++ = ((bch_val3 >> 24) & 0xFF);
                        *ecc_code++ = ((bch_val3 >> 16) & 0xFF);
@@ -1263,14 +1187,11 @@ static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
                        *ecc_code++ = ((bch_val1 >> 16) & 0xFF);
                        *ecc_code++ = ((bch_val1 >> 8) & 0xFF);
                        *ecc_code++ = (bch_val1 & 0xFF);
-                       /*
-                        * Setting 14th byte to zero to handle
-                        * erased page & maintain compatibility
-                        * with RBL
-                        */
-                       *ecc_code++ = 0x0;
-               } else {
-                       /* BCH4 ecc scheme */
+                       break;
+               case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+               case OMAP_ECC_BCH4_CODE_HW:
+                       bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
+                       bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
                        *ecc_code++ = ((bch_val2 >> 12) & 0xFF);
                        *ecc_code++ = ((bch_val2 >> 4) & 0xFF);
                        *ecc_code++ = ((bch_val2 & 0xF) << 4) |
@@ -1279,12 +1200,38 @@ static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
                        *ecc_code++ = ((bch_val1 >> 12) & 0xFF);
                        *ecc_code++ = ((bch_val1 >> 4) & 0xFF);
                        *ecc_code++ = ((bch_val1 & 0xF) << 4);
-                       /*
-                        * Setting 8th byte to zero to handle
-                        * erased page
-                        */
-                       *ecc_code++ = 0x0;
+                       break;
+               default:
+                       return -EINVAL;
                }
+
+               /* ECC scheme specific syndrome customizations */
+               switch (info->ecc_opt) {
+               case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+                       /* Add constant polynomial to remainder, so that
+                        * ECC of blank pages results in 0x0 on reading back */
+                       for (i = 0; i < eccbytes; i++)
+                               ecc_calc[i] ^= bch4_polynomial[i];
+                       break;
+               case OMAP_ECC_BCH4_CODE_HW:
+                       /* Set  8th ECC byte as 0x0 for ROM compatibility */
+                       ecc_calc[eccbytes - 1] = 0x0;
+                       break;
+               case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+                       /* Add constant polynomial to remainder, so that
+                        * ECC of blank pages results in 0x0 on reading back */
+                       for (i = 0; i < eccbytes; i++)
+                               ecc_calc[i] ^= bch8_polynomial[i];
+                       break;
+               case OMAP_ECC_BCH8_CODE_HW:
+                       /* Set 14th ECC byte as 0x0 for ROM compatibility */
+                       ecc_calc[eccbytes - 1] = 0x0;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+       ecc_calc += eccbytes;
        }
 
        return 0;
@@ -1329,6 +1276,7 @@ static int erased_sector_bitflips(u_char *data, u_char *oob,
        return flip_bits;
 }
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_elm_correct_data - corrects page data area in case error reported
  * @mtd:       MTD device structure
@@ -1337,55 +1285,46 @@ static int erased_sector_bitflips(u_char *data, u_char *oob,
  * @calc_ecc:  ecc read from HW ECC registers
  *
  * Calculated ecc vector reported as zero in case of non-error pages.
- * In case of error/erased pages non-zero error vector is reported.
- * In case of non-zero ecc vector, check read_ecc at fixed offset
- * (x = 13/7 in case of BCH8/4 == 0) to find page programmed or not.
- * To handle bit flips in this data, count the number of 0's in
- * read_ecc[x] and check if it greater than 4. If it is less, it is
- * programmed page, else erased page.
- *
- * 1. If page is erased, check with standard ecc vector (ecc vector
- * for erased page to find any bit flip). If check fails, bit flip
- * is present in erased page. Count the bit flips in erased page and
- * if it falls under correctable level, report page with 0xFF and
- * update the correctable bit information.
- * 2. If error is reported on programmed page, update elm error
- * vector and correct the page with ELM error correction routine.
- *
+ * In case of non-zero ecc vector, first filter out erased-pages, and
+ * then process data via ELM to detect bit-flips.
  */
 static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
                                u_char *read_ecc, u_char *calc_ecc)
 {
        struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
                        mtd);
+       struct nand_ecc_ctrl *ecc = &info->nand.ecc;
        int eccsteps = info->nand.ecc.steps;
        int i , j, stat = 0;
-       int eccsize, eccflag, ecc_vector_size;
+       int eccflag, actual_eccbytes;
        struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
        u_char *ecc_vec = calc_ecc;
        u_char *spare_ecc = read_ecc;
        u_char *erased_ecc_vec;
-       enum bch_ecc type;
+       u_char *buf;
+       int bitflip_count;
        bool is_error_reported = false;
+       u32 bit_pos, byte_pos, error_max, pos;
+       int err;
 
-       /* Initialize elm error vector to zero */
-       memset(err_vec, 0, sizeof(err_vec));
-
-       if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
-               type = BCH8_ECC;
-               erased_ecc_vec = bch8_vector;
-       } else {
-               type = BCH4_ECC;
+       switch (info->ecc_opt) {
+       case OMAP_ECC_BCH4_CODE_HW:
+               /* omit  7th ECC byte reserved for ROM code compatibility */
+               actual_eccbytes = ecc->bytes - 1;
                erased_ecc_vec = bch4_vector;
+               break;
+       case OMAP_ECC_BCH8_CODE_HW:
+               /* omit 14th ECC byte reserved for ROM code compatibility */
+               actual_eccbytes = ecc->bytes - 1;
+               erased_ecc_vec = bch8_vector;
+               break;
+       default:
+               pr_err("invalid driver configuration\n");
+               return -EINVAL;
        }
 
-       ecc_vector_size = info->nand.ecc.bytes;
-
-       /*
-        * Remove extra byte padding for BCH8 RBL
-        * compatibility and erased page handling
-        */
-       eccsize = ecc_vector_size - 1;
+       /* Initialize elm error vector to zero */
+       memset(err_vec, 0, sizeof(err_vec));
 
        for (i = 0; i < eccsteps ; i++) {
                eccflag = 0;    /* initialize eccflag */
@@ -1394,8 +1333,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
                 * Check any error reported,
                 * In case of error, non zero ecc reported.
                 */
-
-               for (j = 0; (j < eccsize); j++) {
+               for (j = 0; j < actual_eccbytes; j++) {
                        if (calc_ecc[j] != 0) {
                                eccflag = 1; /* non zero ecc, error present */
                                break;
@@ -1403,50 +1341,43 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
                }
 
                if (eccflag == 1) {
-                       /*
-                        * Set threshold to minimum of 4, half of ecc.strength/2
-                        * to allow max bit flip in byte to 4
-                        */
-                       unsigned int threshold = min_t(unsigned int, 4,
-                                       info->nand.ecc.strength / 2);
-
-                       /*
-                        * Check data area is programmed by counting
-                        * number of 0's at fixed offset in spare area.
-                        * Checking count of 0's against threshold.
-                        * In case programmed page expects at least threshold
-                        * zeros in byte.
-                        * If zeros are less than threshold for programmed page/
-                        * zeros are more than threshold erased page, either
-                        * case page reported as uncorrectable.
-                        */
-                       if (hweight8(~read_ecc[eccsize]) >= threshold) {
+                       if (memcmp(calc_ecc, erased_ecc_vec,
+                                               actual_eccbytes) == 0) {
                                /*
-                                * Update elm error vector as
-                                * data area is programmed
+                                * calc_ecc[] matches pattern for ECC(all 0xff)
+                                * so this is definitely an erased-page
                                 */
-                               err_vec[i].error_reported = true;
-                               is_error_reported = true;
                        } else {
-                               /* Error reported in erased page */
-                               int bitflip_count;
-                               u_char *buf = &data[info->nand.ecc.size * i];
-
-                               if (memcmp(calc_ecc, erased_ecc_vec, eccsize)) {
-                                       bitflip_count = erased_sector_bitflips(
-                                                       buf, read_ecc, info);
-
-                                       if (bitflip_count)
-                                               stat += bitflip_count;
-                                       else
-                                               return -EINVAL;
+                               buf = &data[info->nand.ecc.size * i];
+                               /*
+                                * count number of 0-bits in read_buf.
+                                * This check can be removed once a similar
+                                * check is introduced in generic NAND driver
+                                */
+                               bitflip_count = erased_sector_bitflips(
+                                               buf, read_ecc, info);
+                               if (bitflip_count) {
+                                       /*
+                                        * number of 0-bits within ECC limits
+                                        * So this may be an erased-page
+                                        */
+                                       stat += bitflip_count;
+                               } else {
+                                       /*
+                                        * Too many 0-bits. It may be a
+                                        * - programmed-page, OR
+                                        * - erased-page with many bit-flips
+                                        * So this page requires check by ELM
+                                        */
+                                       err_vec[i].error_reported = true;
+                                       is_error_reported = true;
                                }
                        }
                }
 
                /* Update the ecc vector */
-               calc_ecc += ecc_vector_size;
-               read_ecc += ecc_vector_size;
+               calc_ecc += ecc->bytes;
+               read_ecc += ecc->bytes;
        }
 
        /* Check if any error reported */
@@ -1456,23 +1387,26 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
        /* Decode BCH error using ELM module */
        elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec);
 
+       err = 0;
        for (i = 0; i < eccsteps; i++) {
-               if (err_vec[i].error_reported) {
+               if (err_vec[i].error_uncorrectable) {
+                       pr_err("nand: uncorrectable bit-flips found\n");
+                       err = -EBADMSG;
+               } else if (err_vec[i].error_reported) {
                        for (j = 0; j < err_vec[i].error_count; j++) {
-                               u32 bit_pos, byte_pos, error_max, pos;
-
-                               if (type == BCH8_ECC)
-                                       error_max = BCH8_ECC_MAX;
-                               else
-                                       error_max = BCH4_ECC_MAX;
-
-                               if (info->nand.ecc.strength == BCH8_MAX_ERROR)
-                                       pos = err_vec[i].error_loc[j];
-                               else
-                                       /* Add 4 to take care 4 bit padding */
+                               switch (info->ecc_opt) {
+                               case OMAP_ECC_BCH4_CODE_HW:
+                                       /* Add 4 bits to take care of padding */
                                        pos = err_vec[i].error_loc[j] +
                                                BCH4_BIT_PAD;
-
+                                       break;
+                               case OMAP_ECC_BCH8_CODE_HW:
+                                       pos = err_vec[i].error_loc[j];
+                                       break;
+                               default:
+                                       return -EINVAL;
+                               }
+                               error_max = (ecc->size + actual_eccbytes) * 8;
                                /* Calculate bit position of error */
                                bit_pos = pos % 8;
 
@@ -1480,13 +1414,22 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
                                byte_pos = (error_max - pos - 1) / 8;
 
                                if (pos < error_max) {
-                                       if (byte_pos < 512)
+                                       if (byte_pos < 512) {
+                                               pr_debug("bitflip@dat[%d]=%x\n",
+                                                    byte_pos, data[byte_pos]);
                                                data[byte_pos] ^= 1 << bit_pos;
-                                       else
+                                       } else {
+                                               pr_debug("bitflip@oob[%d]=%x\n",
+                                                       (byte_pos - 512),
+                                                    spare_ecc[byte_pos - 512]);
                                                spare_ecc[byte_pos - 512] ^=
                                                        1 << bit_pos;
+                                       }
+                               } else {
+                                       pr_err("invalid bit-flip @ %d:%d\n",
+                                                        byte_pos, bit_pos);
+                                       err = -EBADMSG;
                                }
-                               /* else, not interested to correct ecc */
                        }
                }
 
@@ -1494,16 +1437,11 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
                stat += err_vec[i].error_count;
 
                /* Update page data with sector size */
-               data += info->nand.ecc.size;
-               spare_ecc += ecc_vector_size;
+               data += ecc->size;
+               spare_ecc += ecc->bytes;
        }
 
-       for (i = 0; i < eccsteps; i++)
-               /* Return error if uncorrectable error present */
-               if (err_vec[i].error_uncorrectable)
-                       return -EINVAL;
-
-       return stat;
+       return (err) ? err : stat;
 }
 
 /**
@@ -1601,7 +1539,8 @@ static int is_elm_present(struct omap_nand_info *info,
                        struct device_node *elm_node, enum bch_ecc bch_type)
 {
        struct platform_device *pdev;
-       info->is_elm_used = false;
+       struct nand_ecc_ctrl *ecc = &info->nand.ecc;
+       int err;
        /* check whether elm-id is passed via DT */
        if (!elm_node) {
                pr_err("nand: error: ELM DT node not found\n");
@@ -1615,10 +1554,10 @@ static int is_elm_present(struct omap_nand_info *info,
        }
        /* ELM module available, now configure it */
        info->elm_dev = &pdev->dev;
-       if (elm_config(info->elm_dev, bch_type))
-               return -ENODEV;
-       info->is_elm_used = true;
-       return 0;
+       err = elm_config(info->elm_dev, bch_type,
+               (info->mtd.writesize / ecc->size), ecc->size, ecc->bytes);
+
+       return err;
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
@@ -1657,6 +1596,7 @@ static int omap_nand_probe(struct platform_device *pdev)
        info->gpmc_cs           = pdata->cs;
        info->reg               = pdata->reg;
        info->of_node           = pdata->of_node;
+       info->ecc_opt           = pdata->ecc_opt;
        mtd                     = &info->mtd;
        mtd->priv               = &info->nand;
        mtd->name               = dev_name(&pdev->dev);
@@ -1666,27 +1606,11 @@ static int omap_nand_probe(struct platform_device *pdev)
        nand_chip->options      |= NAND_SKIP_BBTSCAN;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               err = -EINVAL;
-               dev_err(&pdev->dev, "error getting memory resource\n");
-               goto return_error;
-       }
+       nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(nand_chip->IO_ADDR_R))
+               return PTR_ERR(nand_chip->IO_ADDR_R);
 
        info->phys_base = res->start;
-       info->mem_size = resource_size(res);
-
-       if (!devm_request_mem_region(&pdev->dev, info->phys_base,
-                               info->mem_size, pdev->dev.driver->name)) {
-               err = -EBUSY;
-               goto return_error;
-       }
-
-       nand_chip->IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
-                                               info->mem_size);
-       if (!nand_chip->IO_ADDR_R) {
-               err = -ENOMEM;
-               goto return_error;
-       }
 
        nand_chip->controller = &info->controller;
 
@@ -1812,7 +1736,7 @@ static int omap_nand_probe(struct platform_device *pdev)
        /* populate MTD interface based on ECC scheme */
        nand_chip->ecc.layout   = &omap_oobinfo;
        ecclayout               = &omap_oobinfo;
-       switch (pdata->ecc_opt) {
+       switch (info->ecc_opt) {
        case OMAP_ECC_HAM1_CODE_HW:
                pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
                nand_chip->ecc.mode             = NAND_ECC_HW;
@@ -1844,9 +1768,9 @@ static int omap_nand_probe(struct platform_device *pdev)
                nand_chip->ecc.size             = 512;
                nand_chip->ecc.bytes            = 7;
                nand_chip->ecc.strength         = 4;
-               nand_chip->ecc.hwctl            = omap3_enable_hwecc_bch;
+               nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = nand_bch_correct_data;
-               nand_chip->ecc.calculate        = omap3_calculate_ecc_bch4;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                /* define ECC layout */
                ecclayout->eccbytes             = nand_chip->ecc.bytes *
                                                        (mtd->writesize /
@@ -1884,9 +1808,9 @@ static int omap_nand_probe(struct platform_device *pdev)
                /* 14th bit is kept reserved for ROM-code compatibility */
                nand_chip->ecc.bytes            = 7 + 1;
                nand_chip->ecc.strength         = 4;
-               nand_chip->ecc.hwctl            = omap3_enable_hwecc_bch;
+               nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = omap_elm_correct_data;
-               nand_chip->ecc.calculate        = omap3_calculate_ecc_bch;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                nand_chip->ecc.read_page        = omap_read_page_bch;
                nand_chip->ecc.write_page       = omap_write_page_bch;
                /* define ECC layout */
@@ -1919,9 +1843,9 @@ static int omap_nand_probe(struct platform_device *pdev)
                nand_chip->ecc.size             = 512;
                nand_chip->ecc.bytes            = 13;
                nand_chip->ecc.strength         = 8;
-               nand_chip->ecc.hwctl            = omap3_enable_hwecc_bch;
+               nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = nand_bch_correct_data;
-               nand_chip->ecc.calculate        = omap3_calculate_ecc_bch8;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                /* define ECC layout */
                ecclayout->eccbytes             = nand_chip->ecc.bytes *
                                                        (mtd->writesize /
@@ -1960,9 +1884,9 @@ static int omap_nand_probe(struct platform_device *pdev)
                /* 14th bit is kept reserved for ROM-code compatibility */
                nand_chip->ecc.bytes            = 13 + 1;
                nand_chip->ecc.strength         = 8;
-               nand_chip->ecc.hwctl            = omap3_enable_hwecc_bch;
+               nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = omap_elm_correct_data;
-               nand_chip->ecc.calculate        = omap3_calculate_ecc_bch;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                nand_chip->ecc.read_page        = omap_read_page_bch;
                nand_chip->ecc.write_page       = omap_write_page_bch;
                /* This ECC scheme requires ELM H/W block */
index 90f871acb0efec737c918532bbdd350ca7969220..2c98f9da747111f28ff8e5b538ebf4c2de39ee93 100644 (file)
@@ -23,7 +23,6 @@
 #undef DEBUG
 
 #include <linux/slab.h>
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
index 2a7a0b27ac38dccc511abd296742a767ef183133..7588fe2c127f293329a7cb347969e567f59c436c 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <linux/platform_data/mtd-nand-pxa3xx.h>
 
-#define NAND_DEV_READY_TIMEOUT  50
 #define        CHIP_DELAY_TIMEOUT      (2 * HZ/10)
 #define NAND_STOP_DELAY                (2 * HZ/50)
 #define PAGE_CHUNK_SIZE                (2048)
@@ -1531,7 +1530,7 @@ KEEP_CONFIG:
        if (!ret) {
                dev_err(&info->pdev->dev,
                        "ECC strength %d at page size %d is not supported\n",
-                       chip->ecc_strength_ds, mtd->writesize);
+                       ecc_strength, mtd->writesize);
                return -ENODEV;
        }
 
index f0918e7411d99147fd67c26c48a8672cb237437f..79acbb8691b59c94131944f10d80c4103fbc9594 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/io.h>
index 8e1919b6f07449f007c0b1766f4ffcde5db4c0f1..093c29ac1a13f75e3dbbfbc354e62e9e3905c8e3 100644 (file)
@@ -13,7 +13,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
index 6547c84afc3a4bd6cde72302ddb1add10141b154..d945473c388201ee67cc5529fd984f5799792512 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/device.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
index 1de33b5d390358b58a2cbaaaf6991e08ebcc97db..635ee0027691eb771bc31eac771209b48987d8e2 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
-#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -3238,20 +3237,17 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
 /**
  * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
  * @param mtd          MTD device structure
- * @param buf          the databuffer to put/get data
  * @param len          number of bytes to read
+ * @param retlen       pointer to variable to store the number of read bytes
+ * @param buf          the databuffer to put/get data
  *
  * Read factory OTP info.
  */
-static int onenand_get_fact_prot_info(struct mtd_info *mtd,
-                       struct otp_info *buf, size_t len)
+static int onenand_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+                                     size_t *retlen, struct otp_info *buf)
 {
-       size_t retlen;
-       int ret;
-
-       ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_FACTORY);
-
-       return ret ? : retlen;
+       return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
+                               MTD_OTP_FACTORY);
 }
 
 /**
@@ -3273,20 +3269,17 @@ static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
 /**
  * onenand_get_user_prot_info - [MTD Interface] Read user OTP info
  * @param mtd          MTD device structure
- * @param buf          the databuffer to put/get data
+ * @param retlen       pointer to variable to store the number of read bytes
  * @param len          number of bytes to read
+ * @param buf          the databuffer to put/get data
  *
  * Read user OTP info.
  */
-static int onenand_get_user_prot_info(struct mtd_info *mtd,
-                       struct otp_info *buf, size_t len)
+static int onenand_get_user_prot_info(struct mtd_info *mtd, size_t len,
+                                     size_t *retlen, struct otp_info *buf)
 {
-       size_t retlen;
-       int ret;
-
-       ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_USER);
-
-       return ret ? : retlen;
+       return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
+                               MTD_OTP_USER);
 }
 
 /**
@@ -3995,11 +3988,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        /* Allocate buffers, if necessary */
        if (!this->page_buf) {
                this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
-               if (!this->page_buf) {
-                       printk(KERN_ERR "%s: Can't allocate page_buf\n",
-                               __func__);
+               if (!this->page_buf)
                        return -ENOMEM;
-               }
 #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
                this->verify_buf = kzalloc(mtd->writesize, GFP_KERNEL);
                if (!this->verify_buf) {
@@ -4012,8 +4002,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        if (!this->oob_buf) {
                this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
                if (!this->oob_buf) {
-                       printk(KERN_ERR "%s: Can't allocate oob_buf\n",
-                               __func__);
                        if (this->options & ONENAND_PAGEBUF_ALLOC) {
                                this->options &= ~ONENAND_PAGEBUF_ALLOC;
                                kfree(this->page_buf);
index df7400dd4df847b321bb1fdedbb5ac522e9c5b83..b1a792fd1c23682a63d313b0982ad1bfe666131c 100644 (file)
@@ -872,10 +872,8 @@ static int s3c_onenand_probe(struct platform_device *pdev)
 
        size = sizeof(struct mtd_info) + sizeof(struct onenand_chip);
        mtd = kzalloc(size, GFP_KERNEL);
-       if (!mtd) {
-               dev_err(&pdev->dev, "failed to allocate memory\n");
+       if (!mtd)
                return -ENOMEM;
-       }
 
        onenand = kzalloc(sizeof(struct s3c_onenand), GFP_KERNEL);
        if (!onenand) {
index 233b946e5d66d95a2cfbabb19985e5f8a75efb13..d1cbf26db2c0142d99f538efd543818a424a218d 100644 (file)
@@ -602,8 +602,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
        if (rc) {
                printk(KERN_ERR PREFIX "error writing '%s' at "
                        "0x%lx\n", part->mbd.mtd->name, addr);
-               if (rc)
-                       goto err;
+               goto err;
        }
        if (block == part->current_block)
                part->header_cache[offset + HEADER_MAP_OFFSET] = del;
@@ -675,8 +674,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
        if (rc) {
                printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
                                part->mbd.mtd->name, addr);
-               if (rc)
-                       goto err;
+               goto err;
        }
 
        part->sector_map[sector] = addr;
@@ -695,8 +693,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
        if (rc) {
                printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
                                part->mbd.mtd->name, addr);
-               if (rc)
-                       goto err;
+               goto err;
        }
        block->used_sectors++;
        block->free_sectors--;
index 4b8e89583f2a5d83f366515f4ed0fa5c4239361d..cf49c22673b903fac33d0b7c2289d26f28a7efe9 100644 (file)
@@ -59,15 +59,12 @@ static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
        struct attribute_group *attr_group;
        struct attribute **attributes;
        struct sm_sysfs_attribute *vendor_attribute;
+       char *vendor;
 
-       int vendor_len = strnlen(ftl->cis_buffer + SM_CIS_VENDOR_OFFSET,
-                                       SM_SMALL_PAGE - SM_CIS_VENDOR_OFFSET);
-
-       char *vendor = kmalloc(vendor_len, GFP_KERNEL);
+       vendor = kstrndup(ftl->cis_buffer + SM_CIS_VENDOR_OFFSET,
+                         SM_SMALL_PAGE - SM_CIS_VENDOR_OFFSET, GFP_KERNEL);
        if (!vendor)
                goto error1;
-       memcpy(vendor, ftl->cis_buffer + SM_CIS_VENDOR_OFFSET, vendor_len);
-       vendor[vendor_len] = 0;
 
        /* Initialize sysfs attributes */
        vendor_attribute =
@@ -78,7 +75,7 @@ static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
        sysfs_attr_init(&vendor_attribute->dev_attr.attr);
 
        vendor_attribute->data = vendor;
-       vendor_attribute->len = vendor_len;
+       vendor_attribute->len = strlen(vendor);
        vendor_attribute->dev_attr.attr.name = "vendor";
        vendor_attribute->dev_attr.attr.mode = S_IRUGO;
        vendor_attribute->dev_attr.show = sm_attr_show;
index c818a63532e774035e7f81d748622c0b21810c2a..111ee46a7428e2d8ad384973bdc03e2cb2305122 100644 (file)
@@ -1,6 +1,5 @@
 #define pr_fmt(fmt) "mtd_test: " fmt
 
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/printk.h>
index 36663af56d89d47dd8cf36181e50f3b0ec75740f..f0855ce08ed9ac81c1e1460ae04d10ddc312967e 100644 (file)
@@ -87,4 +87,20 @@ config MTD_UBI_GLUEBI
           work on top of UBI. Do not enable this unless you use legacy
           software.
 
+config MTD_UBI_BLOCK
+       bool "Read-only block devices on top of UBI volumes"
+       default n
+       depends on BLOCK
+       help
+          This option enables read-only UBI block devices support. UBI block
+          devices will be layered on top of UBI volumes, which means that the
+          UBI driver will transparently handle things like bad eraseblocks and
+          bit-flips. You can put any block-oriented file system on top of UBI
+          volumes in read-only mode (e.g., ext4), but it is probably most
+          practical for read-only file systems, like squashfs.
+
+          When selected, this feature will be built in the UBI driver.
+
+          If in doubt, say "N".
+
 endif # MTD_UBI
index b46b0c97858161022c10d3b8f8ee167a33c6b7c0..4e3c3d70d8c3f1983f277388d28756e68f2c1e9c 100644 (file)
@@ -3,5 +3,6 @@ obj-$(CONFIG_MTD_UBI) += ubi.o
 ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o
 ubi-y += misc.o debug.o
 ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o
+ubi-$(CONFIG_MTD_UBI_BLOCK) += block.o
 
 obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
new file mode 100644 (file)
index 0000000..7ff473c
--- /dev/null
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2014 Ezequiel Garcia
+ * Copyright (c) 2011 Free Electrons
+ *
+ * Driver parameter handling strongly based on drivers/mtd/ubi/build.c
+ *   Copyright (c) International Business Machines Corp., 2006
+ *   Copyright (c) Nokia Corporation, 2007
+ *   Authors: Artem Bityutskiy, Frank Haverkamp
+ *
+ * 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 in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ */
+
+/*
+ * Read-only block devices on top of UBI volumes
+ *
+ * A simple implementation to allow a block device to be layered on top of a
+ * UBI volume. The implementation is provided by creating a static 1-to-1
+ * mapping between the block device and the UBI volume.
+ *
+ * The addressed byte is obtained from the addressed block sector, which is
+ * mapped linearly into the corresponding LEB:
+ *
+ *   LEB number = addressed byte / LEB size
+ *
+ * This feature is compiled in the UBI core, and adds a 'block' parameter
+ * to allow early creation of block devices on top of UBI volumes. Runtime
+ * block creation/removal for UBI volumes is provided through two UBI ioctls:
+ * UBI_IOCVOLCRBLK and UBI_IOCVOLRMBLK.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mtd/ubi.h>
+#include <linux/workqueue.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <asm/div64.h>
+
+#include "ubi-media.h"
+#include "ubi.h"
+
+/* Maximum number of supported devices */
+#define UBIBLOCK_MAX_DEVICES 32
+
+/* Maximum length of the 'block=' parameter */
+#define UBIBLOCK_PARAM_LEN 63
+
+/* Maximum number of comma-separated items in the 'block=' parameter */
+#define UBIBLOCK_PARAM_COUNT 2
+
+struct ubiblock_param {
+       int ubi_num;
+       int vol_id;
+       char name[UBIBLOCK_PARAM_LEN+1];
+};
+
+/* Numbers of elements set in the @ubiblock_param array */
+static int ubiblock_devs __initdata;
+
+/* MTD devices specification parameters */
+static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES] __initdata;
+
+struct ubiblock {
+       struct ubi_volume_desc *desc;
+       int ubi_num;
+       int vol_id;
+       int refcnt;
+       int leb_size;
+
+       struct gendisk *gd;
+       struct request_queue *rq;
+
+       struct workqueue_struct *wq;
+       struct work_struct work;
+
+       struct mutex dev_mutex;
+       spinlock_t queue_lock;
+       struct list_head list;
+};
+
+/* Linked list of all ubiblock instances */
+static LIST_HEAD(ubiblock_devices);
+static DEFINE_MUTEX(devices_mutex);
+static int ubiblock_major;
+
+static int __init ubiblock_set_param(const char *val,
+                                    const struct kernel_param *kp)
+{
+       int i, ret;
+       size_t len;
+       struct ubiblock_param *param;
+       char buf[UBIBLOCK_PARAM_LEN];
+       char *pbuf = &buf[0];
+       char *tokens[UBIBLOCK_PARAM_COUNT];
+
+       if (!val)
+               return -EINVAL;
+
+       len = strnlen(val, UBIBLOCK_PARAM_LEN);
+       if (len == 0) {
+               ubi_warn("block: empty 'block=' parameter - ignored\n");
+               return 0;
+       }
+
+       if (len == UBIBLOCK_PARAM_LEN) {
+               ubi_err("block: parameter \"%s\" is too long, max. is %d\n",
+                       val, UBIBLOCK_PARAM_LEN);
+               return -EINVAL;
+       }
+
+       strcpy(buf, val);
+
+       /* Get rid of the final newline */
+       if (buf[len - 1] == '\n')
+               buf[len - 1] = '\0';
+
+       for (i = 0; i < UBIBLOCK_PARAM_COUNT; i++)
+               tokens[i] = strsep(&pbuf, ",");
+
+       param = &ubiblock_param[ubiblock_devs];
+       if (tokens[1]) {
+               /* Two parameters: can be 'ubi, vol_id' or 'ubi, vol_name' */
+               ret = kstrtoint(tokens[0], 10, &param->ubi_num);
+               if (ret < 0)
+                       return -EINVAL;
+
+               /* Second param can be a number or a name */
+               ret = kstrtoint(tokens[1], 10, &param->vol_id);
+               if (ret < 0) {
+                       param->vol_id = -1;
+                       strcpy(param->name, tokens[1]);
+               }
+
+       } else {
+               /* One parameter: must be device path */
+               strcpy(param->name, tokens[0]);
+               param->ubi_num = -1;
+               param->vol_id = -1;
+       }
+
+       ubiblock_devs++;
+
+       return 0;
+}
+
+static struct kernel_param_ops ubiblock_param_ops = {
+       .set    = ubiblock_set_param,
+};
+module_param_cb(block, &ubiblock_param_ops, NULL, 0);
+MODULE_PARM_DESC(block, "Attach block devices to UBI volumes. Parameter format: block=<path|dev,num|dev,name>.\n"
+                       "Multiple \"block\" parameters may be specified.\n"
+                       "UBI volumes may be specified by their number, name, or path to the device node.\n"
+                       "Examples\n"
+                       "Using the UBI volume path:\n"
+                       "ubi.block=/dev/ubi0_0\n"
+                       "Using the UBI device, and the volume name:\n"
+                       "ubi.block=0,rootfs\n"
+                       "Using both UBI device number and UBI volume number:\n"
+                       "ubi.block=0,0\n");
+
+static struct ubiblock *find_dev_nolock(int ubi_num, int vol_id)
+{
+       struct ubiblock *dev;
+
+       list_for_each_entry(dev, &ubiblock_devices, list)
+               if (dev->ubi_num == ubi_num && dev->vol_id == vol_id)
+                       return dev;
+       return NULL;
+}
+
+static int ubiblock_read_to_buf(struct ubiblock *dev, char *buffer,
+                               int leb, int offset, int len)
+{
+       int ret;
+
+       ret = ubi_read(dev->desc, leb, buffer, offset, len);
+       if (ret) {
+               ubi_err("%s ubi_read error %d",
+                       dev->gd->disk_name, ret);
+               return ret;
+       }
+       return 0;
+}
+
+static int ubiblock_read(struct ubiblock *dev, char *buffer,
+                        sector_t sec, int len)
+{
+       int ret, leb, offset;
+       int bytes_left = len;
+       int to_read = len;
+       u64 pos = sec << 9;
+
+       /* Get LEB:offset address to read from */
+       offset = do_div(pos, dev->leb_size);
+       leb = pos;
+
+       while (bytes_left) {
+               /*
+                * We can only read one LEB at a time. Therefore if the read
+                * length is larger than one LEB size, we split the operation.
+                */
+               if (offset + to_read > dev->leb_size)
+                       to_read = dev->leb_size - offset;
+
+               ret = ubiblock_read_to_buf(dev, buffer, leb, offset, to_read);
+               if (ret)
+                       return ret;
+
+               buffer += to_read;
+               bytes_left -= to_read;
+               to_read = bytes_left;
+               leb += 1;
+               offset = 0;
+       }
+       return 0;
+}
+
+static int do_ubiblock_request(struct ubiblock *dev, struct request *req)
+{
+       int len, ret;
+       sector_t sec;
+
+       if (req->cmd_type != REQ_TYPE_FS)
+               return -EIO;
+
+       if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
+           get_capacity(req->rq_disk))
+               return -EIO;
+
+       if (rq_data_dir(req) != READ)
+               return -ENOSYS; /* Write not implemented */
+
+       sec = blk_rq_pos(req);
+       len = blk_rq_cur_bytes(req);
+
+       /*
+        * Let's prevent the device from being removed while we're doing I/O
+        * work. Notice that this means we serialize all the I/O operations,
+        * but it's probably of no impact given the NAND core serializes
+        * flash access anyway.
+        */
+       mutex_lock(&dev->dev_mutex);
+       ret = ubiblock_read(dev, req->buffer, sec, len);
+       mutex_unlock(&dev->dev_mutex);
+
+       return ret;
+}
+
+static void ubiblock_do_work(struct work_struct *work)
+{
+       struct ubiblock *dev =
+               container_of(work, struct ubiblock, work);
+       struct request_queue *rq = dev->rq;
+       struct request *req;
+       int res;
+
+       spin_lock_irq(rq->queue_lock);
+
+       req = blk_fetch_request(rq);
+       while (req) {
+
+               spin_unlock_irq(rq->queue_lock);
+               res = do_ubiblock_request(dev, req);
+               spin_lock_irq(rq->queue_lock);
+
+               /*
+                * If we're done with this request,
+                * we need to fetch a new one
+                */
+               if (!__blk_end_request_cur(req, res))
+                       req = blk_fetch_request(rq);
+       }
+
+       spin_unlock_irq(rq->queue_lock);
+}
+
+static void ubiblock_request(struct request_queue *rq)
+{
+       struct ubiblock *dev;
+       struct request *req;
+
+       dev = rq->queuedata;
+
+       if (!dev)
+               while ((req = blk_fetch_request(rq)) != NULL)
+                       __blk_end_request_all(req, -ENODEV);
+       else
+               queue_work(dev->wq, &dev->work);
+}
+
+static int ubiblock_open(struct block_device *bdev, fmode_t mode)
+{
+       struct ubiblock *dev = bdev->bd_disk->private_data;
+       int ret;
+
+       mutex_lock(&dev->dev_mutex);
+       if (dev->refcnt > 0) {
+               /*
+                * The volume is already open, just increase the reference
+                * counter.
+                */
+               goto out_done;
+       }
+
+       /*
+        * We want users to be aware they should only mount us as read-only.
+        * It's just a paranoid check, as write requests will get rejected
+        * in any case.
+        */
+       if (mode & FMODE_WRITE) {
+               ret = -EPERM;
+               goto out_unlock;
+       }
+
+       dev->desc = ubi_open_volume(dev->ubi_num, dev->vol_id, UBI_READONLY);
+       if (IS_ERR(dev->desc)) {
+               ubi_err("%s failed to open ubi volume %d_%d",
+                       dev->gd->disk_name, dev->ubi_num, dev->vol_id);
+               ret = PTR_ERR(dev->desc);
+               dev->desc = NULL;
+               goto out_unlock;
+       }
+
+out_done:
+       dev->refcnt++;
+       mutex_unlock(&dev->dev_mutex);
+       return 0;
+
+out_unlock:
+       mutex_unlock(&dev->dev_mutex);
+       return ret;
+}
+
+static void ubiblock_release(struct gendisk *gd, fmode_t mode)
+{
+       struct ubiblock *dev = gd->private_data;
+
+       mutex_lock(&dev->dev_mutex);
+       dev->refcnt--;
+       if (dev->refcnt == 0) {
+               ubi_close_volume(dev->desc);
+               dev->desc = NULL;
+       }
+       mutex_unlock(&dev->dev_mutex);
+}
+
+static int ubiblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+       /* Some tools might require this information */
+       geo->heads = 1;
+       geo->cylinders = 1;
+       geo->sectors = get_capacity(bdev->bd_disk);
+       geo->start = 0;
+       return 0;
+}
+
+static const struct block_device_operations ubiblock_ops = {
+       .owner = THIS_MODULE,
+       .open = ubiblock_open,
+       .release = ubiblock_release,
+       .getgeo = ubiblock_getgeo,
+};
+
+int ubiblock_create(struct ubi_volume_info *vi)
+{
+       struct ubiblock *dev;
+       struct gendisk *gd;
+       int disk_capacity;
+       int ret;
+
+       /* Check that the volume isn't already handled */
+       mutex_lock(&devices_mutex);
+       if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
+               mutex_unlock(&devices_mutex);
+               return -EEXIST;
+       }
+       mutex_unlock(&devices_mutex);
+
+       dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       mutex_init(&dev->dev_mutex);
+
+       dev->ubi_num = vi->ubi_num;
+       dev->vol_id = vi->vol_id;
+       dev->leb_size = vi->usable_leb_size;
+
+       /* Initialize the gendisk of this ubiblock device */
+       gd = alloc_disk(1);
+       if (!gd) {
+               ubi_err("block: alloc_disk failed");
+               ret = -ENODEV;
+               goto out_free_dev;
+       }
+
+       gd->fops = &ubiblock_ops;
+       gd->major = ubiblock_major;
+       gd->first_minor = dev->ubi_num * UBI_MAX_VOLUMES + dev->vol_id;
+       gd->private_data = dev;
+       sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
+       disk_capacity = (vi->size * vi->usable_leb_size) >> 9;
+       set_capacity(gd, disk_capacity);
+       dev->gd = gd;
+
+       spin_lock_init(&dev->queue_lock);
+       dev->rq = blk_init_queue(ubiblock_request, &dev->queue_lock);
+       if (!dev->rq) {
+               ubi_err("block: blk_init_queue failed");
+               ret = -ENODEV;
+               goto out_put_disk;
+       }
+
+       dev->rq->queuedata = dev;
+       dev->gd->queue = dev->rq;
+
+       /*
+        * Create one workqueue per volume (per registered block device).
+        * Rembember workqueues are cheap, they're not threads.
+        */
+       dev->wq = alloc_workqueue(gd->disk_name, 0, 0);
+       if (!dev->wq)
+               goto out_free_queue;
+       INIT_WORK(&dev->work, ubiblock_do_work);
+
+       mutex_lock(&devices_mutex);
+       list_add_tail(&dev->list, &ubiblock_devices);
+       mutex_unlock(&devices_mutex);
+
+       /* Must be the last step: anyone can call file ops from now on */
+       add_disk(dev->gd);
+       ubi_msg("%s created from ubi%d:%d(%s)",
+               dev->gd->disk_name, dev->ubi_num, dev->vol_id, vi->name);
+       return 0;
+
+out_free_queue:
+       blk_cleanup_queue(dev->rq);
+out_put_disk:
+       put_disk(dev->gd);
+out_free_dev:
+       kfree(dev);
+
+       return ret;
+}
+
+static void ubiblock_cleanup(struct ubiblock *dev)
+{
+       del_gendisk(dev->gd);
+       blk_cleanup_queue(dev->rq);
+       ubi_msg("%s released", dev->gd->disk_name);
+       put_disk(dev->gd);
+}
+
+int ubiblock_remove(struct ubi_volume_info *vi)
+{
+       struct ubiblock *dev;
+
+       mutex_lock(&devices_mutex);
+       dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
+       if (!dev) {
+               mutex_unlock(&devices_mutex);
+               return -ENODEV;
+       }
+
+       /* Found a device, let's lock it so we can check if it's busy */
+       mutex_lock(&dev->dev_mutex);
+       if (dev->refcnt > 0) {
+               mutex_unlock(&dev->dev_mutex);
+               mutex_unlock(&devices_mutex);
+               return -EBUSY;
+       }
+
+       /* Remove from device list */
+       list_del(&dev->list);
+       mutex_unlock(&devices_mutex);
+
+       /* Flush pending work and stop this workqueue */
+       destroy_workqueue(dev->wq);
+
+       ubiblock_cleanup(dev);
+       mutex_unlock(&dev->dev_mutex);
+       kfree(dev);
+       return 0;
+}
+
+static void ubiblock_resize(struct ubi_volume_info *vi)
+{
+       struct ubiblock *dev;
+       int disk_capacity;
+
+       /*
+        * Need to lock the device list until we stop using the device,
+        * otherwise the device struct might get released in
+        * 'ubiblock_remove()'.
+        */
+       mutex_lock(&devices_mutex);
+       dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
+       if (!dev) {
+               mutex_unlock(&devices_mutex);
+               return;
+       }
+
+       mutex_lock(&dev->dev_mutex);
+       disk_capacity = (vi->size * vi->usable_leb_size) >> 9;
+       set_capacity(dev->gd, disk_capacity);
+       ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size);
+       mutex_unlock(&dev->dev_mutex);
+       mutex_unlock(&devices_mutex);
+}
+
+static int ubiblock_notify(struct notifier_block *nb,
+                        unsigned long notification_type, void *ns_ptr)
+{
+       struct ubi_notification *nt = ns_ptr;
+
+       switch (notification_type) {
+       case UBI_VOLUME_ADDED:
+               /*
+                * We want to enforce explicit block device creation for
+                * volumes, so when a volume is added we do nothing.
+                */
+               break;
+       case UBI_VOLUME_REMOVED:
+               ubiblock_remove(&nt->vi);
+               break;
+       case UBI_VOLUME_RESIZED:
+               ubiblock_resize(&nt->vi);
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block ubiblock_notifier = {
+       .notifier_call = ubiblock_notify,
+};
+
+static struct ubi_volume_desc * __init
+open_volume_desc(const char *name, int ubi_num, int vol_id)
+{
+       if (ubi_num == -1)
+               /* No ubi num, name must be a vol device path */
+               return ubi_open_volume_path(name, UBI_READONLY);
+       else if (vol_id == -1)
+               /* No vol_id, must be vol_name */
+               return ubi_open_volume_nm(ubi_num, name, UBI_READONLY);
+       else
+               return ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
+}
+
+static int __init ubiblock_create_from_param(void)
+{
+       int i, ret;
+       struct ubiblock_param *p;
+       struct ubi_volume_desc *desc;
+       struct ubi_volume_info vi;
+
+       for (i = 0; i < ubiblock_devs; i++) {
+               p = &ubiblock_param[i];
+
+               desc = open_volume_desc(p->name, p->ubi_num, p->vol_id);
+               if (IS_ERR(desc)) {
+                       ubi_err("block: can't open volume, err=%ld\n",
+                               PTR_ERR(desc));
+                       ret = PTR_ERR(desc);
+                       break;
+               }
+
+               ubi_get_volume_info(desc, &vi);
+               ubi_close_volume(desc);
+
+               ret = ubiblock_create(&vi);
+               if (ret) {
+                       ubi_err("block: can't add '%s' volume, err=%d\n",
+                               vi.name, ret);
+                       break;
+               }
+       }
+       return ret;
+}
+
+static void ubiblock_remove_all(void)
+{
+       struct ubiblock *next;
+       struct ubiblock *dev;
+
+       list_for_each_entry_safe(dev, next, &ubiblock_devices, list) {
+               /* Flush pending work and stop workqueue */
+               destroy_workqueue(dev->wq);
+               /* The module is being forcefully removed */
+               WARN_ON(dev->desc);
+               /* Remove from device list */
+               list_del(&dev->list);
+               ubiblock_cleanup(dev);
+               kfree(dev);
+       }
+}
+
+int __init ubiblock_init(void)
+{
+       int ret;
+
+       ubiblock_major = register_blkdev(0, "ubiblock");
+       if (ubiblock_major < 0)
+               return ubiblock_major;
+
+       /* Attach block devices from 'block=' module param */
+       ret = ubiblock_create_from_param();
+       if (ret)
+               goto err_remove;
+
+       /*
+        * Block devices are only created upon user requests, so we ignore
+        * existing volumes.
+        */
+       ret = ubi_register_volume_notifier(&ubiblock_notifier, 1);
+       if (ret)
+               goto err_unreg;
+       return 0;
+
+err_unreg:
+       unregister_blkdev(ubiblock_major, "ubiblock");
+err_remove:
+       ubiblock_remove_all();
+       return ret;
+}
+
+void __exit ubiblock_exit(void)
+{
+       ubi_unregister_volume_notifier(&ubiblock_notifier);
+       ubiblock_remove_all();
+       unregister_blkdev(ubiblock_major, "ubiblock");
+}
index 57deae961429d0a161de940072cbc24dc984a008..6e30a3c280d0ffb6c5ad2f4165a5b946843063b7 100644 (file)
@@ -1298,6 +1298,15 @@ static int __init ubi_init(void)
                }
        }
 
+       err = ubiblock_init();
+       if (err) {
+               ubi_err("block: cannot initialize, error %d", err);
+
+               /* See comment above re-ubi_is_module(). */
+               if (ubi_is_module())
+                       goto out_detach;
+       }
+
        return 0;
 
 out_detach:
@@ -1326,6 +1335,8 @@ static void __exit ubi_exit(void)
 {
        int i;
 
+       ubiblock_exit();
+
        for (i = 0; i < UBI_MAX_DEVICES; i++)
                if (ubi_devices[i]) {
                        mutex_lock(&ubi_devices_mutex);
index 8ca49f2043e4b8a7fe41109129de5760995b59d4..f54562a5998e74dfb8e24fe5a01be80c375c7508 100644 (file)
@@ -561,6 +561,26 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
                break;
        }
 
+       /* Create a R/O block device on top of the UBI volume */
+       case UBI_IOCVOLCRBLK:
+       {
+               struct ubi_volume_info vi;
+
+               ubi_get_volume_info(desc, &vi);
+               err = ubiblock_create(&vi);
+               break;
+       }
+
+       /* Remove the R/O block device */
+       case UBI_IOCVOLRMBLK:
+       {
+               struct ubi_volume_info vi;
+
+               ubi_get_volume_info(desc, &vi);
+               err = ubiblock_remove(&vi);
+               break;
+       }
+
        default:
                err = -ENOTTY;
                break;
index 8ea6297a208f9f8ae79fb10fe6b8d967828f4d36..7bf416329c1973ee58b6c3511f90c8aecc5a997a 100644 (file)
@@ -22,7 +22,6 @@
 #ifndef __UBI_UBI_H__
 #define __UBI_UBI_H__
 
-#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
@@ -864,6 +863,26 @@ int ubi_update_fastmap(struct ubi_device *ubi);
 int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
                     int fm_anchor);
 
+/* block.c */
+#ifdef CONFIG_MTD_UBI_BLOCK
+int ubiblock_init(void);
+void ubiblock_exit(void);
+int ubiblock_create(struct ubi_volume_info *vi);
+int ubiblock_remove(struct ubi_volume_info *vi);
+#else
+static inline int ubiblock_init(void) { return 0; }
+static inline void ubiblock_exit(void) {}
+static inline int ubiblock_create(struct ubi_volume_info *vi)
+{
+       return -ENOSYS;
+}
+static inline int ubiblock_remove(struct ubi_volume_info *vi)
+{
+       return -ENOSYS;
+}
+#endif
+
+
 /*
  * ubi_rb_for_each_entry - walk an RB-tree.
  * @rb: a pointer to type 'struct rb_node' to use as a loop counter
index 4557a142c7525b1405a70a8b4aff0db52058e082..f72d19b7e5d29901471784f01e6b27909c772395 100644 (file)
@@ -2196,64 +2196,65 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
                                        struct device_node *prev)
 {
        struct device_node *endpoint;
-       struct device_node *port = NULL;
+       struct device_node *port;
 
        if (!parent)
                return NULL;
 
+       /*
+        * Start by locating the port node. If no previous endpoint is specified
+        * search for the first port node, otherwise get the previous endpoint
+        * parent port node.
+        */
        if (!prev) {
                struct device_node *node;
-               /*
-                * It's the first call, we have to find a port subnode
-                * within this node or within an optional 'ports' node.
-                */
+
                node = of_get_child_by_name(parent, "ports");
                if (node)
                        parent = node;
 
                port = of_get_child_by_name(parent, "port");
-
-               if (port) {
-                       /* Found a port, get an endpoint. */
-                       endpoint = of_get_next_child(port, NULL);
-                       of_node_put(port);
-               } else {
-                       endpoint = NULL;
-               }
-
-               if (!endpoint)
-                       pr_err("%s(): no endpoint nodes specified for %s\n",
-                              __func__, parent->full_name);
                of_node_put(node);
 
-               return endpoint;
-       }
-
-       port = of_get_parent(prev);
-       if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n",
-                     __func__, prev->full_name))
-               return NULL;
+               if (!port) {
+                       pr_err("%s(): no port node found in %s\n",
+                              __func__, parent->full_name);
+                       return NULL;
+               }
+       } else {
+               port = of_get_parent(prev);
+               if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n",
+                             __func__, prev->full_name))
+                       return NULL;
 
-       /* Avoid dropping prev node refcount to 0. */
-       of_node_get(prev);
-       endpoint = of_get_next_child(port, prev);
-       if (endpoint) {
-               of_node_put(port);
-               return endpoint;
+               /*
+                * Avoid dropping prev node refcount to 0 when getting the next
+                * child below.
+                */
+               of_node_get(prev);
        }
 
-       /* No more endpoints under this port, try the next one. */
-       do {
-               port = of_get_next_child(parent, port);
-               if (!port)
-                       return NULL;
-       } while (of_node_cmp(port->name, "port"));
+       while (1) {
+               /*
+                * Now that we have a port node, get the next endpoint by
+                * getting the next child. If the previous endpoint is NULL this
+                * will return the first child.
+                */
+               endpoint = of_get_next_child(port, prev);
+               if (endpoint) {
+                       of_node_put(port);
+                       return endpoint;
+               }
 
-       /* Pick up the first endpoint in this port. */
-       endpoint = of_get_next_child(port, NULL);
-       of_node_put(port);
+               /* No more endpoints under this port, try the next one. */
+               prev = NULL;
 
-       return endpoint;
+               do {
+                       port = of_get_next_child(parent, port);
+                       if (!port)
+                               return NULL;
+               } while (of_node_cmp(port->name, "port"));
+       }
 }
 EXPORT_SYMBOL(of_graph_get_next_endpoint);
 
index a27ec94877e4de2efbdb84db2427672e2e809bd8..b7361ed705375e6e49dbfde3bd9d7fce4f0c97a2 100644 (file)
@@ -49,6 +49,40 @@ int of_get_nand_ecc_mode(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_get_nand_ecc_mode);
 
+/**
+ * of_get_nand_ecc_step_size - Get ECC step size associated to
+ * the required ECC strength (see below).
+ * @np:        Pointer to the given device_node
+ *
+ * return the ECC step size, or errno in error case.
+ */
+int of_get_nand_ecc_step_size(struct device_node *np)
+{
+       int ret;
+       u32 val;
+
+       ret = of_property_read_u32(np, "nand-ecc-step-size", &val);
+       return ret ? ret : val;
+}
+EXPORT_SYMBOL_GPL(of_get_nand_ecc_step_size);
+
+/**
+ * of_get_nand_ecc_strength - Get required ECC strength over the
+ * correspnding step size as defined by 'nand-ecc-size'
+ * @np:        Pointer to the given device_node
+ *
+ * return the ECC strength, or errno in error case.
+ */
+int of_get_nand_ecc_strength(struct device_node *np)
+{
+       int ret;
+       u32 val;
+
+       ret = of_property_read_u32(np, "nand-ecc-strength", &val);
+       return ret ? ret : val;
+}
+EXPORT_SYMBOL_GPL(of_get_nand_ecc_strength);
+
 /**
  * of_get_nand_bus_width - Get nand bus witdh for given device_node
  * @np:        Pointer to the given device_node
index 76f1c9357f39d2a285c6bd8af17eb2c4aac5dcad..9559829fb234de4088602ca6e942e8dd11bd43ff 100644 (file)
@@ -108,8 +108,8 @@ static void nmi_timer_shutdown(void)
        struct perf_event *event;
        int cpu;
 
-       get_online_cpus();
-       unregister_cpu_notifier(&nmi_timer_cpu_nb);
+       cpu_notifier_register_begin();
+       __unregister_cpu_notifier(&nmi_timer_cpu_nb);
        for_each_possible_cpu(cpu) {
                event = per_cpu(nmi_timer_events, cpu);
                if (!event)
@@ -119,7 +119,7 @@ static void nmi_timer_shutdown(void)
                perf_event_release_kernel(event);
        }
 
-       put_online_cpus();
+       cpu_notifier_register_done();
 }
 
 static int nmi_timer_setup(void)
@@ -132,20 +132,23 @@ static int nmi_timer_setup(void)
        do_div(period, HZ);
        nmi_timer_attr.sample_period = period;
 
-       get_online_cpus();
-       err = register_cpu_notifier(&nmi_timer_cpu_nb);
+       cpu_notifier_register_begin();
+       err = __register_cpu_notifier(&nmi_timer_cpu_nb);
        if (err)
                goto out;
+
        /* can't attach events to offline cpus: */
        for_each_online_cpu(cpu) {
                err = nmi_timer_start_cpu(cpu);
-               if (err)
-                       break;
+               if (err) {
+                       cpu_notifier_register_done();
+                       nmi_timer_shutdown();
+                       return err;
+               }
        }
-       if (err)
-               nmi_timer_shutdown();
+
 out:
-       put_online_cpus();
+       cpu_notifier_register_done();
        return err;
 }
 
index 7dd62fa9d0bdd8c64554ff3f4e737bcee3b2c787..396c200b9ddb3b6d534e571f1827819e221c65e8 100644 (file)
@@ -116,11 +116,11 @@ static void pci_slot_release(struct kobject *kobj)
 }
 
 static struct pci_slot_attribute pci_slot_attr_address =
-       __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL);
+       __ATTR(address, S_IRUGO, address_read_file, NULL);
 static struct pci_slot_attribute pci_slot_attr_max_speed =
-       __ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL);
+       __ATTR(max_bus_speed, S_IRUGO, max_speed_read_file, NULL);
 static struct pci_slot_attribute pci_slot_attr_cur_speed =
-       __ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL);
+       __ATTR(cur_bus_speed, S_IRUGO, cur_speed_read_file, NULL);
 
 static struct attribute *pci_slot_default_attrs[] = {
        &pci_slot_attr_address.attr,
index 8d3c49cc500fadcd212620f62df6d3cc9df68e4a..3bb05f17b9b4edcd05cc15e582aa049e64d01df5 100644 (file)
@@ -27,7 +27,7 @@ config PHY_EXYNOS_MIPI_VIDEO
 
 config PHY_MVEBU_SATA
        def_bool y
-       depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE
+       depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
        depends on OF
        select GENERIC_PHY
 
index 6d452a78b19c7aa3b6f1e24ce629379d72676cba..fa0e4e057b995d065e0777b4b5e541f326177613 100644 (file)
@@ -22,7 +22,7 @@ config POWER_RESET_GPIO
 
 config POWER_RESET_MSM
        bool "Qualcomm MSM power-off driver"
-       depends on POWER_RESET && ARCH_MSM
+       depends on POWER_RESET && ARCH_QCOM
        help
          Power off and restart support for Qualcomm boards.
 
index 37f56f7ee9265daefa7d1bfd0ca458825afba220..a75db7f8a92f4efda86b528c3814615327b85ce2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * QNAP Turbo NAS Board power off
+ * QNAP Turbo NAS Board power off. Can also be used on Synology devices.
  *
  * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch>
  *
 
 #define UART1_REG(x)   (base + ((UART_##x) << 2))
 
+struct power_off_cfg {
+       u32 baud;
+       char cmd;
+};
+
+static const struct power_off_cfg qnap_power_off_cfg = {
+       .baud = 19200,
+       .cmd = 'A',
+};
+
+static const struct power_off_cfg synology_power_off_cfg = {
+       .baud = 9600,
+       .cmd = '1',
+};
+
+static const struct of_device_id qnap_power_off_of_match_table[] = {
+       { .compatible = "qnap,power-off",
+         .data = &qnap_power_off_cfg,
+       },
+       { .compatible = "synology,power-off",
+         .data = &synology_power_off_cfg,
+       },
+       {}
+};
+MODULE_DEVICE_TABLE(of, qnap_power_off_of_match_table);
+
 static void __iomem *base;
 static unsigned long tclk;
+static const struct power_off_cfg *cfg;
 
 static void qnap_power_off(void)
 {
-       /* 19200 baud divisor */
-       const unsigned divisor = ((tclk + (8 * 19200)) / (16 * 19200));
+       const unsigned divisor = ((tclk + (8 * cfg->baud)) / (16 * cfg->baud));
 
        pr_err("%s: triggering power-off...\n", __func__);
 
-       /* hijack UART1 and reset into sane state (19200,8n1) */
+       /* hijack UART1 and reset into sane state */
        writel(0x83, UART1_REG(LCR));
        writel(divisor & 0xff, UART1_REG(DLL));
        writel((divisor >> 8) & 0xff, UART1_REG(DLM));
@@ -44,16 +70,21 @@ static void qnap_power_off(void)
        writel(0x00, UART1_REG(FCR));
        writel(0x00, UART1_REG(MCR));
 
-       /* send the power-off command 'A' to PIC */
-       writel('A', UART1_REG(TX));
+       /* send the power-off command to PIC */
+       writel(cfg->cmd, UART1_REG(TX));
 }
 
 static int qnap_power_off_probe(struct platform_device *pdev)
 {
+       struct device_node *np = pdev->dev.of_node;
        struct resource *res;
        struct clk *clk;
        char symname[KSYM_NAME_LEN];
 
+       const struct of_device_id *match =
+               of_match_node(qnap_power_off_of_match_table, np);
+       cfg = match->data;
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "Missing resource");
@@ -94,12 +125,6 @@ static int qnap_power_off_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id qnap_power_off_of_match_table[] = {
-       { .compatible = "qnap,power-off", },
-       {}
-};
-MODULE_DEVICE_TABLE(of, qnap_power_off_of_match_table);
-
 static struct platform_driver qnap_power_off_driver = {
        .probe  = qnap_power_off_probe,
        .remove = qnap_power_off_remove,
index 61b51e17d932a5c81db81fd99f46c7411dcf79c6..d9a0770b6c73d24b65ae35fce4bf3ac2a7f43343 100644 (file)
@@ -1374,6 +1374,9 @@ static int __init rapl_init(void)
 
                return -ENODEV;
        }
+
+       cpu_notifier_register_begin();
+
        /* prevent CPU hotplug during detection */
        get_online_cpus();
        ret = rapl_detect_topology();
@@ -1385,20 +1388,23 @@ static int __init rapl_init(void)
                ret = -ENODEV;
                goto done;
        }
-       register_hotcpu_notifier(&rapl_cpu_notifier);
+       __register_hotcpu_notifier(&rapl_cpu_notifier);
 done:
        put_online_cpus();
+       cpu_notifier_register_done();
 
        return ret;
 }
 
 static void __exit rapl_exit(void)
 {
+       cpu_notifier_register_begin();
        get_online_cpus();
-       unregister_hotcpu_notifier(&rapl_cpu_notifier);
+       __unregister_hotcpu_notifier(&rapl_cpu_notifier);
        rapl_unregister_powercap();
        rapl_cleanup_data();
        put_online_cpus();
+       cpu_notifier_register_done();
 }
 
 module_init(rapl_init);
index 22f2f2857b820675950fdd11f34470789cf81ff0..5b34ff29ea38042c84b19424ba3bc1826fab24a2 100644 (file)
@@ -71,6 +71,15 @@ config PWM_BFIN
          To compile this driver as a module, choose M here: the module
          will be called pwm-bfin.
 
+config PWM_CLPS711X
+       tristate "CLPS711X PWM support"
+       depends on ARCH_CLPS711X || COMPILE_TEST
+       help
+         Generic PWM framework driver for Cirrus Logic CLPS711X.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-clps711x.
+
 config PWM_EP93XX
        tristate "Cirrus Logic EP93xx PWM support"
        depends on ARCH_EP93XX
@@ -80,6 +89,16 @@ config PWM_EP93XX
          To compile this driver as a module, choose M here: the module
          will be called pwm-ep93xx.
 
+config PWM_FSL_FTM
+       tristate "Freescale FlexTimer Module (FTM) PWM support"
+       depends on OF
+       help
+         Generic FTM PWM framework driver for Freescale VF610 and
+         Layerscape LS-1 SoCs.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-fsl-ftm.
+
 config PWM_IMX
        tristate "i.MX PWM support"
        depends on ARCH_MXC
@@ -119,6 +138,16 @@ config PWM_LPC32XX
          To compile this driver as a module, choose M here: the module
          will be called pwm-lpc32xx.
 
+config PWM_LPSS
+       tristate "Intel LPSS PWM support"
+       depends on ACPI
+       help
+         Generic PWM framework driver for Intel Low Power Subsystem PWM
+         controller.
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-lpss.
+
 config PWM_MXS
        tristate "Freescale MXS PWM support"
        depends on ARCH_MXS && OF
@@ -160,6 +189,7 @@ config PWM_PXA
 config PWM_RENESAS_TPU
        tristate "Renesas TPU PWM support"
        depends on ARCH_SHMOBILE || COMPILE_TEST
+       depends on HAS_IOMEM
        help
          This driver exposes the Timer Pulse Unit (TPU) PWM controller found
          in Renesas chips through the PWM API.
index d8906ec699761ac573c74839c83e9eb46b9db767..e57d2c38a79403902d4855295cfbf7c469510b7f 100644 (file)
@@ -4,11 +4,14 @@ obj-$(CONFIG_PWM_AB8500)      += pwm-ab8500.o
 obj-$(CONFIG_PWM_ATMEL)                += pwm-atmel.o
 obj-$(CONFIG_PWM_ATMEL_TCB)    += pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BFIN)         += pwm-bfin.o
+obj-$(CONFIG_PWM_CLPS711X)     += pwm-clps711x.o
 obj-$(CONFIG_PWM_EP93XX)       += pwm-ep93xx.o
+obj-$(CONFIG_PWM_FSL_FTM)      += pwm-fsl-ftm.o
 obj-$(CONFIG_PWM_IMX)          += pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)       += pwm-jz4740.o
 obj-$(CONFIG_PWM_LP3943)       += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)      += pwm-lpc32xx.o
+obj-$(CONFIG_PWM_LPSS)         += pwm-lpss.o
 obj-$(CONFIG_PWM_MXS)          += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)      += pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)         += pwm-puv3.o
index bf4144a14661bdeb00baedc628131a5a1c81e39e..0adc952cc4ef5e95d8a5bd0fa0a680663150b7e8 100644 (file)
@@ -32,6 +32,7 @@
 /* Bit field in CMR */
 #define PWM_CMR_CPOL           (1 << 9)
 #define PWM_CMR_UPD_CDTY       (1 << 10)
+#define PWM_CMR_CPRE_MSK       0xF
 
 /* The following registers for PWM v1 */
 #define PWMV1_CDTY             0x04
@@ -104,6 +105,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        unsigned long clk_rate, prd, dty;
        unsigned long long div;
        unsigned int pres = 0;
+       u32 val;
        int ret;
 
        if (test_bit(PWMF_ENABLED, &pwm->flags) && (period_ns != pwm->period)) {
@@ -131,7 +133,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        prd = div;
        div *= duty_ns;
        do_div(div, period_ns);
-       dty = div;
+       dty = prd - div;
 
        ret = clk_enable(atmel_pwm->clk);
        if (ret) {
@@ -139,7 +141,10 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                return ret;
        }
 
-       atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, pres);
+       /* It is necessary to preserve CPOL, inside CMR */
+       val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
+       val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);
+       atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
        atmel_pwm->config(chip, pwm, dty, prd);
 
        clk_disable(atmel_pwm->clk);
diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c
new file mode 100644 (file)
index 0000000..fafb6a0
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Cirrus Logic CLPS711X PWM driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+struct clps711x_chip {
+       struct pwm_chip chip;
+       void __iomem *pmpcon;
+       struct clk *clk;
+       spinlock_t lock;
+};
+
+static inline struct clps711x_chip *to_clps711x_chip(struct pwm_chip *chip)
+{
+       return container_of(chip, struct clps711x_chip, chip);
+}
+
+static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v)
+{
+       /* PWM0 - bits 4..7, PWM1 - bits 8..11 */
+       u32 shift = (n + 1) * 4;
+       unsigned long flags;
+       u32 tmp;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       tmp = readl(priv->pmpcon);
+       tmp &= ~(0xf << shift);
+       tmp |= v << shift;
+       writel(tmp, priv->pmpcon);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v)
+{
+       /* Duty cycle 0..15 max */
+       return DIV_ROUND_CLOSEST(v * 0xf, pwm_get_period(pwm));
+}
+
+static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct clps711x_chip *priv = to_clps711x_chip(chip);
+       unsigned int freq = clk_get_rate(priv->clk);
+
+       if (!freq)
+               return -EINVAL;
+
+       /* Store constant period value */
+       pwm_set_period(pwm, DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq));
+
+       return 0;
+}
+
+static int clps711x_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                              int duty_ns, int period_ns)
+{
+       struct clps711x_chip *priv = to_clps711x_chip(chip);
+       unsigned int duty;
+
+       if (period_ns != pwm_get_period(pwm))
+               return -EINVAL;
+
+       duty = clps711x_get_duty(pwm, duty_ns);
+       clps711x_pwm_update_val(priv, pwm->hwpwm, duty);
+
+       return 0;
+}
+
+static int clps711x_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct clps711x_chip *priv = to_clps711x_chip(chip);
+       unsigned int duty;
+
+       duty = clps711x_get_duty(pwm, pwm_get_duty_cycle(pwm));
+       clps711x_pwm_update_val(priv, pwm->hwpwm, duty);
+
+       return 0;
+}
+
+static void clps711x_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct clps711x_chip *priv = to_clps711x_chip(chip);
+
+       clps711x_pwm_update_val(priv, pwm->hwpwm, 0);
+}
+
+static const struct pwm_ops clps711x_pwm_ops = {
+       .request = clps711x_pwm_request,
+       .config = clps711x_pwm_config,
+       .enable = clps711x_pwm_enable,
+       .disable = clps711x_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static struct pwm_device *clps711x_pwm_xlate(struct pwm_chip *chip,
+                                            const struct of_phandle_args *args)
+{
+       if (args->args[0] >= chip->npwm)
+               return ERR_PTR(-EINVAL);
+
+       return pwm_request_from_chip(chip, args->args[0], NULL);
+}
+
+static int clps711x_pwm_probe(struct platform_device *pdev)
+{
+       struct clps711x_chip *priv;
+       struct resource *res;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->pmpcon = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->pmpcon))
+               return PTR_ERR(priv->pmpcon);
+
+       priv->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(priv->clk))
+               return PTR_ERR(priv->clk);
+
+       priv->chip.ops = &clps711x_pwm_ops;
+       priv->chip.dev = &pdev->dev;
+       priv->chip.base = -1;
+       priv->chip.npwm = 2;
+       priv->chip.of_xlate = clps711x_pwm_xlate;
+       priv->chip.of_pwm_n_cells = 1;
+
+       spin_lock_init(&priv->lock);
+
+       platform_set_drvdata(pdev, priv);
+
+       return pwmchip_add(&priv->chip);
+}
+
+static int clps711x_pwm_remove(struct platform_device *pdev)
+{
+       struct clps711x_chip *priv = platform_get_drvdata(pdev);
+
+       return pwmchip_remove(&priv->chip);
+}
+
+static const struct of_device_id __maybe_unused clps711x_pwm_dt_ids[] = {
+       { .compatible = "cirrus,clps711x-pwm", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, clps711x_pwm_dt_ids);
+
+static struct platform_driver clps711x_pwm_driver = {
+       .driver = {
+               .name = "clps711x-pwm",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(clps711x_pwm_dt_ids),
+       },
+       .probe = clps711x_pwm_probe,
+       .remove = clps711x_pwm_remove,
+};
+module_platform_driver(clps711x_pwm_driver);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Cirrus Logic CLPS711X PWM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
new file mode 100644 (file)
index 0000000..420169e
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ *  Freescale FlexTimer Module (FTM) PWM Driver
+ *
+ *  Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define FTM_SC         0x00
+#define FTM_SC_CLK_MASK        0x3
+#define FTM_SC_CLK_SHIFT       3
+#define FTM_SC_CLK(c)  (((c) + 1) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK 0x7
+#define FTM_SC_PS_SHIFT        0
+
+#define FTM_CNT                0x04
+#define FTM_MOD                0x08
+
+#define FTM_CSC_BASE   0x0C
+#define FTM_CSC_MSB    BIT(5)
+#define FTM_CSC_MSA    BIT(4)
+#define FTM_CSC_ELSB   BIT(3)
+#define FTM_CSC_ELSA   BIT(2)
+#define FTM_CSC(_channel)      (FTM_CSC_BASE + ((_channel) * 8))
+
+#define FTM_CV_BASE    0x10
+#define FTM_CV(_channel)       (FTM_CV_BASE + ((_channel) * 8))
+
+#define FTM_CNTIN      0x4C
+#define FTM_STATUS     0x50
+
+#define FTM_MODE       0x54
+#define FTM_MODE_FTMEN BIT(0)
+#define FTM_MODE_INIT  BIT(2)
+#define FTM_MODE_PWMSYNC       BIT(3)
+
+#define FTM_SYNC       0x58
+#define FTM_OUTINIT    0x5C
+#define FTM_OUTMASK    0x60
+#define FTM_COMBINE    0x64
+#define FTM_DEADTIME   0x68
+#define FTM_EXTTRIG    0x6C
+#define FTM_POL                0x70
+#define FTM_FMS                0x74
+#define FTM_FILTER     0x78
+#define FTM_FLTCTRL    0x7C
+#define FTM_QDCTRL     0x80
+#define FTM_CONF       0x84
+#define FTM_FLTPOL     0x88
+#define FTM_SYNCONF    0x8C
+#define FTM_INVCTRL    0x90
+#define FTM_SWOCTRL    0x94
+#define FTM_PWMLOAD    0x98
+
+enum fsl_pwm_clk {
+       FSL_PWM_CLK_SYS,
+       FSL_PWM_CLK_FIX,
+       FSL_PWM_CLK_EXT,
+       FSL_PWM_CLK_CNTEN,
+       FSL_PWM_CLK_MAX
+};
+
+struct fsl_pwm_chip {
+       struct pwm_chip chip;
+
+       struct mutex lock;
+
+       unsigned int use_count;
+       unsigned int cnt_select;
+       unsigned int clk_ps;
+
+       void __iomem *base;
+
+       int period_ns;
+
+       struct clk *clk[FSL_PWM_CLK_MAX];
+};
+
+static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
+{
+       return container_of(chip, struct fsl_pwm_chip, chip);
+}
+
+static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+
+       return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+}
+
+static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+
+       clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+}
+
+static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
+                                       enum fsl_pwm_clk index)
+{
+       unsigned long sys_rate, cnt_rate;
+       unsigned long long ratio;
+
+       sys_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_SYS]);
+       if (!sys_rate)
+               return -EINVAL;
+
+       cnt_rate = clk_get_rate(fpc->clk[fpc->cnt_select]);
+       if (!cnt_rate)
+               return -EINVAL;
+
+       switch (index) {
+       case FSL_PWM_CLK_SYS:
+               fpc->clk_ps = 1;
+               break;
+       case FSL_PWM_CLK_FIX:
+               ratio = 2 * cnt_rate - 1;
+               do_div(ratio, sys_rate);
+               fpc->clk_ps = ratio;
+               break;
+       case FSL_PWM_CLK_EXT:
+               ratio = 4 * cnt_rate - 1;
+               do_div(ratio, sys_rate);
+               fpc->clk_ps = ratio;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned long fsl_pwm_calculate_cycles(struct fsl_pwm_chip *fpc,
+                                             unsigned long period_ns)
+{
+       unsigned long long c, c0;
+
+       c = clk_get_rate(fpc->clk[fpc->cnt_select]);
+       c = c * period_ns;
+       do_div(c, 1000000000UL);
+
+       do {
+               c0 = c;
+               do_div(c0, (1 << fpc->clk_ps));
+               if (c0 <= 0xFFFF)
+                       return (unsigned long)c0;
+       } while (++fpc->clk_ps < 8);
+
+       return 0;
+}
+
+static unsigned long fsl_pwm_calculate_period_cycles(struct fsl_pwm_chip *fpc,
+                                                    unsigned long period_ns,
+                                                    enum fsl_pwm_clk index)
+{
+       int ret;
+
+       ret = fsl_pwm_calculate_default_ps(fpc, index);
+       if (ret) {
+               dev_err(fpc->chip.dev,
+                       "failed to calculate default prescaler: %d\n",
+                       ret);
+               return 0;
+       }
+
+       return fsl_pwm_calculate_cycles(fpc, period_ns);
+}
+
+static unsigned long fsl_pwm_calculate_period(struct fsl_pwm_chip *fpc,
+                                             unsigned long period_ns)
+{
+       enum fsl_pwm_clk m0, m1;
+       unsigned long fix_rate, ext_rate, cycles;
+
+       cycles = fsl_pwm_calculate_period_cycles(fpc, period_ns,
+                       FSL_PWM_CLK_SYS);
+       if (cycles) {
+               fpc->cnt_select = FSL_PWM_CLK_SYS;
+               return cycles;
+       }
+
+       fix_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_FIX]);
+       ext_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_EXT]);
+
+       if (fix_rate > ext_rate) {
+               m0 = FSL_PWM_CLK_FIX;
+               m1 = FSL_PWM_CLK_EXT;
+       } else {
+               m0 = FSL_PWM_CLK_EXT;
+               m1 = FSL_PWM_CLK_FIX;
+       }
+
+       cycles = fsl_pwm_calculate_period_cycles(fpc, period_ns, m0);
+       if (cycles) {
+               fpc->cnt_select = m0;
+               return cycles;
+       }
+
+       fpc->cnt_select = m1;
+
+       return fsl_pwm_calculate_period_cycles(fpc, period_ns, m1);
+}
+
+static unsigned long fsl_pwm_calculate_duty(struct fsl_pwm_chip *fpc,
+                                           unsigned long period_ns,
+                                           unsigned long duty_ns)
+{
+       unsigned long long val, duty;
+
+       val = readl(fpc->base + FTM_MOD);
+       duty = duty_ns * (val + 1);
+       do_div(duty, period_ns);
+
+       return (unsigned long)duty;
+}
+
+static int fsl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                         int duty_ns, int period_ns)
+{
+       struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+       u32 val, period, duty;
+
+       mutex_lock(&fpc->lock);
+
+       /*
+        * The Freescale FTM controller supports only a single period for
+        * all PWM channels, therefore incompatible changes need to be
+        * refused.
+        */
+       if (fpc->period_ns && fpc->period_ns != period_ns) {
+               dev_err(fpc->chip.dev,
+                       "conflicting period requested for PWM %u\n",
+                       pwm->hwpwm);
+               mutex_unlock(&fpc->lock);
+               return -EBUSY;
+       }
+
+       if (!fpc->period_ns && duty_ns) {
+               period = fsl_pwm_calculate_period(fpc, period_ns);
+               if (!period) {
+                       dev_err(fpc->chip.dev, "failed to calculate period\n");
+                       mutex_unlock(&fpc->lock);
+                       return -EINVAL;
+               }
+
+               val = readl(fpc->base + FTM_SC);
+               val &= ~(FTM_SC_PS_MASK << FTM_SC_PS_SHIFT);
+               val |= fpc->clk_ps;
+               writel(val, fpc->base + FTM_SC);
+               writel(period - 1, fpc->base + FTM_MOD);
+
+               fpc->period_ns = period_ns;
+       }
+
+       mutex_unlock(&fpc->lock);
+
+       duty = fsl_pwm_calculate_duty(fpc, period_ns, duty_ns);
+
+       writel(FTM_CSC_MSB | FTM_CSC_ELSB, fpc->base + FTM_CSC(pwm->hwpwm));
+       writel(duty, fpc->base + FTM_CV(pwm->hwpwm));
+
+       return 0;
+}
+
+static int fsl_pwm_set_polarity(struct pwm_chip *chip,
+                               struct pwm_device *pwm,
+                               enum pwm_polarity polarity)
+{
+       struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+       u32 val;
+
+       val = readl(fpc->base + FTM_POL);
+
+       if (polarity == PWM_POLARITY_INVERSED)
+               val |= BIT(pwm->hwpwm);
+       else
+               val &= ~BIT(pwm->hwpwm);
+
+       writel(val, fpc->base + FTM_POL);
+
+       return 0;
+}
+
+static int fsl_counter_clock_enable(struct fsl_pwm_chip *fpc)
+{
+       u32 val;
+       int ret;
+
+       if (fpc->use_count != 0)
+               return 0;
+
+       /* select counter clock source */
+       val = readl(fpc->base + FTM_SC);
+       val &= ~(FTM_SC_CLK_MASK << FTM_SC_CLK_SHIFT);
+       val |= FTM_SC_CLK(fpc->cnt_select);
+       writel(val, fpc->base + FTM_SC);
+
+       ret = clk_prepare_enable(fpc->clk[fpc->cnt_select]);
+       if (ret)
+               return ret;
+
+       ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
+       if (ret) {
+               clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
+               return ret;
+       }
+
+       fpc->use_count++;
+
+       return 0;
+}
+
+static int fsl_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+       u32 val;
+       int ret;
+
+       mutex_lock(&fpc->lock);
+       val = readl(fpc->base + FTM_OUTMASK);
+       val &= ~BIT(pwm->hwpwm);
+       writel(val, fpc->base + FTM_OUTMASK);
+
+       ret = fsl_counter_clock_enable(fpc);
+       mutex_unlock(&fpc->lock);
+
+       return ret;
+}
+
+static void fsl_counter_clock_disable(struct fsl_pwm_chip *fpc)
+{
+       u32 val;
+
+       /*
+        * already disabled, do nothing
+        */
+       if (fpc->use_count == 0)
+               return;
+
+       /* there are still users, so can't disable yet */
+       if (--fpc->use_count > 0)
+               return;
+
+       /* no users left, disable PWM counter clock */
+       val = readl(fpc->base + FTM_SC);
+       val &= ~(FTM_SC_CLK_MASK << FTM_SC_CLK_SHIFT);
+       writel(val, fpc->base + FTM_SC);
+
+       clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
+       clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
+}
+
+static void fsl_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+       u32 val;
+
+       mutex_lock(&fpc->lock);
+       val = readl(fpc->base + FTM_OUTMASK);
+       val |= BIT(pwm->hwpwm);
+       writel(val, fpc->base + FTM_OUTMASK);
+
+       fsl_counter_clock_disable(fpc);
+
+       val = readl(fpc->base + FTM_OUTMASK);
+
+       if ((val & 0xFF) == 0xFF)
+               fpc->period_ns = 0;
+
+       mutex_unlock(&fpc->lock);
+}
+
+static const struct pwm_ops fsl_pwm_ops = {
+       .request = fsl_pwm_request,
+       .free = fsl_pwm_free,
+       .config = fsl_pwm_config,
+       .set_polarity = fsl_pwm_set_polarity,
+       .enable = fsl_pwm_enable,
+       .disable = fsl_pwm_disable,
+       .owner = THIS_MODULE,
+};
+
+static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
+{
+       int ret;
+
+       ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+       if (ret)
+               return ret;
+
+       writel(0x00, fpc->base + FTM_CNTIN);
+       writel(0x00, fpc->base + FTM_OUTINIT);
+       writel(0xFF, fpc->base + FTM_OUTMASK);
+
+       clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+
+       return 0;
+}
+
+static int fsl_pwm_probe(struct platform_device *pdev)
+{
+       struct fsl_pwm_chip *fpc;
+       struct resource *res;
+       int ret;
+
+       fpc = devm_kzalloc(&pdev->dev, sizeof(*fpc), GFP_KERNEL);
+       if (!fpc)
+               return -ENOMEM;
+
+       mutex_init(&fpc->lock);
+
+       fpc->chip.dev = &pdev->dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       fpc->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(fpc->base))
+               return PTR_ERR(fpc->base);
+
+       fpc->clk[FSL_PWM_CLK_SYS] = devm_clk_get(&pdev->dev, "ftm_sys");
+       if (IS_ERR(fpc->clk[FSL_PWM_CLK_SYS])) {
+               dev_err(&pdev->dev, "failed to get \"ftm_sys\" clock\n");
+               return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]);
+       }
+
+       fpc->clk[FSL_PWM_CLK_FIX] = devm_clk_get(fpc->chip.dev, "ftm_fix");
+       if (IS_ERR(fpc->clk[FSL_PWM_CLK_FIX]))
+               return PTR_ERR(fpc->clk[FSL_PWM_CLK_FIX]);
+
+       fpc->clk[FSL_PWM_CLK_EXT] = devm_clk_get(fpc->chip.dev, "ftm_ext");
+       if (IS_ERR(fpc->clk[FSL_PWM_CLK_EXT]))
+               return PTR_ERR(fpc->clk[FSL_PWM_CLK_EXT]);
+
+       fpc->clk[FSL_PWM_CLK_CNTEN] =
+                               devm_clk_get(fpc->chip.dev, "ftm_cnt_clk_en");
+       if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
+               return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);
+
+       fpc->chip.ops = &fsl_pwm_ops;
+       fpc->chip.of_xlate = of_pwm_xlate_with_flags;
+       fpc->chip.of_pwm_n_cells = 3;
+       fpc->chip.base = -1;
+       fpc->chip.npwm = 8;
+
+       ret = pwmchip_add(&fpc->chip);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, fpc);
+
+       return fsl_pwm_init(fpc);
+}
+
+static int fsl_pwm_remove(struct platform_device *pdev)
+{
+       struct fsl_pwm_chip *fpc = platform_get_drvdata(pdev);
+
+       return pwmchip_remove(&fpc->chip);
+}
+
+static const struct of_device_id fsl_pwm_dt_ids[] = {
+       { .compatible = "fsl,vf610-ftm-pwm", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
+
+static struct platform_driver fsl_pwm_driver = {
+       .driver = {
+               .name = "fsl-ftm-pwm",
+               .of_match_table = fsl_pwm_dt_ids,
+       },
+       .probe = fsl_pwm_probe,
+       .remove = fsl_pwm_remove,
+};
+module_platform_driver(fsl_pwm_driver);
+
+MODULE_DESCRIPTION("Freescale FlexTimer Module PWM Driver");
+MODULE_AUTHOR("Xiubo Li <Li.Xiubo@freescale.com>");
+MODULE_ALIAS("platform:fsl-ftm-pwm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
new file mode 100644 (file)
index 0000000..449e372
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Intel Low Power Subsystem PWM controller driver
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ * Author: Chew Kean Ho <kean.ho.chew@intel.com>
+ * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+ * Author: Chew Chiau Ee <chiau.ee.chew@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.
+ */
+
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pwm.h>
+#include <linux/platform_device.h>
+
+#define PWM                            0x00000000
+#define PWM_ENABLE                     BIT(31)
+#define PWM_SW_UPDATE                  BIT(30)
+#define PWM_BASE_UNIT_SHIFT            8
+#define PWM_BASE_UNIT_MASK             0x00ffff00
+#define PWM_ON_TIME_DIV_MASK           0x000000ff
+#define PWM_DIVISION_CORRECTION                0x2
+#define PWM_LIMIT                      (0x8000 + PWM_DIVISION_CORRECTION)
+#define NSECS_PER_SEC                  1000000000UL
+
+struct pwm_lpss_chip {
+       struct pwm_chip chip;
+       void __iomem *regs;
+       struct clk *clk;
+};
+
+static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
+{
+       return container_of(chip, struct pwm_lpss_chip, chip);
+}
+
+static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
+                          int duty_ns, int period_ns)
+{
+       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
+       u8 on_time_div;
+       unsigned long c;
+       unsigned long long base_unit, freq = NSECS_PER_SEC;
+       u32 ctrl;
+
+       do_div(freq, period_ns);
+
+       /* The equation is: base_unit = ((freq / c) * 65536) + correction */
+       base_unit = freq * 65536;
+
+       c = clk_get_rate(lpwm->clk);
+       if (!c)
+               return -EINVAL;
+
+       do_div(base_unit, c);
+       base_unit += PWM_DIVISION_CORRECTION;
+       if (base_unit > PWM_LIMIT)
+               return -EINVAL;
+
+       if (duty_ns <= 0)
+               duty_ns = 1;
+       on_time_div = 255 - (255 * duty_ns / period_ns);
+
+       ctrl = readl(lpwm->regs + PWM);
+       ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
+       ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
+       ctrl |= on_time_div;
+       /* request PWM to update on next cycle */
+       ctrl |= PWM_SW_UPDATE;
+       writel(ctrl, lpwm->regs + PWM);
+
+       return 0;
+}
+
+static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
+       u32 ctrl;
+       int ret;
+
+       ret = clk_prepare_enable(lpwm->clk);
+       if (ret)
+               return ret;
+
+       ctrl = readl(lpwm->regs + PWM);
+       writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);
+
+       return 0;
+}
+
+static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
+       u32 ctrl;
+
+       ctrl = readl(lpwm->regs + PWM);
+       writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
+
+       clk_disable_unprepare(lpwm->clk);
+}
+
+static const struct pwm_ops pwm_lpss_ops = {
+       .config = pwm_lpss_config,
+       .enable = pwm_lpss_enable,
+       .disable = pwm_lpss_disable,
+       .owner = THIS_MODULE,
+};
+
+static const struct acpi_device_id pwm_lpss_acpi_match[] = {
+       { "80860F09", 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
+
+static int pwm_lpss_probe(struct platform_device *pdev)
+{
+       struct pwm_lpss_chip *lpwm;
+       struct resource *r;
+       int ret;
+
+       lpwm = devm_kzalloc(&pdev->dev, sizeof(*lpwm), GFP_KERNEL);
+       if (!lpwm)
+               return -ENOMEM;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       lpwm->regs = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(lpwm->regs))
+               return PTR_ERR(lpwm->regs);
+
+       lpwm->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(lpwm->clk)) {
+               dev_err(&pdev->dev, "failed to get PWM clock\n");
+               return PTR_ERR(lpwm->clk);
+       }
+
+       lpwm->chip.dev = &pdev->dev;
+       lpwm->chip.ops = &pwm_lpss_ops;
+       lpwm->chip.base = -1;
+       lpwm->chip.npwm = 1;
+
+       ret = pwmchip_add(&lpwm->chip);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, lpwm);
+       return 0;
+}
+
+static int pwm_lpss_remove(struct platform_device *pdev)
+{
+       struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
+       u32 ctrl;
+
+       ctrl = readl(lpwm->regs + PWM);
+       writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
+
+       return pwmchip_remove(&lpwm->chip);
+}
+
+static struct platform_driver pwm_lpss_driver = {
+       .driver = {
+               .name = "pwm-lpss",
+               .acpi_match_table = pwm_lpss_acpi_match,
+       },
+       .probe = pwm_lpss_probe,
+       .remove = pwm_lpss_remove,
+};
+module_platform_driver(pwm_lpss_driver);
+
+MODULE_DESCRIPTION("PWM driver for Intel LPSS");
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:pwm-lpss");
index 8d995731cef8d13a96f8168161a038c7446e3d5a..cd356d8702441169773d030494a4c41c42dc7702 100644 (file)
@@ -127,12 +127,12 @@ static struct pwm_ops pxa_pwm_ops = {
 
 #ifdef CONFIG_OF
 /*
- * Device tree users must create one device instance for each pwm channel.
+ * Device tree users must create one device instance for each PWM channel.
  * Hence we dispense with the HAS_SECONDARY_PWM and "tell" the original driver
  * code that this is a single channel pxa25x-pwm.  Currently all devices are
  * supported identically.
  */
-static struct of_device_id pwm_of_match[] = {
+static const struct of_device_id pwm_of_match[] = {
        { .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0]},
        { .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0]},
        { .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0]},
index b59639e0c02978388126a1d7d56d8f3b62c32b6c..d66529a995a193cc28057957ce408ba9daf124cb 100644 (file)
@@ -598,9 +598,8 @@ static int pwm_samsung_resume(struct device *dev)
 }
 #endif
 
-static const struct dev_pm_ops pwm_samsung_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
-};
+static SIMPLE_DEV_PM_OPS(pwm_samsung_pm_ops, pwm_samsung_suspend,
+                        pwm_samsung_resume);
 
 static struct platform_driver pwm_samsung_driver = {
        .driver         = {
index c9d04f79786232b8c1fc5f33e166c704349cd82e..0615f50a14cd21dd6cc56a462a05838bfd8cd77e 100644 (file)
@@ -11,3 +11,5 @@ menuconfig RESET_CONTROLLER
          via GPIOs or SoC-internal reset controller modules.
 
          If unsure, say no.
+
+source "drivers/reset/sti/Kconfig"
index cc29832c96388c6004764f7a609b65eba55beee2..4f60caf750ceb90e860e00d9ffed55cd74a4ec03 100644 (file)
@@ -1,2 +1,3 @@
 obj-$(CONFIG_RESET_CONTROLLER) += core.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_ARCH_STI) += sti/
index d1b6089a0ef82f57c9aece8b86168a336710b70d..baeaf82d40d9f1982761d68ee1cf0c56cd6c346e 100644 (file)
@@ -43,7 +43,7 @@ struct reset_control {
  * This simple translation function should be used for reset controllers
  * with 1:1 mapping, where reset lines can be indexed by number without gaps.
  */
-int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
+static int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
                          const struct of_phandle_args *reset_spec)
 {
        if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
@@ -54,7 +54,6 @@ int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
 
        return reset_spec->args[0];
 }
-EXPORT_SYMBOL_GPL(of_reset_simple_xlate);
 
 /**
  * reset_controller_register - register a reset controller device
@@ -127,15 +126,16 @@ int reset_control_deassert(struct reset_control *rstc)
 EXPORT_SYMBOL_GPL(reset_control_deassert);
 
 /**
- * reset_control_get - Lookup and obtain a reference to a reset controller.
- * @dev: device to be reset by the controller
+ * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * @node: device to be reset by the controller
  * @id: reset line name
  *
  * Returns a struct reset_control or IS_ERR() condition containing errno.
  *
  * Use of id names is optional.
  */
-struct reset_control *reset_control_get(struct device *dev, const char *id)
+struct reset_control *of_reset_control_get(struct device_node *node,
+                                          const char *id)
 {
        struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER);
        struct reset_controller_dev *r, *rcdev;
@@ -144,13 +144,10 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
        int rstc_id;
        int ret;
 
-       if (!dev)
-               return ERR_PTR(-EINVAL);
-
        if (id)
-               index = of_property_match_string(dev->of_node,
+               index = of_property_match_string(node,
                                                 "reset-names", id);
-       ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells",
+       ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
                                         index, &args);
        if (ret)
                return ERR_PTR(ret);
@@ -167,7 +164,7 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
 
        if (!rcdev) {
                mutex_unlock(&reset_controller_list_mutex);
-               return ERR_PTR(-ENODEV);
+               return ERR_PTR(-EPROBE_DEFER);
        }
 
        rstc_id = rcdev->of_xlate(rcdev, &args);
@@ -185,12 +182,35 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
                return ERR_PTR(-ENOMEM);
        }
 
-       rstc->dev = dev;
        rstc->rcdev = rcdev;
        rstc->id = rstc_id;
 
        return rstc;
 }
+EXPORT_SYMBOL_GPL(of_reset_control_get);
+
+/**
+ * reset_control_get - Lookup and obtain a reference to a reset controller.
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Returns a struct reset_control or IS_ERR() condition containing errno.
+ *
+ * Use of id names is optional.
+ */
+struct reset_control *reset_control_get(struct device *dev, const char *id)
+{
+       struct reset_control *rstc;
+
+       if (!dev)
+               return ERR_PTR(-EINVAL);
+
+       rstc = of_reset_control_get(dev->of_node, id);
+       if (!IS_ERR(rstc))
+               rstc->dev = dev;
+
+       return rstc;
+}
 EXPORT_SYMBOL_GPL(reset_control_get);
 
 /**
@@ -243,33 +263,6 @@ struct reset_control *devm_reset_control_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL_GPL(devm_reset_control_get);
 
-static int devm_reset_control_match(struct device *dev, void *res, void *data)
-{
-       struct reset_control **rstc = res;
-       if (WARN_ON(!rstc || !*rstc))
-               return 0;
-       return *rstc == data;
-}
-
-/**
- * devm_reset_control_put - resource managed reset_control_put()
- * @rstc: reset controller to free
- *
- * Deallocate a reset control allocated withd devm_reset_control_get().
- * This function will not need to be called normally, as devres will take
- * care of freeing the resource.
- */
-void devm_reset_control_put(struct reset_control *rstc)
-{
-       int ret;
-
-       ret = devres_release(rstc->dev, devm_reset_control_release,
-                            devm_reset_control_match, rstc);
-       if (ret)
-               WARN_ON(ret);
-}
-EXPORT_SYMBOL_GPL(devm_reset_control_put);
-
 /**
  * device_reset - find reset controller associated with the device
  *                and perform reset
diff --git a/drivers/reset/sti/Kconfig b/drivers/reset/sti/Kconfig
new file mode 100644 (file)
index 0000000..88d2d03
--- /dev/null
@@ -0,0 +1,15 @@
+if ARCH_STI
+
+config STI_RESET_SYSCFG
+       bool
+       select RESET_CONTROLLER
+
+config STIH415_RESET
+       bool
+       select STI_RESET_SYSCFG
+
+config STIH416_RESET
+       bool
+       select STI_RESET_SYSCFG
+
+endif
diff --git a/drivers/reset/sti/Makefile b/drivers/reset/sti/Makefile
new file mode 100644 (file)
index 0000000..be1c976
--- /dev/null
@@ -0,0 +1,4 @@
+obj-$(CONFIG_STI_RESET_SYSCFG) += reset-syscfg.o
+
+obj-$(CONFIG_STIH415_RESET) += reset-stih415.o
+obj-$(CONFIG_STIH416_RESET) += reset-stih416.o
diff --git a/drivers/reset/sti/reset-stih415.c b/drivers/reset/sti/reset-stih415.c
new file mode 100644 (file)
index 0000000..e6f6c41
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ * Author: Stephen Gallimore <stephen.gallimore@st.com>
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/reset-controller/stih415-resets.h>
+
+#include "reset-syscfg.h"
+
+/*
+ * STiH415 Peripheral powerdown definitions.
+ */
+static const char stih415_front[] = "st,stih415-front-syscfg";
+static const char stih415_rear[] = "st,stih415-rear-syscfg";
+static const char stih415_sbc[] = "st,stih415-sbc-syscfg";
+static const char stih415_lpm[] = "st,stih415-lpm-syscfg";
+
+#define STIH415_PDN_FRONT(_bit) \
+       _SYSCFG_RST_CH(stih415_front, SYSCFG_114, _bit, SYSSTAT_187, _bit)
+
+#define STIH415_PDN_REAR(_cntl, _stat) \
+       _SYSCFG_RST_CH(stih415_rear, SYSCFG_336, _cntl, SYSSTAT_384, _stat)
+
+#define STIH415_SRST_REAR(_reg, _bit) \
+       _SYSCFG_RST_CH_NO_ACK(stih415_rear, _reg, _bit)
+
+#define STIH415_SRST_SBC(_reg, _bit) \
+       _SYSCFG_RST_CH_NO_ACK(stih415_sbc, _reg, _bit)
+
+#define STIH415_SRST_FRONT(_reg, _bit) \
+       _SYSCFG_RST_CH_NO_ACK(stih415_front, _reg, _bit)
+
+#define STIH415_SRST_LPM(_reg, _bit) \
+       _SYSCFG_RST_CH_NO_ACK(stih415_lpm, _reg, _bit)
+
+#define SYSCFG_114     0x38 /* Powerdown request EMI/NAND/Keyscan */
+#define SYSSTAT_187    0x15c /* Powerdown status EMI/NAND/Keyscan */
+
+#define SYSCFG_336     0x90 /* Powerdown request USB/SATA/PCIe */
+#define SYSSTAT_384    0x150 /* Powerdown status USB/SATA/PCIe */
+
+#define SYSCFG_376     0x130 /* Reset generator 0 control 0 */
+#define SYSCFG_166     0x108 /* Softreset Ethernet 0 */
+#define SYSCFG_31      0x7c /* Softreset Ethernet 1 */
+#define LPM_SYSCFG_1   0x4 /* Softreset IRB */
+
+static const struct syscfg_reset_channel_data stih415_powerdowns[] = {
+       [STIH415_EMISS_POWERDOWN]       = STIH415_PDN_FRONT(0),
+       [STIH415_NAND_POWERDOWN]        = STIH415_PDN_FRONT(1),
+       [STIH415_KEYSCAN_POWERDOWN]     = STIH415_PDN_FRONT(2),
+       [STIH415_USB0_POWERDOWN]        = STIH415_PDN_REAR(0, 0),
+       [STIH415_USB1_POWERDOWN]        = STIH415_PDN_REAR(1, 1),
+       [STIH415_USB2_POWERDOWN]        = STIH415_PDN_REAR(2, 2),
+       [STIH415_SATA0_POWERDOWN]       = STIH415_PDN_REAR(3, 3),
+       [STIH415_SATA1_POWERDOWN]       = STIH415_PDN_REAR(4, 4),
+       [STIH415_PCIE_POWERDOWN]        = STIH415_PDN_REAR(5, 8),
+};
+
+static const struct syscfg_reset_channel_data stih415_softresets[] = {
+       [STIH415_ETH0_SOFTRESET] = STIH415_SRST_FRONT(SYSCFG_166, 0),
+       [STIH415_ETH1_SOFTRESET] = STIH415_SRST_SBC(SYSCFG_31, 0),
+       [STIH415_IRB_SOFTRESET]  = STIH415_SRST_LPM(LPM_SYSCFG_1, 6),
+       [STIH415_USB0_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 9),
+       [STIH415_USB1_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 10),
+       [STIH415_USB2_SOFTRESET] = STIH415_SRST_REAR(SYSCFG_376, 11),
+};
+
+static struct syscfg_reset_controller_data stih415_powerdown_controller = {
+       .wait_for_ack = true,
+       .nr_channels = ARRAY_SIZE(stih415_powerdowns),
+       .channels = stih415_powerdowns,
+};
+
+static struct syscfg_reset_controller_data stih415_softreset_controller = {
+       .wait_for_ack = false,
+       .active_low = true,
+       .nr_channels = ARRAY_SIZE(stih415_softresets),
+       .channels = stih415_softresets,
+};
+
+static struct of_device_id stih415_reset_match[] = {
+       { .compatible = "st,stih415-powerdown",
+         .data = &stih415_powerdown_controller, },
+       { .compatible = "st,stih415-softreset",
+         .data = &stih415_softreset_controller, },
+       {},
+};
+
+static struct platform_driver stih415_reset_driver = {
+       .probe = syscfg_reset_probe,
+       .driver = {
+               .name = "reset-stih415",
+               .owner = THIS_MODULE,
+               .of_match_table = stih415_reset_match,
+       },
+};
+
+static int __init stih415_reset_init(void)
+{
+       return platform_driver_register(&stih415_reset_driver);
+}
+arch_initcall(stih415_reset_init);
diff --git a/drivers/reset/sti/reset-stih416.c b/drivers/reset/sti/reset-stih416.c
new file mode 100644 (file)
index 0000000..fe3bf02
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ * Author: Stephen Gallimore <stephen.gallimore@st.com>
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/reset-controller/stih416-resets.h>
+
+#include "reset-syscfg.h"
+
+/*
+ * STiH416 Peripheral powerdown definitions.
+ */
+static const char stih416_front[] = "st,stih416-front-syscfg";
+static const char stih416_rear[] = "st,stih416-rear-syscfg";
+static const char stih416_sbc[] = "st,stih416-sbc-syscfg";
+static const char stih416_lpm[] = "st,stih416-lpm-syscfg";
+static const char stih416_cpu[] = "st,stih416-cpu-syscfg";
+
+#define STIH416_PDN_FRONT(_bit) \
+       _SYSCFG_RST_CH(stih416_front, SYSCFG_1500, _bit, SYSSTAT_1578, _bit)
+
+#define STIH416_PDN_REAR(_cntl, _stat) \
+       _SYSCFG_RST_CH(stih416_rear, SYSCFG_2525, _cntl, SYSSTAT_2583, _stat)
+
+#define SYSCFG_1500    0x7d0 /* Powerdown request EMI/NAND/Keyscan */
+#define SYSSTAT_1578   0x908 /* Powerdown status EMI/NAND/Keyscan */
+
+#define SYSCFG_2525    0x834 /* Powerdown request USB/SATA/PCIe */
+#define SYSSTAT_2583   0x91c /* Powerdown status USB/SATA/PCIe */
+
+#define SYSCFG_2552    0x8A0 /* Reset Generator control 0 */
+#define SYSCFG_1539    0x86c /* Softreset Ethernet 0 */
+#define SYSCFG_510     0x7f8 /* Softreset Ethernet 1 */
+#define LPM_SYSCFG_1   0x4 /* Softreset IRB */
+#define SYSCFG_2553    0x8a4 /* Softreset SATA0/1, PCIE0/1 */
+#define SYSCFG_7563    0x8cc /* MPE softresets 0 */
+#define SYSCFG_7564    0x8d0 /* MPE softresets 1 */
+
+#define STIH416_SRST_CPU(_reg, _bit) \
+        _SYSCFG_RST_CH_NO_ACK(stih416_cpu, _reg, _bit)
+
+#define STIH416_SRST_FRONT(_reg, _bit) \
+        _SYSCFG_RST_CH_NO_ACK(stih416_front, _reg, _bit)
+
+#define STIH416_SRST_REAR(_reg, _bit) \
+        _SYSCFG_RST_CH_NO_ACK(stih416_rear, _reg, _bit)
+
+#define STIH416_SRST_LPM(_reg, _bit) \
+        _SYSCFG_RST_CH_NO_ACK(stih416_lpm, _reg, _bit)
+
+#define STIH416_SRST_SBC(_reg, _bit) \
+        _SYSCFG_RST_CH_NO_ACK(stih416_sbc, _reg, _bit)
+
+static const struct syscfg_reset_channel_data stih416_powerdowns[] = {
+       [STIH416_EMISS_POWERDOWN]       = STIH416_PDN_FRONT(0),
+       [STIH416_NAND_POWERDOWN]        = STIH416_PDN_FRONT(1),
+       [STIH416_KEYSCAN_POWERDOWN]     = STIH416_PDN_FRONT(2),
+       [STIH416_USB0_POWERDOWN]        = STIH416_PDN_REAR(0, 0),
+       [STIH416_USB1_POWERDOWN]        = STIH416_PDN_REAR(1, 1),
+       [STIH416_USB2_POWERDOWN]        = STIH416_PDN_REAR(2, 2),
+       [STIH416_USB3_POWERDOWN]        = STIH416_PDN_REAR(6, 5),
+       [STIH416_SATA0_POWERDOWN]       = STIH416_PDN_REAR(3, 3),
+       [STIH416_SATA1_POWERDOWN]       = STIH416_PDN_REAR(4, 4),
+       [STIH416_PCIE0_POWERDOWN]       = STIH416_PDN_REAR(7, 9),
+       [STIH416_PCIE1_POWERDOWN]       = STIH416_PDN_REAR(5, 8),
+};
+
+static const struct syscfg_reset_channel_data stih416_softresets[] = {
+       [STIH416_ETH0_SOFTRESET] = STIH416_SRST_FRONT(SYSCFG_1539, 0),
+       [STIH416_ETH1_SOFTRESET] = STIH416_SRST_SBC(SYSCFG_510, 0),
+       [STIH416_IRB_SOFTRESET]  = STIH416_SRST_LPM(LPM_SYSCFG_1, 6),
+       [STIH416_USB0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 9),
+       [STIH416_USB1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 10),
+       [STIH416_USB2_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 11),
+       [STIH416_USB3_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 28),
+       [STIH416_SATA0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 7),
+       [STIH416_SATA1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 3),
+       [STIH416_PCIE0_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 15),
+       [STIH416_PCIE1_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 2),
+       [STIH416_AUD_DAC_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 14),
+       [STIH416_HDTVOUT_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 5),
+       [STIH416_VTAC_M_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 25),
+       [STIH416_VTAC_A_RX_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2552, 26),
+       [STIH416_SYNC_HD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 5),
+       [STIH416_SYNC_SD_SOFTRESET] = STIH416_SRST_REAR(SYSCFG_2553, 6),
+       [STIH416_BLITTER_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 10),
+       [STIH416_GPU_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 11),
+       [STIH416_VTAC_M_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 18),
+       [STIH416_VTAC_A_TX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 19),
+       [STIH416_VTG_AUX_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 21),
+       [STIH416_JPEG_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7563, 23),
+       [STIH416_HVA_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 2),
+       [STIH416_COMPO_M_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 3),
+       [STIH416_COMPO_A_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 4),
+       [STIH416_VP8_DEC_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 10),
+       [STIH416_VTG_MAIN_SOFTRESET] = STIH416_SRST_CPU(SYSCFG_7564, 16),
+};
+
+static struct syscfg_reset_controller_data stih416_powerdown_controller = {
+       .wait_for_ack   = true,
+       .nr_channels    = ARRAY_SIZE(stih416_powerdowns),
+       .channels       = stih416_powerdowns,
+};
+
+static struct syscfg_reset_controller_data stih416_softreset_controller = {
+       .wait_for_ack = false,
+       .active_low = true,
+       .nr_channels = ARRAY_SIZE(stih416_softresets),
+       .channels = stih416_softresets,
+};
+
+static struct of_device_id stih416_reset_match[] = {
+       { .compatible = "st,stih416-powerdown",
+         .data = &stih416_powerdown_controller, },
+       { .compatible = "st,stih416-softreset",
+         .data = &stih416_softreset_controller, },
+       {},
+};
+
+static struct platform_driver stih416_reset_driver = {
+       .probe = syscfg_reset_probe,
+       .driver = {
+               .name = "reset-stih416",
+               .owner = THIS_MODULE,
+               .of_match_table = stih416_reset_match,
+       },
+};
+
+static int __init stih416_reset_init(void)
+{
+       return platform_driver_register(&stih416_reset_driver);
+}
+arch_initcall(stih416_reset_init);
diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c
new file mode 100644 (file)
index 0000000..a145cc0
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited
+ * Author: Stephen Gallimore <stephen.gallimore@st.com>
+ *
+ * Inspired by mach-imx/src.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.
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include "reset-syscfg.h"
+
+/**
+ * Reset channel regmap configuration
+ *
+ * @reset: regmap field for the channel's reset bit.
+ * @ack: regmap field for the channel's ack bit (optional).
+ */
+struct syscfg_reset_channel {
+       struct regmap_field *reset;
+       struct regmap_field *ack;
+};
+
+/**
+ * A reset controller which groups together a set of related reset bits, which
+ * may be located in different system configuration registers.
+ *
+ * @rst: base reset controller structure.
+ * @active_low: are the resets in this controller active low, i.e. clearing
+ *              the reset bit puts the hardware into reset.
+ * @channels: An array of reset channels for this controller.
+ */
+struct syscfg_reset_controller {
+       struct reset_controller_dev rst;
+       bool active_low;
+       struct syscfg_reset_channel *channels;
+};
+
+#define to_syscfg_reset_controller(_rst) \
+       container_of(_rst, struct syscfg_reset_controller, rst)
+
+static int syscfg_reset_program_hw(struct reset_controller_dev *rcdev,
+                                  unsigned long idx, int assert)
+{
+       struct syscfg_reset_controller *rst = to_syscfg_reset_controller(rcdev);
+       const struct syscfg_reset_channel *ch;
+       u32 ctrl_val = rst->active_low ? !assert : !!assert;
+       int err;
+
+       if (idx >= rcdev->nr_resets)
+               return -EINVAL;
+
+       ch = &rst->channels[idx];
+
+       err = regmap_field_write(ch->reset, ctrl_val);
+       if (err)
+               return err;
+
+       if (ch->ack) {
+               unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+               u32 ack_val;
+
+               while (true) {
+                       err = regmap_field_read(ch->ack, &ack_val);
+                       if (err)
+                               return err;
+
+                       if (ack_val == ctrl_val)
+                               break;
+
+                       if (time_after(jiffies, timeout))
+                               return -ETIME;
+
+                       cpu_relax();
+               }
+       }
+
+       return 0;
+}
+
+static int syscfg_reset_assert(struct reset_controller_dev *rcdev,
+                              unsigned long idx)
+{
+       return syscfg_reset_program_hw(rcdev, idx, true);
+}
+
+static int syscfg_reset_deassert(struct reset_controller_dev *rcdev,
+                                unsigned long idx)
+{
+       return syscfg_reset_program_hw(rcdev, idx, false);
+}
+
+static int syscfg_reset_dev(struct reset_controller_dev *rcdev,
+                           unsigned long idx)
+{
+       int err = syscfg_reset_assert(rcdev, idx);
+       if (err)
+               return err;
+
+       return syscfg_reset_deassert(rcdev, idx);
+}
+
+static struct reset_control_ops syscfg_reset_ops = {
+       .reset    = syscfg_reset_dev,
+       .assert   = syscfg_reset_assert,
+       .deassert = syscfg_reset_deassert,
+};
+
+static int syscfg_reset_controller_register(struct device *dev,
+                               const struct syscfg_reset_controller_data *data)
+{
+       struct syscfg_reset_controller *rc;
+       size_t size;
+       int i, err;
+
+       rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL);
+       if (!rc)
+               return -ENOMEM;
+
+       size = sizeof(struct syscfg_reset_channel) * data->nr_channels;
+
+       rc->channels = devm_kzalloc(dev, size, GFP_KERNEL);
+       if (!rc->channels)
+               return -ENOMEM;
+
+       rc->rst.ops = &syscfg_reset_ops,
+       rc->rst.of_node = dev->of_node;
+       rc->rst.nr_resets = data->nr_channels;
+       rc->active_low = data->active_low;
+
+       for (i = 0; i < data->nr_channels; i++) {
+               struct regmap *map;
+               struct regmap_field *f;
+               const char *compatible = data->channels[i].compatible;
+
+               map = syscon_regmap_lookup_by_compatible(compatible);
+               if (IS_ERR(map))
+                       return PTR_ERR(map);
+
+               f = devm_regmap_field_alloc(dev, map, data->channels[i].reset);
+               if (IS_ERR(f))
+                       return PTR_ERR(f);
+
+               rc->channels[i].reset = f;
+
+               if (!data->wait_for_ack)
+                       continue;
+
+               f = devm_regmap_field_alloc(dev, map, data->channels[i].ack);
+               if (IS_ERR(f))
+                       return PTR_ERR(f);
+
+               rc->channels[i].ack = f;
+       }
+
+       err = reset_controller_register(&rc->rst);
+       if (!err)
+               dev_info(dev, "registered\n");
+
+       return err;
+}
+
+int syscfg_reset_probe(struct platform_device *pdev)
+{
+       struct device *dev = pdev ? &pdev->dev : NULL;
+       const struct of_device_id *match;
+
+       if (!dev || !dev->driver)
+               return -ENODEV;
+
+       match = of_match_device(dev->driver->of_match_table, dev);
+       if (!match || !match->data)
+               return -EINVAL;
+
+       return syscfg_reset_controller_register(dev, match->data);
+}
diff --git a/drivers/reset/sti/reset-syscfg.h b/drivers/reset/sti/reset-syscfg.h
new file mode 100644 (file)
index 0000000..2cc2283
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ * Author: Stephen Gallimore <stephen.gallimore@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __STI_RESET_SYSCFG_H
+#define __STI_RESET_SYSCFG_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+/**
+ * Reset channel description for a system configuration register based
+ * reset controller.
+ *
+ * @compatible: Compatible string of the syscon regmap containing this
+ *              channel's control and ack (status) bits.
+ * @reset: Regmap field description of the channel's reset bit.
+ * @ack: Regmap field description of the channel's acknowledge bit.
+ */
+struct syscfg_reset_channel_data {
+       const char *compatible;
+       struct reg_field reset;
+       struct reg_field ack;
+};
+
+#define _SYSCFG_RST_CH(_c, _rr, _rb, _ar, _ab)         \
+       { .compatible   = _c,                           \
+         .reset        = REG_FIELD(_rr, _rb, _rb),     \
+         .ack          = REG_FIELD(_ar, _ab, _ab), }
+
+#define _SYSCFG_RST_CH_NO_ACK(_c, _rr, _rb)            \
+       { .compatible   = _c,                   \
+         .reset        = REG_FIELD(_rr, _rb, _rb), }
+
+/**
+ * Description of a system configuration register based reset controller.
+ *
+ * @wait_for_ack: The controller will wait for reset assert and de-assert to
+ *                be "ack'd" in a channel's ack field.
+ * @active_low: Are the resets in this controller active low, i.e. clearing
+ *              the reset bit puts the hardware into reset.
+ * @nr_channels: The number of reset channels in this controller.
+ * @channels: An array of reset channel descriptions.
+ */
+struct syscfg_reset_controller_data {
+       bool wait_for_ack;
+       bool active_low;
+       int nr_channels;
+       const struct syscfg_reset_channel_data *channels;
+};
+
+/**
+ * syscfg_reset_probe(): platform device probe function used by syscfg
+ *                       reset controller drivers. This registers a reset
+ *                       controller configured by the OF match data for
+ *                       the compatible device which should be of type
+ *                       "struct syscfg_reset_controller_data".
+ *
+ * @pdev: platform device
+ */
+int syscfg_reset_probe(struct platform_device *pdev);
+
+#endif /* __STI_RESET_SYSCFG_H */
index 309b8b342d9c885ef544e53fc28688d988cd3573..59637430453226c0a7526c44bdba2a3b529030e6 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <mach/at91_rtt.h>
 #include <mach/cpu.h>
-
+#include <mach/hardware.h>
 
 /*
  * This driver uses two configurable hardware resources that live in the
index 7e5ead936a04b5ef5b07c20c8bbd689a10ef0d3a..41bd76aaff7661b11bf12aa327f9edde095b5985 100644 (file)
@@ -274,10 +274,7 @@ static int isl12057_probe(struct i2c_client *client,
        dev_set_drvdata(dev, data);
 
        rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc))
-               return PTR_ERR(rtc);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(rtc);
 }
 
 #ifdef CONFIG_OF
index d536c5962c99f1e6477f63b377e7445c354c5d14..d15a999363fce2808cfcba6089cf8282dfedc48a 100644 (file)
@@ -222,6 +222,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
        struct resource *res;
        struct rtc_plat_data *pdata;
        u32 rtc_time;
+       u32 rtc_date;
        int ret = 0;
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -257,6 +258,17 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
                }
        }
 
+       /*
+        * A date after January 19th, 2038 does not fit on 32 bits and
+        * will confuse the kernel and userspace. Reset to a sane date
+        * (January 1st, 2013) if we're after 2038.
+        */
+       rtc_date = readl(pdata->ioaddr + RTC_DATE_REG_OFFS);
+       if (bcd2bin((rtc_date >> RTC_YEAR_OFFS) & 0xff) >= 38) {
+               dev_info(&pdev->dev, "invalid RTC date, resetting to January 1st, 2013\n");
+               writel(0x130101, pdata->ioaddr + RTC_DATE_REG_OFFS);
+       }
+
        pdata->irq = platform_get_irq(pdev, 0);
 
        platform_set_drvdata(pdev, pdata);
index a355f2b82bb8f24e6fb27346890b92bd0e02d584..cccbf9d89729a51b517aa9948541127627a51885 100644 (file)
@@ -32,7 +32,6 @@
 
 #include <mach/hardware.h>
 
-#define TIMER_FREQ             CLOCK_TICK_RATE
 #define RTC_DEF_DIVIDER                (32768 - 1)
 #define RTC_DEF_TRIM           0
 #define MAXFREQ_PERIODIC       1000
index 6287f6a8b79d6c37b3b93d3509c11350c57d29bd..1d41f4b9114f8253e780d279799dad0ac0d27e04 100644 (file)
@@ -2592,12 +2592,16 @@ static int __init bnx2fc_mod_init(void)
                spin_lock_init(&p->fp_work_lock);
        }
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(cpu) {
                bnx2fc_percpu_thread_create(cpu);
        }
 
        /* Initialize per CPU interrupt thread */
-       register_hotcpu_notifier(&bnx2fc_cpu_notifier);
+       __register_hotcpu_notifier(&bnx2fc_cpu_notifier);
+
+       cpu_notifier_register_done();
 
        cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb);
 
@@ -2662,13 +2666,17 @@ static void __exit bnx2fc_mod_exit(void)
        if (l2_thread)
                kthread_stop(l2_thread);
 
-       unregister_hotcpu_notifier(&bnx2fc_cpu_notifier);
+       cpu_notifier_register_begin();
 
        /* Destroy per cpu threads */
        for_each_online_cpu(cpu) {
                bnx2fc_percpu_thread_destroy(cpu);
        }
 
+       __unregister_hotcpu_notifier(&bnx2fc_cpu_notifier);
+
+       cpu_notifier_register_done();
+
        destroy_workqueue(bnx2fc_wq);
        /*
         * detach from scsi transport
index 34c294b42c84e0353d4049737a72c9d3b57dc61a..80c03b452d61960cbe3df5d198fc409e7c49a9e9 100644 (file)
@@ -537,11 +537,15 @@ static int __init bnx2i_mod_init(void)
                p->iothread = NULL;
        }
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(cpu)
                bnx2i_percpu_thread_create(cpu);
 
        /* Initialize per CPU interrupt thread */
-       register_hotcpu_notifier(&bnx2i_cpu_notifier);
+       __register_hotcpu_notifier(&bnx2i_cpu_notifier);
+
+       cpu_notifier_register_done();
 
        return 0;
 
@@ -581,11 +585,15 @@ static void __exit bnx2i_mod_exit(void)
        }
        mutex_unlock(&bnx2i_dev_lock);
 
-       unregister_hotcpu_notifier(&bnx2i_cpu_notifier);
+       cpu_notifier_register_begin();
 
        for_each_online_cpu(cpu)
                bnx2i_percpu_thread_destroy(cpu);
 
+       __unregister_hotcpu_notifier(&bnx2i_cpu_notifier);
+
+       cpu_notifier_register_done();
+
        iscsi_unregister_transport(&bnx2i_iscsi_transport);
        cnic_unregister_driver(CNIC_ULP_ISCSI);
 }
index f3170008ae71b9b84de3c05b443a600d96e4396d..d5e105b173f0cf121894fcb5105a5afedadc16d5 100644 (file)
@@ -2633,14 +2633,18 @@ static int __init fcoe_init(void)
                skb_queue_head_init(&p->fcoe_rx_list);
        }
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(cpu)
                fcoe_percpu_thread_create(cpu);
 
        /* Initialize per CPU interrupt thread */
-       rc = register_hotcpu_notifier(&fcoe_cpu_notifier);
+       rc = __register_hotcpu_notifier(&fcoe_cpu_notifier);
        if (rc)
                goto out_free;
 
+       cpu_notifier_register_done();
+
        /* Setup link change notification */
        fcoe_dev_setup();
 
@@ -2655,6 +2659,9 @@ out_free:
        for_each_online_cpu(cpu) {
                fcoe_percpu_thread_destroy(cpu);
        }
+
+       cpu_notifier_register_done();
+
        mutex_unlock(&fcoe_config_mutex);
        destroy_workqueue(fcoe_wq);
        return rc;
@@ -2687,11 +2694,15 @@ static void __exit fcoe_exit(void)
        }
        rtnl_unlock();
 
-       unregister_hotcpu_notifier(&fcoe_cpu_notifier);
+       cpu_notifier_register_begin();
 
        for_each_online_cpu(cpu)
                fcoe_percpu_thread_destroy(cpu);
 
+       __unregister_hotcpu_notifier(&fcoe_cpu_notifier);
+
+       cpu_notifier_register_done();
+
        mutex_unlock(&fcoe_config_mutex);
 
        /*
index 1ebe67cd18333c3b39f98d0e2badcd7b0a948090..7442bc130055c3745e02a7a1e4503742335513b5 100644 (file)
@@ -36,9 +36,47 @@ static void sh_clk_write(int value, struct clk *clk)
                iowrite32(value, clk->mapped_reg);
 }
 
+static unsigned int r8(const void __iomem *addr)
+{
+       return ioread8(addr);
+}
+
+static unsigned int r16(const void __iomem *addr)
+{
+       return ioread16(addr);
+}
+
+static unsigned int r32(const void __iomem *addr)
+{
+       return ioread32(addr);
+}
+
 static int sh_clk_mstp_enable(struct clk *clk)
 {
        sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk);
+       if (clk->status_reg) {
+               unsigned int (*read)(const void __iomem *addr);
+               int i;
+               void __iomem *mapped_status = (phys_addr_t)clk->status_reg -
+                       (phys_addr_t)clk->enable_reg + clk->mapped_reg;
+
+               if (clk->flags & CLK_ENABLE_REG_8BIT)
+                       read = r8;
+               else if (clk->flags & CLK_ENABLE_REG_16BIT)
+                       read = r16;
+               else
+                       read = r32;
+
+               for (i = 1000;
+                    (read(mapped_status) & (1 << clk->enable_bit)) && i;
+                    i--)
+                       cpu_relax();
+               if (!i) {
+                       pr_err("cpg: failed to enable %p[%d]\n",
+                              clk->enable_reg, clk->enable_bit);
+                       return -ETIMEDOUT;
+               }
+       }
        return 0;
 }
 
index a305731742a9343958064f81b5635855e130d35a..f7d90617c9d9ca3fb4340d887e221b6bf55e3d11 100644 (file)
@@ -6,7 +6,7 @@ comment "Interrupt controller options"
 
 config INTC_USERIMASK
        bool "Userspace interrupt masking support"
-       depends on ARCH_SHMOBILE || (SUPERH && CPU_SH4A)
+       depends on ARCH_SHMOBILE || (SUPERH && CPU_SH4A) || COMPILE_TEST
        help
          This enables support for hardware-assisted userspace hardirq
          masking.
index eefdb8d061b16f6505fc9179665354d7cac000c8..81cc7a0134bb6693e7c5fd9a97ef7085d88943dd 100644 (file)
@@ -105,8 +105,8 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
 #define ll_vfs_unlink(inode,entry,mnt)   vfs_unlink(inode,entry)
 #define ll_vfs_mknod(dir,entry,mnt,mode,dev)    vfs_mknod(dir,entry,mode,dev)
 #define ll_security_inode_unlink(dir,entry,mnt) security_inode_unlink(dir,entry)
-#define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1,delegated_inode) \
-               vfs_rename(old,old_dir,new,new_dir,delegated_inode)
+#define ll_vfs_rename(old, old_dir, mnt, new, new_dir, mnt1) \
+               vfs_rename(old, old_dir, new, new_dir, NULL, 0)
 
 #define cfs_bio_io_error(a,b)   bio_io_error((a))
 #define cfs_bio_endio(a,b,c)    bio_endio((a),(c))
index e44b7a532de79237a166589093d983dfdb3a1d41..374a9b78e1d2802f247bdbb5e2c3ecf54ad0904d 100644 (file)
@@ -223,7 +223,7 @@ int lustre_rename(struct dentry *dir, struct vfsmount *mnt,
                GOTO(put_old, err = PTR_ERR(dchild_new));
 
        err = ll_vfs_rename(dir->d_inode, dchild_old, mnt,
-                           dir->d_inode, dchild_new, mnt, NULL);
+                           dir->d_inode, dchild_new, mnt);
 
        dput(dchild_new);
 put_old:
index 22b0c9d6f0464059257ac552119287f621e8c9cb..a9f2e63a7c9c21a3690eb2c3913d6d0507fb1a38 100644 (file)
@@ -41,6 +41,8 @@ source "drivers/staging/media/solo6x10/Kconfig"
 
 source "drivers/staging/media/omap4iss/Kconfig"
 
+source "drivers/staging/media/rtl2832u_sdr/Kconfig"
+
 # Keep LIRC at the end, as it has sub-menus
 source "drivers/staging/media/lirc/Kconfig"
 
index bedc62aaede68f9a27e42aa4a380c6ca7bfed551..8e2c5d272162619803e7f4059d7fd3d8563bfd23 100644 (file)
@@ -11,3 +11,5 @@ obj-$(CONFIG_VIDEO_OMAP4)     += omap4iss/
 obj-$(CONFIG_USB_SN9C102)       += sn9c102/
 obj-$(CONFIG_VIDEO_OMAP2)       += omap24xx/
 obj-$(CONFIG_VIDEO_TCM825X)     += omap24xx/
+obj-$(CONFIG_DVB_RTL2832_SDR)  += rtl2832u_sdr/
+
index 2d36b60bdbf166e369049e82ef2ce3f15de26f45..b2daf5e63f88da0297555afe0b52264747e79e92 100644 (file)
@@ -267,7 +267,7 @@ int config_ipipe_hw(struct vpfe_ipipe_device *ipipe)
        }
 
        ipipe_mode = get_ipipe_mode(ipipe);
-       if (ipipe < 0) {
+       if (ipipe_mode < 0) {
                pr_err("Failed to get ipipe mode");
                return -EINVAL;
        }
index d8ce20d2fbda54f35fe5a12031cf391230719f69..cda8388cbb89862f126803aa22b328fce884a0f5 100644 (file)
@@ -298,7 +298,7 @@ static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
 {
        int ret = 0;
 
-       ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
+       ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
                          "vpfe_capture0", vpfe_dev);
        if (ret < 0) {
                v4l2_err(&vpfe_dev->v4l2_dev,
@@ -306,7 +306,7 @@ static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
                return ret;
        }
 
-       ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, IRQF_DISABLED,
+       ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
                          "vpfe_capture1", vpfe_dev);
        if (ret < 0) {
                v4l2_err(&vpfe_dev->v4l2_dev,
@@ -316,7 +316,7 @@ static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
        }
 
        ret = request_irq(vpfe_dev->imp_dma_irq, vpfe_imp_dma_isr,
-                         IRQF_DISABLED, "Imp_Sdram_Irq", vpfe_dev);
+                         0, "Imp_Sdram_Irq", vpfe_dev);
        if (ret < 0) {
                v4l2_err(&vpfe_dev->v4l2_dev,
                         "Error: requesting IMP IRQ interrupt\n");
index 1f3b0f9a8d102e2852603dc376c79b79ceae9323..8c101cbbee97646d2b06166865381bf9144df2cb 100644 (file)
@@ -1201,8 +1201,6 @@ static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count)
        unsigned long addr;
        int ret;
 
-       if (count == 0)
-               return -ENOBUFS;
        ret = mutex_lock_interruptible(&video->lock);
        if (ret)
                goto streamoff;
@@ -1327,6 +1325,7 @@ static int vpfe_reqbufs(struct file *file, void *priv,
        q->type = req_buf->type;
        q->io_modes = VB2_MMAP | VB2_USERPTR;
        q->drv_priv = fh;
+       q->min_buffers_needed = 1;
        q->ops = &video_qops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct vpfe_cap_buffer);
index 97e7a9b48ac2e51bbd7655dfb8b10920d889d28a..afbc2e51960619f6b53bcdf962ed2a9ed88f70fe 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "dt3155v4l.h"
 
-#define DT3155_VENDOR_ID 0x8086
 #define DT3155_DEVICE_ID 0x1223
 
 /* DT3155_CHUNK_SIZE is 4M (2^22) 8 full size buffers */
@@ -391,7 +390,7 @@ dt3155_open(struct file *filp)
                        goto err_alloc_queue;
                }
                pd->q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               pd->q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+               pd->q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
                pd->q->io_modes = VB2_READ | VB2_MMAP;
                pd->q->ops = &q_ops;
                pd->q->mem_ops = &vb2_dma_contig_memops;
@@ -975,7 +974,7 @@ dt3155_remove(struct pci_dev *pdev)
 }
 
 static const struct pci_device_id pci_ids[] = {
-       { PCI_DEVICE(DT3155_VENDOR_ID, DT3155_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, DT3155_DEVICE_ID) },
        { 0, /* zero marks the end */ },
 };
 MODULE_DEVICE_TABLE(pci, pci_ids);
index bdf414e19c8f7ca94ebd35b93125288ae320d2ff..b397aa3c0f443c0ae5ae138f09f0a30a70463fd3 100644 (file)
@@ -471,7 +471,7 @@ static int go7007_buf_prepare(struct vb2_buffer *vb)
        return 0;
 }
 
-static int go7007_buf_finish(struct vb2_buffer *vb)
+static void go7007_buf_finish(struct vb2_buffer *vb)
 {
        struct vb2_queue *vq = vb->vb2_queue;
        struct go7007 *go = vb2_get_drv_priv(vq);
@@ -484,7 +484,6 @@ static int go7007_buf_finish(struct vb2_buffer *vb)
                        V4L2_BUF_FLAG_PFRAME);
        buf->flags |= frame_type_flag;
        buf->field = V4L2_FIELD_NONE;
-       return 0;
 }
 
 static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
@@ -995,7 +994,7 @@ int go7007_v4l2_init(struct go7007 *go)
        go->vidq.mem_ops = &vb2_vmalloc_memops;
        go->vidq.drv_priv = go;
        go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
-       go->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        go->vidq.lock = &go->queue_lock;
        rv = vb2_queue_init(&go->vidq);
        if (rv)
index 0c349c8595e44d542c4625de893cc709ca1acfe7..de0b3bba387304a8d1a946d22aa46cb7d8f4aae6 100644 (file)
@@ -1,5 +1,10 @@
 config USB_MSI3101
        tristate "Mirics MSi3101 SDR Dongle"
-       depends on USB && VIDEO_DEV && VIDEO_V4L2
+       depends on USB && VIDEO_DEV && VIDEO_V4L2 && SPI
        select VIDEOBUF2_CORE
        select VIDEOBUF2_VMALLOC
+       select MEDIA_TUNER_MSI001
+
+config MEDIA_TUNER_MSI001
+       tristate "Mirics MSi001"
+       depends on VIDEO_V4L2 && SPI
index 3730654b0eb951eab39e678b0dbe1135e22ef2de..daf4f58d9a5619171cb7d902ec9579e78b6a790d 100644 (file)
@@ -1 +1,2 @@
 obj-$(CONFIG_USB_MSI3101)             += sdr-msi3101.o
+obj-$(CONFIG_MEDIA_TUNER_MSI001)      += msi001.o
diff --git a/drivers/staging/media/msi3101/msi001.c b/drivers/staging/media/msi3101/msi001.c
new file mode 100644 (file)
index 0000000..ac43bae
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * Mirics MSi001 silicon tuner driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
+ *
+ *    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/gcd.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+static const struct v4l2_frequency_band bands[] = {
+       {
+               .type = V4L2_TUNER_RF,
+               .index = 0,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   =   49000000,
+               .rangehigh  =  263000000,
+       }, {
+               .type = V4L2_TUNER_RF,
+               .index = 1,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   =  390000000,
+               .rangehigh  =  960000000,
+       },
+};
+
+struct msi001 {
+       struct spi_device *spi;
+       struct v4l2_subdev sd;
+
+       /* Controls */
+       struct v4l2_ctrl_handler hdl;
+       struct v4l2_ctrl *bandwidth_auto;
+       struct v4l2_ctrl *bandwidth;
+       struct v4l2_ctrl *lna_gain;
+       struct v4l2_ctrl *mixer_gain;
+       struct v4l2_ctrl *if_gain;
+
+       unsigned int f_tuner;
+};
+
+static inline struct msi001 *sd_to_msi001(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct msi001, sd);
+}
+
+static int msi001_wreg(struct msi001 *s, u32 data)
+{
+       /* Register format: 4 bits addr + 20 bits value */
+       return spi_write(s->spi, &data, 3);
+};
+
+static int msi001_set_gain(struct msi001 *s, int lna_gain, int mixer_gain,
+               int if_gain)
+{
+       int ret;
+       u32 reg;
+       dev_dbg(&s->spi->dev, "%s: lna=%d mixer=%d if=%d\n", __func__,
+                       lna_gain, mixer_gain, if_gain);
+
+       reg = 1 << 0;
+       reg |= (59 - if_gain) << 4;
+       reg |= 0 << 10;
+       reg |= (1 - mixer_gain) << 12;
+       reg |= (1 - lna_gain) << 13;
+       reg |= 4 << 14;
+       reg |= 0 << 17;
+       ret = msi001_wreg(s, reg);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&s->spi->dev, "%s: failed %d\n", __func__, ret);
+       return ret;
+};
+
+static int msi001_set_tuner(struct msi001 *s)
+{
+       int ret, i;
+       unsigned int n, m, thresh, frac, vco_step, tmp, f_if1;
+       u32 reg;
+       u64 f_vco, tmp64;
+       u8 mode, filter_mode, lo_div;
+       static const struct {
+               u32 rf;
+               u8 mode;
+               u8 lo_div;
+       } band_lut[] = {
+               { 50000000, 0xe1, 16}, /* AM_MODE2, antenna 2 */
+               {108000000, 0x42, 32}, /* VHF_MODE */
+               {330000000, 0x44, 16}, /* B3_MODE */
+               {960000000, 0x48,  4}, /* B45_MODE */
+               {      ~0U, 0x50,  2}, /* BL_MODE */
+       };
+       static const struct {
+               u32 freq;
+               u8 filter_mode;
+       } if_freq_lut[] = {
+               {      0, 0x03}, /* Zero IF */
+               { 450000, 0x02}, /* 450 kHz IF */
+               {1620000, 0x01}, /* 1.62 MHz IF */
+               {2048000, 0x00}, /* 2.048 MHz IF */
+       };
+       static const struct {
+               u32 freq;
+               u8 val;
+       } bandwidth_lut[] = {
+               { 200000, 0x00}, /* 200 kHz */
+               { 300000, 0x01}, /* 300 kHz */
+               { 600000, 0x02}, /* 600 kHz */
+               {1536000, 0x03}, /* 1.536 MHz */
+               {5000000, 0x04}, /* 5 MHz */
+               {6000000, 0x05}, /* 6 MHz */
+               {7000000, 0x06}, /* 7 MHz */
+               {8000000, 0x07}, /* 8 MHz */
+       };
+
+       unsigned int f_rf = s->f_tuner;
+
+       /*
+        * bandwidth (Hz)
+        * 200000, 300000, 600000, 1536000, 5000000, 6000000, 7000000, 8000000
+        */
+       unsigned int bandwidth;
+
+       /*
+        * intermediate frequency (Hz)
+        * 0, 450000, 1620000, 2048000
+        */
+       unsigned int f_if = 0;
+       #define F_REF 24000000
+       #define R_REF 4
+       #define F_OUT_STEP 1
+
+       dev_dbg(&s->spi->dev,
+                       "%s: f_rf=%d f_if=%d\n",
+                       __func__, f_rf, f_if);
+
+       for (i = 0; i < ARRAY_SIZE(band_lut); i++) {
+               if (f_rf <= band_lut[i].rf) {
+                       mode = band_lut[i].mode;
+                       lo_div = band_lut[i].lo_div;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(band_lut)) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* AM_MODE is upconverted */
+       if ((mode >> 0) & 0x1)
+               f_if1 =  5 * F_REF;
+       else
+               f_if1 =  0;
+
+       for (i = 0; i < ARRAY_SIZE(if_freq_lut); i++) {
+               if (f_if == if_freq_lut[i].freq) {
+                       filter_mode = if_freq_lut[i].filter_mode;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(if_freq_lut)) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* filters */
+       bandwidth = s->bandwidth->val;
+       bandwidth = clamp(bandwidth, 200000U, 8000000U);
+
+       for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
+               if (bandwidth <= bandwidth_lut[i].freq) {
+                       bandwidth = bandwidth_lut[i].val;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(bandwidth_lut)) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       s->bandwidth->val = bandwidth_lut[i].freq;
+
+       dev_dbg(&s->spi->dev, "%s: bandwidth selected=%d\n",
+                       __func__, bandwidth_lut[i].freq);
+
+       f_vco = (f_rf + f_if + f_if1) * lo_div;
+       tmp64 = f_vco;
+       m = do_div(tmp64, F_REF * R_REF);
+       n = (unsigned int) tmp64;
+
+       vco_step = F_OUT_STEP * lo_div;
+       thresh = (F_REF * R_REF) / vco_step;
+       frac = 1ul * thresh * m / (F_REF * R_REF);
+
+       /* Find out greatest common divisor and divide to smaller. */
+       tmp = gcd(thresh, frac);
+       thresh /= tmp;
+       frac /= tmp;
+
+       /* Force divide to reg max. Resolution will be reduced. */
+       tmp = DIV_ROUND_UP(thresh, 4095);
+       thresh = DIV_ROUND_CLOSEST(thresh, tmp);
+       frac = DIV_ROUND_CLOSEST(frac, tmp);
+
+       /* calc real RF set */
+       tmp = 1ul * F_REF * R_REF * n;
+       tmp += 1ul * F_REF * R_REF * frac / thresh;
+       tmp /= lo_div;
+
+       dev_dbg(&s->spi->dev,
+                       "%s: rf=%u:%u n=%d thresh=%d frac=%d\n",
+                               __func__, f_rf, tmp, n, thresh, frac);
+
+       ret = msi001_wreg(s, 0x00000e);
+       if (ret)
+               goto err;
+
+       ret = msi001_wreg(s, 0x000003);
+       if (ret)
+               goto err;
+
+       reg = 0 << 0;
+       reg |= mode << 4;
+       reg |= filter_mode << 12;
+       reg |= bandwidth << 14;
+       reg |= 0x02 << 17;
+       reg |= 0x00 << 20;
+       ret = msi001_wreg(s, reg);
+       if (ret)
+               goto err;
+
+       reg = 5 << 0;
+       reg |= thresh << 4;
+       reg |= 1 << 19;
+       reg |= 1 << 21;
+       ret = msi001_wreg(s, reg);
+       if (ret)
+               goto err;
+
+       reg = 2 << 0;
+       reg |= frac << 4;
+       reg |= n << 16;
+       ret = msi001_wreg(s, reg);
+       if (ret)
+               goto err;
+
+       ret = msi001_set_gain(s, s->lna_gain->cur.val, s->mixer_gain->cur.val,
+                       s->if_gain->cur.val);
+       if (ret)
+               goto err;
+
+       reg = 6 << 0;
+       reg |= 63 << 4;
+       reg |= 4095 << 10;
+       ret = msi001_wreg(s, reg);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&s->spi->dev, "%s: failed %d\n", __func__, ret);
+       return ret;
+};
+
+static int msi001_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct msi001 *s = sd_to_msi001(sd);
+       int ret;
+       dev_dbg(&s->spi->dev, "%s: on=%d\n", __func__, on);
+
+       if (on)
+               ret = 0;
+       else
+               ret = msi001_wreg(s, 0x000000);
+
+       return ret;
+}
+
+static const struct v4l2_subdev_core_ops msi001_core_ops = {
+       .s_power                  = msi001_s_power,
+};
+
+static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
+{
+       struct msi001 *s = sd_to_msi001(sd);
+       dev_dbg(&s->spi->dev, "%s: index=%d\n", __func__, v->index);
+
+       strlcpy(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;
+       v->rangehigh =  960000000;
+
+       return 0;
+}
+
+static int msi001_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v)
+{
+       struct msi001 *s = sd_to_msi001(sd);
+       dev_dbg(&s->spi->dev, "%s: index=%d\n", __func__, v->index);
+       return 0;
+}
+
+static int msi001_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+       struct msi001 *s = sd_to_msi001(sd);
+       dev_dbg(&s->spi->dev, "%s: tuner=%d\n", __func__, f->tuner);
+       f->frequency = s->f_tuner;
+       return 0;
+}
+
+static int msi001_s_frequency(struct v4l2_subdev *sd,
+               const struct v4l2_frequency *f)
+{
+       struct msi001 *s = sd_to_msi001(sd);
+       unsigned int band;
+       dev_dbg(&s->spi->dev, "%s: tuner=%d type=%d frequency=%u\n",
+                       __func__, f->tuner, f->type, f->frequency);
+
+       if (f->frequency < ((bands[0].rangehigh + bands[1].rangelow) / 2))
+               band = 0;
+       else
+               band = 1;
+       s->f_tuner = clamp_t(unsigned int, f->frequency,
+                       bands[band].rangelow, bands[band].rangehigh);
+
+       return msi001_set_tuner(s);
+}
+
+static int msi001_enum_freq_bands(struct v4l2_subdev *sd,
+               struct v4l2_frequency_band *band)
+{
+       struct msi001 *s = sd_to_msi001(sd);
+       dev_dbg(&s->spi->dev, "%s: tuner=%d type=%d index=%d\n",
+                       __func__, band->tuner, band->type, band->index);
+
+       if (band->index >= ARRAY_SIZE(bands))
+               return -EINVAL;
+
+       band->capability = bands[band->index].capability;
+       band->rangelow = bands[band->index].rangelow;
+       band->rangehigh = bands[band->index].rangehigh;
+
+       return 0;
+}
+
+static const struct v4l2_subdev_tuner_ops msi001_tuner_ops = {
+       .g_tuner                  = msi001_g_tuner,
+       .s_tuner                  = msi001_s_tuner,
+       .g_frequency              = msi001_g_frequency,
+       .s_frequency              = msi001_s_frequency,
+       .enum_freq_bands          = msi001_enum_freq_bands,
+};
+
+static const struct v4l2_subdev_ops msi001_ops = {
+       .core                     = &msi001_core_ops,
+       .tuner                    = &msi001_tuner_ops,
+};
+
+static int msi001_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct msi001 *s = container_of(ctrl->handler, struct msi001, hdl);
+
+       int ret;
+       dev_dbg(&s->spi->dev,
+                       "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
+                       __func__, ctrl->id, ctrl->name, ctrl->val,
+                       ctrl->minimum, ctrl->maximum, ctrl->step);
+
+       switch (ctrl->id) {
+       case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
+       case V4L2_CID_RF_TUNER_BANDWIDTH:
+               ret = msi001_set_tuner(s);
+               break;
+       case  V4L2_CID_RF_TUNER_LNA_GAIN:
+               ret = msi001_set_gain(s, s->lna_gain->val,
+                               s->mixer_gain->cur.val, s->if_gain->cur.val);
+               break;
+       case  V4L2_CID_RF_TUNER_MIXER_GAIN:
+               ret = msi001_set_gain(s, s->lna_gain->cur.val,
+                               s->mixer_gain->val, s->if_gain->cur.val);
+               break;
+       case  V4L2_CID_RF_TUNER_IF_GAIN:
+               ret = msi001_set_gain(s, s->lna_gain->cur.val,
+                               s->mixer_gain->cur.val, s->if_gain->val);
+               break;
+       default:
+               dev_dbg(&s->spi->dev, "%s: unkown control %d\n",
+                               __func__, ctrl->id);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops msi001_ctrl_ops = {
+       .s_ctrl                   = msi001_s_ctrl,
+};
+
+static int msi001_probe(struct spi_device *spi)
+{
+       struct msi001 *s;
+       int ret;
+       dev_dbg(&spi->dev, "%s:\n", __func__);
+
+       s = kzalloc(sizeof(struct msi001), GFP_KERNEL);
+       if (s == NULL) {
+               ret = -ENOMEM;
+               dev_dbg(&spi->dev, "Could not allocate memory for msi001\n");
+               goto err_kfree;
+       }
+
+       s->spi = spi;
+       s->f_tuner = bands[0].rangelow;
+       v4l2_spi_subdev_init(&s->sd, spi, &msi001_ops);
+
+       /* Register controls */
+       v4l2_ctrl_handler_init(&s->hdl, 5);
+       s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
+                       V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
+       s->bandwidth = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
+                       V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000);
+       v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
+       s->lna_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
+                       V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1);
+       s->mixer_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
+                       V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1);
+       s->if_gain = v4l2_ctrl_new_std(&s->hdl, &msi001_ctrl_ops,
+                       V4L2_CID_RF_TUNER_IF_GAIN, 0, 59, 1, 0);
+       if (s->hdl.error) {
+               ret = s->hdl.error;
+               dev_err(&s->spi->dev, "Could not initialize controls\n");
+               /* control init failed, free handler */
+               goto err_ctrl_handler_free;
+       }
+
+       s->sd.ctrl_handler = &s->hdl;
+       return 0;
+
+err_ctrl_handler_free:
+       v4l2_ctrl_handler_free(&s->hdl);
+err_kfree:
+       kfree(s);
+       return ret;
+}
+
+static int msi001_remove(struct spi_device *spi)
+{
+       struct v4l2_subdev *sd = spi_get_drvdata(spi);
+       struct msi001 *s = sd_to_msi001(sd);
+       dev_dbg(&spi->dev, "%s:\n", __func__);
+
+       /*
+        * Registered by v4l2_spi_new_subdev() from master driver, but we must
+        * unregister it from here. Weird.
+        */
+       v4l2_device_unregister_subdev(&s->sd);
+       v4l2_ctrl_handler_free(&s->hdl);
+       kfree(s);
+       return 0;
+}
+
+static const struct spi_device_id msi001_id[] = {
+       {"msi001", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(spi, msi001_id);
+
+static struct spi_driver msi001_driver = {
+       .driver = {
+               .name   = "msi001",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = msi001_probe,
+       .remove         = msi001_remove,
+       .id_table       = msi001_id,
+};
+module_spi_driver(msi001_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Mirics MSi001");
+MODULE_LICENSE("GPL");
index 5a0400fdb98cc9aaca6df3ff903dc6a5e6732b93..260d1b7367212637a70e79ed4628f2025777b263 100644 (file)
  *  (C) 1999-2004 Nemosoft Unv.
  *  (C) 2004-2006 Luc Saillard (luc@saillard.org)
  *  (C) 2011 Hans de Goede <hdegoede@redhat.com>
- *
- * Development tree of that driver will be on:
- * http://git.linuxtv.org/anttip/media_tree.git/shortlog/refs/heads/mirics
- *
- * GNU Radio plugin "gr-kernel" for device usage will be on:
- * http://git.linuxtv.org/anttip/gr-kernel.git
- *
- * TODO:
- * Help is very highly welcome for these + all the others you could imagine:
- * - split USB ADC interface and RF tuner to own drivers (msi2500 and msi001)
- * - move controls to V4L2 API
- * - use libv4l2 for stream format conversions
- * - gr-kernel: switch to v4l2_mmap (current read eats a lot of cpu)
- * - SDRSharp support
  */
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/gcd.h>
 #include <asm/div64.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
 #include <linux/usb.h>
 #include <media/videobuf2-vmalloc.h>
-
-struct msi3101_gain {
-       u8 tot:7;
-       u8 baseband:6;
-       bool lna:1;
-       bool mixer:1;
-};
-
-/* 60 â€“ 120 MHz band, lna 24dB, mixer 19dB */
-static const struct msi3101_gain msi3101_gain_lut_120[] = {
-       {  0,  0,  0,  0},
-       {  1,  1,  0,  0},
-       {  2,  2,  0,  0},
-       {  3,  3,  0,  0},
-       {  4,  4,  0,  0},
-       {  5,  5,  0,  0},
-       {  6,  6,  0,  0},
-       {  7,  7,  0,  0},
-       {  8,  8,  0,  0},
-       {  9,  9,  0,  0},
-       { 10, 10,  0,  0},
-       { 11, 11,  0,  0},
-       { 12, 12,  0,  0},
-       { 13, 13,  0,  0},
-       { 14, 14,  0,  0},
-       { 15, 15,  0,  0},
-       { 16, 16,  0,  0},
-       { 17, 17,  0,  0},
-       { 18, 18,  0,  0},
-       { 19, 19,  0,  0},
-       { 20, 20,  0,  0},
-       { 21, 21,  0,  0},
-       { 22, 22,  0,  0},
-       { 23, 23,  0,  0},
-       { 24, 24,  0,  0},
-       { 25, 25,  0,  0},
-       { 26, 26,  0,  0},
-       { 27, 27,  0,  0},
-       { 28, 28,  0,  0},
-       { 29,  5,  1,  0},
-       { 30,  6,  1,  0},
-       { 31,  7,  1,  0},
-       { 32,  8,  1,  0},
-       { 33,  9,  1,  0},
-       { 34, 10,  1,  0},
-       { 35, 11,  1,  0},
-       { 36, 12,  1,  0},
-       { 37, 13,  1,  0},
-       { 38, 14,  1,  0},
-       { 39, 15,  1,  0},
-       { 40, 16,  1,  0},
-       { 41, 17,  1,  0},
-       { 42, 18,  1,  0},
-       { 43, 19,  1,  0},
-       { 44, 20,  1,  0},
-       { 45, 21,  1,  0},
-       { 46, 22,  1,  0},
-       { 47, 23,  1,  0},
-       { 48, 24,  1,  0},
-       { 49, 25,  1,  0},
-       { 50, 26,  1,  0},
-       { 51, 27,  1,  0},
-       { 52, 28,  1,  0},
-       { 53, 29,  1,  0},
-       { 54, 30,  1,  0},
-       { 55, 31,  1,  0},
-       { 56, 32,  1,  0},
-       { 57, 33,  1,  0},
-       { 58, 34,  1,  0},
-       { 59, 35,  1,  0},
-       { 60, 36,  1,  0},
-       { 61, 37,  1,  0},
-       { 62, 38,  1,  0},
-       { 63, 39,  1,  0},
-       { 64, 40,  1,  0},
-       { 65, 41,  1,  0},
-       { 66, 42,  1,  0},
-       { 67, 43,  1,  0},
-       { 68, 44,  1,  0},
-       { 69, 45,  1,  0},
-       { 70, 46,  1,  0},
-       { 71, 47,  1,  0},
-       { 72, 48,  1,  0},
-       { 73, 49,  1,  0},
-       { 74, 50,  1,  0},
-       { 75, 51,  1,  0},
-       { 76, 52,  1,  0},
-       { 77, 53,  1,  0},
-       { 78, 54,  1,  0},
-       { 79, 55,  1,  0},
-       { 80, 56,  1,  0},
-       { 81, 57,  1,  0},
-       { 82, 58,  1,  0},
-       { 83, 40,  1,  1},
-       { 84, 41,  1,  1},
-       { 85, 42,  1,  1},
-       { 86, 43,  1,  1},
-       { 87, 44,  1,  1},
-       { 88, 45,  1,  1},
-       { 89, 46,  1,  1},
-       { 90, 47,  1,  1},
-       { 91, 48,  1,  1},
-       { 92, 49,  1,  1},
-       { 93, 50,  1,  1},
-       { 94, 51,  1,  1},
-       { 95, 52,  1,  1},
-       { 96, 53,  1,  1},
-       { 97, 54,  1,  1},
-       { 98, 55,  1,  1},
-       { 99, 56,  1,  1},
-       {100, 57,  1,  1},
-       {101, 58,  1,  1},
-       {102, 59,  1,  1},
-};
-
-/* 120 â€“ 245 MHz band, lna 24dB, mixer 19dB */
-static const struct msi3101_gain msi3101_gain_lut_245[] = {
-       {  0,  0,  0,  0},
-       {  1,  1,  0,  0},
-       {  2,  2,  0,  0},
-       {  3,  3,  0,  0},
-       {  4,  4,  0,  0},
-       {  5,  5,  0,  0},
-       {  6,  6,  0,  0},
-       {  7,  7,  0,  0},
-       {  8,  8,  0,  0},
-       {  9,  9,  0,  0},
-       { 10, 10,  0,  0},
-       { 11, 11,  0,  0},
-       { 12, 12,  0,  0},
-       { 13, 13,  0,  0},
-       { 14, 14,  0,  0},
-       { 15, 15,  0,  0},
-       { 16, 16,  0,  0},
-       { 17, 17,  0,  0},
-       { 18, 18,  0,  0},
-       { 19, 19,  0,  0},
-       { 20, 20,  0,  0},
-       { 21, 21,  0,  0},
-       { 22, 22,  0,  0},
-       { 23, 23,  0,  0},
-       { 24, 24,  0,  0},
-       { 25, 25,  0,  0},
-       { 26, 26,  0,  0},
-       { 27, 27,  0,  0},
-       { 28, 28,  0,  0},
-       { 29,  5,  1,  0},
-       { 30,  6,  1,  0},
-       { 31,  7,  1,  0},
-       { 32,  8,  1,  0},
-       { 33,  9,  1,  0},
-       { 34, 10,  1,  0},
-       { 35, 11,  1,  0},
-       { 36, 12,  1,  0},
-       { 37, 13,  1,  0},
-       { 38, 14,  1,  0},
-       { 39, 15,  1,  0},
-       { 40, 16,  1,  0},
-       { 41, 17,  1,  0},
-       { 42, 18,  1,  0},
-       { 43, 19,  1,  0},
-       { 44, 20,  1,  0},
-       { 45, 21,  1,  0},
-       { 46, 22,  1,  0},
-       { 47, 23,  1,  0},
-       { 48, 24,  1,  0},
-       { 49, 25,  1,  0},
-       { 50, 26,  1,  0},
-       { 51, 27,  1,  0},
-       { 52, 28,  1,  0},
-       { 53, 29,  1,  0},
-       { 54, 30,  1,  0},
-       { 55, 31,  1,  0},
-       { 56, 32,  1,  0},
-       { 57, 33,  1,  0},
-       { 58, 34,  1,  0},
-       { 59, 35,  1,  0},
-       { 60, 36,  1,  0},
-       { 61, 37,  1,  0},
-       { 62, 38,  1,  0},
-       { 63, 39,  1,  0},
-       { 64, 40,  1,  0},
-       { 65, 41,  1,  0},
-       { 66, 42,  1,  0},
-       { 67, 43,  1,  0},
-       { 68, 44,  1,  0},
-       { 69, 45,  1,  0},
-       { 70, 46,  1,  0},
-       { 71, 47,  1,  0},
-       { 72, 48,  1,  0},
-       { 73, 49,  1,  0},
-       { 74, 50,  1,  0},
-       { 75, 51,  1,  0},
-       { 76, 52,  1,  0},
-       { 77, 53,  1,  0},
-       { 78, 54,  1,  0},
-       { 79, 55,  1,  0},
-       { 80, 56,  1,  0},
-       { 81, 57,  1,  0},
-       { 82, 58,  1,  0},
-       { 83, 40,  1,  1},
-       { 84, 41,  1,  1},
-       { 85, 42,  1,  1},
-       { 86, 43,  1,  1},
-       { 87, 44,  1,  1},
-       { 88, 45,  1,  1},
-       { 89, 46,  1,  1},
-       { 90, 47,  1,  1},
-       { 91, 48,  1,  1},
-       { 92, 49,  1,  1},
-       { 93, 50,  1,  1},
-       { 94, 51,  1,  1},
-       { 95, 52,  1,  1},
-       { 96, 53,  1,  1},
-       { 97, 54,  1,  1},
-       { 98, 55,  1,  1},
-       { 99, 56,  1,  1},
-       {100, 57,  1,  1},
-       {101, 58,  1,  1},
-       {102, 59,  1,  1},
-};
-
-/* 420 â€“ 1000 MHz band, lna 7dB, mixer 19dB */
-static const struct msi3101_gain msi3101_gain_lut_1000[] = {
-       {  0,  0, 0,  0},
-       {  1,  1, 0,  0},
-       {  2,  2, 0,  0},
-       {  3,  3, 0,  0},
-       {  4,  4, 0,  0},
-       {  5,  5, 0,  0},
-       {  6,  6, 0,  0},
-       {  7,  7, 0,  0},
-       {  8,  8, 0,  0},
-       {  9,  9, 0,  0},
-       { 10, 10, 0,  0},
-       { 11, 11, 0,  0},
-       { 12,  5, 1,  0},
-       { 13,  6, 1,  0},
-       { 14,  7, 1,  0},
-       { 15,  8, 1,  0},
-       { 16,  9, 1,  0},
-       { 17, 10, 1,  0},
-       { 18, 11, 1,  0},
-       { 19, 12, 1,  0},
-       { 20, 13, 1,  0},
-       { 21, 14, 1,  0},
-       { 22, 15, 1,  0},
-       { 23, 16, 1,  0},
-       { 24, 17, 1,  0},
-       { 25, 18, 1,  0},
-       { 26, 19, 1,  0},
-       { 27, 20, 1,  0},
-       { 28, 21, 1,  0},
-       { 29, 22, 1,  0},
-       { 30, 23, 1,  0},
-       { 31, 24, 1,  0},
-       { 32, 25, 1,  0},
-       { 33, 26, 1,  0},
-       { 34, 27, 1,  0},
-       { 35, 28, 1,  0},
-       { 36, 29, 1,  0},
-       { 37, 30, 1,  0},
-       { 38, 31, 1,  0},
-       { 39, 32, 1,  0},
-       { 40, 33, 1,  0},
-       { 41, 34, 1,  0},
-       { 42, 35, 1,  0},
-       { 43, 36, 1,  0},
-       { 44, 37, 1,  0},
-       { 45, 38, 1,  0},
-       { 46, 39, 1,  0},
-       { 47, 40, 1,  0},
-       { 48, 41, 1,  0},
-       { 49, 42, 1,  0},
-       { 50, 43, 1,  0},
-       { 51, 44, 1,  0},
-       { 52, 45, 1,  0},
-       { 53, 46, 1,  0},
-       { 54, 47, 1,  0},
-       { 55, 48, 1,  0},
-       { 56, 49, 1,  0},
-       { 57, 50, 1,  0},
-       { 58, 51, 1,  0},
-       { 59, 52, 1,  0},
-       { 60, 53, 1,  0},
-       { 61, 54, 1,  0},
-       { 62, 55, 1,  0},
-       { 63, 56, 1,  0},
-       { 64, 57, 1,  0},
-       { 65, 58, 1,  0},
-       { 66, 40, 1,  1},
-       { 67, 41, 1,  1},
-       { 68, 42, 1,  1},
-       { 69, 43, 1,  1},
-       { 70, 44, 1,  1},
-       { 71, 45, 1,  1},
-       { 72, 46, 1,  1},
-       { 73, 47, 1,  1},
-       { 74, 48, 1,  1},
-       { 75, 49, 1,  1},
-       { 76, 50, 1,  1},
-       { 77, 51, 1,  1},
-       { 78, 52, 1,  1},
-       { 79, 53, 1,  1},
-       { 80, 54, 1,  1},
-       { 81, 55, 1,  1},
-       { 82, 56, 1,  1},
-       { 83, 57, 1,  1},
-       { 84, 58, 1,  1},
-       { 85, 59, 1,  1},
-};
+#include <linux/spi/spi.h>
 
 /*
  *   iConfiguration          0
@@ -377,13 +52,54 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
 #define MAX_ISOC_ERRORS         20
 
 /* TODO: These should be moved to V4L2 API */
-#define MSI3101_CID_SAMPLING_MODE         ((V4L2_CID_USER_BASE | 0xf000) + 0)
-#define MSI3101_CID_SAMPLING_RATE         ((V4L2_CID_USER_BASE | 0xf000) + 1)
-#define MSI3101_CID_SAMPLING_RESOLUTION   ((V4L2_CID_USER_BASE | 0xf000) + 2)
-#define MSI3101_CID_TUNER_RF              ((V4L2_CID_USER_BASE | 0xf000) + 10)
-#define MSI3101_CID_TUNER_BW              ((V4L2_CID_USER_BASE | 0xf000) + 11)
-#define MSI3101_CID_TUNER_IF              ((V4L2_CID_USER_BASE | 0xf000) + 12)
-#define MSI3101_CID_TUNER_GAIN            ((V4L2_CID_USER_BASE | 0xf000) + 13)
+#define V4L2_PIX_FMT_SDR_S8     v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
+#define V4L2_PIX_FMT_SDR_S12    v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
+#define V4L2_PIX_FMT_SDR_S14    v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
+#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
+
+static const struct v4l2_frequency_band bands[] = {
+       {
+               .tuner = 0,
+               .type = V4L2_TUNER_ADC,
+               .index = 0,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   =  1200000,
+               .rangehigh  = 15000000,
+       },
+};
+
+/* stream formats */
+struct msi3101_format {
+       char    *name;
+       u32     pixelformat;
+};
+
+/* format descriptions for capture and preview */
+static struct msi3101_format formats[] = {
+       {
+               .name           = "IQ U8",
+               .pixelformat    = V4L2_SDR_FMT_CU8,
+       }, {
+               .name           = "IQ U16LE",
+               .pixelformat    =  V4L2_SDR_FMT_CU16LE,
+#if 0
+       }, {
+               .name           = "8-bit signed",
+               .pixelformat    = V4L2_PIX_FMT_SDR_S8,
+       }, {
+               .name           = "10+2-bit signed",
+               .pixelformat    = V4L2_PIX_FMT_SDR_MSI2500_384,
+       }, {
+               .name           = "12-bit signed",
+               .pixelformat    = V4L2_PIX_FMT_SDR_S12,
+       }, {
+               .name           = "14-bit signed",
+               .pixelformat    = V4L2_PIX_FMT_SDR_S14,
+#endif
+       },
+};
+
+static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
 
 /* intermediate buffers with raw data from the USB device */
 struct msi3101_frame_buf {
@@ -394,6 +110,8 @@ struct msi3101_frame_buf {
 struct msi3101_state {
        struct video_device vdev;
        struct v4l2_device v4l2_dev;
+       struct v4l2_subdev *v4l2_subdev;
+       struct spi_master *master;
 
        /* videobuf2 queue and queued buffers list */
        struct vb2_queue vb_queue;
@@ -407,24 +125,22 @@ struct msi3101_state {
        /* Pointer to our usb_device, will be NULL after unplug */
        struct usb_device *udev; /* Both mutexes most be hold when setting! */
 
+       unsigned int f_adc;
+       u32 pixelformat;
+
        unsigned int isoc_errors; /* number of contiguous ISOC errors */
        unsigned int vb_full; /* vb is full and packets dropped */
 
        struct urb *urbs[MAX_ISO_BUFS];
-       int (*convert_stream)(struct msi3101_state *s, u32 *dst, u8 *src,
+       int (*convert_stream)(struct msi3101_state *s, u8 *dst, u8 *src,
                        unsigned int src_len);
 
        /* Controls */
-       struct v4l2_ctrl_handler ctrl_handler;
-       struct v4l2_ctrl *ctrl_sampling_rate;
-       struct v4l2_ctrl *ctrl_tuner_rf;
-       struct v4l2_ctrl *ctrl_tuner_bw;
-       struct v4l2_ctrl *ctrl_tuner_if;
-       struct v4l2_ctrl *ctrl_tuner_gain;
+       struct v4l2_ctrl_handler hdl;
 
        u32 next_sample; /* for track lost packets */
        u32 sample; /* for sample rate calc */
-       unsigned long jiffies;
+       unsigned long jiffies_next;
        unsigned int sample_ctrl_bit[4];
 };
 
@@ -448,98 +164,79 @@ leave:
 
 /*
  * +===========================================================================
- * |   00-1023 | USB packet type '384'
+ * |   00-1023 | USB packet type '504'
  * +===========================================================================
  * |   00-  03 | sequence number of first sample in that USB packet
  * +---------------------------------------------------------------------------
  * |   04-  15 | garbage
  * +---------------------------------------------------------------------------
- * |   16- 175 | samples
- * +---------------------------------------------------------------------------
- * |  176- 179 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * |  180- 339 | samples
- * +---------------------------------------------------------------------------
- * |  340- 343 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * |  344- 503 | samples
- * +---------------------------------------------------------------------------
- * |  504- 507 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * |  508- 667 | samples
- * +---------------------------------------------------------------------------
- * |  668- 671 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * |  672- 831 | samples
- * +---------------------------------------------------------------------------
- * |  832- 835 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * |  836- 995 | samples
- * +---------------------------------------------------------------------------
- * |  996- 999 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 1000-1023 | garbage
+ * |   16-1023 | samples
  * +---------------------------------------------------------------------------
- *
- * Bytes 4 - 7 could have some meaning?
- *
- * Control bits for previous samples is 32-bit field, containing 16 x 2-bit
- * numbers. This results one 2-bit number for 8 samples. It is likely used for
- * for bit shifting sample by given bits, increasing actual sampling resolution.
- * Number 2 (0b10) was never seen.
- *
- * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
+ * signed 8-bit sample
+ * 504 * 2 = 1008 samples
  */
+static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
+               u8 *src, unsigned int src_len)
+{
+       int i, i_max, dst_len = 0;
+       u32 sample_num[3];
 
-/*
- * Integer to 32-bit IEEE floating point representation routine is taken
- * from Radeon R600 driver (drivers/gpu/drm/radeon/r600_blit_kms.c).
- *
- * TODO: Currently we do conversion here in Kernel, but in future that will
- * be moved to the libv4l2 library as video format conversions are.
- */
-#define I2F_FRAC_BITS  23
-#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
+       /* There could be 1-3 1024 bytes URB frames */
+       i_max = src_len / 1024;
 
-/*
- * Converts signed 8-bit integer into 32-bit IEEE floating point
- * representation.
- */
-static u32 msi3101_convert_sample_504(struct msi3101_state *s, u16 x)
-{
-       u32 msb, exponent, fraction, sign;
+       for (i = 0; i < i_max; i++) {
+               sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
+               if (i == 0 && s->next_sample != sample_num[0]) {
+                       dev_dbg_ratelimited(&s->udev->dev,
+                                       "%d samples lost, %d %08x:%08x\n",
+                                       sample_num[0] - s->next_sample,
+                                       src_len, s->next_sample, sample_num[0]);
+               }
 
-       /* Zero is special */
-       if (!x)
-               return 0;
+               /*
+                * Dump all unknown 'garbage' data - maybe we will discover
+                * someday if there is something rational...
+                */
+               dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
 
-       /* Negative / positive value */
-       if (x & (1 << 7)) {
-               x = -x;
-               x &= 0x7f; /* result is 7 bit ... + sign */
-               sign = 1 << 31;
-       } else {
-               sign = 0 << 31;
+               /* 504 x I+Q samples */
+               src += 16;
+               memcpy(dst, src, 1008);
+               src += 1008;
+               dst += 1008;
+               dst_len += 1008;
        }
 
-       /* Get location of the most significant bit */
-       msb = __fls(x);
+       /* calculate samping rate and output it in 10 seconds intervals */
+       if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
+               unsigned long jiffies_now = jiffies;
+               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
+               unsigned int samples = sample_num[i_max - 1] - s->sample;
+               s->jiffies_next = jiffies_now;
+               s->sample = sample_num[i_max - 1];
+               dev_dbg(&s->udev->dev,
+                               "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
+                               src_len, samples, msecs,
+                               samples * 1000UL / msecs);
+       }
 
-       fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
-       exponent = (127 + msb) << I2F_FRAC_BITS;
+       /* next sample (sample = sample + i * 504) */
+       s->next_sample = sample_num[i_max - 1] + 504;
 
-       return (fraction + exponent) | sign;
+       return dst_len;
 }
 
-static int msi3101_convert_stream_504(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_504_u8(struct msi3101_state *s, u8 *dst,
                u8 *src, unsigned int src_len)
 {
        int i, j, i_max, dst_len = 0;
-       u16 sample[2];
        u32 sample_num[3];
+       s8 *s8src;
+       u8 *u8dst;
 
        /* There could be 1-3 1024 bytes URB frames */
        i_max = src_len / 1024;
+       u8dst = (u8 *) dst;
 
        for (i = 0; i < i_max; i++) {
                sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
@@ -556,30 +253,28 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u32 *dst,
                 */
                dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
 
+               /* 504 x I+Q samples */
                src += 16;
-               for (j = 0; j < 1008; j += 2) {
-                       sample[0] = src[j + 0];
-                       sample[1] = src[j + 1];
 
-                       *dst++ = msi3101_convert_sample_504(s, sample[0]);
-                       *dst++ = msi3101_convert_sample_504(s, sample[1]);
-               }
-               /* 504 x I+Q 32bit float samples */
-               dst_len += 504 * 2 * 4;
+               s8src = (s8 *) src;
+               for (j = 0; j < 1008; j++)
+                       *u8dst++ = *s8src++ + 128;
+
                src += 1008;
+               dst += 1008;
+               dst_len += 1008;
        }
 
        /* calculate samping rate and output it in 10 seconds intervals */
-       if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
-               unsigned long jiffies_now = jiffies;
-               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+       if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
+#define MSECS 10000UL
                unsigned int samples = sample_num[i_max - 1] - s->sample;
-               s->jiffies = jiffies_now;
+               s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
                s->sample = sample_num[i_max - 1];
                dev_dbg(&s->udev->dev,
                                "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
-                               src_len, samples, msecs,
-                               samples * 1000UL / msecs);
+                               src_len, samples, MSECS,
+                               samples * 1000UL / MSECS);
        }
 
        /* next sample (sample = sample + i * 504) */
@@ -589,48 +284,53 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u32 *dst,
 }
 
 /*
- * Converts signed ~10+2-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * |   00-1023 | USB packet type '384'
+ * +===========================================================================
+ * |   00-  03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * |   04-  15 | garbage
+ * +---------------------------------------------------------------------------
+ * |   16- 175 | samples
+ * +---------------------------------------------------------------------------
+ * |  176- 179 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * |  180- 339 | samples
+ * +---------------------------------------------------------------------------
+ * |  340- 343 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * |  344- 503 | samples
+ * +---------------------------------------------------------------------------
+ * |  504- 507 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * |  508- 667 | samples
+ * +---------------------------------------------------------------------------
+ * |  668- 671 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * |  672- 831 | samples
+ * +---------------------------------------------------------------------------
+ * |  832- 835 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * |  836- 995 | samples
+ * +---------------------------------------------------------------------------
+ * |  996- 999 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 1000-1023 | garbage
+ * +---------------------------------------------------------------------------
+ *
+ * Bytes 4 - 7 could have some meaning?
+ *
+ * Control bits for previous samples is 32-bit field, containing 16 x 2-bit
+ * numbers. This results one 2-bit number for 8 samples. It is likely used for
+ * for bit shifting sample by given bits, increasing actual sampling resolution.
+ * Number 2 (0b10) was never seen.
+ *
+ * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
  */
-static u32 msi3101_convert_sample_384(struct msi3101_state *s, u16 x, int shift)
-{
-       u32 msb, exponent, fraction, sign;
-       s->sample_ctrl_bit[shift]++;
-
-       /* Zero is special */
-       if (!x)
-               return 0;
-
-       if (shift == 3)
-               shift = 2;
-
-       /* Convert 10-bit two's complement to 12-bit */
-       if (x & (1 << 9)) {
-               x |= ~0U << 10; /* set all the rest bits to one */
-               x <<= shift;
-               x = -x;
-               x &= 0x7ff; /* result is 11 bit ... + sign */
-               sign = 1 << 31;
-       } else {
-               x <<= shift;
-               sign = 0 << 31;
-       }
-
-       /* Get location of the most significant bit */
-       msb = __fls(x);
-
-       fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
-       exponent = (127 + msb) << I2F_FRAC_BITS;
-
-       return (fraction + exponent) | sign;
-}
-
-static int msi3101_convert_stream_384(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
                u8 *src, unsigned int src_len)
 {
-       int i, j, k, l, i_max, dst_len = 0;
-       u16 sample[4];
-       u32 bits;
+       int i, i_max, dst_len = 0;
        u32 sample_num[3];
 
        /* There could be 1-3 1024 bytes URB frames */
@@ -651,38 +351,20 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u32 *dst,
                dev_dbg_ratelimited(&s->udev->dev,
                                "%*ph  %*ph\n", 12, &src[4], 24, &src[1000]);
 
+               /* 384 x I+Q samples */
                src += 16;
-               for (j = 0; j < 6; j++) {
-                       bits = src[160 + 3] << 24 | src[160 + 2] << 16 | src[160 + 1] << 8 | src[160 + 0] << 0;
-                       for (k = 0; k < 16; k++) {
-                               for (l = 0; l < 10; l += 5) {
-                                       sample[0] = (src[l + 0] & 0xff) >> 0 | (src[l + 1] & 0x03) << 8;
-                                       sample[1] = (src[l + 1] & 0xfc) >> 2 | (src[l + 2] & 0x0f) << 6;
-                                       sample[2] = (src[l + 2] & 0xf0) >> 4 | (src[l + 3] & 0x3f) << 4;
-                                       sample[3] = (src[l + 3] & 0xc0) >> 6 | (src[l + 4] & 0xff) << 2;
-
-                                       *dst++ = msi3101_convert_sample_384(s, sample[0], (bits >> (2 * k)) & 0x3);
-                                       *dst++ = msi3101_convert_sample_384(s, sample[1], (bits >> (2 * k)) & 0x3);
-                                       *dst++ = msi3101_convert_sample_384(s, sample[2], (bits >> (2 * k)) & 0x3);
-                                       *dst++ = msi3101_convert_sample_384(s, sample[3], (bits >> (2 * k)) & 0x3);
-                               }
-                               src += 10;
-                       }
-                       dev_dbg_ratelimited(&s->udev->dev,
-                                       "sample control bits %08x\n", bits);
-                       src += 4;
-               }
-               /* 384 x I+Q 32bit float samples */
-               dst_len += 384 * 2 * 4;
-               src += 24;
+               memcpy(dst, src, 984);
+               src += 984 + 24;
+               dst += 984;
+               dst_len += 984;
        }
 
        /* calculate samping rate and output it in 10 seconds intervals */
-       if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
+       if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
                unsigned long jiffies_now = jiffies;
-               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
                unsigned int samples = sample_num[i_max - 1] - s->sample;
-               s->jiffies = jiffies_now;
+               s->jiffies_next = jiffies_now;
                s->sample = sample_num[i_max - 1];
                dev_dbg(&s->udev->dev,
                                "slen=%d samples=%u msecs=%lu sampling rate=%lu bits=%d.%d.%d.%d\n",
@@ -699,40 +381,21 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u32 *dst,
 }
 
 /*
- * Converts signed 12-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * |   00-1023 | USB packet type '336'
+ * +===========================================================================
+ * |   00-  03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * |   04-  15 | garbage
+ * +---------------------------------------------------------------------------
+ * |   16-1023 | samples
+ * +---------------------------------------------------------------------------
+ * signed 12-bit sample
  */
-static u32 msi3101_convert_sample_336(struct msi3101_state *s, u16 x)
-{
-       u32 msb, exponent, fraction, sign;
-
-       /* Zero is special */
-       if (!x)
-               return 0;
-
-       /* Negative / positive value */
-       if (x & (1 << 11)) {
-               x = -x;
-               x &= 0x7ff; /* result is 11 bit ... + sign */
-               sign = 1 << 31;
-       } else {
-               sign = 0 << 31;
-       }
-
-       /* Get location of the most significant bit */
-       msb = __fls(x);
-
-       fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
-       exponent = (127 + msb) << I2F_FRAC_BITS;
-
-       return (fraction + exponent) | sign;
-}
-
-static int msi3101_convert_stream_336(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
                u8 *src, unsigned int src_len)
 {
-       int i, j, i_max, dst_len = 0;
-       u16 sample[2];
+       int i, i_max, dst_len = 0;
        u32 sample_num[3];
 
        /* There could be 1-3 1024 bytes URB frames */
@@ -753,25 +416,20 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u32 *dst,
                 */
                dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
 
+               /* 336 x I+Q samples */
                src += 16;
-               for (j = 0; j < 1008; j += 3) {
-                       sample[0] = (src[j + 0] & 0xff) >> 0 | (src[j + 1] & 0x0f) << 8;
-                       sample[1] = (src[j + 1] & 0xf0) >> 4 | (src[j + 2] & 0xff) << 4;
-
-                       *dst++ = msi3101_convert_sample_336(s, sample[0]);
-                       *dst++ = msi3101_convert_sample_336(s, sample[1]);
-               }
-               /* 336 x I+Q 32bit float samples */
-               dst_len += 336 * 2 * 4;
+               memcpy(dst, src, 1008);
                src += 1008;
+               dst += 1008;
+               dst_len += 1008;
        }
 
        /* calculate samping rate and output it in 10 seconds intervals */
-       if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
+       if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
                unsigned long jiffies_now = jiffies;
-               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
                unsigned int samples = sample_num[i_max - 1] - s->sample;
-               s->jiffies = jiffies_now;
+               s->jiffies_next = jiffies_now;
                s->sample = sample_num[i_max - 1];
                dev_dbg(&s->udev->dev,
                                "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
@@ -786,41 +444,75 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u32 *dst,
 }
 
 /*
- * Converts signed 14-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * |   00-1023 | USB packet type '252'
+ * +===========================================================================
+ * |   00-  03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * |   04-  15 | garbage
+ * +---------------------------------------------------------------------------
+ * |   16-1023 | samples
+ * +---------------------------------------------------------------------------
+ * signed 14-bit sample
  */
-static u32 msi3101_convert_sample_252(struct msi3101_state *s, u16 x)
+static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst,
+               u8 *src, unsigned int src_len)
 {
-       u32 msb, exponent, fraction, sign;
+       int i, i_max, dst_len = 0;
+       u32 sample_num[3];
 
-       /* Zero is special */
-       if (!x)
-               return 0;
+       /* There could be 1-3 1024 bytes URB frames */
+       i_max = src_len / 1024;
 
-       /* Negative / positive value */
-       if (x & (1 << 13)) {
-               x = -x;
-               x &= 0x1fff; /* result is 13 bit ... + sign */
-               sign = 1 << 31;
-       } else {
-               sign = 0 << 31;
+       for (i = 0; i < i_max; i++) {
+               sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
+               if (i == 0 && s->next_sample != sample_num[0]) {
+                       dev_dbg_ratelimited(&s->udev->dev,
+                                       "%d samples lost, %d %08x:%08x\n",
+                                       sample_num[0] - s->next_sample,
+                                       src_len, s->next_sample, sample_num[0]);
+               }
+
+               /*
+                * Dump all unknown 'garbage' data - maybe we will discover
+                * someday if there is something rational...
+                */
+               dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
+
+               /* 252 x I+Q samples */
+               src += 16;
+               memcpy(dst, src, 1008);
+               src += 1008;
+               dst += 1008;
+               dst_len += 1008;
        }
 
-       /* Get location of the most significant bit */
-       msb = __fls(x);
+       /* calculate samping rate and output it in 10 seconds intervals */
+       if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
+               unsigned long jiffies_now = jiffies;
+               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
+               unsigned int samples = sample_num[i_max - 1] - s->sample;
+               s->jiffies_next = jiffies_now;
+               s->sample = sample_num[i_max - 1];
+               dev_dbg(&s->udev->dev,
+                               "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
+                               src_len, samples, msecs,
+                               samples * 1000UL / msecs);
+       }
 
-       fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
-       exponent = (127 + msb) << I2F_FRAC_BITS;
+       /* next sample (sample = sample + i * 252) */
+       s->next_sample = sample_num[i_max - 1] + 252;
 
-       return (fraction + exponent) | sign;
+       return dst_len;
 }
 
-static int msi3101_convert_stream_252(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst,
                u8 *src, unsigned int src_len)
 {
        int i, j, i_max, dst_len = 0;
-       u16 sample[2];
        u32 sample_num[3];
+       u16 *u16dst = (u16 *) dst;
+       struct {signed int x:14;} se;
 
        /* There could be 1-3 1024 bytes URB frames */
        i_max = src_len / 1024;
@@ -840,30 +532,44 @@ static int msi3101_convert_stream_252(struct msi3101_state *s, u32 *dst,
                 */
                dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
 
+               /* 252 x I+Q samples */
                src += 16;
+
                for (j = 0; j < 1008; j += 4) {
-                       sample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
-                       sample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
+                       unsigned int usample[2];
+                       int ssample[2];
+
+                       usample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
+                       usample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
 
-                       *dst++ = msi3101_convert_sample_252(s, sample[0]);
-                       *dst++ = msi3101_convert_sample_252(s, sample[1]);
+                       /* sign extension from 14-bit to signed int */
+                       ssample[0] = se.x = usample[0];
+                       ssample[1] = se.x = usample[1];
+
+                       /* from signed to unsigned */
+                       usample[0] = ssample[0] + 8192;
+                       usample[1] = ssample[1] + 8192;
+
+                       /* from 14-bit to 16-bit */
+                       *u16dst++ = (usample[0] << 2) | (usample[0] >> 12);
+                       *u16dst++ = (usample[1] << 2) | (usample[1] >> 12);
                }
-               /* 252 x I+Q 32bit float samples */
-               dst_len += 252 * 2 * 4;
+
                src += 1008;
+               dst += 1008;
+               dst_len += 1008;
        }
 
        /* calculate samping rate and output it in 10 seconds intervals */
-       if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
-               unsigned long jiffies_now = jiffies;
-               unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+       if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
+#define MSECS 10000UL
                unsigned int samples = sample_num[i_max - 1] - s->sample;
-               s->jiffies = jiffies_now;
+               s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
                s->sample = sample_num[i_max - 1];
                dev_dbg(&s->udev->dev,
                                "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
-                               src_len, samples, msecs,
-                               samples * 1000UL / msecs);
+                               src_len, samples, MSECS,
+                               samples * 1000UL / MSECS);
        }
 
        /* next sample (sample = sample + i * 252) */
@@ -883,14 +589,14 @@ static void msi3101_isoc_handler(struct urb *urb)
        unsigned char *iso_buf = NULL;
        struct msi3101_frame_buf *fbuf;
 
-       if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
-                       urb->status == -ESHUTDOWN) {
+       if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET ||
+                       urb->status == -ESHUTDOWN)) {
                dev_dbg(&s->udev->dev, "URB (%p) unlinked %ssynchronuously\n",
                                urb, urb->status == -ENOENT ? "" : "a");
                return;
        }
 
-       if (urb->status != 0) {
+       if (unlikely(urb->status != 0)) {
                dev_dbg(&s->udev->dev,
                                "msi3101_isoc_handler() called with status %d\n",
                                urb->status);
@@ -910,28 +616,28 @@ static void msi3101_isoc_handler(struct urb *urb)
 
                /* Check frame error */
                fstatus = urb->iso_frame_desc[i].status;
-               if (fstatus) {
+               if (unlikely(fstatus)) {
                        dev_dbg_ratelimited(&s->udev->dev,
                                        "frame=%d/%d has error %d skipping\n",
                                        i, urb->number_of_packets, fstatus);
-                       goto skip;
+                       continue;
                }
 
                /* Check if that frame contains data */
                flen = urb->iso_frame_desc[i].actual_length;
-               if (flen == 0)
-                       goto skip;
+               if (unlikely(flen == 0))
+                       continue;
 
                iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 
                /* Get free framebuffer */
                fbuf = msi3101_get_next_fill_buf(s);
-               if (fbuf == NULL) {
+               if (unlikely(fbuf == NULL)) {
                        s->vb_full++;
                        dev_dbg_ratelimited(&s->udev->dev,
                                        "videobuf is full, %d packets dropped\n",
                                        s->vb_full);
-                       goto skip;
+                       continue;
                }
 
                /* fill framebuffer */
@@ -939,13 +645,11 @@ static void msi3101_isoc_handler(struct urb *urb)
                flen = s->convert_stream(s, ptr, iso_buf, flen);
                vb2_set_plane_payload(&fbuf->vb, 0, flen);
                vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
-skip:
-               ;
        }
 
 handler_end:
        i = usb_submit_urb(urb, GFP_ATOMIC);
-       if (i != 0)
+       if (unlikely(i != 0))
                dev_dbg(&s->udev->dev,
                                "Error (%d) re-submitting urb in msi3101_isoc_handler\n",
                                i);
@@ -1008,7 +712,7 @@ static int msi3101_isoc_init(struct msi3101_state *s)
        udev = s->udev;
 
        ret = usb_set_interface(s->udev, 0, 1);
-       if (ret < 0)
+       if (ret)
                return ret;
 
        /* Allocate and init Isochronuous urbs */
@@ -1094,9 +798,9 @@ static void msi3101_disconnect(struct usb_interface *intf)
        mutex_lock(&s->v4l2_lock);
        /* No need to keep the urbs around after disconnection */
        s->udev = NULL;
-
        v4l2_device_disconnect(&s->v4l2_dev);
        video_unregister_device(&s->vdev);
+       spi_unregister_master(s->master);
        mutex_unlock(&s->v4l2_lock);
        mutex_unlock(&s->vb_queue_lock);
 
@@ -1112,14 +816,12 @@ static int msi3101_querycap(struct file *file, void *fh,
        strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
        strlcpy(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_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
-                       V4L2_CAP_READWRITE;
-       cap->device_caps = V4L2_CAP_TUNER;
+       cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
+                       V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
        return 0;
 }
 
-
 /* Videobuf2 operations */
 static int msi3101_queue_setup(struct vb2_queue *vq,
                const struct v4l2_format *fmt, unsigned int *nbuffers,
@@ -1129,31 +831,20 @@ static int msi3101_queue_setup(struct vb2_queue *vq,
        dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
 
        /* Absolute min and max number of buffers available for mmap() */
-       *nbuffers = 32;
+       *nbuffers = clamp_t(unsigned int, *nbuffers, 8, 32);
        *nplanes = 1;
        /*
         *   3, wMaxPacketSize 3x 1024 bytes
         * 504, max IQ sample pairs per 1024 frame
         *   2, two samples, I and Q
-        *   4, 32-bit float
+        *   2, 16-bit is enough for single sample
         */
-       sizes[0] = PAGE_ALIGN(3 * 504 * 2 * 4); /* = 12096 */
+       sizes[0] = PAGE_ALIGN(3 * 504 * 2 * 2);
        dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
                        __func__, *nbuffers, sizes[0]);
        return 0;
 }
 
-static int msi3101_buf_prepare(struct vb2_buffer *vb)
-{
-       struct msi3101_state *s = vb2_get_drv_priv(vb->vb2_queue);
-
-       /* Don't allow queing new buffers after device disconnection */
-       if (!s->udev)
-               return -ENODEV;
-
-       return 0;
-}
-
 static void msi3101_buf_queue(struct vb2_buffer *vb)
 {
        struct msi3101_state *s = vb2_get_drv_priv(vb->vb2_queue);
@@ -1162,7 +853,7 @@ static void msi3101_buf_queue(struct vb2_buffer *vb)
        unsigned long flags = 0;
 
        /* Check the device has not disconnected between prep and queuing */
-       if (!s->udev) {
+       if (unlikely(!s->udev)) {
                vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
                return;
        }
@@ -1209,41 +900,63 @@ static int msi3101_ctrl_msg(struct msi3101_state *s, u8 cmd, u32 data)
        return ret;
 };
 
-static int msi3101_tuner_write(struct msi3101_state *s, u32 data)
-{
-       return msi3101_ctrl_msg(s, CMD_WREG, data << 8 | 0x09);
-};
-
 #define F_REF 24000000
 #define DIV_R_IN 2
 static int msi3101_set_usb_adc(struct msi3101_state *s)
 {
        int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract;
        u32 reg3, reg4, reg7;
+       struct v4l2_ctrl *bandwidth_auto;
+       struct v4l2_ctrl *bandwidth;
 
-       f_sr = s->ctrl_sampling_rate->val64;
+       f_sr = s->f_adc;
+
+       /* set tuner, subdev, filters according to sampling rate */
+       bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
+       bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
+       if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
+               bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
+               v4l2_ctrl_s_ctrl(bandwidth, s->f_adc);
+       }
 
        /* select stream format */
-       if (f_sr < 6000000) {
-               s->convert_stream = msi3101_convert_stream_252;
+       switch (s->pixelformat) {
+       case V4L2_SDR_FMT_CU8:
+               s->convert_stream = msi3101_convert_stream_504_u8;
+               reg7 = 0x000c9407;
+               break;
+       case  V4L2_SDR_FMT_CU16LE:
+               s->convert_stream = msi3101_convert_stream_252_u16;
                reg7 = 0x00009407;
-       } else if (f_sr < 8000000) {
-               s->convert_stream = msi3101_convert_stream_336;
-               reg7 = 0x00008507;
-       } else if (f_sr < 9000000) {
+               break;
+       case V4L2_PIX_FMT_SDR_S8:
+               s->convert_stream = msi3101_convert_stream_504;
+               reg7 = 0x000c9407;
+               break;
+       case V4L2_PIX_FMT_SDR_MSI2500_384:
                s->convert_stream = msi3101_convert_stream_384;
                reg7 = 0x0000a507;
-       } else {
-               s->convert_stream = msi3101_convert_stream_504;
+               break;
+       case V4L2_PIX_FMT_SDR_S12:
+               s->convert_stream = msi3101_convert_stream_336;
+               reg7 = 0x00008507;
+               break;
+       case V4L2_PIX_FMT_SDR_S14:
+               s->convert_stream = msi3101_convert_stream_252;
+               reg7 = 0x00009407;
+               break;
+       default:
+               s->convert_stream = msi3101_convert_stream_504_u8;
                reg7 = 0x000c9407;
+               break;
        }
 
        /*
         * Synthesizer config is just a educated guess...
         *
         * [7:0]   0x03, register address
-        * [8]     1, always
-        * [9]     ?
+        * [8]     1, power control
+        * [9]     ?, power control
         * [12:10] output divider
         * [13]    0 ?
         * [14]    0 ?
@@ -1334,224 +1047,6 @@ err:
        return ret;
 };
 
-static int msi3101_set_tuner(struct msi3101_state *s)
-{
-       int ret, i, len;
-       unsigned int n, m, thresh, frac, vco_step, tmp, f_if1;
-       u32 reg;
-       u64 f_vco, tmp64;
-       u8 mode, filter_mode, lo_div;
-       const struct msi3101_gain *gain_lut;
-       static const struct {
-               u32 rf;
-               u8 mode;
-               u8 lo_div;
-       } band_lut[] = {
-               { 50000000, 0xe1, 16}, /* AM_MODE2, antenna 2 */
-               {108000000, 0x42, 32}, /* VHF_MODE */
-               {330000000, 0x44, 16}, /* B3_MODE */
-               {960000000, 0x48,  4}, /* B45_MODE */
-               {      ~0U, 0x50,  2}, /* BL_MODE */
-       };
-       static const struct {
-               u32 freq;
-               u8 filter_mode;
-       } if_freq_lut[] = {
-               {      0, 0x03}, /* Zero IF */
-               { 450000, 0x02}, /* 450 kHz IF */
-               {1620000, 0x01}, /* 1.62 MHz IF */
-               {2048000, 0x00}, /* 2.048 MHz IF */
-       };
-       static const struct {
-               u32 freq;
-               u8 val;
-       } bandwidth_lut[] = {
-               { 200000, 0x00}, /* 200 kHz */
-               { 300000, 0x01}, /* 300 kHz */
-               { 600000, 0x02}, /* 600 kHz */
-               {1536000, 0x03}, /* 1.536 MHz */
-               {5000000, 0x04}, /* 5 MHz */
-               {6000000, 0x05}, /* 6 MHz */
-               {7000000, 0x06}, /* 7 MHz */
-               {8000000, 0x07}, /* 8 MHz */
-       };
-
-       unsigned int f_rf = s->ctrl_tuner_rf->val64;
-
-       /*
-        * bandwidth (Hz)
-        * 200000, 300000, 600000, 1536000, 5000000, 6000000, 7000000, 8000000
-        */
-       unsigned int bandwidth = s->ctrl_tuner_bw->val;
-
-       /*
-        * intermediate frequency (Hz)
-        * 0, 450000, 1620000, 2048000
-        */
-       unsigned int f_if = s->ctrl_tuner_if->val;
-
-       /*
-        * gain reduction (dB)
-        * 0 - 102 below 420 MHz
-        * 0 - 85 above 420 MHz
-        */
-       int gain = s->ctrl_tuner_gain->val;
-
-       dev_dbg(&s->udev->dev,
-                       "%s: f_rf=%d bandwidth=%d f_if=%d gain=%d\n",
-                       __func__, f_rf, bandwidth, f_if, gain);
-
-       ret = -EINVAL;
-
-       for (i = 0; i < ARRAY_SIZE(band_lut); i++) {
-               if (f_rf <= band_lut[i].rf) {
-                       mode = band_lut[i].mode;
-                       lo_div = band_lut[i].lo_div;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(band_lut))
-               goto err;
-
-       /* AM_MODE is upconverted */
-       if ((mode >> 0) & 0x1)
-               f_if1 =  5 * F_REF;
-       else
-               f_if1 =  0;
-
-       for (i = 0; i < ARRAY_SIZE(if_freq_lut); i++) {
-               if (f_if == if_freq_lut[i].freq) {
-                       filter_mode = if_freq_lut[i].filter_mode;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(if_freq_lut))
-               goto err;
-
-       for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
-               if (bandwidth == bandwidth_lut[i].freq) {
-                       bandwidth = bandwidth_lut[i].val;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(bandwidth_lut))
-               goto err;
-
-#define F_OUT_STEP 1
-#define R_REF 4
-       f_vco = (f_rf + f_if + f_if1) * lo_div;
-
-       tmp64 = f_vco;
-       m = do_div(tmp64, F_REF * R_REF);
-       n = (unsigned int) tmp64;
-
-       vco_step = F_OUT_STEP * lo_div;
-       thresh = (F_REF * R_REF) / vco_step;
-       frac = 1ul * thresh * m / (F_REF * R_REF);
-
-       /* Find out greatest common divisor and divide to smaller. */
-       tmp = gcd(thresh, frac);
-       thresh /= tmp;
-       frac /= tmp;
-
-       /* Force divide to reg max. Resolution will be reduced. */
-       tmp = DIV_ROUND_UP(thresh, 4095);
-       thresh = DIV_ROUND_CLOSEST(thresh, tmp);
-       frac = DIV_ROUND_CLOSEST(frac, tmp);
-
-       /* calc real RF set */
-       tmp = 1ul * F_REF * R_REF * n;
-       tmp += 1ul * F_REF * R_REF * frac / thresh;
-       tmp /= lo_div;
-
-       dev_dbg(&s->udev->dev,
-                       "%s: rf=%u:%u n=%d thresh=%d frac=%d\n",
-                               __func__, f_rf, tmp, n, thresh, frac);
-
-       ret = msi3101_tuner_write(s, 0x00000e);
-       if (ret)
-               goto err;
-
-       ret = msi3101_tuner_write(s, 0x000003);
-       if (ret)
-               goto err;
-
-       reg = 0 << 0;
-       reg |= mode << 4;
-       reg |= filter_mode << 12;
-       reg |= bandwidth << 14;
-       reg |= 0x02 << 17;
-       reg |= 0x00 << 20;
-       ret = msi3101_tuner_write(s, reg);
-       if (ret)
-               goto err;
-
-       reg = 5 << 0;
-       reg |= thresh << 4;
-       reg |= 1 << 19;
-       reg |= 1 << 21;
-       ret = msi3101_tuner_write(s, reg);
-       if (ret)
-               goto err;
-
-       reg = 2 << 0;
-       reg |= frac << 4;
-       reg |= n << 16;
-       ret = msi3101_tuner_write(s, reg);
-       if (ret)
-               goto err;
-
-       if (f_rf < 120000000) {
-               gain_lut = msi3101_gain_lut_120;
-               len = ARRAY_SIZE(msi3101_gain_lut_120);
-       } else if (f_rf < 245000000) {
-               gain_lut = msi3101_gain_lut_245;
-               len = ARRAY_SIZE(msi3101_gain_lut_120);
-       } else {
-               gain_lut = msi3101_gain_lut_1000;
-               len = ARRAY_SIZE(msi3101_gain_lut_1000);
-       }
-
-       for (i = 0; i < len; i++) {
-               if (gain_lut[i].tot >= gain)
-                       break;
-       }
-
-       if (i == len)
-               goto err;
-
-       dev_dbg(&s->udev->dev,
-                       "%s: gain tot=%d baseband=%d lna=%d mixer=%d\n",
-                       __func__, gain_lut[i].tot, gain_lut[i].baseband,
-                       gain_lut[i].lna, gain_lut[i].mixer);
-
-       reg = 1 << 0;
-       reg |= gain_lut[i].baseband << 4;
-       reg |= 0 << 10;
-       reg |= gain_lut[i].mixer << 12;
-       reg |= gain_lut[i].lna << 13;
-       reg |= 4 << 14;
-       reg |= 0 << 17;
-       ret = msi3101_tuner_write(s, reg);
-       if (ret)
-               goto err;
-
-       reg = 6 << 0;
-       reg |= 63 << 4;
-       reg |= 4095 << 10;
-       ret = msi3101_tuner_write(s, reg);
-       if (ret)
-               goto err;
-
-       return 0;
-err:
-       dev_dbg(&s->udev->dev, "%s: failed %d\n", __func__, ret);
-       return ret;
-};
-
 static int msi3101_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
        struct msi3101_state *s = vb2_get_drv_priv(vq);
@@ -1564,6 +1059,9 @@ static int msi3101_start_streaming(struct vb2_queue *vq, unsigned int count)
        if (mutex_lock_interruptible(&s->v4l2_lock))
                return -ERESTARTSYS;
 
+       /* wake-up tuner */
+       v4l2_subdev_call(s->v4l2_subdev, core, s_power, 1);
+
        ret = msi3101_set_usb_adc(s);
 
        ret = msi3101_isoc_init(s);
@@ -1594,6 +1092,12 @@ static int msi3101_stop_streaming(struct vb2_queue *vq)
        msleep(20);
        msi3101_ctrl_msg(s, CMD_STOP_STREAMING, 0);
 
+       /* sleep USB IF / ADC */
+       msi3101_ctrl_msg(s, CMD_WREG, 0x01000003);
+
+       /* sleep tuner */
+       v4l2_subdev_call(s->v4l2_subdev, core, s_power, 0);
+
        mutex_unlock(&s->v4l2_lock);
 
        return 0;
@@ -1601,7 +1105,6 @@ static int msi3101_stop_streaming(struct vb2_queue *vq)
 
 static struct vb2_ops msi3101_vb2_ops = {
        .queue_setup            = msi3101_queue_setup,
-       .buf_prepare            = msi3101_buf_prepare,
        .buf_queue              = msi3101_buf_queue,
        .start_streaming        = msi3101_start_streaming,
        .stop_streaming         = msi3101_stop_streaming,
@@ -1609,66 +1112,195 @@ static struct vb2_ops msi3101_vb2_ops = {
        .wait_finish            = vb2_ops_wait_finish,
 };
 
-static int msi3101_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+static int msi3101_enum_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_fmtdesc *f)
 {
-       if (i->index != 0)
+       struct msi3101_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, f->index);
+
+       if (f->index >= NUM_FORMATS)
                return -EINVAL;
 
-       strlcpy(i->name, "SDR data", sizeof(i->name));
-       i->type = V4L2_INPUT_TYPE_CAMERA;
+       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       f->pixelformat = formats[f->index].pixelformat;
+
+       return 0;
+}
+
+static int msi3101_g_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_format *f)
+{
+       struct msi3101_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+                       (char *)&s->pixelformat);
+
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+       f->fmt.sdr.pixelformat = s->pixelformat;
 
        return 0;
 }
 
-static int msi3101_g_input(struct file *file, void *fh, unsigned int *i)
+static int msi3101_s_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_format *f)
 {
-       *i = 0;
+       struct msi3101_state *s = video_drvdata(file);
+       struct vb2_queue *q = &s->vb_queue;
+       int i;
+       dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+                       (char *)&f->fmt.sdr.pixelformat);
+
+       if (vb2_is_busy(q))
+               return -EBUSY;
+
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+       for (i = 0; i < NUM_FORMATS; i++) {
+               if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+                       s->pixelformat = f->fmt.sdr.pixelformat;
+                       return 0;
+               }
+       }
+
+       f->fmt.sdr.pixelformat = formats[0].pixelformat;
+       s->pixelformat = formats[0].pixelformat;
 
        return 0;
 }
 
-static int msi3101_s_input(struct file *file, void *fh, unsigned int i)
+static int msi3101_try_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_format *f)
 {
-       return i ? -EINVAL : 0;
+       struct msi3101_state *s = video_drvdata(file);
+       int i;
+       dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+                       (char *)&f->fmt.sdr.pixelformat);
+
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+       for (i = 0; i < NUM_FORMATS; i++) {
+               if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
+                       return 0;
+       }
+
+       f->fmt.sdr.pixelformat = formats[0].pixelformat;
+
+       return 0;
 }
 
-static int vidioc_s_tuner(struct file *file, void *priv,
+static int msi3101_s_tuner(struct file *file, void *priv,
                const struct v4l2_tuner *v)
 {
        struct msi3101_state *s = video_drvdata(file);
-       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+       int ret;
+       dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
 
-       return 0;
+       if (v->index == 0)
+               ret = 0;
+       else if (v->index == 1)
+               ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_tuner, v);
+       else
+               ret = -EINVAL;
+
+       return ret;
 }
 
-static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
+static int msi3101_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
 {
        struct msi3101_state *s = video_drvdata(file);
-       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+       int ret;
+       dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
+
+       if (v->index == 0) {
+               strlcpy(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;
+               v->rangehigh = 15000000;
+               ret = 0;
+       } else if (v->index == 1) {
+               ret = v4l2_subdev_call(s->v4l2_subdev, tuner, g_tuner, v);
+       } else {
+               ret = -EINVAL;
+       }
 
-       strcpy(v->name, "SDR RX");
-       v->capability = V4L2_TUNER_CAP_LOW;
+       return ret;
+}
 
-       return 0;
+static int msi3101_g_frequency(struct file *file, void *priv,
+               struct v4l2_frequency *f)
+{
+       struct msi3101_state *s = video_drvdata(file);
+       int ret  = 0;
+       dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
+                       __func__, f->tuner, f->type);
+
+       if (f->tuner == 0) {
+               f->frequency = s->f_adc;
+               ret = 0;
+       } else if (f->tuner == 1) {
+               f->type = V4L2_TUNER_RF;
+               ret = v4l2_subdev_call(s->v4l2_subdev, tuner, g_frequency, f);
+       } else {
+               ret = -EINVAL;
+       }
+
+       return ret;
 }
 
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int msi3101_s_frequency(struct file *file, void *priv,
                const struct v4l2_frequency *f)
 {
        struct msi3101_state *s = video_drvdata(file);
-       dev_dbg(&s->udev->dev, "%s: frequency=%lu Hz (%u)\n",
-                       __func__, f->frequency * 625UL / 10UL, f->frequency);
+       int ret;
+       dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
+                       __func__, f->tuner, f->type, f->frequency);
+
+       if (f->tuner == 0) {
+               s->f_adc = clamp_t(unsigned int, f->frequency,
+                               bands[0].rangelow,
+                               bands[0].rangehigh);
+               dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
+                               __func__, s->f_adc);
+               ret = msi3101_set_usb_adc(s);
+       } else if (f->tuner == 1) {
+               ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_frequency, f);
+       } else {
+               ret = -EINVAL;
+       }
 
-       return v4l2_ctrl_s_ctrl_int64(s->ctrl_tuner_rf,
-                       f->frequency * 625UL / 10UL);
+       return ret;
+}
+
+static int msi3101_enum_freq_bands(struct file *file, void *priv,
+               struct v4l2_frequency_band *band)
+{
+       struct msi3101_state *s = video_drvdata(file);
+       int ret;
+       dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
+                       __func__, band->tuner, band->type, band->index);
+
+       if (band->tuner == 0) {
+               if (band->index >= ARRAY_SIZE(bands)) {
+                       ret = -EINVAL;
+               } else {
+                       *band = bands[band->index];
+                       ret = 0;
+               }
+       } else if (band->tuner == 1) {
+               ret = v4l2_subdev_call(s->v4l2_subdev, tuner,
+                               enum_freq_bands, band);
+       } else {
+               ret = -EINVAL;
+       }
+
+       return ret;
 }
 
 static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
        .vidioc_querycap          = msi3101_querycap,
 
-       .vidioc_enum_input        = msi3101_enum_input,
-       .vidioc_g_input           = msi3101_g_input,
-       .vidioc_s_input           = msi3101_s_input,
+       .vidioc_enum_fmt_sdr_cap  = msi3101_enum_fmt_sdr_cap,
+       .vidioc_g_fmt_sdr_cap     = msi3101_g_fmt_sdr_cap,
+       .vidioc_s_fmt_sdr_cap     = msi3101_s_fmt_sdr_cap,
+       .vidioc_try_fmt_sdr_cap   = msi3101_try_fmt_sdr_cap,
 
        .vidioc_reqbufs           = vb2_ioctl_reqbufs,
        .vidioc_create_bufs       = vb2_ioctl_create_bufs,
@@ -1680,9 +1312,12 @@ static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
        .vidioc_streamon          = vb2_ioctl_streamon,
        .vidioc_streamoff         = vb2_ioctl_streamoff,
 
-       .vidioc_g_tuner           = vidioc_g_tuner,
-       .vidioc_s_tuner           = vidioc_s_tuner,
-       .vidioc_s_frequency       = vidioc_s_frequency,
+       .vidioc_g_tuner           = msi3101_g_tuner,
+       .vidioc_s_tuner           = msi3101_s_tuner,
+
+       .vidioc_g_frequency       = msi3101_g_frequency,
+       .vidioc_s_frequency       = msi3101_s_frequency,
+       .vidioc_enum_freq_bands   = msi3101_enum_freq_bands,
 
        .vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -1706,129 +1341,52 @@ static struct video_device msi3101_template = {
        .ioctl_ops                = &msi3101_ioctl_ops,
 };
 
-static int msi3101_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct msi3101_state *s =
-                       container_of(ctrl->handler, struct msi3101_state,
-                                       ctrl_handler);
-       int ret;
-       dev_dbg(&s->udev->dev,
-                       "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
-                       __func__, ctrl->id, ctrl->name, ctrl->val,
-                       ctrl->minimum, ctrl->maximum, ctrl->step);
-
-       switch (ctrl->id) {
-       case MSI3101_CID_SAMPLING_MODE:
-       case MSI3101_CID_SAMPLING_RATE:
-       case MSI3101_CID_SAMPLING_RESOLUTION:
-               ret = 0;
-               break;
-       case MSI3101_CID_TUNER_RF:
-       case MSI3101_CID_TUNER_BW:
-       case MSI3101_CID_TUNER_IF:
-       case MSI3101_CID_TUNER_GAIN:
-               ret = msi3101_set_tuner(s);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static const struct v4l2_ctrl_ops msi3101_ctrl_ops = {
-       .s_ctrl = msi3101_s_ctrl,
-};
-
 static void msi3101_video_release(struct v4l2_device *v)
 {
        struct msi3101_state *s =
                        container_of(v, struct msi3101_state, v4l2_dev);
 
-       v4l2_ctrl_handler_free(&s->ctrl_handler);
+       v4l2_ctrl_handler_free(&s->hdl);
        v4l2_device_unregister(&s->v4l2_dev);
        kfree(s);
 }
 
+static int msi3101_transfer_one_message(struct spi_master *master,
+               struct spi_message *m)
+{
+       struct msi3101_state *s = spi_master_get_devdata(master);
+       struct spi_transfer *t;
+       int ret = 0;
+       u32 data;
+
+       list_for_each_entry(t, &m->transfers, transfer_list) {
+               dev_dbg(&s->udev->dev, "%s: msg=%*ph\n",
+                               __func__, t->len, t->tx_buf);
+               data = 0x09; /* reg 9 is SPI adapter */
+               data |= ((u8 *)t->tx_buf)[0] << 8;
+               data |= ((u8 *)t->tx_buf)[1] << 16;
+               data |= ((u8 *)t->tx_buf)[2] << 24;
+               ret = msi3101_ctrl_msg(s, CMD_WREG, data);
+       }
+
+       m->status = ret;
+       spi_finalize_current_message(master);
+       return ret;
+}
+
 static int msi3101_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
 {
        struct usb_device *udev = interface_to_usbdev(intf);
        struct msi3101_state *s = NULL;
+       struct v4l2_subdev *sd;
+       struct spi_master *master;
        int ret;
-       static const char * const ctrl_sampling_mode_qmenu_strings[] = {
-               "Quadrature Sampling",
-               NULL,
-       };
-       static const struct v4l2_ctrl_config ctrl_sampling_mode = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_SAMPLING_MODE,
-               .type   = V4L2_CTRL_TYPE_MENU,
-               .flags  = V4L2_CTRL_FLAG_INACTIVE,
-               .name   = "Sampling Mode",
-               .qmenu  = ctrl_sampling_mode_qmenu_strings,
-       };
-       static const struct v4l2_ctrl_config ctrl_sampling_rate = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_SAMPLING_RATE,
-               .type   = V4L2_CTRL_TYPE_INTEGER64,
-               .name   = "Sampling Rate",
-               .min    = 500000,
-               .max    = 12000000,
-               .def    = 2048000,
-               .step   = 1,
-       };
-       static const struct v4l2_ctrl_config ctrl_sampling_resolution = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_SAMPLING_RESOLUTION,
-               .type   = V4L2_CTRL_TYPE_INTEGER,
-               .flags  = V4L2_CTRL_FLAG_INACTIVE,
-               .name   = "Sampling Resolution",
-               .min    = 10,
-               .max    = 10,
-               .def    = 10,
-               .step   = 1,
-       };
-       static const struct v4l2_ctrl_config ctrl_tuner_rf = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_TUNER_RF,
-               .type   = V4L2_CTRL_TYPE_INTEGER64,
-               .name   = "Tuner RF",
-               .min    = 40000000,
-               .max    = 2000000000,
-               .def    = 100000000,
-               .step   = 1,
-       };
-       static const struct v4l2_ctrl_config ctrl_tuner_bw = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_TUNER_BW,
-               .type   = V4L2_CTRL_TYPE_INTEGER,
-               .name   = "Tuner BW",
-               .min    = 200000,
-               .max    = 8000000,
-               .def    = 600000,
-               .step   = 1,
-       };
-       static const struct v4l2_ctrl_config ctrl_tuner_if = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_TUNER_IF,
-               .type   = V4L2_CTRL_TYPE_INTEGER,
-               .flags  = V4L2_CTRL_FLAG_INACTIVE,
-               .name   = "Tuner IF",
-               .min    = 0,
-               .max    = 2048000,
-               .def    = 0,
-               .step   = 1,
-       };
-       static const struct v4l2_ctrl_config ctrl_tuner_gain = {
-               .ops    = &msi3101_ctrl_ops,
-               .id     = MSI3101_CID_TUNER_GAIN,
-               .type   = V4L2_CTRL_TYPE_INTEGER,
-               .name   = "Tuner Gain",
-               .min    = 0,
-               .max    = 102,
-               .def    = 0,
-               .step   = 1,
+       static struct spi_board_info board_info = {
+               .modalias               = "msi001",
+               .bus_num                = 0,
+               .chip_select            = 0,
+               .max_speed_hz           = 12000000,
        };
 
        s = kzalloc(sizeof(struct msi3101_state), GFP_KERNEL);
@@ -1841,19 +1399,20 @@ static int msi3101_probe(struct usb_interface *intf,
        mutex_init(&s->vb_queue_lock);
        spin_lock_init(&s->queued_bufs_lock);
        INIT_LIST_HEAD(&s->queued_bufs);
-
        s->udev = udev;
+       s->f_adc = bands[0].rangelow;
+       s->pixelformat = V4L2_SDR_FMT_CU8;
 
        /* Init videobuf2 queue structure */
-       s->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
        s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
        s->vb_queue.drv_priv = s;
        s->vb_queue.buf_struct_size = sizeof(struct msi3101_frame_buf);
        s->vb_queue.ops = &msi3101_vb2_ops;
        s->vb_queue.mem_ops = &vb2_vmalloc_memops;
-       s->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        ret = vb2_queue_init(&s->vb_queue);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
                goto err_free_mem;
        }
@@ -1865,36 +1424,59 @@ static int msi3101_probe(struct usb_interface *intf,
        set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
        video_set_drvdata(&s->vdev, s);
 
-       /* Register controls */
-       v4l2_ctrl_handler_init(&s->ctrl_handler, 7);
-       v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_mode, NULL);
-       s->ctrl_sampling_rate = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_rate, NULL);
-       v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_resolution, NULL);
-       s->ctrl_tuner_rf = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_rf, NULL);
-       s->ctrl_tuner_bw = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_bw, NULL);
-       s->ctrl_tuner_if = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_if, NULL);
-       s->ctrl_tuner_gain = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_gain, NULL);
-       if (s->ctrl_handler.error) {
-               ret = s->ctrl_handler.error;
-               dev_err(&s->udev->dev, "Could not initialize controls\n");
-               goto err_free_controls;
-       }
-
        /* Register the v4l2_device structure */
        s->v4l2_dev.release = msi3101_video_release;
        ret = v4l2_device_register(&intf->dev, &s->v4l2_dev);
        if (ret) {
                dev_err(&s->udev->dev,
                                "Failed to register v4l2-device (%d)\n", ret);
+               goto err_free_mem;
+       }
+
+       /* SPI master adapter */
+       master = spi_alloc_master(&s->udev->dev, 0);
+       if (master == NULL) {
+               ret = -ENOMEM;
+               goto err_unregister_v4l2_dev;
+       }
+
+       s->master = master;
+       master->bus_num = 0;
+       master->num_chipselect = 1;
+       master->transfer_one_message = msi3101_transfer_one_message;
+       spi_master_set_devdata(master, s);
+       ret = spi_register_master(master);
+       if (ret) {
+               spi_master_put(master);
+               goto err_unregister_v4l2_dev;
+       }
+
+       /* load v4l2 subdevice */
+       sd = v4l2_spi_new_subdev(&s->v4l2_dev, master, &board_info);
+       s->v4l2_subdev = sd;
+       if (sd == NULL) {
+               dev_err(&s->udev->dev, "cannot get v4l2 subdevice\n");
+               ret = -ENODEV;
+               goto err_unregister_master;
+       }
+
+       /* Register controls */
+       v4l2_ctrl_handler_init(&s->hdl, 0);
+       if (s->hdl.error) {
+               ret = s->hdl.error;
+               dev_err(&s->udev->dev, "Could not initialize controls\n");
                goto err_free_controls;
        }
 
-       s->v4l2_dev.ctrl_handler = &s->ctrl_handler;
+       /* currently all controls are from subdev */
+       v4l2_ctrl_add_handler(&s->hdl, sd->ctrl_handler, NULL);
+
+       s->v4l2_dev.ctrl_handler = &s->hdl;
        s->vdev.v4l2_dev = &s->v4l2_dev;
        s->vdev.lock = &s->v4l2_lock;
 
-       ret = video_register_device(&s->vdev, VFL_TYPE_GRABBER, -1);
-       if (ret < 0) {
+       ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
+       if (ret) {
                dev_err(&s->udev->dev,
                                "Failed to register as video device (%d)\n",
                                ret);
@@ -1905,10 +1487,12 @@ static int msi3101_probe(struct usb_interface *intf,
 
        return 0;
 
+err_free_controls:
+       v4l2_ctrl_handler_free(&s->hdl);
+err_unregister_master:
+       spi_unregister_master(s->master);
 err_unregister_v4l2_dev:
        v4l2_device_unregister(&s->v4l2_dev);
-err_free_controls:
-       v4l2_ctrl_handler_free(&s->ctrl_handler);
 err_free_mem:
        kfree(s);
        return ret;
index 8c7f35029cd54446e5a5e944086e8d846f925caf..ded31ea6bd39545382d4d64b30cc523c18bb1d1f 100644 (file)
@@ -1074,7 +1074,7 @@ static int iss_video_open(struct file *file)
        q->ops = &iss_video_vb2ops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->buf_struct_size = sizeof(struct iss_buffer);
-       q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
        ret = vb2_queue_init(q);
        if (ret) {
diff --git a/drivers/staging/media/rtl2832u_sdr/Kconfig b/drivers/staging/media/rtl2832u_sdr/Kconfig
new file mode 100644 (file)
index 0000000..3ede5fe
--- /dev/null
@@ -0,0 +1,7 @@
+config DVB_RTL2832_SDR
+       tristate "Realtek RTL2832 SDR"
+       depends on USB && DVB_CORE && I2C && VIDEO_V4L2 && DVB_USB_RTL28XXU
+       select DVB_RTL2832
+       select VIDEOBUF2_VMALLOC
+       default m if !MEDIA_SUBDRV_AUTOSELECT
+
diff --git a/drivers/staging/media/rtl2832u_sdr/Makefile b/drivers/staging/media/rtl2832u_sdr/Makefile
new file mode 100644 (file)
index 0000000..7e00a0d
--- /dev/null
@@ -0,0 +1,6 @@
+obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/usb/dvb-usb-v2
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
new file mode 100644 (file)
index 0000000..104ee8a
--- /dev/null
@@ -0,0 +1,1500 @@
+/*
+ * Realtek RTL2832U SDR driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ * GNU Radio plugin "gr-kernel" for device usage will be on:
+ * http://git.linuxtv.org/anttip/gr-kernel.git
+ *
+ */
+
+#include "dvb_frontend.h"
+#include "rtl2832_sdr.h"
+#include "dvb_usb.h"
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include <linux/jiffies.h>
+#include <linux/math64.h>
+
+#define MAX_BULK_BUFS            (10)
+#define BULK_BUFFER_SIZE         (128 * 512)
+
+static const struct v4l2_frequency_band bands_adc[] = {
+       {
+               .tuner = 0,
+               .type = V4L2_TUNER_ADC,
+               .index = 0,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   =  300000,
+               .rangehigh  =  300000,
+       },
+       {
+               .tuner = 0,
+               .type = V4L2_TUNER_ADC,
+               .index = 1,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   =  900001,
+               .rangehigh  = 2800000,
+       },
+       {
+               .tuner = 0,
+               .type = V4L2_TUNER_ADC,
+               .index = 2,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   = 3200000,
+               .rangehigh  = 3200000,
+       },
+};
+
+static const struct v4l2_frequency_band bands_fm[] = {
+       {
+               .tuner = 1,
+               .type = V4L2_TUNER_RF,
+               .index = 0,
+               .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+               .rangelow   =    50000000,
+               .rangehigh  =  2000000000,
+       },
+};
+
+/* stream formats */
+struct rtl2832_sdr_format {
+       char    *name;
+       u32     pixelformat;
+};
+
+static struct rtl2832_sdr_format formats[] = {
+       {
+               .name           = "IQ U8",
+               .pixelformat    =  V4L2_SDR_FMT_CU8,
+       }, {
+               .name           = "IQ U16LE (emulated)",
+               .pixelformat    = V4L2_SDR_FMT_CU16LE,
+       },
+};
+
+static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
+
+/* intermediate buffers with raw data from the USB device */
+struct rtl2832_sdr_frame_buf {
+       struct vb2_buffer vb;   /* common v4l buffer stuff -- must be first */
+       struct list_head list;
+};
+
+struct rtl2832_sdr_state {
+#define POWER_ON           (1 << 1)
+#define URB_BUF            (1 << 2)
+       unsigned long flags;
+
+       const struct rtl2832_config *cfg;
+       struct dvb_frontend *fe;
+       struct dvb_usb_device *d;
+       struct i2c_adapter *i2c;
+       u8 bank;
+
+       struct video_device vdev;
+       struct v4l2_device v4l2_dev;
+
+       /* videobuf2 queue and queued buffers list */
+       struct vb2_queue vb_queue;
+       struct list_head queued_bufs;
+       spinlock_t queued_bufs_lock; /* Protects queued_bufs */
+       unsigned sequence;           /* buffer sequence counter */
+
+       /* Note if taking both locks v4l2_lock must always be locked first! */
+       struct mutex v4l2_lock;      /* Protects everything else */
+       struct mutex vb_queue_lock;  /* Protects vb_queue and capt_file */
+
+       /* Pointer to our usb_device, will be NULL after unplug */
+       struct usb_device *udev; /* Both mutexes most be hold when setting! */
+
+       unsigned int vb_full; /* vb is full and packets dropped */
+
+       struct urb     *urb_list[MAX_BULK_BUFS];
+       int            buf_num;
+       unsigned long  buf_size;
+       u8             *buf_list[MAX_BULK_BUFS];
+       dma_addr_t     dma_addr[MAX_BULK_BUFS];
+       int urbs_initialized;
+       int urbs_submitted;
+
+       unsigned int f_adc, f_tuner;
+       u32 pixelformat;
+
+       /* Controls */
+       struct v4l2_ctrl_handler hdl;
+       struct v4l2_ctrl *bandwidth_auto;
+       struct v4l2_ctrl *bandwidth;
+
+       /* for sample rate calc */
+       unsigned int sample;
+       unsigned int sample_measured;
+       unsigned long jiffies_next;
+};
+
+/* write multiple hardware registers */
+static int rtl2832_sdr_wr(struct rtl2832_sdr_state *s, u8 reg, const u8 *val,
+               int len)
+{
+       int ret;
+#define MAX_WR_LEN 24
+#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
+       u8 buf[MAX_WR_XFER_LEN];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = s->cfg->i2c_addr,
+                       .flags = 0,
+                       .len = 1 + len,
+                       .buf = buf,
+               }
+       };
+
+       if (WARN_ON(len > MAX_WR_LEN))
+               return -EINVAL;
+
+       buf[0] = reg;
+       memcpy(&buf[1], val, len);
+
+       ret = i2c_transfer(s->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               dev_err(&s->i2c->dev,
+                       "%s: I2C wr failed=%d reg=%02x len=%d\n",
+                       KBUILD_MODNAME, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple hardware registers */
+static int rtl2832_sdr_rd(struct rtl2832_sdr_state *s, u8 reg, u8 *val, int len)
+{
+       int ret;
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = s->cfg->i2c_addr,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg,
+               }, {
+                       .addr = s->cfg->i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = val,
+               }
+       };
+
+       ret = i2c_transfer(s->i2c, msg, 2);
+       if (ret == 2) {
+               ret = 0;
+       } else {
+               dev_err(&s->i2c->dev,
+                               "%s: I2C rd failed=%d reg=%02x len=%d\n",
+                               KBUILD_MODNAME, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* write multiple registers */
+static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_state *s, u16 reg,
+               const u8 *val, int len)
+{
+       int ret;
+       u8 reg2 = (reg >> 0) & 0xff;
+       u8 bank = (reg >> 8) & 0xff;
+
+       /* switch bank if needed */
+       if (bank != s->bank) {
+               ret = rtl2832_sdr_wr(s, 0x00, &bank, 1);
+               if (ret)
+                       return ret;
+
+               s->bank = bank;
+       }
+
+       return rtl2832_sdr_wr(s, reg2, val, len);
+}
+
+/* read multiple registers */
+static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_state *s, u16 reg, u8 *val,
+               int len)
+{
+       int ret;
+       u8 reg2 = (reg >> 0) & 0xff;
+       u8 bank = (reg >> 8) & 0xff;
+
+       /* switch bank if needed */
+       if (bank != s->bank) {
+               ret = rtl2832_sdr_wr(s, 0x00, &bank, 1);
+               if (ret)
+                       return ret;
+
+               s->bank = bank;
+       }
+
+       return rtl2832_sdr_rd(s, reg2, val, len);
+}
+
+/* write single register */
+static int rtl2832_sdr_wr_reg(struct rtl2832_sdr_state *s, u16 reg, u8 val)
+{
+       return rtl2832_sdr_wr_regs(s, reg, &val, 1);
+}
+
+#if 0
+/* read single register */
+static int rtl2832_sdr_rd_reg(struct rtl2832_sdr_state *s, u16 reg, u8 *val)
+{
+       return rtl2832_sdr_rd_regs(s, reg, val, 1);
+}
+#endif
+
+/* write single register with mask */
+static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
+               u8 val, u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = rtl2832_sdr_rd_regs(s, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return rtl2832_sdr_wr_regs(s, reg, &val, 1);
+}
+
+#if 0
+/* read single register with mask */
+static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
+               u8 *val, u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = rtl2832_sdr_rd_regs(s, reg, &tmp, 1);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+#endif
+
+/* Private functions */
+static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
+               struct rtl2832_sdr_state *s)
+{
+       unsigned long flags = 0;
+       struct rtl2832_sdr_frame_buf *buf = NULL;
+
+       spin_lock_irqsave(&s->queued_bufs_lock, flags);
+       if (list_empty(&s->queued_bufs))
+               goto leave;
+
+       buf = list_entry(s->queued_bufs.next,
+                       struct rtl2832_sdr_frame_buf, list);
+       list_del(&buf->list);
+leave:
+       spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+       return buf;
+}
+
+static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
+               void *dst, const u8 *src, unsigned int src_len)
+{
+       unsigned int dst_len;
+
+       if (s->pixelformat ==  V4L2_SDR_FMT_CU8) {
+               /* native stream, no need to convert */
+               memcpy(dst, src, src_len);
+               dst_len = src_len;
+       } else if (s->pixelformat == V4L2_SDR_FMT_CU16LE) {
+               /* convert u8 to u16 */
+               unsigned int i;
+               u16 *u16dst = dst;
+               for (i = 0; i < src_len; i++)
+                       *u16dst++ = (src[i] << 8) | (src[i] >> 0);
+               dst_len = 2 * src_len;
+       } else {
+               dst_len = 0;
+       }
+
+       /* calculate samping rate and output it in 10 seconds intervals */
+       if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
+#define MSECS 10000UL
+               unsigned int samples = s->sample - s->sample_measured;
+               s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
+               s->sample_measured = s->sample;
+               dev_dbg(&s->udev->dev,
+                               "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
+                               src_len, samples, MSECS,
+                               samples * 1000UL / MSECS);
+       }
+
+       /* total number of I+Q pairs */
+       s->sample += src_len / 2;
+
+       return dst_len;
+}
+
+/*
+ * This gets called for the bulk stream pipe. This is done in interrupt
+ * time, so it has to be fast, not crash, and not stall. Neat.
+ */
+static void rtl2832_sdr_urb_complete(struct urb *urb)
+{
+       struct rtl2832_sdr_state *s = urb->context;
+       struct rtl2832_sdr_frame_buf *fbuf;
+
+       dev_dbg_ratelimited(&s->udev->dev,
+                       "%s: status=%d length=%d/%d errors=%d\n",
+                       __func__, urb->status, urb->actual_length,
+                       urb->transfer_buffer_length, urb->error_count);
+
+       switch (urb->status) {
+       case 0:             /* success */
+       case -ETIMEDOUT:    /* NAK */
+               break;
+       case -ECONNRESET:   /* kill */
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       default:            /* error */
+               dev_err_ratelimited(&s->udev->dev, "urb failed=%d\n",
+                               urb->status);
+               break;
+       }
+
+       if (likely(urb->actual_length > 0)) {
+               void *ptr;
+               unsigned int len;
+               /* get free framebuffer */
+               fbuf = rtl2832_sdr_get_next_fill_buf(s);
+               if (unlikely(fbuf == NULL)) {
+                       s->vb_full++;
+                       dev_notice_ratelimited(&s->udev->dev,
+                                       "videobuf is full, %d packets dropped\n",
+                                       s->vb_full);
+                       goto skip;
+               }
+
+               /* fill framebuffer */
+               ptr = vb2_plane_vaddr(&fbuf->vb, 0);
+               len = rtl2832_sdr_convert_stream(s, ptr, urb->transfer_buffer,
+                               urb->actual_length);
+               vb2_set_plane_payload(&fbuf->vb, 0, len);
+               v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);
+               fbuf->vb.v4l2_buf.sequence = s->sequence++;
+               vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+       }
+skip:
+       usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int rtl2832_sdr_kill_urbs(struct rtl2832_sdr_state *s)
+{
+       int i;
+
+       for (i = s->urbs_submitted - 1; i >= 0; i--) {
+               dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
+               /* stop the URB */
+               usb_kill_urb(s->urb_list[i]);
+       }
+       s->urbs_submitted = 0;
+
+       return 0;
+}
+
+static int rtl2832_sdr_submit_urbs(struct rtl2832_sdr_state *s)
+{
+       int i, ret;
+
+       for (i = 0; i < s->urbs_initialized; i++) {
+               dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
+               ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
+               if (ret) {
+                       dev_err(&s->udev->dev,
+                                       "Could not submit urb no. %d - get them all back\n",
+                                       i);
+                       rtl2832_sdr_kill_urbs(s);
+                       return ret;
+               }
+               s->urbs_submitted++;
+       }
+
+       return 0;
+}
+
+static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_state *s)
+{
+       if (s->flags & USB_STATE_URB_BUF) {
+               while (s->buf_num) {
+                       s->buf_num--;
+                       dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
+                                       __func__, s->buf_num);
+                       usb_free_coherent(s->udev, s->buf_size,
+                                         s->buf_list[s->buf_num],
+                                         s->dma_addr[s->buf_num]);
+               }
+       }
+       s->flags &= ~USB_STATE_URB_BUF;
+
+       return 0;
+}
+
+static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_state *s)
+{
+       s->buf_num = 0;
+       s->buf_size = BULK_BUFFER_SIZE;
+
+       dev_dbg(&s->udev->dev,
+                       "%s: all in all I will use %u bytes for streaming\n",
+                       __func__,  MAX_BULK_BUFS * BULK_BUFFER_SIZE);
+
+       for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
+               s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
+                               BULK_BUFFER_SIZE, GFP_ATOMIC,
+                               &s->dma_addr[s->buf_num]);
+               if (!s->buf_list[s->buf_num]) {
+                       dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
+                                       __func__, s->buf_num);
+                       rtl2832_sdr_free_stream_bufs(s);
+                       return -ENOMEM;
+               }
+
+               dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
+                               __func__, s->buf_num,
+                               s->buf_list[s->buf_num],
+                               (long long)s->dma_addr[s->buf_num]);
+               s->flags |= USB_STATE_URB_BUF;
+       }
+
+       return 0;
+}
+
+static int rtl2832_sdr_free_urbs(struct rtl2832_sdr_state *s)
+{
+       int i;
+
+       rtl2832_sdr_kill_urbs(s);
+
+       for (i = s->urbs_initialized - 1; i >= 0; i--) {
+               if (s->urb_list[i]) {
+                       dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
+                                       __func__, i);
+                       /* free the URBs */
+                       usb_free_urb(s->urb_list[i]);
+               }
+       }
+       s->urbs_initialized = 0;
+
+       return 0;
+}
+
+static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
+{
+       int i, j;
+
+       /* allocate the URBs */
+       for (i = 0; i < MAX_BULK_BUFS; i++) {
+               dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+               s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+               if (!s->urb_list[i]) {
+                       dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
+                       for (j = 0; j < i; j++)
+                               usb_free_urb(s->urb_list[j]);
+                       return -ENOMEM;
+               }
+               usb_fill_bulk_urb(s->urb_list[i],
+                               s->udev,
+                               usb_rcvbulkpipe(s->udev, 0x81),
+                               s->buf_list[i],
+                               BULK_BUFFER_SIZE,
+                               rtl2832_sdr_urb_complete, s);
+
+               s->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+               s->urb_list[i]->transfer_dma = s->dma_addr[i];
+               s->urbs_initialized++;
+       }
+
+       return 0;
+}
+
+/* Must be called with vb_queue_lock hold */
+static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
+{
+       unsigned long flags = 0;
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       spin_lock_irqsave(&s->queued_bufs_lock, flags);
+       while (!list_empty(&s->queued_bufs)) {
+               struct rtl2832_sdr_frame_buf *buf;
+               buf = list_entry(s->queued_bufs.next,
+                               struct rtl2832_sdr_frame_buf, list);
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+}
+
+/* The user yanked out the cable... */
+static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
+{
+       struct rtl2832_sdr_state *s = fe->sec_priv;
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       mutex_lock(&s->vb_queue_lock);
+       mutex_lock(&s->v4l2_lock);
+       /* No need to keep the urbs around after disconnection */
+       s->udev = NULL;
+
+       v4l2_device_disconnect(&s->v4l2_dev);
+       video_unregister_device(&s->vdev);
+       mutex_unlock(&s->v4l2_lock);
+       mutex_unlock(&s->vb_queue_lock);
+
+       v4l2_device_put(&s->v4l2_dev);
+
+       fe->sec_priv = NULL;
+}
+
+static int rtl2832_sdr_querycap(struct file *file, void *fh,
+               struct v4l2_capability *cap)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strlcpy(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;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       return 0;
+}
+
+/* Videobuf2 operations */
+static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
+               const struct v4l2_format *fmt, unsigned int *nbuffers,
+               unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+       struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+       dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
+
+       /* Need at least 8 buffers */
+       if (vq->num_buffers + *nbuffers < 8)
+               *nbuffers = 8 - vq->num_buffers;
+       *nplanes = 1;
+       /* 2 = max 16-bit sample returned */
+       sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 2);
+       dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
+                       __func__, *nbuffers, sizes[0]);
+       return 0;
+}
+
+static int rtl2832_sdr_buf_prepare(struct vb2_buffer *vb)
+{
+       struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
+
+       /* Don't allow queing new buffers after device disconnection */
+       if (!s->udev)
+               return -ENODEV;
+
+       return 0;
+}
+
+static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
+{
+       struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
+       struct rtl2832_sdr_frame_buf *buf =
+                       container_of(vb, struct rtl2832_sdr_frame_buf, vb);
+       unsigned long flags = 0;
+
+       /* Check the device has not disconnected between prep and queuing */
+       if (!s->udev) {
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+               return;
+       }
+
+       spin_lock_irqsave(&s->queued_bufs_lock, flags);
+       list_add_tail(&buf->list, &s->queued_bufs);
+       spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+}
+
+static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
+{
+       struct dvb_frontend *fe = s->fe;
+       int ret;
+       unsigned int f_sr, f_if;
+       u8 buf[4], u8tmp1, u8tmp2;
+       u64 u64tmp;
+       u32 u32tmp;
+       dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
+
+       if (!test_bit(POWER_ON, &s->flags))
+               return 0;
+
+       if (s->f_adc == 0)
+               return 0;
+
+       f_sr = s->f_adc;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x00\x00", 2);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00\x00\x00\x00", 4);
+       if (ret)
+               goto err;
+
+       /* get IF from tuner */
+       if (fe->ops.tuner_ops.get_if_frequency)
+               ret = fe->ops.tuner_ops.get_if_frequency(fe, &f_if);
+       else
+               ret = -EINVAL;
+
+       if (ret)
+               goto err;
+
+       /* program IF */
+       u64tmp = f_if % s->cfg->xtal;
+       u64tmp *= 0x400000;
+       u64tmp = div_u64(u64tmp, s->cfg->xtal);
+       u64tmp = -u64tmp;
+       u32tmp = u64tmp & 0x3fffff;
+
+       dev_dbg(&s->udev->dev, "%s: f_if=%u if_ctl=%08x\n",
+                       __func__, f_if, u32tmp);
+
+       buf[0] = (u32tmp >> 16) & 0xff;
+       buf[1] = (u32tmp >>  8) & 0xff;
+       buf[2] = (u32tmp >>  0) & 0xff;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x119, buf, 3);
+       if (ret)
+               goto err;
+
+       /* BB / IF mode */
+       /* POR: 0x1b1=0x1f, 0x008=0x0d, 0x006=0x80 */
+       if (f_if) {
+               u8tmp1 = 0x1a; /* disable Zero-IF */
+               u8tmp2 = 0x8d; /* enable ADC I */
+       } else {
+               u8tmp1 = 0x1b; /* enable Zero-IF, DC, IQ */
+               u8tmp2 = 0xcd; /* enable ADC I, ADC Q */
+       }
+
+       ret = rtl2832_sdr_wr_reg(s, 0x1b1, u8tmp1);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_reg(s, 0x008, u8tmp2);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_reg(s, 0x006, 0x80);
+       if (ret)
+               goto err;
+
+       /* program sampling rate (resampling down) */
+       u32tmp = div_u64(s->cfg->xtal * 0x400000ULL, f_sr * 4U);
+       u32tmp <<= 2;
+       buf[0] = (u32tmp >> 24) & 0xff;
+       buf[1] = (u32tmp >> 16) & 0xff;
+       buf[2] = (u32tmp >>  8) & 0xff;
+       buf[3] = (u32tmp >>  0) & 0xff;
+       ret = rtl2832_sdr_wr_regs(s, 0x19f, buf, 4);
+       if (ret)
+               goto err;
+
+       /* low-pass filter */
+       ret = rtl2832_sdr_wr_regs(s, 0x11c,
+                       "\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5",
+                       20);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
+       if (ret)
+               goto err;
+
+       /* mode */
+       ret = rtl2832_sdr_wr_regs(s, 0x019, "\x05", 1);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x01a, "\x1b\x16\x0d\x06\x01\xff", 6);
+       if (ret)
+               goto err;
+
+       /* FSM */
+       ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00\xf0\x0f", 3);
+       if (ret)
+               goto err;
+
+       /* PID filter */
+       ret = rtl2832_sdr_wr_regs(s, 0x061, "\x60", 1);
+       if (ret)
+               goto err;
+
+       /* used RF tuner based settings */
+       switch (s->cfg->tuner) {
+       case RTL2832_TUNER_E4000:
+               ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x104, "\xd0", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x18", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x14", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xec", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x83", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x010, "\x49", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x87", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x85", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x013, "\x02", 1);
+               break;
+       case RTL2832_TUNER_FC0012:
+       case RTL2832_TUNER_FC0013:
+               ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x2c", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x16", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x011, "\xe9\xbf", 2);
+               ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x11", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xef", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
+               break;
+       case RTL2832_TUNER_R820T:
+               ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x103, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x24", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+               ret = rtl2832_sdr_wr_regs(s, 0x011, "\xf4", 1);
+               break;
+       default:
+               dev_notice(&s->udev->dev, "Unsupported tuner\n");
+       }
+
+       /* software reset */
+       ret = rtl2832_sdr_wr_reg_mask(s, 0x101, 0x04, 0x04);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_reg_mask(s, 0x101, 0x00, 0x04);
+       if (ret)
+               goto err;
+err:
+       return ret;
+};
+
+static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_state *s)
+{
+       int ret;
+
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       /* PID filter */
+       ret = rtl2832_sdr_wr_regs(s, 0x061, "\xe0", 1);
+       if (ret)
+               goto err;
+
+       /* mode */
+       ret = rtl2832_sdr_wr_regs(s, 0x019, "\x20", 1);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
+       if (ret)
+               goto err;
+
+       /* FSM */
+       ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00\x0f\xff", 3);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x40\x00", 2);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_wr_regs(s, 0x115, "\x06\x3f\xce\xcc", 4);
+       if (ret)
+               goto err;
+err:
+       return;
+};
+
+static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
+{
+       struct dvb_frontend *fe = s->fe;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct v4l2_ctrl *bandwidth_auto;
+       struct v4l2_ctrl *bandwidth;
+
+       /*
+        * tuner RF (Hz)
+        */
+       if (s->f_tuner == 0)
+               return 0;
+
+       /*
+        * bandwidth (Hz)
+        */
+       bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
+       bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
+       if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
+               c->bandwidth_hz = s->f_adc;
+               v4l2_ctrl_s_ctrl(bandwidth, s->f_adc);
+       } else {
+               c->bandwidth_hz = v4l2_ctrl_g_ctrl(bandwidth);
+       }
+
+       c->frequency = s->f_tuner;
+       c->delivery_system = SYS_DVBT;
+
+       dev_dbg(&s->udev->dev, "%s: frequency=%u bandwidth=%d\n",
+                       __func__, c->frequency, c->bandwidth_hz);
+
+       if (!test_bit(POWER_ON, &s->flags))
+               return 0;
+
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       return 0;
+};
+
+static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
+{
+       struct dvb_frontend *fe = s->fe;
+
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       if (fe->ops.tuner_ops.init)
+               fe->ops.tuner_ops.init(fe);
+
+       return 0;
+};
+
+static void rtl2832_sdr_unset_tuner(struct rtl2832_sdr_state *s)
+{
+       struct dvb_frontend *fe = s->fe;
+
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       if (fe->ops.tuner_ops.sleep)
+               fe->ops.tuner_ops.sleep(fe);
+
+       return;
+};
+
+static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+       int ret;
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       if (!s->udev)
+               return -ENODEV;
+
+       if (mutex_lock_interruptible(&s->v4l2_lock))
+               return -ERESTARTSYS;
+
+       if (s->d->props->power_ctrl)
+               s->d->props->power_ctrl(s->d, 1);
+
+       set_bit(POWER_ON, &s->flags);
+
+       ret = rtl2832_sdr_set_tuner(s);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_set_tuner_freq(s);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_set_adc(s);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_alloc_stream_bufs(s);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_sdr_alloc_urbs(s);
+       if (ret)
+               goto err;
+
+       s->sequence = 0;
+
+       ret = rtl2832_sdr_submit_urbs(s);
+       if (ret)
+               goto err;
+
+err:
+       mutex_unlock(&s->v4l2_lock);
+
+       return ret;
+}
+
+static int rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
+{
+       struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       if (mutex_lock_interruptible(&s->v4l2_lock))
+               return -ERESTARTSYS;
+
+       rtl2832_sdr_kill_urbs(s);
+       rtl2832_sdr_free_urbs(s);
+       rtl2832_sdr_free_stream_bufs(s);
+       rtl2832_sdr_cleanup_queued_bufs(s);
+       rtl2832_sdr_unset_adc(s);
+       rtl2832_sdr_unset_tuner(s);
+
+       clear_bit(POWER_ON, &s->flags);
+
+       if (s->d->props->power_ctrl)
+               s->d->props->power_ctrl(s->d, 0);
+
+       mutex_unlock(&s->v4l2_lock);
+
+       return 0;
+}
+
+static struct vb2_ops rtl2832_sdr_vb2_ops = {
+       .queue_setup            = rtl2832_sdr_queue_setup,
+       .buf_prepare            = rtl2832_sdr_buf_prepare,
+       .buf_queue              = rtl2832_sdr_buf_queue,
+       .start_streaming        = rtl2832_sdr_start_streaming,
+       .stop_streaming         = rtl2832_sdr_stop_streaming,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+};
+
+static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
+               struct v4l2_tuner *v)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
+                       __func__, v->index, v->type);
+
+       if (v->index == 0) {
+               strlcpy(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;
+               v->rangehigh = 3200000;
+       } else if (v->index == 1) {
+               strlcpy(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;
+               v->rangehigh = 2000000000;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
+               const struct v4l2_tuner *v)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       if (v->index > 1)
+               return -EINVAL;
+       return 0;
+}
+
+static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
+               struct v4l2_frequency_band *band)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
+                       __func__, band->tuner, band->type, band->index);
+
+       if (band->tuner == 0) {
+               if (band->index >= ARRAY_SIZE(bands_adc))
+                       return -EINVAL;
+
+               *band = bands_adc[band->index];
+       } else if (band->tuner == 1) {
+               if (band->index >= ARRAY_SIZE(bands_fm))
+                       return -EINVAL;
+
+               *band = bands_fm[band->index];
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
+               struct v4l2_frequency *f)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       int ret  = 0;
+       dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
+                       __func__, f->tuner, f->type);
+
+       if (f->tuner == 0) {
+               f->frequency = s->f_adc;
+               f->type = V4L2_TUNER_ADC;
+       } else if (f->tuner == 1) {
+               f->frequency = s->f_tuner;
+               f->type = V4L2_TUNER_RF;
+       } else {
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
+               const struct v4l2_frequency *f)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       int ret, band;
+
+       dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
+                       __func__, f->tuner, f->type, f->frequency);
+
+       /* ADC band midpoints */
+       #define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
+       #define BAND_ADC_1 ((bands_adc[1].rangehigh + bands_adc[2].rangelow) / 2)
+
+       if (f->tuner == 0 && f->type == V4L2_TUNER_ADC) {
+               if (f->frequency < BAND_ADC_0)
+                       band = 0;
+               else if (f->frequency < BAND_ADC_1)
+                       band = 1;
+               else
+                       band = 2;
+
+               s->f_adc = clamp_t(unsigned int, f->frequency,
+                               bands_adc[band].rangelow,
+                               bands_adc[band].rangehigh);
+
+               dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
+                               __func__, s->f_adc);
+               ret = rtl2832_sdr_set_adc(s);
+       } else if (f->tuner == 1) {
+               s->f_tuner = clamp_t(unsigned int, f->frequency,
+                               bands_fm[0].rangelow,
+                               bands_fm[0].rangehigh);
+               dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
+                               __func__, f->frequency);
+
+               ret = rtl2832_sdr_set_tuner_freq(s);
+       } else {
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_fmtdesc *f)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       if (f->index >= NUM_FORMATS)
+               return -EINVAL;
+
+       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       f->pixelformat = formats[f->index].pixelformat;
+
+       return 0;
+}
+
+static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_format *f)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+       f->fmt.sdr.pixelformat = s->pixelformat;
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+
+       return 0;
+}
+
+static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_format *f)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       struct vb2_queue *q = &s->vb_queue;
+       int i;
+       dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+                       (char *)&f->fmt.sdr.pixelformat);
+
+       if (vb2_is_busy(q))
+               return -EBUSY;
+
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+       for (i = 0; i < NUM_FORMATS; i++) {
+               if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+                       s->pixelformat = f->fmt.sdr.pixelformat;
+                       return 0;
+               }
+       }
+
+       f->fmt.sdr.pixelformat = formats[0].pixelformat;
+       s->pixelformat = formats[0].pixelformat;
+
+       return 0;
+}
+
+static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
+               struct v4l2_format *f)
+{
+       struct rtl2832_sdr_state *s = video_drvdata(file);
+       int i;
+       dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+                       (char *)&f->fmt.sdr.pixelformat);
+
+       memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+       for (i = 0; i < NUM_FORMATS; i++) {
+               if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
+                       return 0;
+       }
+
+       f->fmt.sdr.pixelformat = formats[0].pixelformat;
+
+       return 0;
+}
+
+static const struct v4l2_ioctl_ops rtl2832_sdr_ioctl_ops = {
+       .vidioc_querycap          = rtl2832_sdr_querycap,
+
+       .vidioc_enum_fmt_sdr_cap  = rtl2832_sdr_enum_fmt_sdr_cap,
+       .vidioc_g_fmt_sdr_cap     = rtl2832_sdr_g_fmt_sdr_cap,
+       .vidioc_s_fmt_sdr_cap     = rtl2832_sdr_s_fmt_sdr_cap,
+       .vidioc_try_fmt_sdr_cap   = rtl2832_sdr_try_fmt_sdr_cap,
+
+       .vidioc_reqbufs           = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs       = vb2_ioctl_create_bufs,
+       .vidioc_prepare_buf       = vb2_ioctl_prepare_buf,
+       .vidioc_querybuf          = vb2_ioctl_querybuf,
+       .vidioc_qbuf              = vb2_ioctl_qbuf,
+       .vidioc_dqbuf             = vb2_ioctl_dqbuf,
+
+       .vidioc_streamon          = vb2_ioctl_streamon,
+       .vidioc_streamoff         = vb2_ioctl_streamoff,
+
+       .vidioc_g_tuner           = rtl2832_sdr_g_tuner,
+       .vidioc_s_tuner           = rtl2832_sdr_s_tuner,
+
+       .vidioc_enum_freq_bands   = rtl2832_sdr_enum_freq_bands,
+       .vidioc_g_frequency       = rtl2832_sdr_g_frequency,
+       .vidioc_s_frequency       = rtl2832_sdr_s_frequency,
+
+       .vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+       .vidioc_log_status        = v4l2_ctrl_log_status,
+};
+
+static const struct v4l2_file_operations rtl2832_sdr_fops = {
+       .owner                    = THIS_MODULE,
+       .open                     = v4l2_fh_open,
+       .release                  = vb2_fop_release,
+       .read                     = vb2_fop_read,
+       .poll                     = vb2_fop_poll,
+       .mmap                     = vb2_fop_mmap,
+       .unlocked_ioctl           = video_ioctl2,
+};
+
+static struct video_device rtl2832_sdr_template = {
+       .name                     = "Realtek RTL2832 SDR",
+       .release                  = video_device_release_empty,
+       .fops                     = &rtl2832_sdr_fops,
+       .ioctl_ops                = &rtl2832_sdr_ioctl_ops,
+};
+
+static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct rtl2832_sdr_state *s =
+                       container_of(ctrl->handler, struct rtl2832_sdr_state,
+                                       hdl);
+       struct dvb_frontend *fe = s->fe;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       dev_dbg(&s->udev->dev,
+                       "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
+                       __func__, ctrl->id, ctrl->name, ctrl->val,
+                       ctrl->minimum, ctrl->maximum, ctrl->step);
+
+       switch (ctrl->id) {
+       case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
+       case V4L2_CID_RF_TUNER_BANDWIDTH:
+               /* TODO: these controls should be moved to tuner drivers */
+               if (s->bandwidth_auto->val) {
+                       /* Round towards the closest legal value */
+                       s32 val = s->f_adc + s->bandwidth->step / 2;
+                       u32 offset;
+                       val = clamp(val, s->bandwidth->minimum, s->bandwidth->maximum);
+                       offset = val - s->bandwidth->minimum;
+                       offset = s->bandwidth->step * (offset / s->bandwidth->step);
+                       s->bandwidth->val = s->bandwidth->minimum + offset;
+               }
+
+               c->bandwidth_hz = s->bandwidth->val;
+
+               if (!test_bit(POWER_ON, &s->flags))
+                       return 0;
+
+               if (fe->ops.tuner_ops.set_params)
+                       ret = fe->ops.tuner_ops.set_params(fe);
+               else
+                       ret = 0;
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops rtl2832_sdr_ctrl_ops = {
+       .s_ctrl = rtl2832_sdr_s_ctrl,
+};
+
+static void rtl2832_sdr_video_release(struct v4l2_device *v)
+{
+       struct rtl2832_sdr_state *s =
+                       container_of(v, struct rtl2832_sdr_state, v4l2_dev);
+
+       v4l2_ctrl_handler_free(&s->hdl);
+       v4l2_device_unregister(&s->v4l2_dev);
+       kfree(s);
+}
+
+struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+               struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
+               struct v4l2_subdev *sd)
+{
+       int ret;
+       struct rtl2832_sdr_state *s;
+       const struct v4l2_ctrl_ops *ops = &rtl2832_sdr_ctrl_ops;
+       struct dvb_usb_device *d = i2c_get_adapdata(i2c);
+
+       s = kzalloc(sizeof(struct rtl2832_sdr_state), GFP_KERNEL);
+       if (s == NULL) {
+               dev_err(&d->udev->dev,
+                               "Could not allocate memory for rtl2832_sdr_state\n");
+               return NULL;
+       }
+
+       /* setup the state */
+       s->fe = fe;
+       s->d = d;
+       s->udev = d->udev;
+       s->i2c = i2c;
+       s->cfg = cfg;
+       s->f_adc = bands_adc[0].rangelow;
+       s->f_tuner = bands_fm[0].rangelow;
+       s->pixelformat =  V4L2_SDR_FMT_CU8;
+
+       mutex_init(&s->v4l2_lock);
+       mutex_init(&s->vb_queue_lock);
+       spin_lock_init(&s->queued_bufs_lock);
+       INIT_LIST_HEAD(&s->queued_bufs);
+
+       /* Init videobuf2 queue structure */
+       s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
+       s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+       s->vb_queue.drv_priv = s;
+       s->vb_queue.buf_struct_size = sizeof(struct rtl2832_sdr_frame_buf);
+       s->vb_queue.ops = &rtl2832_sdr_vb2_ops;
+       s->vb_queue.mem_ops = &vb2_vmalloc_memops;
+       s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       ret = vb2_queue_init(&s->vb_queue);
+       if (ret) {
+               dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
+               goto err_free_mem;
+       }
+
+       /* Register controls */
+       switch (s->cfg->tuner) {
+       case RTL2832_TUNER_E4000:
+               v4l2_ctrl_handler_init(&s->hdl, 9);
+               if (sd)
+                       v4l2_ctrl_add_handler(&s->hdl, sd->ctrl_handler, NULL);
+               break;
+       case RTL2832_TUNER_R820T:
+               v4l2_ctrl_handler_init(&s->hdl, 2);
+               s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
+               s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 0, 8000000, 100000, 0);
+               v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
+               break;
+       case RTL2832_TUNER_FC0012:
+       case RTL2832_TUNER_FC0013:
+               v4l2_ctrl_handler_init(&s->hdl, 2);
+               s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
+               s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 6000000, 8000000, 1000000, 6000000);
+               v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
+               break;
+       default:
+               v4l2_ctrl_handler_init(&s->hdl, 0);
+               dev_notice(&s->udev->dev, "%s: Unsupported tuner\n",
+                               KBUILD_MODNAME);
+               goto err_free_controls;
+       }
+
+       if (s->hdl.error) {
+               ret = s->hdl.error;
+               dev_err(&s->udev->dev, "Could not initialize controls\n");
+               goto err_free_controls;
+       }
+
+       /* Init video_device structure */
+       s->vdev = rtl2832_sdr_template;
+       s->vdev.queue = &s->vb_queue;
+       s->vdev.queue->lock = &s->vb_queue_lock;
+       set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
+       video_set_drvdata(&s->vdev, s);
+
+       /* Register the v4l2_device structure */
+       s->v4l2_dev.release = rtl2832_sdr_video_release;
+       ret = v4l2_device_register(&s->udev->dev, &s->v4l2_dev);
+       if (ret) {
+               dev_err(&s->udev->dev,
+                               "Failed to register v4l2-device (%d)\n", ret);
+               goto err_free_controls;
+       }
+
+       s->v4l2_dev.ctrl_handler = &s->hdl;
+       s->vdev.v4l2_dev = &s->v4l2_dev;
+       s->vdev.lock = &s->v4l2_lock;
+       s->vdev.vfl_dir = VFL_DIR_RX;
+
+       ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
+       if (ret) {
+               dev_err(&s->udev->dev,
+                               "Failed to register as video device (%d)\n",
+                               ret);
+               goto err_unregister_v4l2_dev;
+       }
+       dev_info(&s->udev->dev, "Registered as %s\n",
+                       video_device_node_name(&s->vdev));
+
+       fe->sec_priv = s;
+       fe->ops.release_sec = rtl2832_sdr_release_sec;
+
+       dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n",
+                       KBUILD_MODNAME);
+       return fe;
+
+err_unregister_v4l2_dev:
+       v4l2_device_unregister(&s->v4l2_dev);
+err_free_controls:
+       v4l2_ctrl_handler_free(&s->hdl);
+err_free_mem:
+       kfree(s);
+       return NULL;
+}
+EXPORT_SYMBOL(rtl2832_sdr_attach);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Realtek RTL2832 SDR driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
new file mode 100644 (file)
index 0000000..b865fad
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Realtek RTL2832U SDR driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ *
+ * GNU Radio plugin "gr-kernel" for device usage will be on:
+ * http://git.linuxtv.org/anttip/gr-kernel.git
+ *
+ * TODO:
+ * Help is very highly welcome for these + all the others you could imagine:
+ * - move controls to V4L2 API
+ * - use libv4l2 for stream format conversions
+ * - gr-kernel: switch to v4l2_mmap (current read eats a lot of cpu)
+ * - SDRSharp support
+ */
+
+#ifndef RTL2832_SDR_H
+#define RTL2832_SDR_H
+
+#include <linux/kconfig.h>
+#include <media/v4l2-subdev.h>
+
+/* for config struct */
+#include "rtl2832.h"
+
+#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR)
+extern struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
+       struct v4l2_subdev *sd);
+#else
+static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
+       struct v4l2_subdev *sd)
+{
+       dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* RTL2832_SDR_H */
index 5aeb9c0c27814bba39495d0be3183e14e8cbfd91..2cbe088f16975a3af260cc920946304afc44d05c 100644 (file)
@@ -1295,7 +1295,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
        solo_enc->vidq.mem_ops = &vb2_dma_sg_memops;
        solo_enc->vidq.drv_priv = solo_enc;
        solo_enc->vidq.gfp_flags = __GFP_DMA32;
-       solo_enc->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       solo_enc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        solo_enc->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
        solo_enc->vidq.lock = &solo_enc->lock;
        ret = vb2_queue_init(&solo_enc->vidq);
index 47e72dac9b13652c6eb6a1d063f69e7da0aa0ead..1815f765d033422186cfe7e742bc5bb5de20ee36 100644 (file)
@@ -676,7 +676,7 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
        solo_dev->vidq.ops = &solo_video_qops;
        solo_dev->vidq.mem_ops = &vb2_dma_contig_memops;
        solo_dev->vidq.drv_priv = solo_dev;
-       solo_dev->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        solo_dev->vidq.gfp_flags = __GFP_DMA32;
        solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
        solo_dev->vidq.lock = &solo_dev->lock;
index e2f597ee6261cb143e0f02ef05558734d24e2631..1ca91f7092b176cc8d27d4f1f36ddb694ff32d28 100644 (file)
@@ -851,75 +851,75 @@ static ssize_t message_store(struct kobject *kobj, struct kobj_attribute *attr,
  * Declare the attributes.
  */
 static struct kobj_attribute keymap_attribute =
-       __ATTR(keymap, ROOT_W, keymap_show, keymap_store);
+       __ATTR(keymap, S_IWUSR|S_IRUGO, keymap_show, keymap_store);
 static struct kobj_attribute silent_attribute =
-       __ATTR(silent, USER_W, NULL, silent_store);
+       __ATTR(silent, S_IWUGO, NULL, silent_store);
 static struct kobj_attribute synth_attribute =
-       __ATTR(synth, USER_RW, synth_show, synth_store);
+       __ATTR(synth, S_IWUGO|S_IRUGO, synth_show, synth_store);
 static struct kobj_attribute synth_direct_attribute =
-       __ATTR(synth_direct, USER_W, NULL, synth_direct_store);
+       __ATTR(synth_direct, S_IWUGO, NULL, synth_direct_store);
 static struct kobj_attribute version_attribute =
        __ATTR_RO(version);
 
 static struct kobj_attribute delimiters_attribute =
-       __ATTR(delimiters, USER_RW, punc_show, punc_store);
+       __ATTR(delimiters, S_IWUGO|S_IRUGO, punc_show, punc_store);
 static struct kobj_attribute ex_num_attribute =
-       __ATTR(ex_num, USER_RW, punc_show, punc_store);
+       __ATTR(ex_num, S_IWUGO|S_IRUGO, punc_show, punc_store);
 static struct kobj_attribute punc_all_attribute =
-       __ATTR(punc_all, USER_RW, punc_show, punc_store);
+       __ATTR(punc_all, S_IWUGO|S_IRUGO, punc_show, punc_store);
 static struct kobj_attribute punc_most_attribute =
-       __ATTR(punc_most, USER_RW, punc_show, punc_store);
+       __ATTR(punc_most, S_IWUGO|S_IRUGO, punc_show, punc_store);
 static struct kobj_attribute punc_some_attribute =
-       __ATTR(punc_some, USER_RW, punc_show, punc_store);
+       __ATTR(punc_some, S_IWUGO|S_IRUGO, punc_show, punc_store);
 static struct kobj_attribute repeats_attribute =
-       __ATTR(repeats, USER_RW, punc_show, punc_store);
+       __ATTR(repeats, S_IWUGO|S_IRUGO, punc_show, punc_store);
 
 static struct kobj_attribute attrib_bleep_attribute =
-       __ATTR(attrib_bleep, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(attrib_bleep, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute bell_pos_attribute =
-       __ATTR(bell_pos, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(bell_pos, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute bleep_time_attribute =
-       __ATTR(bleep_time, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(bleep_time, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute bleeps_attribute =
-       __ATTR(bleeps, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(bleeps, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute cursor_time_attribute =
-       __ATTR(cursor_time, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(cursor_time, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute key_echo_attribute =
-       __ATTR(key_echo, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(key_echo, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute no_interrupt_attribute =
-       __ATTR(no_interrupt, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(no_interrupt, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punc_level_attribute =
-       __ATTR(punc_level, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punc_level, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute reading_punc_attribute =
-       __ATTR(reading_punc, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(reading_punc, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute say_control_attribute =
-       __ATTR(say_control, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(say_control, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute say_word_ctl_attribute =
-       __ATTR(say_word_ctl, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(say_word_ctl, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute spell_delay_attribute =
-       __ATTR(spell_delay, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(spell_delay, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * These attributes are i18n related.
  */
 static struct kobj_attribute announcements_attribute =
-       __ATTR(announcements, USER_RW, message_show, message_store);
+       __ATTR(announcements, S_IWUGO|S_IRUGO, message_show, message_store);
 static struct kobj_attribute characters_attribute =
-       __ATTR(characters, USER_RW, chars_chartab_show, chars_chartab_store);
+       __ATTR(characters, S_IWUGO|S_IRUGO, chars_chartab_show, chars_chartab_store);
 static struct kobj_attribute chartab_attribute =
-       __ATTR(chartab, USER_RW, chars_chartab_show, chars_chartab_store);
+       __ATTR(chartab, S_IWUGO|S_IRUGO, chars_chartab_show, chars_chartab_store);
 static struct kobj_attribute ctl_keys_attribute =
-       __ATTR(ctl_keys, USER_RW, message_show, message_store);
+       __ATTR(ctl_keys, S_IWUGO|S_IRUGO, message_show, message_store);
 static struct kobj_attribute colors_attribute =
-       __ATTR(colors, USER_RW, message_show, message_store);
+       __ATTR(colors, S_IWUGO|S_IRUGO, message_show, message_store);
 static struct kobj_attribute formatted_attribute =
-       __ATTR(formatted, USER_RW, message_show, message_store);
+       __ATTR(formatted, S_IWUGO|S_IRUGO, message_show, message_store);
 static struct kobj_attribute function_names_attribute =
-       __ATTR(function_names, USER_RW, message_show, message_store);
+       __ATTR(function_names, S_IWUGO|S_IRUGO, message_show, message_store);
 static struct kobj_attribute key_names_attribute =
-       __ATTR(key_names, USER_RW, message_show, message_store);
+       __ATTR(key_names, S_IWUGO|S_IRUGO, message_show, message_store);
 static struct kobj_attribute states_attribute =
-       __ATTR(states, USER_RW, message_show, message_store);
+       __ATTR(states, S_IWUGO|S_IRUGO, message_show, message_store);
 
 /*
  * Create groups of attributes so that we can create and destroy them all
index 0126f714821a126808670de2655b0017461b5346..a7bcceec436a97d702cfba0a6b63e4862484eb7b 100644 (file)
@@ -12,8 +12,6 @@
 /* proc permissions */
 #define USER_R (S_IFREG|S_IRUGO)
 #define USER_W (S_IFREG|S_IWUGO)
-#define USER_RW (S_IFREG|S_IRUGO|S_IWUGO)
-#define ROOT_W (S_IFREG|S_IRUGO|S_IWUSR)
 
 #define TOGGLE_0 .u.n = {NULL, 0, 0, 1, 0, 0, NULL }
 #define TOGGLE_1 .u.n = {NULL, 1, 0, 1, 0, 0, NULL }
index 1c8a7f4a0ef52035e8954197db31024815974811..e7dfa434bd9607e2ef9dd6087e2244dd7f8a682d 100644 (file)
@@ -62,28 +62,28 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/acntpc.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 22a8b72910986d986b5d41690ac1f81c8556bf03..c7f014ed96280c6c28b58f30a529d910d3317ea1 100644 (file)
@@ -47,28 +47,28 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/acntsa.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 70cf1591676a2c2acb0f33bec628e83d719cbc30..38c8c2221e4e1c47022d14d6437cf14d3c8e054e 100644 (file)
@@ -53,30 +53,30 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/apollo.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute lang_attribute =
-       __ATTR(lang, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(lang, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 61a3ceeb0d3ae081258400749cfa68110d24e7a2..de5b4a5f43b62f9f732a5d192a446affc039db0d 100644 (file)
@@ -49,30 +49,30 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/audptr.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 4bfe3d458dc0699b33057cd3fb3a0287e0c7e81c..4939e8c7272ec64a012803769df48f9a1a093f62 100644 (file)
@@ -44,28 +44,28 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/bns.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index d306e010d3ea9799f2e60420918041d2a9339cb3..b17af980392984b16b1fda94f31fbe4aebb09492 100644 (file)
@@ -70,30 +70,30 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/decext.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index ea6b72d40b317f9eb342b66c9a3c762b8f6f96cb..cfa4bc0323580a3117a0b572b1862937e2b256f1 100644 (file)
@@ -164,30 +164,30 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/decpc.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 756d01535d3ec317e2839402c919f240633159ae..1fcae55dabba1fa46e0721480538821e40030e37 100644 (file)
@@ -70,30 +70,30 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/dectlk.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 1feb0fba1b436bbe13ee619c296f434895c7dda6..5c6c34191e8dc007494b9a6106b2fd93be8c7a13 100644 (file)
@@ -67,34 +67,34 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/dtlk.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute freq_attribute =
-       __ATTR(freq, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(freq, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 4a24b9c1e8e3f099604f4704ddd45a85e2e7fc13..e19e9994bbb557c194dc4ddd2a8508732dc7a734 100644 (file)
@@ -46,28 +46,28 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/dummy.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 2f2fe5eeff63e185f7ccf7e4db22f1308b52a65e..9c246d701a956f5b3c6a5a166199ba01b4df7e37 100644 (file)
@@ -59,24 +59,24 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/keypc.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 326f94d6b0798881780a4cc70ef600cbbd83d0aa..c9be6f52c2541a061e3d86e154a56aa6f1050148 100644 (file)
@@ -50,34 +50,34 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/ltlk.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute freq_attribute =
-       __ATTR(freq, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(freq, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 243c3d52fe5e616f75e829df544e3182cbc3ff7e..ee6089502a96301cfd2fb6442b05d9f8598ac468 100644 (file)
@@ -61,41 +61,41 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/soft.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute freq_attribute =
-       __ATTR(freq, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(freq, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute voice_attribute =
-       __ATTR(voice, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(voice, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * We should uncomment the following definition, when we agree on a
  * method of passing a language designation to the software synthesizer.
  * static struct kobj_attribute lang_attribute =
- *     __ATTR(lang, USER_RW, spk_var_show, spk_var_store);
+ *     __ATTR(lang, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
  */
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index e74f85620c68b30bb753a2dcbea5ccbf75cae1af..711cf114df8376be2d6ad6182b3c4ac1f0886151 100644 (file)
@@ -48,30 +48,30 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/spkout.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute punct_attribute =
-       __ATTR(punct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(punct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 5a29b9fcc93035fa11edad15378b16f5896aabef..3f0be04df071d1356d87a43fec71f49b29877b57 100644 (file)
@@ -44,28 +44,28 @@ static struct var_t vars[] = {
  * These attributes will appear in /sys/accessibility/speakup/txprt.
  */
 static struct kobj_attribute caps_start_attribute =
-       __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_start, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute caps_stop_attribute =
-       __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(caps_stop, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute pitch_attribute =
-       __ATTR(pitch, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(pitch, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute rate_attribute =
-       __ATTR(rate, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(rate, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute tone_attribute =
-       __ATTR(tone, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(tone, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute vol_attribute =
-       __ATTR(vol, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 
 static struct kobj_attribute delay_time_attribute =
-       __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute direct_attribute =
-       __ATTR(direct, USER_RW, spk_var_show, spk_var_store);
+       __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute full_time_attribute =
-       __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute jiffy_delta_attribute =
-       __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 static struct kobj_attribute trigger_time_attribute =
-       __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store);
+       __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
 
 /*
  * Create a group of attributes so that we can create and destroy them all
index 5f88d767671e956fa400b039f2cc21de9bc58621..2d51912a6e408a338ff0e8c6727dc8a8d21c6dd1 100644 (file)
@@ -143,7 +143,7 @@ config RCAR_THERMAL
 
 config KIRKWOOD_THERMAL
        tristate "Temperature sensor on Marvell Kirkwood SoCs"
-       depends on ARCH_KIRKWOOD
+       depends on ARCH_KIRKWOOD || MACH_KIRKWOOD
        depends on OF
        help
          Support for the Kirkwood thermal sensor driver into the Linux thermal
index 081fd7e6a9f070c683deaea799437a2e459b94f4..9ea3d9d49ffc55d4fc8c9679a5e3e88e7e5549f4 100644 (file)
@@ -590,12 +590,12 @@ static int __init pkg_temp_thermal_init(void)
        platform_thermal_package_rate_control =
                        pkg_temp_thermal_platform_thermal_rate_control;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
        for_each_online_cpu(i)
                if (get_core_online(i))
                        goto err_ret;
-       register_hotcpu_notifier(&pkg_temp_thermal_notifier);
-       put_online_cpus();
+       __register_hotcpu_notifier(&pkg_temp_thermal_notifier);
+       cpu_notifier_register_done();
 
        pkg_temp_debugfs_init(); /* Don't care if fails */
 
@@ -604,7 +604,7 @@ static int __init pkg_temp_thermal_init(void)
 err_ret:
        for_each_online_cpu(i)
                put_core_offline(i);
-       put_online_cpus();
+       cpu_notifier_register_done();
        kfree(pkg_work_scheduled);
        platform_thermal_package_notify = NULL;
        platform_thermal_package_rate_control = NULL;
@@ -617,8 +617,8 @@ static void __exit pkg_temp_thermal_exit(void)
        struct phy_dev_entry *phdev, *n;
        int i;
 
-       get_online_cpus();
-       unregister_hotcpu_notifier(&pkg_temp_thermal_notifier);
+       cpu_notifier_register_begin();
+       __unregister_hotcpu_notifier(&pkg_temp_thermal_notifier);
        mutex_lock(&phy_dev_list_mutex);
        list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
                /* Retore old MSR value for package thermal interrupt */
@@ -636,7 +636,7 @@ static void __exit pkg_temp_thermal_exit(void)
        for_each_online_cpu(i)
                cancel_delayed_work_sync(
                        &per_cpu(pkg_temp_thermal_threshold_work, i));
-       put_online_cpus();
+       cpu_notifier_register_done();
 
        kfree(pkg_work_scheduled);
 
index 2577d67bacb24aa092b4974808bec500f2b585f6..2e6d8ddc44252b44bfeba8e9a2a0072052a9414f 100644 (file)
@@ -1024,7 +1024,7 @@ config SERIAL_SGI_IOC3
 
 config SERIAL_MSM
        bool "MSM on-chip serial port support"
-       depends on ARCH_MSM
+       depends on ARCH_MSM || ARCH_QCOM
        select SERIAL_CORE
 
 config SERIAL_MSM_CONSOLE
index b0603e1f7d82002195ada10d4a0f478f1b6a194f..53eeea13ff165fe93609d5a3d34fb27efaf280e9 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/dma-mapping.h>
 #include <linux/atmel_pdc.h>
 #include <linux/atmel_serial.h>
 #include <linux/uaccess.h>
 #include <linux/platform_data/atmel.h>
 #include <linux/timer.h>
+#include <linux/gpio.h>
 
 #include <asm/io.h>
 #include <asm/ioctls.h>
 
-#ifdef CONFIG_ARM
-#include <mach/cpu.h>
-#include <asm/gpio.h>
-#endif
-
 #define PDC_BUFFER_SIZE                512
 /* Revisit: We should calculate this based on the actual port settings */
 #define PDC_RX_TIMEOUT         (3 * 10)                /* 3 bytes */
@@ -165,6 +162,7 @@ struct atmel_uart_port {
        struct circ_buf         rx_ring;
 
        struct serial_rs485     rs485;          /* rs485 settings */
+       int                     rts_gpio;       /* optional RTS GPIO */
        unsigned int            tx_done_mask;
        bool                    is_usart;       /* usart or uart */
        struct timer_list       uart_timer;     /* uart timer */
@@ -298,20 +296,16 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
        unsigned int mode;
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-#ifdef CONFIG_ARCH_AT91RM9200
-       if (cpu_is_at91rm9200()) {
-               /*
-                * AT91RM9200 Errata #39: RTS0 is not internally connected
-                * to PA21. We need to drive the pin manually.
-                */
-               if (port->mapbase == AT91RM9200_BASE_US0) {
-                       if (mctrl & TIOCM_RTS)
-                               at91_set_gpio_value(AT91_PIN_PA21, 0);
-                       else
-                               at91_set_gpio_value(AT91_PIN_PA21, 1);
-               }
+       /*
+        * AT91RM9200 Errata #39: RTS0 is not internally connected
+        * to PA21. We need to drive the pin as a GPIO.
+        */
+       if (gpio_is_valid(atmel_port->rts_gpio)) {
+               if (mctrl & TIOCM_RTS)
+                       gpio_set_value(atmel_port->rts_gpio, 0);
+               else
+                       gpio_set_value(atmel_port->rts_gpio, 1);
        }
-#endif
 
        if (mctrl & TIOCM_RTS)
                control |= ATMEL_US_RTSEN;
@@ -2365,6 +2359,25 @@ static int atmel_serial_probe(struct platform_device *pdev)
        port = &atmel_ports[ret];
        port->backup_imr = 0;
        port->uart.line = ret;
+       port->rts_gpio = -EINVAL; /* Invalid, zero could be valid */
+       if (pdata)
+               port->rts_gpio = pdata->rts_gpio;
+       else if (np)
+               port->rts_gpio = of_get_named_gpio(np, "rts-gpios", 0);
+
+       if (gpio_is_valid(port->rts_gpio)) {
+               ret = devm_gpio_request(&pdev->dev, port->rts_gpio, "RTS");
+               if (ret) {
+                       dev_err(&pdev->dev, "error requesting RTS GPIO\n");
+                       goto err;
+               }
+               /* Default to 1 as RTS is active low */
+               ret = gpio_direction_output(port->rts_gpio, 1);
+               if (ret) {
+                       dev_err(&pdev->dev, "error setting up RTS GPIO\n");
+                       goto err;
+               }
+       }
 
        ret = atmel_init_port(port, pdev);
        if (ret)
index a139894c600fc6a5f022d78e37f1d15ce0bc2934..e471580a2a3bee941ca5b4a251c618215b242105 100644 (file)
@@ -55,7 +55,6 @@
 #include <mach/hardware.h>
 #include <linux/io.h>
 #include <asm/irq.h>
-#include <asm/system.h>
 
 #include <mach/platform.h>
 #include <mach/irqs.h>
index b4b209ce80292f6ddea6f2ed298ab29786f353bd..6c793bc683d98c86f060c079579f365c2cdb1222 100644 (file)
@@ -967,7 +967,7 @@ config FB_PVR2
 
 config FB_OPENCORES
        tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
-       depends on FB
+       depends on FB && HAS_DMA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index cd961622f9c1aac941f33fb0053f192010cd6c09..e683b6ef95940dc6e5424691abff0806c61a784f 100644 (file)
@@ -1190,12 +1190,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
        if (!sinfo->config)
                goto free_info;
 
-       strcpy(info->fix.id, sinfo->pdev->name);
        info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
        info->pseudo_palette = sinfo->pseudo_palette;
        info->fbops = &atmel_lcdfb_ops;
 
        info->fix = atmel_lcdfb_fix;
+       strcpy(info->fix.id, sinfo->pdev->name);
 
        /* Enable LCDC Clocks */
        sinfo->bus_clk = clk_get(dev, "hclk");
@@ -1298,6 +1298,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
                goto unregister_irqs;
        }
 
+       ret = atmel_lcdfb_set_par(info);
+       if (ret < 0) {
+               dev_err(dev, "set par failed: %d\n", ret);
+               goto unregister_irqs;
+       }
+
        dev_set_drvdata(dev, info);
 
        /*
index 28fafbf864a50e91c7ef13135abec9bb9ca2b407..c3d0074a32db750c01d4d0ed4e72153499c86c69 100644 (file)
@@ -862,8 +862,8 @@ static int aty_var_to_crtc(const struct fb_info *info,
        h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
        v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
 
-       if ((xres > 1600) || (yres > 1200)) {
-               FAIL("MACH64 chips are designed for max 1600x1200\n"
+       if ((xres > 1920) || (yres > 1200)) {
+               FAIL("MACH64 chips are designed for max 1920x1200\n"
                     "select another resolution.");
        }
        h_sync_strt = h_disp + var->right_margin;
@@ -2653,7 +2653,8 @@ static int aty_init(struct fb_info *info)
                      FBINFO_HWACCEL_IMAGEBLIT |
                      FBINFO_HWACCEL_FILLRECT  |
                      FBINFO_HWACCEL_COPYAREA  |
-                     FBINFO_HWACCEL_YPAN;
+                     FBINFO_HWACCEL_YPAN      |
+                     FBINFO_READS_FAST;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
        if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {
index e45833ce975bd6cb60fb2d8b09db767d28987c14..182bd680141f7f35ffe5e9afcff97fae540fa11c 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/delay.h>
+#include <asm/unaligned.h>
 #include <linux/fb.h>
 #include <video/mach64.h>
 #include "atyfb.h"
@@ -419,7 +420,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
                u32 *pbitmap, dwords = (src_bytes + 3) / 4;
                for (pbitmap = (u32*)(image->data); dwords; dwords--, pbitmap++) {
                        wait_for_fifo(1, par);
-                       aty_st_le32(HOST_DATA0, le32_to_cpup(pbitmap), par);
+                       aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par);
                }
        }
 
index 95ec042ddbf8ee4f93eda9592ee55f0f6a3c6063..0fe02e22d9a436e46cbc46fc7053e5afa83e3b2d 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include "../fb_draw.h"
 
 #include <asm/io.h>
 
@@ -157,24 +158,33 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 
            for (i = 0; i < height; i++) {
                for (j = 0; j < width; j++) {
+                       u16 l = 0xaaaa;
                        b = *src++;
                        m = *msk++;
                        switch (cursor->rop) {
                        case ROP_XOR:
                            // Upper 4 bits of mask data
-                           fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++);
+                           l = cursor_bits_lookup[(b ^ m) >> 4] |
                            // Lower 4 bits of mask
-                           fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f],
-                                     dst++);
+                                   (cursor_bits_lookup[(b ^ m) & 0x0f] << 8);
                            break;
                        case ROP_COPY:
                            // Upper 4 bits of mask data
-                           fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++);
+                           l = cursor_bits_lookup[(b & m) >> 4] |
                            // Lower 4 bits of mask
-                           fb_writeb(cursor_bits_lookup[(b & m) & 0x0f],
-                                     dst++);
+                                   (cursor_bits_lookup[(b & m) & 0x0f] << 8);
                            break;
                        }
+                       /*
+                        * If cursor size is not a multiple of 8 characters
+                        * we must pad it with transparent pattern (0xaaaa).
+                        */
+                       if ((j + 1) * 8 > cursor->image.width) {
+                               l = comp(l, 0xaaaa,
+                                   (1 << ((cursor->image.width & 7) * 2)) - 1);
+                       }
+                       fb_writeb(l & 0xff, dst++);
+                       fb_writeb(l >> 8, dst++);
                }
                dst += offset;
            }
index bb5a96b1645dc4a46600ee38f387e6d4267f3618..bcb57235fcc70c8b389f9bf1134e59a6f9a2adb3 100644 (file)
      */
 
 static void
-bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
-               const unsigned long __iomem *src, int src_idx, int bits,
+bitcpy(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx,
+               const unsigned long __iomem *src, unsigned src_idx, int bits,
                unsigned n, u32 bswapmask)
 {
        unsigned long first, last;
        int const shift = dst_idx-src_idx;
-       int left, right;
+
+#if 0
+       /*
+        * If you suspect bug in this function, compare it with this simple
+        * memmove implementation.
+        */
+       fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8,
+                  (char *)src + ((src_idx & (bits - 1))) / 8, n / 8);
+       return;
+#endif
 
        first = fb_shifted_pixels_mask_long(p, dst_idx, bswapmask);
        last = ~fb_shifted_pixels_mask_long(p, (dst_idx+n) % bits, bswapmask);
@@ -98,9 +107,8 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                unsigned long d0, d1;
                int m;
 
-               right = shift & (bits - 1);
-               left = -shift & (bits - 1);
-               bswapmask &= shift;
+               int const left = shift & (bits - 1);
+               int const right = -shift & (bits - 1);
 
                if (dst_idx+n <= bits) {
                        // Single destination word
@@ -110,15 +118,15 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                        d0 = fb_rev_pixels_in_long(d0, bswapmask);
                        if (shift > 0) {
                                // Single source word
-                               d0 >>= right;
+                               d0 <<= left;
                        } else if (src_idx+n <= bits) {
                                // Single source word
-                               d0 <<= left;
+                               d0 >>= right;
                        } else {
                                // 2 source words
                                d1 = FB_READL(src + 1);
                                d1 = fb_rev_pixels_in_long(d1, bswapmask);
-                               d0 = d0<<left | d1>>right;
+                               d0 = d0 >> right | d1 << left;
                        }
                        d0 = fb_rev_pixels_in_long(d0, bswapmask);
                        FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
@@ -135,60 +143,59 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                        if (shift > 0) {
                                // Single source word
                                d1 = d0;
-                               d0 >>= right;
-                               dst++;
+                               d0 <<= left;
                                n -= bits - dst_idx;
                        } else {
                                // 2 source words
                                d1 = FB_READL(src++);
                                d1 = fb_rev_pixels_in_long(d1, bswapmask);
 
-                               d0 = d0<<left | d1>>right;
-                               dst++;
+                               d0 = d0 >> right | d1 << left;
                                n -= bits - dst_idx;
                        }
                        d0 = fb_rev_pixels_in_long(d0, bswapmask);
                        FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
                        d0 = d1;
+                       dst++;
 
                        // Main chunk
                        m = n % bits;
                        n /= bits;
                        while ((n >= 4) && !bswapmask) {
                                d1 = FB_READL(src++);
-                               FB_WRITEL(d0 << left | d1 >> right, dst++);
+                               FB_WRITEL(d0 >> right | d1 << left, dst++);
                                d0 = d1;
                                d1 = FB_READL(src++);
-                               FB_WRITEL(d0 << left | d1 >> right, dst++);
+                               FB_WRITEL(d0 >> right | d1 << left, dst++);
                                d0 = d1;
                                d1 = FB_READL(src++);
-                               FB_WRITEL(d0 << left | d1 >> right, dst++);
+                               FB_WRITEL(d0 >> right | d1 << left, dst++);
                                d0 = d1;
                                d1 = FB_READL(src++);
-                               FB_WRITEL(d0 << left | d1 >> right, dst++);
+                               FB_WRITEL(d0 >> right | d1 << left, dst++);
                                d0 = d1;
                                n -= 4;
                        }
                        while (n--) {
                                d1 = FB_READL(src++);
                                d1 = fb_rev_pixels_in_long(d1, bswapmask);
-                               d0 = d0 << left | d1 >> right;
+                               d0 = d0 >> right | d1 << left;
                                d0 = fb_rev_pixels_in_long(d0, bswapmask);
                                FB_WRITEL(d0, dst++);
                                d0 = d1;
                        }
 
                        // Trailing bits
-                       if (last) {
-                               if (m <= right) {
+                       if (m) {
+                               if (m <= bits - right) {
                                        // Single source word
-                                       d0 <<= left;
+                                       d0 >>= right;
                                } else {
                                        // 2 source words
                                        d1 = FB_READL(src);
                                        d1 = fb_rev_pixels_in_long(d1,
                                                                bswapmask);
-                                       d0 = d0<<left | d1>>right;
+                                       d0 = d0 >> right | d1 << left;
                                }
                                d0 = fb_rev_pixels_in_long(d0, bswapmask);
                                FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
@@ -202,43 +209,46 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
      */
 
 static void
-bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
-               const unsigned long __iomem *src, int src_idx, int bits,
+bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx,
+               const unsigned long __iomem *src, unsigned src_idx, int bits,
                unsigned n, u32 bswapmask)
 {
        unsigned long first, last;
        int shift;
 
-       dst += (n-1)/bits;
-       src += (n-1)/bits;
-       if ((n-1) % bits) {
-               dst_idx += (n-1) % bits;
-               dst += dst_idx >> (ffs(bits) - 1);
-               dst_idx &= bits - 1;
-               src_idx += (n-1) % bits;
-               src += src_idx >> (ffs(bits) - 1);
-               src_idx &= bits - 1;
-       }
+#if 0
+       /*
+        * If you suspect bug in this function, compare it with this simple
+        * memmove implementation.
+        */
+       fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8,
+                  (char *)src + ((src_idx & (bits - 1))) / 8, n / 8);
+       return;
+#endif
+
+       dst += (dst_idx + n - 1) / bits;
+       src += (src_idx + n - 1) / bits;
+       dst_idx = (dst_idx + n - 1) % bits;
+       src_idx = (src_idx + n - 1) % bits;
 
        shift = dst_idx-src_idx;
 
-       first = fb_shifted_pixels_mask_long(p, bits - 1 - dst_idx, bswapmask);
-       last = ~fb_shifted_pixels_mask_long(p, bits - 1 - ((dst_idx-n) % bits),
-                                           bswapmask);
+       first = ~fb_shifted_pixels_mask_long(p, (dst_idx + 1) % bits, bswapmask);
+       last = fb_shifted_pixels_mask_long(p, (bits + dst_idx + 1 - n) % bits, bswapmask);
 
        if (!shift) {
                // Same alignment for source and dest
 
                if ((unsigned long)dst_idx+1 >= n) {
                        // Single word
-                       if (last)
-                               first &= last;
-                       FB_WRITEL( comp( FB_READL(src), FB_READL(dst), first), dst);
+                       if (first)
+                               last &= first;
+                       FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
                } else {
                        // Multiple destination words
 
                        // Leading bits
-                       if (first != ~0UL) {
+                       if (first) {
                                FB_WRITEL( comp( FB_READL(src), FB_READL(dst), first), dst);
                                dst--;
                                src--;
@@ -262,7 +272,7 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                                FB_WRITEL(FB_READL(src--), dst--);
 
                        // Trailing bits
-                       if (last)
+                       if (last != -1UL)
                                FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
                }
        } else {
@@ -270,29 +280,28 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                unsigned long d0, d1;
                int m;
 
-               int const left = -shift & (bits-1);
-               int const right = shift & (bits-1);
-               bswapmask &= shift;
+               int const left = shift & (bits-1);
+               int const right = -shift & (bits-1);
 
                if ((unsigned long)dst_idx+1 >= n) {
                        // Single destination word
-                       if (last)
-                               first &= last;
+                       if (first)
+                               last &= first;
                        d0 = FB_READL(src);
                        if (shift < 0) {
                                // Single source word
-                               d0 <<= left;
+                               d0 >>= right;
                        } else if (1+(unsigned long)src_idx >= n) {
                                // Single source word
-                               d0 >>= right;
+                               d0 <<= left;
                        } else {
                                // 2 source words
                                d1 = FB_READL(src - 1);
                                d1 = fb_rev_pixels_in_long(d1, bswapmask);
-                               d0 = d0>>right | d1<<left;
+                               d0 = d0 << left | d1 >> right;
                        }
                        d0 = fb_rev_pixels_in_long(d0, bswapmask);
-                       FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
+                       FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
                } else {
                        // Multiple destination words
                        /** We must always remember the last value read, because in case
@@ -307,12 +316,12 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                        if (shift < 0) {
                                // Single source word
                                d1 = d0;
-                               d0 <<= left;
+                               d0 >>= right;
                        } else {
                                // 2 source words
                                d1 = FB_READL(src--);
                                d1 = fb_rev_pixels_in_long(d1, bswapmask);
-                               d0 = d0>>right | d1<<left;
+                               d0 = d0 << left | d1 >> right;
                        }
                        d0 = fb_rev_pixels_in_long(d0, bswapmask);
                        FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
@@ -325,39 +334,39 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
                        n /= bits;
                        while ((n >= 4) && !bswapmask) {
                                d1 = FB_READL(src--);
-                               FB_WRITEL(d0 >> right | d1 << left, dst--);
+                               FB_WRITEL(d0 << left | d1 >> right, dst--);
                                d0 = d1;
                                d1 = FB_READL(src--);
-                               FB_WRITEL(d0 >> right | d1 << left, dst--);
+                               FB_WRITEL(d0 << left | d1 >> right, dst--);
                                d0 = d1;
                                d1 = FB_READL(src--);
-                               FB_WRITEL(d0 >> right | d1 << left, dst--);
+                               FB_WRITEL(d0 << left | d1 >> right, dst--);
                                d0 = d1;
                                d1 = FB_READL(src--);
-                               FB_WRITEL(d0 >> right | d1 << left, dst--);
+                               FB_WRITEL(d0 << left | d1 >> right, dst--);
                                d0 = d1;
                                n -= 4;
                        }
                        while (n--) {
                                d1 = FB_READL(src--);
                                d1 = fb_rev_pixels_in_long(d1, bswapmask);
-                               d0 = d0 >> right | d1 << left;
+                               d0 = d0 << left | d1 >> right;
                                d0 = fb_rev_pixels_in_long(d0, bswapmask);
                                FB_WRITEL(d0, dst--);
                                d0 = d1;
                        }
 
                        // Trailing bits
-                       if (last) {
-                               if (m <= left) {
+                       if (m) {
+                               if (m <= bits - left) {
                                        // Single source word
-                                       d0 >>= right;
+                                       d0 <<= left;
                                } else {
                                        // 2 source words
                                        d1 = FB_READL(src);
                                        d1 = fb_rev_pixels_in_long(d1,
                                                                bswapmask);
-                                       d0 = d0>>right | d1<<left;
+                                       d0 = d0 << left | d1 >> right;
                                }
                                d0 = fb_rev_pixels_in_long(d0, bswapmask);
                                FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
@@ -371,9 +380,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
        u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
        u32 height = area->height, width = area->width;
        unsigned long const bits_per_line = p->fix.line_length*8u;
-       unsigned long __iomem *dst = NULL, *src = NULL;
+       unsigned long __iomem *base = NULL;
        int bits = BITS_PER_LONG, bytes = bits >> 3;
-       int dst_idx = 0, src_idx = 0, rev_copy = 0;
+       unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
        u32 bswapmask = fb_compute_bswapmask(p);
 
        if (p->state != FBINFO_STATE_RUNNING)
@@ -389,7 +398,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
 
        // split the base of the framebuffer into a long-aligned address and the
        // index of the first bit
-       dst = src = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
+       base = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
        dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
        // add offset of source and target area
        dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
@@ -402,20 +411,14 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
                while (height--) {
                        dst_idx -= bits_per_line;
                        src_idx -= bits_per_line;
-                       dst += dst_idx >> (ffs(bits) - 1);
-                       dst_idx &= (bytes - 1);
-                       src += src_idx >> (ffs(bits) - 1);
-                       src_idx &= (bytes - 1);
-                       bitcpy_rev(p, dst, dst_idx, src, src_idx, bits,
+                       bitcpy_rev(p, base + (dst_idx / bits), dst_idx % bits,
+                               base + (src_idx / bits), src_idx % bits, bits,
                                width*p->var.bits_per_pixel, bswapmask);
                }
        } else {
                while (height--) {
-                       dst += dst_idx >> (ffs(bits) - 1);
-                       dst_idx &= (bytes - 1);
-                       src += src_idx >> (ffs(bits) - 1);
-                       src_idx &= (bytes - 1);
-                       bitcpy(p, dst, dst_idx, src, src_idx, bits,
+                       bitcpy(p, base + (dst_idx / bits), dst_idx % bits,
+                               base + (src_idx / bits), src_idx % bits, bits,
                                width*p->var.bits_per_pixel, bswapmask);
                        dst_idx += bits_per_line;
                        src_idx += bits_per_line;
index 4e39291ac8b47212431d6990b180b65bb622e5dc..f447734b09b48a11edff75b19f46999709233096 100644 (file)
@@ -759,7 +759,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
                  newinfo in an undefined state. Thus, a call to
                  fb_set_par() may be needed for the newinfo.
                */
-               if (newinfo->fbops->fb_set_par) {
+               if (newinfo && newinfo->fbops->fb_set_par) {
                        ret = newinfo->fbops->fb_set_par(newinfo);
 
                        if (ret)
@@ -3028,8 +3028,31 @@ static int fbcon_fb_unbind(int idx)
                        if (con2fb_map[i] == idx)
                                set_con2fb_map(i, new_idx, 0);
                }
-       } else
+       } else {
+               struct fb_info *info = registered_fb[idx];
+
+               /* This is sort of like set_con2fb_map, except it maps
+                * the consoles to no device and then releases the
+                * oldinfo to free memory and cancel the cursor blink
+                * timer. I can imagine this just becoming part of
+                * set_con2fb_map where new_idx is -1
+                */
+               for (i = first_fb_vc; i <= last_fb_vc; i++) {
+                       if (con2fb_map[i] == idx) {
+                               con2fb_map[i] = -1;
+                               if (!search_fb_in_map(idx)) {
+                                       ret = con2fb_release_oldinfo(vc_cons[i].d,
+                                                                    info, NULL, i,
+                                                                    idx, 0);
+                                       if (ret) {
+                                               con2fb_map[i] = idx;
+                                               return ret;
+                                       }
+                               }
+                       }
+               }
                ret = fbcon_unbind();
+       }
 
        return ret;
 }
index a1d74dd119884b26a0b8ceaa91650846402f5878..0c0ba920ea481f2adfbf8204a64f8b32b6f80b03 100644 (file)
@@ -1546,7 +1546,7 @@ err_pm_runtime_disable:
        return ret;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static struct lcdc_context {
        u32 clk_enable;
        u32 ctrl;
@@ -1610,9 +1610,9 @@ static void lcd_context_restore(void)
        return;
 }
 
-static int fb_suspend(struct platform_device *dev, pm_message_t state)
+static int fb_suspend(struct device *dev)
 {
-       struct fb_info *info = platform_get_drvdata(dev);
+       struct fb_info *info = dev_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
 
        console_lock();
@@ -1622,18 +1622,18 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
        fb_set_suspend(info, 1);
        lcd_disable_raster(DA8XX_FRAME_WAIT);
        lcd_context_save();
-       pm_runtime_put_sync(&dev->dev);
+       pm_runtime_put_sync(dev);
        console_unlock();
 
        return 0;
 }
-static int fb_resume(struct platform_device *dev)
+static int fb_resume(struct device *dev)
 {
-       struct fb_info *info = platform_get_drvdata(dev);
+       struct fb_info *info = dev_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
 
        console_lock();
-       pm_runtime_get_sync(&dev->dev);
+       pm_runtime_get_sync(dev);
        lcd_context_restore();
        if (par->blank == FB_BLANK_UNBLANK) {
                lcd_enable_raster();
@@ -1647,19 +1647,17 @@ static int fb_resume(struct platform_device *dev)
 
        return 0;
 }
-#else
-#define fb_suspend NULL
-#define fb_resume NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(fb_pm_ops, fb_suspend, fb_resume);
+
 static struct platform_driver da8xx_fb_driver = {
        .probe = fb_probe,
        .remove = fb_remove,
-       .suspend = fb_suspend,
-       .resume = fb_resume,
        .driver = {
                   .name = DRIVER_NAME,
                   .owner = THIS_MODULE,
+                  .pm  = &fb_pm_ops,
                   },
 };
 module_platform_driver(da8xx_fb_driver);
index cd7c0df9f24ba33cd88783653b3021e61c45f8af..ae9618ff6735cca96a4a076b48f3594dd8acc8af 100644 (file)
@@ -73,7 +73,6 @@ static void efifb_destroy(struct fb_info *info)
                release_mem_region(info->apertures->ranges[0].base,
                                   info->apertures->ranges[0].size);
        fb_dealloc_cmap(&info->cmap);
-       framebuffer_release(info);
 }
 
 static struct fb_ops efifb_ops = {
@@ -244,6 +243,7 @@ static int efifb_probe(struct platform_device *dev)
                err = -ENOMEM;
                goto err_release_mem;
        }
+       platform_set_drvdata(dev, info);
        info->pseudo_palette = info->par;
        info->par = NULL;
 
@@ -337,12 +337,23 @@ err_release_mem:
        return err;
 }
 
+static int efifb_remove(struct platform_device *pdev)
+{
+       struct fb_info *info = platform_get_drvdata(pdev);
+
+       unregister_framebuffer(info);
+       framebuffer_release(info);
+
+       return 0;
+}
+
 static struct platform_driver efifb_driver = {
        .driver = {
                .name = "efi-framebuffer",
                .owner = THIS_MODULE,
        },
        .probe = efifb_probe,
+       .remove = efifb_remove,
 };
 
 module_platform_driver(efifb_driver);
index 75c8a8e7efc03ad42f2a2f44e60b61d273d62c18..eb6f2b059821933b3faedb0acea9f67c7ebd663f 100644 (file)
@@ -31,7 +31,7 @@ config EXYNOS_LCD_S6E8AX0
 
 config EXYNOS_DP
        bool "EXYNOS DP driver support"
-       depends on OF && ARCH_EXYNOS
+       depends on ARCH_EXYNOS
        default n
        help
          This enables support for DP device.
index ca2602413aa43a0b0dcda6a47ce4e6e57fc574e7..29e70ed3f154eaded6287982e1fa1a99d6f6e443 100644 (file)
@@ -794,19 +794,18 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
                return ret;
        }
 
-       lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
+       lcd->ld = devm_lcd_device_register(lcd->dev, "s6e8ax0", lcd->dev, lcd,
                        &s6e8ax0_lcd_ops);
        if (IS_ERR(lcd->ld)) {
                dev_err(lcd->dev, "failed to register lcd ops.\n");
                return PTR_ERR(lcd->ld);
        }
 
-       lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
-                       &s6e8ax0_backlight_ops, NULL);
+       lcd->bd = devm_backlight_device_register(lcd->dev, "s6e8ax0-bl",
+                               lcd->dev, lcd, &s6e8ax0_backlight_ops, NULL);
        if (IS_ERR(lcd->bd)) {
                dev_err(lcd->dev, "failed to register backlight ops.\n");
-               ret = PTR_ERR(lcd->bd);
-               goto err_backlight_register;
+               return PTR_ERR(lcd->bd);
        }
 
        lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
@@ -834,10 +833,6 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
        dev_dbg(lcd->dev, "probed s6e8ax0 panel driver.\n");
 
        return 0;
-
-err_backlight_register:
-       lcd_device_unregister(lcd->ld);
-       return ret;
 }
 
 #ifdef CONFIG_PM
index 7309ac704e2641e410fe75f60278e273348573e3..b6d5008f361f99227ae7426366ca378493831540 100644 (file)
@@ -1596,8 +1596,7 @@ static int do_remove_conflicting_framebuffers(struct apertures_struct *a,
                        (primary && gen_aper && gen_aper->count &&
                         gen_aper->ranges[0].base == VGA_FB_PHYS)) {
 
-                       printk(KERN_INFO "fb: conflicting fb hw usage "
-                              "%s vs %s - removing generic driver\n",
+                       printk(KERN_INFO "fb: switching to %s from %s\n",
                               name, registered_fb[i]->fix.id);
                        ret = do_unregister_framebuffer(registered_fb[i]);
                        if (ret)
index 44ee678481d5680571c7d0cb4b990b128e7c052b..f6e621684953c9b6c3b9fed324694b3632684b8f 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/lcd.h>
 #include <linux/math64.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 
+#include <linux/regulator/consumer.h>
+
 #include <video/of_display_timing.h>
 #include <video/of_videomode.h>
 #include <video/videomode.h>
  */
 #define DEBUG_VAR 1
 
-#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
-       (defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
-               defined(CONFIG_FB_IMX_MODULE))
-#define PWMR_BACKLIGHT_AVAILABLE
-#endif
-
 #define DRIVER_NAME "imx-fb"
 
 #define LCDC_SSA       0x00
@@ -153,11 +150,8 @@ struct imxfb_info {
         * the framebuffer memory region to.
         */
        dma_addr_t              map_dma;
-       u_char                  *map_cpu;
        u_int                   map_size;
 
-       u_char                  *screen_cpu;
-       dma_addr_t              screen_dma;
        u_int                   palette_size;
 
        dma_addr_t              dbar1;
@@ -167,18 +161,13 @@ struct imxfb_info {
        u_int                   pwmr;
        u_int                   lscr1;
        u_int                   dmacr;
-       u_int                   cmap_inverse:1,
-                               cmap_static:1,
-                               unused:30;
+       bool                    cmap_inverse;
+       bool                    cmap_static;
 
        struct imx_fb_videomode *mode;
        int                     num_modes;
-#ifdef PWMR_BACKLIGHT_AVAILABLE
-       struct backlight_device *bl;
-#endif
 
-       void (*lcd_power)(int);
-       void (*backlight_power)(int);
+       struct regulator        *lcd_pwr;
 };
 
 static struct platform_device_id imxfb_devtype[] = {
@@ -484,83 +473,6 @@ static int imxfb_set_par(struct fb_info *info)
        return 0;
 }
 
-#ifdef PWMR_BACKLIGHT_AVAILABLE
-static int imxfb_bl_get_brightness(struct backlight_device *bl)
-{
-       struct imxfb_info *fbi = bl_get_data(bl);
-
-       return readl(fbi->regs + LCDC_PWMR) & 0xFF;
-}
-
-static int imxfb_bl_update_status(struct backlight_device *bl)
-{
-       struct imxfb_info *fbi = bl_get_data(bl);
-       int brightness = bl->props.brightness;
-
-       if (!fbi->pwmr)
-               return 0;
-
-       if (bl->props.power != FB_BLANK_UNBLANK)
-               brightness = 0;
-       if (bl->props.fb_blank != FB_BLANK_UNBLANK)
-               brightness = 0;
-
-       fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
-
-       if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
-               clk_prepare_enable(fbi->clk_ipg);
-               clk_prepare_enable(fbi->clk_ahb);
-               clk_prepare_enable(fbi->clk_per);
-       }
-       writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
-       if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
-               clk_disable_unprepare(fbi->clk_per);
-               clk_disable_unprepare(fbi->clk_ahb);
-               clk_disable_unprepare(fbi->clk_ipg);
-       }
-
-       return 0;
-}
-
-static const struct backlight_ops imxfb_lcdc_bl_ops = {
-       .update_status = imxfb_bl_update_status,
-       .get_brightness = imxfb_bl_get_brightness,
-};
-
-static void imxfb_init_backlight(struct imxfb_info *fbi)
-{
-       struct backlight_properties props;
-       struct backlight_device *bl;
-
-       if (fbi->bl)
-               return;
-
-       memset(&props, 0, sizeof(struct backlight_properties));
-       props.max_brightness = 0xff;
-       props.type = BACKLIGHT_RAW;
-       writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
-
-       bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi,
-                                      &imxfb_lcdc_bl_ops, &props);
-       if (IS_ERR(bl)) {
-               dev_err(&fbi->pdev->dev, "error %ld on backlight register\n",
-                               PTR_ERR(bl));
-               return;
-       }
-
-       fbi->bl = bl;
-       bl->props.power = FB_BLANK_UNBLANK;
-       bl->props.fb_blank = FB_BLANK_UNBLANK;
-       bl->props.brightness = imxfb_bl_get_brightness(bl);
-}
-
-static void imxfb_exit_backlight(struct imxfb_info *fbi)
-{
-       if (fbi->bl)
-               backlight_device_unregister(fbi->bl);
-}
-#endif
-
 static void imxfb_enable_controller(struct imxfb_info *fbi)
 {
 
@@ -569,7 +481,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
 
        pr_debug("Enabling LCD controller\n");
 
-       writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
+       writel(fbi->map_dma, fbi->regs + LCDC_SSA);
 
        /* panning offset 0 (0 pixel offset)        */
        writel(0x00000000, fbi->regs + LCDC_POS);
@@ -588,11 +500,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
        clk_prepare_enable(fbi->clk_ahb);
        clk_prepare_enable(fbi->clk_per);
        fbi->enabled = true;
-
-       if (fbi->backlight_power)
-               fbi->backlight_power(1);
-       if (fbi->lcd_power)
-               fbi->lcd_power(1);
 }
 
 static void imxfb_disable_controller(struct imxfb_info *fbi)
@@ -602,11 +509,6 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
 
        pr_debug("Disabling LCD controller\n");
 
-       if (fbi->backlight_power)
-               fbi->backlight_power(0);
-       if (fbi->lcd_power)
-               fbi->lcd_power(0);
-
        clk_disable_unprepare(fbi->clk_per);
        clk_disable_unprepare(fbi->clk_ipg);
        clk_disable_unprepare(fbi->clk_ahb);
@@ -709,10 +611,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
                        fbi->regs + LCDC_SIZE);
 
        writel(fbi->pcr, fbi->regs + LCDC_PCR);
-#ifndef PWMR_BACKLIGHT_AVAILABLE
        if (fbi->pwmr)
                writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
-#endif
        writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 
        /* dmacr = 0 is no valid value, as we need DMA control marks. */
@@ -722,37 +622,6 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
        return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * Power management hooks.  Note that we won't be called from IRQ context,
- * unlike the blank functions above, so we may sleep.
- */
-static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
-{
-       struct fb_info *info = platform_get_drvdata(dev);
-       struct imxfb_info *fbi = info->par;
-
-       pr_debug("%s\n", __func__);
-
-       imxfb_disable_controller(fbi);
-       return 0;
-}
-
-static int imxfb_resume(struct platform_device *dev)
-{
-       struct fb_info *info = platform_get_drvdata(dev);
-       struct imxfb_info *fbi = info->par;
-
-       pr_debug("%s\n", __func__);
-
-       imxfb_enable_controller(fbi);
-       return 0;
-}
-#else
-#define imxfb_suspend  NULL
-#define imxfb_resume   NULL
-#endif
-
 static int imxfb_init_fbinfo(struct platform_device *pdev)
 {
        struct imx_fb_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -790,14 +659,9 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
        info->flags                     = FBINFO_FLAG_DEFAULT |
                                          FBINFO_READS_FAST;
        if (pdata) {
-               info->var.grayscale             = pdata->cmap_greyscale;
-               fbi->cmap_inverse               = pdata->cmap_inverse;
-               fbi->cmap_static                = pdata->cmap_static;
                fbi->lscr1                      = pdata->lscr1;
                fbi->dmacr                      = pdata->dmacr;
                fbi->pwmr                       = pdata->pwmr;
-               fbi->lcd_power                  = pdata->lcd_power;
-               fbi->backlight_power            = pdata->backlight_power;
        } else {
                np = pdev->dev.of_node;
                info->var.grayscale = of_property_read_bool(np,
@@ -806,14 +670,12 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
                fbi->cmap_static = of_property_read_bool(np, "cmap-static");
 
                fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
+
+               of_property_read_u32(np, "fsl,lpccr", &fbi->pwmr);
+
                of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);
 
                of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
-
-               /* These two function pointers could be used by some specific
-                * platforms. */
-               fbi->lcd_power = NULL;
-               fbi->backlight_power = NULL;
        }
 
        return 0;
@@ -856,9 +718,98 @@ static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
        return 0;
 }
 
+static int imxfb_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
+{
+       struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
+
+       if (!fi || fi->par == fbi)
+               return 1;
+
+       return 0;
+}
+
+static int imxfb_lcd_get_contrast(struct lcd_device *lcddev)
+{
+       struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
+
+       return fbi->pwmr & 0xff;
+}
+
+static int imxfb_lcd_set_contrast(struct lcd_device *lcddev, int contrast)
+{
+       struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
+
+       if (fbi->pwmr && fbi->enabled) {
+               if (contrast > 255)
+                       contrast = 255;
+               else if (contrast < 0)
+                       contrast = 0;
+
+               fbi->pwmr &= ~0xff;
+               fbi->pwmr |= contrast;
+
+               writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
+       }
+
+       return 0;
+}
+
+static int imxfb_lcd_get_power(struct lcd_device *lcddev)
+{
+       struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
+
+       if (!IS_ERR(fbi->lcd_pwr))
+               return regulator_is_enabled(fbi->lcd_pwr);
+
+       return 1;
+}
+
+static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power)
+{
+       struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
+
+       if (!IS_ERR(fbi->lcd_pwr)) {
+               if (power)
+                       return regulator_enable(fbi->lcd_pwr);
+               else
+                       return regulator_disable(fbi->lcd_pwr);
+       }
+
+       return 0;
+}
+
+static struct lcd_ops imxfb_lcd_ops = {
+       .check_fb       = imxfb_lcd_check_fb,
+       .get_contrast   = imxfb_lcd_get_contrast,
+       .set_contrast   = imxfb_lcd_set_contrast,
+       .get_power      = imxfb_lcd_get_power,
+       .set_power      = imxfb_lcd_set_power,
+};
+
+static int imxfb_setup(void)
+{
+       char *opt, *options = NULL;
+
+       if (fb_get_options("imxfb", &options))
+               return -ENODEV;
+
+       if (!options || !*options)
+               return 0;
+
+       while ((opt = strsep(&options, ",")) != NULL) {
+               if (!*opt)
+                       continue;
+               else
+                       fb_mode = opt;
+       }
+
+       return 0;
+}
+
 static int imxfb_probe(struct platform_device *pdev)
 {
        struct imxfb_info *fbi;
+       struct lcd_device *lcd;
        struct fb_info *info;
        struct imx_fb_platform_data *pdata;
        struct resource *res;
@@ -869,6 +820,10 @@ static int imxfb_probe(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
 
+       ret = imxfb_setup();
+       if (ret < 0)
+               return ret;
+
        of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
        if (of_id)
                pdev->id_entry = of_id->data;
@@ -966,32 +921,18 @@ static int imxfb_probe(struct platform_device *pdev)
                goto failed_ioremap;
        }
 
-       /* Seems not being used by anyone, so no support for oftree */
-       if (!pdata || !pdata->fixed_screen_cpu) {
-               fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
-               fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
-                               fbi->map_size, &fbi->map_dma, GFP_KERNEL);
+       fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
+       info->screen_base = dma_alloc_writecombine(&pdev->dev, fbi->map_size,
+                                                  &fbi->map_dma, GFP_KERNEL);
 
-               if (!fbi->map_cpu) {
-                       dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
-                       ret = -ENOMEM;
-                       goto failed_map;
-               }
-
-               info->screen_base = fbi->map_cpu;
-               fbi->screen_cpu = fbi->map_cpu;
-               fbi->screen_dma = fbi->map_dma;
-               info->fix.smem_start = fbi->screen_dma;
-       } else {
-               /* Fixed framebuffer mapping enables location of the screen in eSRAM */
-               fbi->map_cpu = pdata->fixed_screen_cpu;
-               fbi->map_dma = pdata->fixed_screen_dma;
-               info->screen_base = fbi->map_cpu;
-               fbi->screen_cpu = fbi->map_cpu;
-               fbi->screen_dma = fbi->map_dma;
-               info->fix.smem_start = fbi->screen_dma;
+       if (!info->screen_base) {
+               dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
+               ret = -ENOMEM;
+               goto failed_map;
        }
 
+       info->fix.smem_start = fbi->map_dma;
+
        if (pdata && pdata->init) {
                ret = pdata->init(fbi->pdev);
                if (ret)
@@ -1020,23 +961,37 @@ static int imxfb_probe(struct platform_device *pdev)
                goto failed_register;
        }
 
+       fbi->lcd_pwr = devm_regulator_get(&pdev->dev, "lcd");
+       if (IS_ERR(fbi->lcd_pwr) && (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER)) {
+               ret = -EPROBE_DEFER;
+               goto failed_lcd;
+       }
+
+       lcd = devm_lcd_device_register(&pdev->dev, "imxfb-lcd", &pdev->dev, fbi,
+                                      &imxfb_lcd_ops);
+       if (IS_ERR(lcd)) {
+               ret = PTR_ERR(lcd);
+               goto failed_lcd;
+       }
+
+       lcd->props.max_contrast = 0xff;
+
        imxfb_enable_controller(fbi);
        fbi->pdev = pdev;
-#ifdef PWMR_BACKLIGHT_AVAILABLE
-       imxfb_init_backlight(fbi);
-#endif
 
        return 0;
 
+failed_lcd:
+       unregister_framebuffer(info);
+
 failed_register:
        fb_dealloc_cmap(&info->cmap);
 failed_cmap:
        if (pdata && pdata->exit)
                pdata->exit(fbi->pdev);
 failed_platform_init:
-       if (pdata && !pdata->fixed_screen_cpu)
-               dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
-                       fbi->map_dma);
+       dma_free_writecombine(&pdev->dev, fbi->map_size, info->screen_base,
+                             fbi->map_dma);
 failed_map:
        iounmap(fbi->regs);
 failed_ioremap:
@@ -1061,9 +1016,6 @@ static int imxfb_remove(struct platform_device *pdev)
 
        imxfb_disable_controller(fbi);
 
-#ifdef PWMR_BACKLIGHT_AVAILABLE
-       imxfb_exit_backlight(fbi);
-#endif
        unregister_framebuffer(info);
 
        pdata = dev_get_platdata(&pdev->dev);
@@ -1074,69 +1026,49 @@ static int imxfb_remove(struct platform_device *pdev)
        kfree(info->pseudo_palette);
        framebuffer_release(info);
 
+       dma_free_writecombine(&pdev->dev, fbi->map_size, info->screen_base,
+                             fbi->map_dma);
+
        iounmap(fbi->regs);
        release_mem_region(res->start, resource_size(res));
 
        return 0;
 }
 
-static void imxfb_shutdown(struct platform_device *dev)
+static int __maybe_unused imxfb_suspend(struct device *dev)
 {
-       struct fb_info *info = platform_get_drvdata(dev);
+       struct fb_info *info = dev_get_drvdata(dev);
        struct imxfb_info *fbi = info->par;
-       imxfb_disable_controller(fbi);
-}
-
-static struct platform_driver imxfb_driver = {
-       .suspend        = imxfb_suspend,
-       .resume         = imxfb_resume,
-       .remove         = imxfb_remove,
-       .shutdown       = imxfb_shutdown,
-       .driver         = {
-               .name   = DRIVER_NAME,
-               .of_match_table = imxfb_of_dev_id,
-       },
-       .id_table       = imxfb_devtype,
-};
-
-static int imxfb_setup(void)
-{
-#ifndef MODULE
-       char *opt, *options = NULL;
 
-       if (fb_get_options("imxfb", &options))
-               return -ENODEV;
-
-       if (!options || !*options)
-               return 0;
+       imxfb_disable_controller(fbi);
 
-       while ((opt = strsep(&options, ",")) != NULL) {
-               if (!*opt)
-                       continue;
-               else
-                       fb_mode = opt;
-       }
-#endif
        return 0;
 }
 
-static int __init imxfb_init(void)
+static int __maybe_unused imxfb_resume(struct device *dev)
 {
-       int ret = imxfb_setup();
+       struct fb_info *info = dev_get_drvdata(dev);
+       struct imxfb_info *fbi = info->par;
 
-       if (ret < 0)
-               return ret;
+       imxfb_enable_controller(fbi);
 
-       return platform_driver_probe(&imxfb_driver, imxfb_probe);
+       return 0;
 }
 
-static void __exit imxfb_cleanup(void)
-{
-       platform_driver_unregister(&imxfb_driver);
-}
+static SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume);
 
-module_init(imxfb_init);
-module_exit(imxfb_cleanup);
+static struct platform_driver imxfb_driver = {
+       .driver         = {
+               .name   = DRIVER_NAME,
+               .of_match_table = imxfb_of_dev_id,
+               .owner  = THIS_MODULE,
+               .pm     = &imxfb_pm_ops,
+       },
+       .probe          = imxfb_probe,
+       .remove         = imxfb_remove,
+       .id_table       = imxfb_devtype,
+};
+module_platform_driver(imxfb_driver);
 
 MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
index 8335a6fe303e3ac9e4dd42423e6512f10355daee..0d5cb85d071a57dca81ff161750ecd6f3aa9ac89 100644 (file)
@@ -192,10 +192,18 @@ void matrox_cfbX_init(struct matrox_fb_info *minfo)
        minfo->accel.m_dwg_rect = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
        if (isMilleniumII(minfo)) minfo->accel.m_dwg_rect |= M_DWG_TRANSC;
        minfo->accel.m_opmode = mopmode;
+       minfo->accel.m_access = maccess;
+       minfo->accel.m_pitch = mpitch;
 }
 
 EXPORT_SYMBOL(matrox_cfbX_init);
 
+static void matrox_accel_restore_maccess(struct matrox_fb_info *minfo)
+{
+       mga_outl(M_MACCESS, minfo->accel.m_access);
+       mga_outl(M_PITCH, minfo->accel.m_pitch);
+}
+
 static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
                               int sx, int dy, int dx, int height, int width)
 {
@@ -207,7 +215,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
        CRITBEGIN
 
        if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
-               mga_fifo(2);
+               mga_fifo(4);
+               matrox_accel_restore_maccess(minfo);
                mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
                         M_DWG_BFCOL | M_DWG_REPLACE);
                mga_outl(M_AR5, vxres);
@@ -215,7 +224,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
                start = sy*vxres+sx+curr_ydstorg(minfo);
                end = start+width;
        } else {
-               mga_fifo(3);
+               mga_fifo(5);
+               matrox_accel_restore_maccess(minfo);
                mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
                mga_outl(M_SGN, 5);
                mga_outl(M_AR5, -vxres);
@@ -224,7 +234,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
                start = end+width;
                dy += height-1;
        }
-       mga_fifo(4);
+       mga_fifo(6);
+       matrox_accel_restore_maccess(minfo);
        mga_outl(M_AR0, end);
        mga_outl(M_AR3, start);
        mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
@@ -246,7 +257,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
        CRITBEGIN
 
        if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
-               mga_fifo(2);
+               mga_fifo(4);
+               matrox_accel_restore_maccess(minfo);
                mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
                        M_DWG_BFCOL | M_DWG_REPLACE);
                mga_outl(M_AR5, vxres);
@@ -254,7 +266,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
                start = sy*vxres+sx+curr_ydstorg(minfo);
                end = start+width;
        } else {
-               mga_fifo(3);
+               mga_fifo(5);
+               matrox_accel_restore_maccess(minfo);
                mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
                mga_outl(M_SGN, 5);
                mga_outl(M_AR5, -vxres);
@@ -263,7 +276,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
                start = end+width;
                dy += height-1;
        }
-       mga_fifo(5);
+       mga_fifo(7);
+       matrox_accel_restore_maccess(minfo);
        mga_outl(M_AR0, end);
        mga_outl(M_AR3, start);
        mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
@@ -298,7 +312,8 @@ static void matroxfb_accel_clear(struct matrox_fb_info *minfo, u_int32_t color,
 
        CRITBEGIN
 
-       mga_fifo(5);
+       mga_fifo(7);
+       matrox_accel_restore_maccess(minfo);
        mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE);
        mga_outl(M_FCOL, color);
        mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
@@ -341,7 +356,8 @@ static void matroxfb_cfb4_clear(struct matrox_fb_info *minfo, u_int32_t bgx,
        width >>= 1;
        sx >>= 1;
        if (width) {
-               mga_fifo(5);
+               mga_fifo(7);
+               matrox_accel_restore_maccess(minfo);
                mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE2);
                mga_outl(M_FCOL, bgx);
                mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
@@ -415,7 +431,8 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
 
        CRITBEGIN
 
-       mga_fifo(3);
+       mga_fifo(5);
+       matrox_accel_restore_maccess(minfo);
        if (easy)
                mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
        else
@@ -425,7 +442,8 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
        fxbndry = ((xx + width - 1) << 16) | xx;
        mmio = minfo->mmio.vbase;
 
-       mga_fifo(6);
+       mga_fifo(8);
+       matrox_accel_restore_maccess(minfo);
        mga_writel(mmio, M_FXBNDRY, fxbndry);
        mga_writel(mmio, M_AR0, ar0);
        mga_writel(mmio, M_AR3, 0);
index 87c64ff4546cb0db9fec5bb6351b7947cdc49504..7116c5309c7da829116215998f86769eebfe8580 100644 (file)
@@ -1773,7 +1773,8 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
                                      FBINFO_HWACCEL_FILLRECT |  /* And fillrect */
                                      FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */
                                      FBINFO_HWACCEL_XPAN |      /* And we support both horizontal */
-                                     FBINFO_HWACCEL_YPAN;       /* And vertical panning */
+                                     FBINFO_HWACCEL_YPAN |      /* And vertical panning */
+                                     FBINFO_READS_FAST;
        minfo->video.len_usable &= PAGE_MASK;
        fb_alloc_cmap(&minfo->fbcon.cmap, 256, 1);
 
index 11ed57bb704e4cf644c29f1624cc3920848d5e9d..556d96ce40bf27681db498992fb0bb6f1af34f4a 100644 (file)
@@ -307,6 +307,8 @@ struct matrox_accel_data {
 #endif
        u_int32_t       m_dwg_rect;
        u_int32_t       m_opmode;
+       u_int32_t       m_access;
+       u_int32_t       m_pitch;
 };
 
 struct v4l2_queryctrl;
index ccd9073f706f6d59242a5b1866d74dcd2c9bffa6..5ee3b5505f7fb3d53aff30d0e79a146011df9609 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
@@ -31,7 +32,7 @@ struct panel_drv_data {
 static const struct omap_video_timings tvc_pal_timings = {
        .x_res          = 720,
        .y_res          = 574,
-       .pixel_clock    = 13500,
+       .pixelclock     = 13500000,
        .hsw            = 64,
        .hfp            = 12,
        .hbp            = 68,
@@ -42,6 +43,12 @@ static const struct omap_video_timings tvc_pal_timings = {
        .interlace      = true,
 };
 
+static const struct of_device_id tvc_of_match[];
+
+struct tvc_of_data {
+       enum omap_dss_venc_type connector_type;
+};
+
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
 
 static int tvc_connect(struct omap_dss_device *dssdev)
@@ -91,8 +98,12 @@ static int tvc_enable(struct omap_dss_device *dssdev)
 
        in->ops.atv->set_timings(in, &ddata->timings);
 
-       in->ops.atv->set_type(in, ddata->connector_type);
-       in->ops.atv->invert_vid_out_polarity(in, ddata->invert_polarity);
+       if (!ddata->dev->of_node) {
+               in->ops.atv->set_type(in, ddata->connector_type);
+
+               in->ops.atv->invert_vid_out_polarity(in,
+                       ddata->invert_polarity);
+       }
 
        r = in->ops.atv->enable(in);
        if (r)
@@ -205,6 +216,23 @@ static int tvc_probe_pdata(struct platform_device *pdev)
        return 0;
 }
 
+static int tvc_probe_of(struct platform_device *pdev)
+{
+       struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+       struct device_node *node = pdev->dev.of_node;
+       struct omap_dss_device *in;
+
+       in = omapdss_of_find_source_for_first_ep(node);
+       if (IS_ERR(in)) {
+               dev_err(&pdev->dev, "failed to find video source\n");
+               return PTR_ERR(in);
+       }
+
+       ddata->in = in;
+
+       return 0;
+}
+
 static int tvc_probe(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata;
@@ -222,6 +250,10 @@ static int tvc_probe(struct platform_device *pdev)
                r = tvc_probe_pdata(pdev);
                if (r)
                        return r;
+       } else if (pdev->dev.of_node) {
+               r = tvc_probe_of(pdev);
+               if (r)
+                       return r;
        } else {
                return -ENODEV;
        }
@@ -263,12 +295,19 @@ static int __exit tvc_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id tvc_of_match[] = {
+       { .compatible = "omapdss,svideo-connector", },
+       { .compatible = "omapdss,composite-video-connector", },
+       {},
+};
+
 static struct platform_driver tvc_connector_driver = {
        .probe  = tvc_probe,
        .remove = __exit_p(tvc_remove),
        .driver = {
                .name   = "connector-analog-tv",
                .owner  = THIS_MODULE,
+               .of_match_table = tvc_of_match,
        },
 };
 
index b6c50904038efcce92c9b324d846a16bfa07a4ef..74de2bc50c4feca760cb9b0928a24eb288108610 100644 (file)
@@ -23,7 +23,7 @@ static const struct omap_video_timings dvic_default_timings = {
        .x_res          = 640,
        .y_res          = 480,
 
-       .pixel_clock    = 23500,
+       .pixelclock     = 23500000,
 
        .hfp            = 48,
        .hsw            = 32,
@@ -277,6 +277,37 @@ static int dvic_probe_pdata(struct platform_device *pdev)
        return 0;
 }
 
+static int dvic_probe_of(struct platform_device *pdev)
+{
+       struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+       struct device_node *node = pdev->dev.of_node;
+       struct omap_dss_device *in;
+       struct device_node *adapter_node;
+       struct i2c_adapter *adapter;
+
+       in = omapdss_of_find_source_for_first_ep(node);
+       if (IS_ERR(in)) {
+               dev_err(&pdev->dev, "failed to find video source\n");
+               return PTR_ERR(in);
+       }
+
+       ddata->in = in;
+
+       adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0);
+       if (adapter_node) {
+               adapter = of_find_i2c_adapter_by_node(adapter_node);
+               if (adapter == NULL) {
+                       dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n");
+                       omap_dss_put_device(ddata->in);
+                       return -EPROBE_DEFER;
+               }
+
+               ddata->i2c_adapter = adapter;
+       }
+
+       return 0;
+}
+
 static int dvic_probe(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata;
@@ -293,6 +324,10 @@ static int dvic_probe(struct platform_device *pdev)
                r = dvic_probe_pdata(pdev);
                if (r)
                        return r;
+       } else if (pdev->dev.of_node) {
+               r = dvic_probe_of(pdev);
+               if (r)
+                       return r;
        } else {
                return -ENODEV;
        }
@@ -342,12 +377,20 @@ static int __exit dvic_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id dvic_of_match[] = {
+       { .compatible = "omapdss,dvi-connector", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, dvic_of_match);
+
 static struct platform_driver dvi_connector_driver = {
        .probe  = dvic_probe,
        .remove = __exit_p(dvic_remove),
        .driver = {
                .name   = "connector-dvi",
                .owner  = THIS_MODULE,
+               .of_match_table = dvic_of_match,
        },
 };
 
index 9abe2c039ae9c44f0ea2cb2a3362c021e9273df4..29ed21b9dce5934afa12025789f23ff81bd23a37 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <drm/drm_edid.h>
 
@@ -21,7 +22,7 @@
 static const struct omap_video_timings hdmic_default_timings = {
        .x_res          = 640,
        .y_res          = 480,
-       .pixel_clock    = 25175,
+       .pixelclock     = 25175000,
        .hsw            = 96,
        .hfp            = 16,
        .hbp            = 48,
@@ -301,6 +302,23 @@ static int hdmic_probe_pdata(struct platform_device *pdev)
        return 0;
 }
 
+static int hdmic_probe_of(struct platform_device *pdev)
+{
+       struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+       struct device_node *node = pdev->dev.of_node;
+       struct omap_dss_device *in;
+
+       in = omapdss_of_find_source_for_first_ep(node);
+       if (IS_ERR(in)) {
+               dev_err(&pdev->dev, "failed to find video source\n");
+               return PTR_ERR(in);
+       }
+
+       ddata->in = in;
+
+       return 0;
+}
+
 static int hdmic_probe(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata;
@@ -318,6 +336,10 @@ static int hdmic_probe(struct platform_device *pdev)
                r = hdmic_probe_pdata(pdev);
                if (r)
                        return r;
+       } else if (pdev->dev.of_node) {
+               r = hdmic_probe_of(pdev);
+               if (r)
+                       return r;
        } else {
                return -ENODEV;
        }
@@ -359,12 +381,20 @@ static int __exit hdmic_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id hdmic_of_match[] = {
+       { .compatible = "omapdss,hdmi-connector", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, hdmic_of_match);
+
 static struct platform_driver hdmi_connector_driver = {
        .probe  = hdmic_probe,
        .remove = __exit_p(hdmic_remove),
        .driver = {
                .name   = "connector-hdmi",
                .owner  = THIS_MODULE,
+               .of_match_table = hdmic_of_match,
        },
 };
 
index 4a291e756be944cfc0dcb647312d520891bca4e0..b4e9a42a79e61cc58d9dc0abd50811e0db694d48 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/of_gpio.h>
 
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
@@ -82,7 +83,8 @@ static int tfp410_enable(struct omap_dss_device *dssdev)
                return 0;
 
        in->ops.dpi->set_timings(in, &ddata->timings);
-       in->ops.dpi->set_data_lines(in, ddata->data_lines);
+       if (ddata->data_lines)
+               in->ops.dpi->set_data_lines(in, ddata->data_lines);
 
        r = in->ops.dpi->enable(in);
        if (r)
@@ -179,6 +181,33 @@ static int tfp410_probe_pdata(struct platform_device *pdev)
        return 0;
 }
 
+static int tfp410_probe_of(struct platform_device *pdev)
+{
+       struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+       struct device_node *node = pdev->dev.of_node;
+       struct omap_dss_device *in;
+       int gpio;
+
+       gpio = of_get_named_gpio(node, "powerdown-gpios", 0);
+
+       if (gpio_is_valid(gpio) || gpio == -ENOENT) {
+               ddata->pd_gpio = gpio;
+       } else {
+               dev_err(&pdev->dev, "failed to parse PD gpio\n");
+               return gpio;
+       }
+
+       in = omapdss_of_find_source_for_first_ep(node);
+       if (IS_ERR(in)) {
+               dev_err(&pdev->dev, "failed to find video source\n");
+               return PTR_ERR(in);
+       }
+
+       ddata->in = in;
+
+       return 0;
+}
+
 static int tfp410_probe(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata;
@@ -195,6 +224,10 @@ static int tfp410_probe(struct platform_device *pdev)
                r = tfp410_probe_pdata(pdev);
                if (r)
                        return r;
+       } else if (pdev->dev.of_node) {
+               r = tfp410_probe_of(pdev);
+               if (r)
+                       return r;
        } else {
                return -ENODEV;
        }
@@ -251,12 +284,20 @@ static int __exit tfp410_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id tfp410_of_match[] = {
+       { .compatible = "omapdss,ti,tfp410", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, tfp410_of_match);
+
 static struct platform_driver tfp410_driver = {
        .probe  = tfp410_probe,
        .remove = __exit_p(tfp410_remove),
        .driver = {
                .name   = "tfp410",
                .owner  = THIS_MODULE,
+               .of_match_table = tfp410_of_match,
        },
 };
 
index d5c936cb217fe78bc0f072a602f22c14b61e388f..7e33686171e3dd9a658922610133b62df74fb359 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/of_gpio.h>
 
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
@@ -289,6 +290,49 @@ static int tpd_probe_pdata(struct platform_device *pdev)
        return 0;
 }
 
+static int tpd_probe_of(struct platform_device *pdev)
+{
+       struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+       struct device_node *node = pdev->dev.of_node;
+       struct omap_dss_device *in;
+       int gpio;
+
+       /* CT CP HPD GPIO */
+       gpio = of_get_gpio(node, 0);
+       if (!gpio_is_valid(gpio)) {
+               dev_err(&pdev->dev, "failed to parse CT CP HPD gpio\n");
+               return gpio;
+       }
+       ddata->ct_cp_hpd_gpio = gpio;
+
+       /* LS OE GPIO */
+       gpio = of_get_gpio(node, 1);
+       if (gpio_is_valid(gpio) || gpio == -ENOENT) {
+               ddata->ls_oe_gpio = gpio;
+       } else {
+               dev_err(&pdev->dev, "failed to parse LS OE gpio\n");
+               return gpio;
+       }
+
+       /* HPD GPIO */
+       gpio = of_get_gpio(node, 2);
+       if (!gpio_is_valid(gpio)) {
+               dev_err(&pdev->dev, "failed to parse HPD gpio\n");
+               return gpio;
+       }
+       ddata->hpd_gpio = gpio;
+
+       in = omapdss_of_find_source_for_first_ep(node);
+       if (IS_ERR(in)) {
+               dev_err(&pdev->dev, "failed to find video source\n");
+               return PTR_ERR(in);
+       }
+
+       ddata->in = in;
+
+       return 0;
+}
+
 static int tpd_probe(struct platform_device *pdev)
 {
        struct omap_dss_device *in, *dssdev;
@@ -307,6 +351,10 @@ static int tpd_probe(struct platform_device *pdev)
                r = tpd_probe_pdata(pdev);
                if (r)
                        return r;
+       } else if (pdev->dev.of_node) {
+               r = tpd_probe_of(pdev);
+               if (r)
+                       return r;
        } else {
                return -ENODEV;
        }
@@ -379,12 +427,20 @@ static int __exit tpd_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id tpd_of_match[] = {
+       { .compatible = "omapdss,ti,tpd12s015", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, tpd_of_match);
+
 static struct platform_driver tpd_driver = {
        .probe  = tpd_probe,
        .remove = __exit_p(tpd_remove),
        .driver = {
                .name   = "tpd12s015",
                .owner  = THIS_MODULE,
+               .of_match_table = tpd_of_match,
        },
 };
 
index b7baafe83aa3ddc3556281e08b356adbf9c84198..d6f14e8717e89e87d978131f3b05d8696536a02a 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
@@ -595,10 +597,13 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
                .lp_clk_max = 10000000,
        };
 
-       r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
-       if (r) {
-               dev_err(&ddata->pdev->dev, "failed to configure DSI pins\n");
-               goto err0;
+       if (ddata->pin_config.num_pins > 0) {
+               r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
+               if (r) {
+                       dev_err(&ddata->pdev->dev,
+                               "failed to configure DSI pins\n");
+                       goto err0;
+               }
        }
 
        r = in->ops.dsi->set_config(in, &dsi_config);
@@ -1156,6 +1161,41 @@ static int dsicm_probe_pdata(struct platform_device *pdev)
        return 0;
 }
 
+static int dsicm_probe_of(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct panel_drv_data *ddata = platform_get_drvdata(pdev);
+       struct omap_dss_device *in;
+       int gpio;
+
+       gpio = of_get_named_gpio(node, "reset-gpios", 0);
+       if (!gpio_is_valid(gpio)) {
+               dev_err(&pdev->dev, "failed to parse reset gpio\n");
+               return gpio;
+       }
+       ddata->reset_gpio = gpio;
+
+       gpio = of_get_named_gpio(node, "te-gpios", 0);
+       if (gpio_is_valid(gpio) || gpio == -ENOENT) {
+               ddata->ext_te_gpio = gpio;
+       } else {
+               dev_err(&pdev->dev, "failed to parse TE gpio\n");
+               return gpio;
+       }
+
+       in = omapdss_of_find_source_for_first_ep(node);
+       if (IS_ERR(in)) {
+               dev_err(&pdev->dev, "failed to find video source\n");
+               return PTR_ERR(in);
+       }
+
+       ddata->in = in;
+
+       /* TODO: ulps, backlight */
+
+       return 0;
+}
+
 static int dsicm_probe(struct platform_device *pdev)
 {
        struct backlight_properties props;
@@ -1178,13 +1218,17 @@ static int dsicm_probe(struct platform_device *pdev)
                r = dsicm_probe_pdata(pdev);
                if (r)
                        return r;
+       } else if (pdev->dev.of_node) {
+               r = dsicm_probe_of(pdev);
+               if (r)
+                       return r;
        } else {
                return -ENODEV;
        }
 
        ddata->timings.x_res = 864;
        ddata->timings.y_res = 480;
-       ddata->timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000);
+       ddata->timings.pixelclock = 864 * 480 * 60;
 
        dssdev = &ddata->dssdev;
        dssdev->dev = dev;
@@ -1320,12 +1364,20 @@ static int __exit dsicm_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id dsicm_of_match[] = {
+       { .compatible = "omapdss,panel-dsi-cm", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, dsicm_of_match);
+
 static struct platform_driver dsicm_driver = {
        .probe = dsicm_probe,
        .remove = __exit_p(dsicm_remove),
        .driver = {
                .name = "panel-dsi-cm",
                .owner = THIS_MODULE,
+               .of_match_table = dsicm_of_match,
        },
 };
 
index 6e8977b189500b86fa9390fb814b6791e38e4cda..2e6b513222d93d339bcf502a8a2d2c44521bde0e 100644 (file)
@@ -23,7 +23,7 @@ static struct omap_video_timings lb035q02_timings = {
        .x_res = 320,
        .y_res = 240,
 
-       .pixel_clock    = 6500,
+       .pixelclock     = 6500000,
 
        .hsw            = 2,
        .hfp            = 20,
index bb217da65c5fc4cd32e35d92edf2e637dcf8366e..996fa004b48ce6e961eca92e93df70ce7b9c4d8b 100644 (file)
@@ -40,7 +40,7 @@ struct panel_drv_data {
  * NEC PIX Clock Ratings
  * MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz
  */
-#define LCD_PIXEL_CLOCK                23800
+#define LCD_PIXEL_CLOCK                23800000
 
 static const struct {
        unsigned char addr;
@@ -69,7 +69,7 @@ static const struct {
 static const struct omap_video_timings nec_8048_panel_timings = {
        .x_res          = LCD_XRES,
        .y_res          = LCD_YRES,
-       .pixel_clock    = LCD_PIXEL_CLOCK,
+       .pixelclock     = LCD_PIXEL_CLOCK,
        .hfp            = 6,
        .hsw            = 1,
        .hbp            = 4,
index 72a4fb5aa6b13c590b817ddf285f4b87c2163b19..b2f710be565d11bc093d8edfa365fcd8a4e09e97 100644 (file)
@@ -37,7 +37,7 @@ static const struct omap_video_timings sharp_ls_timings = {
        .x_res = 480,
        .y_res = 640,
 
-       .pixel_clock    = 19200,
+       .pixelclock     = 19200000,
 
        .hsw            = 2,
        .hfp            = 1,
index 8e97d06921ffdfff11a20ce6916666d8c1672351..c7ba4d8b928a53f49848a0fe75f4431792350886 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/backlight.h>
 #include <linux/fb.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
@@ -93,7 +95,7 @@ struct panel_drv_data {
 static const struct omap_video_timings acx565akm_panel_timings = {
        .x_res          = 800,
        .y_res          = 480,
-       .pixel_clock    = 24000,
+       .pixelclock     = 24000000,
        .hfp            = 28,
        .hsw            = 4,
        .hbp            = 24,
@@ -547,7 +549,9 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
        dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 
        in->ops.sdi->set_timings(in, &ddata->videomode);
-       in->ops.sdi->set_datapairs(in, ddata->datapairs);
+
+       if (ddata->datapairs > 0)
+               in->ops.sdi->set_datapairs(in, ddata->datapairs);
 
        r = in->ops.sdi->enable(in);
        if (r) {
@@ -726,6 +730,22 @@ static int acx565akm_probe_pdata(struct spi_device *spi)
        return 0;
 }
 
+static int acx565akm_probe_of(struct spi_device *spi)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+       struct device_node *np = spi->dev.of_node;
+
+       ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
+
+       ddata->in = omapdss_of_find_source_for_first_ep(np);
+       if (IS_ERR(ddata->in)) {
+               dev_err(&spi->dev, "failed to find video source\n");
+               return PTR_ERR(ddata->in);
+       }
+
+       return 0;
+}
+
 static int acx565akm_probe(struct spi_device *spi)
 {
        struct panel_drv_data *ddata;
@@ -753,7 +773,12 @@ static int acx565akm_probe(struct spi_device *spi)
                r = acx565akm_probe_pdata(spi);
                if (r)
                        return r;
+       } else if (spi->dev.of_node) {
+               r = acx565akm_probe_of(spi);
+               if (r)
+                       return r;
        } else {
+               dev_err(&spi->dev, "platform data missing!\n");
                return -ENODEV;
        }
 
@@ -864,10 +889,16 @@ static int acx565akm_remove(struct spi_device *spi)
        return 0;
 }
 
+static const struct of_device_id acx565akm_of_match[] = {
+       { .compatible = "omapdss,sony,acx565akm", },
+       {},
+};
+
 static struct spi_driver acx565akm_driver = {
        .driver = {
                .name   = "acx565akm",
                .owner  = THIS_MODULE,
+               .of_match_table = acx565akm_of_match,
        },
        .probe  = acx565akm_probe,
        .remove = acx565akm_remove,
index 9a08908fe998f68fee9a964bc2b52f6c510a3f90..fae6adc005a7d9395fe57c77a737422339714243 100644 (file)
@@ -45,7 +45,7 @@ struct panel_drv_data {
 static struct omap_video_timings td028ttec1_panel_timings = {
        .x_res          = 480,
        .y_res          = 640,
-       .pixel_clock    = 22153,
+       .pixelclock     = 22153000,
        .hfp            = 24,
        .hsw            = 8,
        .hbp            = 8,
index eadc6529fa3daac6fc429b1544a1256bea0b1f49..875b40263b33006bf68ebb05e6b175e5dea29f7a 100644 (file)
@@ -76,7 +76,7 @@ static const struct omap_video_timings tpo_td043_timings = {
        .x_res          = 800,
        .y_res          = 480,
 
-       .pixel_clock    = 36000,
+       .pixelclock     = 36000000,
 
        .hsw            = 1,
        .hfp            = 68,
index d3aa91bdd6a8a35b95a840f818d95a5717f9e25d..8aec8bda27ccfe2c11546c1f0405c51fe111e7b9 100644 (file)
@@ -1,7 +1,7 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 # Core DSS files
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-       output.o
+       output.o dss-of.o
 # DSS compat layer files
 omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
        dispc-compat.o display-sysfs.o
index 77d6221618f4eba677190c9a5c7acf7546b3f55d..2bbdb7ff7daf3111104fef6c87f518e0c8187d38 100644 (file)
@@ -100,8 +100,6 @@ static struct {
        struct platform_device *pdev;
        void __iomem    *base;
 
-       int             ctx_loss_cnt;
-
        int irq;
 
        unsigned long core_clk_rate;
@@ -357,29 +355,20 @@ static void dispc_save_context(void)
        if (dss_has_feature(FEAT_CORE_CLK_DIV))
                SR(DIVISOR);
 
-       dispc.ctx_loss_cnt = dss_get_ctx_loss_count();
        dispc.ctx_valid = true;
 
-       DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
+       DSSDBG("context saved\n");
 }
 
 static void dispc_restore_context(void)
 {
-       int i, j, ctx;
+       int i, j;
 
        DSSDBG("dispc_restore_context\n");
 
        if (!dispc.ctx_valid)
                return;
 
-       ctx = dss_get_ctx_loss_count();
-
-       if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
-               return;
-
-       DSSDBG("ctx_loss_count: saved %d, current %d\n",
-                       dispc.ctx_loss_cnt, ctx);
-
        /*RR(IRQENABLE);*/
        /*RR(CONTROL);*/
        RR(CONFIG);
@@ -2884,7 +2873,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
 
        timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
 
-       timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixel_clock * 1000);
+       timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);
 
        if (dss_mgr_is_lcd(channel)) {
                timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
@@ -2979,10 +2968,10 @@ void dispc_mgr_set_timings(enum omap_channel channel,
                xtot = t.x_res + t.hfp + t.hsw + t.hbp;
                ytot = t.y_res + t.vfp + t.vsw + t.vbp;
 
-               ht = (timings->pixel_clock * 1000) / xtot;
-               vt = (timings->pixel_clock * 1000) / xtot / ytot;
+               ht = timings->pixelclock / xtot;
+               vt = timings->pixelclock / xtot / ytot;
 
-               DSSDBG("pck %u\n", timings->pixel_clock);
+               DSSDBG("pck %u\n", timings->pixelclock);
                DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
                        t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp);
                DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n",
@@ -3768,6 +3757,15 @@ static int dispc_runtime_suspend(struct device *dev)
 
 static int dispc_runtime_resume(struct device *dev)
 {
+       /*
+        * The reset value for load mode is 0 (OMAP_DSS_LOAD_CLUT_AND_FRAME)
+        * but we always initialize it to 2 (OMAP_DSS_LOAD_FRAME_ONLY) in
+        * _omap_dispc_initial_config(). We can thus use it to detect if
+        * we have lost register context.
+        */
+       if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
+               return 0;
+
        _omap_dispc_initial_config();
 
        dispc_restore_context();
@@ -3780,12 +3778,20 @@ static const struct dev_pm_ops dispc_pm_ops = {
        .runtime_resume = dispc_runtime_resume,
 };
 
+static const struct of_device_id dispc_of_match[] = {
+       { .compatible = "ti,omap2-dispc", },
+       { .compatible = "ti,omap3-dispc", },
+       { .compatible = "ti,omap4-dispc", },
+       {},
+};
+
 static struct platform_driver omap_dispchw_driver = {
        .remove         = __exit_p(omap_dispchw_remove),
        .driver         = {
                .name   = "omapdss_dispc",
                .owner  = THIS_MODULE,
                .pm     = &dispc_pm_ops,
+               .of_match_table = dispc_of_match,
        },
 };
 
index f7b5f956104163a942e0a4d88b1f9f42505bd778..5a2095a98ed868016f0f5283c431b012bf2eac08 100644 (file)
@@ -132,7 +132,7 @@ static ssize_t display_timings_show(struct device *dev,
        dssdev->driver->get_timings(dssdev, &t);
 
        return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
-                       t.pixel_clock,
+                       t.pixelclock,
                        t.x_res, t.hfp, t.hbp, t.hsw,
                        t.y_res, t.vfp, t.vbp, t.vsw);
 }
@@ -158,7 +158,7 @@ static ssize_t display_timings_store(struct device *dev,
        }
 #endif
        if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
-                               &t.pixel_clock,
+                               &t.pixelclock,
                                &t.x_res, &t.hfp, &t.hbp, &t.hsw,
                                &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
                return -EINVAL;
index 669a81fdf58ef3775c677030408ab264c26ef176..2412a0dd0c1312baa732296e895d5d9f1a63eea6 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/jiffies.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 #include "dss.h"
@@ -133,9 +134,32 @@ static int disp_num_counter;
 int omapdss_register_display(struct omap_dss_device *dssdev)
 {
        struct omap_dss_driver *drv = dssdev->driver;
+       int id;
 
-       snprintf(dssdev->alias, sizeof(dssdev->alias),
-                       "display%d", disp_num_counter++);
+       /*
+        * Note: this presumes all the displays are either using DT or non-DT,
+        * which normally should be the case. This also presumes that all
+        * displays either have an DT alias, or none has.
+        */
+
+       if (dssdev->dev->of_node) {
+               id = of_alias_get_id(dssdev->dev->of_node, "display");
+
+               if (id < 0)
+                       id = disp_num_counter++;
+       } else {
+               id = disp_num_counter++;
+       }
+
+       snprintf(dssdev->alias, sizeof(dssdev->alias), "display%d", id);
+
+       /* Use 'label' property for name, if it exists */
+       if (dssdev->dev->of_node)
+               of_property_read_string(dssdev->dev->of_node, "label",
+                       &dssdev->name);
+
+       if (dssdev->name == NULL)
+               dssdev->name = dssdev->alias;
 
        if (drv && drv->get_resolution == NULL)
                drv->get_resolution = omapdss_default_get_resolution;
@@ -248,7 +272,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
 {
        memset(ovt, 0, sizeof(*ovt));
 
-       ovt->pixel_clock = vm->pixelclock / 1000;
+       ovt->pixelclock = vm->pixelclock;
        ovt->x_res = vm->hactive;
        ovt->hbp = vm->hback_porch;
        ovt->hfp = vm->hfront_porch;
@@ -280,7 +304,7 @@ void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
 {
        memset(vm, 0, sizeof(*vm));
 
-       vm->pixelclock = ovt->pixel_clock * 1000;
+       vm->pixelclock = ovt->pixelclock;
 
        vm->hactive = ovt->x_res;
        vm->hback_porch = ovt->hbp;
index 23ef21ffc2c4998eee877e956f95c4b6d3166082..157921db447a4ef3f3d0032feb56e83922867c94 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/string.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 
@@ -49,6 +50,8 @@ static struct {
        int data_lines;
 
        struct omap_dss_device output;
+
+       bool port_initialized;
 } dpi;
 
 static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
@@ -307,22 +310,21 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)
        int r = 0;
 
        if (dpi.dsidev)
-               r = dpi_set_dsi_clk(mgr->id, t->pixel_clock * 1000, &fck,
+               r = dpi_set_dsi_clk(mgr->id, t->pixelclock, &fck,
                                &lck_div, &pck_div);
        else
-               r = dpi_set_dispc_clk(t->pixel_clock * 1000, &fck,
+               r = dpi_set_dispc_clk(t->pixelclock, &fck,
                                &lck_div, &pck_div);
        if (r)
                return r;
 
-       pck = fck / lck_div / pck_div / 1000;
+       pck = fck / lck_div / pck_div;
 
-       if (pck != t->pixel_clock) {
-               DSSWARN("Could not find exact pixel clock. "
-                               "Requested %d kHz, got %lu kHz\n",
-                               t->pixel_clock, pck);
+       if (pck != t->pixelclock) {
+               DSSWARN("Could not find exact pixel clock. Requested %d Hz, got %lu Hz\n",
+                       t->pixelclock, pck);
 
-               t->pixel_clock = pck;
+               t->pixelclock = pck;
        }
 
        dss_mgr_set_timings(mgr, t);
@@ -480,17 +482,17 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
        if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
                return -EINVAL;
 
-       if (timings->pixel_clock == 0)
+       if (timings->pixelclock == 0)
                return -EINVAL;
 
        if (dpi.dsidev) {
-               ok = dpi_dsi_clk_calc(timings->pixel_clock * 1000, &ctx);
+               ok = dpi_dsi_clk_calc(timings->pixelclock, &ctx);
                if (!ok)
                        return -EINVAL;
 
                fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
        } else {
-               ok = dpi_dss_clk_calc(timings->pixel_clock * 1000, &ctx);
+               ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
                if (!ok)
                        return -EINVAL;
 
@@ -500,9 +502,9 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
        lck_div = ctx.dispc_cinfo.lck_div;
        pck_div = ctx.dispc_cinfo.pck_div;
 
-       pck = fck / lck_div / pck_div / 1000;
+       pck = fck / lck_div / pck_div;
 
-       timings->pixel_clock = pck;
+       timings->pixelclock = pck;
 
        return 0;
 }
@@ -726,3 +728,47 @@ void __exit dpi_uninit_platform_driver(void)
 {
        platform_driver_unregister(&omap_dpi_driver);
 }
+
+int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
+{
+       struct device_node *ep;
+       u32 datalines;
+       int r;
+
+       ep = omapdss_of_get_next_endpoint(port, NULL);
+       if (!ep)
+               return 0;
+
+       r = of_property_read_u32(ep, "data-lines", &datalines);
+       if (r) {
+               DSSERR("failed to parse datalines\n");
+               goto err_datalines;
+       }
+
+       dpi.data_lines = datalines;
+
+       of_node_put(ep);
+
+       dpi.pdev = pdev;
+
+       mutex_init(&dpi.lock);
+
+       dpi_init_output(pdev);
+
+       dpi.port_initialized = true;
+
+       return 0;
+
+err_datalines:
+       of_node_put(ep);
+
+       return r;
+}
+
+void __exit dpi_uninit_port(void)
+{
+       if (!dpi.port_initialized)
+               return;
+
+       dpi_uninit_output(dpi.pdev);
+}
index a820c37e323ed66d90f6cee54259cc4fd53c7fd6..121d1049d0bc3d6a7cc383e0dcd9fc0e39e490bb 100644 (file)
@@ -38,6 +38,8 @@
 #include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 
 #include <video/omapdss.h>
 #include <video/mipi_display.h>
@@ -386,6 +388,13 @@ struct dsi_packet_sent_handler_data {
        struct completion *completion;
 };
 
+struct dsi_module_id_data {
+       u32 address;
+       int id;
+};
+
+static const struct of_device_id dsi_of_match[];
+
 #ifdef DSI_PERF_MEASURE
 static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
@@ -1151,15 +1160,11 @@ static int dsi_regulator_init(struct platform_device *dsidev)
        if (dsi->vdds_dsi_reg != NULL)
                return 0;
 
-       vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdds_dsi");
-
-       /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
-       if (IS_ERR(vdds_dsi))
-               vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO");
+       vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdd");
 
        if (IS_ERR(vdds_dsi)) {
                if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
-                       DSSERR("can't get VDDS_DSI regulator\n");
+                       DSSERR("can't get DSI VDD regulator\n");
                return PTR_ERR(vdds_dsi);
        }
 
@@ -4616,7 +4621,7 @@ static void print_dsi_vm(const char *str,
 
 static void print_dispc_vm(const char *str, const struct omap_video_timings *t)
 {
-       unsigned long pck = t->pixel_clock * 1000;
+       unsigned long pck = t->pixelclock;
        int hact, bl, tot;
 
        hact = t->x_res;
@@ -4656,7 +4661,7 @@ static void print_dsi_dispc_vm(const char *str,
        dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(t->hact * t->bitspp, 8) + 6, t->ndl);
        dsi_htot = t->hss + t->hsa + t->hse + t->hbp + dsi_hact + t->hfp;
 
-       vm.pixel_clock = pck / 1000;
+       vm.pixelclock = pck;
        vm.hsw = div64_u64((u64)(t->hsa + t->hse) * pck, byteclk);
        vm.hbp = div64_u64((u64)t->hbp * pck, byteclk);
        vm.hfp = div64_u64((u64)t->hfp * pck, byteclk);
@@ -4678,7 +4683,7 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
        ctx->dispc_cinfo.pck = pck;
 
        *t = *ctx->config->timings;
-       t->pixel_clock = pck / 1000;
+       t->pixelclock = pck;
        t->x_res = ctx->config->timings->x_res;
        t->y_res = ctx->config->timings->y_res;
        t->hsw = t->hfp = t->hbp = t->vsw = 1;
@@ -4732,7 +4737,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
         * especially as we go to LP between each pixel packet due to HW
         * "feature". So let's just estimate very roughly and multiply by 1.5.
         */
-       pck = cfg->timings->pixel_clock * 1000;
+       pck = cfg->timings->pixelclock;
        pck = pck * 3 / 2;
        txbyteclk = pck * bitspp / 8 / ndl;
 
@@ -4909,7 +4914,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
 
        dispc_vm = &ctx->dispc_vm;
        *dispc_vm = *req_vm;
-       dispc_vm->pixel_clock = dispc_pck / 1000;
+       dispc_vm->pixelclock = dispc_pck;
 
        if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) {
                hsa = div64_u64((u64)req_vm->hsw * dispc_pck,
@@ -5031,9 +5036,9 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
        ctx->dsi_cinfo.clkin = clkin;
 
        /* these limits should come from the panel driver */
-       ctx->req_pck_min = t->pixel_clock * 1000 - 1000;
-       ctx->req_pck_nom = t->pixel_clock * 1000;
-       ctx->req_pck_max = t->pixel_clock * 1000 + 1000;
+       ctx->req_pck_min = t->pixelclock - 1000;
+       ctx->req_pck_nom = t->pixelclock;
+       ctx->req_pck_max = t->pixelclock + 1000;
 
        byteclk_min = div64_u64((u64)ctx->req_pck_min * bitspp, ndl * 8);
        pll_min = max(cfg->hs_clk_min * 4, byteclk_min * 4 * 4);
@@ -5370,12 +5375,69 @@ static void dsi_uninit_output(struct platform_device *dsidev)
        omapdss_unregister_output(out);
 }
 
+static int dsi_probe_of(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+       struct property *prop;
+       u32 lane_arr[10];
+       int len, num_pins;
+       int r, i;
+       struct device_node *ep;
+       struct omap_dsi_pin_config pin_cfg;
+
+       ep = omapdss_of_get_first_endpoint(node);
+       if (!ep)
+               return 0;
+
+       prop = of_find_property(ep, "lanes", &len);
+       if (prop == NULL) {
+               dev_err(&pdev->dev, "failed to find lane data\n");
+               r = -EINVAL;
+               goto err;
+       }
+
+       num_pins = len / sizeof(u32);
+
+       if (num_pins < 4 || num_pins % 2 != 0 ||
+               num_pins > dsi->num_lanes_supported * 2) {
+               dev_err(&pdev->dev, "bad number of lanes\n");
+               r = -EINVAL;
+               goto err;
+       }
+
+       r = of_property_read_u32_array(ep, "lanes", lane_arr, num_pins);
+       if (r) {
+               dev_err(&pdev->dev, "failed to read lane data\n");
+               goto err;
+       }
+
+       pin_cfg.num_pins = num_pins;
+       for (i = 0; i < num_pins; ++i)
+               pin_cfg.pins[i] = (int)lane_arr[i];
+
+       r = dsi_configure_pins(&dsi->output, &pin_cfg);
+       if (r) {
+               dev_err(&pdev->dev, "failed to configure pins");
+               goto err;
+       }
+
+       of_node_put(ep);
+
+       return 0;
+
+err:
+       of_node_put(ep);
+       return r;
+}
+
 /* DSI1 HW IP initialisation */
 static int omap_dsihw_probe(struct platform_device *dsidev)
 {
        u32 rev;
        int r, i;
        struct dsi_data *dsi;
+       struct resource *dsi_mem;
        struct resource *res;
        struct resource temp_res;
 
@@ -5383,7 +5445,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
        if (!dsi)
                return -ENOMEM;
 
-       dsi->module_id = dsidev->id;
        dsi->pdev = dsidev;
        dev_set_drvdata(&dsidev->dev, dsi);
 
@@ -5421,6 +5482,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
                res = &temp_res;
        }
 
+       dsi_mem = res;
+
        dsi->proto_base = devm_ioremap(&dsidev->dev, res->start,
                resource_size(res));
        if (!dsi->proto_base) {
@@ -5481,6 +5544,31 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
                return r;
        }
 
+       if (dsidev->dev.of_node) {
+               const struct of_device_id *match;
+               const struct dsi_module_id_data *d;
+
+               match = of_match_node(dsi_of_match, dsidev->dev.of_node);
+               if (!match) {
+                       DSSERR("unsupported DSI module\n");
+                       return -ENODEV;
+               }
+
+               d = match->data;
+
+               while (d->address != 0 && d->address != dsi_mem->start)
+                       d++;
+
+               if (d->address == 0) {
+                       DSSERR("unsupported DSI module\n");
+                       return -ENODEV;
+               }
+
+               dsi->module_id = d->id;
+       } else {
+               dsi->module_id = dsidev->id;
+       }
+
        /* DSI VCs initialization */
        for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
                dsi->vc[i].source = DSI_VC_SOURCE_L4;
@@ -5516,6 +5604,19 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 
        dsi_init_output(dsidev);
 
+       if (dsidev->dev.of_node) {
+               r = dsi_probe_of(dsidev);
+               if (r) {
+                       DSSERR("Invalid DSI DT data\n");
+                       goto err_probe_of;
+               }
+
+               r = of_platform_populate(dsidev->dev.of_node, NULL, NULL,
+                       &dsidev->dev);
+               if (r)
+                       DSSERR("Failed to populate DSI child devices: %d\n", r);
+       }
+
        dsi_runtime_put(dsidev);
 
        if (dsi->module_id == 0)
@@ -5529,17 +5630,31 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
        else if (dsi->module_id == 1)
                dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs);
 #endif
+
        return 0;
 
+err_probe_of:
+       dsi_uninit_output(dsidev);
+       dsi_runtime_put(dsidev);
+
 err_runtime_get:
        pm_runtime_disable(&dsidev->dev);
        return r;
 }
 
+static int dsi_unregister_child(struct device *dev, void *data)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       platform_device_unregister(pdev);
+       return 0;
+}
+
 static int __exit omap_dsihw_remove(struct platform_device *dsidev)
 {
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
+       device_for_each_child(&dsidev->dev, NULL, dsi_unregister_child);
+
        WARN_ON(dsi->scp_clk_refcount > 0);
 
        dsi_uninit_output(dsidev);
@@ -5577,6 +5692,23 @@ static const struct dev_pm_ops dsi_pm_ops = {
        .runtime_resume = dsi_runtime_resume,
 };
 
+static const struct dsi_module_id_data dsi_of_data_omap3[] = {
+       { .address = 0x4804fc00, .id = 0, },
+       { },
+};
+
+static const struct dsi_module_id_data dsi_of_data_omap4[] = {
+       { .address = 0x58004000, .id = 0, },
+       { .address = 0x58005000, .id = 1, },
+       { },
+};
+
+static const struct of_device_id dsi_of_match[] = {
+       { .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, },
+       { .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, },
+       {},
+};
+
 static struct platform_driver omap_dsihw_driver = {
        .probe          = omap_dsihw_probe,
        .remove         = __exit_p(omap_dsihw_remove),
@@ -5584,6 +5716,7 @@ static struct platform_driver omap_dsihw_driver = {
                .name   = "omapdss_dsi",
                .owner  = THIS_MODULE,
                .pm     = &dsi_pm_ops,
+               .of_match_table = dsi_of_match,
        },
 };
 
diff --git a/drivers/video/omap2/dss/dss-of.c b/drivers/video/omap2/dss/dss-of.c
new file mode 100644 (file)
index 0000000..a4b20aa
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2013 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/seq_file.h>
+
+#include <video/omapdss.h>
+
+struct device_node *
+omapdss_of_get_next_port(const struct device_node *parent,
+                        struct device_node *prev)
+{
+       struct device_node *port = NULL;
+
+       if (!parent)
+               return NULL;
+
+       if (!prev) {
+               struct device_node *ports;
+               /*
+                * It's the first call, we have to find a port subnode
+                * within this node or within an optional 'ports' node.
+                */
+               ports = of_get_child_by_name(parent, "ports");
+               if (ports)
+                       parent = ports;
+
+               port = of_get_child_by_name(parent, "port");
+
+               /* release the 'ports' node */
+               of_node_put(ports);
+       } else {
+               struct device_node *ports;
+
+               ports = of_get_parent(prev);
+               if (!ports)
+                       return NULL;
+
+               do {
+                       port = of_get_next_child(ports, prev);
+                       if (!port) {
+                               of_node_put(ports);
+                               return NULL;
+                       }
+                       prev = port;
+               } while (of_node_cmp(port->name, "port") != 0);
+       }
+
+       return port;
+}
+EXPORT_SYMBOL_GPL(omapdss_of_get_next_port);
+
+struct device_node *
+omapdss_of_get_next_endpoint(const struct device_node *parent,
+                            struct device_node *prev)
+{
+       struct device_node *ep = NULL;
+
+       if (!parent)
+               return NULL;
+
+       do {
+               ep = of_get_next_child(parent, prev);
+               if (!ep)
+                       return NULL;
+               prev = ep;
+       } while (of_node_cmp(ep->name, "endpoint") != 0);
+
+       return ep;
+}
+EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
+
+static struct device_node *
+omapdss_of_get_remote_device_node(const struct device_node *node)
+{
+       struct device_node *np;
+       int i;
+
+       np = of_parse_phandle(node, "remote-endpoint", 0);
+
+       if (!np)
+               return NULL;
+
+       np = of_get_next_parent(np);
+
+       for (i = 0; i < 3 && np; ++i) {
+               struct property *prop;
+
+               prop = of_find_property(np, "compatible", NULL);
+
+               if (prop)
+                       return np;
+
+               np = of_get_next_parent(np);
+       }
+
+       return NULL;
+}
+
+struct device_node *
+omapdss_of_get_first_endpoint(const struct device_node *parent)
+{
+       struct device_node *port, *ep;
+
+       port = omapdss_of_get_next_port(parent, NULL);
+
+       if (!port)
+               return NULL;
+
+       ep = omapdss_of_get_next_endpoint(port, NULL);
+
+       of_node_put(port);
+
+       return ep;
+}
+EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
+
+struct omap_dss_device *
+omapdss_of_find_source_for_first_ep(struct device_node *node)
+{
+       struct device_node *ep;
+       struct device_node *src_node;
+       struct omap_dss_device *src;
+
+       ep = omapdss_of_get_first_endpoint(node);
+       if (!ep)
+               return ERR_PTR(-EINVAL);
+
+       src_node = omapdss_of_get_remote_device_node(ep);
+
+       of_node_put(ep);
+
+       if (!src_node)
+               return ERR_PTR(-EINVAL);
+
+       src = omap_dss_find_output_by_node(src_node);
+
+       of_node_put(src_node);
+
+       if (!src)
+               return ERR_PTR(-EPROBE_DEFER);
+
+       return src;
+}
+EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
index 9a145da35ad3a20402dd10fb6202e27f61e44cac..825c019ddee7680238f65848d73dd872985c0f93 100644 (file)
@@ -23,6 +23,7 @@
 #define DSS_SUBSYS_NAME "DSS"
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/export.h>
 #include <linux/err.h>
@@ -33,6 +34,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/gfp.h>
 #include <linux/sizes.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 
@@ -154,22 +156,6 @@ static void dss_restore_context(void)
 #undef SR
 #undef RR
 
-int dss_get_ctx_loss_count(void)
-{
-       struct platform_device *core_pdev = dss_get_core_pdev();
-       struct omap_dss_board_info *board_data = core_pdev->dev.platform_data;
-       int cnt;
-
-       if (!board_data->get_context_loss_count)
-               return -ENOENT;
-
-       cnt = board_data->get_context_loss_count(&dss.pdev->dev);
-
-       WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
-
-       return cnt;
-}
-
 void dss_sdi_init(int datapairs)
 {
        u32 l;
@@ -788,6 +774,56 @@ static int __init dss_init_features(struct platform_device *pdev)
        return 0;
 }
 
+static int __init dss_init_ports(struct platform_device *pdev)
+{
+       struct device_node *parent = pdev->dev.of_node;
+       struct device_node *port;
+       int r;
+
+       if (parent == NULL)
+               return 0;
+
+       port = omapdss_of_get_next_port(parent, NULL);
+       if (!port) {
+#ifdef CONFIG_OMAP2_DSS_DPI
+               dpi_init_port(pdev, parent);
+#endif
+               return 0;
+       }
+
+       do {
+               u32 reg;
+
+               r = of_property_read_u32(port, "reg", &reg);
+               if (r)
+                       reg = 0;
+
+#ifdef CONFIG_OMAP2_DSS_DPI
+               if (reg == 0)
+                       dpi_init_port(pdev, port);
+#endif
+
+#ifdef CONFIG_OMAP2_DSS_SDI
+               if (reg == 1)
+                       sdi_init_port(pdev, port);
+#endif
+
+       } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
+
+       return 0;
+}
+
+static void dss_uninit_ports(void)
+{
+#ifdef CONFIG_OMAP2_DSS_DPI
+       dpi_uninit_port();
+#endif
+
+#ifdef CONFIG_OMAP2_DSS_SDI
+       sdi_uninit_port();
+#endif
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -846,6 +882,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
        dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
        dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 
+       dss_init_ports(pdev);
+
        rev = dss_read_reg(DSS_REVISION);
        printk(KERN_INFO "OMAP DSS rev %d.%d\n",
                        FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -865,6 +903,8 @@ err_setup_clocks:
 
 static int __exit omap_dsshw_remove(struct platform_device *pdev)
 {
+       dss_uninit_ports();
+
        pm_runtime_disable(&pdev->dev);
 
        dss_put_clocks();
@@ -902,12 +942,22 @@ static const struct dev_pm_ops dss_pm_ops = {
        .runtime_resume = dss_runtime_resume,
 };
 
+static const struct of_device_id dss_of_match[] = {
+       { .compatible = "ti,omap2-dss", },
+       { .compatible = "ti,omap3-dss", },
+       { .compatible = "ti,omap4-dss", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, dss_of_match);
+
 static struct platform_driver omap_dsshw_driver = {
        .remove         = __exit_p(omap_dsshw_remove),
        .driver         = {
                .name   = "omapdss_dss",
                .owner  = THIS_MODULE,
                .pm     = &dss_pm_ops,
+               .of_match_table = dss_of_match,
        },
 };
 
index 057f24c8a3325b1ebc0e8b97f1f9dcca32c900a6..918fec18242496ef7eff156aa6be0f9c59964f5b 100644 (file)
@@ -225,8 +225,6 @@ void dss_dump_clocks(struct seq_file *s);
 void dss_debug_dump_clocks(struct seq_file *s);
 #endif
 
-int dss_get_ctx_loss_count(void);
-
 void dss_sdi_init(int datapairs);
 int dss_sdi_enable(void);
 void dss_sdi_disable(void);
@@ -252,6 +250,9 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
 int sdi_init_platform_driver(void) __init;
 void sdi_uninit_platform_driver(void) __exit;
 
+int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init;
+void sdi_uninit_port(void) __exit;
+
 /* DSI */
 
 typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
@@ -363,6 +364,9 @@ static inline bool dsi_pll_calc(struct platform_device *dsidev,
 int dpi_init_platform_driver(void) __init;
 void dpi_uninit_platform_driver(void) __exit;
 
+int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
+void dpi_uninit_port(void) __exit;
+
 /* DISPC */
 int dispc_init_platform_driver(void) __init;
 void dispc_uninit_platform_driver(void) __exit;
index 4a74538f9ea5ea87b8a0f49149700662c103c01a..f5f7944a1fd1d6521624e8d4a5f62971bac916ed 100644 (file)
@@ -88,15 +88,11 @@ static int hdmi_init_regulator(void)
        if (hdmi.vdda_hdmi_dac_reg != NULL)
                return 0;
 
-       reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
-
-       /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
-       if (IS_ERR(reg))
-               reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
+       reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
 
        if (IS_ERR(reg)) {
                if (PTR_ERR(reg) != -EPROBE_DEFER)
-                       DSSERR("can't get VDDA_HDMI_DAC regulator\n");
+                       DSSERR("can't get VDDA regulator\n");
                return PTR_ERR(reg);
        }
 
@@ -153,7 +149,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
 
        DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 
-       phy = p->pixel_clock;
+       /* the functions below use kHz pixel clock. TODO: change to Hz */
+       phy = p->pixelclock / 1000;
 
        hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
 
@@ -238,13 +235,13 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
        if (t != NULL) {
                hdmi.cfg = *t;
 
-               dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
+               dispc_set_tv_pclk(t->timings.pixelclock);
        } else {
                hdmi.cfg.timings = *timings;
                hdmi.cfg.cm.code = 0;
                hdmi.cfg.cm.mode = HDMI_DVI;
 
-               dispc_set_tv_pclk(timings->pixel_clock * 1000);
+               dispc_set_tv_pclk(timings->pixelclock);
        }
 
        DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
@@ -509,7 +506,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
                struct omap_dss_audio *audio)
 {
        int r;
-       u32 pclk = hdmi.cfg.timings.pixel_clock;
+       u32 pclk = hdmi.cfg.timings.pixelclock;
 
        mutex_lock(&hdmi.lock);
 
@@ -679,6 +676,11 @@ static const struct dev_pm_ops hdmi_pm_ops = {
        .runtime_resume = hdmi_runtime_resume,
 };
 
+static const struct of_device_id hdmi_of_match[] = {
+       { .compatible = "ti,omap4-hdmi", },
+       {},
+};
+
 static struct platform_driver omapdss_hdmihw_driver = {
        .probe          = omapdss_hdmihw_probe,
        .remove         = __exit_p(omapdss_hdmihw_remove),
@@ -686,6 +688,7 @@ static struct platform_driver omapdss_hdmihw_driver = {
                .name   = "omapdss_hdmi",
                .owner  = THIS_MODULE,
                .pm     = &hdmi_pm_ops,
+               .of_match_table = hdmi_of_match,
        },
 };
 
index 0614922902dd7729e99d441954e7277ba2912113..b11afac8e068033a1248282899c63e76c0406326 100644 (file)
 
 static const struct hdmi_config cea_timings[] = {
        {
-               { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
+               { 640, 480, 25200000, 96, 16, 48, 2, 10, 33,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 1, HDMI_HDMI },
        },
        {
-               { 720, 480, 27027, 62, 16, 60, 6, 9, 30,
+               { 720, 480, 27027000, 62, 16, 60, 6, 9, 30,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 2, HDMI_HDMI },
        },
        {
-               { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
+               { 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 4, HDMI_HDMI },
        },
        {
-               { 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
+               { 1920, 540, 74250000, 44, 88, 148, 5, 2, 15,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        true, },
                { 5, HDMI_HDMI },
        },
        {
-               { 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
+               { 1440, 240, 27027000, 124, 38, 114, 3, 4, 15,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        true, },
                { 6, HDMI_HDMI },
        },
        {
-               { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
+               { 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 16, HDMI_HDMI },
        },
        {
-               { 720, 576, 27000, 64, 12, 68, 5, 5, 39,
+               { 720, 576, 27000000, 64, 12, 68, 5, 5, 39,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 17, HDMI_HDMI },
        },
        {
-               { 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
+               { 1280, 720, 74250000, 40, 440, 220, 5, 5, 20,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 19, HDMI_HDMI },
        },
        {
-               { 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
+               { 1920, 540, 74250000, 44, 528, 148, 5, 2, 15,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        true, },
                { 20, HDMI_HDMI },
        },
        {
-               { 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
+               { 1440, 288, 27000000, 126, 24, 138, 3, 2, 19,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        true, },
                { 21, HDMI_HDMI },
        },
        {
-               { 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
+               { 1440, 576, 54000000, 128, 24, 136, 5, 5, 39,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 29, HDMI_HDMI },
        },
        {
-               { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
+               { 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 31, HDMI_HDMI },
        },
        {
-               { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
+               { 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 32, HDMI_HDMI },
        },
        {
-               { 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
+               { 2880, 480, 108108000, 248, 64, 240, 6, 9, 30,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 35, HDMI_HDMI },
        },
        {
-               { 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
+               { 2880, 576, 108000000, 256, 48, 272, 5, 5, 39,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 37, HDMI_HDMI },
@@ -117,121 +117,121 @@ static const struct hdmi_config cea_timings[] = {
 static const struct hdmi_config vesa_timings[] = {
 /* VESA From Here */
        {
-               { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
+               { 640, 480, 25175000, 96, 16, 48, 2, 11, 31,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 4, HDMI_DVI },
        },
        {
-               { 800, 600, 40000, 128, 40, 88, 4, 1, 23,
+               { 800, 600, 40000000, 128, 40, 88, 4, 1, 23,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 9, HDMI_DVI },
        },
        {
-               { 848, 480, 33750, 112, 16, 112, 8, 6, 23,
+               { 848, 480, 33750000, 112, 16, 112, 8, 6, 23,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0xE, HDMI_DVI },
        },
        {
-               { 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
+               { 1280, 768, 79500000, 128, 64, 192, 7, 3, 20,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 0x17, HDMI_DVI },
        },
        {
-               { 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
+               { 1280, 800, 83500000, 128, 72, 200, 6, 3, 22,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 0x1C, HDMI_DVI },
        },
        {
-               { 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
+               { 1360, 768, 85500000, 112, 64, 256, 6, 3, 18,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x27, HDMI_DVI },
        },
        {
-               { 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
+               { 1280, 960, 108000000, 112, 96, 312, 3, 1, 36,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x20, HDMI_DVI },
        },
        {
-               { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
+               { 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x23, HDMI_DVI },
        },
        {
-               { 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
+               { 1024, 768, 65000000, 136, 24, 160, 6, 3, 29,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 0x10, HDMI_DVI },
        },
        {
-               { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
+               { 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 0x2A, HDMI_DVI },
        },
        {
-               { 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
+               { 1440, 900, 106500000, 152, 80, 232, 6, 3, 25,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 0x2F, HDMI_DVI },
        },
        {
-               { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
+               { 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
                        false, },
                { 0x3A, HDMI_DVI },
        },
        {
-               { 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
+               { 1366, 768, 85500000, 143, 70, 213, 3, 3, 24,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x51, HDMI_DVI },
        },
        {
-               { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
+               { 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x52, HDMI_DVI },
        },
        {
-               { 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
+               { 1280, 768, 68250000, 32, 48, 80, 7, 3, 12,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x16, HDMI_DVI },
        },
        {
-               { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
+               { 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x29, HDMI_DVI },
        },
        {
-               { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
+               { 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x39, HDMI_DVI },
        },
        {
-               { 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
+               { 1280, 800, 79500000, 32, 48, 80, 6, 3, 14,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x1B, HDMI_DVI },
        },
        {
-               { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
+               { 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
                        OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x55, HDMI_DVI },
        },
        {
-               { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
+               { 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26,
                        OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
                        false, },
                { 0x44, HDMI_DVI },
@@ -277,8 +277,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
 {
        int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
 
-       if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
-                       DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
+       if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) ==
+                       DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) &&
                (timing2->x_res == timing1->x_res) &&
                (timing2->y_res == timing1->y_res)) {
 
index cd620c6e43a05ec8b9ca81a1f6566b2697166a00..f5f4ccf50d90be5bf6905c3b7e9efccc64060c7e 100644 (file)
@@ -171,6 +171,8 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
        video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
        video_fmt->y_res = param->timings.y_res;
        video_fmt->x_res = param->timings.x_res;
+       if (param->timings.interlace)
+               video_fmt->y_res /= 2;
 
        timings->hbp = param->timings.hbp;
        timings->hfp = param->timings.hfp;
index ba806c9e7f5486ffa40c1e6ba6e38e4dcc993ed7..911dcc9173a6b1e7f0b8e8ae508d8d0ec4bd652b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/string.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 #include "dss.h"
@@ -41,6 +42,8 @@ static struct {
        int datapairs;
 
        struct omap_dss_device output;
+
+       bool port_initialized;
 } sdi;
 
 struct sdi_clk_calc_ctx {
@@ -149,20 +152,19 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
        t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
        t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 
-       r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo);
+       r = sdi_calc_clock_div(t->pixelclock, &fck, &dispc_cinfo);
        if (r)
                goto err_calc_clock_div;
 
        sdi.mgr_config.clock_info = dispc_cinfo;
 
-       pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
+       pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
 
-       if (pck != t->pixel_clock) {
-               DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
-                               "got %lu kHz\n",
-                               t->pixel_clock, pck);
+       if (pck != t->pixelclock) {
+               DSSWARN("Could not find exact pixel clock. Requested %d Hz, got %lu Hz\n",
+                       t->pixelclock, pck);
 
-               t->pixel_clock = pck;
+               t->pixelclock = pck;
        }
 
 
@@ -244,7 +246,7 @@ static int sdi_check_timings(struct omap_dss_device *dssdev,
        if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
                return -EINVAL;
 
-       if (timings->pixel_clock == 0)
+       if (timings->pixelclock == 0)
                return -EINVAL;
 
        return 0;
@@ -387,3 +389,45 @@ void __exit sdi_uninit_platform_driver(void)
 {
        platform_driver_unregister(&omap_sdi_driver);
 }
+
+int __init sdi_init_port(struct platform_device *pdev, struct device_node *port)
+{
+       struct device_node *ep;
+       u32 datapairs;
+       int r;
+
+       ep = omapdss_of_get_next_endpoint(port, NULL);
+       if (!ep)
+               return 0;
+
+       r = of_property_read_u32(ep, "datapairs", &datapairs);
+       if (r) {
+               DSSERR("failed to parse datapairs\n");
+               goto err_datapairs;
+       }
+
+       sdi.datapairs = datapairs;
+
+       of_node_put(ep);
+
+       sdi.pdev = pdev;
+
+       sdi_init_output(pdev);
+
+       sdi.port_initialized = true;
+
+       return 0;
+
+err_datapairs:
+       of_node_put(ep);
+
+       return r;
+}
+
+void __exit sdi_uninit_port(void)
+{
+       if (!sdi.port_initialized)
+               return;
+
+       sdi_uninit_output(sdi.pdev);
+}
index 2cd7f7e42105a727b5213bde9950e32fcb7ca7b7..21d81113962bb81df71783be6f21ac4b7ef9e7b1 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
 
 #include <video/omapdss.h>
 
@@ -264,7 +265,7 @@ static const struct venc_config venc_config_pal_bdghi = {
 const struct omap_video_timings omap_dss_pal_timings = {
        .x_res          = 720,
        .y_res          = 574,
-       .pixel_clock    = 13500,
+       .pixelclock     = 13500000,
        .hsw            = 64,
        .hfp            = 12,
        .hbp            = 68,
@@ -279,7 +280,7 @@ EXPORT_SYMBOL(omap_dss_pal_timings);
 const struct omap_video_timings omap_dss_ntsc_timings = {
        .x_res          = 720,
        .y_res          = 482,
-       .pixel_clock    = 13500,
+       .pixelclock     = 13500000,
        .hsw            = 64,
        .hfp            = 16,
        .hbp            = 58,
@@ -636,7 +637,10 @@ static int venc_init_regulator(void)
        if (venc.vdda_dac_reg != NULL)
                return 0;
 
-       vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
+       if (venc.pdev->dev.of_node)
+               vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda");
+       else
+               vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
 
        if (IS_ERR(vdda_dac)) {
                if (PTR_ERR(vdda_dac) != -EPROBE_DEFER)
@@ -805,6 +809,48 @@ static void __exit venc_uninit_output(struct platform_device *pdev)
        omapdss_unregister_output(out);
 }
 
+static int venc_probe_of(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *ep;
+       u32 channels;
+       int r;
+
+       ep = omapdss_of_get_first_endpoint(node);
+       if (!ep)
+               return 0;
+
+       venc.invert_polarity = of_property_read_bool(ep, "ti,invert-polarity");
+
+       r = of_property_read_u32(ep, "ti,channels", &channels);
+       if (r) {
+               dev_err(&pdev->dev,
+                       "failed to read property 'ti,channels': %d\n", r);
+               goto err;
+       }
+
+       switch (channels) {
+       case 1:
+               venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+               break;
+       case 2:
+               venc.type = OMAP_DSS_VENC_TYPE_SVIDEO;
+               break;
+       default:
+               dev_err(&pdev->dev, "bad channel propert '%d'\n", channels);
+               r = -EINVAL;
+               goto err;
+       }
+
+       of_node_put(ep);
+
+       return 0;
+err:
+       of_node_put(ep);
+
+       return 0;
+}
+
 /* VENC HW IP initialisation */
 static int omap_venchw_probe(struct platform_device *pdev)
 {
@@ -846,12 +892,21 @@ static int omap_venchw_probe(struct platform_device *pdev)
 
        venc_runtime_put();
 
+       if (pdev->dev.of_node) {
+               r = venc_probe_of(pdev);
+               if (r) {
+                       DSSERR("Invalid DT data\n");
+                       goto err_probe_of;
+               }
+       }
+
        dss_debugfs_create_file("venc", venc_dump_regs);
 
        venc_init_output(pdev);
 
        return 0;
 
+err_probe_of:
 err_runtime_get:
        pm_runtime_disable(&pdev->dev);
        return r;
@@ -895,6 +950,14 @@ static const struct dev_pm_ops venc_pm_ops = {
        .runtime_resume = venc_runtime_resume,
 };
 
+
+static const struct of_device_id venc_of_match[] = {
+       { .compatible = "ti,omap2-venc", },
+       { .compatible = "ti,omap3-venc", },
+       { .compatible = "ti,omap4-venc", },
+       {},
+};
+
 static struct platform_driver omap_venchw_driver = {
        .probe          = omap_venchw_probe,
        .remove         = __exit_p(omap_venchw_remove),
@@ -902,6 +965,7 @@ static struct platform_driver omap_venchw_driver = {
                .name   = "omapdss_venc",
                .owner  = THIS_MODULE,
                .pm     = &venc_pm_ops,
+               .of_match_table = venc_of_match,
        },
 };
 
index f7d92c57bd73db8c34161226db27d4ac80242cab..af68cd444d7e0be36a875b0ab23f94c72c1a247f 100644 (file)
@@ -89,7 +89,7 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
        const struct omap_video_timings default_timings = {
                .x_res          = 720,
                .y_res          = 574,
-               .pixel_clock    = 13500,
+               .pixelclock     = 13500000,
                .hsw            = 64,
                .hfp            = 12,
                .hbp            = 68,
index fcb9e932d00cff60b1426a132d150e0348afc37b..ec2d132c782d20b2ffa0d08e842131b56511cbda 100644 (file)
@@ -723,8 +723,8 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
                display->driver->get_timings(display, &timings);
 
                /* pixclock in ps, the rest in pixclock */
-               var->pixclock = timings.pixel_clock != 0 ?
-                       KHZ2PICOS(timings.pixel_clock) :
+               var->pixclock = timings.pixelclock != 0 ?
+                       KHZ2PICOS(timings.pixelclock / 1000) :
                        0;
                var->left_margin = timings.hbp;
                var->right_margin = timings.hfp;
@@ -2077,7 +2077,7 @@ static int omapfb_mode_to_timings(const char *mode_str,
                timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
        }
 
-       timings->pixel_clock = PICOS2KHZ(var->pixclock);
+       timings->pixelclock = PICOS2KHZ(var->pixclock) * 1000;
        timings->hbp = var->left_margin;
        timings->hfp = var->right_margin;
        timings->vbp = var->upper_margin;
@@ -2229,7 +2229,7 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,
 
        t->x_res = m->xres;
        t->y_res = m->yres;
-       t->pixel_clock = PICOS2KHZ(m->pixclock);
+       t->pixelclock = PICOS2KHZ(m->pixclock) * 1000;
        t->hsw = m->hsync_len;
        t->hfp = m->right_margin;
        t->hbp = m->left_margin;
@@ -2417,6 +2417,55 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,
        return 0;
 }
 
+static struct omap_dss_device *
+omapfb_find_default_display(struct omapfb2_device *fbdev)
+{
+       const char *def_name;
+       int i;
+
+       /*
+        * Search with the display name from the user or the board file,
+        * comparing to display names and aliases
+        */
+
+       def_name = omapdss_get_default_display_name();
+
+       if (def_name) {
+               for (i = 0; i < fbdev->num_displays; ++i) {
+                       struct omap_dss_device *dssdev;
+
+                       dssdev = fbdev->displays[i].dssdev;
+
+                       if (dssdev->name && strcmp(def_name, dssdev->name) == 0)
+                               return dssdev;
+
+                       if (strcmp(def_name, dssdev->alias) == 0)
+                               return dssdev;
+               }
+
+               /* def_name given but not found */
+               return NULL;
+       }
+
+       /* then look for DT alias display0 */
+       for (i = 0; i < fbdev->num_displays; ++i) {
+               struct omap_dss_device *dssdev;
+               int id;
+
+               dssdev = fbdev->displays[i].dssdev;
+
+               if (dssdev->dev->of_node == NULL)
+                       continue;
+
+               id = of_alias_get_id(dssdev->dev->of_node, "display");
+               if (id == 0)
+                       return dssdev;
+       }
+
+       /* return the first display we have in the list */
+       return fbdev->displays[0].dssdev;
+}
+
 static int omapfb_probe(struct platform_device *pdev)
 {
        struct omapfb2_device *fbdev = NULL;
@@ -2494,23 +2543,7 @@ static int omapfb_probe(struct platform_device *pdev)
        for (i = 0; i < fbdev->num_managers; i++)
                fbdev->managers[i] = omap_dss_get_overlay_manager(i);
 
-       def_display = NULL;
-
-       for (i = 0; i < fbdev->num_displays; ++i) {
-               struct omap_dss_device *dssdev;
-               const char *def_name;
-
-               def_name = omapdss_get_default_display_name();
-
-               dssdev = fbdev->displays[i].dssdev;
-
-               if (def_name == NULL ||
-                       (dssdev->name && strcmp(def_name, dssdev->name) == 0)) {
-                       def_display = dssdev;
-                       break;
-               }
-       }
-
+       def_display = omapfb_find_default_display(fbdev);
        if (def_display == NULL) {
                dev_err(fbdev->dev, "failed to find default display\n");
                r = -EPROBE_DEFER;
index ad382b3396cdb126aad44aa4499d585fcdfe9e44..417f9a27eb7d3ba6bdb0651c216e13a54b6e245b 100644 (file)
@@ -107,7 +107,6 @@ struct pxa3xx_gcu_priv {
        struct timeval            base_time;
 
        struct pxa3xx_gcu_batch *free;
-
        struct pxa3xx_gcu_batch *ready;
        struct pxa3xx_gcu_batch *ready_last;
        struct pxa3xx_gcu_batch *running;
@@ -368,27 +367,35 @@ pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)
 
 /* Misc device layer */
 
-static inline struct pxa3xx_gcu_priv *file_dev(struct file *file)
+static inline struct pxa3xx_gcu_priv *to_pxa3xx_gcu_priv(struct file *file)
 {
        struct miscdevice *dev = file->private_data;
        return container_of(dev, struct pxa3xx_gcu_priv, misc_dev);
 }
 
+/*
+ * provide an empty .open callback, so the core sets file->private_data
+ * for us.
+ */
+static int pxa3xx_gcu_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
 static ssize_t
-pxa3xx_gcu_misc_write(struct file *file, const char *buff,
-                     size_t count, loff_t *offp)
+pxa3xx_gcu_write(struct file *file, const char *buff,
+                size_t count, loff_t *offp)
 {
        int ret;
        unsigned long flags;
        struct pxa3xx_gcu_batch *buffer;
-       struct pxa3xx_gcu_priv *priv = file_dev(file);
+       struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
 
        int words = count / 4;
 
        /* Does not need to be atomic. There's a lock in user space,
         * but anyhow, this is just for statistics. */
        priv->shared->num_writes++;
-
        priv->shared->num_words += words;
 
        /* Last word reserved for batch buffer end command */
@@ -406,10 +413,8 @@ pxa3xx_gcu_misc_write(struct file *file, const char *buff,
         * Get buffer from free list
         */
        spin_lock_irqsave(&priv->spinlock, flags);
-
        buffer = priv->free;
        priv->free = buffer->next;
-
        spin_unlock_irqrestore(&priv->spinlock, flags);
 
 
@@ -454,10 +459,10 @@ pxa3xx_gcu_misc_write(struct file *file, const char *buff,
 
 
 static long
-pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+pxa3xx_gcu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        unsigned long flags;
-       struct pxa3xx_gcu_priv *priv = file_dev(file);
+       struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
 
        switch (cmd) {
        case PXA3XX_GCU_IOCTL_RESET:
@@ -474,10 +479,10 @@ pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 }
 
 static int
-pxa3xx_gcu_misc_mmap(struct file *file, struct vm_area_struct *vma)
+pxa3xx_gcu_mmap(struct file *file, struct vm_area_struct *vma)
 {
        unsigned int size = vma->vm_end - vma->vm_start;
-       struct pxa3xx_gcu_priv *priv = file_dev(file);
+       struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
 
        switch (vma->vm_pgoff) {
        case 0:
@@ -532,8 +537,8 @@ static inline void pxa3xx_gcu_init_debug_timer(void) {}
 #endif
 
 static int
-add_buffer(struct platform_device *dev,
-          struct pxa3xx_gcu_priv *priv)
+pxa3xx_gcu_add_buffer(struct device *dev,
+                     struct pxa3xx_gcu_priv *priv)
 {
        struct pxa3xx_gcu_batch *buffer;
 
@@ -541,7 +546,7 @@ add_buffer(struct platform_device *dev,
        if (!buffer)
                return -ENOMEM;
 
-       buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
+       buffer->ptr = dma_alloc_coherent(dev, PXA3XX_GCU_BATCH_WORDS * 4,
                                         &buffer->phys, GFP_KERNEL);
        if (!buffer->ptr) {
                kfree(buffer);
@@ -549,57 +554,49 @@ add_buffer(struct platform_device *dev,
        }
 
        buffer->next = priv->free;
-
        priv->free = buffer;
 
        return 0;
 }
 
 static void
-free_buffers(struct platform_device *dev,
-            struct pxa3xx_gcu_priv *priv)
+pxa3xx_gcu_free_buffers(struct device *dev,
+                       struct pxa3xx_gcu_priv *priv)
 {
        struct pxa3xx_gcu_batch *next, *buffer = priv->free;
 
        while (buffer) {
                next = buffer->next;
 
-               dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
+               dma_free_coherent(dev, PXA3XX_GCU_BATCH_WORDS * 4,
                                  buffer->ptr, buffer->phys);
 
                kfree(buffer);
-
                buffer = next;
        }
 
        priv->free = NULL;
 }
 
-static const struct file_operations misc_fops = {
-       .owner  = THIS_MODULE,
-       .write  = pxa3xx_gcu_misc_write,
-       .unlocked_ioctl = pxa3xx_gcu_misc_ioctl,
-       .mmap   = pxa3xx_gcu_misc_mmap
+static const struct file_operations pxa3xx_gcu_miscdev_fops = {
+       .owner =                THIS_MODULE,
+       .open =                 pxa3xx_gcu_open,
+       .write =                pxa3xx_gcu_write,
+       .unlocked_ioctl =       pxa3xx_gcu_ioctl,
+       .mmap =                 pxa3xx_gcu_mmap,
 };
 
-static int pxa3xx_gcu_probe(struct platform_device *dev)
+static int pxa3xx_gcu_probe(struct platform_device *pdev)
 {
        int i, ret, irq;
        struct resource *r;
        struct pxa3xx_gcu_priv *priv;
+       struct device *dev = &pdev->dev;
 
-       priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       for (i = 0; i < 8; i++) {
-               ret = add_buffer(dev, priv);
-               if (ret) {
-                       dev_err(&dev->dev, "failed to allocate DMA memory\n");
-                       goto err_free_priv;
-               }
-       }
-
        init_waitqueue_head(&priv->wait_idle);
        init_waitqueue_head(&priv->wait_free);
        spin_lock_init(&priv->spinlock);
@@ -611,125 +608,99 @@ static int pxa3xx_gcu_probe(struct platform_device *dev)
 
        priv->misc_dev.minor    = MISCDEV_MINOR,
        priv->misc_dev.name     = DRV_NAME,
-       priv->misc_dev.fops     = &misc_fops,
+       priv->misc_dev.fops     = &pxa3xx_gcu_miscdev_fops;
 
-       /* register misc device */
-       ret = misc_register(&priv->misc_dev);
-       if (ret < 0) {
-               dev_err(&dev->dev, "misc_register() for minor %d failed\n",
-                       MISCDEV_MINOR);
-               goto err_free_priv;
+       /* handle IO resources */
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->mmio_base = devm_request_and_ioremap(dev, r);
+       if (IS_ERR(priv->mmio_base)) {
+               dev_err(dev, "failed to map I/O memory\n");
+               return PTR_ERR(priv->mmio_base);
        }
 
-       /* handle IO resources */
-       r = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       if (r == NULL) {
-               dev_err(&dev->dev, "no I/O memory resource defined\n");
-               ret = -ENODEV;
-               goto err_misc_deregister;
+       /* enable the clock */
+       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);
        }
 
-       if (!request_mem_region(r->start, resource_size(r), dev->name)) {
-               dev_err(&dev->dev, "failed to request I/O memory\n");
-               ret = -EBUSY;
-               goto err_misc_deregister;
+       /* request the IRQ */
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "no IRQ defined\n");
+               return -ENODEV;
        }
 
-       priv->mmio_base = ioremap_nocache(r->start, resource_size(r));
-       if (!priv->mmio_base) {
-               dev_err(&dev->dev, "failed to map I/O memory\n");
-               ret = -EBUSY;
-               goto err_free_mem_region;
+       ret = devm_request_irq(dev, irq, pxa3xx_gcu_handle_irq,
+                              0, DRV_NAME, priv);
+       if (ret < 0) {
+               dev_err(dev, "request_irq failed\n");
+               return ret;
        }
 
        /* allocate dma memory */
-       priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE,
+       priv->shared = dma_alloc_coherent(dev, SHARED_SIZE,
                                          &priv->shared_phys, GFP_KERNEL);
-
        if (!priv->shared) {
-               dev_err(&dev->dev, "failed to allocate DMA memory\n");
-               ret = -ENOMEM;
-               goto err_free_io;
+               dev_err(dev, "failed to allocate DMA memory\n");
+               return -ENOMEM;
        }
 
-       /* enable the clock */
-       priv->clk = clk_get(&dev->dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               dev_err(&dev->dev, "failed to get clock\n");
-               ret = -ENODEV;
+       /* register misc device */
+       ret = misc_register(&priv->misc_dev);
+       if (ret < 0) {
+               dev_err(dev, "misc_register() for minor %d failed\n",
+                       MISCDEV_MINOR);
                goto err_free_dma;
        }
 
        ret = clk_enable(priv->clk);
        if (ret < 0) {
-               dev_err(&dev->dev, "failed to enable clock\n");
-               goto err_put_clk;
-       }
-
-       /* request the IRQ */
-       irq = platform_get_irq(dev, 0);
-       if (irq < 0) {
-               dev_err(&dev->dev, "no IRQ defined\n");
-               ret = -ENODEV;
-               goto err_put_clk;
+               dev_err(dev, "failed to enable clock\n");
+               goto err_misc_deregister;
        }
 
-       ret = request_irq(irq, pxa3xx_gcu_handle_irq,
-                         0, DRV_NAME, priv);
-       if (ret) {
-               dev_err(&dev->dev, "request_irq failed\n");
-               ret = -EBUSY;
-               goto err_put_clk;
+       for (i = 0; i < 8; i++) {
+               ret = pxa3xx_gcu_add_buffer(dev, priv);
+               if (ret) {
+                       dev_err(dev, "failed to allocate DMA memory\n");
+                       goto err_disable_clk;
+               }
        }
 
-       platform_set_drvdata(dev, priv);
+       platform_set_drvdata(pdev, priv);
        priv->resource_mem = r;
        pxa3xx_gcu_reset(priv);
        pxa3xx_gcu_init_debug_timer();
 
-       dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
+       dev_info(dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
                        (void *) r->start, (void *) priv->shared_phys,
                        SHARED_SIZE, irq);
        return 0;
 
-err_put_clk:
-       clk_disable(priv->clk);
-       clk_put(priv->clk);
-
 err_free_dma:
-       dma_free_coherent(&dev->dev, SHARED_SIZE,
+       dma_free_coherent(dev, SHARED_SIZE,
                        priv->shared, priv->shared_phys);
 
-err_free_io:
-       iounmap(priv->mmio_base);
-
-err_free_mem_region:
-       release_mem_region(r->start, resource_size(r));
-
 err_misc_deregister:
        misc_deregister(&priv->misc_dev);
 
-err_free_priv:
-       free_buffers(dev, priv);
-       kfree(priv);
+err_disable_clk:
+       clk_disable(priv->clk);
+
        return ret;
 }
 
-static int pxa3xx_gcu_remove(struct platform_device *dev)
+static int pxa3xx_gcu_remove(struct platform_device *pdev)
 {
-       struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev);
-       struct resource *r = priv->resource_mem;
+       struct pxa3xx_gcu_priv *priv = platform_get_drvdata(pdev);
+       struct device *dev = &pdev->dev;
 
        pxa3xx_gcu_wait_idle(priv);
-
        misc_deregister(&priv->misc_dev);
-       dma_free_coherent(&dev->dev, SHARED_SIZE,
-                       priv->shared, priv->shared_phys);
-       iounmap(priv->mmio_base);
-       release_mem_region(r->start, resource_size(r));
-       clk_disable(priv->clk);
-       free_buffers(dev, priv);
-       kfree(priv);
+       dma_free_coherent(dev, SHARED_SIZE, priv->shared, priv->shared_phys);
+       pxa3xx_gcu_free_buffers(dev, priv);
 
        return 0;
 }
index 4f26bc28e60b9646d60389ba3e215111583d91f4..bd40f5ecd901f47f451ca7fd9895a56de7c614eb 100644 (file)
@@ -651,6 +651,7 @@ SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispla
             switch(VDisplay) {
             case 720:
                ModeIndex = ModeIndex_1280x720[Depth];
+               break;
             case 768:
                if(VGAEngine == SIS_300_VGA) {
                   ModeIndex = ModeIndex_300_1280x768[Depth];
index 07c7df9ee77bbd54347fdf211066a2c03b227db1..65ba9921506e2b818f05fa4a308ac383f90c7ddf 100644 (file)
@@ -182,6 +182,8 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
        if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
                return -EINVAL;
+       if (var->xres * var->yres * (var->bits_per_pixel >> 3) > info->fix.smem_len)
+               return -EINVAL;
        if (var->nonstd)
                return -EINVAL;
        if (1000000000 / var->pixclock > TGA_PLL_MAX_FREQ)
@@ -190,8 +192,8 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                return -EINVAL;
 
        /* Some of the acceleration routines assume the line width is
-          a multiple of 64 bytes.  */
-       if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 64)
+          a multiple of 8 bytes.  */
+       if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 8)
                return -EINVAL;
 
        return 0;
@@ -262,6 +264,7 @@ tgafb_set_par(struct fb_info *info)
        par->yres = info->var.yres;
        par->pll_freq = pll_freq = 1000000000 / info->var.pixclock;
        par->bits_per_pixel = info->var.bits_per_pixel;
+       info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
 
        tga_type = par->tga_type;
 
@@ -1136,222 +1139,57 @@ copyarea_line_32bpp(struct fb_info *info, u32 dy, u32 sy,
        __raw_writel(TGA_MODE_SBM_24BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
 }
 
-/* The general case of forward copy in 8bpp mode.  */
+/* The (almost) general case of backward copy in 8bpp mode.  */
 static inline void
-copyarea_foreward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
-                      u32 height, u32 width, u32 line_length)
+copyarea_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
+             u32 height, u32 width, u32 line_length,
+             const struct fb_copyarea *area)
 {
        struct tga_par *par = (struct tga_par *) info->par;
-       unsigned long i, copied, left;
-       unsigned long dpos, spos, dalign, salign, yincr;
-       u32 smask_first, dmask_first, dmask_last;
-       int pixel_shift, need_prime, need_second;
-       unsigned long n64, n32, xincr_first;
+       unsigned i, yincr;
+       int depos, sepos, backward, last_step, step;
+       u32 mask_last;
+       unsigned n32;
        void __iomem *tga_regs;
        void __iomem *tga_fb;
 
-       yincr = line_length;
-       if (dy > sy) {
-               dy += height - 1;
-               sy += height - 1;
-               yincr = -yincr;
-       }
-
-       /* Compute the offsets and alignments in the frame buffer.
-          More than anything else, these control how we do copies.  */
-       dpos = dy * line_length + dx;
-       spos = sy * line_length + sx;
-       dalign = dpos & 7;
-       salign = spos & 7;
-       dpos &= -8;
-       spos &= -8;
-
-       /* Compute the value for the PIXELSHIFT register.  This controls
-          both non-co-aligned source and destination and copy direction.  */
-       if (dalign >= salign)
-               pixel_shift = dalign - salign;
-       else
-               pixel_shift = 8 - (salign - dalign);
-
-       /* Figure out if we need an additional priming step for the
-          residue register.  */
-       need_prime = (salign > dalign);
-       if (need_prime)
-               dpos -= 8;
-
-       /* Begin by copying the leading unaligned destination.  Copy enough
-          to make the next destination address 32-byte aligned.  */
-       copied = 32 - (dalign + (dpos & 31));
-       if (copied == 32)
-               copied = 0;
-       xincr_first = (copied + 7) & -8;
-       smask_first = dmask_first = (1ul << copied) - 1;
-       smask_first <<= salign;
-       dmask_first <<= dalign + need_prime*8;
-       if (need_prime && copied > 24)
-               copied -= 8;
-       left = width - copied;
-
-       /* Care for small copies.  */
-       if (copied > width) {
-               u32 t;
-               t = (1ul << width) - 1;
-               t <<= dalign + need_prime*8;
-               dmask_first &= t;
-               left = 0;
-       }
-
-       /* Attempt to use 64-byte copies.  This is only possible if the
-          source and destination are co-aligned at 64 bytes.  */
-       n64 = need_second = 0;
-       if ((dpos & 63) == (spos & 63)
-           && (height == 1 || line_length % 64 == 0)) {
-               /* We may need a 32-byte copy to ensure 64 byte alignment.  */
-               need_second = (dpos + xincr_first) & 63;
-               if ((need_second & 32) != need_second)
-                       printk(KERN_ERR "tgafb: need_second wrong\n");
-               if (left >= need_second + 64) {
-                       left -= need_second;
-                       n64 = left / 64;
-                       left %= 64;
-               } else
-                       need_second = 0;
-       }
-
-       /* Copy trailing full 32-byte sections.  This will be the main
-          loop if the 64 byte loop can't be used.  */
-       n32 = left / 32;
-       left %= 32;
-
-       /* Copy the trailing unaligned destination.  */
-       dmask_last = (1ul << left) - 1;
-
-       tga_regs = par->tga_regs_base;
-       tga_fb = par->tga_fb_base;
-
-       /* Set up the MODE and PIXELSHIFT registers.  */
-       __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
-       __raw_writel(pixel_shift, tga_regs+TGA_PIXELSHIFT_REG);
-       wmb();
-
-       for (i = 0; i < height; ++i) {
-               unsigned long j;
-               void __iomem *sfb;
-               void __iomem *dfb;
-
-               sfb = tga_fb + spos;
-               dfb = tga_fb + dpos;
-               if (dmask_first) {
-                       __raw_writel(smask_first, sfb);
-                       wmb();
-                       __raw_writel(dmask_first, dfb);
-                       wmb();
-                       sfb += xincr_first;
-                       dfb += xincr_first;
-               }
-
-               if (need_second) {
-                       __raw_writel(0xffffffff, sfb);
-                       wmb();
-                       __raw_writel(0xffffffff, dfb);
-                       wmb();
-                       sfb += 32;
-                       dfb += 32;
-               }
-
-               if (n64 && (((unsigned long)sfb | (unsigned long)dfb) & 63))
-                       printk(KERN_ERR
-                              "tgafb: misaligned copy64 (s:%p, d:%p)\n",
-                              sfb, dfb);
-
-               for (j = 0; j < n64; ++j) {
-                       __raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
-                       wmb();
-                       __raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
-                       wmb();
-                       sfb += 64;
-                       dfb += 64;
-               }
-
-               for (j = 0; j < n32; ++j) {
-                       __raw_writel(0xffffffff, sfb);
-                       wmb();
-                       __raw_writel(0xffffffff, dfb);
-                       wmb();
-                       sfb += 32;
-                       dfb += 32;
-               }
-
-               if (dmask_last) {
-                       __raw_writel(0xffffffff, sfb);
-                       wmb();
-                       __raw_writel(dmask_last, dfb);
-                       wmb();
-               }
-
-               spos += yincr;
-               dpos += yincr;
+       /* Do acceleration only if we are aligned on 8 pixels */
+       if ((dx | sx | width) & 7) {
+               cfb_copyarea(info, area);
+               return;
        }
 
-       /* Reset the MODE register to normal.  */
-       __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
-}
-
-/* The (almost) general case of backward copy in 8bpp mode.  */
-static inline void
-copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
-                      u32 height, u32 width, u32 line_length,
-                      const struct fb_copyarea *area)
-{
-       struct tga_par *par = (struct tga_par *) info->par;
-       unsigned long i, left, yincr;
-       unsigned long depos, sepos, dealign, sealign;
-       u32 mask_first, mask_last;
-       unsigned long n32;
-       void __iomem *tga_regs;
-       void __iomem *tga_fb;
-
        yincr = line_length;
        if (dy > sy) {
                dy += height - 1;
                sy += height - 1;
                yincr = -yincr;
        }
+       backward = dy == sy && dx > sx && dx < sx + width;
 
        /* Compute the offsets and alignments in the frame buffer.
           More than anything else, these control how we do copies.  */
-       depos = dy * line_length + dx + width;
-       sepos = sy * line_length + sx + width;
-       dealign = depos & 7;
-       sealign = sepos & 7;
-
-       /* ??? The documentation appears to be incorrect (or very
-          misleading) wrt how pixel shifting works in backward copy
-          mode, i.e. when PIXELSHIFT is negative.  I give up for now.
-          Do handle the common case of co-aligned backward copies,
-          but frob everything else back on generic code.  */
-       if (dealign != sealign) {
-               cfb_copyarea(info, area);
-               return;
-       }
-
-       /* We begin the copy with the trailing pixels of the
-          unaligned destination.  */
-       mask_first = (1ul << dealign) - 1;
-       left = width - dealign;
-
-       /* Care for small copies.  */
-       if (dealign > width) {
-               mask_first ^= (1ul << (dealign - width)) - 1;
-               left = 0;
-       }
+       depos = dy * line_length + dx;
+       sepos = sy * line_length + sx;
+       if (backward)
+               depos += width, sepos += width;
 
        /* Next copy full words at a time.  */
-       n32 = left / 32;
-       left %= 32;
+       n32 = width / 32;
+       last_step = width % 32;
 
        /* Finally copy the unaligned head of the span.  */
-       mask_last = -1 << (32 - left);
+       mask_last = (1ul << last_step) - 1;
+
+       if (!backward) {
+               step = 32;
+               last_step = 32;
+       } else {
+               step = -32;
+               last_step = -last_step;
+               sepos -= 32;
+               depos -= 32;
+       }
 
        tga_regs = par->tga_regs_base;
        tga_fb = par->tga_fb_base;
@@ -1368,25 +1206,33 @@ copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
 
                sfb = tga_fb + sepos;
                dfb = tga_fb + depos;
-               if (mask_first) {
-                       __raw_writel(mask_first, sfb);
-                       wmb();
-                       __raw_writel(mask_first, dfb);
-                       wmb();
-               }
 
-               for (j = 0; j < n32; ++j) {
-                       sfb -= 32;
-                       dfb -= 32;
+               for (j = 0; j < n32; j++) {
+                       if (j < 2 && j + 1 < n32 && !backward &&
+                           !(((unsigned long)sfb | (unsigned long)dfb) & 63)) {
+                               do {
+                                       __raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
+                                       wmb();
+                                       __raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
+                                       wmb();
+                                       sfb += 64;
+                                       dfb += 64;
+                                       j += 2;
+                               } while (j + 1 < n32);
+                               j--;
+                               continue;
+                       }
                        __raw_writel(0xffffffff, sfb);
                        wmb();
                        __raw_writel(0xffffffff, dfb);
                        wmb();
+                       sfb += step;
+                       dfb += step;
                }
 
                if (mask_last) {
-                       sfb -= 32;
-                       dfb -= 32;
+                       sfb += last_step - step;
+                       dfb += last_step - step;
                        __raw_writel(mask_last, sfb);
                        wmb();
                        __raw_writel(mask_last, dfb);
@@ -1434,7 +1280,7 @@ tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        bpp = info->var.bits_per_pixel;
 
        /* Detect copies of the entire line.  */
-       if (width * (bpp >> 3) == line_length) {
+       if (!(line_length & 63) && width * (bpp >> 3) == line_length) {
                if (bpp == 8)
                        copyarea_line_8bpp(info, dy, sy, height, width);
                else
@@ -1447,14 +1293,9 @@ tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        else if (bpp == 32)
                cfb_copyarea(info, area);
 
-       /* Detect overlapping source and destination that requires
-          a backward copy.  */
-       else if (dy == sy && dx > sx && dx < sx + width)
-               copyarea_backward_8bpp(info, dx, dy, sx, sy, height,
-                                      width, line_length, area);
        else
-               copyarea_foreward_8bpp(info, dx, dy, sx, sy, height,
-                                      width, line_length);
+               copyarea_8bpp(info, dx, dy, sx, sy, height,
+                             width, line_length, area);
 }
 
 
@@ -1470,6 +1311,7 @@ tgafb_init_fix(struct fb_info *info)
        int tga_bus_tc = TGA_BUS_TC(par->dev);
        u8 tga_type = par->tga_type;
        const char *tga_type_name = NULL;
+       unsigned memory_size;
 
        switch (tga_type) {
        case TGA_TYPE_8PLANE:
@@ -1477,22 +1319,27 @@ tgafb_init_fix(struct fb_info *info)
                        tga_type_name = "Digital ZLXp-E1";
                if (tga_bus_tc)
                        tga_type_name = "Digital ZLX-E1";
+               memory_size = 2097152;
                break;
        case TGA_TYPE_24PLANE:
                if (tga_bus_pci)
                        tga_type_name = "Digital ZLXp-E2";
                if (tga_bus_tc)
                        tga_type_name = "Digital ZLX-E2";
+               memory_size = 8388608;
                break;
        case TGA_TYPE_24PLUSZ:
                if (tga_bus_pci)
                        tga_type_name = "Digital ZLXp-E3";
                if (tga_bus_tc)
                        tga_type_name = "Digital ZLX-E3";
+               memory_size = 16777216;
                break;
        }
-       if (!tga_type_name)
+       if (!tga_type_name) {
                tga_type_name = "Unknown";
+               memory_size = 16777216;
+       }
 
        strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id));
 
@@ -1502,9 +1349,8 @@ tgafb_init_fix(struct fb_info *info)
                            ? FB_VISUAL_PSEUDOCOLOR
                            : FB_VISUAL_DIRECTCOLOR);
 
-       info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
        info->fix.smem_start = (size_t) par->tga_fb_base;
-       info->fix.smem_len = info->fix.line_length * par->yres;
+       info->fix.smem_len = memory_size;
        info->fix.mmio_start = (size_t) par->tga_regs_base;
        info->fix.mmio_len = 512;
 
@@ -1628,6 +1474,9 @@ static int tgafb_register(struct device *dev)
                modedb_tga = &modedb_tc;
                modedbsize_tga = 1;
        }
+
+       tgafb_init_fix(info);
+
        ret = fb_find_mode(&info->var, info,
                           mode_option ? mode_option : mode_option_tga,
                           modedb_tga, modedbsize_tga, NULL,
@@ -1645,7 +1494,6 @@ static int tgafb_register(struct device *dev)
        }
 
        tgafb_set_par(info);
-       tgafb_init_fix(info);
 
        if (register_framebuffer(info) < 0) {
                printk(KERN_ERR "tgafb: Could not register framebuffer\n");
index 1f38445014c17c85860d88bb0dac0d9086c08102..509d452e8f91f8ed2181cf148139305deccb60a8 100644 (file)
@@ -1474,12 +1474,7 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)
         *                 used video mode, i.e. the minimum amount of
         *                 memory we need.
         */
-       if (mode != NULL) {
-               size_vmode = info->var.yres * mode->bytes_per_scan_line;
-       } else {
-               size_vmode = info->var.yres * info->var.xres *
-                            ((info->var.bits_per_pixel + 7) >> 3);
-       }
+       size_vmode = info->var.yres * mode->bytes_per_scan_line;
 
        /*
         *   size_total -- all video memory we have. Used for mtrr
@@ -1812,11 +1807,9 @@ static int uvesafb_remove(struct platform_device *dev)
                fb_destroy_modedb(info->monspecs.modedb);
                fb_dealloc_cmap(&info->cmap);
 
-               if (par) {
-                       kfree(par->vbe_modes);
-                       kfree(par->vbe_state_orig);
-                       kfree(par->vbe_state_saved);
-               }
+               kfree(par->vbe_modes);
+               kfree(par->vbe_state_orig);
+               kfree(par->vbe_state_saved);
 
                framebuffer_release(info);
        }
index 1c7da3b098d6ba044d64ca94ec79cbf798938ce9..6170e7f5864071a36577caec2f672e10bd9bb887 100644 (file)
@@ -179,7 +179,6 @@ static void vesafb_destroy(struct fb_info *info)
        if (info->screen_base)
                iounmap(info->screen_base);
        release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
-       framebuffer_release(info);
 }
 
 static struct fb_ops vesafb_ops = {
@@ -297,6 +296,7 @@ static int vesafb_probe(struct platform_device *dev)
                release_mem_region(vesafb_fix.smem_start, size_total);
                return -ENOMEM;
        }
+       platform_set_drvdata(dev, info);
        info->pseudo_palette = info->par;
        info->par = NULL;
 
@@ -499,12 +499,23 @@ err:
        return err;
 }
 
+static int vesafb_remove(struct platform_device *pdev)
+{
+       struct fb_info *info = platform_get_drvdata(pdev);
+
+       unregister_framebuffer(info);
+       framebuffer_release(info);
+
+       return 0;
+}
+
 static struct platform_driver vesafb_driver = {
        .driver = {
                .name = "vesa-framebuffer",
                .owner = THIS_MODULE,
        },
        .probe = vesafb_probe,
+       .remove = vesafb_remove,
 };
 
 module_platform_driver(vesafb_driver);
index 6ff1a91e9dfdaa64c9612bca68d2e0c04dd24dff..553cff2f3f4c8233786773c368ad9cb0968ad8e1 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
-#include <linux/xilinxfb.h>
 #include <linux/slab.h>
 
 #ifdef CONFIG_PPC_DCR
 
 #define PALETTE_ENTRIES_NO     16      /* passed to fb_alloc_cmap() */
 
+/* ML300/403 reference design framebuffer driver platform data struct */
+struct xilinxfb_platform_data {
+       u32 rotate_screen;      /* Flag to rotate display 180 degrees */
+       u32 screen_height_mm;   /* Physical dimensions of screen in mm */
+       u32 screen_width_mm;
+       u32 xres, yres;         /* resolution of screen in pixels */
+       u32 xvirt, yvirt;       /* resolution of memory buffer */
+
+       /* Physical address of framebuffer memory; If non-zero, driver
+       * will use provided memory address instead of allocating one from
+       * the consistent pool. */
+       u32 fb_phys;
+};
+
 /*
  * Default xilinxfb configuration
  */
index 0c6048d5c9a363a5ebd18256eaec3c149fff4d5b..74ec8fc5cc0303fa81fd036c87632c7f8524c824 100644 (file)
@@ -301,7 +301,7 @@ config DAVINCI_WATCHDOG
 
 config ORION_WATCHDOG
        tristate "Orion watchdog"
-       depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE
+       depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU
        select WATCHDOG_CORE
        help
          Say Y here if to include support for the watchdog timer
index 0e6c0333f775775aa776902cff248abddd9e3a5e..0ba1b7c997603e43fd24a99fc2e97f689f0515a9 100644 (file)
@@ -48,7 +48,7 @@
 
 /* Module and version information */
 #define DRV_NAME       "iTCO_wdt"
-#define DRV_VERSION    "1.10"
+#define DRV_VERSION    "1.11"
 
 /* Includes */
 #include <linux/module.h>              /* For module specific items */
@@ -92,9 +92,12 @@ static struct {              /* this is private data for the iTCO_wdt device */
        unsigned int iTCO_version;
        struct resource *tco_res;
        struct resource *smi_res;
-       struct resource *gcs_res;
-       /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
-       unsigned long __iomem *gcs;
+       /*
+        * NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2),
+        * or memory-mapped PMC register bit 4 (TCO version 3).
+        */
+       struct resource *gcs_pmc_res;
+       unsigned long __iomem *gcs_pmc;
        /* the lock for io operations */
        spinlock_t io_lock;
        struct platform_device *dev;
@@ -125,11 +128,19 @@ MODULE_PARM_DESC(turn_SMI_watchdog_clear_off,
  * Some TCO specific functions
  */
 
-static inline unsigned int seconds_to_ticks(int seconds)
+/*
+ * The iTCO v1 and v2's internal timer is stored as ticks which decrement
+ * every 0.6 seconds.  v3's internal timer is stored as seconds (some
+ * datasheets incorrectly state 0.6 seconds).
+ */
+static inline unsigned int seconds_to_ticks(int secs)
 {
-       /* the internal timer is stored as ticks which decrement
-        * every 0.6 seconds */
-       return (seconds * 10) / 6;
+       return iTCO_wdt_private.iTCO_version == 3 ? secs : (secs * 10) / 6;
+}
+
+static inline unsigned int ticks_to_seconds(int ticks)
+{
+       return iTCO_wdt_private.iTCO_version == 3 ? ticks : (ticks * 6) / 10;
 }
 
 static void iTCO_wdt_set_NO_REBOOT_bit(void)
@@ -137,10 +148,14 @@ static void iTCO_wdt_set_NO_REBOOT_bit(void)
        u32 val32;
 
        /* Set the NO_REBOOT bit: this disables reboots */
-       if (iTCO_wdt_private.iTCO_version == 2) {
-               val32 = readl(iTCO_wdt_private.gcs);
+       if (iTCO_wdt_private.iTCO_version == 3) {
+               val32 = readl(iTCO_wdt_private.gcs_pmc);
+               val32 |= 0x00000010;
+               writel(val32, iTCO_wdt_private.gcs_pmc);
+       } else if (iTCO_wdt_private.iTCO_version == 2) {
+               val32 = readl(iTCO_wdt_private.gcs_pmc);
                val32 |= 0x00000020;
-               writel(val32, iTCO_wdt_private.gcs);
+               writel(val32, iTCO_wdt_private.gcs_pmc);
        } else if (iTCO_wdt_private.iTCO_version == 1) {
                pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
                val32 |= 0x00000002;
@@ -154,12 +169,20 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void)
        u32 val32;
 
        /* Unset the NO_REBOOT bit: this enables reboots */
-       if (iTCO_wdt_private.iTCO_version == 2) {
-               val32 = readl(iTCO_wdt_private.gcs);
+       if (iTCO_wdt_private.iTCO_version == 3) {
+               val32 = readl(iTCO_wdt_private.gcs_pmc);
+               val32 &= 0xffffffef;
+               writel(val32, iTCO_wdt_private.gcs_pmc);
+
+               val32 = readl(iTCO_wdt_private.gcs_pmc);
+               if (val32 & 0x00000010)
+                       ret = -EIO;
+       } else if (iTCO_wdt_private.iTCO_version == 2) {
+               val32 = readl(iTCO_wdt_private.gcs_pmc);
                val32 &= 0xffffffdf;
-               writel(val32, iTCO_wdt_private.gcs);
+               writel(val32, iTCO_wdt_private.gcs_pmc);
 
-               val32 = readl(iTCO_wdt_private.gcs);
+               val32 = readl(iTCO_wdt_private.gcs_pmc);
                if (val32 & 0x00000020)
                        ret = -EIO;
        } else if (iTCO_wdt_private.iTCO_version == 1) {
@@ -192,7 +215,7 @@ static int iTCO_wdt_start(struct watchdog_device *wd_dev)
 
        /* Force the timer to its reload value by writing to the TCO_RLD
           register */
-       if (iTCO_wdt_private.iTCO_version == 2)
+       if (iTCO_wdt_private.iTCO_version >= 2)
                outw(0x01, TCO_RLD);
        else if (iTCO_wdt_private.iTCO_version == 1)
                outb(0x01, TCO_RLD);
@@ -240,9 +263,9 @@ static int iTCO_wdt_ping(struct watchdog_device *wd_dev)
        iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, wd_dev->timeout);
 
        /* Reload the timer by writing to the TCO Timer Counter register */
-       if (iTCO_wdt_private.iTCO_version == 2)
+       if (iTCO_wdt_private.iTCO_version >= 2) {
                outw(0x01, TCO_RLD);
-       else if (iTCO_wdt_private.iTCO_version == 1) {
+       else if (iTCO_wdt_private.iTCO_version == 1) {
                /* Reset the timeout status bit so that the timer
                 * needs to count down twice again before rebooting */
                outw(0x0008, TCO1_STS); /* write 1 to clear bit */
@@ -270,14 +293,14 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t)
        /* "Values of 0h-3h are ignored and should not be attempted" */
        if (tmrval < 0x04)
                return -EINVAL;
-       if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
+       if (((iTCO_wdt_private.iTCO_version >= 2) && (tmrval > 0x3ff)) ||
            ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
                return -EINVAL;
 
        iTCO_vendor_pre_set_heartbeat(tmrval);
 
        /* Write new heartbeat to watchdog */
-       if (iTCO_wdt_private.iTCO_version == 2) {
+       if (iTCO_wdt_private.iTCO_version >= 2) {
                spin_lock(&iTCO_wdt_private.io_lock);
                val16 = inw(TCOv2_TMR);
                val16 &= 0xfc00;
@@ -312,13 +335,13 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
        unsigned int time_left = 0;
 
        /* read the TCO Timer */
-       if (iTCO_wdt_private.iTCO_version == 2) {
+       if (iTCO_wdt_private.iTCO_version >= 2) {
                spin_lock(&iTCO_wdt_private.io_lock);
                val16 = inw(TCO_RLD);
                val16 &= 0x3ff;
                spin_unlock(&iTCO_wdt_private.io_lock);
 
-               time_left = (val16 * 6) / 10;
+               time_left = ticks_to_seconds(val16);
        } else if (iTCO_wdt_private.iTCO_version == 1) {
                spin_lock(&iTCO_wdt_private.io_lock);
                val8 = inb(TCO_RLD);
@@ -327,7 +350,7 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
                        val8 += (inb(TCOv1_TMR) & 0x3f);
                spin_unlock(&iTCO_wdt_private.io_lock);
 
-               time_left = (val8 * 6) / 10;
+               time_left = ticks_to_seconds(val8);
        }
        return time_left;
 }
@@ -376,16 +399,16 @@ static void iTCO_wdt_cleanup(void)
                        resource_size(iTCO_wdt_private.tco_res));
        release_region(iTCO_wdt_private.smi_res->start,
                        resource_size(iTCO_wdt_private.smi_res));
-       if (iTCO_wdt_private.iTCO_version == 2) {
-               iounmap(iTCO_wdt_private.gcs);
-               release_mem_region(iTCO_wdt_private.gcs_res->start,
-                               resource_size(iTCO_wdt_private.gcs_res));
+       if (iTCO_wdt_private.iTCO_version >= 2) {
+               iounmap(iTCO_wdt_private.gcs_pmc);
+               release_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
+                               resource_size(iTCO_wdt_private.gcs_pmc_res));
        }
 
        iTCO_wdt_private.tco_res = NULL;
        iTCO_wdt_private.smi_res = NULL;
-       iTCO_wdt_private.gcs_res = NULL;
-       iTCO_wdt_private.gcs = NULL;
+       iTCO_wdt_private.gcs_pmc_res = NULL;
+       iTCO_wdt_private.gcs_pmc = NULL;
 }
 
 static int iTCO_wdt_probe(struct platform_device *dev)
@@ -414,27 +437,27 @@ static int iTCO_wdt_probe(struct platform_device *dev)
        iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent);
 
        /*
-        * Get the Memory-Mapped GCS register, we need it for the
-        * NO_REBOOT flag (TCO v2).
+        * Get the Memory-Mapped GCS or PMC register, we need it for the
+        * NO_REBOOT flag (TCO v2 and v3).
         */
-       if (iTCO_wdt_private.iTCO_version == 2) {
-               iTCO_wdt_private.gcs_res = platform_get_resource(dev,
+       if (iTCO_wdt_private.iTCO_version >= 2) {
+               iTCO_wdt_private.gcs_pmc_res = platform_get_resource(dev,
                                                        IORESOURCE_MEM,
-                                                       ICH_RES_MEM_GCS);
+                                                       ICH_RES_MEM_GCS_PMC);
 
-               if (!iTCO_wdt_private.gcs_res)
+               if (!iTCO_wdt_private.gcs_pmc_res)
                        goto out;
 
-               if (!request_mem_region(iTCO_wdt_private.gcs_res->start,
-                       resource_size(iTCO_wdt_private.gcs_res), dev->name)) {
+               if (!request_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
+                       resource_size(iTCO_wdt_private.gcs_pmc_res), dev->name)) {
                        ret = -EBUSY;
                        goto out;
                }
-               iTCO_wdt_private.gcs = ioremap(iTCO_wdt_private.gcs_res->start,
-                       resource_size(iTCO_wdt_private.gcs_res));
-               if (!iTCO_wdt_private.gcs) {
+               iTCO_wdt_private.gcs_pmc = ioremap(iTCO_wdt_private.gcs_pmc_res->start,
+                       resource_size(iTCO_wdt_private.gcs_pmc_res));
+               if (!iTCO_wdt_private.gcs_pmc) {
                        ret = -EIO;
-                       goto unreg_gcs;
+                       goto unreg_gcs_pmc;
                }
        }
 
@@ -442,7 +465,7 @@ static int iTCO_wdt_probe(struct platform_device *dev)
        if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
                pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
                ret = -ENODEV;  /* Cannot reset NO_REBOOT bit */
-               goto unmap_gcs;
+               goto unmap_gcs_pmc;
        }
 
        /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
@@ -454,7 +477,7 @@ static int iTCO_wdt_probe(struct platform_device *dev)
                pr_err("I/O address 0x%04llx already in use, device disabled\n",
                       (u64)SMI_EN);
                ret = -EBUSY;
-               goto unmap_gcs;
+               goto unmap_gcs_pmc;
        }
        if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) {
                /*
@@ -478,9 +501,13 @@ static int iTCO_wdt_probe(struct platform_device *dev)
                ich_info->name, ich_info->iTCO_version, (u64)TCOBASE);
 
        /* Clear out the (probably old) status */
-       outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */
-       outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */
-       outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */
+       if (iTCO_wdt_private.iTCO_version == 3) {
+               outl(0x20008, TCO1_STS);
+       } else {
+               outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */
+               outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */
+               outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */
+       }
 
        iTCO_wdt_watchdog_dev.bootstatus = 0;
        iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT;
@@ -515,18 +542,18 @@ unreg_tco:
 unreg_smi:
        release_region(iTCO_wdt_private.smi_res->start,
                        resource_size(iTCO_wdt_private.smi_res));
-unmap_gcs:
-       if (iTCO_wdt_private.iTCO_version == 2)
-               iounmap(iTCO_wdt_private.gcs);
-unreg_gcs:
-       if (iTCO_wdt_private.iTCO_version == 2)
-               release_mem_region(iTCO_wdt_private.gcs_res->start,
-                               resource_size(iTCO_wdt_private.gcs_res));
+unmap_gcs_pmc:
+       if (iTCO_wdt_private.iTCO_version >= 2)
+               iounmap(iTCO_wdt_private.gcs_pmc);
+unreg_gcs_pmc:
+       if (iTCO_wdt_private.iTCO_version >= 2)
+               release_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
+                               resource_size(iTCO_wdt_private.gcs_pmc_res));
 out:
        iTCO_wdt_private.tco_res = NULL;
        iTCO_wdt_private.smi_res = NULL;
-       iTCO_wdt_private.gcs_res = NULL;
-       iTCO_wdt_private.gcs = NULL;
+       iTCO_wdt_private.gcs_pmc_res = NULL;
+       iTCO_wdt_private.gcs_pmc = NULL;
 
        return ret;
 }
index 461208831428e4da609606282af2b56f4c3c81f4..4baf2d788920484f5f9fe8d752d9f51ecf7b63fb 100644 (file)
@@ -708,10 +708,13 @@ static int __init octeon_wdt_init(void)
 
        cpumask_clear(&irq_enabled_cpus);
 
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu)
                octeon_wdt_setup_interrupt(cpu);
 
-       register_hotcpu_notifier(&octeon_wdt_cpu_notifier);
+       __register_hotcpu_notifier(&octeon_wdt_cpu_notifier);
+       cpu_notifier_register_done();
+
 out:
        return ret;
 }
@@ -725,7 +728,8 @@ static void __exit octeon_wdt_cleanup(void)
 
        misc_deregister(&octeon_wdt_miscdev);
 
-       unregister_hotcpu_notifier(&octeon_wdt_cpu_notifier);
+       cpu_notifier_register_begin();
+       __unregister_hotcpu_notifier(&octeon_wdt_cpu_notifier);
 
        for_each_online_cpu(cpu) {
                int core = cpu2core(cpu);
@@ -734,6 +738,9 @@ static void __exit octeon_wdt_cleanup(void)
                /* Free the interrupt handler */
                free_irq(OCTEON_IRQ_WDOG0 + core, octeon_wdt_poke_irq);
        }
+
+       cpu_notifier_register_done();
+
        /*
         * Disable the boot-bus memory, the code it points to is soon
         * to go missing.
index 498163497c1cc039db45a4f2fdd373b6dbf49d42..9b3c41d1870370860d582f4e8e74cf5a290d54f6 100644 (file)
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/watchdog.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/spinlock.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <mach/bridge-regs.h>
+#include <linux/of_device.h>
+
+/* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */
+#define ORION_RSTOUT_MASK_OFFSET       0x20108
+
+/* Internal registers can be configured at any 1 MiB aligned address */
+#define INTERNAL_REGS_MASK             ~(SZ_1M - 1)
 
 /*
  * Watchdog timer block registers.
  */
 #define TIMER_CTRL             0x0000
-#define WDT_EN                 0x0010
-#define WDT_VAL                        0x0024
+#define TIMER_A370_STATUS      0x04
 
 #define WDT_MAX_CYCLE_COUNT    0xffffffff
-#define WDT_IN_USE             0
-#define WDT_OK_TO_CLOSE                1
 
-#define WDT_RESET_OUT_EN       BIT(1)
-#define WDT_INT_REQ            BIT(3)
+#define WDT_A370_RATIO_MASK(v) ((v) << 16)
+#define WDT_A370_RATIO_SHIFT   5
+#define WDT_A370_RATIO         (1 << WDT_A370_RATIO_SHIFT)
+
+#define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
+#define WDT_A370_EXPIRED       BIT(31)
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
 static int heartbeat = -1;             /* module parameter (seconds) */
-static unsigned int wdt_max_duration;  /* (seconds) */
-static struct clk *clk;
-static unsigned int wdt_tclk;
-static void __iomem *wdt_reg;
-static DEFINE_SPINLOCK(wdt_lock);
 
-static int orion_wdt_ping(struct watchdog_device *wdt_dev)
+struct orion_watchdog;
+
+struct orion_watchdog_data {
+       int wdt_counter_offset;
+       int wdt_enable_bit;
+       int rstout_enable_bit;
+       int (*clock_init)(struct platform_device *,
+                         struct orion_watchdog *);
+       int (*start)(struct watchdog_device *);
+};
+
+struct orion_watchdog {
+       struct watchdog_device wdt;
+       void __iomem *reg;
+       void __iomem *rstout;
+       unsigned long clk_rate;
+       struct clk *clk;
+       const struct orion_watchdog_data *data;
+};
+
+static int orion_wdt_clock_init(struct platform_device *pdev,
+                               struct orion_watchdog *dev)
 {
-       spin_lock(&wdt_lock);
+       int ret;
 
-       /* Reload watchdog duration */
-       writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
+       dev->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(dev->clk))
+               return PTR_ERR(dev->clk);
+       ret = clk_prepare_enable(dev->clk);
+       if (ret) {
+               clk_put(dev->clk);
+               return ret;
+       }
 
-       spin_unlock(&wdt_lock);
+       dev->clk_rate = clk_get_rate(dev->clk);
        return 0;
 }
 
-static int orion_wdt_start(struct watchdog_device *wdt_dev)
+static int armada370_wdt_clock_init(struct platform_device *pdev,
+                                   struct orion_watchdog *dev)
 {
-       u32 reg;
+       int ret;
 
-       spin_lock(&wdt_lock);
+       dev->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(dev->clk))
+               return PTR_ERR(dev->clk);
+       ret = clk_prepare_enable(dev->clk);
+       if (ret) {
+               clk_put(dev->clk);
+               return ret;
+       }
+
+       /* Setup watchdog input clock */
+       atomic_io_modify(dev->reg + TIMER_CTRL,
+                       WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT),
+                       WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT));
+
+       dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO;
+       return 0;
+}
+
+static int armadaxp_wdt_clock_init(struct platform_device *pdev,
+                                  struct orion_watchdog *dev)
+{
+       int ret;
+
+       dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
+       if (IS_ERR(dev->clk))
+               return PTR_ERR(dev->clk);
+       ret = clk_prepare_enable(dev->clk);
+       if (ret) {
+               clk_put(dev->clk);
+               return ret;
+       }
+
+       /* Enable the fixed watchdog clock input */
+       atomic_io_modify(dev->reg + TIMER_CTRL,
+                        WDT_AXP_FIXED_ENABLE_BIT,
+                        WDT_AXP_FIXED_ENABLE_BIT);
+
+       dev->clk_rate = clk_get_rate(dev->clk);
+       return 0;
+}
+
+static int orion_wdt_ping(struct watchdog_device *wdt_dev)
+{
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
+       /* Reload watchdog duration */
+       writel(dev->clk_rate * wdt_dev->timeout,
+              dev->reg + dev->data->wdt_counter_offset);
+       return 0;
+}
+
+static int armada370_start(struct watchdog_device *wdt_dev)
+{
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 
        /* Set watchdog duration */
-       writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
+       writel(dev->clk_rate * wdt_dev->timeout,
+              dev->reg + dev->data->wdt_counter_offset);
 
-       /* Clear watchdog timer interrupt */
-       writel(~WDT_INT_REQ, BRIDGE_CAUSE);
+       /* Clear the watchdog expiration bit */
+       atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0);
 
        /* Enable watchdog timer */
-       reg = readl(wdt_reg + TIMER_CTRL);
-       reg |= WDT_EN;
-       writel(reg, wdt_reg + TIMER_CTRL);
+       atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
+                                               dev->data->wdt_enable_bit);
+
+       atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit,
+                                     dev->data->rstout_enable_bit);
+       return 0;
+}
+
+static int orion_start(struct watchdog_device *wdt_dev)
+{
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
+
+       /* Set watchdog duration */
+       writel(dev->clk_rate * wdt_dev->timeout,
+              dev->reg + dev->data->wdt_counter_offset);
+
+       /* Enable watchdog timer */
+       atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
+                                               dev->data->wdt_enable_bit);
 
        /* Enable reset on watchdog */
-       reg = readl(RSTOUTn_MASK);
-       reg |= WDT_RESET_OUT_EN;
-       writel(reg, RSTOUTn_MASK);
+       atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit,
+                                     dev->data->rstout_enable_bit);
 
-       spin_unlock(&wdt_lock);
        return 0;
 }
 
-static int orion_wdt_stop(struct watchdog_device *wdt_dev)
+static int orion_wdt_start(struct watchdog_device *wdt_dev)
 {
-       u32 reg;
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 
-       spin_lock(&wdt_lock);
+       /* There are some per-SoC quirks to handle */
+       return dev->data->start(wdt_dev);
+}
+
+static int orion_wdt_stop(struct watchdog_device *wdt_dev)
+{
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 
        /* Disable reset on watchdog */
-       reg = readl(RSTOUTn_MASK);
-       reg &= ~WDT_RESET_OUT_EN;
-       writel(reg, RSTOUTn_MASK);
+       atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit, 0);
 
        /* Disable watchdog timer */
-       reg = readl(wdt_reg + TIMER_CTRL);
-       reg &= ~WDT_EN;
-       writel(reg, wdt_reg + TIMER_CTRL);
+       atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, 0);
 
-       spin_unlock(&wdt_lock);
        return 0;
 }
 
-static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
+static int orion_wdt_enabled(struct orion_watchdog *dev)
 {
-       unsigned int time_left;
+       bool enabled, running;
+
+       enabled = readl(dev->rstout) & dev->data->rstout_enable_bit;
+       running = readl(dev->reg + TIMER_CTRL) & dev->data->wdt_enable_bit;
 
-       spin_lock(&wdt_lock);
-       time_left = readl(wdt_reg + WDT_VAL) / wdt_tclk;
-       spin_unlock(&wdt_lock);
+       return enabled && running;
+}
 
-       return time_left;
+static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
+{
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
+       return readl(dev->reg + dev->data->wdt_counter_offset) / dev->clk_rate;
 }
 
 static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
@@ -136,68 +239,188 @@ static const struct watchdog_ops orion_wdt_ops = {
        .get_timeleft = orion_wdt_get_timeleft,
 };
 
-static struct watchdog_device orion_wdt = {
-       .info = &orion_wdt_info,
-       .ops = &orion_wdt_ops,
-       .min_timeout = 1,
+static irqreturn_t orion_wdt_irq(int irq, void *devid)
+{
+       panic("Watchdog Timeout");
+       return IRQ_HANDLED;
+}
+
+/*
+ * The original devicetree binding for this driver specified only
+ * one memory resource, so in order to keep DT backwards compatibility
+ * we try to fallback to a hardcoded register address, if the resource
+ * is missing from the devicetree.
+ */
+static void __iomem *orion_wdt_ioremap_rstout(struct platform_device *pdev,
+                                             phys_addr_t internal_regs)
+{
+       struct resource *res;
+       phys_addr_t rstout;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (res)
+               return devm_ioremap(&pdev->dev, res->start,
+                                   resource_size(res));
+
+       /* This workaround works only for "orion-wdt", DT-enabled */
+       if (!of_device_is_compatible(pdev->dev.of_node, "marvell,orion-wdt"))
+               return NULL;
+
+       rstout = internal_regs + ORION_RSTOUT_MASK_OFFSET;
+
+       WARN(1, FW_BUG "falling back to harcoded RSTOUT reg %pa\n", &rstout);
+       return devm_ioremap(&pdev->dev, rstout, 0x4);
+}
+
+static const struct orion_watchdog_data orion_data = {
+       .rstout_enable_bit = BIT(1),
+       .wdt_enable_bit = BIT(4),
+       .wdt_counter_offset = 0x24,
+       .clock_init = orion_wdt_clock_init,
+       .start = orion_start,
+};
+
+static const struct orion_watchdog_data armada370_data = {
+       .rstout_enable_bit = BIT(8),
+       .wdt_enable_bit = BIT(8),
+       .wdt_counter_offset = 0x34,
+       .clock_init = armada370_wdt_clock_init,
+       .start = armada370_start,
 };
 
+static const struct orion_watchdog_data armadaxp_data = {
+       .rstout_enable_bit = BIT(8),
+       .wdt_enable_bit = BIT(8),
+       .wdt_counter_offset = 0x34,
+       .clock_init = armadaxp_wdt_clock_init,
+       .start = armada370_start,
+};
+
+static const struct of_device_id orion_wdt_of_match_table[] = {
+       {
+               .compatible = "marvell,orion-wdt",
+               .data = &orion_data,
+       },
+       {
+               .compatible = "marvell,armada-370-wdt",
+               .data = &armada370_data,
+       },
+       {
+               .compatible = "marvell,armada-xp-wdt",
+               .data = &armadaxp_data,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
+
 static int orion_wdt_probe(struct platform_device *pdev)
 {
+       struct orion_watchdog *dev;
+       const struct of_device_id *match;
+       unsigned int wdt_max_duration;  /* (seconds) */
        struct resource *res;
-       int ret;
+       int ret, irq;
 
-       clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(clk)) {
-               dev_err(&pdev->dev, "Orion Watchdog missing clock\n");
-               return -ENODEV;
-       }
-       clk_prepare_enable(clk);
-       wdt_tclk = clk_get_rate(clk);
+       dev = devm_kzalloc(&pdev->dev, sizeof(struct orion_watchdog),
+                          GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       match = of_match_device(orion_wdt_of_match_table, &pdev->dev);
+       if (!match)
+               /* Default legacy match */
+               match = &orion_wdt_of_match_table[0];
+
+       dev->wdt.info = &orion_wdt_info;
+       dev->wdt.ops = &orion_wdt_ops;
+       dev->wdt.min_timeout = 1;
+       dev->data = match->data;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
                return -ENODEV;
-       wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
-       if (!wdt_reg)
-               return -ENOMEM;
 
-       wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
+       dev->reg = devm_ioremap(&pdev->dev, res->start,
+                              resource_size(res));
+       if (!dev->reg)
+               return -ENOMEM;
 
-       orion_wdt.timeout = wdt_max_duration;
-       orion_wdt.max_timeout = wdt_max_duration;
-       watchdog_init_timeout(&orion_wdt, heartbeat, &pdev->dev);
+       dev->rstout = orion_wdt_ioremap_rstout(pdev, res->start &
+                                                    INTERNAL_REGS_MASK);
+       if (!dev->rstout)
+               return -ENODEV;
 
-       watchdog_set_nowayout(&orion_wdt, nowayout);
-       ret = watchdog_register_device(&orion_wdt);
+       ret = dev->data->clock_init(pdev, dev);
        if (ret) {
-               clk_disable_unprepare(clk);
+               dev_err(&pdev->dev, "cannot initialize clock\n");
                return ret;
        }
 
+       wdt_max_duration = WDT_MAX_CYCLE_COUNT / dev->clk_rate;
+
+       dev->wdt.timeout = wdt_max_duration;
+       dev->wdt.max_timeout = wdt_max_duration;
+       watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
+
+       platform_set_drvdata(pdev, &dev->wdt);
+       watchdog_set_drvdata(&dev->wdt, dev);
+
+       /*
+        * Let's make sure the watchdog is fully stopped, unless it's
+        * explicitly enabled. This may be the case if the module was
+        * removed and re-insterted, or if the bootloader explicitly
+        * set a running watchdog before booting the kernel.
+        */
+       if (!orion_wdt_enabled(dev))
+               orion_wdt_stop(&dev->wdt);
+
+       /* Request the IRQ only after the watchdog is disabled */
+       irq = platform_get_irq(pdev, 0);
+       if (irq > 0) {
+               /*
+                * Not all supported platforms specify an interrupt for the
+                * watchdog, so let's make it optional.
+                */
+               ret = devm_request_irq(&pdev->dev, irq, orion_wdt_irq, 0,
+                                      pdev->name, dev);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to request IRQ\n");
+                       goto disable_clk;
+               }
+       }
+
+       watchdog_set_nowayout(&dev->wdt, nowayout);
+       ret = watchdog_register_device(&dev->wdt);
+       if (ret)
+               goto disable_clk;
+
        pr_info("Initial timeout %d sec%s\n",
-               orion_wdt.timeout, nowayout ? ", nowayout" : "");
+               dev->wdt.timeout, nowayout ? ", nowayout" : "");
        return 0;
+
+disable_clk:
+       clk_disable_unprepare(dev->clk);
+       clk_put(dev->clk);
+       return ret;
 }
 
 static int orion_wdt_remove(struct platform_device *pdev)
 {
-       watchdog_unregister_device(&orion_wdt);
-       clk_disable_unprepare(clk);
+       struct watchdog_device *wdt_dev = platform_get_drvdata(pdev);
+       struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
+
+       watchdog_unregister_device(wdt_dev);
+       clk_disable_unprepare(dev->clk);
+       clk_put(dev->clk);
        return 0;
 }
 
 static void orion_wdt_shutdown(struct platform_device *pdev)
 {
-       orion_wdt_stop(&orion_wdt);
+       struct watchdog_device *wdt_dev = platform_get_drvdata(pdev);
+       orion_wdt_stop(wdt_dev);
 }
 
-static const struct of_device_id orion_wdt_of_match_table[] = {
-       { .compatible = "marvell,orion-wdt", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
-
 static struct platform_driver orion_wdt_driver = {
        .probe          = orion_wdt_probe,
        .remove         = orion_wdt_remove,
index 61a6ac8fa8fc7ab00dcc7c33cea47981f2509d4b..b7a506f2bb144e1c2e59b0f84c4c736d90dd830b 100644 (file)
@@ -604,19 +604,29 @@ static void __init balloon_add_region(unsigned long start_pfn,
        }
 }
 
+static int alloc_balloon_scratch_page(int cpu)
+{
+       if (per_cpu(balloon_scratch_page, cpu) != NULL)
+               return 0;
+
+       per_cpu(balloon_scratch_page, cpu) = alloc_page(GFP_KERNEL);
+       if (per_cpu(balloon_scratch_page, cpu) == NULL) {
+               pr_warn("Failed to allocate balloon_scratch_page for cpu %d\n", cpu);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+
 static int balloon_cpu_notify(struct notifier_block *self,
                                    unsigned long action, void *hcpu)
 {
        int cpu = (long)hcpu;
        switch (action) {
        case CPU_UP_PREPARE:
-               if (per_cpu(balloon_scratch_page, cpu) != NULL)
-                       break;
-               per_cpu(balloon_scratch_page, cpu) = alloc_page(GFP_KERNEL);
-               if (per_cpu(balloon_scratch_page, cpu) == NULL) {
-                       pr_warn("Failed to allocate balloon_scratch_page for cpu %d\n", cpu);
+               if (alloc_balloon_scratch_page(cpu))
                        return NOTIFY_BAD;
-               }
                break;
        default:
                break;
@@ -636,15 +646,17 @@ static int __init balloon_init(void)
                return -ENODEV;
 
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-               for_each_online_cpu(cpu)
-               {
-                       per_cpu(balloon_scratch_page, cpu) = alloc_page(GFP_KERNEL);
-                       if (per_cpu(balloon_scratch_page, cpu) == NULL) {
-                               pr_warn("Failed to allocate balloon_scratch_page for cpu %d\n", cpu);
+               register_cpu_notifier(&balloon_cpu_notifier);
+
+               get_online_cpus();
+               for_each_online_cpu(cpu) {
+                       if (alloc_balloon_scratch_page(cpu)) {
+                               put_online_cpus();
+                               unregister_cpu_notifier(&balloon_cpu_notifier);
                                return -ENOMEM;
                        }
                }
-               register_cpu_notifier(&balloon_cpu_notifier);
+               put_online_cpus();
        }
 
        pr_info("Initialising balloon driver\n");
index 7b3003cb6f1bde4d562d01e85db3455d120c7309..952aeb048349c73ea9a6d9354015163640e47d4b 100644 (file)
@@ -212,6 +212,7 @@ static int parse_options(struct super_block *sb, char *options)
 
 static int adfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        return parse_options(sb, data);
 }
index d098731b82ffa794853e66ff0bcb4e05aa59fcbc..307453086c3f84bab8edaff9a201e0da3baad819 100644 (file)
@@ -530,6 +530,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
 
        pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
 
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
 
        memcpy(volume, sbi->s_volume, 32);
index 5188f1222987412c87f8b8ec974b79c05441be87..d626756ff7219415d027380590371b70384445c9 100644 (file)
@@ -913,6 +913,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
 static int
 befs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if (!(*flags & MS_RDONLY))
                return -EINVAL;
        return 0;
index c1e0b0caf9cc975c2822cadf9aaaf0c1454dcf91..ecb5832c0967e96ffcb0084435f3a37f69f0d661 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007 Oracle.  All rights reserved.
+ * Copyright (C) 2014 Fujitsu.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
+#include <linux/workqueue.h>
 #include "async-thread.h"
+#include "ctree.h"
+
+#define WORK_DONE_BIT 0
+#define WORK_ORDER_DONE_BIT 1
+#define WORK_HIGH_PRIO_BIT 2
+
+#define NO_THRESHOLD (-1)
+#define DFT_THRESHOLD (32)
+
+struct __btrfs_workqueue {
+       struct workqueue_struct *normal_wq;
+       /* List head pointing to ordered work list */
+       struct list_head ordered_list;
+
+       /* Spinlock for ordered_list */
+       spinlock_t list_lock;
+
+       /* Thresholding related variants */
+       atomic_t pending;
+       int max_active;
+       int current_max;
+       int thresh;
+       unsigned int count;
+       spinlock_t thres_lock;
+};
 
-#define WORK_QUEUED_BIT 0
-#define WORK_DONE_BIT 1
-#define WORK_ORDER_DONE_BIT 2
-#define WORK_HIGH_PRIO_BIT 3
-
-/*
- * container for the kthread task pointer and the list of pending work
- * One of these is allocated per thread.
- */
-struct btrfs_worker_thread {
-       /* pool we belong to */
-       struct btrfs_workers *workers;
-
-       /* list of struct btrfs_work that are waiting for service */
-       struct list_head pending;
-       struct list_head prio_pending;
-
-       /* list of worker threads from struct btrfs_workers */
-       struct list_head worker_list;
-
-       /* kthread */
-       struct task_struct *task;
+struct btrfs_workqueue {
+       struct __btrfs_workqueue *normal;
+       struct __btrfs_workqueue *high;
+};
 
-       /* number of things on the pending list */
-       atomic_t num_pending;
+static inline struct __btrfs_workqueue
+*__btrfs_alloc_workqueue(const char *name, int flags, int max_active,
+                        int thresh)
+{
+       struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS);
 
-       /* reference counter for this struct */
-       atomic_t refs;
+       if (unlikely(!ret))
+               return NULL;
 
-       unsigned long sequence;
+       ret->max_active = max_active;
+       atomic_set(&ret->pending, 0);
+       if (thresh == 0)
+               thresh = DFT_THRESHOLD;
+       /* For low threshold, disabling threshold is a better choice */
+       if (thresh < DFT_THRESHOLD) {
+               ret->current_max = max_active;
+               ret->thresh = NO_THRESHOLD;
+       } else {
+               ret->current_max = 1;
+               ret->thresh = thresh;
+       }
 
-       /* protects the pending list. */
-       spinlock_t lock;
+       if (flags & WQ_HIGHPRI)
+               ret->normal_wq = alloc_workqueue("%s-%s-high", flags,
+                                                ret->max_active,
+                                                "btrfs", name);
+       else
+               ret->normal_wq = alloc_workqueue("%s-%s", flags,
+                                                ret->max_active, "btrfs",
+                                                name);
+       if (unlikely(!ret->normal_wq)) {
+               kfree(ret);
+               return NULL;
+       }
 
-       /* set to non-zero when this thread is already awake and kicking */
-       int working;
+       INIT_LIST_HEAD(&ret->ordered_list);
+       spin_lock_init(&ret->list_lock);
+       spin_lock_init(&ret->thres_lock);
+       trace_btrfs_workqueue_alloc(ret, name, flags & WQ_HIGHPRI);
+       return ret;
+}
 
-       /* are we currently idle */
-       int idle;
-};
+static inline void
+__btrfs_destroy_workqueue(struct __btrfs_workqueue *wq);
 
-static int __btrfs_start_workers(struct btrfs_workers *workers);
+struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
+                                             int flags,
+                                             int max_active,
+                                             int thresh)
+{
+       struct btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_NOFS);
 
-/*
- * btrfs_start_workers uses kthread_run, which can block waiting for memory
- * for a very long time.  It will actually throttle on page writeback,
- * and so it may not make progress until after our btrfs worker threads
- * process all of the pending work structs in their queue
- *
- * This means we can't use btrfs_start_workers from inside a btrfs worker
- * thread that is used as part of cleaning dirty memory, which pretty much
- * involves all of the worker threads.
- *
- * Instead we have a helper queue who never has more than one thread
- * where we scheduler thread start operations.  This worker_start struct
- * is used to contain the work and hold a pointer to the queue that needs
- * another worker.
- */
-struct worker_start {
-       struct btrfs_work work;
-       struct btrfs_workers *queue;
-};
+       if (unlikely(!ret))
+               return NULL;
 
-static void start_new_worker_func(struct btrfs_work *work)
-{
-       struct worker_start *start;
-       start = container_of(work, struct worker_start, work);
-       __btrfs_start_workers(start->queue);
-       kfree(start);
-}
+       ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI,
+                                             max_active, thresh);
+       if (unlikely(!ret->normal)) {
+               kfree(ret);
+               return NULL;
+       }
 
-/*
- * helper function to move a thread onto the idle list after it
- * has finished some requests.
- */
-static void check_idle_worker(struct btrfs_worker_thread *worker)
-{
-       if (!worker->idle && atomic_read(&worker->num_pending) <
-           worker->workers->idle_thresh / 2) {
-               unsigned long flags;
-               spin_lock_irqsave(&worker->workers->lock, flags);
-               worker->idle = 1;
-
-               /* the list may be empty if the worker is just starting */
-               if (!list_empty(&worker->worker_list) &&
-                   !worker->workers->stopping) {
-                       list_move(&worker->worker_list,
-                                &worker->workers->idle_list);
+       if (flags & WQ_HIGHPRI) {
+               ret->high = __btrfs_alloc_workqueue(name, flags, max_active,
+                                                   thresh);
+               if (unlikely(!ret->high)) {
+                       __btrfs_destroy_workqueue(ret->normal);
+                       kfree(ret);
+                       return NULL;
                }
-               spin_unlock_irqrestore(&worker->workers->lock, flags);
        }
+       return ret;
 }
 
 /*
- * helper function to move a thread off the idle list after new
- * pending work is added.
+ * Hook for threshold which will be called in btrfs_queue_work.
+ * This hook WILL be called in IRQ handler context,
+ * so workqueue_set_max_active MUST NOT be called in this hook
  */
-static void check_busy_worker(struct btrfs_worker_thread *worker)
+static inline void thresh_queue_hook(struct __btrfs_workqueue *wq)
 {
-       if (worker->idle && atomic_read(&worker->num_pending) >=
-           worker->workers->idle_thresh) {
-               unsigned long flags;
-               spin_lock_irqsave(&worker->workers->lock, flags);
-               worker->idle = 0;
-
-               if (!list_empty(&worker->worker_list) &&
-                   !worker->workers->stopping) {
-                       list_move_tail(&worker->worker_list,
-                                     &worker->workers->worker_list);
-               }
-               spin_unlock_irqrestore(&worker->workers->lock, flags);
-       }
+       if (wq->thresh == NO_THRESHOLD)
+               return;
+       atomic_inc(&wq->pending);
 }
 
-static void check_pending_worker_creates(struct btrfs_worker_thread *worker)
+/*
+ * Hook for threshold which will be called before executing the work,
+ * This hook is called in kthread content.
+ * So workqueue_set_max_active is called here.
+ */
+static inline void thresh_exec_hook(struct __btrfs_workqueue *wq)
 {
-       struct btrfs_workers *workers = worker->workers;
-       struct worker_start *start;
-       unsigned long flags;
+       int new_max_active;
+       long pending;
+       int need_change = 0;
 
-       rmb();
-       if (!workers->atomic_start_pending)
+       if (wq->thresh == NO_THRESHOLD)
                return;
 
-       start = kzalloc(sizeof(*start), GFP_NOFS);
-       if (!start)
-               return;
-
-       start->work.func = start_new_worker_func;
-       start->queue = workers;
-
-       spin_lock_irqsave(&workers->lock, flags);
-       if (!workers->atomic_start_pending)
-               goto out;
-
-       workers->atomic_start_pending = 0;
-       if (workers->num_workers + workers->num_workers_starting >=
-           workers->max_workers)
-               goto out;
-
-       workers->num_workers_starting += 1;
-       spin_unlock_irqrestore(&workers->lock, flags);
-       btrfs_queue_worker(workers->atomic_worker_start, &start->work);
-       return;
+       atomic_dec(&wq->pending);
+       spin_lock(&wq->thres_lock);
+       /*
+        * Use wq->count to limit the calling frequency of
+        * workqueue_set_max_active.
+        */
+       wq->count++;
+       wq->count %= (wq->thresh / 4);
+       if (!wq->count)
+               goto  out;
+       new_max_active = wq->current_max;
 
+       /*
+        * pending may be changed later, but it's OK since we really
+        * don't need it so accurate to calculate new_max_active.
+        */
+       pending = atomic_read(&wq->pending);
+       if (pending > wq->thresh)
+               new_max_active++;
+       if (pending < wq->thresh / 2)
+               new_max_active--;
+       new_max_active = clamp_val(new_max_active, 1, wq->max_active);
+       if (new_max_active != wq->current_max)  {
+               need_change = 1;
+               wq->current_max = new_max_active;
+       }
 out:
-       kfree(start);
-       spin_unlock_irqrestore(&workers->lock, flags);
+       spin_unlock(&wq->thres_lock);
+
+       if (need_change) {
+               workqueue_set_max_active(wq->normal_wq, wq->current_max);
+       }
 }
 
-static noinline void run_ordered_completions(struct btrfs_workers *workers,
-                                           struct btrfs_work *work)
+static void run_ordered_work(struct __btrfs_workqueue *wq)
 {
-       if (!workers->ordered)
-               return;
-
-       set_bit(WORK_DONE_BIT, &work->flags);
-
-       spin_lock(&workers->order_lock);
+       struct list_head *list = &wq->ordered_list;
+       struct btrfs_work *work;
+       spinlock_t *lock = &wq->list_lock;
+       unsigned long flags;
 
        while (1) {
-               if (!list_empty(&workers->prio_order_list)) {
-                       work = list_entry(workers->prio_order_list.next,
-                                         struct btrfs_work, order_list);
-               } else if (!list_empty(&workers->order_list)) {
-                       work = list_entry(workers->order_list.next,
-                                         struct btrfs_work, order_list);
-               } else {
+               spin_lock_irqsave(lock, flags);
+               if (list_empty(list))
                        break;
-               }
+               work = list_entry(list->next, struct btrfs_work,
+                                 ordered_list);
                if (!test_bit(WORK_DONE_BIT, &work->flags))
                        break;
 
-               /* we are going to call the ordered done function, but
+               /*
+                * we are going to call the ordered done function, but
                 * we leave the work item on the list as a barrier so
                 * that later work items that are done don't have their
                 * functions called before this one returns
                 */
                if (test_and_set_bit(WORK_ORDER_DONE_BIT, &work->flags))
                        break;
-
-               spin_unlock(&workers->order_lock);
-
+               trace_btrfs_ordered_sched(work);
+               spin_unlock_irqrestore(lock, flags);
                work->ordered_func(work);
 
                /* now take the lock again and drop our item from the list */
-               spin_lock(&workers->order_lock);
-               list_del(&work->order_list);
-               spin_unlock(&workers->order_lock);
+               spin_lock_irqsave(lock, flags);
+               list_del(&work->ordered_list);
+               spin_unlock_irqrestore(lock, flags);
 
                /*
                 * we don't want to call the ordered free functions
                 * with the lock held though
                 */
                work->ordered_free(work);
-               spin_lock(&workers->order_lock);
-       }
-
-       spin_unlock(&workers->order_lock);
-}
-
-static void put_worker(struct btrfs_worker_thread *worker)
-{
-       if (atomic_dec_and_test(&worker->refs))
-               kfree(worker);
-}
-
-static int try_worker_shutdown(struct btrfs_worker_thread *worker)
-{
-       int freeit = 0;
-
-       spin_lock_irq(&worker->lock);
-       spin_lock(&worker->workers->lock);
-       if (worker->workers->num_workers > 1 &&
-           worker->idle &&
-           !worker->working &&
-           !list_empty(&worker->worker_list) &&
-           list_empty(&worker->prio_pending) &&
-           list_empty(&worker->pending) &&
-           atomic_read(&worker->num_pending) == 0) {
-               freeit = 1;
-               list_del_init(&worker->worker_list);
-               worker->workers->num_workers--;
+               trace_btrfs_all_work_done(work);
        }
-       spin_unlock(&worker->workers->lock);
-       spin_unlock_irq(&worker->lock);
-
-       if (freeit)
-               put_worker(worker);
-       return freeit;
+       spin_unlock_irqrestore(lock, flags);
 }
 
-static struct btrfs_work *get_next_work(struct btrfs_worker_thread *worker,
-                                       struct list_head *prio_head,
-                                       struct list_head *head)
-{
-       struct btrfs_work *work = NULL;
-       struct list_head *cur = NULL;
-
-       if (!list_empty(prio_head))
-               cur = prio_head->next;
-
-       smp_mb();
-       if (!list_empty(&worker->prio_pending))
-               goto refill;
-
-       if (!list_empty(head))
-               cur = head->next;
-
-       if (cur)
-               goto out;
-
-refill:
-       spin_lock_irq(&worker->lock);
-       list_splice_tail_init(&worker->prio_pending, prio_head);
-       list_splice_tail_init(&worker->pending, head);
-
-       if (!list_empty(prio_head))
-               cur = prio_head->next;
-       else if (!list_empty(head))
-               cur = head->next;
-       spin_unlock_irq(&worker->lock);
-
-       if (!cur)
-               goto out_fail;
-
-out:
-       work = list_entry(cur, struct btrfs_work, list);
-
-out_fail:
-       return work;
-}
-
-/*
- * main loop for servicing work items
- */
-static int worker_loop(void *arg)
+static void normal_work_helper(struct work_struct *arg)
 {
-       struct btrfs_worker_thread *worker = arg;
-       struct list_head head;
-       struct list_head prio_head;
        struct btrfs_work *work;
+       struct __btrfs_workqueue *wq;
+       int need_order = 0;
 
-       INIT_LIST_HEAD(&head);
-       INIT_LIST_HEAD(&prio_head);
-
-       do {
-again:
-               while (1) {
-
-
-                       work = get_next_work(worker, &prio_head, &head);
-                       if (!work)
-                               break;
-
-                       list_del(&work->list);
-                       clear_bit(WORK_QUEUED_BIT, &work->flags);
-
-                       work->worker = worker;
-
-                       work->func(work);
-
-                       atomic_dec(&worker->num_pending);
-                       /*
-                        * unless this is an ordered work queue,
-                        * 'work' was probably freed by func above.
-                        */
-                       run_ordered_completions(worker->workers, work);
-
-                       check_pending_worker_creates(worker);
-                       cond_resched();
-               }
-
-               spin_lock_irq(&worker->lock);
-               check_idle_worker(worker);
-
-               if (freezing(current)) {
-                       worker->working = 0;
-                       spin_unlock_irq(&worker->lock);
-                       try_to_freeze();
-               } else {
-                       spin_unlock_irq(&worker->lock);
-                       if (!kthread_should_stop()) {
-                               cpu_relax();
-                               /*
-                                * we've dropped the lock, did someone else
-                                * jump_in?
-                                */
-                               smp_mb();
-                               if (!list_empty(&worker->pending) ||
-                                   !list_empty(&worker->prio_pending))
-                                       continue;
-
-                               /*
-                                * this short schedule allows more work to
-                                * come in without the queue functions
-                                * needing to go through wake_up_process()
-                                *
-                                * worker->working is still 1, so nobody
-                                * is going to try and wake us up
-                                */
-                               schedule_timeout(1);
-                               smp_mb();
-                               if (!list_empty(&worker->pending) ||
-                                   !list_empty(&worker->prio_pending))
-                                       continue;
-
-                               if (kthread_should_stop())
-                                       break;
-
-                               /* still no more work?, sleep for real */
-                               spin_lock_irq(&worker->lock);
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               if (!list_empty(&worker->pending) ||
-                                   !list_empty(&worker->prio_pending)) {
-                                       spin_unlock_irq(&worker->lock);
-                                       set_current_state(TASK_RUNNING);
-                                       goto again;
-                               }
-
-                               /*
-                                * this makes sure we get a wakeup when someone
-                                * adds something new to the queue
-                                */
-                               worker->working = 0;
-                               spin_unlock_irq(&worker->lock);
-
-                               if (!kthread_should_stop()) {
-                                       schedule_timeout(HZ * 120);
-                                       if (!worker->working &&
-                                           try_worker_shutdown(worker)) {
-                                               return 0;
-                                       }
-                               }
-                       }
-                       __set_current_state(TASK_RUNNING);
-               }
-       } while (!kthread_should_stop());
-       return 0;
-}
-
-/*
- * this will wait for all the worker threads to shutdown
- */
-void btrfs_stop_workers(struct btrfs_workers *workers)
-{
-       struct list_head *cur;
-       struct btrfs_worker_thread *worker;
-       int can_stop;
-
-       spin_lock_irq(&workers->lock);
-       workers->stopping = 1;
-       list_splice_init(&workers->idle_list, &workers->worker_list);
-       while (!list_empty(&workers->worker_list)) {
-               cur = workers->worker_list.next;
-               worker = list_entry(cur, struct btrfs_worker_thread,
-                                   worker_list);
-
-               atomic_inc(&worker->refs);
-               workers->num_workers -= 1;
-               if (!list_empty(&worker->worker_list)) {
-                       list_del_init(&worker->worker_list);
-                       put_worker(worker);
-                       can_stop = 1;
-               } else
-                       can_stop = 0;
-               spin_unlock_irq(&workers->lock);
-               if (can_stop)
-                       kthread_stop(worker->task);
-               spin_lock_irq(&workers->lock);
-               put_worker(worker);
+       work = container_of(arg, struct btrfs_work, normal_work);
+       /*
+        * We should not touch things inside work in the following cases:
+        * 1) after work->func() if it has no ordered_free
+        *    Since the struct is freed in work->func().
+        * 2) after setting WORK_DONE_BIT
+        *    The work may be freed in other threads almost instantly.
+        * So we save the needed things here.
+        */
+       if (work->ordered_func)
+               need_order = 1;
+       wq = work->wq;
+
+       trace_btrfs_work_sched(work);
+       thresh_exec_hook(wq);
+       work->func(work);
+       if (need_order) {
+               set_bit(WORK_DONE_BIT, &work->flags);
+               run_ordered_work(wq);
        }
-       spin_unlock_irq(&workers->lock);
+       if (!need_order)
+               trace_btrfs_all_work_done(work);
 }
 
-/*
- * simple init on struct btrfs_workers
- */
-void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
-                       struct btrfs_workers *async_helper)
+void btrfs_init_work(struct btrfs_work *work,
+                    btrfs_func_t func,
+                    btrfs_func_t ordered_func,
+                    btrfs_func_t ordered_free)
 {
-       workers->num_workers = 0;
-       workers->num_workers_starting = 0;
-       INIT_LIST_HEAD(&workers->worker_list);
-       INIT_LIST_HEAD(&workers->idle_list);
-       INIT_LIST_HEAD(&workers->order_list);
-       INIT_LIST_HEAD(&workers->prio_order_list);
-       spin_lock_init(&workers->lock);
-       spin_lock_init(&workers->order_lock);
-       workers->max_workers = max;
-       workers->idle_thresh = 32;
-       workers->name = name;
-       workers->ordered = 0;
-       workers->atomic_start_pending = 0;
-       workers->atomic_worker_start = async_helper;
-       workers->stopping = 0;
+       work->func = func;
+       work->ordered_func = ordered_func;
+       work->ordered_free = ordered_free;
+       INIT_WORK(&work->normal_work, normal_work_helper);
+       INIT_LIST_HEAD(&work->ordered_list);
+       work->flags = 0;
 }
 
-/*
- * starts new worker threads.  This does not enforce the max worker
- * count in case you need to temporarily go past it.
- */
-static int __btrfs_start_workers(struct btrfs_workers *workers)
+static inline void __btrfs_queue_work(struct __btrfs_workqueue *wq,
+                                     struct btrfs_work *work)
 {
-       struct btrfs_worker_thread *worker;
-       int ret = 0;
-
-       worker = kzalloc(sizeof(*worker), GFP_NOFS);
-       if (!worker) {
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       INIT_LIST_HEAD(&worker->pending);
-       INIT_LIST_HEAD(&worker->prio_pending);
-       INIT_LIST_HEAD(&worker->worker_list);
-       spin_lock_init(&worker->lock);
-
-       atomic_set(&worker->num_pending, 0);
-       atomic_set(&worker->refs, 1);
-       worker->workers = workers;
-       worker->task = kthread_create(worker_loop, worker,
-                                     "btrfs-%s-%d", workers->name,
-                                     workers->num_workers + 1);
-       if (IS_ERR(worker->task)) {
-               ret = PTR_ERR(worker->task);
-               goto fail;
-       }
+       unsigned long flags;
 
-       spin_lock_irq(&workers->lock);
-       if (workers->stopping) {
-               spin_unlock_irq(&workers->lock);
-               ret = -EINVAL;
-               goto fail_kthread;
+       work->wq = wq;
+       thresh_queue_hook(wq);
+       if (work->ordered_func) {
+               spin_lock_irqsave(&wq->list_lock, flags);
+               list_add_tail(&work->ordered_list, &wq->ordered_list);
+               spin_unlock_irqrestore(&wq->list_lock, flags);
        }
-       list_add_tail(&worker->worker_list, &workers->idle_list);
-       worker->idle = 1;
-       workers->num_workers++;
-       workers->num_workers_starting--;
-       WARN_ON(workers->num_workers_starting < 0);
-       spin_unlock_irq(&workers->lock);
-
-       wake_up_process(worker->task);
-       return 0;
-
-fail_kthread:
-       kthread_stop(worker->task);
-fail:
-       kfree(worker);
-       spin_lock_irq(&workers->lock);
-       workers->num_workers_starting--;
-       spin_unlock_irq(&workers->lock);
-       return ret;
+       queue_work(wq->normal_wq, &work->normal_work);
+       trace_btrfs_work_queued(work);
 }
 
-int btrfs_start_workers(struct btrfs_workers *workers)
+void btrfs_queue_work(struct btrfs_workqueue *wq,
+                     struct btrfs_work *work)
 {
-       spin_lock_irq(&workers->lock);
-       workers->num_workers_starting++;
-       spin_unlock_irq(&workers->lock);
-       return __btrfs_start_workers(workers);
-}
-
-/*
- * run through the list and find a worker thread that doesn't have a lot
- * to do right now.  This can return null if we aren't yet at the thread
- * count limit and all of the threads are busy.
- */
-static struct btrfs_worker_thread *next_worker(struct btrfs_workers *workers)
-{
-       struct btrfs_worker_thread *worker;
-       struct list_head *next;
-       int enforce_min;
-
-       enforce_min = (workers->num_workers + workers->num_workers_starting) <
-               workers->max_workers;
-
-       /*
-        * if we find an idle thread, don't move it to the end of the
-        * idle list.  This improves the chance that the next submission
-        * will reuse the same thread, and maybe catch it while it is still
-        * working
-        */
-       if (!list_empty(&workers->idle_list)) {
-               next = workers->idle_list.next;
-               worker = list_entry(next, struct btrfs_worker_thread,
-                                   worker_list);
-               return worker;
-       }
-       if (enforce_min || list_empty(&workers->worker_list))
-               return NULL;
-
-       /*
-        * if we pick a busy task, move the task to the end of the list.
-        * hopefully this will keep things somewhat evenly balanced.
-        * Do the move in batches based on the sequence number.  This groups
-        * requests submitted at roughly the same time onto the same worker.
-        */
-       next = workers->worker_list.next;
-       worker = list_entry(next, struct btrfs_worker_thread, worker_list);
-       worker->sequence++;
+       struct __btrfs_workqueue *dest_wq;
 
-       if (worker->sequence % workers->idle_thresh == 0)
-               list_move_tail(next, &workers->worker_list);
-       return worker;
+       if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags) && wq->high)
+               dest_wq = wq->high;
+       else
+               dest_wq = wq->normal;
+       __btrfs_queue_work(dest_wq, work);
 }
 
-/*
- * selects a worker thread to take the next job.  This will either find
- * an idle worker, start a new worker up to the max count, or just return
- * one of the existing busy workers.
- */
-static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers)
+static inline void
+__btrfs_destroy_workqueue(struct __btrfs_workqueue *wq)
 {
-       struct btrfs_worker_thread *worker;
-       unsigned long flags;
-       struct list_head *fallback;
-       int ret;
-
-       spin_lock_irqsave(&workers->lock, flags);
-again:
-       worker = next_worker(workers);
-
-       if (!worker) {
-               if (workers->num_workers + workers->num_workers_starting >=
-                   workers->max_workers) {
-                       goto fallback;
-               } else if (workers->atomic_worker_start) {
-                       workers->atomic_start_pending = 1;
-                       goto fallback;
-               } else {
-                       workers->num_workers_starting++;
-                       spin_unlock_irqrestore(&workers->lock, flags);
-                       /* we're below the limit, start another worker */
-                       ret = __btrfs_start_workers(workers);
-                       spin_lock_irqsave(&workers->lock, flags);
-                       if (ret)
-                               goto fallback;
-                       goto again;
-               }
-       }
-       goto found;
-
-fallback:
-       fallback = NULL;
-       /*
-        * we have failed to find any workers, just
-        * return the first one we can find.
-        */
-       if (!list_empty(&workers->worker_list))
-               fallback = workers->worker_list.next;
-       if (!list_empty(&workers->idle_list))
-               fallback = workers->idle_list.next;
-       BUG_ON(!fallback);
-       worker = list_entry(fallback,
-                 struct btrfs_worker_thread, worker_list);
-found:
-       /*
-        * this makes sure the worker doesn't exit before it is placed
-        * onto a busy/idle list
-        */
-       atomic_inc(&worker->num_pending);
-       spin_unlock_irqrestore(&workers->lock, flags);
-       return worker;
+       destroy_workqueue(wq->normal_wq);
+       trace_btrfs_workqueue_destroy(wq);
+       kfree(wq);
 }
 
-/*
- * btrfs_requeue_work just puts the work item back on the tail of the list
- * it was taken from.  It is intended for use with long running work functions
- * that make some progress and want to give the cpu up for others.
- */
-void btrfs_requeue_work(struct btrfs_work *work)
+void btrfs_destroy_workqueue(struct btrfs_workqueue *wq)
 {
-       struct btrfs_worker_thread *worker = work->worker;
-       unsigned long flags;
-       int wake = 0;
-
-       if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
+       if (!wq)
                return;
-
-       spin_lock_irqsave(&worker->lock, flags);
-       if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags))
-               list_add_tail(&work->list, &worker->prio_pending);
-       else
-               list_add_tail(&work->list, &worker->pending);
-       atomic_inc(&worker->num_pending);
-
-       /* by definition we're busy, take ourselves off the idle
-        * list
-        */
-       if (worker->idle) {
-               spin_lock(&worker->workers->lock);
-               worker->idle = 0;
-               list_move_tail(&worker->worker_list,
-                             &worker->workers->worker_list);
-               spin_unlock(&worker->workers->lock);
-       }
-       if (!worker->working) {
-               wake = 1;
-               worker->working = 1;
-       }
-
-       if (wake)
-               wake_up_process(worker->task);
-       spin_unlock_irqrestore(&worker->lock, flags);
+       if (wq->high)
+               __btrfs_destroy_workqueue(wq->high);
+       __btrfs_destroy_workqueue(wq->normal);
+       kfree(wq);
 }
 
-void btrfs_set_work_high_prio(struct btrfs_work *work)
+void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max)
 {
-       set_bit(WORK_HIGH_PRIO_BIT, &work->flags);
+       wq->normal->max_active = max;
+       if (wq->high)
+               wq->high->max_active = max;
 }
 
-/*
- * places a struct btrfs_work into the pending queue of one of the kthreads
- */
-void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
+void btrfs_set_work_high_priority(struct btrfs_work *work)
 {
-       struct btrfs_worker_thread *worker;
-       unsigned long flags;
-       int wake = 0;
-
-       /* don't requeue something already on a list */
-       if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
-               return;
-
-       worker = find_worker(workers);
-       if (workers->ordered) {
-               /*
-                * you're not allowed to do ordered queues from an
-                * interrupt handler
-                */
-               spin_lock(&workers->order_lock);
-               if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags)) {
-                       list_add_tail(&work->order_list,
-                                     &workers->prio_order_list);
-               } else {
-                       list_add_tail(&work->order_list, &workers->order_list);
-               }
-               spin_unlock(&workers->order_lock);
-       } else {
-               INIT_LIST_HEAD(&work->order_list);
-       }
-
-       spin_lock_irqsave(&worker->lock, flags);
-
-       if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags))
-               list_add_tail(&work->list, &worker->prio_pending);
-       else
-               list_add_tail(&work->list, &worker->pending);
-       check_busy_worker(worker);
-
-       /*
-        * avoid calling into wake_up_process if this thread has already
-        * been kicked
-        */
-       if (!worker->working)
-               wake = 1;
-       worker->working = 1;
-
-       if (wake)
-               wake_up_process(worker->task);
-       spin_unlock_irqrestore(&worker->lock, flags);
+       set_bit(WORK_HIGH_PRIO_BIT, &work->flags);
 }
index 1f26792683edf195b48db80992c05acae6fd71f0..9c6b66d15fb0a07cd0a6a4656d6865848aa5c8ea 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007 Oracle.  All rights reserved.
+ * Copyright (C) 2014 Fujitsu.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
 #ifndef __BTRFS_ASYNC_THREAD_
 #define __BTRFS_ASYNC_THREAD_
 
-struct btrfs_worker_thread;
+struct btrfs_workqueue;
+/* Internal use only */
+struct __btrfs_workqueue;
+struct btrfs_work;
+typedef void (*btrfs_func_t)(struct btrfs_work *arg);
 
-/*
- * This is similar to a workqueue, but it is meant to spread the operations
- * across all available cpus instead of just the CPU that was used to
- * queue the work.  There is also some batching introduced to try and
- * cut down on context switches.
- *
- * By default threads are added on demand up to 2 * the number of cpus.
- * Changing struct btrfs_workers->max_workers is one way to prevent
- * demand creation of kthreads.
- *
- * the basic model of these worker threads is to embed a btrfs_work
- * structure in your own data struct, and use container_of in a
- * work function to get back to your data struct.
- */
 struct btrfs_work {
-       /*
-        * func should be set to the function you want called
-        * your work struct is passed as the only arg
-        *
-        * ordered_func must be set for work sent to an ordered work queue,
-        * and it is called to complete a given work item in the same
-        * order they were sent to the queue.
-        */
-       void (*func)(struct btrfs_work *work);
-       void (*ordered_func)(struct btrfs_work *work);
-       void (*ordered_free)(struct btrfs_work *work);
-
-       /*
-        * flags should be set to zero.  It is used to make sure the
-        * struct is only inserted once into the list.
-        */
+       btrfs_func_t func;
+       btrfs_func_t ordered_func;
+       btrfs_func_t ordered_free;
+
+       /* Don't touch things below */
+       struct work_struct normal_work;
+       struct list_head ordered_list;
+       struct __btrfs_workqueue *wq;
        unsigned long flags;
-
-       /* don't touch these */
-       struct btrfs_worker_thread *worker;
-       struct list_head list;
-       struct list_head order_list;
-};
-
-struct btrfs_workers {
-       /* current number of running workers */
-       int num_workers;
-
-       int num_workers_starting;
-
-       /* max number of workers allowed.  changed by btrfs_start_workers */
-       int max_workers;
-
-       /* once a worker has this many requests or fewer, it is idle */
-       int idle_thresh;
-
-       /* force completions in the order they were queued */
-       int ordered;
-
-       /* more workers required, but in an interrupt handler */
-       int atomic_start_pending;
-
-       /*
-        * are we allowed to sleep while starting workers or are we required
-        * to start them at a later time?  If we can't sleep, this indicates
-        * which queue we need to use to schedule thread creation.
-        */
-       struct btrfs_workers *atomic_worker_start;
-
-       /* list with all the work threads.  The workers on the idle thread
-        * may be actively servicing jobs, but they haven't yet hit the
-        * idle thresh limit above.
-        */
-       struct list_head worker_list;
-       struct list_head idle_list;
-
-       /*
-        * when operating in ordered mode, this maintains the list
-        * of work items waiting for completion
-        */
-       struct list_head order_list;
-       struct list_head prio_order_list;
-
-       /* lock for finding the next worker thread to queue on */
-       spinlock_t lock;
-
-       /* lock for the ordered lists */
-       spinlock_t order_lock;
-
-       /* extra name for this worker, used for current->name */
-       char *name;
-
-       int stopping;
 };
 
-void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work);
-int btrfs_start_workers(struct btrfs_workers *workers);
-void btrfs_stop_workers(struct btrfs_workers *workers);
-void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
-                       struct btrfs_workers *async_starter);
-void btrfs_requeue_work(struct btrfs_work *work);
-void btrfs_set_work_high_prio(struct btrfs_work *work);
+struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
+                                             int flags,
+                                             int max_active,
+                                             int thresh);
+void btrfs_init_work(struct btrfs_work *work,
+                    btrfs_func_t func,
+                    btrfs_func_t ordered_func,
+                    btrfs_func_t ordered_free);
+void btrfs_queue_work(struct btrfs_workqueue *wq,
+                     struct btrfs_work *work);
+void btrfs_destroy_workqueue(struct btrfs_workqueue *wq);
+void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max);
+void btrfs_set_work_high_priority(struct btrfs_work *work);
 #endif
index aded3ef3d3d4abfa6d61fa078a51e64e4b80be65..aad7201ad11bb767cbe760df38f88572fe788cf5 100644 (file)
@@ -220,7 +220,8 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
 
 static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
                           struct ulist *parents, struct __prelim_ref *ref,
-                          int level, u64 time_seq, const u64 *extent_item_pos)
+                          int level, u64 time_seq, const u64 *extent_item_pos,
+                          u64 total_refs)
 {
        int ret = 0;
        int slot;
@@ -249,7 +250,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
        if (path->slots[0] >= btrfs_header_nritems(path->nodes[0]))
                ret = btrfs_next_old_leaf(root, path, time_seq);
 
-       while (!ret && count < ref->count) {
+       while (!ret && count < total_refs) {
                eb = path->nodes[0];
                slot = path->slots[0];
 
@@ -306,7 +307,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
                                  struct btrfs_path *path, u64 time_seq,
                                  struct __prelim_ref *ref,
                                  struct ulist *parents,
-                                 const u64 *extent_item_pos)
+                                 const u64 *extent_item_pos, u64 total_refs)
 {
        struct btrfs_root *root;
        struct btrfs_key root_key;
@@ -361,7 +362,7 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
        }
 
        ret = add_all_parents(root, path, parents, ref, level, time_seq,
-                             extent_item_pos);
+                             extent_item_pos, total_refs);
 out:
        path->lowest_level = 0;
        btrfs_release_path(path);
@@ -374,7 +375,7 @@ out:
 static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
                                   struct btrfs_path *path, u64 time_seq,
                                   struct list_head *head,
-                                  const u64 *extent_item_pos)
+                                  const u64 *extent_item_pos, u64 total_refs)
 {
        int err;
        int ret = 0;
@@ -400,7 +401,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
                if (ref->count == 0)
                        continue;
                err = __resolve_indirect_ref(fs_info, path, time_seq, ref,
-                                            parents, extent_item_pos);
+                                            parents, extent_item_pos,
+                                            total_refs);
                /*
                 * we can only tolerate ENOENT,otherwise,we should catch error
                 * and return directly.
@@ -557,7 +559,7 @@ static void __merge_refs(struct list_head *head, int mode)
  * smaller or equal that seq to the list
  */
 static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
-                             struct list_head *prefs)
+                             struct list_head *prefs, u64 *total_refs)
 {
        struct btrfs_delayed_extent_op *extent_op = head->extent_op;
        struct rb_node *n = &head->node.rb_node;
@@ -593,6 +595,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
                default:
                        BUG_ON(1);
                }
+               *total_refs += (node->ref_mod * sgn);
                switch (node->type) {
                case BTRFS_TREE_BLOCK_REF_KEY: {
                        struct btrfs_delayed_tree_ref *ref;
@@ -653,7 +656,8 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
  */
 static int __add_inline_refs(struct btrfs_fs_info *fs_info,
                             struct btrfs_path *path, u64 bytenr,
-                            int *info_level, struct list_head *prefs)
+                            int *info_level, struct list_head *prefs,
+                            u64 *total_refs)
 {
        int ret = 0;
        int slot;
@@ -677,6 +681,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
 
        ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
        flags = btrfs_extent_flags(leaf, ei);
+       *total_refs += btrfs_extent_refs(leaf, ei);
        btrfs_item_key_to_cpu(leaf, &found_key, slot);
 
        ptr = (unsigned long)(ei + 1);
@@ -859,6 +864,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
        struct list_head prefs;
        struct __prelim_ref *ref;
        struct extent_inode_elem *eie = NULL;
+       u64 total_refs = 0;
 
        INIT_LIST_HEAD(&prefs);
        INIT_LIST_HEAD(&prefs_delayed);
@@ -873,8 +879,10 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
-       if (!trans)
+       if (!trans) {
                path->search_commit_root = 1;
+               path->skip_locking = 1;
+       }
 
        /*
         * grab both a lock on the path and a lock on the delayed ref head.
@@ -915,7 +923,7 @@ again:
                        }
                        spin_unlock(&delayed_refs->lock);
                        ret = __add_delayed_refs(head, time_seq,
-                                                &prefs_delayed);
+                                                &prefs_delayed, &total_refs);
                        mutex_unlock(&head->mutex);
                        if (ret)
                                goto out;
@@ -936,7 +944,8 @@ again:
                    (key.type == BTRFS_EXTENT_ITEM_KEY ||
                     key.type == BTRFS_METADATA_ITEM_KEY)) {
                        ret = __add_inline_refs(fs_info, path, bytenr,
-                                               &info_level, &prefs);
+                                               &info_level, &prefs,
+                                               &total_refs);
                        if (ret)
                                goto out;
                        ret = __add_keyed_refs(fs_info, path, bytenr,
@@ -956,7 +965,7 @@ again:
        __merge_refs(&prefs, 1);
 
        ret = __resolve_indirect_refs(fs_info, path, time_seq, &prefs,
-                                     extent_item_pos);
+                                     extent_item_pos, total_refs);
        if (ret)
                goto out;
 
@@ -965,7 +974,7 @@ again:
        while (!list_empty(&prefs)) {
                ref = list_first_entry(&prefs, struct __prelim_ref, list);
                WARN_ON(ref->count < 0);
-               if (ref->count && ref->root_id && ref->parent == 0) {
+               if (roots && ref->count && ref->root_id && ref->parent == 0) {
                        /* no parent == root of tree */
                        ret = ulist_add(roots, ref->root_id, 0, GFP_NOFS);
                        if (ret < 0)
@@ -1061,22 +1070,14 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
                                u64 time_seq, struct ulist **leafs,
                                const u64 *extent_item_pos)
 {
-       struct ulist *tmp;
        int ret;
 
-       tmp = ulist_alloc(GFP_NOFS);
-       if (!tmp)
-               return -ENOMEM;
        *leafs = ulist_alloc(GFP_NOFS);
-       if (!*leafs) {
-               ulist_free(tmp);
+       if (!*leafs)
                return -ENOMEM;
-       }
 
        ret = find_parent_nodes(trans, fs_info, bytenr,
-                               time_seq, *leafs, tmp, extent_item_pos);
-       ulist_free(tmp);
-
+                               time_seq, *leafs, NULL, extent_item_pos);
        if (ret < 0 && ret != -ENOENT) {
                free_leaf_list(*leafs);
                return ret;
@@ -1333,38 +1334,13 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
        if (ret < 0)
                return ret;
 
-       while (1) {
-               u32 nritems;
-               if (path->slots[0] == 0) {
-                       btrfs_set_path_blocking(path);
-                       ret = btrfs_prev_leaf(fs_info->extent_root, path);
-                       if (ret != 0) {
-                               if (ret > 0) {
-                                       pr_debug("logical %llu is not within "
-                                                "any extent\n", logical);
-                                       ret = -ENOENT;
-                               }
-                               return ret;
-                       }
-               } else {
-                       path->slots[0]--;
-               }
-               nritems = btrfs_header_nritems(path->nodes[0]);
-               if (nritems == 0) {
-                       pr_debug("logical %llu is not within any extent\n",
-                                logical);
-                       return -ENOENT;
-               }
-               if (path->slots[0] == nritems)
-                       path->slots[0]--;
-
-               btrfs_item_key_to_cpu(path->nodes[0], found_key,
-                                     path->slots[0]);
-               if (found_key->type == BTRFS_EXTENT_ITEM_KEY ||
-                   found_key->type == BTRFS_METADATA_ITEM_KEY)
-                       break;
+       ret = btrfs_previous_extent_item(fs_info->extent_root, path, 0);
+       if (ret) {
+               if (ret > 0)
+                       ret = -ENOENT;
+               return ret;
        }
-
+       btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]);
        if (found_key->type == BTRFS_METADATA_ITEM_KEY)
                size = fs_info->extent_root->leafsize;
        else if (found_key->type == BTRFS_EXTENT_ITEM_KEY)
index 8fed2125689ed39b928800e78cfbf3b720d52a24..c9a24444ec9a317483c4486fb132b6893f57a19d 100644 (file)
@@ -109,14 +109,17 @@ struct btrfs_inode {
        u64 last_trans;
 
        /*
-        * log transid when this inode was last modified
+        * transid that last logged this inode
         */
-       u64 last_sub_trans;
+       u64 logged_trans;
 
        /*
-        * transid that last logged this inode
+        * log transid when this inode was last modified
         */
-       u64 logged_trans;
+       int last_sub_trans;
+
+       /* a local copy of root's last_log_commit */
+       int last_log_commit;
 
        /* total number of bytes pending delalloc, used by stat to calc the
         * real block usage of the file
@@ -155,9 +158,6 @@ struct btrfs_inode {
        /* flags field from the on disk inode */
        u32 flags;
 
-       /* a local copy of root's last_log_commit */
-       unsigned long last_log_commit;
-
        /*
         * Counters to keep track of the number of extent item's we may use due
         * to delalloc and such.  outstanding_extents is the number of extent
index cbd3a7d6fa681acfc0b00cb515fcddbcf8880f49..88d1b1eedc9cd3a9679758dc1d209e0bf88767aa 100644 (file)
@@ -5376,6 +5376,8 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
        int advance_right;
        u64 left_blockptr;
        u64 right_blockptr;
+       u64 left_gen;
+       u64 right_gen;
        u64 left_start_ctransid;
        u64 right_start_ctransid;
        u64 ctransid;
@@ -5640,7 +5642,14 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
                                right_blockptr = btrfs_node_blockptr(
                                                right_path->nodes[right_level],
                                                right_path->slots[right_level]);
-                               if (left_blockptr == right_blockptr) {
+                               left_gen = btrfs_node_ptr_generation(
+                                               left_path->nodes[left_level],
+                                               left_path->slots[left_level]);
+                               right_gen = btrfs_node_ptr_generation(
+                                               right_path->nodes[right_level],
+                                               right_path->slots[right_level]);
+                               if (left_blockptr == right_blockptr &&
+                                   left_gen == right_gen) {
                                        /*
                                         * As we're on a shared block, don't
                                         * allow to go deeper.
index 2c1a42ca519f43a8dd85ce95a24fc6ed0a22d07d..bc96c03dd259836de717f2ccaabc7b9032d33a34 100644 (file)
@@ -351,6 +351,7 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
 #define BTRFS_FS_STATE_ERROR           0
 #define BTRFS_FS_STATE_REMOUNTING      1
 #define BTRFS_FS_STATE_TRANS_ABORTED   2
+#define BTRFS_FS_STATE_DEV_REPLACING   3
 
 /* Super block flags */
 /* Errors detected */
@@ -1489,6 +1490,7 @@ struct btrfs_fs_info {
         */
        struct list_head ordered_roots;
 
+       struct mutex delalloc_root_mutex;
        spinlock_t delalloc_root_lock;
        /* all fs/file tree roots that have delalloc inodes. */
        struct list_head delalloc_roots;
@@ -1503,28 +1505,27 @@ struct btrfs_fs_info {
         * A third pool does submit_bio to avoid deadlocking with the other
         * two
         */
-       struct btrfs_workers generic_worker;
-       struct btrfs_workers workers;
-       struct btrfs_workers delalloc_workers;
-       struct btrfs_workers flush_workers;
-       struct btrfs_workers endio_workers;
-       struct btrfs_workers endio_meta_workers;
-       struct btrfs_workers endio_raid56_workers;
-       struct btrfs_workers rmw_workers;
-       struct btrfs_workers endio_meta_write_workers;
-       struct btrfs_workers endio_write_workers;
-       struct btrfs_workers endio_freespace_worker;
-       struct btrfs_workers submit_workers;
-       struct btrfs_workers caching_workers;
-       struct btrfs_workers readahead_workers;
+       struct btrfs_workqueue *workers;
+       struct btrfs_workqueue *delalloc_workers;
+       struct btrfs_workqueue *flush_workers;
+       struct btrfs_workqueue *endio_workers;
+       struct btrfs_workqueue *endio_meta_workers;
+       struct btrfs_workqueue *endio_raid56_workers;
+       struct btrfs_workqueue *rmw_workers;
+       struct btrfs_workqueue *endio_meta_write_workers;
+       struct btrfs_workqueue *endio_write_workers;
+       struct btrfs_workqueue *endio_freespace_worker;
+       struct btrfs_workqueue *submit_workers;
+       struct btrfs_workqueue *caching_workers;
+       struct btrfs_workqueue *readahead_workers;
 
        /*
         * fixup workers take dirty pages that didn't properly go through
         * the cow mechanism and make them safe to write.  It happens
         * for the sys_munmap function call path
         */
-       struct btrfs_workers fixup_workers;
-       struct btrfs_workers delayed_workers;
+       struct btrfs_workqueue *fixup_workers;
+       struct btrfs_workqueue *delayed_workers;
        struct task_struct *transaction_kthread;
        struct task_struct *cleaner_kthread;
        int thread_pool_size;
@@ -1604,9 +1605,9 @@ struct btrfs_fs_info {
        atomic_t scrub_cancel_req;
        wait_queue_head_t scrub_pause_wait;
        int scrub_workers_refcnt;
-       struct btrfs_workers scrub_workers;
-       struct btrfs_workers scrub_wr_completion_workers;
-       struct btrfs_workers scrub_nocow_workers;
+       struct btrfs_workqueue *scrub_workers;
+       struct btrfs_workqueue *scrub_wr_completion_workers;
+       struct btrfs_workqueue *scrub_nocow_workers;
 
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        u32 check_integrity_print_mask;
@@ -1647,7 +1648,7 @@ struct btrfs_fs_info {
        /* qgroup rescan items */
        struct mutex qgroup_rescan_lock; /* protects the progress item */
        struct btrfs_key qgroup_rescan_progress;
-       struct btrfs_workers qgroup_rescan_workers;
+       struct btrfs_workqueue *qgroup_rescan_workers;
        struct completion qgroup_rescan_completion;
        struct btrfs_work qgroup_rescan_work;
 
@@ -1674,10 +1675,18 @@ struct btrfs_fs_info {
 
        atomic_t mutually_exclusive_operation_running;
 
+       struct percpu_counter bio_counter;
+       wait_queue_head_t replace_wait;
+
        struct semaphore uuid_tree_rescan_sem;
        unsigned int update_uuid_tree_gen:1;
 };
 
+struct btrfs_subvolume_writers {
+       struct percpu_counter   counter;
+       wait_queue_head_t       wait;
+};
+
 /*
  * in ram representation of the tree.  extent_root is used for all allocations
  * and for the extent tree extent_root root.
@@ -1714,11 +1723,15 @@ struct btrfs_root {
        struct mutex log_mutex;
        wait_queue_head_t log_writer_wait;
        wait_queue_head_t log_commit_wait[2];
+       struct list_head log_ctxs[2];
        atomic_t log_writers;
        atomic_t log_commit[2];
        atomic_t log_batch;
-       unsigned long log_transid;
-       unsigned long last_log_commit;
+       int log_transid;
+       /* No matter the commit succeeds or not*/
+       int log_transid_committed;
+       /* Just be updated when the commit succeeds. */
+       int last_log_commit;
        pid_t log_start_pid;
        bool log_multiple_pids;
 
@@ -1793,6 +1806,7 @@ struct btrfs_root {
        spinlock_t root_item_lock;
        atomic_t refs;
 
+       struct mutex delalloc_mutex;
        spinlock_t delalloc_lock;
        /*
         * all of the inodes that have delalloc bytes.  It is possible for
@@ -1802,6 +1816,8 @@ struct btrfs_root {
        struct list_head delalloc_inodes;
        struct list_head delalloc_root;
        u64 nr_delalloc_inodes;
+
+       struct mutex ordered_extent_mutex;
        /*
         * this is used by the balancing code to wait for all the pending
         * ordered extents
@@ -1822,6 +1838,8 @@ struct btrfs_root {
         * manipulation with the read-only status via SUBVOL_SETFLAGS
         */
        int send_in_progress;
+       struct btrfs_subvolume_writers *subv_writers;
+       atomic_t will_be_snapshoted;
 };
 
 struct btrfs_ioctl_defrag_range_args {
@@ -3346,6 +3364,9 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info);
 int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans,
                                         struct btrfs_fs_info *fs_info);
 int __get_raid_index(u64 flags);
+
+int btrfs_start_nocow_write(struct btrfs_root *root);
+void btrfs_end_nocow_write(struct btrfs_root *root);
 /* ctree.c */
 int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
                     int level, int *slot);
@@ -3723,7 +3744,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
                               u32 min_type);
 
 int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
-int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput);
+int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
+                              int nr);
 int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
                              struct extent_state **cached_state);
 int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
@@ -4005,6 +4027,11 @@ int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info,
 int btrfs_scrub_progress(struct btrfs_root *root, u64 devid,
                         struct btrfs_scrub_progress *progress);
 
+/* dev-replace.c */
+void btrfs_bio_counter_inc_blocked(struct btrfs_fs_info *fs_info);
+void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info);
+void btrfs_bio_counter_dec(struct btrfs_fs_info *fs_info);
+
 /* reada.c */
 struct reada_control {
        struct btrfs_root       *root;          /* tree to prefetch */
index 451b00c86f6c0a038ed532f29855009abaa1d8a3..33e561a84013f19bb327939e7860753bd5eaa0bf 100644 (file)
@@ -1392,11 +1392,11 @@ static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
                return -ENOMEM;
 
        async_work->delayed_root = delayed_root;
-       async_work->work.func = btrfs_async_run_delayed_root;
-       async_work->work.flags = 0;
+       btrfs_init_work(&async_work->work, btrfs_async_run_delayed_root,
+                       NULL, NULL);
        async_work->nr = nr;
 
-       btrfs_queue_worker(&root->fs_info->delayed_workers, &async_work->work);
+       btrfs_queue_work(root->fs_info->delayed_workers, &async_work->work);
        return 0;
 }
 
index f3bff89eecf09346e2eb49b4ffeb861f35e33d4b..31299646024d65340b4a8c401a41bdb594402d57 100644 (file)
@@ -199,44 +199,31 @@ static struct btrfs_delayed_ref_head *htree_insert(struct rb_root *root,
  */
 static struct btrfs_delayed_ref_head *
 find_ref_head(struct rb_root *root, u64 bytenr,
-             struct btrfs_delayed_ref_head **last, int return_bigger)
+             int return_bigger)
 {
        struct rb_node *n;
        struct btrfs_delayed_ref_head *entry;
-       int cmp = 0;
 
-again:
        n = root->rb_node;
        entry = NULL;
        while (n) {
                entry = rb_entry(n, struct btrfs_delayed_ref_head, href_node);
-               if (last)
-                       *last = entry;
 
                if (bytenr < entry->node.bytenr)
-                       cmp = -1;
-               else if (bytenr > entry->node.bytenr)
-                       cmp = 1;
-               else
-                       cmp = 0;
-
-               if (cmp < 0)
                        n = n->rb_left;
-               else if (cmp > 0)
+               else if (bytenr > entry->node.bytenr)
                        n = n->rb_right;
                else
                        return entry;
        }
        if (entry && return_bigger) {
-               if (cmp > 0) {
+               if (bytenr > entry->node.bytenr) {
                        n = rb_next(&entry->href_node);
                        if (!n)
                                n = rb_first(root);
                        entry = rb_entry(n, struct btrfs_delayed_ref_head,
                                         href_node);
-                       bytenr = entry->node.bytenr;
-                       return_bigger = 0;
-                       goto again;
+                       return entry;
                }
                return entry;
        }
@@ -415,12 +402,12 @@ btrfs_select_ref_head(struct btrfs_trans_handle *trans)
 
 again:
        start = delayed_refs->run_delayed_start;
-       head = find_ref_head(&delayed_refs->href_root, start, NULL, 1);
+       head = find_ref_head(&delayed_refs->href_root, start, 1);
        if (!head && !loop) {
                delayed_refs->run_delayed_start = 0;
                start = 0;
                loop = true;
-               head = find_ref_head(&delayed_refs->href_root, start, NULL, 1);
+               head = find_ref_head(&delayed_refs->href_root, start, 1);
                if (!head)
                        return NULL;
        } else if (!head && loop) {
@@ -508,6 +495,7 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing,
        ref = btrfs_delayed_node_to_head(update);
        BUG_ON(existing_ref->is_data != ref->is_data);
 
+       spin_lock(&existing_ref->lock);
        if (ref->must_insert_reserved) {
                /* if the extent was freed and then
                 * reallocated before the delayed ref
@@ -549,7 +537,6 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing,
         * only need the lock for this case cause we could be processing it
         * currently, for refs we just added we know we're a-ok.
         */
-       spin_lock(&existing_ref->lock);
        existing->ref_mod += update->ref_mod;
        spin_unlock(&existing_ref->lock);
 }
@@ -898,7 +885,7 @@ btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr)
        struct btrfs_delayed_ref_root *delayed_refs;
 
        delayed_refs = &trans->transaction->delayed_refs;
-       return find_ref_head(&delayed_refs->href_root, bytenr, NULL, 0);
+       return find_ref_head(&delayed_refs->href_root, bytenr, 0);
 }
 
 void btrfs_delayed_ref_exit(void)
index 564c92638b20a8d4929a920eb843c4f4fe71745b..9f2290509acaeb105e3097831be8401b9a659dbe 100644 (file)
@@ -431,6 +431,35 @@ leave_no_lock:
        return ret;
 }
 
+/*
+ * blocked until all flighting bios are finished.
+ */
+static void btrfs_rm_dev_replace_blocked(struct btrfs_fs_info *fs_info)
+{
+       s64 writers;
+       DEFINE_WAIT(wait);
+
+       set_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state);
+       do {
+               prepare_to_wait(&fs_info->replace_wait, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               writers = percpu_counter_sum(&fs_info->bio_counter);
+               if (writers)
+                       schedule();
+               finish_wait(&fs_info->replace_wait, &wait);
+       } while (writers);
+}
+
+/*
+ * we have removed target device, it is safe to allow new bios request.
+ */
+static void btrfs_rm_dev_replace_unblocked(struct btrfs_fs_info *fs_info)
+{
+       clear_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state);
+       if (waitqueue_active(&fs_info->replace_wait))
+               wake_up(&fs_info->replace_wait);
+}
+
 static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
                                       int scrub_ret)
 {
@@ -458,17 +487,11 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
        src_device = dev_replace->srcdev;
        btrfs_dev_replace_unlock(dev_replace);
 
-       /* replace old device with new one in mapping tree */
-       if (!scrub_ret)
-               btrfs_dev_replace_update_device_in_mapping_tree(fs_info,
-                                                               src_device,
-                                                               tgt_device);
-
        /*
         * flush all outstanding I/O and inode extent mappings before the
         * copy operation is declared as being finished
         */
-       ret = btrfs_start_delalloc_roots(root->fs_info, 0);
+       ret = btrfs_start_delalloc_roots(root->fs_info, 0, -1);
        if (ret) {
                mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
                return ret;
@@ -484,6 +507,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
        WARN_ON(ret);
 
        /* keep away write_all_supers() during the finishing procedure */
+       mutex_lock(&root->fs_info->chunk_mutex);
        mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
        btrfs_dev_replace_lock(dev_replace);
        dev_replace->replace_state =
@@ -494,7 +518,12 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
        dev_replace->time_stopped = get_seconds();
        dev_replace->item_needs_writeback = 1;
 
-       if (scrub_ret) {
+       /* replace old device with new one in mapping tree */
+       if (!scrub_ret) {
+               btrfs_dev_replace_update_device_in_mapping_tree(fs_info,
+                                                               src_device,
+                                                               tgt_device);
+       } else {
                printk_in_rcu(KERN_ERR
                              "BTRFS: btrfs_scrub_dev(%s, %llu, %s) failed %d\n",
                              src_device->missing ? "<missing disk>" :
@@ -503,6 +532,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
                              rcu_str_deref(tgt_device->name), scrub_ret);
                btrfs_dev_replace_unlock(dev_replace);
                mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+               mutex_unlock(&root->fs_info->chunk_mutex);
                if (tgt_device)
                        btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device);
                mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
@@ -532,8 +562,12 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
                fs_info->fs_devices->latest_bdev = tgt_device->bdev;
        list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
 
+       btrfs_rm_dev_replace_blocked(fs_info);
+
        btrfs_rm_dev_replace_srcdev(fs_info, src_device);
 
+       btrfs_rm_dev_replace_unblocked(fs_info);
+
        /*
         * this is again a consistent state where no dev_replace procedure
         * is running, the target device is part of the filesystem, the
@@ -543,6 +577,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
         */
        btrfs_dev_replace_unlock(dev_replace);
        mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+       mutex_unlock(&root->fs_info->chunk_mutex);
 
        /* write back the superblocks */
        trans = btrfs_start_transaction(root, 0);
@@ -862,3 +897,31 @@ void btrfs_dev_replace_unlock(struct btrfs_dev_replace *dev_replace)
                mutex_unlock(&dev_replace->lock_management_lock);
        }
 }
+
+void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info)
+{
+       percpu_counter_inc(&fs_info->bio_counter);
+}
+
+void btrfs_bio_counter_dec(struct btrfs_fs_info *fs_info)
+{
+       percpu_counter_dec(&fs_info->bio_counter);
+
+       if (waitqueue_active(&fs_info->replace_wait))
+               wake_up(&fs_info->replace_wait);
+}
+
+void btrfs_bio_counter_inc_blocked(struct btrfs_fs_info *fs_info)
+{
+       DEFINE_WAIT(wait);
+again:
+       percpu_counter_inc(&fs_info->bio_counter);
+       if (test_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state)) {
+               btrfs_bio_counter_dec(fs_info);
+               wait_event(fs_info->replace_wait,
+                          !test_bit(BTRFS_FS_STATE_DEV_REPLACING,
+                                    &fs_info->fs_state));
+               goto again;
+       }
+
+}
index 81ea55314b1ff0f61d2691f786a481889cd831ac..bd0f752b797ba3c3f9f5eedb9186b304b0ac1433 100644 (file)
@@ -678,32 +678,31 @@ static void end_workqueue_bio(struct bio *bio, int err)
 
        fs_info = end_io_wq->info;
        end_io_wq->error = err;
-       end_io_wq->work.func = end_workqueue_fn;
-       end_io_wq->work.flags = 0;
+       btrfs_init_work(&end_io_wq->work, end_workqueue_fn, NULL, NULL);
 
        if (bio->bi_rw & REQ_WRITE) {
                if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA)
-                       btrfs_queue_worker(&fs_info->endio_meta_write_workers,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_meta_write_workers,
+                                        &end_io_wq->work);
                else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_FREE_SPACE)
-                       btrfs_queue_worker(&fs_info->endio_freespace_worker,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_freespace_worker,
+                                        &end_io_wq->work);
                else if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56)
-                       btrfs_queue_worker(&fs_info->endio_raid56_workers,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_raid56_workers,
+                                        &end_io_wq->work);
                else
-                       btrfs_queue_worker(&fs_info->endio_write_workers,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_write_workers,
+                                        &end_io_wq->work);
        } else {
                if (end_io_wq->metadata == BTRFS_WQ_ENDIO_RAID56)
-                       btrfs_queue_worker(&fs_info->endio_raid56_workers,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_raid56_workers,
+                                        &end_io_wq->work);
                else if (end_io_wq->metadata)
-                       btrfs_queue_worker(&fs_info->endio_meta_workers,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_meta_workers,
+                                        &end_io_wq->work);
                else
-                       btrfs_queue_worker(&fs_info->endio_workers,
-                                          &end_io_wq->work);
+                       btrfs_queue_work(fs_info->endio_workers,
+                                        &end_io_wq->work);
        }
 }
 
@@ -738,7 +737,7 @@ int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
 unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info)
 {
        unsigned long limit = min_t(unsigned long,
-                                   info->workers.max_workers,
+                                   info->thread_pool_size,
                                    info->fs_devices->open_devices);
        return 256 * limit;
 }
@@ -811,11 +810,9 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
        async->submit_bio_start = submit_bio_start;
        async->submit_bio_done = submit_bio_done;
 
-       async->work.func = run_one_async_start;
-       async->work.ordered_func = run_one_async_done;
-       async->work.ordered_free = run_one_async_free;
+       btrfs_init_work(&async->work, run_one_async_start,
+                       run_one_async_done, run_one_async_free);
 
-       async->work.flags = 0;
        async->bio_flags = bio_flags;
        async->bio_offset = bio_offset;
 
@@ -824,9 +821,9 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
        atomic_inc(&fs_info->nr_async_submits);
 
        if (rw & REQ_SYNC)
-               btrfs_set_work_high_prio(&async->work);
+               btrfs_set_work_high_priority(&async->work);
 
-       btrfs_queue_worker(&fs_info->workers, &async->work);
+       btrfs_queue_work(fs_info->workers, &async->work);
 
        while (atomic_read(&fs_info->async_submit_draining) &&
              atomic_read(&fs_info->nr_async_submits)) {
@@ -1149,6 +1146,32 @@ void clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        }
 }
 
+static struct btrfs_subvolume_writers *btrfs_alloc_subvolume_writers(void)
+{
+       struct btrfs_subvolume_writers *writers;
+       int ret;
+
+       writers = kmalloc(sizeof(*writers), GFP_NOFS);
+       if (!writers)
+               return ERR_PTR(-ENOMEM);
+
+       ret = percpu_counter_init(&writers->counter, 0);
+       if (ret < 0) {
+               kfree(writers);
+               return ERR_PTR(ret);
+       }
+
+       init_waitqueue_head(&writers->wait);
+       return writers;
+}
+
+static void
+btrfs_free_subvolume_writers(struct btrfs_subvolume_writers *writers)
+{
+       percpu_counter_destroy(&writers->counter);
+       kfree(writers);
+}
+
 static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
                         u32 stripesize, struct btrfs_root *root,
                         struct btrfs_fs_info *fs_info,
@@ -1194,16 +1217,22 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
        spin_lock_init(&root->log_extents_lock[1]);
        mutex_init(&root->objectid_mutex);
        mutex_init(&root->log_mutex);
+       mutex_init(&root->ordered_extent_mutex);
+       mutex_init(&root->delalloc_mutex);
        init_waitqueue_head(&root->log_writer_wait);
        init_waitqueue_head(&root->log_commit_wait[0]);
        init_waitqueue_head(&root->log_commit_wait[1]);
+       INIT_LIST_HEAD(&root->log_ctxs[0]);
+       INIT_LIST_HEAD(&root->log_ctxs[1]);
        atomic_set(&root->log_commit[0], 0);
        atomic_set(&root->log_commit[1], 0);
        atomic_set(&root->log_writers, 0);
        atomic_set(&root->log_batch, 0);
        atomic_set(&root->orphan_inodes, 0);
        atomic_set(&root->refs, 1);
+       atomic_set(&root->will_be_snapshoted, 0);
        root->log_transid = 0;
+       root->log_transid_committed = -1;
        root->last_log_commit = 0;
        if (fs_info)
                extent_io_tree_init(&root->dirty_log_pages,
@@ -1417,6 +1446,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
        WARN_ON(root->log_root);
        root->log_root = log_root;
        root->log_transid = 0;
+       root->log_transid_committed = -1;
        root->last_log_commit = 0;
        return 0;
 }
@@ -1498,6 +1528,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
 int btrfs_init_fs_root(struct btrfs_root *root)
 {
        int ret;
+       struct btrfs_subvolume_writers *writers;
 
        root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS);
        root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned),
@@ -1507,6 +1538,13 @@ int btrfs_init_fs_root(struct btrfs_root *root)
                goto fail;
        }
 
+       writers = btrfs_alloc_subvolume_writers();
+       if (IS_ERR(writers)) {
+               ret = PTR_ERR(writers);
+               goto fail;
+       }
+       root->subv_writers = writers;
+
        btrfs_init_free_ino_ctl(root);
        mutex_init(&root->fs_commit_mutex);
        spin_lock_init(&root->cache_lock);
@@ -1514,8 +1552,11 @@ int btrfs_init_fs_root(struct btrfs_root *root)
 
        ret = get_anon_bdev(&root->anon_dev);
        if (ret)
-               goto fail;
+               goto free_writers;
        return 0;
+
+free_writers:
+       btrfs_free_subvolume_writers(root->subv_writers);
 fail:
        kfree(root->free_ino_ctl);
        kfree(root->free_ino_pinned);
@@ -1990,23 +2031,22 @@ static noinline int next_root_backup(struct btrfs_fs_info *info,
 /* helper to cleanup workers */
 static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info)
 {
-       btrfs_stop_workers(&fs_info->generic_worker);
-       btrfs_stop_workers(&fs_info->fixup_workers);
-       btrfs_stop_workers(&fs_info->delalloc_workers);
-       btrfs_stop_workers(&fs_info->workers);
-       btrfs_stop_workers(&fs_info->endio_workers);
-       btrfs_stop_workers(&fs_info->endio_meta_workers);
-       btrfs_stop_workers(&fs_info->endio_raid56_workers);
-       btrfs_stop_workers(&fs_info->rmw_workers);
-       btrfs_stop_workers(&fs_info->endio_meta_write_workers);
-       btrfs_stop_workers(&fs_info->endio_write_workers);
-       btrfs_stop_workers(&fs_info->endio_freespace_worker);
-       btrfs_stop_workers(&fs_info->submit_workers);
-       btrfs_stop_workers(&fs_info->delayed_workers);
-       btrfs_stop_workers(&fs_info->caching_workers);
-       btrfs_stop_workers(&fs_info->readahead_workers);
-       btrfs_stop_workers(&fs_info->flush_workers);
-       btrfs_stop_workers(&fs_info->qgroup_rescan_workers);
+       btrfs_destroy_workqueue(fs_info->fixup_workers);
+       btrfs_destroy_workqueue(fs_info->delalloc_workers);
+       btrfs_destroy_workqueue(fs_info->workers);
+       btrfs_destroy_workqueue(fs_info->endio_workers);
+       btrfs_destroy_workqueue(fs_info->endio_meta_workers);
+       btrfs_destroy_workqueue(fs_info->endio_raid56_workers);
+       btrfs_destroy_workqueue(fs_info->rmw_workers);
+       btrfs_destroy_workqueue(fs_info->endio_meta_write_workers);
+       btrfs_destroy_workqueue(fs_info->endio_write_workers);
+       btrfs_destroy_workqueue(fs_info->endio_freespace_worker);
+       btrfs_destroy_workqueue(fs_info->submit_workers);
+       btrfs_destroy_workqueue(fs_info->delayed_workers);
+       btrfs_destroy_workqueue(fs_info->caching_workers);
+       btrfs_destroy_workqueue(fs_info->readahead_workers);
+       btrfs_destroy_workqueue(fs_info->flush_workers);
+       btrfs_destroy_workqueue(fs_info->qgroup_rescan_workers);
 }
 
 static void free_root_extent_buffers(struct btrfs_root *root)
@@ -2097,6 +2137,8 @@ int open_ctree(struct super_block *sb,
        int err = -EINVAL;
        int num_backups_tried = 0;
        int backup_index = 0;
+       int max_active;
+       int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND;
        bool create_uuid_tree;
        bool check_uuid_tree;
 
@@ -2133,10 +2175,16 @@ int open_ctree(struct super_block *sb,
                goto fail_dirty_metadata_bytes;
        }
 
+       ret = percpu_counter_init(&fs_info->bio_counter, 0);
+       if (ret) {
+               err = ret;
+               goto fail_delalloc_bytes;
+       }
+
        fs_info->btree_inode = new_inode(sb);
        if (!fs_info->btree_inode) {
                err = -ENOMEM;
-               goto fail_delalloc_bytes;
+               goto fail_bio_counter;
        }
 
        mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
@@ -2159,6 +2207,7 @@ int open_ctree(struct super_block *sb,
        spin_lock_init(&fs_info->buffer_lock);
        rwlock_init(&fs_info->tree_mod_log_lock);
        mutex_init(&fs_info->reloc_mutex);
+       mutex_init(&fs_info->delalloc_root_mutex);
        seqlock_init(&fs_info->profiles_lock);
 
        init_completion(&fs_info->kobj_unregister);
@@ -2211,6 +2260,7 @@ int open_ctree(struct super_block *sb,
        atomic_set(&fs_info->scrub_pause_req, 0);
        atomic_set(&fs_info->scrubs_paused, 0);
        atomic_set(&fs_info->scrub_cancel_req, 0);
+       init_waitqueue_head(&fs_info->replace_wait);
        init_waitqueue_head(&fs_info->scrub_pause_wait);
        fs_info->scrub_workers_refcnt = 0;
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
@@ -2458,104 +2508,68 @@ int open_ctree(struct super_block *sb,
                goto fail_alloc;
        }
 
-       btrfs_init_workers(&fs_info->generic_worker,
-                          "genwork", 1, NULL);
-
-       btrfs_init_workers(&fs_info->workers, "worker",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
+       max_active = fs_info->thread_pool_size;
 
-       btrfs_init_workers(&fs_info->delalloc_workers, "delalloc",
-                          fs_info->thread_pool_size, NULL);
+       fs_info->workers =
+               btrfs_alloc_workqueue("worker", flags | WQ_HIGHPRI,
+                                     max_active, 16);
 
-       btrfs_init_workers(&fs_info->flush_workers, "flush_delalloc",
-                          fs_info->thread_pool_size, NULL);
+       fs_info->delalloc_workers =
+               btrfs_alloc_workqueue("delalloc", flags, max_active, 2);
 
-       btrfs_init_workers(&fs_info->submit_workers, "submit",
-                          min_t(u64, fs_devices->num_devices,
-                          fs_info->thread_pool_size), NULL);
+       fs_info->flush_workers =
+               btrfs_alloc_workqueue("flush_delalloc", flags, max_active, 0);
 
-       btrfs_init_workers(&fs_info->caching_workers, "cache",
-                          fs_info->thread_pool_size, NULL);
+       fs_info->caching_workers =
+               btrfs_alloc_workqueue("cache", flags, max_active, 0);
 
-       /* a higher idle thresh on the submit workers makes it much more
+       /*
+        * a higher idle thresh on the submit workers makes it much more
         * likely that bios will be send down in a sane order to the
         * devices
         */
-       fs_info->submit_workers.idle_thresh = 64;
-
-       fs_info->workers.idle_thresh = 16;
-       fs_info->workers.ordered = 1;
-
-       fs_info->delalloc_workers.idle_thresh = 2;
-       fs_info->delalloc_workers.ordered = 1;
-
-       btrfs_init_workers(&fs_info->fixup_workers, "fixup", 1,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->endio_workers, "endio",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->endio_meta_workers, "endio-meta",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->endio_meta_write_workers,
-                          "endio-meta-write", fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->endio_raid56_workers,
-                          "endio-raid56", fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->rmw_workers,
-                          "rmw", fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->endio_write_workers, "endio-write",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write",
-                          1, &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->readahead_workers, "readahead",
-                          fs_info->thread_pool_size,
-                          &fs_info->generic_worker);
-       btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1,
-                          &fs_info->generic_worker);
+       fs_info->submit_workers =
+               btrfs_alloc_workqueue("submit", flags,
+                                     min_t(u64, fs_devices->num_devices,
+                                           max_active), 64);
+
+       fs_info->fixup_workers =
+               btrfs_alloc_workqueue("fixup", flags, 1, 0);
 
        /*
         * endios are largely parallel and should have a very
         * low idle thresh
         */
-       fs_info->endio_workers.idle_thresh = 4;
-       fs_info->endio_meta_workers.idle_thresh = 4;
-       fs_info->endio_raid56_workers.idle_thresh = 4;
-       fs_info->rmw_workers.idle_thresh = 2;
-
-       fs_info->endio_write_workers.idle_thresh = 2;
-       fs_info->endio_meta_write_workers.idle_thresh = 2;
-       fs_info->readahead_workers.idle_thresh = 2;
-
-       /*
-        * btrfs_start_workers can really only fail because of ENOMEM so just
-        * return -ENOMEM if any of these fail.
-        */
-       ret = btrfs_start_workers(&fs_info->workers);
-       ret |= btrfs_start_workers(&fs_info->generic_worker);
-       ret |= btrfs_start_workers(&fs_info->submit_workers);
-       ret |= btrfs_start_workers(&fs_info->delalloc_workers);
-       ret |= btrfs_start_workers(&fs_info->fixup_workers);
-       ret |= btrfs_start_workers(&fs_info->endio_workers);
-       ret |= btrfs_start_workers(&fs_info->endio_meta_workers);
-       ret |= btrfs_start_workers(&fs_info->rmw_workers);
-       ret |= btrfs_start_workers(&fs_info->endio_raid56_workers);
-       ret |= btrfs_start_workers(&fs_info->endio_meta_write_workers);
-       ret |= btrfs_start_workers(&fs_info->endio_write_workers);
-       ret |= btrfs_start_workers(&fs_info->endio_freespace_worker);
-       ret |= btrfs_start_workers(&fs_info->delayed_workers);
-       ret |= btrfs_start_workers(&fs_info->caching_workers);
-       ret |= btrfs_start_workers(&fs_info->readahead_workers);
-       ret |= btrfs_start_workers(&fs_info->flush_workers);
-       ret |= btrfs_start_workers(&fs_info->qgroup_rescan_workers);
-       if (ret) {
+       fs_info->endio_workers =
+               btrfs_alloc_workqueue("endio", flags, max_active, 4);
+       fs_info->endio_meta_workers =
+               btrfs_alloc_workqueue("endio-meta", flags, max_active, 4);
+       fs_info->endio_meta_write_workers =
+               btrfs_alloc_workqueue("endio-meta-write", flags, max_active, 2);
+       fs_info->endio_raid56_workers =
+               btrfs_alloc_workqueue("endio-raid56", flags, max_active, 4);
+       fs_info->rmw_workers =
+               btrfs_alloc_workqueue("rmw", flags, max_active, 2);
+       fs_info->endio_write_workers =
+               btrfs_alloc_workqueue("endio-write", flags, max_active, 2);
+       fs_info->endio_freespace_worker =
+               btrfs_alloc_workqueue("freespace-write", flags, max_active, 0);
+       fs_info->delayed_workers =
+               btrfs_alloc_workqueue("delayed-meta", flags, max_active, 0);
+       fs_info->readahead_workers =
+               btrfs_alloc_workqueue("readahead", flags, max_active, 2);
+       fs_info->qgroup_rescan_workers =
+               btrfs_alloc_workqueue("qgroup-rescan", flags, 1, 0);
+
+       if (!(fs_info->workers && fs_info->delalloc_workers &&
+             fs_info->submit_workers && fs_info->flush_workers &&
+             fs_info->endio_workers && fs_info->endio_meta_workers &&
+             fs_info->endio_meta_write_workers &&
+             fs_info->endio_write_workers && fs_info->endio_raid56_workers &&
+             fs_info->endio_freespace_worker && fs_info->rmw_workers &&
+             fs_info->caching_workers && fs_info->readahead_workers &&
+             fs_info->fixup_workers && fs_info->delayed_workers &&
+             fs_info->qgroup_rescan_workers)) {
                err = -ENOMEM;
                goto fail_sb_buffer;
        }
@@ -2963,6 +2977,8 @@ fail_iput:
        btrfs_mapping_tree_free(&fs_info->mapping_tree);
 
        iput(fs_info->btree_inode);
+fail_bio_counter:
+       percpu_counter_destroy(&fs_info->bio_counter);
 fail_delalloc_bytes:
        percpu_counter_destroy(&fs_info->delalloc_bytes);
 fail_dirty_metadata_bytes:
@@ -3244,6 +3260,8 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
        /* send down all the barriers */
        head = &info->fs_devices->devices;
        list_for_each_entry_rcu(dev, head, dev_list) {
+               if (dev->missing)
+                       continue;
                if (!dev->bdev) {
                        errors_send++;
                        continue;
@@ -3258,6 +3276,8 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
 
        /* wait for all the barriers */
        list_for_each_entry_rcu(dev, head, dev_list) {
+               if (dev->missing)
+                       continue;
                if (!dev->bdev) {
                        errors_wait++;
                        continue;
@@ -3477,6 +3497,8 @@ static void free_fs_root(struct btrfs_root *root)
        root->orphan_block_rsv = NULL;
        if (root->anon_dev)
                free_anon_bdev(root->anon_dev);
+       if (root->subv_writers)
+               btrfs_free_subvolume_writers(root->subv_writers);
        free_extent_buffer(root->node);
        free_extent_buffer(root->commit_root);
        kfree(root->free_ino_ctl);
@@ -3610,6 +3632,7 @@ int close_ctree(struct btrfs_root *root)
 
        percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
        percpu_counter_destroy(&fs_info->delalloc_bytes);
+       percpu_counter_destroy(&fs_info->bio_counter);
        bdi_destroy(&fs_info->bdi);
        cleanup_srcu_struct(&fs_info->subvol_srcu);
 
@@ -3791,9 +3814,11 @@ static void btrfs_destroy_all_ordered_extents(struct btrfs_fs_info *fs_info)
                list_move_tail(&root->ordered_root,
                               &fs_info->ordered_roots);
 
+               spin_unlock(&fs_info->ordered_root_lock);
                btrfs_destroy_ordered_extents(root);
 
-               cond_resched_lock(&fs_info->ordered_root_lock);
+               cond_resched();
+               spin_lock(&fs_info->ordered_root_lock);
        }
        spin_unlock(&fs_info->ordered_root_lock);
 }
index 32312e09f0f5999d05aaabafceebcce62b685568..c6b6a6e3e735ce73bf06a735a9ee85533d94e4bf 100644 (file)
@@ -549,7 +549,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
        caching_ctl->block_group = cache;
        caching_ctl->progress = cache->key.objectid;
        atomic_set(&caching_ctl->count, 1);
-       caching_ctl->work.func = caching_thread;
+       btrfs_init_work(&caching_ctl->work, caching_thread, NULL, NULL);
 
        spin_lock(&cache->lock);
        /*
@@ -640,7 +640,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
 
        btrfs_get_block_group(cache);
 
-       btrfs_queue_worker(&fs_info->caching_workers, &caching_ctl->work);
+       btrfs_queue_work(fs_info->caching_workers, &caching_ctl->work);
 
        return ret;
 }
@@ -3971,7 +3971,7 @@ static int can_overcommit(struct btrfs_root *root,
 }
 
 static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
-                                        unsigned long nr_pages)
+                                        unsigned long nr_pages, int nr_items)
 {
        struct super_block *sb = root->fs_info->sb;
 
@@ -3986,9 +3986,9 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
                 * the filesystem is readonly(all dirty pages are written to
                 * the disk).
                 */
-               btrfs_start_delalloc_roots(root->fs_info, 0);
+               btrfs_start_delalloc_roots(root->fs_info, 0, nr_items);
                if (!current->journal_info)
-                       btrfs_wait_ordered_roots(root->fs_info, -1);
+                       btrfs_wait_ordered_roots(root->fs_info, nr_items);
        }
 }
 
@@ -4045,7 +4045,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
        while (delalloc_bytes && loops < 3) {
                max_reclaim = min(delalloc_bytes, to_reclaim);
                nr_pages = max_reclaim >> PAGE_CACHE_SHIFT;
-               btrfs_writeback_inodes_sb_nr(root, nr_pages);
+               btrfs_writeback_inodes_sb_nr(root, nr_pages, items);
                /*
                 * We need to wait for the async pages to actually start before
                 * we do anything.
@@ -4112,13 +4112,9 @@ static int may_commit_transaction(struct btrfs_root *root,
                goto commit;
 
        /* See if there is enough pinned space to make this reservation */
-       spin_lock(&space_info->lock);
        if (percpu_counter_compare(&space_info->total_bytes_pinned,
-                                  bytes) >= 0) {
-               spin_unlock(&space_info->lock);
+                                  bytes) >= 0)
                goto commit;
-       }
-       spin_unlock(&space_info->lock);
 
        /*
         * See if there is some space in the delayed insertion reservation for
@@ -4127,16 +4123,13 @@ static int may_commit_transaction(struct btrfs_root *root,
        if (space_info != delayed_rsv->space_info)
                return -ENOSPC;
 
-       spin_lock(&space_info->lock);
        spin_lock(&delayed_rsv->lock);
        if (percpu_counter_compare(&space_info->total_bytes_pinned,
                                   bytes - delayed_rsv->size) >= 0) {
                spin_unlock(&delayed_rsv->lock);
-               spin_unlock(&space_info->lock);
                return -ENOSPC;
        }
        spin_unlock(&delayed_rsv->lock);
-       spin_unlock(&space_info->lock);
 
 commit:
        trans = btrfs_join_transaction(root);
@@ -4181,7 +4174,7 @@ static int flush_space(struct btrfs_root *root,
                break;
        case FLUSH_DELALLOC:
        case FLUSH_DELALLOC_WAIT:
-               shrink_delalloc(root, num_bytes, orig_bytes,
+               shrink_delalloc(root, num_bytes * 2, orig_bytes,
                                state == FLUSH_DELALLOC_WAIT);
                break;
        case ALLOC_CHUNK:
@@ -8938,3 +8931,38 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
        range->len = trimmed;
        return ret;
 }
+
+/*
+ * btrfs_{start,end}_write() is similar to mnt_{want, drop}_write(),
+ * they are used to prevent the some tasks writing data into the page cache
+ * by nocow before the subvolume is snapshoted, but flush the data into
+ * the disk after the snapshot creation.
+ */
+void btrfs_end_nocow_write(struct btrfs_root *root)
+{
+       percpu_counter_dec(&root->subv_writers->counter);
+       /*
+        * Make sure counter is updated before we wake up
+        * waiters.
+        */
+       smp_mb();
+       if (waitqueue_active(&root->subv_writers->wait))
+               wake_up(&root->subv_writers->wait);
+}
+
+int btrfs_start_nocow_write(struct btrfs_root *root)
+{
+       if (unlikely(atomic_read(&root->will_be_snapshoted)))
+               return 0;
+
+       percpu_counter_inc(&root->subv_writers->counter);
+       /*
+        * Make sure counter is updated before we check for snapshot creation.
+        */
+       smp_mb();
+       if (unlikely(atomic_read(&root->will_be_snapshoted))) {
+               btrfs_end_nocow_write(root);
+               return 0;
+       }
+       return 1;
+}
index 85bbd01f1271379de6b3bcf41f4a42bd9d30320a..ae69a00387e75149f2bca5565787ec2440b5275b 100644 (file)
@@ -229,12 +229,14 @@ void free_extent_state(struct extent_state *state)
        }
 }
 
-static struct rb_node *tree_insert(struct rb_root *root, u64 offset,
+static struct rb_node *tree_insert(struct rb_root *root,
+                                  struct rb_node *search_start,
+                                  u64 offset,
                                   struct rb_node *node,
                                   struct rb_node ***p_in,
                                   struct rb_node **parent_in)
 {
-       struct rb_node **p = &root->rb_node;
+       struct rb_node **p;
        struct rb_node *parent = NULL;
        struct tree_entry *entry;
 
@@ -244,6 +246,7 @@ static struct rb_node *tree_insert(struct rb_root *root, u64 offset,
                goto do_insert;
        }
 
+       p = search_start ? &search_start : &root->rb_node;
        while (*p) {
                parent = *p;
                entry = rb_entry(parent, struct tree_entry, rb_node);
@@ -430,7 +433,7 @@ static int insert_state(struct extent_io_tree *tree,
 
        set_state_bits(tree, state, bits);
 
-       node = tree_insert(&tree->state, end, &state->rb_node, p, parent);
+       node = tree_insert(&tree->state, NULL, end, &state->rb_node, p, parent);
        if (node) {
                struct extent_state *found;
                found = rb_entry(node, struct extent_state, rb_node);
@@ -477,8 +480,8 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig,
        prealloc->state = orig->state;
        orig->start = split;
 
-       node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node,
-                          NULL, NULL);
+       node = tree_insert(&tree->state, &orig->rb_node, prealloc->end,
+                          &prealloc->rb_node, NULL, NULL);
        if (node) {
                free_extent_state(prealloc);
                return -EEXIST;
@@ -2757,7 +2760,7 @@ __get_extent_map(struct inode *inode, struct page *page, size_t pg_offset,
 
        if (em_cached && *em_cached) {
                em = *em_cached;
-               if (em->in_tree && start >= em->start &&
+               if (extent_map_in_tree(em) && start >= em->start &&
                    start < extent_map_end(em)) {
                        atomic_inc(&em->refs);
                        return em;
index 996ad56b57db64bbc0516f4674d8ad3fd2d43976..1874aee69c86391e6b8a70eb3931a8a824e3da65 100644 (file)
@@ -51,7 +51,7 @@ struct extent_map *alloc_extent_map(void)
        em = kmem_cache_zalloc(extent_map_cache, GFP_NOFS);
        if (!em)
                return NULL;
-       em->in_tree = 0;
+       RB_CLEAR_NODE(&em->rb_node);
        em->flags = 0;
        em->compress_type = BTRFS_COMPRESS_NONE;
        em->generation = 0;
@@ -73,7 +73,7 @@ void free_extent_map(struct extent_map *em)
                return;
        WARN_ON(atomic_read(&em->refs) == 0);
        if (atomic_dec_and_test(&em->refs)) {
-               WARN_ON(em->in_tree);
+               WARN_ON(extent_map_in_tree(em));
                WARN_ON(!list_empty(&em->list));
                kmem_cache_free(extent_map_cache, em);
        }
@@ -99,8 +99,6 @@ static int tree_insert(struct rb_root *root, struct extent_map *em)
                parent = *p;
                entry = rb_entry(parent, struct extent_map, rb_node);
 
-               WARN_ON(!entry->in_tree);
-
                if (em->start < entry->start)
                        p = &(*p)->rb_left;
                else if (em->start >= extent_map_end(entry))
@@ -128,7 +126,6 @@ static int tree_insert(struct rb_root *root, struct extent_map *em)
                if (end > entry->start && em->start < extent_map_end(entry))
                        return -EEXIST;
 
-       em->in_tree = 1;
        rb_link_node(&em->rb_node, orig_parent, p);
        rb_insert_color(&em->rb_node, root);
        return 0;
@@ -153,8 +150,6 @@ static struct rb_node *__tree_search(struct rb_root *root, u64 offset,
                prev = n;
                prev_entry = entry;
 
-               WARN_ON(!entry->in_tree);
-
                if (offset < entry->start)
                        n = n->rb_left;
                else if (offset >= extent_map_end(entry))
@@ -240,12 +235,12 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
                        em->len += merge->len;
                        em->block_len += merge->block_len;
                        em->block_start = merge->block_start;
-                       merge->in_tree = 0;
                        em->mod_len = (em->mod_len + em->mod_start) - merge->mod_start;
                        em->mod_start = merge->mod_start;
                        em->generation = max(em->generation, merge->generation);
 
                        rb_erase(&merge->rb_node, &tree->map);
+                       RB_CLEAR_NODE(&merge->rb_node);
                        free_extent_map(merge);
                }
        }
@@ -257,7 +252,7 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
                em->len += merge->len;
                em->block_len += merge->block_len;
                rb_erase(&merge->rb_node, &tree->map);
-               merge->in_tree = 0;
+               RB_CLEAR_NODE(&merge->rb_node);
                em->mod_len = (merge->mod_start + merge->mod_len) - em->mod_start;
                em->generation = max(em->generation, merge->generation);
                free_extent_map(merge);
@@ -319,7 +314,21 @@ out:
 void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em)
 {
        clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
-       if (em->in_tree)
+       if (extent_map_in_tree(em))
+               try_merge_map(tree, em);
+}
+
+static inline void setup_extent_mapping(struct extent_map_tree *tree,
+                                       struct extent_map *em,
+                                       int modified)
+{
+       atomic_inc(&em->refs);
+       em->mod_start = em->start;
+       em->mod_len = em->len;
+
+       if (modified)
+               list_move(&em->list, &tree->modified_extents);
+       else
                try_merge_map(tree, em);
 }
 
@@ -342,15 +351,7 @@ int add_extent_mapping(struct extent_map_tree *tree,
        if (ret)
                goto out;
 
-       atomic_inc(&em->refs);
-
-       em->mod_start = em->start;
-       em->mod_len = em->len;
-
-       if (modified)
-               list_move(&em->list, &tree->modified_extents);
-       else
-               try_merge_map(tree, em);
+       setup_extent_mapping(tree, em, modified);
 out:
        return ret;
 }
@@ -434,6 +435,21 @@ int remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em)
        rb_erase(&em->rb_node, &tree->map);
        if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags))
                list_del_init(&em->list);
-       em->in_tree = 0;
+       RB_CLEAR_NODE(&em->rb_node);
        return ret;
 }
+
+void replace_extent_mapping(struct extent_map_tree *tree,
+                           struct extent_map *cur,
+                           struct extent_map *new,
+                           int modified)
+{
+       WARN_ON(test_bit(EXTENT_FLAG_PINNED, &cur->flags));
+       ASSERT(extent_map_in_tree(cur));
+       if (!test_bit(EXTENT_FLAG_LOGGING, &cur->flags))
+               list_del_init(&cur->list);
+       rb_replace_node(&cur->rb_node, &new->rb_node, &tree->map);
+       RB_CLEAR_NODE(&cur->rb_node);
+
+       setup_extent_mapping(tree, new, modified);
+}
index 93fba716d7f82f517ad082a65354611d1afecdd2..e7fd8a56a140f89e521d7901a02c8448e1b929d5 100644 (file)
@@ -33,7 +33,6 @@ struct extent_map {
        unsigned long flags;
        struct block_device *bdev;
        atomic_t refs;
-       unsigned int in_tree;
        unsigned int compress_type;
        struct list_head list;
 };
@@ -44,6 +43,11 @@ struct extent_map_tree {
        rwlock_t lock;
 };
 
+static inline int extent_map_in_tree(const struct extent_map *em)
+{
+       return !RB_EMPTY_NODE(&em->rb_node);
+}
+
 static inline u64 extent_map_end(struct extent_map *em)
 {
        if (em->start + em->len < em->start)
@@ -64,6 +68,10 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
 int add_extent_mapping(struct extent_map_tree *tree,
                       struct extent_map *em, int modified);
 int remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em);
+void replace_extent_mapping(struct extent_map_tree *tree,
+                           struct extent_map *cur,
+                           struct extent_map *new,
+                           int modified);
 
 struct extent_map *alloc_extent_map(void);
 void free_extent_map(struct extent_map *em);
index 7331a230e30b2531a1d94d8c13c628d1afa992fd..e1ffb1e2289896a61bc85d76c535184979789751 100644 (file)
@@ -591,7 +591,6 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                clear_bit(EXTENT_FLAG_PINNED, &em->flags);
                clear_bit(EXTENT_FLAG_LOGGING, &flags);
                modified = !list_empty(&em->list);
-               remove_extent_mapping(em_tree, em);
                if (no_splits)
                        goto next;
 
@@ -622,8 +621,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                        split->bdev = em->bdev;
                        split->flags = flags;
                        split->compress_type = em->compress_type;
-                       ret = add_extent_mapping(em_tree, split, modified);
-                       BUG_ON(ret); /* Logic error */
+                       replace_extent_mapping(em_tree, em, split, modified);
                        free_extent_map(split);
                        split = split2;
                        split2 = NULL;
@@ -661,12 +659,20 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                                split->orig_block_len = 0;
                        }
 
-                       ret = add_extent_mapping(em_tree, split, modified);
-                       BUG_ON(ret); /* Logic error */
+                       if (extent_map_in_tree(em)) {
+                               replace_extent_mapping(em_tree, em, split,
+                                                      modified);
+                       } else {
+                               ret = add_extent_mapping(em_tree, split,
+                                                        modified);
+                               ASSERT(ret == 0); /* Logic error */
+                       }
                        free_extent_map(split);
                        split = NULL;
                }
 next:
+               if (extent_map_in_tree(em))
+                       remove_extent_mapping(em_tree, em);
                write_unlock(&em_tree->lock);
 
                /* once for us */
@@ -720,7 +726,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
        if (drop_cache)
                btrfs_drop_extent_cache(inode, start, end - 1, 0);
 
-       if (start >= BTRFS_I(inode)->disk_i_size)
+       if (start >= BTRFS_I(inode)->disk_i_size && !replace_extent)
                modify_tree = 0;
 
        while (1) {
@@ -798,7 +804,10 @@ next_slot:
                 */
                if (start > key.offset && end < extent_end) {
                        BUG_ON(del_nr > 0);
-                       BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
+                       if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
+                               ret = -EINVAL;
+                               break;
+                       }
 
                        memcpy(&new_key, &key, sizeof(new_key));
                        new_key.offset = start;
@@ -841,7 +850,10 @@ next_slot:
                 *      | -------- extent -------- |
                 */
                if (start <= key.offset && end < extent_end) {
-                       BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
+                       if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
+                               ret = -EINVAL;
+                               break;
+                       }
 
                        memcpy(&new_key, &key, sizeof(new_key));
                        new_key.offset = end;
@@ -864,7 +876,10 @@ next_slot:
                 */
                if (start > key.offset && end >= extent_end) {
                        BUG_ON(del_nr > 0);
-                       BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
+                       if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
+                               ret = -EINVAL;
+                               break;
+                       }
 
                        btrfs_set_file_extent_num_bytes(leaf, fi,
                                                        start - key.offset);
@@ -938,34 +953,42 @@ next_slot:
                 * Set path->slots[0] to first slot, so that after the delete
                 * if items are move off from our leaf to its immediate left or
                 * right neighbor leafs, we end up with a correct and adjusted
-                * path->slots[0] for our insertion.
+                * path->slots[0] for our insertion (if replace_extent != 0).
                 */
                path->slots[0] = del_slot;
                ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
                if (ret)
                        btrfs_abort_transaction(trans, root, ret);
+       }
 
-               leaf = path->nodes[0];
-               /*
-                * leaf eb has flag EXTENT_BUFFER_STALE if it was deleted (that
-                * is, its contents got pushed to its neighbors), in which case
-                * it means path->locks[0] == 0
-                */
-               if (!ret && replace_extent && leafs_visited == 1 &&
-                   path->locks[0] &&
-                   btrfs_leaf_free_space(root, leaf) >=
-                   sizeof(struct btrfs_item) + extent_item_size) {
-
-                       key.objectid = ino;
-                       key.type = BTRFS_EXTENT_DATA_KEY;
-                       key.offset = start;
-                       setup_items_for_insert(root, path, &key,
-                                              &extent_item_size,
-                                              extent_item_size,
-                                              sizeof(struct btrfs_item) +
-                                              extent_item_size, 1);
-                       *key_inserted = 1;
+       leaf = path->nodes[0];
+       /*
+        * If btrfs_del_items() was called, it might have deleted a leaf, in
+        * which case it unlocked our path, so check path->locks[0] matches a
+        * write lock.
+        */
+       if (!ret && replace_extent && leafs_visited == 1 &&
+           (path->locks[0] == BTRFS_WRITE_LOCK_BLOCKING ||
+            path->locks[0] == BTRFS_WRITE_LOCK) &&
+           btrfs_leaf_free_space(root, leaf) >=
+           sizeof(struct btrfs_item) + extent_item_size) {
+
+               key.objectid = ino;
+               key.type = BTRFS_EXTENT_DATA_KEY;
+               key.offset = start;
+               if (!del_nr && path->slots[0] < btrfs_header_nritems(leaf)) {
+                       struct btrfs_key slot_key;
+
+                       btrfs_item_key_to_cpu(leaf, &slot_key, path->slots[0]);
+                       if (btrfs_comp_cpu_keys(&key, &slot_key) > 0)
+                               path->slots[0]++;
                }
+               setup_items_for_insert(root, path, &key,
+                                      &extent_item_size,
+                                      extent_item_size,
+                                      sizeof(struct btrfs_item) +
+                                      extent_item_size, 1);
+               *key_inserted = 1;
        }
 
        if (!replace_extent || !(*key_inserted))
@@ -1346,11 +1369,11 @@ lock_and_cleanup_extent_if_need(struct inode *inode, struct page **pages,
                struct btrfs_ordered_extent *ordered;
                lock_extent_bits(&BTRFS_I(inode)->io_tree,
                                 start_pos, last_pos, 0, cached_state);
-               ordered = btrfs_lookup_first_ordered_extent(inode, last_pos);
+               ordered = btrfs_lookup_ordered_range(inode, start_pos,
+                                                    last_pos - start_pos + 1);
                if (ordered &&
                    ordered->file_offset + ordered->len > start_pos &&
                    ordered->file_offset <= last_pos) {
-                       btrfs_put_ordered_extent(ordered);
                        unlock_extent_cached(&BTRFS_I(inode)->io_tree,
                                             start_pos, last_pos,
                                             cached_state, GFP_NOFS);
@@ -1358,12 +1381,9 @@ lock_and_cleanup_extent_if_need(struct inode *inode, struct page **pages,
                                unlock_page(pages[i]);
                                page_cache_release(pages[i]);
                        }
-                       ret = btrfs_wait_ordered_range(inode, start_pos,
-                                               last_pos - start_pos + 1);
-                       if (ret)
-                               return ret;
-                       else
-                               return -EAGAIN;
+                       btrfs_start_ordered_extent(inode, ordered, 1);
+                       btrfs_put_ordered_extent(ordered);
+                       return -EAGAIN;
                }
                if (ordered)
                        btrfs_put_ordered_extent(ordered);
@@ -1396,8 +1416,12 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos,
        u64 num_bytes;
        int ret;
 
+       ret = btrfs_start_nocow_write(root);
+       if (!ret)
+               return -ENOSPC;
+
        lockstart = round_down(pos, root->sectorsize);
-       lockend = lockstart + round_up(*write_bytes, root->sectorsize) - 1;
+       lockend = round_up(pos + *write_bytes, root->sectorsize) - 1;
 
        while (1) {
                lock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend);
@@ -1415,12 +1439,10 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos,
        ret = can_nocow_extent(inode, lockstart, &num_bytes, NULL, NULL, NULL);
        if (ret <= 0) {
                ret = 0;
+               btrfs_end_nocow_write(root);
        } else {
-               clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend,
-                                EXTENT_DIRTY | EXTENT_DELALLOC |
-                                EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
-                                NULL, GFP_NOFS);
-               *write_bytes = min_t(size_t, *write_bytes, num_bytes);
+               *write_bytes = min_t(size_t, *write_bytes ,
+                                    num_bytes - pos + lockstart);
        }
 
        unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend);
@@ -1510,6 +1532,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
                        if (!only_release_metadata)
                                btrfs_free_reserved_data_space(inode,
                                                               reserve_bytes);
+                       else
+                               btrfs_end_nocow_write(root);
                        break;
                }
 
@@ -1598,6 +1622,9 @@ again:
                }
 
                release_bytes = 0;
+               if (only_release_metadata)
+                       btrfs_end_nocow_write(root);
+
                if (only_release_metadata && copied > 0) {
                        u64 lockstart = round_down(pos, root->sectorsize);
                        u64 lockend = lockstart +
@@ -1624,10 +1651,12 @@ again:
        kfree(pages);
 
        if (release_bytes) {
-               if (only_release_metadata)
+               if (only_release_metadata) {
+                       btrfs_end_nocow_write(root);
                        btrfs_delalloc_release_metadata(inode, release_bytes);
-               else
+               } else {
                        btrfs_delalloc_release_space(inode, release_bytes);
+               }
        }
 
        return num_written ? num_written : ret;
@@ -1856,8 +1885,9 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        struct dentry *dentry = file->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
-       int ret = 0;
        struct btrfs_trans_handle *trans;
+       struct btrfs_log_ctx ctx;
+       int ret = 0;
        bool full_sync = 0;
 
        trace_btrfs_sync_file(file, datasync);
@@ -1951,7 +1981,9 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        }
        trans->sync = true;
 
-       ret = btrfs_log_dentry_safe(trans, root, dentry);
+       btrfs_init_log_ctx(&ctx);
+
+       ret = btrfs_log_dentry_safe(trans, root, dentry, &ctx);
        if (ret < 0) {
                /* Fallthrough and commit/free transaction. */
                ret = 1;
@@ -1971,7 +2003,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 
        if (ret != BTRFS_NO_LOG_SYNC) {
                if (!ret) {
-                       ret = btrfs_sync_log(trans, root);
+                       ret = btrfs_sync_log(trans, root, &ctx);
                        if (!ret) {
                                ret = btrfs_end_transaction(trans, root);
                                goto out;
@@ -2157,6 +2189,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
        bool same_page = ((offset >> PAGE_CACHE_SHIFT) ==
                          ((offset + len - 1) >> PAGE_CACHE_SHIFT));
        bool no_holes = btrfs_fs_incompat(root->fs_info, NO_HOLES);
+       u64 ino_size = round_up(inode->i_size, PAGE_CACHE_SIZE);
 
        ret = btrfs_wait_ordered_range(inode, offset, len);
        if (ret)
@@ -2172,14 +2205,14 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
         * entire page.
         */
        if (same_page && len < PAGE_CACHE_SIZE) {
-               if (offset < round_up(inode->i_size, PAGE_CACHE_SIZE))
+               if (offset < ino_size)
                        ret = btrfs_truncate_page(inode, offset, len, 0);
                mutex_unlock(&inode->i_mutex);
                return ret;
        }
 
        /* zero back part of the first page */
-       if (offset < round_up(inode->i_size, PAGE_CACHE_SIZE)) {
+       if (offset < ino_size) {
                ret = btrfs_truncate_page(inode, offset, 0, 0);
                if (ret) {
                        mutex_unlock(&inode->i_mutex);
@@ -2188,7 +2221,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
        }
 
        /* zero the front end of the last page */
-       if (offset + len < round_up(inode->i_size, PAGE_CACHE_SIZE)) {
+       if (offset + len < ino_size) {
                ret = btrfs_truncate_page(inode, offset + len, 0, 1);
                if (ret) {
                        mutex_unlock(&inode->i_mutex);
@@ -2277,10 +2310,13 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
 
                trans->block_rsv = &root->fs_info->trans_block_rsv;
 
-               ret = fill_holes(trans, inode, path, cur_offset, drop_end);
-               if (ret) {
-                       err = ret;
-                       break;
+               if (cur_offset < ino_size) {
+                       ret = fill_holes(trans, inode, path, cur_offset,
+                                        drop_end);
+                       if (ret) {
+                               err = ret;
+                               break;
+                       }
                }
 
                cur_offset = drop_end;
@@ -2313,10 +2349,12 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
        }
 
        trans->block_rsv = &root->fs_info->trans_block_rsv;
-       ret = fill_holes(trans, inode, path, cur_offset, drop_end);
-       if (ret) {
-               err = ret;
-               goto out_trans;
+       if (cur_offset < ino_size) {
+               ret = fill_holes(trans, inode, path, cur_offset, drop_end);
+               if (ret) {
+                       err = ret;
+                       goto out_trans;
+               }
        }
 
 out_trans:
index 49ec1398879f7a1a5202587c4328b4c104960f44..06e9a4152b1419c6e4afbd4fd3580615ffc4eadd 100644 (file)
@@ -864,7 +864,8 @@ static noinline int cow_file_range(struct inode *inode,
 
        if (btrfs_is_free_space_inode(inode)) {
                WARN_ON_ONCE(1);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_unlock;
        }
 
        num_bytes = ALIGN(end - start + 1, blocksize);
@@ -1075,17 +1076,15 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
                async_cow->end = cur_end;
                INIT_LIST_HEAD(&async_cow->extents);
 
-               async_cow->work.func = async_cow_start;
-               async_cow->work.ordered_func = async_cow_submit;
-               async_cow->work.ordered_free = async_cow_free;
-               async_cow->work.flags = 0;
+               btrfs_init_work(&async_cow->work, async_cow_start,
+                               async_cow_submit, async_cow_free);
 
                nr_pages = (cur_end - start + PAGE_CACHE_SIZE) >>
                        PAGE_CACHE_SHIFT;
                atomic_add(nr_pages, &root->fs_info->async_delalloc_pages);
 
-               btrfs_queue_worker(&root->fs_info->delalloc_workers,
-                                  &async_cow->work);
+               btrfs_queue_work(root->fs_info->delalloc_workers,
+                                &async_cow->work);
 
                if (atomic_read(&root->fs_info->async_delalloc_pages) > limit) {
                        wait_event(root->fs_info->async_submit_wait,
@@ -1843,9 +1842,9 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end)
 
        SetPageChecked(page);
        page_cache_get(page);
-       fixup->work.func = btrfs_writepage_fixup_worker;
+       btrfs_init_work(&fixup->work, btrfs_writepage_fixup_worker, NULL, NULL);
        fixup->page = page;
-       btrfs_queue_worker(&root->fs_info->fixup_workers, &fixup->work);
+       btrfs_queue_work(root->fs_info->fixup_workers, &fixup->work);
        return -EBUSY;
 }
 
@@ -2239,6 +2238,11 @@ static noinline int relink_extent_backref(struct btrfs_path *path,
                return PTR_ERR(root);
        }
 
+       if (btrfs_root_readonly(root)) {
+               srcu_read_unlock(&fs_info->subvol_srcu, index);
+               return 0;
+       }
+
        /* step 2: get inode */
        key.objectid = backref->inum;
        key.type = BTRFS_INODE_ITEM_KEY;
@@ -2759,7 +2763,7 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
        struct inode *inode = page->mapping->host;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_ordered_extent *ordered_extent = NULL;
-       struct btrfs_workers *workers;
+       struct btrfs_workqueue *workers;
 
        trace_btrfs_writepage_end_io_hook(page, start, end, uptodate);
 
@@ -2768,14 +2772,13 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
                                            end - start + 1, uptodate))
                return 0;
 
-       ordered_extent->work.func = finish_ordered_fn;
-       ordered_extent->work.flags = 0;
+       btrfs_init_work(&ordered_extent->work, finish_ordered_fn, NULL, NULL);
 
        if (btrfs_is_free_space_inode(inode))
-               workers = &root->fs_info->endio_freespace_worker;
+               workers = root->fs_info->endio_freespace_worker;
        else
-               workers = &root->fs_info->endio_write_workers;
-       btrfs_queue_worker(workers, &ordered_extent->work);
+               workers = root->fs_info->endio_write_workers;
+       btrfs_queue_work(workers, &ordered_extent->work);
 
        return 0;
 }
@@ -4924,7 +4927,8 @@ void btrfs_invalidate_inodes(struct btrfs_root *root)
        struct inode *inode;
        u64 objectid = 0;
 
-       WARN_ON(btrfs_root_refs(&root->root_item) != 0);
+       if (!test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
+               WARN_ON(btrfs_root_refs(&root->root_item) != 0);
 
        spin_lock(&root->inode_lock);
 again:
@@ -5799,6 +5803,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        }
 out_unlock:
        btrfs_end_transaction(trans, root);
+       btrfs_balance_delayed_items(root);
        btrfs_btree_balance_dirty(root);
        if (drop_inode) {
                inode_dec_link_count(inode);
@@ -5872,6 +5877,7 @@ out_unlock:
                inode_dec_link_count(inode);
                iput(inode);
        }
+       btrfs_balance_delayed_items(root);
        btrfs_btree_balance_dirty(root);
        return err;
 }
@@ -5930,6 +5936,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
        }
 
        btrfs_end_transaction(trans, root);
+       btrfs_balance_delayed_items(root);
 fail:
        if (drop_inode) {
                inode_dec_link_count(inode);
@@ -5996,6 +6003,7 @@ out_fail:
        btrfs_end_transaction(trans, root);
        if (drop_on_err)
                iput(inode);
+       btrfs_balance_delayed_items(root);
        btrfs_btree_balance_dirty(root);
        return err;
 }
@@ -6550,6 +6558,7 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
        int ret;
        struct extent_buffer *leaf;
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
        struct btrfs_file_extent_item *fi;
        struct btrfs_key key;
        u64 disk_bytenr;
@@ -6626,6 +6635,20 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
 
        if (btrfs_extent_readonly(root, disk_bytenr))
                goto out;
+
+       num_bytes = min(offset + *len, extent_end) - offset;
+       if (!nocow && found_type == BTRFS_FILE_EXTENT_PREALLOC) {
+               u64 range_end;
+
+               range_end = round_up(offset + num_bytes, root->sectorsize) - 1;
+               ret = test_range_bit(io_tree, offset, range_end,
+                                    EXTENT_DELALLOC, 0, NULL);
+               if (ret) {
+                       ret = -EAGAIN;
+                       goto out;
+               }
+       }
+
        btrfs_release_path(path);
 
        /*
@@ -6654,7 +6677,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
         */
        disk_bytenr += backref_offset;
        disk_bytenr += offset - key.offset;
-       num_bytes = min(offset + *len, extent_end) - offset;
        if (csum_exist_in_range(root, disk_bytenr, num_bytes))
                                goto out;
        /*
@@ -7024,10 +7046,9 @@ again:
        if (!ret)
                goto out_test;
 
-       ordered->work.func = finish_ordered_fn;
-       ordered->work.flags = 0;
-       btrfs_queue_worker(&root->fs_info->endio_write_workers,
-                          &ordered->work);
+       btrfs_init_work(&ordered->work, finish_ordered_fn, NULL, NULL);
+       btrfs_queue_work(root->fs_info->endio_write_workers,
+                        &ordered->work);
 out_test:
        /*
         * our bio might span multiple ordered extents.  If we haven't
@@ -7404,15 +7425,15 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
        smp_mb__after_atomic_inc();
 
        /*
-        * The generic stuff only does filemap_write_and_wait_range, which isn't
-        * enough if we've written compressed pages to this area, so we need to
-        * call btrfs_wait_ordered_range to make absolutely sure that any
-        * outstanding dirty pages are on disk.
+        * The generic stuff only does filemap_write_and_wait_range, which
+        * isn't enough if we've written compressed pages to this area, so
+        * we need to flush the dirty pages again to make absolutely sure
+        * that any outstanding dirty pages are on disk.
         */
        count = iov_length(iov, nr_segs);
-       ret = btrfs_wait_ordered_range(inode, offset, count);
-       if (ret)
-               return ret;
+       if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
+                    &BTRFS_I(inode)->runtime_flags))
+               filemap_fdatawrite_range(inode->i_mapping, offset, count);
 
        if (rw & WRITE) {
                /*
@@ -8404,7 +8425,7 @@ struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode,
        work->inode = inode;
        work->wait = wait;
        work->delay_iput = delay_iput;
-       work->work.func = btrfs_run_delalloc_work;
+       btrfs_init_work(&work->work, btrfs_run_delalloc_work, NULL, NULL);
 
        return work;
 }
@@ -8419,7 +8440,8 @@ void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work)
  * some fairly slow code that needs optimization. This walks the list
  * of all the inodes with pending delalloc and forces them to disk.
  */
-static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
+static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput,
+                                  int nr)
 {
        struct btrfs_inode *binode;
        struct inode *inode;
@@ -8431,6 +8453,7 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
        INIT_LIST_HEAD(&works);
        INIT_LIST_HEAD(&splice);
 
+       mutex_lock(&root->delalloc_mutex);
        spin_lock(&root->delalloc_lock);
        list_splice_init(&root->delalloc_inodes, &splice);
        while (!list_empty(&splice)) {
@@ -8453,23 +8476,19 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
                        else
                                iput(inode);
                        ret = -ENOMEM;
-                       goto out;
+                       break;
                }
                list_add_tail(&work->list, &works);
-               btrfs_queue_worker(&root->fs_info->flush_workers,
-                                  &work->work);
-
+               btrfs_queue_work(root->fs_info->flush_workers,
+                                &work->work);
+               ret++;
+               if (nr != -1 && ret >= nr)
+                       break;
                cond_resched();
                spin_lock(&root->delalloc_lock);
        }
        spin_unlock(&root->delalloc_lock);
 
-       list_for_each_entry_safe(work, next, &works, list) {
-               list_del_init(&work->list);
-               btrfs_wait_and_free_delalloc_work(work);
-       }
-       return 0;
-out:
        list_for_each_entry_safe(work, next, &works, list) {
                list_del_init(&work->list);
                btrfs_wait_and_free_delalloc_work(work);
@@ -8480,6 +8499,7 @@ out:
                list_splice_tail(&splice, &root->delalloc_inodes);
                spin_unlock(&root->delalloc_lock);
        }
+       mutex_unlock(&root->delalloc_mutex);
        return ret;
 }
 
@@ -8490,7 +8510,9 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
        if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
                return -EROFS;
 
-       ret = __start_delalloc_inodes(root, delay_iput);
+       ret = __start_delalloc_inodes(root, delay_iput, -1);
+       if (ret > 0)
+               ret = 0;
        /*
         * the filemap_flush will queue IO into the worker threads, but
         * we have to make sure the IO is actually started and that
@@ -8507,7 +8529,8 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
        return ret;
 }
 
-int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
+int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
+                              int nr)
 {
        struct btrfs_root *root;
        struct list_head splice;
@@ -8518,9 +8541,10 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
 
        INIT_LIST_HEAD(&splice);
 
+       mutex_lock(&fs_info->delalloc_root_mutex);
        spin_lock(&fs_info->delalloc_root_lock);
        list_splice_init(&fs_info->delalloc_roots, &splice);
-       while (!list_empty(&splice)) {
+       while (!list_empty(&splice) && nr) {
                root = list_first_entry(&splice, struct btrfs_root,
                                        delalloc_root);
                root = btrfs_grab_fs_root(root);
@@ -8529,15 +8553,20 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
                               &fs_info->delalloc_roots);
                spin_unlock(&fs_info->delalloc_root_lock);
 
-               ret = __start_delalloc_inodes(root, delay_iput);
+               ret = __start_delalloc_inodes(root, delay_iput, nr);
                btrfs_put_fs_root(root);
-               if (ret)
+               if (ret < 0)
                        goto out;
 
+               if (nr != -1) {
+                       nr -= ret;
+                       WARN_ON(nr < 0);
+               }
                spin_lock(&fs_info->delalloc_root_lock);
        }
        spin_unlock(&fs_info->delalloc_root_lock);
 
+       ret = 0;
        atomic_inc(&fs_info->async_submit_draining);
        while (atomic_read(&fs_info->nr_async_submits) ||
              atomic_read(&fs_info->async_delalloc_pages)) {
@@ -8546,13 +8575,13 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
                    atomic_read(&fs_info->async_delalloc_pages) == 0));
        }
        atomic_dec(&fs_info->async_submit_draining);
-       return 0;
 out:
        if (!list_empty_careful(&splice)) {
                spin_lock(&fs_info->delalloc_root_lock);
                list_splice_tail(&splice, &fs_info->delalloc_roots);
                spin_unlock(&fs_info->delalloc_root_lock);
        }
+       mutex_unlock(&fs_info->delalloc_root_mutex);
        return ret;
 }
 
index a6d8efa46bfe50129b54ef11e4a854adad3b56ac..0401397b5c92787eba43d9dbc3097a0dfc2dbdac 100644 (file)
 #include "props.h"
 #include "sysfs.h"
 
+#ifdef CONFIG_64BIT
+/* If we have a 32-bit userspace and 64-bit kernel, then the UAPI
+ * structures are incorrect, as the timespec structure from userspace
+ * is 4 bytes too small. We define these alternatives here to teach
+ * the kernel about the 32-bit struct packing.
+ */
+struct btrfs_ioctl_timespec_32 {
+       __u64 sec;
+       __u32 nsec;
+} __attribute__ ((__packed__));
+
+struct btrfs_ioctl_received_subvol_args_32 {
+       char    uuid[BTRFS_UUID_SIZE];  /* in */
+       __u64   stransid;               /* in */
+       __u64   rtransid;               /* out */
+       struct btrfs_ioctl_timespec_32 stime; /* in */
+       struct btrfs_ioctl_timespec_32 rtime; /* out */
+       __u64   flags;                  /* in */
+       __u64   reserved[16];           /* in */
+} __attribute__ ((__packed__));
+
+#define BTRFS_IOC_SET_RECEIVED_SUBVOL_32 _IOWR(BTRFS_IOCTL_MAGIC, 37, \
+                               struct btrfs_ioctl_received_subvol_args_32)
+#endif
+
+
 static int btrfs_clone(struct inode *src, struct inode *inode,
                       u64 off, u64 olen, u64 olen_aligned, u64 destoff);
 
@@ -585,6 +611,23 @@ fail:
        return ret;
 }
 
+static void btrfs_wait_nocow_write(struct btrfs_root *root)
+{
+       s64 writers;
+       DEFINE_WAIT(wait);
+
+       do {
+               prepare_to_wait(&root->subv_writers->wait, &wait,
+                               TASK_UNINTERRUPTIBLE);
+
+               writers = percpu_counter_sum(&root->subv_writers->counter);
+               if (writers)
+                       schedule();
+
+               finish_wait(&root->subv_writers->wait, &wait);
+       } while (writers);
+}
+
 static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                           struct dentry *dentry, char *name, int namelen,
                           u64 *async_transid, bool readonly,
@@ -598,15 +641,21 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
        if (!root->ref_cows)
                return -EINVAL;
 
+       atomic_inc(&root->will_be_snapshoted);
+       smp_mb__after_atomic_inc();
+       btrfs_wait_nocow_write(root);
+
        ret = btrfs_start_delalloc_inodes(root, 0);
        if (ret)
-               return ret;
+               goto out;
 
        btrfs_wait_ordered_extents(root, -1);
 
        pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
-       if (!pending_snapshot)
-               return -ENOMEM;
+       if (!pending_snapshot) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        btrfs_init_block_rsv(&pending_snapshot->block_rsv,
                             BTRFS_BLOCK_RSV_TEMP);
@@ -623,7 +672,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                                        &pending_snapshot->qgroup_reserved,
                                        false);
        if (ret)
-               goto out;
+               goto free;
 
        pending_snapshot->dentry = dentry;
        pending_snapshot->root = root;
@@ -674,8 +723,10 @@ fail:
        btrfs_subvolume_release_metadata(BTRFS_I(dir)->root,
                                         &pending_snapshot->block_rsv,
                                         pending_snapshot->qgroup_reserved);
-out:
+free:
        kfree(pending_snapshot);
+out:
+       atomic_dec(&root->will_be_snapshoted);
        return ret;
 }
 
@@ -884,12 +935,14 @@ static int find_new_extents(struct btrfs_root *root,
        min_key.type = BTRFS_EXTENT_DATA_KEY;
        min_key.offset = *off;
 
-       path->keep_locks = 1;
-
        while (1) {
+               path->keep_locks = 1;
                ret = btrfs_search_forward(root, &min_key, path, newer_than);
                if (ret != 0)
                        goto none;
+               path->keep_locks = 0;
+               btrfs_unlock_up_safe(path, 1);
+process_slot:
                if (min_key.objectid != ino)
                        goto none;
                if (min_key.type != BTRFS_EXTENT_DATA_KEY)
@@ -908,6 +961,12 @@ static int find_new_extents(struct btrfs_root *root,
                        return 0;
                }
 
+               path->slots[0]++;
+               if (path->slots[0] < btrfs_header_nritems(leaf)) {
+                       btrfs_item_key_to_cpu(leaf, &min_key, path->slots[0]);
+                       goto process_slot;
+               }
+
                if (min_key.offset == (u64)-1)
                        goto none;
 
@@ -935,10 +994,13 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start)
        read_unlock(&em_tree->lock);
 
        if (!em) {
+               struct extent_state *cached = NULL;
+               u64 end = start + len - 1;
+
                /* get the big lock and read metadata off disk */
-               lock_extent(io_tree, start, start + len - 1);
+               lock_extent_bits(io_tree, start, end, 0, &cached);
                em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
-               unlock_extent(io_tree, start, start + len - 1);
+               unlock_extent_cached(io_tree, start, end, &cached, GFP_NOFS);
 
                if (IS_ERR(em))
                        return NULL;
@@ -957,7 +1019,8 @@ static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em)
                return false;
 
        next = defrag_lookup_extent(inode, em->start + em->len);
-       if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
+       if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE ||
+           (em->block_start + em->block_len == next->block_start))
                ret = false;
 
        free_extent_map(next);
@@ -1076,10 +1139,12 @@ again:
                page_start = page_offset(page);
                page_end = page_start + PAGE_CACHE_SIZE - 1;
                while (1) {
-                       lock_extent(tree, page_start, page_end);
+                       lock_extent_bits(tree, page_start, page_end,
+                                        0, &cached_state);
                        ordered = btrfs_lookup_ordered_extent(inode,
                                                              page_start);
-                       unlock_extent(tree, page_start, page_end);
+                       unlock_extent_cached(tree, page_start, page_end,
+                                            &cached_state, GFP_NOFS);
                        if (!ordered)
                                break;
 
@@ -1356,8 +1421,12 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                }
        }
 
-       if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO))
+       if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO)) {
                filemap_flush(inode->i_mapping);
+               if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
+                            &BTRFS_I(inode)->runtime_flags))
+                       filemap_flush(inode->i_mapping);
+       }
 
        if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
                /* the filemap_flush will queue IO into the worker threads, but
@@ -1573,7 +1642,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
                if (src_inode->i_sb != file_inode(file)->i_sb) {
                        btrfs_info(BTRFS_I(src_inode)->root->fs_info,
                                   "Snapshot src from another FS");
-                       ret = -EINVAL;
+                       ret = -EXDEV;
                } else if (!inode_owner_or_capable(src_inode)) {
                        /*
                         * Subvolume creation is not restricted, but snapshots
@@ -1797,7 +1866,9 @@ static noinline int may_destroy_subvol(struct btrfs_root *root)
        if (di && !IS_ERR(di)) {
                btrfs_dir_item_key_to_cpu(path->nodes[0], di, &key);
                if (key.objectid == root->root_key.objectid) {
-                       ret = -ENOTEMPTY;
+                       ret = -EPERM;
+                       btrfs_err(root->fs_info, "deleting default subvolume "
+                                 "%llu is not allowed", key.objectid);
                        goto out;
                }
                btrfs_release_path(path);
@@ -2994,8 +3065,9 @@ process_slot:
                                                         new_key.offset + datal,
                                                         1);
                                if (ret) {
-                                       btrfs_abort_transaction(trans, root,
-                                                               ret);
+                                       if (ret != -EINVAL)
+                                               btrfs_abort_transaction(trans,
+                                                               root, ret);
                                        btrfs_end_transaction(trans, root);
                                        goto out;
                                }
@@ -3153,8 +3225,9 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
         *   decompress into destination's address_space (the file offset
         *   may change, so source mapping won't do), then recompress (or
         *   otherwise reinsert) a subrange.
-        * - allow ranges within the same file to be cloned (provided
-        *   they don't overlap)?
+        *
+        * - split destination inode's inline extents.  The inline extents can
+        *   be either compressed or non-compressed.
         */
 
        /* the destination must be opened for writing */
@@ -4353,10 +4426,9 @@ static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg)
        return btrfs_qgroup_wait_for_completion(root->fs_info);
 }
 
-static long btrfs_ioctl_set_received_subvol(struct file *file,
-                                           void __user *arg)
+static long _btrfs_ioctl_set_received_subvol(struct file *file,
+                                           struct btrfs_ioctl_received_subvol_args *sa)
 {
-       struct btrfs_ioctl_received_subvol_args *sa = NULL;
        struct inode *inode = file_inode(file);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_root_item *root_item = &root->root_item;
@@ -4384,13 +4456,6 @@ static long btrfs_ioctl_set_received_subvol(struct file *file,
                goto out;
        }
 
-       sa = memdup_user(arg, sizeof(*sa));
-       if (IS_ERR(sa)) {
-               ret = PTR_ERR(sa);
-               sa = NULL;
-               goto out;
-       }
-
        /*
         * 1 - root item
         * 2 - uuid items (received uuid + subvol uuid)
@@ -4444,14 +4509,91 @@ static long btrfs_ioctl_set_received_subvol(struct file *file,
                goto out;
        }
 
+out:
+       up_write(&root->fs_info->subvol_sem);
+       mnt_drop_write_file(file);
+       return ret;
+}
+
+#ifdef CONFIG_64BIT
+static long btrfs_ioctl_set_received_subvol_32(struct file *file,
+                                               void __user *arg)
+{
+       struct btrfs_ioctl_received_subvol_args_32 *args32 = NULL;
+       struct btrfs_ioctl_received_subvol_args *args64 = NULL;
+       int ret = 0;
+
+       args32 = memdup_user(arg, sizeof(*args32));
+       if (IS_ERR(args32)) {
+               ret = PTR_ERR(args32);
+               args32 = NULL;
+               goto out;
+       }
+
+       args64 = kmalloc(sizeof(*args64), GFP_NOFS);
+       if (IS_ERR(args64)) {
+               ret = PTR_ERR(args64);
+               args64 = NULL;
+               goto out;
+       }
+
+       memcpy(args64->uuid, args32->uuid, BTRFS_UUID_SIZE);
+       args64->stransid = args32->stransid;
+       args64->rtransid = args32->rtransid;
+       args64->stime.sec = args32->stime.sec;
+       args64->stime.nsec = args32->stime.nsec;
+       args64->rtime.sec = args32->rtime.sec;
+       args64->rtime.nsec = args32->rtime.nsec;
+       args64->flags = args32->flags;
+
+       ret = _btrfs_ioctl_set_received_subvol(file, args64);
+       if (ret)
+               goto out;
+
+       memcpy(args32->uuid, args64->uuid, BTRFS_UUID_SIZE);
+       args32->stransid = args64->stransid;
+       args32->rtransid = args64->rtransid;
+       args32->stime.sec = args64->stime.sec;
+       args32->stime.nsec = args64->stime.nsec;
+       args32->rtime.sec = args64->rtime.sec;
+       args32->rtime.nsec = args64->rtime.nsec;
+       args32->flags = args64->flags;
+
+       ret = copy_to_user(arg, args32, sizeof(*args32));
+       if (ret)
+               ret = -EFAULT;
+
+out:
+       kfree(args32);
+       kfree(args64);
+       return ret;
+}
+#endif
+
+static long btrfs_ioctl_set_received_subvol(struct file *file,
+                                           void __user *arg)
+{
+       struct btrfs_ioctl_received_subvol_args *sa = NULL;
+       int ret = 0;
+
+       sa = memdup_user(arg, sizeof(*sa));
+       if (IS_ERR(sa)) {
+               ret = PTR_ERR(sa);
+               sa = NULL;
+               goto out;
+       }
+
+       ret = _btrfs_ioctl_set_received_subvol(file, sa);
+
+       if (ret)
+               goto out;
+
        ret = copy_to_user(arg, sa, sizeof(*sa));
        if (ret)
                ret = -EFAULT;
 
 out:
        kfree(sa);
-       up_write(&root->fs_info->subvol_sem);
-       mnt_drop_write_file(file);
        return ret;
 }
 
@@ -4746,7 +4888,7 @@ long btrfs_ioctl(struct file *file, unsigned int
        case BTRFS_IOC_SYNC: {
                int ret;
 
-               ret = btrfs_start_delalloc_roots(root->fs_info, 0);
+               ret = btrfs_start_delalloc_roots(root->fs_info, 0, -1);
                if (ret)
                        return ret;
                ret = btrfs_sync_fs(file->f_dentry->d_sb, 1);
@@ -4770,6 +4912,10 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_balance_progress(root, argp);
        case BTRFS_IOC_SET_RECEIVED_SUBVOL:
                return btrfs_ioctl_set_received_subvol(file, argp);
+#ifdef CONFIG_64BIT
+       case BTRFS_IOC_SET_RECEIVED_SUBVOL_32:
+               return btrfs_ioctl_set_received_subvol_32(file, argp);
+#endif
        case BTRFS_IOC_SEND:
                return btrfs_ioctl_send(file, argp);
        case BTRFS_IOC_GET_DEV_STATS:
index b16450b840e73be00d42e217e0fcecb2fae1894d..a94b05f728695c464074a0e070723fec412be9bc 100644 (file)
@@ -349,10 +349,13 @@ int btrfs_dec_test_first_ordered_pending(struct inode *inode,
        if (!uptodate)
                set_bit(BTRFS_ORDERED_IOERR, &entry->flags);
 
-       if (entry->bytes_left == 0)
+       if (entry->bytes_left == 0) {
                ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
-       else
+               if (waitqueue_active(&entry->wait))
+                       wake_up(&entry->wait);
+       } else {
                ret = 1;
+       }
 out:
        if (!ret && cached && entry) {
                *cached = entry;
@@ -410,10 +413,13 @@ have_entry:
        if (!uptodate)
                set_bit(BTRFS_ORDERED_IOERR, &entry->flags);
 
-       if (entry->bytes_left == 0)
+       if (entry->bytes_left == 0) {
                ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
-       else
+               if (waitqueue_active(&entry->wait))
+                       wake_up(&entry->wait);
+       } else {
                ret = 1;
+       }
 out:
        if (!ret && cached && entry) {
                *cached = entry;
@@ -424,27 +430,48 @@ out:
 }
 
 /* Needs to either be called under a log transaction or the log_mutex */
-void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode)
+void btrfs_get_logged_extents(struct inode *inode,
+                             struct list_head *logged_list)
 {
        struct btrfs_ordered_inode_tree *tree;
        struct btrfs_ordered_extent *ordered;
        struct rb_node *n;
-       int index = log->log_transid % 2;
 
        tree = &BTRFS_I(inode)->ordered_tree;
        spin_lock_irq(&tree->lock);
        for (n = rb_first(&tree->tree); n; n = rb_next(n)) {
                ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node);
-               spin_lock(&log->log_extents_lock[index]);
-               if (list_empty(&ordered->log_list)) {
-                       list_add_tail(&ordered->log_list, &log->logged_list[index]);
-                       atomic_inc(&ordered->refs);
-               }
-               spin_unlock(&log->log_extents_lock[index]);
+               if (!list_empty(&ordered->log_list))
+                       continue;
+               list_add_tail(&ordered->log_list, logged_list);
+               atomic_inc(&ordered->refs);
        }
        spin_unlock_irq(&tree->lock);
 }
 
+void btrfs_put_logged_extents(struct list_head *logged_list)
+{
+       struct btrfs_ordered_extent *ordered;
+
+       while (!list_empty(logged_list)) {
+               ordered = list_first_entry(logged_list,
+                                          struct btrfs_ordered_extent,
+                                          log_list);
+               list_del_init(&ordered->log_list);
+               btrfs_put_ordered_extent(ordered);
+       }
+}
+
+void btrfs_submit_logged_extents(struct list_head *logged_list,
+                                struct btrfs_root *log)
+{
+       int index = log->log_transid % 2;
+
+       spin_lock_irq(&log->log_extents_lock[index]);
+       list_splice_tail(logged_list, &log->logged_list[index]);
+       spin_unlock_irq(&log->log_extents_lock[index]);
+}
+
 void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid)
 {
        struct btrfs_ordered_extent *ordered;
@@ -577,7 +604,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
        INIT_LIST_HEAD(&splice);
        INIT_LIST_HEAD(&works);
 
-       mutex_lock(&root->fs_info->ordered_operations_mutex);
+       mutex_lock(&root->ordered_extent_mutex);
        spin_lock(&root->ordered_extent_lock);
        list_splice_init(&root->ordered_extents, &splice);
        while (!list_empty(&splice) && nr) {
@@ -588,10 +615,11 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
                atomic_inc(&ordered->refs);
                spin_unlock(&root->ordered_extent_lock);
 
-               ordered->flush_work.func = btrfs_run_ordered_extent_work;
+               btrfs_init_work(&ordered->flush_work,
+                               btrfs_run_ordered_extent_work, NULL, NULL);
                list_add_tail(&ordered->work_list, &works);
-               btrfs_queue_worker(&root->fs_info->flush_workers,
-                                  &ordered->flush_work);
+               btrfs_queue_work(root->fs_info->flush_workers,
+                                &ordered->flush_work);
 
                cond_resched();
                spin_lock(&root->ordered_extent_lock);
@@ -608,7 +636,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
                btrfs_put_ordered_extent(ordered);
                cond_resched();
        }
-       mutex_unlock(&root->fs_info->ordered_operations_mutex);
+       mutex_unlock(&root->ordered_extent_mutex);
 
        return count;
 }
@@ -621,6 +649,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr)
 
        INIT_LIST_HEAD(&splice);
 
+       mutex_lock(&fs_info->ordered_operations_mutex);
        spin_lock(&fs_info->ordered_root_lock);
        list_splice_init(&fs_info->ordered_roots, &splice);
        while (!list_empty(&splice) && nr) {
@@ -643,6 +672,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr)
        }
        list_splice_tail(&splice, &fs_info->ordered_roots);
        spin_unlock(&fs_info->ordered_root_lock);
+       mutex_unlock(&fs_info->ordered_operations_mutex);
 }
 
 /*
@@ -704,8 +734,8 @@ int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans,
                        goto out;
                }
                list_add_tail(&work->list, &works);
-               btrfs_queue_worker(&root->fs_info->flush_workers,
-                                  &work->work);
+               btrfs_queue_work(root->fs_info->flush_workers,
+                                &work->work);
 
                cond_resched();
                spin_lock(&root->fs_info->ordered_root_lock);
index 9b0450f7ac20aa1d5488e2408b80768deb7438ae..246897058efb009ffd521cee2d61cb60fc0bde0f 100644 (file)
@@ -197,7 +197,11 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
                                 struct inode *inode);
 int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr);
 void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr);
-void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode);
+void btrfs_get_logged_extents(struct inode *inode,
+                             struct list_head *logged_list);
+void btrfs_put_logged_extents(struct list_head *logged_list);
+void btrfs_submit_logged_extents(struct list_head *logged_list,
+                                struct btrfs_root *log);
 void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid);
 void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid);
 int __init ordered_data_init(void);
index 472302a2d745646a2d3a051da57fb95f2865cd0f..2cf905877aaf4cab8b24d27a9bd1fc6a309d0103 100644 (file)
@@ -1509,8 +1509,8 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
                ret = qgroup_rescan_init(fs_info, 0, 1);
                if (!ret) {
                        qgroup_rescan_zero_tracking(fs_info);
-                       btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
-                                          &fs_info->qgroup_rescan_work);
+                       btrfs_queue_work(fs_info->qgroup_rescan_workers,
+                                        &fs_info->qgroup_rescan_work);
                }
                ret = 0;
        }
@@ -2095,7 +2095,8 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
 
        memset(&fs_info->qgroup_rescan_work, 0,
               sizeof(fs_info->qgroup_rescan_work));
-       fs_info->qgroup_rescan_work.func = btrfs_qgroup_rescan_worker;
+       btrfs_init_work(&fs_info->qgroup_rescan_work,
+                       btrfs_qgroup_rescan_worker, NULL, NULL);
 
        if (ret) {
 err:
@@ -2158,8 +2159,8 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
 
        qgroup_rescan_zero_tracking(fs_info);
 
-       btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
-                          &fs_info->qgroup_rescan_work);
+       btrfs_queue_work(fs_info->qgroup_rescan_workers,
+                        &fs_info->qgroup_rescan_work);
 
        return 0;
 }
@@ -2190,6 +2191,6 @@ void
 btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info)
 {
        if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN)
-               btrfs_queue_worker(&fs_info->qgroup_rescan_workers,
-                                  &fs_info->qgroup_rescan_work);
+               btrfs_queue_work(fs_info->qgroup_rescan_workers,
+                                &fs_info->qgroup_rescan_work);
 }
index 9af0b25d991a8c64653b4fa20f4dc31c2794b943..4055291a523e933c6f4a561da8b58098790cb7ba 100644 (file)
@@ -1416,20 +1416,18 @@ cleanup:
 
 static void async_rmw_stripe(struct btrfs_raid_bio *rbio)
 {
-       rbio->work.flags = 0;
-       rbio->work.func = rmw_work;
+       btrfs_init_work(&rbio->work, rmw_work, NULL, NULL);
 
-       btrfs_queue_worker(&rbio->fs_info->rmw_workers,
-                          &rbio->work);
+       btrfs_queue_work(rbio->fs_info->rmw_workers,
+                        &rbio->work);
 }
 
 static void async_read_rebuild(struct btrfs_raid_bio *rbio)
 {
-       rbio->work.flags = 0;
-       rbio->work.func = read_rebuild_work;
+       btrfs_init_work(&rbio->work, read_rebuild_work, NULL, NULL);
 
-       btrfs_queue_worker(&rbio->fs_info->rmw_workers,
-                          &rbio->work);
+       btrfs_queue_work(rbio->fs_info->rmw_workers,
+                        &rbio->work);
 }
 
 /*
@@ -1667,10 +1665,9 @@ static void btrfs_raid_unplug(struct blk_plug_cb *cb, bool from_schedule)
        plug = container_of(cb, struct btrfs_plug_cb, cb);
 
        if (from_schedule) {
-               plug->work.flags = 0;
-               plug->work.func = unplug_work;
-               btrfs_queue_worker(&plug->info->rmw_workers,
-                                  &plug->work);
+               btrfs_init_work(&plug->work, unplug_work, NULL, NULL);
+               btrfs_queue_work(plug->info->rmw_workers,
+                                &plug->work);
                return;
        }
        run_plug(plug);
index 31c797c48c3ecdf9273473a7c0669adf86f5870a..30947f923620678f9bc1a27fda49359c6b36e9a4 100644 (file)
@@ -793,10 +793,10 @@ static void reada_start_machine(struct btrfs_fs_info *fs_info)
                /* FIXME we cannot handle this properly right now */
                BUG();
        }
-       rmw->work.func = reada_start_machine_worker;
+       btrfs_init_work(&rmw->work, reada_start_machine_worker, NULL, NULL);
        rmw->fs_info = fs_info;
 
-       btrfs_queue_worker(&fs_info->readahead_workers, &rmw->work);
+       btrfs_queue_work(fs_info->readahead_workers, &rmw->work);
 }
 
 #ifdef DEBUG
index 07b3b36f40ee51657b248112a6d1f028cea9e364..def428a25b2ab915f1331fccf4d8e98d62509ec7 100644 (file)
@@ -4248,7 +4248,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        btrfs_info(extent_root->fs_info, "relocating block group %llu flags %llu",
               rc->block_group->key.objectid, rc->block_group->flags);
 
-       ret = btrfs_start_delalloc_roots(fs_info, 0);
+       ret = btrfs_start_delalloc_roots(fs_info, 0, -1);
        if (ret < 0) {
                err = ret;
                goto out;
index 1389b69059de3ba33dcccbcb9474fa7d6537afd1..38bb47e7d6b12acca994c48c8c1a41b788b62307 100644 (file)
@@ -16,6 +16,7 @@
  * Boston, MA 021110-1307, USA.
  */
 
+#include <linux/err.h>
 #include <linux/uuid.h>
 #include "ctree.h"
 #include "transaction.h"
@@ -271,7 +272,7 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
                key.offset++;
 
                root = btrfs_read_fs_root(tree_root, &root_key);
-               err = PTR_RET(root);
+               err = PTR_ERR_OR_ZERO(root);
                if (err && err != -ENOENT) {
                        break;
                } else if (err == -ENOENT) {
index efba5d1282ee40addd128cf05427181a0aade83f..93e6d717284477d02b54c290dd6956af4a23038b 100644 (file)
@@ -315,6 +315,16 @@ static void scrub_pending_trans_workers_inc(struct scrub_ctx *sctx)
        atomic_inc(&fs_info->scrubs_running);
        atomic_inc(&fs_info->scrubs_paused);
        mutex_unlock(&fs_info->scrub_lock);
+
+       /*
+        * check if @scrubs_running=@scrubs_paused condition
+        * inside wait_event() is not an atomic operation.
+        * which means we may inc/dec @scrub_running/paused
+        * at any time. Let's wake up @scrub_pause_wait as
+        * much as we can to let commit transaction blocked less.
+        */
+       wake_up(&fs_info->scrub_pause_wait);
+
        atomic_inc(&sctx->workers_pending);
 }
 
@@ -418,7 +428,8 @@ struct scrub_ctx *scrub_setup_ctx(struct btrfs_device *dev, int is_dev_replace)
                sbio->index = i;
                sbio->sctx = sctx;
                sbio->page_count = 0;
-               sbio->work.func = scrub_bio_end_io_worker;
+               btrfs_init_work(&sbio->work, scrub_bio_end_io_worker,
+                               NULL, NULL);
 
                if (i != SCRUB_BIOS_PER_SCTX - 1)
                        sctx->bios[i]->next_free = i + 1;
@@ -987,9 +998,10 @@ nodatasum_case:
                fixup_nodatasum->root = fs_info->extent_root;
                fixup_nodatasum->mirror_num = failed_mirror_index + 1;
                scrub_pending_trans_workers_inc(sctx);
-               fixup_nodatasum->work.func = scrub_fixup_nodatasum;
-               btrfs_queue_worker(&fs_info->scrub_workers,
-                                  &fixup_nodatasum->work);
+               btrfs_init_work(&fixup_nodatasum->work, scrub_fixup_nodatasum,
+                               NULL, NULL);
+               btrfs_queue_work(fs_info->scrub_workers,
+                                &fixup_nodatasum->work);
                goto out;
        }
 
@@ -1603,8 +1615,8 @@ static void scrub_wr_bio_end_io(struct bio *bio, int err)
        sbio->err = err;
        sbio->bio = bio;
 
-       sbio->work.func = scrub_wr_bio_end_io_worker;
-       btrfs_queue_worker(&fs_info->scrub_wr_completion_workers, &sbio->work);
+       btrfs_init_work(&sbio->work, scrub_wr_bio_end_io_worker, NULL, NULL);
+       btrfs_queue_work(fs_info->scrub_wr_completion_workers, &sbio->work);
 }
 
 static void scrub_wr_bio_end_io_worker(struct btrfs_work *work)
@@ -2072,7 +2084,7 @@ static void scrub_bio_end_io(struct bio *bio, int err)
        sbio->err = err;
        sbio->bio = bio;
 
-       btrfs_queue_worker(&fs_info->scrub_workers, &sbio->work);
+       btrfs_queue_work(fs_info->scrub_workers, &sbio->work);
 }
 
 static void scrub_bio_end_io_worker(struct btrfs_work *work)
@@ -2686,10 +2698,23 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
 
                wait_event(sctx->list_wait,
                           atomic_read(&sctx->bios_in_flight) == 0);
-               atomic_set(&sctx->wr_ctx.flush_all_writes, 0);
+               atomic_inc(&fs_info->scrubs_paused);
+               wake_up(&fs_info->scrub_pause_wait);
+
+               /*
+                * must be called before we decrease @scrub_paused.
+                * make sure we don't block transaction commit while
+                * we are waiting pending workers finished.
+                */
                wait_event(sctx->list_wait,
                           atomic_read(&sctx->workers_pending) == 0);
-               scrub_blocked_if_needed(fs_info);
+               atomic_set(&sctx->wr_ctx.flush_all_writes, 0);
+
+               mutex_lock(&fs_info->scrub_lock);
+               __scrub_blocked_if_needed(fs_info);
+               atomic_dec(&fs_info->scrubs_paused);
+               mutex_unlock(&fs_info->scrub_lock);
+               wake_up(&fs_info->scrub_pause_wait);
 
                btrfs_put_block_group(cache);
                if (ret)
@@ -2757,33 +2782,35 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
                                                int is_dev_replace)
 {
        int ret = 0;
+       int flags = WQ_FREEZABLE | WQ_UNBOUND;
+       int max_active = fs_info->thread_pool_size;
 
        if (fs_info->scrub_workers_refcnt == 0) {
                if (is_dev_replace)
-                       btrfs_init_workers(&fs_info->scrub_workers, "scrub", 1,
-                                       &fs_info->generic_worker);
+                       fs_info->scrub_workers =
+                               btrfs_alloc_workqueue("btrfs-scrub", flags,
+                                                     1, 4);
                else
-                       btrfs_init_workers(&fs_info->scrub_workers, "scrub",
-                                       fs_info->thread_pool_size,
-                                       &fs_info->generic_worker);
-               fs_info->scrub_workers.idle_thresh = 4;
-               ret = btrfs_start_workers(&fs_info->scrub_workers);
-               if (ret)
+                       fs_info->scrub_workers =
+                               btrfs_alloc_workqueue("btrfs-scrub", flags,
+                                                     max_active, 4);
+               if (!fs_info->scrub_workers) {
+                       ret = -ENOMEM;
                        goto out;
-               btrfs_init_workers(&fs_info->scrub_wr_completion_workers,
-                                  "scrubwrc",
-                                  fs_info->thread_pool_size,
-                                  &fs_info->generic_worker);
-               fs_info->scrub_wr_completion_workers.idle_thresh = 2;
-               ret = btrfs_start_workers(
-                               &fs_info->scrub_wr_completion_workers);
-               if (ret)
+               }
+               fs_info->scrub_wr_completion_workers =
+                       btrfs_alloc_workqueue("btrfs-scrubwrc", flags,
+                                             max_active, 2);
+               if (!fs_info->scrub_wr_completion_workers) {
+                       ret = -ENOMEM;
                        goto out;
-               btrfs_init_workers(&fs_info->scrub_nocow_workers, "scrubnc", 1,
-                                  &fs_info->generic_worker);
-               ret = btrfs_start_workers(&fs_info->scrub_nocow_workers);
-               if (ret)
+               }
+               fs_info->scrub_nocow_workers =
+                       btrfs_alloc_workqueue("btrfs-scrubnc", flags, 1, 0);
+               if (!fs_info->scrub_nocow_workers) {
+                       ret = -ENOMEM;
                        goto out;
+               }
        }
        ++fs_info->scrub_workers_refcnt;
 out:
@@ -2793,9 +2820,9 @@ out:
 static noinline_for_stack void scrub_workers_put(struct btrfs_fs_info *fs_info)
 {
        if (--fs_info->scrub_workers_refcnt == 0) {
-               btrfs_stop_workers(&fs_info->scrub_workers);
-               btrfs_stop_workers(&fs_info->scrub_wr_completion_workers);
-               btrfs_stop_workers(&fs_info->scrub_nocow_workers);
+               btrfs_destroy_workqueue(fs_info->scrub_workers);
+               btrfs_destroy_workqueue(fs_info->scrub_wr_completion_workers);
+               btrfs_destroy_workqueue(fs_info->scrub_nocow_workers);
        }
        WARN_ON(fs_info->scrub_workers_refcnt < 0);
 }
@@ -3106,10 +3133,10 @@ static int copy_nocow_pages(struct scrub_ctx *sctx, u64 logical, u64 len,
        nocow_ctx->len = len;
        nocow_ctx->mirror_num = mirror_num;
        nocow_ctx->physical_for_dev_replace = physical_for_dev_replace;
-       nocow_ctx->work.func = copy_nocow_pages_worker;
+       btrfs_init_work(&nocow_ctx->work, copy_nocow_pages_worker, NULL, NULL);
        INIT_LIST_HEAD(&nocow_ctx->inodes);
-       btrfs_queue_worker(&fs_info->scrub_nocow_workers,
-                          &nocow_ctx->work);
+       btrfs_queue_work(fs_info->scrub_nocow_workers,
+                        &nocow_ctx->work);
 
        return 0;
 }
index 9dde9717c1b9264124d007184bc4c4d60276d99c..9b6da9d55f9a8778c47cf64c15a143951fc2ccf7 100644 (file)
@@ -51,15 +51,18 @@ struct fs_path {
                struct {
                        char *start;
                        char *end;
-                       char *prepared;
 
                        char *buf;
-                       int buf_len;
-                       unsigned int reversed:1;
-                       unsigned int virtual_mem:1;
+                       unsigned short buf_len:15;
+                       unsigned short reversed:1;
                        char inline_buf[];
                };
-               char pad[PAGE_SIZE];
+               /*
+                * Average path length does not exceed 200 bytes, we'll have
+                * better packing in the slab and higher chance to satisfy
+                * a allocation later during send.
+                */
+               char pad[256];
        };
 };
 #define FS_PATH_INLINE_SIZE \
@@ -109,6 +112,7 @@ struct send_ctx {
        int cur_inode_deleted;
        u64 cur_inode_size;
        u64 cur_inode_mode;
+       u64 cur_inode_rdev;
        u64 cur_inode_last_extent;
 
        u64 send_progress;
@@ -120,6 +124,8 @@ struct send_ctx {
        struct list_head name_cache_list;
        int name_cache_size;
 
+       struct file_ra_state ra;
+
        char *read_buf;
 
        /*
@@ -175,6 +181,47 @@ struct send_ctx {
         * own move/rename can be performed.
         */
        struct rb_root waiting_dir_moves;
+
+       /*
+        * A directory that is going to be rm'ed might have a child directory
+        * which is in the pending directory moves index above. In this case,
+        * the directory can only be removed after the move/rename of its child
+        * is performed. Example:
+        *
+        * Parent snapshot:
+        *
+        * .                        (ino 256)
+        * |-- a/                   (ino 257)
+        *     |-- b/               (ino 258)
+        *         |-- c/           (ino 259)
+        *         |   |-- x/       (ino 260)
+        *         |
+        *         |-- y/           (ino 261)
+        *
+        * Send snapshot:
+        *
+        * .                        (ino 256)
+        * |-- a/                   (ino 257)
+        *     |-- b/               (ino 258)
+        *         |-- YY/          (ino 261)
+        *              |-- x/      (ino 260)
+        *
+        * Sequence of steps that lead to the send snapshot:
+        * rm -f /a/b/c/foo.txt
+        * mv /a/b/y /a/b/YY
+        * mv /a/b/c/x /a/b/YY
+        * rmdir /a/b/c
+        *
+        * When the child is processed, its move/rename is delayed until its
+        * parent is processed (as explained above), but all other operations
+        * like update utimes, chown, chgrp, etc, are performed and the paths
+        * that it uses for those operations must use the orphanized name of
+        * its parent (the directory we're going to rm later), so we need to
+        * memorize that name.
+        *
+        * Indexed by the inode number of the directory to be deleted.
+        */
+       struct rb_root orphan_dirs;
 };
 
 struct pending_dir_move {
@@ -189,6 +236,18 @@ struct pending_dir_move {
 struct waiting_dir_move {
        struct rb_node node;
        u64 ino;
+       /*
+        * There might be some directory that could not be removed because it
+        * was waiting for this directory inode to be moved first. Therefore
+        * after this directory is moved, we can try to rmdir the ino rmdir_ino.
+        */
+       u64 rmdir_ino;
+};
+
+struct orphan_dir_info {
+       struct rb_node node;
+       u64 ino;
+       u64 gen;
 };
 
 struct name_cache_entry {
@@ -214,6 +273,11 @@ struct name_cache_entry {
 
 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino);
 
+static struct waiting_dir_move *
+get_waiting_dir_move(struct send_ctx *sctx, u64 ino);
+
+static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino);
+
 static int need_send_hole(struct send_ctx *sctx)
 {
        return (sctx->parent_root && !sctx->cur_inode_new &&
@@ -242,7 +306,6 @@ static struct fs_path *fs_path_alloc(void)
        if (!p)
                return NULL;
        p->reversed = 0;
-       p->virtual_mem = 0;
        p->buf = p->inline_buf;
        p->buf_len = FS_PATH_INLINE_SIZE;
        fs_path_reset(p);
@@ -265,12 +328,8 @@ static void fs_path_free(struct fs_path *p)
 {
        if (!p)
                return;
-       if (p->buf != p->inline_buf) {
-               if (p->virtual_mem)
-                       vfree(p->buf);
-               else
-                       kfree(p->buf);
-       }
+       if (p->buf != p->inline_buf)
+               kfree(p->buf);
        kfree(p);
 }
 
@@ -292,40 +351,23 @@ static int fs_path_ensure_buf(struct fs_path *p, int len)
 
        path_len = p->end - p->start;
        old_buf_len = p->buf_len;
-       len = PAGE_ALIGN(len);
-
-       if (p->buf == p->inline_buf) {
-               tmp_buf = kmalloc(len, GFP_NOFS | __GFP_NOWARN);
-               if (!tmp_buf) {
-                       tmp_buf = vmalloc(len);
-                       if (!tmp_buf)
-                               return -ENOMEM;
-                       p->virtual_mem = 1;
-               }
-               memcpy(tmp_buf, p->buf, p->buf_len);
-               p->buf = tmp_buf;
-               p->buf_len = len;
-       } else {
-               if (p->virtual_mem) {
-                       tmp_buf = vmalloc(len);
-                       if (!tmp_buf)
-                               return -ENOMEM;
-                       memcpy(tmp_buf, p->buf, p->buf_len);
-                       vfree(p->buf);
-               } else {
-                       tmp_buf = krealloc(p->buf, len, GFP_NOFS);
-                       if (!tmp_buf) {
-                               tmp_buf = vmalloc(len);
-                               if (!tmp_buf)
-                                       return -ENOMEM;
-                               memcpy(tmp_buf, p->buf, p->buf_len);
-                               kfree(p->buf);
-                               p->virtual_mem = 1;
-                       }
-               }
-               p->buf = tmp_buf;
-               p->buf_len = len;
-       }
+
+       /*
+        * First time the inline_buf does not suffice
+        */
+       if (p->buf == p->inline_buf)
+               tmp_buf = kmalloc(len, GFP_NOFS);
+       else
+               tmp_buf = krealloc(p->buf, len, GFP_NOFS);
+       if (!tmp_buf)
+               return -ENOMEM;
+       p->buf = tmp_buf;
+       /*
+        * The real size of the buffer is bigger, this will let the fast path
+        * happen most of the time
+        */
+       p->buf_len = ksize(p->buf);
+
        if (p->reversed) {
                tmp_buf = p->buf + old_buf_len - path_len - 1;
                p->end = p->buf + p->buf_len - 1;
@@ -338,7 +380,8 @@ static int fs_path_ensure_buf(struct fs_path *p, int len)
        return 0;
 }
 
-static int fs_path_prepare_for_add(struct fs_path *p, int name_len)
+static int fs_path_prepare_for_add(struct fs_path *p, int name_len,
+                                  char **prepared)
 {
        int ret;
        int new_len;
@@ -354,11 +397,11 @@ static int fs_path_prepare_for_add(struct fs_path *p, int name_len)
                if (p->start != p->end)
                        *--p->start = '/';
                p->start -= name_len;
-               p->prepared = p->start;
+               *prepared = p->start;
        } else {
                if (p->start != p->end)
                        *p->end++ = '/';
-               p->prepared = p->end;
+               *prepared = p->end;
                p->end += name_len;
                *p->end = 0;
        }
@@ -370,12 +413,12 @@ out:
 static int fs_path_add(struct fs_path *p, const char *name, int name_len)
 {
        int ret;
+       char *prepared;
 
-       ret = fs_path_prepare_for_add(p, name_len);
+       ret = fs_path_prepare_for_add(p, name_len, &prepared);
        if (ret < 0)
                goto out;
-       memcpy(p->prepared, name, name_len);
-       p->prepared = NULL;
+       memcpy(prepared, name, name_len);
 
 out:
        return ret;
@@ -384,12 +427,12 @@ out:
 static int fs_path_add_path(struct fs_path *p, struct fs_path *p2)
 {
        int ret;
+       char *prepared;
 
-       ret = fs_path_prepare_for_add(p, p2->end - p2->start);
+       ret = fs_path_prepare_for_add(p, p2->end - p2->start, &prepared);
        if (ret < 0)
                goto out;
-       memcpy(p->prepared, p2->start, p2->end - p2->start);
-       p->prepared = NULL;
+       memcpy(prepared, p2->start, p2->end - p2->start);
 
 out:
        return ret;
@@ -400,13 +443,13 @@ static int fs_path_add_from_extent_buffer(struct fs_path *p,
                                          unsigned long off, int len)
 {
        int ret;
+       char *prepared;
 
-       ret = fs_path_prepare_for_add(p, len);
+       ret = fs_path_prepare_for_add(p, len, &prepared);
        if (ret < 0)
                goto out;
 
-       read_extent_buffer(eb, p->prepared, off, len);
-       p->prepared = NULL;
+       read_extent_buffer(eb, prepared, off, len);
 
 out:
        return ret;
@@ -915,9 +958,7 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
        struct btrfs_dir_item *di;
        struct btrfs_key di_key;
        char *buf = NULL;
-       char *buf2 = NULL;
-       int buf_len;
-       int buf_virtual = 0;
+       const int buf_len = PATH_MAX;
        u32 name_len;
        u32 data_len;
        u32 cur;
@@ -927,7 +968,6 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
        int num;
        u8 type;
 
-       buf_len = PAGE_SIZE;
        buf = kmalloc(buf_len, GFP_NOFS);
        if (!buf) {
                ret = -ENOMEM;
@@ -949,30 +989,12 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
                type = btrfs_dir_type(eb, di);
                btrfs_dir_item_key_to_cpu(eb, di, &di_key);
 
+               /*
+                * Path too long
+                */
                if (name_len + data_len > buf_len) {
-                       buf_len = PAGE_ALIGN(name_len + data_len);
-                       if (buf_virtual) {
-                               buf2 = vmalloc(buf_len);
-                               if (!buf2) {
-                                       ret = -ENOMEM;
-                                       goto out;
-                               }
-                               vfree(buf);
-                       } else {
-                               buf2 = krealloc(buf, buf_len, GFP_NOFS);
-                               if (!buf2) {
-                                       buf2 = vmalloc(buf_len);
-                                       if (!buf2) {
-                                               ret = -ENOMEM;
-                                               goto out;
-                                       }
-                                       kfree(buf);
-                                       buf_virtual = 1;
-                               }
-                       }
-
-                       buf = buf2;
-                       buf2 = NULL;
+                       ret = -ENAMETOOLONG;
+                       goto out;
                }
 
                read_extent_buffer(eb, buf, (unsigned long)(di + 1),
@@ -995,10 +1017,7 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
        }
 
 out:
-       if (buf_virtual)
-               vfree(buf);
-       else
-               kfree(buf);
+       kfree(buf);
        return ret;
 }
 
@@ -1292,8 +1311,6 @@ static int find_extent_clone(struct send_ctx *sctx,
                extent_item_pos = logical - found_key.objectid;
        else
                extent_item_pos = 0;
-
-       extent_item_pos = logical - found_key.objectid;
        ret = iterate_extent_inodes(sctx->send_root->fs_info,
                                        found_key.objectid, extent_item_pos, 1,
                                        __iterate_backrefs, backref_ctx);
@@ -1418,11 +1435,7 @@ static int gen_unique_name(struct send_ctx *sctx,
        while (1) {
                len = snprintf(tmp, sizeof(tmp), "o%llu-%llu-%llu",
                                ino, gen, idx);
-               if (len >= sizeof(tmp)) {
-                       /* should really not happen */
-                       ret = -EOVERFLOW;
-                       goto out;
-               }
+               ASSERT(len < sizeof(tmp));
 
                di = btrfs_lookup_dir_item(NULL, sctx->send_root,
                                path, BTRFS_FIRST_FREE_OBJECTID,
@@ -1898,13 +1911,20 @@ static void name_cache_delete(struct send_ctx *sctx,
 
        nce_head = radix_tree_lookup(&sctx->name_cache,
                        (unsigned long)nce->ino);
-       BUG_ON(!nce_head);
+       if (!nce_head) {
+               btrfs_err(sctx->send_root->fs_info,
+             "name_cache_delete lookup failed ino %llu cache size %d, leaking memory",
+                       nce->ino, sctx->name_cache_size);
+       }
 
        list_del(&nce->radix_list);
        list_del(&nce->list);
        sctx->name_cache_size--;
 
-       if (list_empty(nce_head)) {
+       /*
+        * We may not get to the final release of nce_head if the lookup fails
+        */
+       if (nce_head && list_empty(nce_head)) {
                radix_tree_delete(&sctx->name_cache, (unsigned long)nce->ino);
                kfree(nce_head);
        }
@@ -1977,7 +1997,6 @@ static void name_cache_free(struct send_ctx *sctx)
  */
 static int __get_cur_name_and_parent(struct send_ctx *sctx,
                                     u64 ino, u64 gen,
-                                    int skip_name_cache,
                                     u64 *parent_ino,
                                     u64 *parent_gen,
                                     struct fs_path *dest)
@@ -1987,8 +2006,6 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
        struct btrfs_path *path = NULL;
        struct name_cache_entry *nce = NULL;
 
-       if (skip_name_cache)
-               goto get_ref;
        /*
         * First check if we already did a call to this function with the same
         * ino/gen. If yes, check if the cache entry is still up-to-date. If yes
@@ -2033,12 +2050,11 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
                goto out_cache;
        }
 
-get_ref:
        /*
         * Depending on whether the inode was already processed or not, use
         * send_root or parent_root for ref lookup.
         */
-       if (ino < sctx->send_progress && !skip_name_cache)
+       if (ino < sctx->send_progress)
                ret = get_first_ref(sctx->send_root, ino,
                                    parent_ino, parent_gen, dest);
        else
@@ -2062,8 +2078,6 @@ get_ref:
                        goto out;
                ret = 1;
        }
-       if (skip_name_cache)
-               goto out;
 
 out_cache:
        /*
@@ -2131,9 +2145,6 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
        u64 parent_inode = 0;
        u64 parent_gen = 0;
        int stop = 0;
-       u64 start_ino = ino;
-       u64 start_gen = gen;
-       int skip_name_cache = 0;
 
        name = fs_path_alloc();
        if (!name) {
@@ -2141,31 +2152,33 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen,
                goto out;
        }
 
-       if (is_waiting_for_move(sctx, ino))
-               skip_name_cache = 1;
-
-again:
        dest->reversed = 1;
        fs_path_reset(dest);
 
        while (!stop && ino != BTRFS_FIRST_FREE_OBJECTID) {
                fs_path_reset(name);
 
-               ret = __get_cur_name_and_parent(sctx, ino, gen, skip_name_cache,
-                               &parent_inode, &parent_gen, name);
+               if (is_waiting_for_rm(sctx, ino)) {
+                       ret = gen_unique_name(sctx, ino, gen, name);
+                       if (ret < 0)
+                               goto out;
+                       ret = fs_path_add_path(dest, name);
+                       break;
+               }
+
+               if (is_waiting_for_move(sctx, ino)) {
+                       ret = get_first_ref(sctx->parent_root, ino,
+                                           &parent_inode, &parent_gen, name);
+               } else {
+                       ret = __get_cur_name_and_parent(sctx, ino, gen,
+                                                       &parent_inode,
+                                                       &parent_gen, name);
+                       if (ret)
+                               stop = 1;
+               }
+
                if (ret < 0)
                        goto out;
-               if (ret)
-                       stop = 1;
-
-               if (!skip_name_cache &&
-                   is_waiting_for_move(sctx, parent_inode)) {
-                       ino = start_ino;
-                       gen = start_gen;
-                       stop = 0;
-                       skip_name_cache = 1;
-                       goto again;
-               }
 
                ret = fs_path_add_path(dest, name);
                if (ret < 0)
@@ -2429,10 +2442,16 @@ verbose_printk("btrfs: send_create_inode %llu\n", ino);
        if (!p)
                return -ENOMEM;
 
-       ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode, NULL,
-                       NULL, &rdev);
-       if (ret < 0)
-               goto out;
+       if (ino != sctx->cur_ino) {
+               ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode,
+                                    NULL, NULL, &rdev);
+               if (ret < 0)
+                       goto out;
+       } else {
+               gen = sctx->cur_inode_gen;
+               mode = sctx->cur_inode_mode;
+               rdev = sctx->cur_inode_rdev;
+       }
 
        if (S_ISREG(mode)) {
                cmd = BTRFS_SEND_C_MKFILE;
@@ -2512,17 +2531,26 @@ static int did_create_dir(struct send_ctx *sctx, u64 dir)
        key.objectid = dir;
        key.type = BTRFS_DIR_INDEX_KEY;
        key.offset = 0;
+       ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0);
+       if (ret < 0)
+               goto out;
+
        while (1) {
-               ret = btrfs_search_slot_for_read(sctx->send_root, &key, path,
-                               1, 0);
-               if (ret < 0)
-                       goto out;
-               if (!ret) {
-                       eb = path->nodes[0];
-                       slot = path->slots[0];
-                       btrfs_item_key_to_cpu(eb, &found_key, slot);
+               eb = path->nodes[0];
+               slot = path->slots[0];
+               if (slot >= btrfs_header_nritems(eb)) {
+                       ret = btrfs_next_leaf(sctx->send_root, path);
+                       if (ret < 0) {
+                               goto out;
+                       } else if (ret > 0) {
+                               ret = 0;
+                               break;
+                       }
+                       continue;
                }
-               if (ret || found_key.objectid != key.objectid ||
+
+               btrfs_item_key_to_cpu(eb, &found_key, slot);
+               if (found_key.objectid != key.objectid ||
                    found_key.type != key.type) {
                        ret = 0;
                        goto out;
@@ -2537,8 +2565,7 @@ static int did_create_dir(struct send_ctx *sctx, u64 dir)
                        goto out;
                }
 
-               key.offset = found_key.offset + 1;
-               btrfs_release_path(path);
+               path->slots[0]++;
        }
 
 out:
@@ -2590,7 +2617,7 @@ struct recorded_ref {
  * everything mixed. So we first record all refs and later process them.
  * This function is a helper to record one ref.
  */
-static int record_ref(struct list_head *head, u64 dir,
+static int __record_ref(struct list_head *head, u64 dir,
                      u64 dir_gen, struct fs_path *path)
 {
        struct recorded_ref *ref;
@@ -2676,12 +2703,78 @@ out:
        return ret;
 }
 
+static struct orphan_dir_info *
+add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
+{
+       struct rb_node **p = &sctx->orphan_dirs.rb_node;
+       struct rb_node *parent = NULL;
+       struct orphan_dir_info *entry, *odi;
+
+       odi = kmalloc(sizeof(*odi), GFP_NOFS);
+       if (!odi)
+               return ERR_PTR(-ENOMEM);
+       odi->ino = dir_ino;
+       odi->gen = 0;
+
+       while (*p) {
+               parent = *p;
+               entry = rb_entry(parent, struct orphan_dir_info, node);
+               if (dir_ino < entry->ino) {
+                       p = &(*p)->rb_left;
+               } else if (dir_ino > entry->ino) {
+                       p = &(*p)->rb_right;
+               } else {
+                       kfree(odi);
+                       return entry;
+               }
+       }
+
+       rb_link_node(&odi->node, parent, p);
+       rb_insert_color(&odi->node, &sctx->orphan_dirs);
+       return odi;
+}
+
+static struct orphan_dir_info *
+get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino)
+{
+       struct rb_node *n = sctx->orphan_dirs.rb_node;
+       struct orphan_dir_info *entry;
+
+       while (n) {
+               entry = rb_entry(n, struct orphan_dir_info, node);
+               if (dir_ino < entry->ino)
+                       n = n->rb_left;
+               else if (dir_ino > entry->ino)
+                       n = n->rb_right;
+               else
+                       return entry;
+       }
+       return NULL;
+}
+
+static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino)
+{
+       struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino);
+
+       return odi != NULL;
+}
+
+static void free_orphan_dir_info(struct send_ctx *sctx,
+                                struct orphan_dir_info *odi)
+{
+       if (!odi)
+               return;
+       rb_erase(&odi->node, &sctx->orphan_dirs);
+       kfree(odi);
+}
+
 /*
  * Returns 1 if a directory can be removed at this point in time.
  * We check this by iterating all dir items and checking if the inode behind
  * the dir item was already processed.
  */
-static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 send_progress)
+static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen,
+                    u64 send_progress)
 {
        int ret = 0;
        struct btrfs_root *root = sctx->parent_root;
@@ -2704,31 +2797,52 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 send_progress)
        key.objectid = dir;
        key.type = BTRFS_DIR_INDEX_KEY;
        key.offset = 0;
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0)
+               goto out;
 
        while (1) {
-               ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
-               if (ret < 0)
-                       goto out;
-               if (!ret) {
-                       btrfs_item_key_to_cpu(path->nodes[0], &found_key,
-                                       path->slots[0]);
+               struct waiting_dir_move *dm;
+
+               if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
+                       ret = btrfs_next_leaf(root, path);
+                       if (ret < 0)
+                               goto out;
+                       else if (ret > 0)
+                               break;
+                       continue;
                }
-               if (ret || found_key.objectid != key.objectid ||
-                   found_key.type != key.type) {
+               btrfs_item_key_to_cpu(path->nodes[0], &found_key,
+                                     path->slots[0]);
+               if (found_key.objectid != key.objectid ||
+                   found_key.type != key.type)
                        break;
-               }
 
                di = btrfs_item_ptr(path->nodes[0], path->slots[0],
                                struct btrfs_dir_item);
                btrfs_dir_item_key_to_cpu(path->nodes[0], di, &loc);
 
+               dm = get_waiting_dir_move(sctx, loc.objectid);
+               if (dm) {
+                       struct orphan_dir_info *odi;
+
+                       odi = add_orphan_dir_info(sctx, dir);
+                       if (IS_ERR(odi)) {
+                               ret = PTR_ERR(odi);
+                               goto out;
+                       }
+                       odi->gen = dir_gen;
+                       dm->rmdir_ino = dir;
+                       ret = 0;
+                       goto out;
+               }
+
                if (loc.objectid > send_progress) {
                        ret = 0;
                        goto out;
                }
 
-               btrfs_release_path(path);
-               key.offset = found_key.offset + 1;
+               path->slots[0]++;
        }
 
        ret = 1;
@@ -2740,19 +2854,9 @@ out:
 
 static int is_waiting_for_move(struct send_ctx *sctx, u64 ino)
 {
-       struct rb_node *n = sctx->waiting_dir_moves.rb_node;
-       struct waiting_dir_move *entry;
+       struct waiting_dir_move *entry = get_waiting_dir_move(sctx, ino);
 
-       while (n) {
-               entry = rb_entry(n, struct waiting_dir_move, node);
-               if (ino < entry->ino)
-                       n = n->rb_left;
-               else if (ino > entry->ino)
-                       n = n->rb_right;
-               else
-                       return 1;
-       }
-       return 0;
+       return entry != NULL;
 }
 
 static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino)
@@ -2765,6 +2869,7 @@ static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino)
        if (!dm)
                return -ENOMEM;
        dm->ino = ino;
+       dm->rmdir_ino = 0;
 
        while (*p) {
                parent = *p;
@@ -2784,31 +2889,41 @@ static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino)
        return 0;
 }
 
-static int del_waiting_dir_move(struct send_ctx *sctx, u64 ino)
+static struct waiting_dir_move *
+get_waiting_dir_move(struct send_ctx *sctx, u64 ino)
 {
        struct rb_node *n = sctx->waiting_dir_moves.rb_node;
        struct waiting_dir_move *entry;
 
        while (n) {
                entry = rb_entry(n, struct waiting_dir_move, node);
-               if (ino < entry->ino) {
+               if (ino < entry->ino)
                        n = n->rb_left;
-               } else if (ino > entry->ino) {
+               else if (ino > entry->ino)
                        n = n->rb_right;
-               } else {
-                       rb_erase(&entry->node, &sctx->waiting_dir_moves);
-                       kfree(entry);
-                       return 0;
-               }
+               else
+                       return entry;
        }
-       return -ENOENT;
+       return NULL;
+}
+
+static void free_waiting_dir_move(struct send_ctx *sctx,
+                                 struct waiting_dir_move *dm)
+{
+       if (!dm)
+               return;
+       rb_erase(&dm->node, &sctx->waiting_dir_moves);
+       kfree(dm);
 }
 
-static int add_pending_dir_move(struct send_ctx *sctx, u64 parent_ino)
+static int add_pending_dir_move(struct send_ctx *sctx,
+                               u64 ino,
+                               u64 ino_gen,
+                               u64 parent_ino)
 {
        struct rb_node **p = &sctx->pending_dir_moves.rb_node;
        struct rb_node *parent = NULL;
-       struct pending_dir_move *entry, *pm;
+       struct pending_dir_move *entry = NULL, *pm;
        struct recorded_ref *cur;
        int exists = 0;
        int ret;
@@ -2817,8 +2932,8 @@ static int add_pending_dir_move(struct send_ctx *sctx, u64 parent_ino)
        if (!pm)
                return -ENOMEM;
        pm->parent_ino = parent_ino;
-       pm->ino = sctx->cur_ino;
-       pm->gen = sctx->cur_inode_gen;
+       pm->ino = ino;
+       pm->gen = ino_gen;
        INIT_LIST_HEAD(&pm->list);
        INIT_LIST_HEAD(&pm->update_refs);
        RB_CLEAR_NODE(&pm->node);
@@ -2888,19 +3003,52 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
 {
        struct fs_path *from_path = NULL;
        struct fs_path *to_path = NULL;
+       struct fs_path *name = NULL;
        u64 orig_progress = sctx->send_progress;
        struct recorded_ref *cur;
+       u64 parent_ino, parent_gen;
+       struct waiting_dir_move *dm = NULL;
+       u64 rmdir_ino = 0;
        int ret;
 
+       name = fs_path_alloc();
        from_path = fs_path_alloc();
-       if (!from_path)
-               return -ENOMEM;
+       if (!name || !from_path) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
-       sctx->send_progress = pm->ino;
-       ret = get_cur_path(sctx, pm->ino, pm->gen, from_path);
+       dm = get_waiting_dir_move(sctx, pm->ino);
+       ASSERT(dm);
+       rmdir_ino = dm->rmdir_ino;
+       free_waiting_dir_move(sctx, dm);
+
+       ret = get_first_ref(sctx->parent_root, pm->ino,
+                           &parent_ino, &parent_gen, name);
        if (ret < 0)
                goto out;
 
+       if (parent_ino == sctx->cur_ino) {
+               /* child only renamed, not moved */
+               ASSERT(parent_gen == sctx->cur_inode_gen);
+               ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
+                                  from_path);
+               if (ret < 0)
+                       goto out;
+               ret = fs_path_add_path(from_path, name);
+               if (ret < 0)
+                       goto out;
+       } else {
+               /* child moved and maybe renamed too */
+               sctx->send_progress = pm->ino;
+               ret = get_cur_path(sctx, pm->ino, pm->gen, from_path);
+               if (ret < 0)
+                       goto out;
+       }
+
+       fs_path_free(name);
+       name = NULL;
+
        to_path = fs_path_alloc();
        if (!to_path) {
                ret = -ENOMEM;
@@ -2908,9 +3056,6 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
        }
 
        sctx->send_progress = sctx->cur_ino + 1;
-       ret = del_waiting_dir_move(sctx, pm->ino);
-       ASSERT(ret == 0);
-
        ret = get_cur_path(sctx, pm->ino, pm->gen, to_path);
        if (ret < 0)
                goto out;
@@ -2919,6 +3064,35 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
        if (ret < 0)
                goto out;
 
+       if (rmdir_ino) {
+               struct orphan_dir_info *odi;
+
+               odi = get_orphan_dir_info(sctx, rmdir_ino);
+               if (!odi) {
+                       /* already deleted */
+                       goto finish;
+               }
+               ret = can_rmdir(sctx, rmdir_ino, odi->gen, sctx->cur_ino + 1);
+               if (ret < 0)
+                       goto out;
+               if (!ret)
+                       goto finish;
+
+               name = fs_path_alloc();
+               if (!name) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               ret = get_cur_path(sctx, rmdir_ino, odi->gen, name);
+               if (ret < 0)
+                       goto out;
+               ret = send_rmdir(sctx, name);
+               if (ret < 0)
+                       goto out;
+               free_orphan_dir_info(sctx, odi);
+       }
+
+finish:
        ret = send_utimes(sctx, pm->ino, pm->gen);
        if (ret < 0)
                goto out;
@@ -2928,12 +3102,15 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
         * and old parent(s).
         */
        list_for_each_entry(cur, &pm->update_refs, list) {
+               if (cur->dir == rmdir_ino)
+                       continue;
                ret = send_utimes(sctx, cur->dir, cur->dir_gen);
                if (ret < 0)
                        goto out;
        }
 
 out:
+       fs_path_free(name);
        fs_path_free(from_path);
        fs_path_free(to_path);
        sctx->send_progress = orig_progress;
@@ -3005,17 +3182,19 @@ static int wait_for_parent_move(struct send_ctx *sctx,
        int ret;
        u64 ino = parent_ref->dir;
        u64 parent_ino_before, parent_ino_after;
-       u64 new_gen, old_gen;
+       u64 old_gen;
        struct fs_path *path_before = NULL;
        struct fs_path *path_after = NULL;
        int len1, len2;
-
-       if (parent_ref->dir <= sctx->cur_ino)
-               return 0;
+       int register_upper_dirs;
+       u64 gen;
 
        if (is_waiting_for_move(sctx, ino))
                return 1;
 
+       if (parent_ref->dir <= sctx->cur_ino)
+               return 0;
+
        ret = get_inode_info(sctx->parent_root, ino, NULL, &old_gen,
                             NULL, NULL, NULL, NULL);
        if (ret == -ENOENT)
@@ -3023,12 +3202,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
        else if (ret < 0)
                return ret;
 
-       ret = get_inode_info(sctx->send_root, ino, NULL, &new_gen,
-                            NULL, NULL, NULL, NULL);
-       if (ret < 0)
-               return ret;
-
-       if (new_gen != old_gen)
+       if (parent_ref->dir_gen != old_gen)
                return 0;
 
        path_before = fs_path_alloc();
@@ -3051,7 +3225,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
        }
 
        ret = get_first_ref(sctx->send_root, ino, &parent_ino_after,
-                           NULL, path_after);
+                           &gen, path_after);
        if (ret == -ENOENT) {
                ret = 0;
                goto out;
@@ -3061,13 +3235,67 @@ static int wait_for_parent_move(struct send_ctx *sctx,
 
        len1 = fs_path_len(path_before);
        len2 = fs_path_len(path_after);
-       if ((parent_ino_before != parent_ino_after) && (len1 != len2 ||
-            memcmp(path_before->start, path_after->start, len1))) {
+       if (parent_ino_before != parent_ino_after || len1 != len2 ||
+            memcmp(path_before->start, path_after->start, len1)) {
                ret = 1;
                goto out;
        }
        ret = 0;
 
+       /*
+        * Ok, our new most direct ancestor has a higher inode number but
+        * wasn't moved/renamed. So maybe some of the new ancestors higher in
+        * the hierarchy have an higher inode number too *and* were renamed
+        * or moved - in this case we need to wait for the ancestor's rename
+        * or move operation before we can do the move/rename for the current
+        * inode.
+        */
+       register_upper_dirs = 0;
+       ino = parent_ino_after;
+again:
+       while ((ret == 0 || register_upper_dirs) && ino > sctx->cur_ino) {
+               u64 parent_gen;
+
+               fs_path_reset(path_before);
+               fs_path_reset(path_after);
+
+               ret = get_first_ref(sctx->send_root, ino, &parent_ino_after,
+                                   &parent_gen, path_after);
+               if (ret < 0)
+                       goto out;
+               ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before,
+                                   NULL, path_before);
+               if (ret == -ENOENT) {
+                       ret = 0;
+                       break;
+               } else if (ret < 0) {
+                       goto out;
+               }
+
+               len1 = fs_path_len(path_before);
+               len2 = fs_path_len(path_after);
+               if (parent_ino_before != parent_ino_after || len1 != len2 ||
+                   memcmp(path_before->start, path_after->start, len1)) {
+                       ret = 1;
+                       if (register_upper_dirs) {
+                               break;
+                       } else {
+                               register_upper_dirs = 1;
+                               ino = parent_ref->dir;
+                               gen = parent_ref->dir_gen;
+                               goto again;
+                       }
+               } else if (register_upper_dirs) {
+                       ret = add_pending_dir_move(sctx, ino, gen,
+                                                  parent_ino_after);
+                       if (ret < 0 && ret != -EEXIST)
+                               goto out;
+               }
+
+               ino = parent_ino_after;
+               gen = parent_gen;
+       }
+
 out:
        fs_path_free(path_before);
        fs_path_free(path_after);
@@ -3089,6 +3317,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
        u64 ow_gen;
        int did_overwrite = 0;
        int is_orphan = 0;
+       u64 last_dir_ino_rm = 0;
 
 verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
 
@@ -3227,9 +3456,14 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
                                 * dirs, we always have one new and one deleted
                                 * ref. The deleted ref is ignored later.
                                 */
-                               if (wait_for_parent_move(sctx, cur)) {
+                               ret = wait_for_parent_move(sctx, cur);
+                               if (ret < 0)
+                                       goto out;
+                               if (ret) {
                                        ret = add_pending_dir_move(sctx,
-                                                                  cur->dir);
+                                                          sctx->cur_ino,
+                                                          sctx->cur_inode_gen,
+                                                          cur->dir);
                                        *pending_move = 1;
                                } else {
                                        ret = send_rename(sctx, valid_path,
@@ -3259,7 +3493,8 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
                 * later, we do this check again and rmdir it then if possible.
                 * See the use of check_dirs for more details.
                 */
-               ret = can_rmdir(sctx, sctx->cur_ino, sctx->cur_ino);
+               ret = can_rmdir(sctx, sctx->cur_ino, sctx->cur_inode_gen,
+                               sctx->cur_ino);
                if (ret < 0)
                        goto out;
                if (ret) {
@@ -3350,8 +3585,10 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
                        ret = send_utimes(sctx, cur->dir, cur->dir_gen);
                        if (ret < 0)
                                goto out;
-               } else if (ret == inode_state_did_delete) {
-                       ret = can_rmdir(sctx, cur->dir, sctx->cur_ino);
+               } else if (ret == inode_state_did_delete &&
+                          cur->dir != last_dir_ino_rm) {
+                       ret = can_rmdir(sctx, cur->dir, cur->dir_gen,
+                                       sctx->cur_ino);
                        if (ret < 0)
                                goto out;
                        if (ret) {
@@ -3362,6 +3599,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
                                ret = send_rmdir(sctx, valid_path);
                                if (ret < 0)
                                        goto out;
+                               last_dir_ino_rm = cur->dir;
                        }
                }
        }
@@ -3375,9 +3613,8 @@ out:
        return ret;
 }
 
-static int __record_new_ref(int num, u64 dir, int index,
-                           struct fs_path *name,
-                           void *ctx)
+static int record_ref(struct btrfs_root *root, int num, u64 dir, int index,
+                     struct fs_path *name, void *ctx, struct list_head *refs)
 {
        int ret = 0;
        struct send_ctx *sctx = ctx;
@@ -3388,7 +3625,7 @@ static int __record_new_ref(int num, u64 dir, int index,
        if (!p)
                return -ENOMEM;
 
-       ret = get_inode_info(sctx->send_root, dir, NULL, &gen, NULL, NULL,
+       ret = get_inode_info(root, dir, NULL, &gen, NULL, NULL,
                        NULL, NULL);
        if (ret < 0)
                goto out;
@@ -3400,7 +3637,7 @@ static int __record_new_ref(int num, u64 dir, int index,
        if (ret < 0)
                goto out;
 
-       ret = record_ref(&sctx->new_refs, dir, gen, p);
+       ret = __record_ref(refs, dir, gen, p);
 
 out:
        if (ret)
@@ -3408,37 +3645,23 @@ out:
        return ret;
 }
 
+static int __record_new_ref(int num, u64 dir, int index,
+                           struct fs_path *name,
+                           void *ctx)
+{
+       struct send_ctx *sctx = ctx;
+       return record_ref(sctx->send_root, num, dir, index, name,
+                         ctx, &sctx->new_refs);
+}
+
+
 static int __record_deleted_ref(int num, u64 dir, int index,
                                struct fs_path *name,
                                void *ctx)
 {
-       int ret = 0;
        struct send_ctx *sctx = ctx;
-       struct fs_path *p;
-       u64 gen;
-
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
-
-       ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, NULL,
-                       NULL, NULL);
-       if (ret < 0)
-               goto out;
-
-       ret = get_cur_path(sctx, dir, gen, p);
-       if (ret < 0)
-               goto out;
-       ret = fs_path_add_path(p, name);
-       if (ret < 0)
-               goto out;
-
-       ret = record_ref(&sctx->deleted_refs, dir, gen, p);
-
-out:
-       if (ret)
-               fs_path_free(p);
-       return ret;
+       return record_ref(sctx->parent_root, num, dir, index, name,
+                         ctx, &sctx->deleted_refs);
 }
 
 static int record_new_ref(struct send_ctx *sctx)
@@ -3619,21 +3842,31 @@ static int process_all_refs(struct send_ctx *sctx,
                root = sctx->parent_root;
                cb = __record_deleted_ref;
        } else {
-               BUG();
+               btrfs_err(sctx->send_root->fs_info,
+                               "Wrong command %d in process_all_refs", cmd);
+               ret = -EINVAL;
+               goto out;
        }
 
        key.objectid = sctx->cmp_key->objectid;
        key.type = BTRFS_INODE_REF_KEY;
        key.offset = 0;
-       while (1) {
-               ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
-               if (ret < 0)
-                       goto out;
-               if (ret)
-                       break;
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0)
+               goto out;
 
+       while (1) {
                eb = path->nodes[0];
                slot = path->slots[0];
+               if (slot >= btrfs_header_nritems(eb)) {
+                       ret = btrfs_next_leaf(root, path);
+                       if (ret < 0)
+                               goto out;
+                       else if (ret > 0)
+                               break;
+                       continue;
+               }
+
                btrfs_item_key_to_cpu(eb, &found_key, slot);
 
                if (found_key.objectid != key.objectid ||
@@ -3642,11 +3875,10 @@ static int process_all_refs(struct send_ctx *sctx,
                        break;
 
                ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx);
-               btrfs_release_path(path);
                if (ret < 0)
                        goto out;
 
-               key.offset = found_key.offset + 1;
+               path->slots[0]++;
        }
        btrfs_release_path(path);
 
@@ -3927,19 +4159,25 @@ static int process_all_new_xattrs(struct send_ctx *sctx)
        key.objectid = sctx->cmp_key->objectid;
        key.type = BTRFS_XATTR_ITEM_KEY;
        key.offset = 0;
-       while (1) {
-               ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
-               if (ret < 0)
-                       goto out;
-               if (ret) {
-                       ret = 0;
-                       goto out;
-               }
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0)
+               goto out;
 
+       while (1) {
                eb = path->nodes[0];
                slot = path->slots[0];
-               btrfs_item_key_to_cpu(eb, &found_key, slot);
+               if (slot >= btrfs_header_nritems(eb)) {
+                       ret = btrfs_next_leaf(root, path);
+                       if (ret < 0) {
+                               goto out;
+                       } else if (ret > 0) {
+                               ret = 0;
+                               break;
+                       }
+                       continue;
+               }
 
+               btrfs_item_key_to_cpu(eb, &found_key, slot);
                if (found_key.objectid != key.objectid ||
                    found_key.type != key.type) {
                        ret = 0;
@@ -3951,8 +4189,7 @@ static int process_all_new_xattrs(struct send_ctx *sctx)
                if (ret < 0)
                        goto out;
 
-               btrfs_release_path(path);
-               key.offset = found_key.offset + 1;
+               path->slots[0]++;
        }
 
 out:
@@ -3991,6 +4228,13 @@ static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len)
                goto out;
 
        last_index = (offset + len - 1) >> PAGE_CACHE_SHIFT;
+
+       /* initial readahead */
+       memset(&sctx->ra, 0, sizeof(struct file_ra_state));
+       file_ra_state_init(&sctx->ra, inode->i_mapping);
+       btrfs_force_ra(inode->i_mapping, &sctx->ra, NULL, index,
+                      last_index - index + 1);
+
        while (index <= last_index) {
                unsigned cur_len = min_t(unsigned, len,
                                         PAGE_CACHE_SIZE - pg_offset);
@@ -4763,18 +5007,19 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
                ret = apply_children_dir_moves(sctx);
                if (ret)
                        goto out;
+               /*
+                * Need to send that every time, no matter if it actually
+                * changed between the two trees as we have done changes to
+                * the inode before. If our inode is a directory and it's
+                * waiting to be moved/renamed, we will send its utimes when
+                * it's moved/renamed, therefore we don't need to do it here.
+                */
+               sctx->send_progress = sctx->cur_ino + 1;
+               ret = send_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen);
+               if (ret < 0)
+                       goto out;
        }
 
-       /*
-        * Need to send that every time, no matter if it actually
-        * changed between the two trees as we have done changes to
-        * the inode before.
-        */
-       sctx->send_progress = sctx->cur_ino + 1;
-       ret = send_utimes(sctx, sctx->cur_ino, sctx->cur_inode_gen);
-       if (ret < 0)
-               goto out;
-
 out:
        return ret;
 }
@@ -4840,6 +5085,8 @@ static int changed_inode(struct send_ctx *sctx,
                                sctx->left_path->nodes[0], left_ii);
                sctx->cur_inode_mode = btrfs_inode_mode(
                                sctx->left_path->nodes[0], left_ii);
+               sctx->cur_inode_rdev = btrfs_inode_rdev(
+                               sctx->left_path->nodes[0], left_ii);
                if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
                        ret = send_create_inode_if_needed(sctx);
        } else if (result == BTRFS_COMPARE_TREE_DELETED) {
@@ -4884,6 +5131,8 @@ static int changed_inode(struct send_ctx *sctx,
                                        sctx->left_path->nodes[0], left_ii);
                        sctx->cur_inode_mode = btrfs_inode_mode(
                                        sctx->left_path->nodes[0], left_ii);
+                       sctx->cur_inode_rdev = btrfs_inode_rdev(
+                                       sctx->left_path->nodes[0], left_ii);
                        ret = send_create_inode_if_needed(sctx);
                        if (ret < 0)
                                goto out;
@@ -5118,6 +5367,7 @@ out:
 static int full_send_tree(struct send_ctx *sctx)
 {
        int ret;
+       struct btrfs_trans_handle *trans = NULL;
        struct btrfs_root *send_root = sctx->send_root;
        struct btrfs_key key;
        struct btrfs_key found_key;
@@ -5139,6 +5389,19 @@ static int full_send_tree(struct send_ctx *sctx)
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
 
+join_trans:
+       /*
+        * We need to make sure the transaction does not get committed
+        * while we do anything on commit roots. Join a transaction to prevent
+        * this.
+        */
+       trans = btrfs_join_transaction(send_root);
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               trans = NULL;
+               goto out;
+       }
+
        /*
         * Make sure the tree has not changed after re-joining. We detect this
         * by comparing start_ctransid and ctransid. They should always match.
@@ -5162,6 +5425,19 @@ static int full_send_tree(struct send_ctx *sctx)
                goto out_finish;
 
        while (1) {
+               /*
+                * When someone want to commit while we iterate, end the
+                * joined transaction and rejoin.
+                */
+               if (btrfs_should_end_transaction(trans, send_root)) {
+                       ret = btrfs_end_transaction(trans, send_root);
+                       trans = NULL;
+                       if (ret < 0)
+                               goto out;
+                       btrfs_release_path(path);
+                       goto join_trans;
+               }
+
                eb = path->nodes[0];
                slot = path->slots[0];
                btrfs_item_key_to_cpu(eb, &found_key, slot);
@@ -5189,6 +5465,12 @@ out_finish:
 
 out:
        btrfs_free_path(path);
+       if (trans) {
+               if (!ret)
+                       ret = btrfs_end_transaction(trans, send_root);
+               else
+                       btrfs_end_transaction(trans, send_root);
+       }
        return ret;
 }
 
@@ -5340,6 +5622,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
 
        sctx->pending_dir_moves = RB_ROOT;
        sctx->waiting_dir_moves = RB_ROOT;
+       sctx->orphan_dirs = RB_ROOT;
 
        sctx->clone_roots = vzalloc(sizeof(struct clone_root) *
                        (arg->clone_sources_count + 1));
@@ -5477,6 +5760,16 @@ out:
                kfree(dm);
        }
 
+       WARN_ON(sctx && !ret && !RB_EMPTY_ROOT(&sctx->orphan_dirs));
+       while (sctx && !RB_EMPTY_ROOT(&sctx->orphan_dirs)) {
+               struct rb_node *n;
+               struct orphan_dir_info *odi;
+
+               n = rb_first(&sctx->orphan_dirs);
+               odi = rb_entry(n, struct orphan_dir_info, node);
+               free_orphan_dir_info(sctx, odi);
+       }
+
        if (sort_clone_roots) {
                for (i = 0; i < sctx->clone_roots_cnt; i++)
                        btrfs_root_dec_send_in_progress(
index d04db817be5c8271f531d87d0ee9a4a950f616f8..9dbf4239515308a480b3cdb2cfc48b4b38812811 100644 (file)
@@ -1305,13 +1305,6 @@ error_fs_info:
        return ERR_PTR(error);
 }
 
-static void btrfs_set_max_workers(struct btrfs_workers *workers, int new_limit)
-{
-       spin_lock_irq(&workers->lock);
-       workers->max_workers = new_limit;
-       spin_unlock_irq(&workers->lock);
-}
-
 static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info,
                                     int new_pool_size, int old_pool_size)
 {
@@ -1323,21 +1316,20 @@ static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info,
        btrfs_info(fs_info, "resize thread pool %d -> %d",
               old_pool_size, new_pool_size);
 
-       btrfs_set_max_workers(&fs_info->generic_worker, new_pool_size);
-       btrfs_set_max_workers(&fs_info->workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->delalloc_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->submit_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->caching_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->fixup_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->endio_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->endio_meta_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->endio_meta_write_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->endio_write_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->endio_freespace_worker, new_pool_size);
-       btrfs_set_max_workers(&fs_info->delayed_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->readahead_workers, new_pool_size);
-       btrfs_set_max_workers(&fs_info->scrub_wr_completion_workers,
-                             new_pool_size);
+       btrfs_workqueue_set_max(fs_info->workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->delalloc_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->submit_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->caching_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->endio_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->endio_meta_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->endio_meta_write_workers,
+                               new_pool_size);
+       btrfs_workqueue_set_max(fs_info->endio_write_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->endio_freespace_worker, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->delayed_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->readahead_workers, new_pool_size);
+       btrfs_workqueue_set_max(fs_info->scrub_wr_completion_workers,
+                               new_pool_size);
 }
 
 static inline void btrfs_remount_prepare(struct btrfs_fs_info *fs_info)
@@ -1388,6 +1380,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
        unsigned int old_metadata_ratio = fs_info->metadata_ratio;
        int ret;
 
+       sync_filesystem(sb);
        btrfs_remount_prepare(fs_info);
 
        ret = btrfs_parse_options(root, data);
@@ -1479,6 +1472,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                sb->s_flags &= ~MS_RDONLY;
        }
 out:
+       wake_up_process(fs_info->transaction_kthread);
        btrfs_remount_cleanup(fs_info, old_opts);
        return 0;
 
index 865f4cf9a7695899c18d368f6ab2629340994dce..c5eb2143dc66760d088161e8b201de3effc342c6 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kobject.h>
 #include <linux/bug.h>
 #include <linux/genhd.h>
+#include <linux/debugfs.h>
 
 #include "ctree.h"
 #include "disk-io.h"
@@ -599,6 +600,12 @@ static int add_device_membership(struct btrfs_fs_info *fs_info)
 /* /sys/fs/btrfs/ entry */
 static struct kset *btrfs_kset;
 
+/* /sys/kernel/debug/btrfs */
+static struct dentry *btrfs_debugfs_root_dentry;
+
+/* Debugging tunables and exported data */
+u64 btrfs_debugfs_test;
+
 int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
 {
        int error;
@@ -642,27 +649,41 @@ failure:
        return error;
 }
 
+static int btrfs_init_debugfs(void)
+{
+#ifdef CONFIG_DEBUG_FS
+       btrfs_debugfs_root_dentry = debugfs_create_dir("btrfs", NULL);
+       if (!btrfs_debugfs_root_dentry)
+               return -ENOMEM;
+
+       debugfs_create_u64("test", S_IRUGO | S_IWUGO, btrfs_debugfs_root_dentry,
+                       &btrfs_debugfs_test);
+#endif
+       return 0;
+}
+
 int btrfs_init_sysfs(void)
 {
        int ret;
+
        btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
        if (!btrfs_kset)
                return -ENOMEM;
 
-       init_feature_attrs();
+       ret = btrfs_init_debugfs();
+       if (ret)
+               return ret;
 
+       init_feature_attrs();
        ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
-       if (ret) {
-               kset_unregister(btrfs_kset);
-               return ret;
-       }
 
-       return 0;
+       return ret;
 }
 
 void btrfs_exit_sysfs(void)
 {
        sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
        kset_unregister(btrfs_kset);
+       debugfs_remove_recursive(btrfs_debugfs_root_dentry);
 }
 
index f3cea3710d44f74edfebb0264b6136d75ee678b0..9ab576318a84f06cec8e46b2a9afc557e0840d9d 100644 (file)
@@ -1,6 +1,11 @@
 #ifndef _BTRFS_SYSFS_H_
 #define _BTRFS_SYSFS_H_
 
+/*
+ * Data exported through sysfs
+ */
+extern u64 btrfs_debugfs_test;
+
 enum btrfs_feature_set {
        FEAT_COMPAT,
        FEAT_COMPAT_RO,
index 34cd83184c4ad2ff7ce85bb13fea48dfb61198b4..a04707f740d6aed809ccbf477cfc3305dfe5c44f 100644 (file)
@@ -683,7 +683,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
        int lock = (trans->type != TRANS_JOIN_NOLOCK);
        int err = 0;
 
-       if (--trans->use_count) {
+       if (trans->use_count > 1) {
+               trans->use_count--;
                trans->block_rsv = trans->orig_rsv;
                return 0;
        }
@@ -731,17 +732,10 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
        }
 
        if (lock && ACCESS_ONCE(cur_trans->state) == TRANS_STATE_BLOCKED) {
-               if (throttle) {
-                       /*
-                        * We may race with somebody else here so end up having
-                        * to call end_transaction on ourselves again, so inc
-                        * our use_count.
-                        */
-                       trans->use_count++;
+               if (throttle)
                        return btrfs_commit_transaction(trans, root);
-               } else {
+               else
                        wake_up_process(info->transaction_kthread);
-               }
        }
 
        if (trans->type & __TRANS_FREEZABLE)
@@ -1578,10 +1572,9 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
 
        trace_btrfs_transaction_commit(root);
 
-       btrfs_scrub_continue(root);
-
        if (current->journal_info == trans)
                current->journal_info = NULL;
+       btrfs_scrub_cancel(root->fs_info);
 
        kmem_cache_free(btrfs_trans_handle_cachep, trans);
 }
@@ -1621,7 +1614,7 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans,
 static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
 {
        if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT))
-               return btrfs_start_delalloc_roots(fs_info, 1);
+               return btrfs_start_delalloc_roots(fs_info, 1, -1);
        return 0;
 }
 
@@ -1754,7 +1747,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        /* ->aborted might be set after the previous check, so check it */
        if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
                ret = cur_trans->aborted;
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
        /*
         * the reloc mutex makes sure that we stop
@@ -1771,7 +1764,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        ret = create_pending_snapshots(trans, root->fs_info);
        if (ret) {
                mutex_unlock(&root->fs_info->reloc_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        /*
@@ -1787,13 +1780,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        ret = btrfs_run_delayed_items(trans, root);
        if (ret) {
                mutex_unlock(&root->fs_info->reloc_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
        if (ret) {
                mutex_unlock(&root->fs_info->reloc_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        /*
@@ -1823,7 +1816,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        if (ret) {
                mutex_unlock(&root->fs_info->tree_log_mutex);
                mutex_unlock(&root->fs_info->reloc_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        /*
@@ -1844,7 +1837,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        if (ret) {
                mutex_unlock(&root->fs_info->tree_log_mutex);
                mutex_unlock(&root->fs_info->reloc_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        /*
@@ -1855,7 +1848,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                ret = cur_trans->aborted;
                mutex_unlock(&root->fs_info->tree_log_mutex);
                mutex_unlock(&root->fs_info->reloc_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        btrfs_prepare_extent_commit(trans, root);
@@ -1891,13 +1884,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                btrfs_error(root->fs_info, ret,
                            "Error while writing out transaction");
                mutex_unlock(&root->fs_info->tree_log_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        ret = write_ctree_super(trans, root, 0);
        if (ret) {
                mutex_unlock(&root->fs_info->tree_log_mutex);
-               goto cleanup_transaction;
+               goto scrub_continue;
        }
 
        /*
@@ -1940,6 +1933,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        return ret;
 
+scrub_continue:
+       btrfs_scrub_continue(root);
 cleanup_transaction:
        btrfs_trans_release_metadata(trans, root);
        trans->block_rsv = NULL;
index 39d83da03e0398db90428e52b98524982da469b5..e2f45fc02610950ac2991faa534b90d4e0827934 100644 (file)
@@ -136,13 +136,20 @@ static noinline int replay_dir_deletes(struct btrfs_trans_handle *trans,
  * syncing the tree wait for us to finish
  */
 static int start_log_trans(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root)
+                          struct btrfs_root *root,
+                          struct btrfs_log_ctx *ctx)
 {
+       int index;
        int ret;
-       int err = 0;
 
        mutex_lock(&root->log_mutex);
        if (root->log_root) {
+               if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
+                   trans->transid) {
+                       ret = -EAGAIN;
+                       goto out;
+               }
+
                if (!root->log_start_pid) {
                        root->log_start_pid = current->pid;
                        root->log_multiple_pids = false;
@@ -152,27 +159,40 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
 
                atomic_inc(&root->log_batch);
                atomic_inc(&root->log_writers);
+               if (ctx) {
+                       index = root->log_transid % 2;
+                       list_add_tail(&ctx->list, &root->log_ctxs[index]);
+                       ctx->log_transid = root->log_transid;
+               }
                mutex_unlock(&root->log_mutex);
                return 0;
        }
-       root->log_multiple_pids = false;
-       root->log_start_pid = current->pid;
+
+       ret = 0;
        mutex_lock(&root->fs_info->tree_log_mutex);
-       if (!root->fs_info->log_root_tree) {
+       if (!root->fs_info->log_root_tree)
                ret = btrfs_init_log_root_tree(trans, root->fs_info);
-               if (ret)
-                       err = ret;
-       }
-       if (err == 0 && !root->log_root) {
+       mutex_unlock(&root->fs_info->tree_log_mutex);
+       if (ret)
+               goto out;
+
+       if (!root->log_root) {
                ret = btrfs_add_log_tree(trans, root);
                if (ret)
-                       err = ret;
+                       goto out;
        }
-       mutex_unlock(&root->fs_info->tree_log_mutex);
+       root->log_multiple_pids = false;
+       root->log_start_pid = current->pid;
        atomic_inc(&root->log_batch);
        atomic_inc(&root->log_writers);
+       if (ctx) {
+               index = root->log_transid % 2;
+               list_add_tail(&ctx->list, &root->log_ctxs[index]);
+               ctx->log_transid = root->log_transid;
+       }
+out:
        mutex_unlock(&root->log_mutex);
-       return err;
+       return ret;
 }
 
 /*
@@ -2359,8 +2379,8 @@ static int update_log_root(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-static int wait_log_commit(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root, unsigned long transid)
+static void wait_log_commit(struct btrfs_trans_handle *trans,
+                           struct btrfs_root *root, int transid)
 {
        DEFINE_WAIT(wait);
        int index = transid % 2;
@@ -2375,36 +2395,63 @@ static int wait_log_commit(struct btrfs_trans_handle *trans,
                                &wait, TASK_UNINTERRUPTIBLE);
                mutex_unlock(&root->log_mutex);
 
-               if (root->fs_info->last_trans_log_full_commit !=
-                   trans->transid && root->log_transid < transid + 2 &&
+               if (root->log_transid_committed < transid &&
                    atomic_read(&root->log_commit[index]))
                        schedule();
 
                finish_wait(&root->log_commit_wait[index], &wait);
                mutex_lock(&root->log_mutex);
-       } while (root->fs_info->last_trans_log_full_commit !=
-                trans->transid && root->log_transid < transid + 2 &&
+       } while (root->log_transid_committed < transid &&
                 atomic_read(&root->log_commit[index]));
-       return 0;
 }
 
 static void wait_for_writer(struct btrfs_trans_handle *trans,
                            struct btrfs_root *root)
 {
        DEFINE_WAIT(wait);
-       while (root->fs_info->last_trans_log_full_commit !=
-              trans->transid && atomic_read(&root->log_writers)) {
+
+       while (atomic_read(&root->log_writers)) {
                prepare_to_wait(&root->log_writer_wait,
                                &wait, TASK_UNINTERRUPTIBLE);
                mutex_unlock(&root->log_mutex);
-               if (root->fs_info->last_trans_log_full_commit !=
-                   trans->transid && atomic_read(&root->log_writers))
+               if (atomic_read(&root->log_writers))
                        schedule();
                mutex_lock(&root->log_mutex);
                finish_wait(&root->log_writer_wait, &wait);
        }
 }
 
+static inline void btrfs_remove_log_ctx(struct btrfs_root *root,
+                                       struct btrfs_log_ctx *ctx)
+{
+       if (!ctx)
+               return;
+
+       mutex_lock(&root->log_mutex);
+       list_del_init(&ctx->list);
+       mutex_unlock(&root->log_mutex);
+}
+
+/* 
+ * Invoked in log mutex context, or be sure there is no other task which
+ * can access the list.
+ */
+static inline void btrfs_remove_all_log_ctxs(struct btrfs_root *root,
+                                            int index, int error)
+{
+       struct btrfs_log_ctx *ctx;
+
+       if (!error) {
+               INIT_LIST_HEAD(&root->log_ctxs[index]);
+               return;
+       }
+
+       list_for_each_entry(ctx, &root->log_ctxs[index], list)
+               ctx->log_ret = error;
+
+       INIT_LIST_HEAD(&root->log_ctxs[index]);
+}
+
 /*
  * btrfs_sync_log does sends a given tree log down to the disk and
  * updates the super blocks to record it.  When this call is done,
@@ -2418,7 +2465,7 @@ static void wait_for_writer(struct btrfs_trans_handle *trans,
  * that has happened.
  */
 int btrfs_sync_log(struct btrfs_trans_handle *trans,
-                  struct btrfs_root *root)
+                  struct btrfs_root *root, struct btrfs_log_ctx *ctx)
 {
        int index1;
        int index2;
@@ -2426,22 +2473,30 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        int ret;
        struct btrfs_root *log = root->log_root;
        struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
-       unsigned long log_transid = 0;
+       int log_transid = 0;
+       struct btrfs_log_ctx root_log_ctx;
        struct blk_plug plug;
 
        mutex_lock(&root->log_mutex);
-       log_transid = root->log_transid;
-       index1 = root->log_transid % 2;
+       log_transid = ctx->log_transid;
+       if (root->log_transid_committed >= log_transid) {
+               mutex_unlock(&root->log_mutex);
+               return ctx->log_ret;
+       }
+
+       index1 = log_transid % 2;
        if (atomic_read(&root->log_commit[index1])) {
-               wait_log_commit(trans, root, root->log_transid);
+               wait_log_commit(trans, root, log_transid);
                mutex_unlock(&root->log_mutex);
-               return 0;
+               return ctx->log_ret;
        }
+       ASSERT(log_transid == root->log_transid);
        atomic_set(&root->log_commit[index1], 1);
 
        /* wait for previous tree log sync to complete */
        if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
-               wait_log_commit(trans, root, root->log_transid - 1);
+               wait_log_commit(trans, root, log_transid - 1);
+
        while (1) {
                int batch = atomic_read(&root->log_batch);
                /* when we're on an ssd, just kick the log commit out */
@@ -2456,7 +2511,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        }
 
        /* bail out if we need to do a full commit */
-       if (root->fs_info->last_trans_log_full_commit == trans->transid) {
+       if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
+           trans->transid) {
                ret = -EAGAIN;
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&root->log_mutex);
@@ -2477,6 +2533,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                blk_finish_plug(&plug);
                btrfs_abort_transaction(trans, root, ret);
                btrfs_free_logged_extents(log, log_transid);
+               ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+                                                               trans->transid;
                mutex_unlock(&root->log_mutex);
                goto out;
        }
@@ -2486,7 +2544,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        root->log_transid++;
        log->log_transid = root->log_transid;
        root->log_start_pid = 0;
-       smp_mb();
        /*
         * IO has been started, blocks of the log tree have WRITTEN flag set
         * in their headers. new modifications of the log will be written to
@@ -2494,9 +2551,16 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         */
        mutex_unlock(&root->log_mutex);
 
+       btrfs_init_log_ctx(&root_log_ctx);
+
        mutex_lock(&log_root_tree->log_mutex);
        atomic_inc(&log_root_tree->log_batch);
        atomic_inc(&log_root_tree->log_writers);
+
+       index2 = log_root_tree->log_transid % 2;
+       list_add_tail(&root_log_ctx.list, &log_root_tree->log_ctxs[index2]);
+       root_log_ctx.log_transid = log_root_tree->log_transid;
+
        mutex_unlock(&log_root_tree->log_mutex);
 
        ret = update_log_root(trans, log);
@@ -2509,13 +2573,17 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        }
 
        if (ret) {
+               if (!list_empty(&root_log_ctx.list))
+                       list_del_init(&root_log_ctx.list);
+
                blk_finish_plug(&plug);
+               ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+                                                               trans->transid;
                if (ret != -ENOSPC) {
                        btrfs_abort_transaction(trans, root, ret);
                        mutex_unlock(&log_root_tree->log_mutex);
                        goto out;
                }
-               root->fs_info->last_trans_log_full_commit = trans->transid;
                btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
@@ -2523,22 +2591,29 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       index2 = log_root_tree->log_transid % 2;
+       if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) {
+               mutex_unlock(&log_root_tree->log_mutex);
+               ret = root_log_ctx.log_ret;
+               goto out;
+       }
+
+       index2 = root_log_ctx.log_transid % 2;
        if (atomic_read(&log_root_tree->log_commit[index2])) {
                blk_finish_plug(&plug);
                btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
                wait_log_commit(trans, log_root_tree,
-                               log_root_tree->log_transid);
+                               root_log_ctx.log_transid);
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
-               ret = 0;
+               ret = root_log_ctx.log_ret;
                goto out;
        }
+       ASSERT(root_log_ctx.log_transid == log_root_tree->log_transid);
        atomic_set(&log_root_tree->log_commit[index2], 1);
 
        if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) {
                wait_log_commit(trans, log_root_tree,
-                               log_root_tree->log_transid - 1);
+                               root_log_ctx.log_transid - 1);
        }
 
        wait_for_writer(trans, log_root_tree);
@@ -2547,7 +2622,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         * now that we've moved on to the tree of log tree roots,
         * check the full commit flag again
         */
-       if (root->fs_info->last_trans_log_full_commit == trans->transid) {
+       if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
+           trans->transid) {
                blk_finish_plug(&plug);
                btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
                btrfs_free_logged_extents(log, log_transid);
@@ -2561,6 +2637,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                                         EXTENT_DIRTY | EXTENT_NEW);
        blk_finish_plug(&plug);
        if (ret) {
+               ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+                                                               trans->transid;
                btrfs_abort_transaction(trans, root, ret);
                btrfs_free_logged_extents(log, log_transid);
                mutex_unlock(&log_root_tree->log_mutex);
@@ -2578,8 +2656,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                                btrfs_header_level(log_root_tree->node));
 
        log_root_tree->log_transid++;
-       smp_mb();
-
        mutex_unlock(&log_root_tree->log_mutex);
 
        /*
@@ -2591,6 +2667,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         */
        ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
        if (ret) {
+               ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
+                                                               trans->transid;
                btrfs_abort_transaction(trans, root, ret);
                goto out_wake_log_root;
        }
@@ -2601,13 +2679,28 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        mutex_unlock(&root->log_mutex);
 
 out_wake_log_root:
+       /*
+        * We needn't get log_mutex here because we are sure all
+        * the other tasks are blocked.
+        */
+       btrfs_remove_all_log_ctxs(log_root_tree, index2, ret);
+
+       mutex_lock(&log_root_tree->log_mutex);
+       log_root_tree->log_transid_committed++;
        atomic_set(&log_root_tree->log_commit[index2], 0);
-       smp_mb();
+       mutex_unlock(&log_root_tree->log_mutex);
+
        if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
                wake_up(&log_root_tree->log_commit_wait[index2]);
 out:
+       /* See above. */
+       btrfs_remove_all_log_ctxs(root, index1, ret);
+
+       mutex_lock(&root->log_mutex);
+       root->log_transid_committed++;
        atomic_set(&root->log_commit[index1], 0);
-       smp_mb();
+       mutex_unlock(&root->log_mutex);
+
        if (waitqueue_active(&root->log_commit_wait[index1]))
                wake_up(&root->log_commit_wait[index1]);
        return ret;
@@ -3479,7 +3572,8 @@ static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
 
 static int log_one_extent(struct btrfs_trans_handle *trans,
                          struct inode *inode, struct btrfs_root *root,
-                         struct extent_map *em, struct btrfs_path *path)
+                         struct extent_map *em, struct btrfs_path *path,
+                         struct list_head *logged_list)
 {
        struct btrfs_root *log = root->log_root;
        struct btrfs_file_extent_item *fi;
@@ -3495,7 +3589,6 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
        u64 extent_offset = em->start - em->orig_start;
        u64 block_len;
        int ret;
-       int index = log->log_transid % 2;
        bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
        int extent_inserted = 0;
 
@@ -3579,17 +3672,12 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
         * First check and see if our csums are on our outstanding ordered
         * extents.
         */
-again:
-       spin_lock_irq(&log->log_extents_lock[index]);
-       list_for_each_entry(ordered, &log->logged_list[index], log_list) {
+       list_for_each_entry(ordered, logged_list, log_list) {
                struct btrfs_ordered_sum *sum;
 
                if (!mod_len)
                        break;
 
-               if (ordered->inode != inode)
-                       continue;
-
                if (ordered->file_offset + ordered->len <= mod_start ||
                    mod_start + mod_len <= ordered->file_offset)
                        continue;
@@ -3632,12 +3720,6 @@ again:
                if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM,
                                     &ordered->flags))
                        continue;
-               atomic_inc(&ordered->refs);
-               spin_unlock_irq(&log->log_extents_lock[index]);
-               /*
-                * we've dropped the lock, we must either break or
-                * start over after this.
-                */
 
                if (ordered->csum_bytes_left) {
                        btrfs_start_ordered_extent(inode, ordered, 0);
@@ -3647,16 +3729,11 @@ again:
 
                list_for_each_entry(sum, &ordered->list, list) {
                        ret = btrfs_csum_file_blocks(trans, log, sum);
-                       if (ret) {
-                               btrfs_put_ordered_extent(ordered);
+                       if (ret)
                                goto unlocked;
-                       }
                }
-               btrfs_put_ordered_extent(ordered);
-               goto again;
 
        }
-       spin_unlock_irq(&log->log_extents_lock[index]);
 unlocked:
 
        if (!mod_len || ret)
@@ -3694,7 +3771,8 @@ unlocked:
 static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     struct inode *inode,
-                                    struct btrfs_path *path)
+                                    struct btrfs_path *path,
+                                    struct list_head *logged_list)
 {
        struct extent_map *em, *n;
        struct list_head extents;
@@ -3752,7 +3830,7 @@ process:
 
                write_unlock(&tree->lock);
 
-               ret = log_one_extent(trans, inode, root, em, path);
+               ret = log_one_extent(trans, inode, root, em, path, logged_list);
                write_lock(&tree->lock);
                clear_em_logging(tree, em);
                free_extent_map(em);
@@ -3788,6 +3866,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
        struct btrfs_key max_key;
        struct btrfs_root *log = root->log_root;
        struct extent_buffer *src = NULL;
+       LIST_HEAD(logged_list);
        u64 last_extent = 0;
        int err = 0;
        int ret;
@@ -3836,7 +3915,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
 
        mutex_lock(&BTRFS_I(inode)->log_mutex);
 
-       btrfs_get_logged_extents(log, inode);
+       btrfs_get_logged_extents(inode, &logged_list);
 
        /*
         * a brute force approach to making sure we get the most uptodate
@@ -3962,7 +4041,8 @@ log_extents:
        btrfs_release_path(path);
        btrfs_release_path(dst_path);
        if (fast_search) {
-               ret = btrfs_log_changed_extents(trans, root, inode, dst_path);
+               ret = btrfs_log_changed_extents(trans, root, inode, dst_path,
+                                               &logged_list);
                if (ret) {
                        err = ret;
                        goto out_unlock;
@@ -3987,8 +4067,10 @@ log_extents:
        BTRFS_I(inode)->logged_trans = trans->transid;
        BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
 out_unlock:
-       if (err)
-               btrfs_free_logged_extents(log, log->log_transid);
+       if (unlikely(err))
+               btrfs_put_logged_extents(&logged_list);
+       else
+               btrfs_submit_logged_extents(&logged_list, log);
        mutex_unlock(&BTRFS_I(inode)->log_mutex);
 
        btrfs_free_path(path);
@@ -4079,7 +4161,8 @@ out:
  */
 static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
                                  struct btrfs_root *root, struct inode *inode,
-                                 struct dentry *parent, int exists_only)
+                                 struct dentry *parent, int exists_only,
+                                 struct btrfs_log_ctx *ctx)
 {
        int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL;
        struct super_block *sb;
@@ -4116,9 +4199,9 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
                goto end_no_trans;
        }
 
-       ret = start_log_trans(trans, root);
+       ret = start_log_trans(trans, root, ctx);
        if (ret)
-               goto end_trans;
+               goto end_no_trans;
 
        ret = btrfs_log_inode(trans, root, inode, inode_only);
        if (ret)
@@ -4166,6 +4249,9 @@ end_trans:
                root->fs_info->last_trans_log_full_commit = trans->transid;
                ret = 1;
        }
+
+       if (ret)
+               btrfs_remove_log_ctx(root, ctx);
        btrfs_end_log_trans(root);
 end_no_trans:
        return ret;
@@ -4178,12 +4264,14 @@ end_no_trans:
  * data on disk.
  */
 int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
-                         struct btrfs_root *root, struct dentry *dentry)
+                         struct btrfs_root *root, struct dentry *dentry,
+                         struct btrfs_log_ctx *ctx)
 {
        struct dentry *parent = dget_parent(dentry);
        int ret;
 
-       ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 0);
+       ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent,
+                                    0, ctx);
        dput(parent);
 
        return ret;
@@ -4420,6 +4508,6 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
                    root->fs_info->last_trans_committed))
                return 0;
 
-       return btrfs_log_inode_parent(trans, root, inode, parent, 1);
+       return btrfs_log_inode_parent(trans, root, inode, parent, 1, NULL);
 }
 
index 1d4ae0d15a7038ffcef2db5e98b6fce169f9f281..91b145fce3336719a745085dc8497bed380405de 100644 (file)
 /* return value for btrfs_log_dentry_safe that means we don't need to log it at all */
 #define BTRFS_NO_LOG_SYNC 256
 
+struct btrfs_log_ctx {
+       int log_ret;
+       int log_transid;
+       struct list_head list;
+};
+
+static inline void btrfs_init_log_ctx(struct btrfs_log_ctx *ctx)
+{
+       ctx->log_ret = 0;
+       ctx->log_transid = 0;
+       INIT_LIST_HEAD(&ctx->list);
+}
+
 int btrfs_sync_log(struct btrfs_trans_handle *trans,
-                  struct btrfs_root *root);
+                  struct btrfs_root *root, struct btrfs_log_ctx *ctx);
 int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root);
 int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
                             struct btrfs_fs_info *fs_info);
 int btrfs_recover_log_trees(struct btrfs_root *tree_root);
 int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
-                         struct btrfs_root *root, struct dentry *dentry);
+                         struct btrfs_root *root, struct dentry *dentry,
+                         struct btrfs_log_ctx *ctx);
 int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *root,
                                 const char *name, int name_len,
index bab0b84d8f806adf711b797c0909cb9dd664cc95..d241130a32fddfd351237b8a14f0982f46b7e2e2 100644 (file)
@@ -415,7 +415,8 @@ loop_lock:
                        device->running_pending = 1;
 
                        spin_unlock(&device->io_lock);
-                       btrfs_requeue_work(&device->work);
+                       btrfs_queue_work(fs_info->submit_workers,
+                                        &device->work);
                        goto done;
                }
                /* unplug every 64 requests just for good measure */
@@ -5263,6 +5264,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
 static void btrfs_end_bio(struct bio *bio, int err)
 {
        struct btrfs_bio *bbio = bio->bi_private;
+       struct btrfs_device *dev = bbio->stripes[0].dev;
        int is_orig_bio = 0;
 
        if (err) {
@@ -5270,7 +5272,6 @@ static void btrfs_end_bio(struct bio *bio, int err)
                if (err == -EIO || err == -EREMOTEIO) {
                        unsigned int stripe_index =
                                btrfs_io_bio(bio)->stripe_index;
-                       struct btrfs_device *dev;
 
                        BUG_ON(stripe_index >= bbio->num_stripes);
                        dev = bbio->stripes[stripe_index].dev;
@@ -5292,6 +5293,8 @@ static void btrfs_end_bio(struct bio *bio, int err)
        if (bio == bbio->orig_bio)
                is_orig_bio = 1;
 
+       btrfs_bio_counter_dec(bbio->fs_info);
+
        if (atomic_dec_and_test(&bbio->stripes_pending)) {
                if (!is_orig_bio) {
                        bio_put(bio);
@@ -5328,13 +5331,6 @@ static void btrfs_end_bio(struct bio *bio, int err)
        }
 }
 
-struct async_sched {
-       struct bio *bio;
-       int rw;
-       struct btrfs_fs_info *info;
-       struct btrfs_work work;
-};
-
 /*
  * see run_scheduled_bios for a description of why bios are collected for
  * async submit.
@@ -5391,8 +5387,8 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
        spin_unlock(&device->io_lock);
 
        if (should_queue)
-               btrfs_queue_worker(&root->fs_info->submit_workers,
-                                  &device->work);
+               btrfs_queue_work(root->fs_info->submit_workers,
+                                &device->work);
 }
 
 static int bio_size_ok(struct block_device *bdev, struct bio *bio,
@@ -5447,6 +5443,9 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
        }
 #endif
        bio->bi_bdev = dev->bdev;
+
+       btrfs_bio_counter_inc_noblocked(root->fs_info);
+
        if (async)
                btrfs_schedule_bio(root, dev, rw, bio);
        else
@@ -5515,28 +5514,38 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        length = bio->bi_iter.bi_size;
        map_length = length;
 
+       btrfs_bio_counter_inc_blocked(root->fs_info);
        ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio,
                              mirror_num, &raid_map);
-       if (ret) /* -ENOMEM */
+       if (ret) {
+               btrfs_bio_counter_dec(root->fs_info);
                return ret;
+       }
 
        total_devs = bbio->num_stripes;
        bbio->orig_bio = first_bio;
        bbio->private = first_bio->bi_private;
        bbio->end_io = first_bio->bi_end_io;
+       bbio->fs_info = root->fs_info;
        atomic_set(&bbio->stripes_pending, bbio->num_stripes);
 
        if (raid_map) {
                /* In this case, map_length has been set to the length of
                   a single stripe; not the whole write */
                if (rw & WRITE) {
-                       return raid56_parity_write(root, bio, bbio,
-                                                  raid_map, map_length);
+                       ret = raid56_parity_write(root, bio, bbio,
+                                                 raid_map, map_length);
                } else {
-                       return raid56_parity_recover(root, bio, bbio,
-                                                    raid_map, map_length,
-                                                    mirror_num);
+                       ret = raid56_parity_recover(root, bio, bbio,
+                                                   raid_map, map_length,
+                                                   mirror_num);
                }
+               /*
+                * FIXME, replace dosen't support raid56 yet, please fix
+                * it in the future.
+                */
+               btrfs_bio_counter_dec(root->fs_info);
+               return ret;
        }
 
        if (map_length < length) {
@@ -5578,6 +5587,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                                  async_submit);
                dev_nr++;
        }
+       btrfs_bio_counter_dec(root->fs_info);
        return 0;
 }
 
@@ -5666,7 +5676,7 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
        else
                generate_random_uuid(dev->uuid);
 
-       dev->work.func = pending_bios_fn;
+       btrfs_init_work(&dev->work, pending_bios_fn, NULL, NULL);
 
        return dev;
 }
index 8b3cd142b3734dc0161c479b9bfcc9eb144cdaab..80754f9dd3df9faa208a03a274bb7274a002b671 100644 (file)
@@ -192,6 +192,7 @@ typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err);
 
 struct btrfs_bio {
        atomic_t stripes_pending;
+       struct btrfs_fs_info *fs_info;
        bio_end_io_t *end_io;
        struct bio *orig_bio;
        void *private;
index ca65f39dc8dc38823bb4a6070c717671acffba72..6494d9f673aa51490a59694d600bd8a7101559bf 100644 (file)
@@ -391,12 +391,12 @@ try_again:
        path.dentry = dir;
        path_to_graveyard.mnt = cache->mnt;
        path_to_graveyard.dentry = cache->graveyard;
-       ret = security_path_rename(&path, rep, &path_to_graveyard, grave);
+       ret = security_path_rename(&path, rep, &path_to_graveyard, grave, 0);
        if (ret < 0) {
                cachefiles_io_error(cache, "Rename security error %d", ret);
        } else {
                ret = vfs_rename(dir->d_inode, rep,
-                                cache->graveyard->d_inode, grave, NULL);
+                                cache->graveyard->d_inode, grave, NULL, 0);
                if (ret != 0 && ret != -ENOMEM)
                        cachefiles_io_error(cache,
                                            "Rename failed with error %d", ret);
index 8c44fdd4e1c39f836b2c8a9b2a7a025f1844d3b3..834f9f3723fbe3980e8a9705e8c1d0f86936eb40 100644 (file)
@@ -205,6 +205,7 @@ void ceph_fscache_register_inode_cookie(struct ceph_fs_client* fsc,
        ci->fscache = fscache_acquire_cookie(fsc->fscache,
                                             &ceph_fscache_inode_object_def,
                                             ci, true);
+       fscache_check_consistency(ci->fscache);
 done:
        mutex_unlock(&inode->i_mutex);
 
index da95f61b7a09e850e6d28de88aceb4493d7157b8..5ac591bd012bc8cd3653cdd8f9ca731511a051d1 100644 (file)
@@ -48,6 +48,12 @@ void ceph_readpage_to_fscache(struct inode *inode, struct page *page);
 void ceph_invalidate_fscache_page(struct inode* inode, struct page *page);
 void ceph_queue_revalidate(struct inode *inode);
 
+static inline void ceph_fscache_update_objectsize(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       fscache_attr_changed(ci->fscache);
+}
+
 static inline void ceph_fscache_invalidate(struct inode *inode)
 {
        fscache_invalidate(ceph_inode(inode)->fscache);
@@ -135,6 +141,10 @@ static inline void ceph_readpage_to_fscache(struct inode *inode,
 {
 }
 
+static inline void ceph_fscache_update_objectsize(struct inode *inode)
+{
+}
+
 static inline void ceph_fscache_invalidate(struct inode *inode)
 {
 }
index 17543383545c162f58425fbc8629a99f1c5a717e..2e5e648eb5c3dc3bd82bea5ce8dead051864cf75 100644 (file)
@@ -622,8 +622,10 @@ retry:
 
        if (flags & CEPH_CAP_FLAG_AUTH) {
                if (ci->i_auth_cap == NULL ||
-                   ceph_seq_cmp(ci->i_auth_cap->mseq, mseq) < 0)
+                   ceph_seq_cmp(ci->i_auth_cap->mseq, mseq) < 0) {
                        ci->i_auth_cap = cap;
+                       cap->mds_wanted = wanted;
+               }
                ci->i_cap_exporting_issued = 0;
        } else {
                WARN_ON(ci->i_auth_cap == cap);
@@ -885,7 +887,10 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci)
                cap = rb_entry(p, struct ceph_cap, ci_node);
                if (!__cap_is_valid(cap))
                        continue;
-               mds_wanted |= cap->mds_wanted;
+               if (cap == ci->i_auth_cap)
+                       mds_wanted |= cap->mds_wanted;
+               else
+                       mds_wanted |= (cap->mds_wanted & ~CEPH_CAP_ANY_FILE_WR);
        }
        return mds_wanted;
 }
index 6d59006bfa27e688d37499b88f45e28a22df24db..16b54aa31f08ef801f2aa852b9f00c81aeffe9ce 100644 (file)
@@ -93,6 +93,8 @@ static int mdsc_show(struct seq_file *s, void *p)
                } else if (req->r_path1) {
                        seq_printf(s, " #%llx/%s", req->r_ino1.ino,
                                   req->r_path1);
+               } else {
+                       seq_printf(s, " #%llx", req->r_ino1.ino);
                }
 
                if (req->r_old_dentry) {
@@ -102,7 +104,8 @@ static int mdsc_show(struct seq_file *s, void *p)
                                path = NULL;
                        spin_lock(&req->r_old_dentry->d_lock);
                        seq_printf(s, " #%llx/%.*s (%s)",
-                          ceph_ino(req->r_old_dentry_dir),
+                                  req->r_old_dentry_dir ?
+                                  ceph_ino(req->r_old_dentry_dir) : 0,
                                   req->r_old_dentry->d_name.len,
                                   req->r_old_dentry->d_name.name,
                                   path ? path : "");
index 45eda6d7a40c2030db42fc06fa2d741f180c254f..766410a12c2cb209a224fcfd97f63a055fd20801 100644 (file)
@@ -119,7 +119,8 @@ static int fpos_cmp(loff_t l, loff_t r)
  * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
  * the MDS if/when the directory is modified).
  */
-static int __dcache_readdir(struct file *file, struct dir_context *ctx)
+static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
+                           u32 shared_gen)
 {
        struct ceph_file_info *fi = file->private_data;
        struct dentry *parent = file->f_dentry;
@@ -133,8 +134,8 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx)
        last = fi->dentry;
        fi->dentry = NULL;
 
-       dout("__dcache_readdir %p at %llu (last %p)\n", dir, ctx->pos,
-            last);
+       dout("__dcache_readdir %p v%u at %llu (last %p)\n",
+            dir, shared_gen, ctx->pos, last);
 
        spin_lock(&parent->d_lock);
 
@@ -161,7 +162,8 @@ more:
                        goto out_unlock;
                }
                spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
-               if (!d_unhashed(dentry) && dentry->d_inode &&
+               if (di->lease_shared_gen == shared_gen &&
+                   !d_unhashed(dentry) && dentry->d_inode &&
                    ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
                    ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
                    fpos_cmp(ctx->pos, di->offset) <= 0)
@@ -190,7 +192,7 @@ more:
                if (last) {
                        /* remember our position */
                        fi->dentry = last;
-                       fi->next_offset = di->offset;
+                       fi->next_offset = fpos_off(di->offset);
                }
                dput(dentry);
                return 0;
@@ -252,8 +254,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
        int err;
        u32 ftype;
        struct ceph_mds_reply_info_parsed *rinfo;
-       const int max_entries = fsc->mount_options->max_readdir;
-       const int max_bytes = fsc->mount_options->max_readdir_bytes;
 
        dout("readdir %p file %p frag %u off %u\n", inode, file, frag, off);
        if (fi->flags & CEPH_F_ATEND)
@@ -291,8 +291,9 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
            ceph_snap(inode) != CEPH_SNAPDIR &&
            __ceph_dir_is_complete(ci) &&
            __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
+               u32 shared_gen = ci->i_shared_gen;
                spin_unlock(&ci->i_ceph_lock);
-               err = __dcache_readdir(file, ctx);
+               err = __dcache_readdir(file, ctx, shared_gen);
                if (err != -EAGAIN)
                        return err;
        } else {
@@ -322,14 +323,16 @@ more:
                        fi->last_readdir = NULL;
                }
 
-               /* requery frag tree, as the frag topology may have changed */
-               frag = ceph_choose_frag(ceph_inode(inode), frag, NULL, NULL);
-
                dout("readdir fetching %llx.%llx frag %x offset '%s'\n",
                     ceph_vinop(inode), frag, fi->last_name);
                req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
                if (IS_ERR(req))
                        return PTR_ERR(req);
+               err = ceph_alloc_readdir_reply_buffer(req, inode);
+               if (err) {
+                       ceph_mdsc_put_request(req);
+                       return err;
+               }
                req->r_inode = inode;
                ihold(inode);
                req->r_dentry = dget(file->f_dentry);
@@ -340,9 +343,6 @@ more:
                req->r_path2 = kstrdup(fi->last_name, GFP_NOFS);
                req->r_readdir_offset = fi->next_offset;
                req->r_args.readdir.frag = cpu_to_le32(frag);
-               req->r_args.readdir.max_entries = cpu_to_le32(max_entries);
-               req->r_args.readdir.max_bytes = cpu_to_le32(max_bytes);
-               req->r_num_caps = max_entries + 1;
                err = ceph_mdsc_do_request(mdsc, NULL, req);
                if (err < 0) {
                        ceph_mdsc_put_request(req);
@@ -369,9 +369,9 @@ more:
                                fi->next_offset = 0;
                        off = fi->next_offset;
                }
+               fi->frag = frag;
                fi->offset = fi->next_offset;
                fi->last_readdir = req;
-               fi->frag = frag;
 
                if (req->r_reply_info.dir_end) {
                        kfree(fi->last_name);
@@ -454,7 +454,7 @@ more:
        return 0;
 }
 
-static void reset_readdir(struct ceph_file_info *fi)
+static void reset_readdir(struct ceph_file_info *fi, unsigned frag)
 {
        if (fi->last_readdir) {
                ceph_mdsc_put_request(fi->last_readdir);
@@ -462,7 +462,10 @@ static void reset_readdir(struct ceph_file_info *fi)
        }
        kfree(fi->last_name);
        fi->last_name = NULL;
-       fi->next_offset = 2;  /* compensate for . and .. */
+       if (ceph_frag_is_leftmost(frag))
+               fi->next_offset = 2;  /* compensate for . and .. */
+       else
+               fi->next_offset = 0;
        if (fi->dentry) {
                dput(fi->dentry);
                fi->dentry = NULL;
@@ -474,7 +477,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
 {
        struct ceph_file_info *fi = file->private_data;
        struct inode *inode = file->f_mapping->host;
-       loff_t old_offset = offset;
+       loff_t old_offset = ceph_make_fpos(fi->frag, fi->next_offset);
        loff_t retval;
 
        mutex_lock(&inode->i_mutex);
@@ -491,7 +494,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
                goto out;
        }
 
-       if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
+       if (offset >= 0) {
                if (offset != file->f_pos) {
                        file->f_pos = offset;
                        file->f_version = 0;
@@ -504,14 +507,14 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
                 * seek to new frag, or seek prior to current chunk.
                 */
                if (offset == 0 ||
-                   fpos_frag(offset) != fpos_frag(old_offset) ||
+                   fpos_frag(offset) != fi->frag ||
                    fpos_off(offset) < fi->offset) {
                        dout("dir_llseek dropping %p content\n", file);
-                       reset_readdir(fi);
+                       reset_readdir(fi, fpos_frag(offset));
                }
 
                /* bump dir_release_count if we did a forward seek */
-               if (offset > old_offset)
+               if (fpos_cmp(offset, old_offset) > 0)
                        fi->dir_release_count--;
        }
 out:
@@ -812,8 +815,7 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
        }
        req->r_dentry = dget(dentry);
        req->r_num_caps = 2;
-       req->r_old_dentry = dget(old_dentry); /* or inode? hrm. */
-       req->r_old_dentry_dir = ceph_get_dentry_parent_inode(old_dentry);
+       req->r_old_dentry = dget(old_dentry);
        req->r_locked_dir = dir;
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
@@ -911,10 +913,11 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
        req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS);
        if (IS_ERR(req))
                return PTR_ERR(req);
+       ihold(old_dir);
        req->r_dentry = dget(new_dentry);
        req->r_num_caps = 2;
        req->r_old_dentry = dget(old_dentry);
-       req->r_old_dentry_dir = ceph_get_dentry_parent_inode(old_dentry);
+       req->r_old_dentry_dir = old_dir;
        req->r_locked_dir = new_dir;
        req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
index 16796be53ca59450ebc81a074c84e7e08955a71b..00d6af6a32ec9a37f204705da091122e7ddd7151 100644 (file)
@@ -7,23 +7,6 @@
 #include "super.h"
 #include "mds_client.h"
 
-/*
- * NFS export support
- *
- * NFS re-export of a ceph mount is, at present, only semireliable.
- * The basic issue is that the Ceph architectures doesn't lend itself
- * well to generating filehandles that will remain valid forever.
- *
- * So, we do our best.  If you're lucky, your inode will be in the
- * client's cache.  If it's not, and you have a connectable fh, then
- * the MDS server may be able to find it for you.  Otherwise, you get
- * ESTALE.
- *
- * There are ways to this more reliable, but in the non-connectable fh
- * case, we won't every work perfectly, and in the connectable case,
- * some changes are needed on the MDS side to work better.
- */
-
 /*
  * Basic fh
  */
@@ -32,22 +15,12 @@ struct ceph_nfs_fh {
 } __attribute__ ((packed));
 
 /*
- * Larger 'connectable' fh that includes parent ino and name hash.
- * Use this whenever possible, as it works more reliably.
+ * Larger fh that includes parent ino.
  */
 struct ceph_nfs_confh {
        u64 ino, parent_ino;
-       u32 parent_name_hash;
 } __attribute__ ((packed));
 
-/*
- * The presence of @parent_inode here tells us whether NFS wants a
- * connectable file handle.  However, we want to make a connectionable
- * file handle unconditionally so that the MDS gets as much of a hint
- * as possible.  That means we only use @parent_dentry to indicate
- * whether nfsd wants a connectable fh, and whether we should indicate
- * failure from a too-small @max_len.
- */
 static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
                          struct inode *parent_inode)
 {
@@ -56,54 +29,36 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
        struct ceph_nfs_confh *cfh = (void *)rawfh;
        int connected_handle_length = sizeof(*cfh)/4;
        int handle_length = sizeof(*fh)/4;
-       struct dentry *dentry;
-       struct dentry *parent;
 
        /* don't re-export snaps */
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EINVAL;
 
-       dentry = d_find_alias(inode);
+       if (parent_inode && (*max_len < connected_handle_length)) {
+               *max_len = connected_handle_length;
+               return FILEID_INVALID;
+       } else if (*max_len < handle_length) {
+               *max_len = handle_length;
+               return FILEID_INVALID;
+       }
 
-       /* if we found an alias, generate a connectable fh */
-       if (*max_len >= connected_handle_length && dentry) {
-               dout("encode_fh %p connectable\n", dentry);
-               spin_lock(&dentry->d_lock);
-               parent = dentry->d_parent;
+       if (parent_inode) {
+               dout("encode_fh %llx with parent %llx\n",
+                    ceph_ino(inode), ceph_ino(parent_inode));
                cfh->ino = ceph_ino(inode);
-               cfh->parent_ino = ceph_ino(parent->d_inode);
-               cfh->parent_name_hash = ceph_dentry_hash(parent->d_inode,
-                                                        dentry);
+               cfh->parent_ino = ceph_ino(parent_inode);
                *max_len = connected_handle_length;
-               type = 2;
-               spin_unlock(&dentry->d_lock);
-       } else if (*max_len >= handle_length) {
-               if (parent_inode) {
-                       /* nfsd wants connectable */
-                       *max_len = connected_handle_length;
-                       type = FILEID_INVALID;
-               } else {
-                       dout("encode_fh %p\n", dentry);
-                       fh->ino = ceph_ino(inode);
-                       *max_len = handle_length;
-                       type = 1;
-               }
+               type = FILEID_INO32_GEN_PARENT;
        } else {
+               dout("encode_fh %llx\n", ceph_ino(inode));
+               fh->ino = ceph_ino(inode);
                *max_len = handle_length;
-               type = FILEID_INVALID;
+               type = FILEID_INO32_GEN;
        }
-       if (dentry)
-               dput(dentry);
        return type;
 }
 
-/*
- * convert regular fh to dentry
- *
- * FIXME: we should try harder by querying the mds for the ino.
- */
-static struct dentry *__fh_to_dentry(struct super_block *sb,
-                                    struct ceph_nfs_fh *fh, int fh_len)
+static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
        struct inode *inode;
@@ -111,11 +66,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
        struct ceph_vino vino;
        int err;
 
-       if (fh_len < sizeof(*fh) / 4)
-               return ERR_PTR(-ESTALE);
-
-       dout("__fh_to_dentry %llx\n", fh->ino);
-       vino.ino = fh->ino;
+       vino.ino = ino;
        vino.snap = CEPH_NOSNAP;
        inode = ceph_find_inode(sb, vino);
        if (!inode) {
@@ -139,139 +90,161 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
 
        dentry = d_obtain_alias(inode);
        if (IS_ERR(dentry)) {
-               pr_err("fh_to_dentry %llx -- inode %p but ENOMEM\n",
-                      fh->ino, inode);
                iput(inode);
                return dentry;
        }
        err = ceph_init_dentry(dentry);
        if (err < 0) {
-               iput(inode);
+               dput(dentry);
                return ERR_PTR(err);
        }
-       dout("__fh_to_dentry %llx %p dentry %p\n", fh->ino, inode, dentry);
+       dout("__fh_to_dentry %llx %p dentry %p\n", ino, inode, dentry);
        return dentry;
 }
 
 /*
- * convert connectable fh to dentry
+ * convert regular fh to dentry
  */
-static struct dentry *__cfh_to_dentry(struct super_block *sb,
-                                     struct ceph_nfs_confh *cfh, int fh_len)
+static struct dentry *ceph_fh_to_dentry(struct super_block *sb,
+                                       struct fid *fid,
+                                       int fh_len, int fh_type)
+{
+       struct ceph_nfs_fh *fh = (void *)fid->raw;
+
+       if (fh_type != FILEID_INO32_GEN  &&
+           fh_type != FILEID_INO32_GEN_PARENT)
+               return NULL;
+       if (fh_len < sizeof(*fh) / 4)
+               return NULL;
+
+       dout("fh_to_dentry %llx\n", fh->ino);
+       return __fh_to_dentry(sb, fh->ino);
+}
+
+static struct dentry *__get_parent(struct super_block *sb,
+                                  struct dentry *child, u64 ino)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
+       struct ceph_mds_request *req;
        struct inode *inode;
        struct dentry *dentry;
-       struct ceph_vino vino;
        int err;
 
-       if (fh_len < sizeof(*cfh) / 4)
-               return ERR_PTR(-ESTALE);
-
-       dout("__cfh_to_dentry %llx (%llx/%x)\n",
-            cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
-
-       vino.ino = cfh->ino;
-       vino.snap = CEPH_NOSNAP;
-       inode = ceph_find_inode(sb, vino);
-       if (!inode) {
-               struct ceph_mds_request *req;
-
-               req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH,
-                                              USE_ANY_MDS);
-               if (IS_ERR(req))
-                       return ERR_CAST(req);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPPARENT,
+                                      USE_ANY_MDS);
+       if (IS_ERR(req))
+               return ERR_CAST(req);
 
-               req->r_ino1 = vino;
-               req->r_ino2.ino = cfh->parent_ino;
-               req->r_ino2.snap = CEPH_NOSNAP;
-               req->r_path2 = kmalloc(16, GFP_NOFS);
-               snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash);
-               req->r_num_caps = 1;
-               err = ceph_mdsc_do_request(mdsc, NULL, req);
-               inode = req->r_target_inode;
-               if (inode)
-                       ihold(inode);
-               ceph_mdsc_put_request(req);
-               if (!inode)
-                       return ERR_PTR(err ? err : -ESTALE);
+       if (child) {
+               req->r_inode = child->d_inode;
+               ihold(child->d_inode);
+       } else {
+               req->r_ino1 = (struct ceph_vino) {
+                       .ino = ino,
+                       .snap = CEPH_NOSNAP,
+               };
        }
+       req->r_num_caps = 1;
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
+       inode = req->r_target_inode;
+       if (inode)
+               ihold(inode);
+       ceph_mdsc_put_request(req);
+       if (!inode)
+               return ERR_PTR(-ENOENT);
 
        dentry = d_obtain_alias(inode);
        if (IS_ERR(dentry)) {
-               pr_err("cfh_to_dentry %llx -- inode %p but ENOMEM\n",
-                      cfh->ino, inode);
                iput(inode);
                return dentry;
        }
        err = ceph_init_dentry(dentry);
        if (err < 0) {
-               iput(inode);
+               dput(dentry);
                return ERR_PTR(err);
        }
-       dout("__cfh_to_dentry %llx %p dentry %p\n", cfh->ino, inode, dentry);
+       dout("__get_parent ino %llx parent %p ino %llx.%llx\n",
+            child ? ceph_ino(child->d_inode) : ino,
+            dentry, ceph_vinop(inode));
        return dentry;
 }
 
-static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
-                                       int fh_len, int fh_type)
+struct dentry *ceph_get_parent(struct dentry *child)
 {
-       if (fh_type == 1)
-               return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw,
-                                                               fh_len);
-       else
-               return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw,
-                                                               fh_len);
+       /* don't re-export snaps */
+       if (ceph_snap(child->d_inode) != CEPH_NOSNAP)
+               return ERR_PTR(-EINVAL);
+
+       dout("get_parent %p ino %llx.%llx\n",
+            child, ceph_vinop(child->d_inode));
+       return __get_parent(child->d_sb, child, 0);
 }
 
 /*
- * get parent, if possible.
- *
- * FIXME: we could do better by querying the mds to discover the
- * parent.
+ * convert regular fh to parent
  */
 static struct dentry *ceph_fh_to_parent(struct super_block *sb,
-                                        struct fid *fid,
+                                       struct fid *fid,
                                        int fh_len, int fh_type)
 {
        struct ceph_nfs_confh *cfh = (void *)fid->raw;
-       struct ceph_vino vino;
-       struct inode *inode;
        struct dentry *dentry;
-       int err;
 
-       if (fh_type == 1)
-               return ERR_PTR(-ESTALE);
+       if (fh_type != FILEID_INO32_GEN_PARENT)
+               return NULL;
        if (fh_len < sizeof(*cfh) / 4)
-               return ERR_PTR(-ESTALE);
+               return NULL;
 
-       pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
-                cfh->parent_name_hash);
+       dout("fh_to_parent %llx\n", cfh->parent_ino);
+       dentry = __get_parent(sb, NULL, cfh->ino);
+       if (IS_ERR(dentry) && PTR_ERR(dentry) == -ENOENT)
+               dentry = __fh_to_dentry(sb, cfh->parent_ino);
+       return dentry;
+}
 
-       vino.ino = cfh->ino;
-       vino.snap = CEPH_NOSNAP;
-       inode = ceph_find_inode(sb, vino);
-       if (!inode)
-               return ERR_PTR(-ESTALE);
+static int ceph_get_name(struct dentry *parent, char *name,
+                        struct dentry *child)
+{
+       struct ceph_mds_client *mdsc;
+       struct ceph_mds_request *req;
+       int err;
 
-       dentry = d_obtain_alias(inode);
-       if (IS_ERR(dentry)) {
-               pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n",
-                      cfh->ino, inode);
-               iput(inode);
-               return dentry;
-       }
-       err = ceph_init_dentry(dentry);
-       if (err < 0) {
-               iput(inode);
-               return ERR_PTR(err);
+       mdsc = ceph_inode_to_client(child->d_inode)->mdsc;
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPNAME,
+                                      USE_ANY_MDS);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       mutex_lock(&parent->d_inode->i_mutex);
+
+       req->r_inode = child->d_inode;
+       ihold(child->d_inode);
+       req->r_ino2 = ceph_vino(parent->d_inode);
+       req->r_locked_dir = parent->d_inode;
+       req->r_num_caps = 2;
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
+
+       mutex_unlock(&parent->d_inode->i_mutex);
+
+       if (!err) {
+               struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+               memcpy(name, rinfo->dname, rinfo->dname_len);
+               name[rinfo->dname_len] = 0;
+               dout("get_name %p ino %llx.%llx name %s\n",
+                    child, ceph_vinop(child->d_inode), name);
+       } else {
+               dout("get_name %p ino %llx.%llx err %d\n",
+                    child, ceph_vinop(child->d_inode), err);
        }
-       dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry);
-       return dentry;
+
+       ceph_mdsc_put_request(req);
+       return err;
 }
 
 const struct export_operations ceph_export_ops = {
        .encode_fh = ceph_encode_fh,
        .fh_to_dentry = ceph_fh_to_dentry,
        .fh_to_parent = ceph_fh_to_parent,
+       .get_parent = ceph_get_parent,
+       .get_name = ceph_get_name,
 };
index 09c7afe32e496c7dfe20d527106c7a184248c3ca..66075a4ad97900edbfaf98775d484c31c7496200 100644 (file)
@@ -210,7 +210,7 @@ int ceph_open(struct inode *inode, struct file *file)
        ihold(inode);
 
        req->r_num_caps = 1;
-       if (flags & (O_CREAT|O_TRUNC))
+       if (flags & O_CREAT)
                parent_inode = ceph_get_dentry_parent_inode(file->f_dentry);
        err = ceph_mdsc_do_request(mdsc, parent_inode, req);
        iput(parent_inode);
@@ -291,8 +291,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
                }
                err = finish_open(file, dentry, ceph_open, opened);
        }
-
 out_err:
+       if (!req->r_err && req->r_target_inode)
+               ceph_put_fmode(ceph_inode(req->r_target_inode), req->r_fmode);
        ceph_mdsc_put_request(req);
        dout("atomic_open result=%d\n", err);
        return err;
@@ -970,6 +971,7 @@ retry_snap:
                        goto retry_snap;
                }
        } else {
+               loff_t old_size = inode->i_size;
                /*
                 * No need to acquire the i_truncate_mutex. Because
                 * the MDS revokes Fwb caps before sending truncate
@@ -980,6 +982,8 @@ retry_snap:
                written = generic_file_buffered_write(iocb, iov, nr_segs,
                                                      pos, &iocb->ki_pos,
                                                      count, 0);
+               if (inode->i_size > old_size)
+                       ceph_fscache_update_objectsize(inode);
                mutex_unlock(&inode->i_mutex);
        }
 
index 32d519d8a2e210316fbf2af3b2c0a842d47a13b2..0b0728e5be2d7cba589a935159b88f9d26f0b2e9 100644 (file)
@@ -659,14 +659,6 @@ static int fill_inode(struct inode *inode,
                            le32_to_cpu(info->time_warp_seq),
                            &ctime, &mtime, &atime);
 
-       /* only update max_size on auth cap */
-       if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
-           ci->i_max_size != le64_to_cpu(info->max_size)) {
-               dout("max_size %lld -> %llu\n", ci->i_max_size,
-                    le64_to_cpu(info->max_size));
-               ci->i_max_size = le64_to_cpu(info->max_size);
-       }
-
        ci->i_layout = info->layout;
        inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
 
@@ -755,6 +747,14 @@ static int fill_inode(struct inode *inode,
                ci->i_max_offset = 2;
        }
 no_change:
+       /* only update max_size on auth cap */
+       if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
+           ci->i_max_size != le64_to_cpu(info->max_size)) {
+               dout("max_size %lld -> %llu\n", ci->i_max_size,
+                    le64_to_cpu(info->max_size));
+               ci->i_max_size = le64_to_cpu(info->max_size);
+       }
+
        spin_unlock(&ci->i_ceph_lock);
 
        /* queue truncate if we saw i_size decrease */
@@ -1044,10 +1044,59 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                                         session, req->r_request_started, -1,
                                         &req->r_caps_reservation);
                        if (err < 0)
-                               return err;
+                               goto done;
                } else {
                        WARN_ON_ONCE(1);
                }
+
+               if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME) {
+                       struct qstr dname;
+                       struct dentry *dn, *parent;
+
+                       BUG_ON(!rinfo->head->is_target);
+                       BUG_ON(req->r_dentry);
+
+                       parent = d_find_any_alias(dir);
+                       BUG_ON(!parent);
+
+                       dname.name = rinfo->dname;
+                       dname.len = rinfo->dname_len;
+                       dname.hash = full_name_hash(dname.name, dname.len);
+                       vino.ino = le64_to_cpu(rinfo->targeti.in->ino);
+                       vino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
+retry_lookup:
+                       dn = d_lookup(parent, &dname);
+                       dout("d_lookup on parent=%p name=%.*s got %p\n",
+                            parent, dname.len, dname.name, dn);
+
+                       if (!dn) {
+                               dn = d_alloc(parent, &dname);
+                               dout("d_alloc %p '%.*s' = %p\n", parent,
+                                    dname.len, dname.name, dn);
+                               if (dn == NULL) {
+                                       dput(parent);
+                                       err = -ENOMEM;
+                                       goto done;
+                               }
+                               err = ceph_init_dentry(dn);
+                               if (err < 0) {
+                                       dput(dn);
+                                       dput(parent);
+                                       goto done;
+                               }
+                       } else if (dn->d_inode &&
+                                  (ceph_ino(dn->d_inode) != vino.ino ||
+                                   ceph_snap(dn->d_inode) != vino.snap)) {
+                               dout(" dn %p points to wrong inode %p\n",
+                                    dn, dn->d_inode);
+                               d_delete(dn);
+                               dput(dn);
+                               goto retry_lookup;
+                       }
+
+                       req->r_dentry = dn;
+                       dput(parent);
+               }
        }
 
        if (rinfo->head->is_target) {
@@ -1063,7 +1112,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
 
                err = fill_inode(in, &rinfo->targeti, NULL,
                                session, req->r_request_started,
-                               (le32_to_cpu(rinfo->head->result) == 0) ?
+                               (!req->r_aborted && rinfo->head->result == 0) ?
                                req->r_fmode : -1,
                                &req->r_caps_reservation);
                if (err < 0) {
@@ -1616,8 +1665,6 @@ static const struct inode_operations ceph_symlink_iops = {
        .getxattr = ceph_getxattr,
        .listxattr = ceph_listxattr,
        .removexattr = ceph_removexattr,
-       .get_acl = ceph_get_acl,
-       .set_acl = ceph_set_acl,
 };
 
 /*
@@ -1627,7 +1674,6 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct inode *parent_inode;
        const unsigned int ia_valid = attr->ia_valid;
        struct ceph_mds_request *req;
        struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
@@ -1819,9 +1865,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
                req->r_inode_drop = release;
                req->r_args.setattr.mask = cpu_to_le32(mask);
                req->r_num_caps = 1;
-               parent_inode = ceph_get_dentry_parent_inode(dentry);
-               err = ceph_mdsc_do_request(mdsc, parent_inode, req);
-               iput(parent_inode);
+               err = ceph_mdsc_do_request(mdsc, NULL, req);
        }
        dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
             ceph_cap_string(dirtied), mask);
index dc66c9e023e4f3aee170db98d2bb549819d99abc..efbe082892920333e6d2c703fa58f0a275e3d87b 100644 (file)
@@ -64,7 +64,6 @@ static long __validate_layout(struct ceph_mds_client *mdsc,
 static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
 {
        struct inode *inode = file_inode(file);
-       struct inode *parent_inode;
        struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
        struct ceph_mds_request *req;
        struct ceph_ioctl_layout l;
@@ -121,9 +120,7 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
                cpu_to_le32(l.object_size);
        req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool);
 
-       parent_inode = ceph_get_dentry_parent_inode(file->f_dentry);
-       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
-       iput(parent_inode);
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
        ceph_mdsc_put_request(req);
        return err;
 }
index ae6d14e82b0f439153b5e62adfd4d0c2ebed73a1..d94ba0df9f4d195cabf677fcdcd41cc01096c7e7 100644 (file)
@@ -2,11 +2,31 @@
 
 #include <linux/file.h>
 #include <linux/namei.h>
+#include <linux/random.h>
 
 #include "super.h"
 #include "mds_client.h"
 #include <linux/ceph/pagelist.h>
 
+static u64 lock_secret;
+
+static inline u64 secure_addr(void *addr)
+{
+       u64 v = lock_secret ^ (u64)(unsigned long)addr;
+       /*
+        * Set the most significant bit, so that MDS knows the 'owner'
+        * is sufficient to identify the owner of lock. (old code uses
+        * both 'owner' and 'pid')
+        */
+       v |= (1ULL << 63);
+       return v;
+}
+
+void __init ceph_flock_init(void)
+{
+       get_random_bytes(&lock_secret, sizeof(lock_secret));
+}
+
 /**
  * Implement fcntl and flock locking functions.
  */
@@ -14,11 +34,11 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
                             int cmd, u8 wait, struct file_lock *fl)
 {
        struct inode *inode = file_inode(file);
-       struct ceph_mds_client *mdsc =
-               ceph_sb_to_client(inode->i_sb)->mdsc;
+       struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
        struct ceph_mds_request *req;
        int err;
        u64 length = 0;
+       u64 owner;
 
        req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
        if (IS_ERR(req))
@@ -32,25 +52,27 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
        else
                length = fl->fl_end - fl->fl_start + 1;
 
-       dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
-            "length: %llu, wait: %d, type: %d", (int)lock_type,
-            (int)operation, (u64)fl->fl_pid, fl->fl_start,
-            length, wait, fl->fl_type);
+       if (lock_type == CEPH_LOCK_FCNTL)
+               owner = secure_addr(fl->fl_owner);
+       else
+               owner = secure_addr(fl->fl_file);
+
+       dout("ceph_lock_message: rule: %d, op: %d, owner: %llx, pid: %llu, "
+            "start: %llu, length: %llu, wait: %d, type: %d", (int)lock_type,
+            (int)operation, owner, (u64)fl->fl_pid, fl->fl_start, length,
+            wait, fl->fl_type);
 
        req->r_args.filelock_change.rule = lock_type;
        req->r_args.filelock_change.type = cmd;
+       req->r_args.filelock_change.owner = cpu_to_le64(owner);
        req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
-       /* This should be adjusted, but I'm not sure if
-          namespaces actually get id numbers*/
-       req->r_args.filelock_change.pid_namespace =
-               cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
        req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
        req->r_args.filelock_change.length = cpu_to_le64(length);
        req->r_args.filelock_change.wait = wait;
 
        err = ceph_mdsc_do_request(mdsc, inode, req);
 
-       if ( operation == CEPH_MDS_OP_GETFILELOCK){
+       if (operation == CEPH_MDS_OP_GETFILELOCK) {
                fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
                if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
                        fl->fl_type = F_RDLCK;
@@ -87,14 +109,19 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
        u8 wait = 0;
        u16 op = CEPH_MDS_OP_SETFILELOCK;
 
-       fl->fl_nspid = get_pid(task_tgid(current));
-       dout("ceph_lock, fl_pid:%d", fl->fl_pid);
+       if (!(fl->fl_flags & FL_POSIX))
+               return -ENOLCK;
+       /* No mandatory locks */
+       if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
+               return -ENOLCK;
+
+       dout("ceph_lock, fl_owner: %p", fl->fl_owner);
 
        /* set wait bit as appropriate, then make command as Ceph expects it*/
-       if (F_SETLKW == cmd)
-               wait = 1;
-       if (F_GETLK == cmd)
+       if (IS_GETLK(cmd))
                op = CEPH_MDS_OP_GETFILELOCK;
+       else if (IS_SETLKW(cmd))
+               wait = 1;
 
        if (F_RDLCK == fl->fl_type)
                lock_cmd = CEPH_LOCK_SHARED;
@@ -105,7 +132,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 
        err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
        if (!err) {
-               if ( op != CEPH_MDS_OP_GETFILELOCK ){
+               if (op != CEPH_MDS_OP_GETFILELOCK) {
                        dout("mds locked, locking locally");
                        err = posix_lock_file(file, fl, NULL);
                        if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
@@ -131,20 +158,22 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
 {
        u8 lock_cmd;
        int err;
-       u8 wait = 1;
-
-       fl->fl_nspid = get_pid(task_tgid(current));
-       dout("ceph_flock, fl_pid:%d", fl->fl_pid);
-
-       /* set wait bit, then clear it out of cmd*/
-       if (cmd & LOCK_NB)
-               wait = 0;
-       cmd = cmd & (LOCK_SH | LOCK_EX | LOCK_UN);
-       /* set command sequence that Ceph wants to see:
-          shared lock, exclusive lock, or unlock */
-       if (LOCK_SH == cmd)
+       u8 wait = 0;
+
+       if (!(fl->fl_flags & FL_FLOCK))
+               return -ENOLCK;
+       /* No mandatory locks */
+       if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
+               return -ENOLCK;
+
+       dout("ceph_flock, fl_file: %p", fl->fl_file);
+
+       if (IS_SETLKW(cmd))
+               wait = 1;
+
+       if (F_RDLCK == fl->fl_type)
                lock_cmd = CEPH_LOCK_SHARED;
-       else if (LOCK_EX == cmd)
+       else if (F_WRLCK == fl->fl_type)
                lock_cmd = CEPH_LOCK_EXCL;
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
@@ -280,13 +309,14 @@ int lock_to_ceph_filelock(struct file_lock *lock,
                          struct ceph_filelock *cephlock)
 {
        int err = 0;
-
        cephlock->start = cpu_to_le64(lock->fl_start);
        cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
        cephlock->client = cpu_to_le64(0);
-       cephlock->pid = cpu_to_le64(lock->fl_pid);
-       cephlock->pid_namespace =
-               cpu_to_le64((u64)(unsigned long)lock->fl_nspid);
+       cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
+       if (lock->fl_flags & FL_POSIX)
+               cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
+       else
+               cephlock->owner = cpu_to_le64(secure_addr(lock->fl_file));
 
        switch (lock->fl_type) {
        case F_RDLCK:
index f4f050a69a48fff9a707c28d4a024691a5bdc814..2b4d093d056319424369f01321c710f2c9d27185 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/fs.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -165,21 +166,18 @@ static int parse_reply_info_dir(void **p, void *end,
        if (num == 0)
                goto done;
 
-       /* alloc large array */
-       info->dir_nr = num;
-       info->dir_in = kcalloc(num, sizeof(*info->dir_in) +
-                              sizeof(*info->dir_dname) +
-                              sizeof(*info->dir_dname_len) +
-                              sizeof(*info->dir_dlease),
-                              GFP_NOFS);
-       if (info->dir_in == NULL) {
-               err = -ENOMEM;
-               goto out_bad;
-       }
+       BUG_ON(!info->dir_in);
        info->dir_dname = (void *)(info->dir_in + num);
        info->dir_dname_len = (void *)(info->dir_dname + num);
        info->dir_dlease = (void *)(info->dir_dname_len + num);
+       if ((unsigned long)(info->dir_dlease + num) >
+           (unsigned long)info->dir_in + info->dir_buf_size) {
+               pr_err("dir contents are larger than expected\n");
+               WARN_ON(1);
+               goto bad;
+       }
 
+       info->dir_nr = num;
        while (num) {
                /* dentry */
                ceph_decode_need(p, end, sizeof(u32)*2, bad);
@@ -327,7 +325,9 @@ out_bad:
 
 static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
 {
-       kfree(info->dir_in);
+       if (!info->dir_in)
+               return;
+       free_pages((unsigned long)info->dir_in, get_order(info->dir_buf_size));
 }
 
 
@@ -512,12 +512,11 @@ void ceph_mdsc_release_request(struct kref *kref)
        struct ceph_mds_request *req = container_of(kref,
                                                    struct ceph_mds_request,
                                                    r_kref);
+       destroy_reply_info(&req->r_reply_info);
        if (req->r_request)
                ceph_msg_put(req->r_request);
-       if (req->r_reply) {
+       if (req->r_reply)
                ceph_msg_put(req->r_reply);
-               destroy_reply_info(&req->r_reply_info);
-       }
        if (req->r_inode) {
                ceph_put_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
                iput(req->r_inode);
@@ -528,7 +527,9 @@ void ceph_mdsc_release_request(struct kref *kref)
                iput(req->r_target_inode);
        if (req->r_dentry)
                dput(req->r_dentry);
-       if (req->r_old_dentry) {
+       if (req->r_old_dentry)
+               dput(req->r_old_dentry);
+       if (req->r_old_dentry_dir) {
                /*
                 * track (and drop pins for) r_old_dentry_dir
                 * separately, since r_old_dentry's d_parent may have
@@ -537,7 +538,6 @@ void ceph_mdsc_release_request(struct kref *kref)
                 */
                ceph_put_cap_refs(ceph_inode(req->r_old_dentry_dir),
                                  CEPH_CAP_PIN);
-               dput(req->r_old_dentry);
                iput(req->r_old_dentry_dir);
        }
        kfree(req->r_path1);
@@ -1311,6 +1311,9 @@ static int trim_caps(struct ceph_mds_client *mdsc,
                        trim_caps - session->s_trim_caps);
                session->s_trim_caps = 0;
        }
+
+       ceph_add_cap_releases(mdsc, session);
+       ceph_send_cap_releases(mdsc, session);
        return 0;
 }
 
@@ -1461,15 +1464,18 @@ static void discard_cap_releases(struct ceph_mds_client *mdsc,
 
        dout("discard_cap_releases mds%d\n", session->s_mds);
 
-       /* zero out the in-progress message */
-       msg = list_first_entry(&session->s_cap_releases,
-                              struct ceph_msg, list_head);
-       head = msg->front.iov_base;
-       num = le32_to_cpu(head->num);
-       dout("discard_cap_releases mds%d %p %u\n", session->s_mds, msg, num);
-       head->num = cpu_to_le32(0);
-       msg->front.iov_len = sizeof(*head);
-       session->s_num_cap_releases += num;
+       if (!list_empty(&session->s_cap_releases)) {
+               /* zero out the in-progress message */
+               msg = list_first_entry(&session->s_cap_releases,
+                                       struct ceph_msg, list_head);
+               head = msg->front.iov_base;
+               num = le32_to_cpu(head->num);
+               dout("discard_cap_releases mds%d %p %u\n",
+                    session->s_mds, msg, num);
+               head->num = cpu_to_le32(0);
+               msg->front.iov_len = sizeof(*head);
+               session->s_num_cap_releases += num;
+       }
 
        /* requeue completed messages */
        while (!list_empty(&session->s_cap_releases_done)) {
@@ -1492,6 +1498,43 @@ static void discard_cap_releases(struct ceph_mds_client *mdsc,
  * requests
  */
 
+int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
+                                   struct inode *dir)
+{
+       struct ceph_inode_info *ci = ceph_inode(dir);
+       struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+       struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options;
+       size_t size = sizeof(*rinfo->dir_in) + sizeof(*rinfo->dir_dname_len) +
+                     sizeof(*rinfo->dir_dname) + sizeof(*rinfo->dir_dlease);
+       int order, num_entries;
+
+       spin_lock(&ci->i_ceph_lock);
+       num_entries = ci->i_files + ci->i_subdirs;
+       spin_unlock(&ci->i_ceph_lock);
+       num_entries = max(num_entries, 1);
+       num_entries = min(num_entries, opt->max_readdir);
+
+       order = get_order(size * num_entries);
+       while (order >= 0) {
+               rinfo->dir_in = (void*)__get_free_pages(GFP_NOFS | __GFP_NOWARN,
+                                                       order);
+               if (rinfo->dir_in)
+                       break;
+               order--;
+       }
+       if (!rinfo->dir_in)
+               return -ENOMEM;
+
+       num_entries = (PAGE_SIZE << order) / size;
+       num_entries = min(num_entries, opt->max_readdir);
+
+       rinfo->dir_buf_size = PAGE_SIZE << order;
+       req->r_num_caps = num_entries + 1;
+       req->r_args.readdir.max_entries = cpu_to_le32(num_entries);
+       req->r_args.readdir.max_bytes = cpu_to_le32(opt->max_readdir_bytes);
+       return 0;
+}
+
 /*
  * Create an mds request.
  */
@@ -2053,7 +2096,7 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
                ceph_get_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
        if (req->r_locked_dir)
                ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
-       if (req->r_old_dentry)
+       if (req->r_old_dentry_dir)
                ceph_get_cap_refs(ceph_inode(req->r_old_dentry_dir),
                                  CEPH_CAP_PIN);
 
index 68288917c7371fbebc314a0085e691580f57a711..e90cfccf93bd9e90a21ef3c22ebfa9b54e43b3a1 100644 (file)
@@ -67,6 +67,7 @@ struct ceph_mds_reply_info_parsed {
                /* for readdir results */
                struct {
                        struct ceph_mds_reply_dirfrag *dir_dir;
+                       size_t                        dir_buf_size;
                        int                           dir_nr;
                        char                          **dir_dname;
                        u32                           *dir_dname_len;
@@ -346,7 +347,8 @@ extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc,
                                    struct dentry *dn);
 
 extern void ceph_invalidate_dir_request(struct ceph_mds_request *req);
-
+extern int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
+                                          struct inode *dir);
 extern struct ceph_mds_request *
 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
 extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
index 4440f447fd3f2329b28f8e88e44e10141e4b30c4..51cc23e4811147ad537fdc0d49ffb2f07bcc9dcf 100644 (file)
@@ -54,6 +54,7 @@ const char *ceph_mds_op_name(int op)
        case CEPH_MDS_OP_LOOKUPHASH:  return "lookuphash";
        case CEPH_MDS_OP_LOOKUPPARENT:  return "lookupparent";
        case CEPH_MDS_OP_LOOKUPINO:  return "lookupino";
+       case CEPH_MDS_OP_LOOKUPNAME:  return "lookupname";
        case CEPH_MDS_OP_GETATTR:  return "getattr";
        case CEPH_MDS_OP_SETXATTR: return "setxattr";
        case CEPH_MDS_OP_SETATTR: return "setattr";
index 10a4ccbf38dab2c6f26407e7383815986f337bc0..06150fd745ac65d72c456b1fe57f537336f1064a 100644 (file)
@@ -1026,6 +1026,7 @@ static int __init init_ceph(void)
        if (ret)
                goto out;
 
+       ceph_flock_init();
        ceph_xattr_init();
        ret = register_filesystem(&ceph_fs_type);
        if (ret)
index d8801a95b6857d514fc27e440af8d476513cae3e..7866cd05a6bbee4afd2478f3737d0ccd8ac28975 100644 (file)
@@ -577,7 +577,7 @@ struct ceph_file_info {
 
        /* readdir: position within a frag */
        unsigned offset;       /* offset of last chunk, adjusted for . and .. */
-       u64 next_offset;       /* offset of next chunk (last_name's + 1) */
+       unsigned next_offset;  /* offset of next chunk (last_name's + 1) */
        char *last_name;       /* last entry in previous chunk */
        struct dentry *dentry; /* next dentry (for dcache readdir) */
        int dir_release_count;
@@ -871,6 +871,7 @@ extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 extern const struct export_operations ceph_export_ops;
 
 /* locks.c */
+extern __init void ceph_flock_init(void);
 extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl);
 extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl);
 extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num);
index a55ec37378c6730efa476d3d6a923e37ba10ec72..c9c2b887381ec2504ee48c673cf113e396f3b04e 100644 (file)
@@ -64,32 +64,48 @@ static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci)
 }
 
 static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
-                                       size_t size)
+                                  size_t size)
 {
        int ret;
        struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
        struct ceph_osd_client *osdc = &fsc->client->osdc;
        s64 pool = ceph_file_layout_pg_pool(ci->i_layout);
        const char *pool_name;
+       char buf[128];
 
        dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode);
        down_read(&osdc->map_sem);
        pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
-       if (pool_name)
-               ret = snprintf(val, size,
-               "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%s",
+       if (pool_name) {
+               size_t len = strlen(pool_name);
+               ret = snprintf(buf, sizeof(buf),
+               "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=",
                (unsigned long long)ceph_file_layout_su(ci->i_layout),
                (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
-               (unsigned long long)ceph_file_layout_object_size(ci->i_layout),
-               pool_name);
-       else
-               ret = snprintf(val, size,
+               (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
+               if (!size) {
+                       ret += len;
+               } else if (ret + len > size) {
+                       ret = -ERANGE;
+               } else {
+                       memcpy(val, buf, ret);
+                       memcpy(val + ret, pool_name, len);
+                       ret += len;
+               }
+       } else {
+               ret = snprintf(buf, sizeof(buf),
                "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%lld",
                (unsigned long long)ceph_file_layout_su(ci->i_layout),
                (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
                (unsigned long long)ceph_file_layout_object_size(ci->i_layout),
                (unsigned long long)pool);
-
+               if (size) {
+                       if (ret <= size)
+                               memcpy(val, buf, ret);
+                       else
+                               ret = -ERANGE;
+               }
+       }
        up_read(&osdc->map_sem);
        return ret;
 }
@@ -215,7 +231,7 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {
                .name_size = sizeof("ceph.dir.layout"),
                .getxattr_cb = ceph_vxattrcb_layout,
                .readonly = false,
-               .hidden = false,
+               .hidden = true,
                .exists_cb = ceph_vxattrcb_layout_exists,
        },
        XATTR_LAYOUT_FIELD(dir, layout, stripe_unit),
@@ -242,7 +258,7 @@ static struct ceph_vxattr ceph_file_vxattrs[] = {
                .name_size = sizeof("ceph.file.layout"),
                .getxattr_cb = ceph_vxattrcb_layout,
                .readonly = false,
-               .hidden = false,
+               .hidden = true,
                .exists_cb = ceph_vxattrcb_layout_exists,
        },
        XATTR_LAYOUT_FIELD(file, layout, stripe_unit),
@@ -842,7 +858,6 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
        struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
        struct inode *inode = dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct inode *parent_inode;
        struct ceph_mds_request *req;
        struct ceph_mds_client *mdsc = fsc->mdsc;
        int err;
@@ -893,9 +908,7 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
        req->r_data_len = size;
 
        dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
-       parent_inode = ceph_get_dentry_parent_inode(dentry);
-       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
-       iput(parent_inode);
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
        ceph_mdsc_put_request(req);
        dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
 
@@ -1019,7 +1032,6 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name)
        struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
        struct ceph_mds_client *mdsc = fsc->mdsc;
        struct inode *inode = dentry->d_inode;
-       struct inode *parent_inode;
        struct ceph_mds_request *req;
        int err;
 
@@ -1033,9 +1045,7 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name)
        req->r_num_caps = 1;
        req->r_path2 = kstrdup(name, GFP_NOFS);
 
-       parent_inode = ceph_get_dentry_parent_inode(dentry);
-       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
-       iput(parent_inode);
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
        ceph_mdsc_put_request(req);
        return err;
 }
index ab8ad2546c3e69d40f005f193c064a9062a2977a..2c70cbe35d39c3b7df79dd0b7e2b3fde6401f8fe 100644 (file)
@@ -541,6 +541,7 @@ static int cifs_show_stats(struct seq_file *s, struct dentry *root)
 
 static int cifs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        return 0;
 }
index 626abc02b694e074cd9dc631cc619b7d8c9e44ed..d9c7751f10acef9bc7195c342552c4d58e0f9a71 100644 (file)
@@ -96,6 +96,7 @@ void coda_destroy_inodecache(void)
 
 static int coda_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NOATIME;
        return 0;
 }
index f86df85dff612b2910e6e33f35fc8d85c13b635b..ca926ad0430cf715af12ebc3f0fa86d8c273d492 100644 (file)
@@ -399,12 +399,28 @@ static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *u
 }
 #endif
 
+static unsigned int
+convert_fcntl_cmd(unsigned int cmd)
+{
+       switch (cmd) {
+       case F_GETLK64:
+               return F_GETLK;
+       case F_SETLK64:
+               return F_SETLK;
+       case F_SETLKW64:
+               return F_SETLKW;
+       }
+
+       return cmd;
+}
+
 COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
                       compat_ulong_t, arg)
 {
        mm_segment_t old_fs;
        struct flock f;
        long ret;
+       unsigned int conv_cmd;
 
        switch (cmd) {
        case F_GETLK:
@@ -441,16 +457,18 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
        case F_GETLK64:
        case F_SETLK64:
        case F_SETLKW64:
+       case F_GETLKP:
+       case F_SETLKP:
+       case F_SETLKPW:
                ret = get_compat_flock64(&f, compat_ptr(arg));
                if (ret != 0)
                        break;
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               ret = sys_fcntl(fd, (cmd == F_GETLK64) ? F_GETLK :
-                               ((cmd == F_SETLK64) ? F_SETLK : F_SETLKW),
-                               (unsigned long)&f);
+               conv_cmd = convert_fcntl_cmd(cmd);
+               ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f);
                set_fs(old_fs);
-               if (cmd == F_GETLK64 && ret == 0) {
+               if ((conv_cmd == F_GETLK || conv_cmd == F_GETLKP) && ret == 0) {
                        /* need to return lock information - see above for commentary */
                        if (f.l_start > COMPAT_LOFF_T_MAX)
                                ret = -EOVERFLOW;
@@ -471,8 +489,15 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
 COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
                       compat_ulong_t, arg)
 {
-       if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64))
+       switch (cmd) {
+       case F_GETLK64:
+       case F_SETLK64:
+       case F_SETLKW64:
+       case F_GETLKP:
+       case F_SETLKP:
+       case F_SETLKPW:
                return -EINVAL;
+       }
        return compat_sys_fcntl64(fd, cmd, arg);
 }
 
index a1f801c14fbc206bacf02a12040c4b3c1515937c..ddcfe590b8a857a13faf7c5eefc4a9d7d8bcbdb9 100644 (file)
@@ -243,6 +243,7 @@ static void cramfs_kill_sb(struct super_block *sb)
 
 static int cramfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index ca02c13a84aa24d55b18bbced577ece923605665..66cba5a8a3467768edeeec573d2a61e5bfea27cc 100644 (file)
@@ -2483,12 +2483,14 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
                        dentry->d_name.name = dentry->d_iname;
                } else {
                        /*
-                        * Both are internal.  Just copy target to dentry
+                        * Both are internal.
                         */
-                       memcpy(dentry->d_iname, target->d_name.name,
-                                       target->d_name.len + 1);
-                       dentry->d_name.len = target->d_name.len;
-                       return;
+                       unsigned int i;
+                       BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long)));
+                       for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) {
+                               swap(((long *) &dentry->d_iname)[i],
+                                    ((long *) &target->d_iname)[i]);
+                       }
                }
        }
        swap(dentry->d_name.len, target->d_name.len);
@@ -2545,13 +2547,15 @@ static void dentry_unlock_parents_for_move(struct dentry *dentry,
  * __d_move - move a dentry
  * @dentry: entry to move
  * @target: new dentry
+ * @exchange: exchange the two dentries
  *
  * Update the dcache to reflect the move of a file name. Negative
  * dcache entries should not be moved in this way. Caller must hold
  * rename_lock, the i_mutex of the source and target directories,
  * and the sb->s_vfs_rename_mutex if they differ. See lock_rename().
  */
-static void __d_move(struct dentry * dentry, struct dentry * target)
+static void __d_move(struct dentry *dentry, struct dentry *target,
+                    bool exchange)
 {
        if (!dentry->d_inode)
                printk(KERN_WARNING "VFS: moving negative dcache entry\n");
@@ -2573,8 +2577,15 @@ static void __d_move(struct dentry * dentry, struct dentry * target)
        __d_drop(dentry);
        __d_rehash(dentry, d_hash(target->d_parent, target->d_name.hash));
 
-       /* Unhash the target: dput() will then get rid of it */
+       /*
+        * Unhash the target (d_delete() is not usable here).  If exchanging
+        * the two dentries, then rehash onto the other's hash queue.
+        */
        __d_drop(target);
+       if (exchange) {
+               __d_rehash(target,
+                          d_hash(dentry->d_parent, dentry->d_name.hash));
+       }
 
        list_del(&dentry->d_u.d_child);
        list_del(&target->d_u.d_child);
@@ -2601,6 +2612,8 @@ static void __d_move(struct dentry * dentry, struct dentry * target)
        write_seqcount_end(&dentry->d_seq);
 
        dentry_unlock_parents_for_move(dentry, target);
+       if (exchange)
+               fsnotify_d_move(target);
        spin_unlock(&target->d_lock);
        fsnotify_d_move(dentry);
        spin_unlock(&dentry->d_lock);
@@ -2618,11 +2631,30 @@ static void __d_move(struct dentry * dentry, struct dentry * target)
 void d_move(struct dentry *dentry, struct dentry *target)
 {
        write_seqlock(&rename_lock);
-       __d_move(dentry, target);
+       __d_move(dentry, target, false);
        write_sequnlock(&rename_lock);
 }
 EXPORT_SYMBOL(d_move);
 
+/*
+ * d_exchange - exchange two dentries
+ * @dentry1: first dentry
+ * @dentry2: second dentry
+ */
+void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
+{
+       write_seqlock(&rename_lock);
+
+       WARN_ON(!dentry1->d_inode);
+       WARN_ON(!dentry2->d_inode);
+       WARN_ON(IS_ROOT(dentry1));
+       WARN_ON(IS_ROOT(dentry2));
+
+       __d_move(dentry1, dentry2, true);
+
+       write_sequnlock(&rename_lock);
+}
+
 /**
  * d_ancestor - search for an ancestor
  * @p1: ancestor dentry
@@ -2670,7 +2702,7 @@ static struct dentry *__d_unalias(struct inode *inode,
        m2 = &alias->d_parent->d_inode->i_mutex;
 out_unalias:
        if (likely(!d_mountpoint(alias))) {
-               __d_move(alias, dentry);
+               __d_move(alias, dentry, false);
                ret = alias;
        }
 out_err:
index ca4a08f383743868db0a4949c608b1b3cc4e1be1..8c41b52da35872461cffbbebcd0299b2cc9d4d45 100644 (file)
@@ -218,6 +218,7 @@ static int debugfs_remount(struct super_block *sb, int *flags, char *data)
        int err;
        struct debugfs_fs_info *fsi = sb->s_fs_info;
 
+       sync_filesystem(sb);
        err = debugfs_parse_options(data, &fsi->mount_opts);
        if (err)
                goto fail;
index a726b9f29cb71735eb99ada9367f4348da45eb3d..c71038079b47831bb14b58e375592044906091c3 100644 (file)
@@ -313,6 +313,7 @@ static int devpts_remount(struct super_block *sb, int *flags, char *data)
        struct pts_fs_info *fsi = DEVPTS_SB(sb);
        struct pts_mount_opts *opts = &fsi->mount_opts;
 
+       sync_filesystem(sb);
        err = parse_mount_options(data, PARSE_REMOUNT, opts);
 
        /*
index 6e6bff3752446036990fb4a5d0eca4cdaad3fac5..31ba0935e32ed2f271253a1d828778a91193b211 100644 (file)
@@ -1193,13 +1193,19 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        }
 
        /*
-        * For file extending writes updating i_size before data
-        * writeouts complete can expose uninitialized blocks. So
-        * even for AIO, we need to wait for i/o to complete before
-        * returning in this case.
+        * For file extending writes updating i_size before data writeouts
+        * complete can expose uninitialized blocks in dumb filesystems.
+        * In that case we need to wait for I/O completion even if asked
+        * for an asynchronous write.
         */
-       dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) &&
-               (end > i_size_read(inode)));
+       if (is_sync_kiocb(iocb))
+               dio->is_async = false;
+       else if (!(dio->flags & DIO_ASYNC_EXTEND) &&
+            (rw & WRITE) && end > i_size_read(inode))
+               dio->is_async = false;
+       else
+               dio->is_async = true;
+
        dio->inode = inode;
        dio->rw = rw;
 
index 0e90f0c91b931c74d2c0fdd51b9c54de3330e32f..dcea1e37a1b7342ee78d245e7398809620d8e789 100644 (file)
@@ -14,6 +14,7 @@
 #include "dlm_internal.h"
 #include "lock.h"
 #include "user.h"
+#include "ast.h"
 
 static uint64_t dlm_cb_seq;
 static DEFINE_SPINLOCK(dlm_cb_seq_spin);
@@ -308,6 +309,6 @@ void dlm_callback_resume(struct dlm_ls *ls)
        mutex_unlock(&ls->ls_cb_mutex);
 
        if (count)
-               log_debug(ls, "dlm_callback_resume %d", count);
+               log_rinfo(ls, "dlm_callback_resume %d", count);
 }
 
index 278a75cda4463006d4b2c2e85d75c7728d5b4526..d975851a7e1e2e4794859a36e516050a16856075 100644 (file)
@@ -68,7 +68,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
        uint16_t namelen;
        unsigned int count = 0, count_match = 0, count_bad = 0, count_add = 0;
 
-       log_debug(ls, "dlm_recover_directory");
+       log_rinfo(ls, "dlm_recover_directory");
 
        if (dlm_no_directory(ls))
                goto out_status;
@@ -189,7 +189,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
        error = 0;
        dlm_set_recover_status(ls, DLM_RS_DIR);
 
-       log_debug(ls, "dlm_recover_directory %u in %u new",
+       log_rinfo(ls, "dlm_recover_directory %u in %u new",
                  count, count_add);
  out_free:
        kfree(last_name);
index e7665c31f7b10dda86364567c538c7737a1421db..5eff6ea3e27f19423be38f8372e65031855c0c5a 100644 (file)
@@ -65,6 +65,8 @@ struct dlm_mhandle;
        printk(KERN_ERR "dlm: "fmt"\n" , ##args)
 #define log_error(ls, fmt, args...) \
        printk(KERN_ERR "dlm: %s: " fmt "\n", (ls)->ls_name , ##args)
+#define log_rinfo(ls, fmt, args...) \
+       printk(KERN_INFO "dlm: %s: " fmt "\n", (ls)->ls_name , ##args);
 
 #define log_debug(ls, fmt, args...) \
 do { \
index e223a911a8346691d065e573f0ce0ab0ea9465fc..83f3d5520307f86c1e4ba1079b8635358d7bac08 100644 (file)
@@ -687,6 +687,7 @@ static int find_rsb_dir(struct dlm_ls *ls, char *name, int len,
                log_error(ls, "find_rsb new from_other %d dir %d our %d %s",
                          from_nodeid, dir_nodeid, our_nodeid, r->res_name);
                dlm_free_rsb(r);
+               r = NULL;
                error = -ENOTBLK;
                goto out_unlock;
        }
@@ -5462,7 +5463,7 @@ void dlm_recover_purge(struct dlm_ls *ls)
        up_write(&ls->ls_root_sem);
 
        if (lkb_count)
-               log_debug(ls, "dlm_recover_purge %u locks for %u nodes",
+               log_rinfo(ls, "dlm_recover_purge %u locks for %u nodes",
                          lkb_count, nodes_count);
 }
 
@@ -5536,7 +5537,7 @@ void dlm_recover_grant(struct dlm_ls *ls)
        }
 
        if (lkb_count)
-               log_debug(ls, "dlm_recover_grant %u locks on %u resources",
+               log_rinfo(ls, "dlm_recover_grant %u locks on %u resources",
                          lkb_count, rsb_count);
 }
 
@@ -5695,7 +5696,7 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
        put_rsb(r);
  out:
        if (error && error != -EEXIST)
-               log_debug(ls, "dlm_recover_master_copy remote %d %x error %d",
+               log_rinfo(ls, "dlm_recover_master_copy remote %d %x error %d",
                          from_nodeid, remid, error);
        rl->rl_result = cpu_to_le32(error);
        return error;
index d5abafd56a6d69e53242f61fd487b6c04798abb5..04d6398c1f1ce3e408a115a8c4f2feca7b2c67e1 100644 (file)
@@ -190,7 +190,7 @@ static int do_uevent(struct dlm_ls *ls, int in)
        else
                kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);
 
-       log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");
+       log_rinfo(ls, "%s the lockspace group...", in ? "joining" : "leaving");
 
        /* dlm_controld will see the uevent, do the necessary group management
           and then write to sysfs to wake us */
@@ -198,7 +198,7 @@ static int do_uevent(struct dlm_ls *ls, int in)
        error = wait_event_interruptible(ls->ls_uevent_wait,
                        test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
 
-       log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);
+       log_rinfo(ls, "group event done %d %d", error, ls->ls_uevent_result);
 
        if (error)
                goto out;
@@ -640,7 +640,7 @@ static int new_lockspace(const char *name, const char *cluster,
 
        dlm_create_debug_file(ls);
 
-       log_debug(ls, "join complete");
+       log_rinfo(ls, "join complete");
        *lockspace = ls;
        return 0;
 
@@ -835,7 +835,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
        dlm_clear_members(ls);
        dlm_clear_members_gone(ls);
        kfree(ls->ls_node_array);
-       log_debug(ls, "release_lockspace final free");
+       log_rinfo(ls, "release_lockspace final free");
        kobject_put(&ls->ls_kobj);
        /* The ls structure will be freed when the kobject is done with */
 
index 476557b54921793a246cb11b1fc8f19c348aa17d..9c47f1c14a8badb59048a88cf33b674e93a679e4 100644 (file)
@@ -60,18 +60,15 @@ void dlm_slots_copy_out(struct dlm_ls *ls, struct dlm_rcom *rc)
 
 #define SLOT_DEBUG_LINE 128
 
-static void log_debug_slots(struct dlm_ls *ls, uint32_t gen, int num_slots,
-                           struct rcom_slot *ro0, struct dlm_slot *array,
-                           int array_size)
+static void log_slots(struct dlm_ls *ls, uint32_t gen, int num_slots,
+                     struct rcom_slot *ro0, struct dlm_slot *array,
+                     int array_size)
 {
        char line[SLOT_DEBUG_LINE];
        int len = SLOT_DEBUG_LINE - 1;
        int pos = 0;
        int ret, i;
 
-       if (!dlm_config.ci_log_debug)
-               return;
-
        memset(line, 0, sizeof(line));
 
        if (array) {
@@ -95,7 +92,7 @@ static void log_debug_slots(struct dlm_ls *ls, uint32_t gen, int num_slots,
                }
        }
 
-       log_debug(ls, "generation %u slots %d%s", gen, num_slots, line);
+       log_rinfo(ls, "generation %u slots %d%s", gen, num_slots, line);
 }
 
 int dlm_slots_copy_in(struct dlm_ls *ls)
@@ -129,7 +126,7 @@ int dlm_slots_copy_in(struct dlm_ls *ls)
                ro->ro_slot = le16_to_cpu(ro->ro_slot);
        }
 
-       log_debug_slots(ls, gen, num_slots, ro0, NULL, 0);
+       log_slots(ls, gen, num_slots, ro0, NULL, 0);
 
        list_for_each_entry(memb, &ls->ls_nodes, list) {
                for (i = 0, ro = ro0; i < num_slots; i++, ro++) {
@@ -274,7 +271,7 @@ int dlm_slots_assign(struct dlm_ls *ls, int *num_slots, int *slots_size,
 
        gen++;
 
-       log_debug_slots(ls, gen, num, NULL, array, array_size);
+       log_slots(ls, gen, num, NULL, array, array_size);
 
        max_slots = (dlm_config.ci_buffer_size - sizeof(struct dlm_rcom) -
                     sizeof(struct rcom_config)) / sizeof(struct rcom_slot);
@@ -447,7 +444,7 @@ static int ping_members(struct dlm_ls *ls)
                        break;
        }
        if (error)
-               log_debug(ls, "ping_members aborted %d last nodeid %d",
+               log_rinfo(ls, "ping_members aborted %d last nodeid %d",
                          error, ls->ls_recover_nodeid);
        return error;
 }
@@ -539,7 +536,7 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
           count as a negative change so the "neg" recovery steps will happen */
 
        list_for_each_entry(memb, &ls->ls_nodes_gone, list) {
-               log_debug(ls, "prev removed member %d", memb->nodeid);
+               log_rinfo(ls, "prev removed member %d", memb->nodeid);
                neg++;
        }
 
@@ -551,10 +548,10 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
                        continue;
 
                if (!node) {
-                       log_debug(ls, "remove member %d", memb->nodeid);
+                       log_rinfo(ls, "remove member %d", memb->nodeid);
                } else {
                        /* removed and re-added */
-                       log_debug(ls, "remove member %d comm_seq %u %u",
+                       log_rinfo(ls, "remove member %d comm_seq %u %u",
                                  memb->nodeid, memb->comm_seq, node->comm_seq);
                }
 
@@ -571,7 +568,7 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
                if (dlm_is_member(ls, node->nodeid))
                        continue;
                dlm_add_member(ls, node);
-               log_debug(ls, "add member %d", node->nodeid);
+               log_rinfo(ls, "add member %d", node->nodeid);
        }
 
        list_for_each_entry(memb, &ls->ls_nodes, list) {
@@ -591,7 +588,7 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
                complete(&ls->ls_members_done);
        }
 
-       log_debug(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes);
+       log_rinfo(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes);
        return error;
 }
 
index a6bc63f6e31baa6ac6be822c048206daa8b77ad4..eaea789bf97d0dd862545c202156484a532eedbb 100644 (file)
@@ -526,7 +526,7 @@ int dlm_recover_masters(struct dlm_ls *ls)
        int nodir = dlm_no_directory(ls);
        int error;
 
-       log_debug(ls, "dlm_recover_masters");
+       log_rinfo(ls, "dlm_recover_masters");
 
        down_read(&ls->ls_root_sem);
        list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
@@ -552,7 +552,7 @@ int dlm_recover_masters(struct dlm_ls *ls)
        }
        up_read(&ls->ls_root_sem);
 
-       log_debug(ls, "dlm_recover_masters %u of %u", count, total);
+       log_rinfo(ls, "dlm_recover_masters %u of %u", count, total);
 
        error = dlm_wait_function(ls, &recover_idr_empty);
  out:
@@ -685,7 +685,7 @@ int dlm_recover_locks(struct dlm_ls *ls)
        }
        up_read(&ls->ls_root_sem);
 
-       log_debug(ls, "dlm_recover_locks %d out", count);
+       log_rinfo(ls, "dlm_recover_locks %d out", count);
 
        error = dlm_wait_function(ls, &recover_list_empty);
  out:
@@ -883,7 +883,7 @@ void dlm_recover_rsbs(struct dlm_ls *ls)
        up_read(&ls->ls_root_sem);
 
        if (count)
-               log_debug(ls, "dlm_recover_rsbs %d done", count);
+               log_rinfo(ls, "dlm_recover_rsbs %d done", count);
 }
 
 /* Create a single list of all root rsb's to be used during recovery */
@@ -950,6 +950,6 @@ void dlm_clear_toss(struct dlm_ls *ls)
        }
 
        if (count)
-               log_debug(ls, "dlm_clear_toss %u done", count);
+               log_rinfo(ls, "dlm_clear_toss %u done", count);
 }
 
index 32f9f8926ec3f17a3a69433402e8a0fecb07a1f6..6859b4bf971ece075e6bee500e036807be88854f 100644 (file)
@@ -55,7 +55,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
        unsigned long start;
        int error, neg = 0;
 
-       log_debug(ls, "dlm_recover %llu", (unsigned long long)rv->seq);
+       log_rinfo(ls, "dlm_recover %llu", (unsigned long long)rv->seq);
 
        mutex_lock(&ls->ls_recoverd_active);
 
@@ -76,7 +76,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_members(ls, rv, &neg);
        if (error) {
-               log_debug(ls, "dlm_recover_members error %d", error);
+               log_rinfo(ls, "dlm_recover_members error %d", error);
                goto fail;
        }
 
@@ -90,7 +90,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_members_wait(ls);
        if (error) {
-               log_debug(ls, "dlm_recover_members_wait error %d", error);
+               log_rinfo(ls, "dlm_recover_members_wait error %d", error);
                goto fail;
        }
 
@@ -103,7 +103,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_directory(ls);
        if (error) {
-               log_debug(ls, "dlm_recover_directory error %d", error);
+               log_rinfo(ls, "dlm_recover_directory error %d", error);
                goto fail;
        }
 
@@ -111,11 +111,11 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_directory_wait(ls);
        if (error) {
-               log_debug(ls, "dlm_recover_directory_wait error %d", error);
+               log_rinfo(ls, "dlm_recover_directory_wait error %d", error);
                goto fail;
        }
 
-       log_debug(ls, "dlm_recover_directory %u out %u messages",
+       log_rinfo(ls, "dlm_recover_directory %u out %u messages",
                  ls->ls_recover_dir_sent_res, ls->ls_recover_dir_sent_msg);
 
        /*
@@ -144,7 +144,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_masters(ls);
                if (error) {
-                       log_debug(ls, "dlm_recover_masters error %d", error);
+                       log_rinfo(ls, "dlm_recover_masters error %d", error);
                        goto fail;
                }
 
@@ -154,7 +154,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_locks(ls);
                if (error) {
-                       log_debug(ls, "dlm_recover_locks error %d", error);
+                       log_rinfo(ls, "dlm_recover_locks error %d", error);
                        goto fail;
                }
 
@@ -162,11 +162,11 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_locks_wait(ls);
                if (error) {
-                       log_debug(ls, "dlm_recover_locks_wait error %d", error);
+                       log_rinfo(ls, "dlm_recover_locks_wait error %d", error);
                        goto fail;
                }
 
-               log_debug(ls, "dlm_recover_locks %u in",
+               log_rinfo(ls, "dlm_recover_locks %u in",
                          ls->ls_recover_locks_in);
 
                /*
@@ -186,7 +186,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
                error = dlm_recover_locks_wait(ls);
                if (error) {
-                       log_debug(ls, "dlm_recover_locks_wait error %d", error);
+                       log_rinfo(ls, "dlm_recover_locks_wait error %d", error);
                        goto fail;
                }
        }
@@ -205,7 +205,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = dlm_recover_done_wait(ls);
        if (error) {
-               log_debug(ls, "dlm_recover_done_wait error %d", error);
+               log_rinfo(ls, "dlm_recover_done_wait error %d", error);
                goto fail;
        }
 
@@ -217,25 +217,25 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        error = enable_locking(ls, rv->seq);
        if (error) {
-               log_debug(ls, "enable_locking error %d", error);
+               log_rinfo(ls, "enable_locking error %d", error);
                goto fail;
        }
 
        error = dlm_process_requestqueue(ls);
        if (error) {
-               log_debug(ls, "dlm_process_requestqueue error %d", error);
+               log_rinfo(ls, "dlm_process_requestqueue error %d", error);
                goto fail;
        }
 
        error = dlm_recover_waiters_post(ls);
        if (error) {
-               log_debug(ls, "dlm_recover_waiters_post error %d", error);
+               log_rinfo(ls, "dlm_recover_waiters_post error %d", error);
                goto fail;
        }
 
        dlm_recover_grant(ls);
 
-       log_debug(ls, "dlm_recover %llu generation %u done: %u ms",
+       log_rinfo(ls, "dlm_recover %llu generation %u done: %u ms",
                  (unsigned long long)rv->seq, ls->ls_generation,
                  jiffies_to_msecs(jiffies - start));
        mutex_unlock(&ls->ls_recoverd_active);
@@ -245,7 +245,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
  fail:
        dlm_release_root_list(ls);
-       log_debug(ls, "dlm_recover %llu error %d",
+       log_rinfo(ls, "dlm_recover %llu error %d",
                  (unsigned long long)rv->seq, error);
        mutex_unlock(&ls->ls_recoverd_active);
        return error;
index b167ca48b8eef4984dec79a609644012421e6fea..d4a9431ec73ce0cb215fc3b6e52727b4059f9528 100644 (file)
@@ -641,7 +641,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        }
        rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
                        lower_new_dir_dentry->d_inode, lower_new_dentry,
-                       NULL);
+                       NULL, 0);
        if (rc)
                goto out_lock;
        if (target_inode)
index f8def1acf08cf3e2e313319f810854131830d62b..3befcc9f5d63c55c9872989300ff7f744553be1f 100644 (file)
@@ -114,6 +114,7 @@ static void destroy_inodecache(void)
 
 static int efs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 20d6697bd6386560a679dda5e8b8592a65d63798..d260115c0350e91be14eca760b813032e5325fca 100644 (file)
@@ -1254,6 +1254,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
        unsigned long old_sb_flags;
        int err;
 
+       sync_filesystem(sb);
        spin_lock(&sbi->s_lock);
 
        /* Store the old options */
index 37fd31ed16e781fd525773e2f9dc0a2e7b274ab0..95c6c5a6d0c56e20fe6bc2374dc8a3bed5da2b72 100644 (file)
@@ -2649,6 +2649,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
        int i;
 #endif
 
+       sync_filesystem(sb);
+
        /* Store the original options */
        old_sb_flags = sb->s_flags;
        old_opts.s_mount_opt = sbi->s_mount_opt;
index d3a534fdc5ff6c766131e5d843591149736cc4d8..f1c65dc7cc0ad268a9fccc7b6f1aeaf078d84a0a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/percpu_counter.h>
 #include <linux/ratelimit.h>
 #include <crypto/hash.h>
+#include <linux/falloc.h>
 #ifdef __KERNEL__
 #include <linux/compat.h>
 #endif
@@ -567,6 +568,8 @@ enum {
 #define EXT4_GET_BLOCKS_NO_LOCK                        0x0100
        /* Do not put hole in extent cache */
 #define EXT4_GET_BLOCKS_NO_PUT_HOLE            0x0200
+       /* Convert written extents to unwritten */
+#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN      0x0400
 
 /*
  * The bit position of these flags must not overlap with any of the
@@ -998,6 +1001,8 @@ struct ext4_inode_info {
 #define EXT4_MOUNT2_STD_GROUP_SIZE     0x00000002 /* We have standard group
                                                      size of blocksize * 8
                                                      blocks */
+#define EXT4_MOUNT2_HURD_COMPAT                0x00000004 /* Support HURD-castrated
+                                                     file systems */
 
 #define clear_opt(sb, opt)             EXT4_SB(sb)->s_mount_opt &= \
                                                ~EXT4_MOUNT_##opt
@@ -1326,6 +1331,7 @@ struct ext4_sb_info {
        struct list_head s_es_lru;
        unsigned long s_es_last_sorted;
        struct percpu_counter s_extent_cache_cnt;
+       struct mb_cache *s_mb_cache;
        spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp;
 
        /* Ratelimit ext4 messages. */
@@ -2133,8 +2139,6 @@ extern int ext4_writepage_trans_blocks(struct inode *);
 extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
 extern int ext4_block_truncate_page(handle_t *handle,
                struct address_space *mapping, loff_t from);
-extern int ext4_block_zero_page_range(handle_t *handle,
-               struct address_space *mapping, loff_t from, loff_t length);
 extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
                             loff_t lstart, loff_t lend);
 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
@@ -2757,6 +2761,7 @@ extern int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk);
 extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        __u64 start, __u64 len);
 extern int ext4_ext_precache(struct inode *inode);
+extern int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len);
 
 /* move_extent.c */
 extern void ext4_double_down_write_data_sem(struct inode *first,
@@ -2766,6 +2771,8 @@ extern void ext4_double_up_write_data_sem(struct inode *orig_inode,
 extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
                             __u64 start_orig, __u64 start_donor,
                             __u64 len, __u64 *moved_len);
+extern int mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
+                           struct ext4_extent **extent);
 
 /* page-io.c */
 extern int __init ext4_init_pageio(void);
index 3fe29de832c825e390b8d59d818b5ec37a8eb61f..c3fb607413ed4345ec1371611bd80ded541a3c02 100644 (file)
@@ -259,6 +259,16 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
                if (WARN_ON_ONCE(err)) {
                        ext4_journal_abort_handle(where, line, __func__, bh,
                                                  handle, err);
+                       if (inode == NULL) {
+                               pr_err("EXT4: jbd2_journal_dirty_metadata "
+                                      "failed: handle type %u started at "
+                                      "line %u, credits %u/%u, errcode %d",
+                                      handle->h_type,
+                                      handle->h_line_no,
+                                      handle->h_requested_credits,
+                                      handle->h_buffer_credits, err);
+                               return err;
+                       }
                        ext4_error_inode(inode, where, line,
                                         bh->b_blocknr,
                                         "journal_dirty_metadata failed: "
index 74bc2d549c58bd57d60ebcb0a143a3fdf4e95997..82df3ce9874ab7f3a65abc10e2bd2238b1ae2af3 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/quotaops.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include <linux/falloc.h>
 #include <asm/uaccess.h>
 #include <linux/fiemap.h>
 #include "ext4_jbd2.h"
@@ -1691,7 +1690,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
         * the extent that was written properly split out and conversion to
         * initialized is trivial.
         */
-       if (ext4_ext_is_uninitialized(ex1) || ext4_ext_is_uninitialized(ex2))
+       if (ext4_ext_is_uninitialized(ex1) != ext4_ext_is_uninitialized(ex2))
                return 0;
 
        ext1_ee_len = ext4_ext_get_actual_len(ex1);
@@ -1708,6 +1707,11 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
         */
        if (ext1_ee_len + ext2_ee_len > EXT_INIT_MAX_LEN)
                return 0;
+       if (ext4_ext_is_uninitialized(ex1) &&
+           (ext4_test_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN) ||
+            atomic_read(&EXT4_I(inode)->i_unwritten) ||
+            (ext1_ee_len + ext2_ee_len > EXT_UNINIT_MAX_LEN)))
+               return 0;
 #ifdef AGGRESSIVE_TEST
        if (ext1_ee_len >= 4)
                return 0;
@@ -1731,7 +1735,7 @@ static int ext4_ext_try_to_merge_right(struct inode *inode,
 {
        struct ext4_extent_header *eh;
        unsigned int depth, len;
-       int merge_done = 0;
+       int merge_done = 0, uninit;
 
        depth = ext_depth(inode);
        BUG_ON(path[depth].p_hdr == NULL);
@@ -1741,8 +1745,11 @@ static int ext4_ext_try_to_merge_right(struct inode *inode,
                if (!ext4_can_extents_be_merged(inode, ex, ex + 1))
                        break;
                /* merge with next extent! */
+               uninit = ext4_ext_is_uninitialized(ex);
                ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)
                                + ext4_ext_get_actual_len(ex + 1));
+               if (uninit)
+                       ext4_ext_mark_uninitialized(ex);
 
                if (ex + 1 < EXT_LAST_EXTENT(eh)) {
                        len = (EXT_LAST_EXTENT(eh) - ex - 1)
@@ -1896,7 +1903,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
        struct ext4_ext_path *npath = NULL;
        int depth, len, err;
        ext4_lblk_t next;
-       int mb_flags = 0;
+       int mb_flags = 0, uninit;
 
        if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
                EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
@@ -1946,9 +1953,11 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
                                                  path + depth);
                        if (err)
                                return err;
-
+                       uninit = ext4_ext_is_uninitialized(ex);
                        ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)
                                        + ext4_ext_get_actual_len(newext));
+                       if (uninit)
+                               ext4_ext_mark_uninitialized(ex);
                        eh = path[depth].p_hdr;
                        nearex = ex;
                        goto merge;
@@ -1971,10 +1980,13 @@ prepend:
                        if (err)
                                return err;
 
+                       uninit = ext4_ext_is_uninitialized(ex);
                        ex->ee_block = newext->ee_block;
                        ext4_ext_store_pblock(ex, ext4_ext_pblock(newext));
                        ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)
                                        + ext4_ext_get_actual_len(newext));
+                       if (uninit)
+                               ext4_ext_mark_uninitialized(ex);
                        eh = path[depth].p_hdr;
                        nearex = ex;
                        goto merge;
@@ -2585,6 +2597,27 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
        ex_ee_block = le32_to_cpu(ex->ee_block);
        ex_ee_len = ext4_ext_get_actual_len(ex);
 
+       /*
+        * If we're starting with an extent other than the last one in the
+        * node, we need to see if it shares a cluster with the extent to
+        * the right (towards the end of the file). If its leftmost cluster
+        * is this extent's rightmost cluster and it is not cluster aligned,
+        * we'll mark it as a partial that is not to be deallocated.
+        */
+
+       if (ex != EXT_LAST_EXTENT(eh)) {
+               ext4_fsblk_t current_pblk, right_pblk;
+               long long current_cluster, right_cluster;
+
+               current_pblk = ext4_ext_pblock(ex) + ex_ee_len - 1;
+               current_cluster = (long long)EXT4_B2C(sbi, current_pblk);
+               right_pblk = ext4_ext_pblock(ex + 1);
+               right_cluster = (long long)EXT4_B2C(sbi, right_pblk);
+               if (current_cluster == right_cluster &&
+                       EXT4_PBLK_COFF(sbi, right_pblk))
+                       *partial_cluster = -right_cluster;
+       }
+
        trace_ext4_ext_rm_leaf(inode, start, ex, *partial_cluster);
 
        while (ex >= EXT_FIRST_EXTENT(eh) &&
@@ -2710,10 +2743,15 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
                err = ext4_ext_correct_indexes(handle, inode, path);
 
        /*
-        * Free the partial cluster only if the current extent does not
-        * reference it. Otherwise we might free used cluster.
+        * If there's a partial cluster and at least one extent remains in
+        * the leaf, free the partial cluster if it isn't shared with the
+        * current extent.  If there's a partial cluster and no extents
+        * remain in the leaf, it can't be freed here.  It can only be
+        * freed when it's possible to determine if it's not shared with
+        * any other extent - when the next leaf is processed or when space
+        * removal is complete.
         */
-       if (*partial_cluster > 0 &&
+       if (*partial_cluster > 0 && eh->eh_entries &&
            (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) !=
             *partial_cluster)) {
                int flags = get_default_free_blocks_flags(inode);
@@ -3569,6 +3607,8 @@ out:
  *   b> Splits in two extents: Write is happening at either end of the extent
  *   c> Splits in three extents: Somone is writing in middle of the extent
  *
+ * This works the same way in the case of initialized -> unwritten conversion.
+ *
  * One of more index blocks maybe needed if the extent tree grow after
  * the uninitialized extent split. To prevent ENOSPC occur at the IO
  * complete, we need to split the uninitialized extent before DIO submit
@@ -3579,7 +3619,7 @@ out:
  *
  * Returns the size of uninitialized extent to be written on success.
  */
-static int ext4_split_unwritten_extents(handle_t *handle,
+static int ext4_split_convert_extents(handle_t *handle,
                                        struct inode *inode,
                                        struct ext4_map_blocks *map,
                                        struct ext4_ext_path *path,
@@ -3591,9 +3631,9 @@ static int ext4_split_unwritten_extents(handle_t *handle,
        unsigned int ee_len;
        int split_flag = 0, depth;
 
-       ext_debug("ext4_split_unwritten_extents: inode %lu, logical"
-               "block %llu, max_blocks %u\n", inode->i_ino,
-               (unsigned long long)map->m_lblk, map->m_len);
+       ext_debug("%s: inode %lu, logical block %llu, max_blocks %u\n",
+                 __func__, inode->i_ino,
+                 (unsigned long long)map->m_lblk, map->m_len);
 
        eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
                inode->i_sb->s_blocksize_bits;
@@ -3608,14 +3648,73 @@ static int ext4_split_unwritten_extents(handle_t *handle,
        ee_block = le32_to_cpu(ex->ee_block);
        ee_len = ext4_ext_get_actual_len(ex);
 
-       split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
-       split_flag |= EXT4_EXT_MARK_UNINIT2;
-       if (flags & EXT4_GET_BLOCKS_CONVERT)
-               split_flag |= EXT4_EXT_DATA_VALID2;
+       /* Convert to unwritten */
+       if (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN) {
+               split_flag |= EXT4_EXT_DATA_VALID1;
+       /* Convert to initialized */
+       } else if (flags & EXT4_GET_BLOCKS_CONVERT) {
+               split_flag |= ee_block + ee_len <= eof_block ?
+                             EXT4_EXT_MAY_ZEROOUT : 0;
+               split_flag |= (EXT4_EXT_MARK_UNINIT2 | EXT4_EXT_DATA_VALID2);
+       }
        flags |= EXT4_GET_BLOCKS_PRE_IO;
        return ext4_split_extent(handle, inode, path, map, split_flag, flags);
 }
 
+static int ext4_convert_initialized_extents(handle_t *handle,
+                                           struct inode *inode,
+                                           struct ext4_map_blocks *map,
+                                           struct ext4_ext_path *path)
+{
+       struct ext4_extent *ex;
+       ext4_lblk_t ee_block;
+       unsigned int ee_len;
+       int depth;
+       int err = 0;
+
+       depth = ext_depth(inode);
+       ex = path[depth].p_ext;
+       ee_block = le32_to_cpu(ex->ee_block);
+       ee_len = ext4_ext_get_actual_len(ex);
+
+       ext_debug("%s: inode %lu, logical"
+               "block %llu, max_blocks %u\n", __func__, inode->i_ino,
+                 (unsigned long long)ee_block, ee_len);
+
+       if (ee_block != map->m_lblk || ee_len > map->m_len) {
+               err = ext4_split_convert_extents(handle, inode, map, path,
+                               EXT4_GET_BLOCKS_CONVERT_UNWRITTEN);
+               if (err < 0)
+                       goto out;
+               ext4_ext_drop_refs(path);
+               path = ext4_ext_find_extent(inode, map->m_lblk, path, 0);
+               if (IS_ERR(path)) {
+                       err = PTR_ERR(path);
+                       goto out;
+               }
+               depth = ext_depth(inode);
+               ex = path[depth].p_ext;
+       }
+
+       err = ext4_ext_get_access(handle, inode, path + depth);
+       if (err)
+               goto out;
+       /* first mark the extent as uninitialized */
+       ext4_ext_mark_uninitialized(ex);
+
+       /* note: ext4_ext_correct_indexes() isn't needed here because
+        * borders are not changed
+        */
+       ext4_ext_try_to_merge(handle, inode, path, ex);
+
+       /* Mark modified extent as dirty */
+       err = ext4_ext_dirty(handle, inode, path + path->p_depth);
+out:
+       ext4_ext_show_leaf(inode, path);
+       return err;
+}
+
+
 static int ext4_convert_unwritten_extents_endio(handle_t *handle,
                                                struct inode *inode,
                                                struct ext4_map_blocks *map,
@@ -3649,8 +3748,8 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
                             inode->i_ino, (unsigned long long)ee_block, ee_len,
                             (unsigned long long)map->m_lblk, map->m_len);
 #endif
-               err = ext4_split_unwritten_extents(handle, inode, map, path,
-                                                  EXT4_GET_BLOCKS_CONVERT);
+               err = ext4_split_convert_extents(handle, inode, map, path,
+                                                EXT4_GET_BLOCKS_CONVERT);
                if (err < 0)
                        goto out;
                ext4_ext_drop_refs(path);
@@ -3850,6 +3949,38 @@ get_reserved_cluster_alloc(struct inode *inode, ext4_lblk_t lblk_start,
        return allocated_clusters;
 }
 
+static int
+ext4_ext_convert_initialized_extent(handle_t *handle, struct inode *inode,
+                       struct ext4_map_blocks *map,
+                       struct ext4_ext_path *path, int flags,
+                       unsigned int allocated, ext4_fsblk_t newblock)
+{
+       int ret = 0;
+       int err = 0;
+
+       /*
+        * Make sure that the extent is no bigger than we support with
+        * uninitialized extent
+        */
+       if (map->m_len > EXT_UNINIT_MAX_LEN)
+               map->m_len = EXT_UNINIT_MAX_LEN / 2;
+
+       ret = ext4_convert_initialized_extents(handle, inode, map,
+                                               path);
+       if (ret >= 0) {
+               ext4_update_inode_fsync_trans(handle, inode, 1);
+               err = check_eofblocks_fl(handle, inode, map->m_lblk,
+                                        path, map->m_len);
+       } else
+               err = ret;
+       map->m_flags |= EXT4_MAP_UNWRITTEN;
+       if (allocated > map->m_len)
+               allocated = map->m_len;
+       map->m_len = allocated;
+
+       return err ? err : allocated;
+}
+
 static int
 ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
                        struct ext4_map_blocks *map,
@@ -3877,8 +4008,8 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
 
        /* get_block() before submit the IO, split the extent */
        if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
-               ret = ext4_split_unwritten_extents(handle, inode, map,
-                                                  path, flags);
+               ret = ext4_split_convert_extents(handle, inode, map,
+                                        path, flags | EXT4_GET_BLOCKS_CONVERT);
                if (ret <= 0)
                        goto out;
                /*
@@ -3993,10 +4124,6 @@ out1:
        map->m_pblk = newblock;
        map->m_len = allocated;
 out2:
-       if (path) {
-               ext4_ext_drop_refs(path);
-               kfree(path);
-       }
        return err ? err : allocated;
 }
 
@@ -4128,7 +4255,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
        struct ext4_extent newex, *ex, *ex2;
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        ext4_fsblk_t newblock = 0;
-       int free_on_err = 0, err = 0, depth;
+       int free_on_err = 0, err = 0, depth, ret;
        unsigned int allocated = 0, offset = 0;
        unsigned int allocated_clusters = 0;
        struct ext4_allocation_request ar;
@@ -4170,6 +4297,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
                ext4_fsblk_t ee_start = ext4_ext_pblock(ex);
                unsigned short ee_len;
 
+
                /*
                 * Uninitialized extents are treated as holes, except that
                 * we split out initialized portions during a write.
@@ -4186,13 +4314,27 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
                        ext_debug("%u fit into %u:%d -> %llu\n", map->m_lblk,
                                  ee_block, ee_len, newblock);
 
-                       if (!ext4_ext_is_uninitialized(ex))
+                       /*
+                        * If the extent is initialized check whether the
+                        * caller wants to convert it to unwritten.
+                        */
+                       if ((!ext4_ext_is_uninitialized(ex)) &&
+                           (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)) {
+                               allocated = ext4_ext_convert_initialized_extent(
+                                               handle, inode, map, path, flags,
+                                               allocated, newblock);
+                               goto out2;
+                       } else if (!ext4_ext_is_uninitialized(ex))
                                goto out;
 
-                       allocated = ext4_ext_handle_uninitialized_extents(
+                       ret = ext4_ext_handle_uninitialized_extents(
                                handle, inode, map, path, flags,
                                allocated, newblock);
-                       goto out3;
+                       if (ret < 0)
+                               err = ret;
+                       else
+                               allocated = ret;
+                       goto out2;
                }
        }
 
@@ -4473,7 +4615,6 @@ out2:
                kfree(path);
        }
 
-out3:
        trace_ext4_ext_map_blocks_exit(inode, flags, map,
                                       err ? err : allocated);
        ext4_es_lru_add(inode);
@@ -4514,34 +4655,200 @@ retry:
        ext4_std_error(inode->i_sb, err);
 }
 
-static void ext4_falloc_update_inode(struct inode *inode,
-                               int mode, loff_t new_size, int update_ctime)
+static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
+                                 ext4_lblk_t len, int flags, int mode)
 {
-       struct timespec now;
+       struct inode *inode = file_inode(file);
+       handle_t *handle;
+       int ret = 0;
+       int ret2 = 0;
+       int retries = 0;
+       struct ext4_map_blocks map;
+       unsigned int credits;
 
-       if (update_ctime) {
-               now = current_fs_time(inode->i_sb);
-               if (!timespec_equal(&inode->i_ctime, &now))
-                       inode->i_ctime = now;
+       map.m_lblk = offset;
+       /*
+        * Don't normalize the request if it can fit in one extent so
+        * that it doesn't get unnecessarily split into multiple
+        * extents.
+        */
+       if (len <= EXT_UNINIT_MAX_LEN)
+               flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
+
+       /*
+        * credits to insert 1 extent into extent tree
+        */
+       credits = ext4_chunk_trans_blocks(inode, len);
+
+retry:
+       while (ret >= 0 && ret < len) {
+               map.m_lblk = map.m_lblk + ret;
+               map.m_len = len = len - ret;
+               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
+                                           credits);
+               if (IS_ERR(handle)) {
+                       ret = PTR_ERR(handle);
+                       break;
+               }
+               ret = ext4_map_blocks(handle, inode, &map, flags);
+               if (ret <= 0) {
+                       ext4_debug("inode #%lu: block %u: len %u: "
+                                  "ext4_ext_map_blocks returned %d",
+                                  inode->i_ino, map.m_lblk,
+                                  map.m_len, ret);
+                       ext4_mark_inode_dirty(handle, inode);
+                       ret2 = ext4_journal_stop(handle);
+                       break;
+               }
+               ret2 = ext4_journal_stop(handle);
+               if (ret2)
+                       break;
+       }
+       if (ret == -ENOSPC &&
+                       ext4_should_retry_alloc(inode->i_sb, &retries)) {
+               ret = 0;
+               goto retry;
        }
+
+       return ret > 0 ? ret2 : ret;
+}
+
+static long ext4_zero_range(struct file *file, loff_t offset,
+                           loff_t len, int mode)
+{
+       struct inode *inode = file_inode(file);
+       handle_t *handle = NULL;
+       unsigned int max_blocks;
+       loff_t new_size = 0;
+       int ret = 0;
+       int flags;
+       int partial;
+       loff_t start, end;
+       ext4_lblk_t lblk;
+       struct address_space *mapping = inode->i_mapping;
+       unsigned int blkbits = inode->i_blkbits;
+
+       trace_ext4_zero_range(inode, offset, len, mode);
+
+       /*
+        * Write out all dirty pages to avoid race conditions
+        * Then release them.
+        */
+       if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
+               ret = filemap_write_and_wait_range(mapping, offset,
+                                                  offset + len - 1);
+               if (ret)
+                       return ret;
+       }
+
        /*
-        * Update only when preallocation was requested beyond
-        * the file size.
+        * Round up offset. This is not fallocate, we neet to zero out
+        * blocks, so convert interior block aligned part of the range to
+        * unwritten and possibly manually zero out unaligned parts of the
+        * range.
         */
-       if (!(mode & FALLOC_FL_KEEP_SIZE)) {
+       start = round_up(offset, 1 << blkbits);
+       end = round_down((offset + len), 1 << blkbits);
+
+       if (start < offset || end > offset + len)
+               return -EINVAL;
+       partial = (offset + len) & ((1 << blkbits) - 1);
+
+       lblk = start >> blkbits;
+       max_blocks = (end >> blkbits);
+       if (max_blocks < lblk)
+               max_blocks = 0;
+       else
+               max_blocks -= lblk;
+
+       flags = EXT4_GET_BLOCKS_CREATE_UNINIT_EXT |
+               EXT4_GET_BLOCKS_CONVERT_UNWRITTEN;
+       if (mode & FALLOC_FL_KEEP_SIZE)
+               flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
+
+       mutex_lock(&inode->i_mutex);
+
+       /*
+        * Indirect files do not support unwritten extnets
+        */
+       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
+               ret = -EOPNOTSUPP;
+               goto out_mutex;
+       }
+
+       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+            offset + len > i_size_read(inode)) {
+               new_size = offset + len;
+               ret = inode_newsize_ok(inode, new_size);
+               if (ret)
+                       goto out_mutex;
+               /*
+                * If we have a partial block after EOF we have to allocate
+                * the entire block.
+                */
+               if (partial)
+                       max_blocks += 1;
+       }
+
+       if (max_blocks > 0) {
+
+               /* Now release the pages and zero block aligned part of pages*/
+               truncate_pagecache_range(inode, start, end - 1);
+
+               /* Wait all existing dio workers, newcomers will block on i_mutex */
+               ext4_inode_block_unlocked_dio(inode);
+               inode_dio_wait(inode);
+
+               /*
+                * Remove entire range from the extent status tree.
+                */
+               ret = ext4_es_remove_extent(inode, lblk, max_blocks);
+               if (ret)
+                       goto out_dio;
+
+               ret = ext4_alloc_file_blocks(file, lblk, max_blocks, flags,
+                                            mode);
+               if (ret)
+                       goto out_dio;
+       }
+
+       handle = ext4_journal_start(inode, EXT4_HT_MISC, 4);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               ext4_std_error(inode->i_sb, ret);
+               goto out_dio;
+       }
+
+       inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+
+       if (new_size) {
                if (new_size > i_size_read(inode))
                        i_size_write(inode, new_size);
                if (new_size > EXT4_I(inode)->i_disksize)
                        ext4_update_i_disksize(inode, new_size);
        } else {
                /*
-                * Mark that we allocate beyond EOF so the subsequent truncate
-                * can proceed even if the new size is the same as i_size.
-                */
-               if (new_size > i_size_read(inode))
+               * Mark that we allocate beyond EOF so the subsequent truncate
+               * can proceed even if the new size is the same as i_size.
+               */
+               if ((offset + len) > i_size_read(inode))
                        ext4_set_inode_flag(inode, EXT4_INODE_EOFBLOCKS);
        }
 
+       ext4_mark_inode_dirty(handle, inode);
+
+       /* Zero out partial block at the edges of the range */
+       ret = ext4_zero_partial_blocks(handle, inode, offset, len);
+
+       if (file->f_flags & O_SYNC)
+               ext4_handle_sync(handle);
+
+       ext4_journal_stop(handle);
+out_dio:
+       ext4_inode_resume_unlocked_dio(inode);
+out_mutex:
+       mutex_unlock(&inode->i_mutex);
+       return ret;
 }
 
 /*
@@ -4555,22 +4862,25 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
 {
        struct inode *inode = file_inode(file);
        handle_t *handle;
-       loff_t new_size;
+       loff_t new_size = 0;
        unsigned int max_blocks;
        int ret = 0;
-       int ret2 = 0;
-       int retries = 0;
        int flags;
-       struct ext4_map_blocks map;
-       unsigned int credits, blkbits = inode->i_blkbits;
+       ext4_lblk_t lblk;
+       struct timespec tv;
+       unsigned int blkbits = inode->i_blkbits;
 
        /* Return error if mode is not supported */
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+                    FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE))
                return -EOPNOTSUPP;
 
        if (mode & FALLOC_FL_PUNCH_HOLE)
                return ext4_punch_hole(inode, offset, len);
 
+       if (mode & FALLOC_FL_COLLAPSE_RANGE)
+               return ext4_collapse_range(inode, offset, len);
+
        ret = ext4_convert_inline_data(inode);
        if (ret)
                return ret;
@@ -4582,83 +4892,66 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
                return -EOPNOTSUPP;
 
+       if (mode & FALLOC_FL_ZERO_RANGE)
+               return ext4_zero_range(file, offset, len, mode);
+
        trace_ext4_fallocate_enter(inode, offset, len, mode);
-       map.m_lblk = offset >> blkbits;
+       lblk = offset >> blkbits;
        /*
         * We can't just convert len to max_blocks because
         * If blocksize = 4096 offset = 3072 and len = 2048
         */
        max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
-               - map.m_lblk;
-       /*
-        * credits to insert 1 extent into extent tree
-        */
-       credits = ext4_chunk_trans_blocks(inode, max_blocks);
-       mutex_lock(&inode->i_mutex);
-       ret = inode_newsize_ok(inode, (len + offset));
-       if (ret) {
-               mutex_unlock(&inode->i_mutex);
-               trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
-               return ret;
-       }
+               - lblk;
+
        flags = EXT4_GET_BLOCKS_CREATE_UNINIT_EXT;
        if (mode & FALLOC_FL_KEEP_SIZE)
                flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
-       /*
-        * Don't normalize the request if it can fit in one extent so
-        * that it doesn't get unnecessarily split into multiple
-        * extents.
-        */
-       if (len <= EXT_UNINIT_MAX_LEN << blkbits)
-               flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
 
-retry:
-       while (ret >= 0 && ret < max_blocks) {
-               map.m_lblk = map.m_lblk + ret;
-               map.m_len = max_blocks = max_blocks - ret;
-               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
-                                           credits);
-               if (IS_ERR(handle)) {
-                       ret = PTR_ERR(handle);
-                       break;
-               }
-               ret = ext4_map_blocks(handle, inode, &map, flags);
-               if (ret <= 0) {
-#ifdef EXT4FS_DEBUG
-                       ext4_warning(inode->i_sb,
-                                    "inode #%lu: block %u: len %u: "
-                                    "ext4_ext_map_blocks returned %d",
-                                    inode->i_ino, map.m_lblk,
-                                    map.m_len, ret);
-#endif
-                       ext4_mark_inode_dirty(handle, inode);
-                       ret2 = ext4_journal_stop(handle);
-                       break;
-               }
-               if ((map.m_lblk + ret) >= (EXT4_BLOCK_ALIGN(offset + len,
-                                               blkbits) >> blkbits))
-                       new_size = offset + len;
-               else
-                       new_size = ((loff_t) map.m_lblk + ret) << blkbits;
+       mutex_lock(&inode->i_mutex);
 
-               ext4_falloc_update_inode(inode, mode, new_size,
-                                        (map.m_flags & EXT4_MAP_NEW));
-               ext4_mark_inode_dirty(handle, inode);
-               if ((file->f_flags & O_SYNC) && ret >= max_blocks)
-                       ext4_handle_sync(handle);
-               ret2 = ext4_journal_stop(handle);
-               if (ret2)
-                       break;
+       if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+            offset + len > i_size_read(inode)) {
+               new_size = offset + len;
+               ret = inode_newsize_ok(inode, new_size);
+               if (ret)
+                       goto out;
        }
-       if (ret == -ENOSPC &&
-                       ext4_should_retry_alloc(inode->i_sb, &retries)) {
-               ret = 0;
-               goto retry;
+
+       ret = ext4_alloc_file_blocks(file, lblk, max_blocks, flags, mode);
+       if (ret)
+               goto out;
+
+       handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+       if (IS_ERR(handle))
+               goto out;
+
+       tv = inode->i_ctime = ext4_current_time(inode);
+
+       if (new_size) {
+               if (new_size > i_size_read(inode)) {
+                       i_size_write(inode, new_size);
+                       inode->i_mtime = tv;
+               }
+               if (new_size > EXT4_I(inode)->i_disksize)
+                       ext4_update_i_disksize(inode, new_size);
+       } else {
+               /*
+               * Mark that we allocate beyond EOF so the subsequent truncate
+               * can proceed even if the new size is the same as i_size.
+               */
+               if ((offset + len) > i_size_read(inode))
+                       ext4_set_inode_flag(inode, EXT4_INODE_EOFBLOCKS);
        }
+       ext4_mark_inode_dirty(handle, inode);
+       if (file->f_flags & O_SYNC)
+               ext4_handle_sync(handle);
+
+       ext4_journal_stop(handle);
+out:
        mutex_unlock(&inode->i_mutex);
-       trace_ext4_fallocate_exit(inode, offset, max_blocks,
-                               ret > 0 ? ret2 : ret);
-       return ret > 0 ? ret2 : ret;
+       trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
+       return ret;
 }
 
 /*
@@ -4869,3 +5162,304 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        ext4_es_lru_add(inode);
        return error;
 }
+
+/*
+ * ext4_access_path:
+ * Function to access the path buffer for marking it dirty.
+ * It also checks if there are sufficient credits left in the journal handle
+ * to update path.
+ */
+static int
+ext4_access_path(handle_t *handle, struct inode *inode,
+               struct ext4_ext_path *path)
+{
+       int credits, err;
+
+       if (!ext4_handle_valid(handle))
+               return 0;
+
+       /*
+        * Check if need to extend journal credits
+        * 3 for leaf, sb, and inode plus 2 (bmap and group
+        * descriptor) for each block group; assume two block
+        * groups
+        */
+       if (handle->h_buffer_credits < 7) {
+               credits = ext4_writepage_trans_blocks(inode);
+               err = ext4_ext_truncate_extend_restart(handle, inode, credits);
+               /* EAGAIN is success */
+               if (err && err != -EAGAIN)
+                       return err;
+       }
+
+       err = ext4_ext_get_access(handle, inode, path);
+       return err;
+}
+
+/*
+ * ext4_ext_shift_path_extents:
+ * Shift the extents of a path structure lying between path[depth].p_ext
+ * and EXT_LAST_EXTENT(path[depth].p_hdr) downwards, by subtracting shift
+ * from starting block for each extent.
+ */
+static int
+ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift,
+                           struct inode *inode, handle_t *handle,
+                           ext4_lblk_t *start)
+{
+       int depth, err = 0;
+       struct ext4_extent *ex_start, *ex_last;
+       bool update = 0;
+       depth = path->p_depth;
+
+       while (depth >= 0) {
+               if (depth == path->p_depth) {
+                       ex_start = path[depth].p_ext;
+                       if (!ex_start)
+                               return -EIO;
+
+                       ex_last = EXT_LAST_EXTENT(path[depth].p_hdr);
+                       if (!ex_last)
+                               return -EIO;
+
+                       err = ext4_access_path(handle, inode, path + depth);
+                       if (err)
+                               goto out;
+
+                       if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr))
+                               update = 1;
+
+                       *start = ex_last->ee_block +
+                               ext4_ext_get_actual_len(ex_last);
+
+                       while (ex_start <= ex_last) {
+                               ex_start->ee_block -= shift;
+                               if (ex_start >
+                                       EXT_FIRST_EXTENT(path[depth].p_hdr)) {
+                                       if (ext4_ext_try_to_merge_right(inode,
+                                               path, ex_start - 1))
+                                               ex_last--;
+                               }
+                               ex_start++;
+                       }
+                       err = ext4_ext_dirty(handle, inode, path + depth);
+                       if (err)
+                               goto out;
+
+                       if (--depth < 0 || !update)
+                               break;
+               }
+
+               /* Update index too */
+               err = ext4_access_path(handle, inode, path + depth);
+               if (err)
+                       goto out;
+
+               path[depth].p_idx->ei_block -= shift;
+               err = ext4_ext_dirty(handle, inode, path + depth);
+               if (err)
+                       goto out;
+
+               /* we are done if current index is not a starting index */
+               if (path[depth].p_idx != EXT_FIRST_INDEX(path[depth].p_hdr))
+                       break;
+
+               depth--;
+       }
+
+out:
+       return err;
+}
+
+/*
+ * ext4_ext_shift_extents:
+ * All the extents which lies in the range from start to the last allocated
+ * block for the file are shifted downwards by shift blocks.
+ * On success, 0 is returned, error otherwise.
+ */
+static int
+ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+                      ext4_lblk_t start, ext4_lblk_t shift)
+{
+       struct ext4_ext_path *path;
+       int ret = 0, depth;
+       struct ext4_extent *extent;
+       ext4_lblk_t stop_block, current_block;
+       ext4_lblk_t ex_start, ex_end;
+
+       /* Let path point to the last extent */
+       path = ext4_ext_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, 0);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+
+       depth = path->p_depth;
+       extent = path[depth].p_ext;
+       if (!extent) {
+               ext4_ext_drop_refs(path);
+               kfree(path);
+               return ret;
+       }
+
+       stop_block = extent->ee_block + ext4_ext_get_actual_len(extent);
+       ext4_ext_drop_refs(path);
+       kfree(path);
+
+       /* Nothing to shift, if hole is at the end of file */
+       if (start >= stop_block)
+               return ret;
+
+       /*
+        * Don't start shifting extents until we make sure the hole is big
+        * enough to accomodate the shift.
+        */
+       path = ext4_ext_find_extent(inode, start - 1, NULL, 0);
+       depth = path->p_depth;
+       extent =  path[depth].p_ext;
+       ex_start = extent->ee_block;
+       ex_end = extent->ee_block + ext4_ext_get_actual_len(extent);
+       ext4_ext_drop_refs(path);
+       kfree(path);
+
+       if ((start == ex_start && shift > ex_start) ||
+           (shift > start - ex_end))
+               return -EINVAL;
+
+       /* Its safe to start updating extents */
+       while (start < stop_block) {
+               path = ext4_ext_find_extent(inode, start, NULL, 0);
+               if (IS_ERR(path))
+                       return PTR_ERR(path);
+               depth = path->p_depth;
+               extent = path[depth].p_ext;
+               current_block = extent->ee_block;
+               if (start > current_block) {
+                       /* Hole, move to the next extent */
+                       ret = mext_next_extent(inode, path, &extent);
+                       if (ret != 0) {
+                               ext4_ext_drop_refs(path);
+                               kfree(path);
+                               if (ret == 1)
+                                       ret = 0;
+                               break;
+                       }
+               }
+               ret = ext4_ext_shift_path_extents(path, shift, inode,
+                               handle, &start);
+               ext4_ext_drop_refs(path);
+               kfree(path);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
+/*
+ * ext4_collapse_range:
+ * This implements the fallocate's collapse range functionality for ext4
+ * Returns: 0 and non-zero on error.
+ */
+int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
+{
+       struct super_block *sb = inode->i_sb;
+       ext4_lblk_t punch_start, punch_stop;
+       handle_t *handle;
+       unsigned int credits;
+       loff_t new_size;
+       int ret;
+
+       BUG_ON(offset + len > i_size_read(inode));
+
+       /* Collapse range works only on fs block size aligned offsets. */
+       if (offset & (EXT4_BLOCK_SIZE(sb) - 1) ||
+           len & (EXT4_BLOCK_SIZE(sb) - 1))
+               return -EINVAL;
+
+       if (!S_ISREG(inode->i_mode))
+               return -EOPNOTSUPP;
+
+       trace_ext4_collapse_range(inode, offset, len);
+
+       punch_start = offset >> EXT4_BLOCK_SIZE_BITS(sb);
+       punch_stop = (offset + len) >> EXT4_BLOCK_SIZE_BITS(sb);
+
+       /* Write out all dirty pages */
+       ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1);
+       if (ret)
+               return ret;
+
+       /* Take mutex lock */
+       mutex_lock(&inode->i_mutex);
+
+       /* It's not possible punch hole on append only file */
+       if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
+               ret = -EPERM;
+               goto out_mutex;
+       }
+
+       if (IS_SWAPFILE(inode)) {
+               ret = -ETXTBSY;
+               goto out_mutex;
+       }
+
+       /* Currently just for extent based files */
+       if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
+               ret = -EOPNOTSUPP;
+               goto out_mutex;
+       }
+
+       truncate_pagecache_range(inode, offset, -1);
+
+       /* Wait for existing dio to complete */
+       ext4_inode_block_unlocked_dio(inode);
+       inode_dio_wait(inode);
+
+       credits = ext4_writepage_trans_blocks(inode);
+       handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out_dio;
+       }
+
+       down_write(&EXT4_I(inode)->i_data_sem);
+       ext4_discard_preallocations(inode);
+
+       ret = ext4_es_remove_extent(inode, punch_start,
+                                   EXT_MAX_BLOCKS - punch_start - 1);
+       if (ret) {
+               up_write(&EXT4_I(inode)->i_data_sem);
+               goto out_stop;
+       }
+
+       ret = ext4_ext_remove_space(inode, punch_start, punch_stop - 1);
+       if (ret) {
+               up_write(&EXT4_I(inode)->i_data_sem);
+               goto out_stop;
+       }
+
+       ret = ext4_ext_shift_extents(inode, handle, punch_stop,
+                                    punch_stop - punch_start);
+       if (ret) {
+               up_write(&EXT4_I(inode)->i_data_sem);
+               goto out_stop;
+       }
+
+       new_size = i_size_read(inode) - len;
+       truncate_setsize(inode, new_size);
+       EXT4_I(inode)->i_disksize = new_size;
+
+       ext4_discard_preallocations(inode);
+       up_write(&EXT4_I(inode)->i_data_sem);
+       if (IS_SYNC(inode))
+               ext4_handle_sync(handle);
+       inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+       ext4_mark_inode_dirty(handle, inode);
+
+out_stop:
+       ext4_journal_stop(handle);
+out_dio:
+       ext4_inode_resume_unlocked_dio(inode);
+out_mutex:
+       mutex_unlock(&inode->i_mutex);
+       return ret;
+}
index 3981ff7839503df43a56ff282cd570d522bf764e..0a014a7194b28cac95e56f21b59f3776fcf8c9fc 100644 (file)
@@ -184,7 +184,7 @@ static void ext4_es_print_tree(struct inode *inode)
        while (node) {
                struct extent_status *es;
                es = rb_entry(node, struct extent_status, rb_node);
-               printk(KERN_DEBUG " [%u/%u) %llu %llx",
+               printk(KERN_DEBUG " [%u/%u) %llu %x",
                       es->es_lblk, es->es_len,
                       ext4_es_pblock(es), ext4_es_status(es));
                node = rb_next(node);
@@ -445,8 +445,8 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
                                pr_warn("ES insert assertion failed for "
                                        "inode: %lu we can find an extent "
                                        "at block [%d/%d/%llu/%c], but we "
-                                       "want to add an delayed/hole extent "
-                                       "[%d/%d/%llu/%llx]\n",
+                                       "want to add a delayed/hole extent "
+                                       "[%d/%d/%llu/%x]\n",
                                        inode->i_ino, ee_block, ee_len,
                                        ee_start, ee_status ? 'u' : 'w',
                                        es->es_lblk, es->es_len,
@@ -486,8 +486,8 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
                if (!ext4_es_is_delayed(es) && !ext4_es_is_hole(es)) {
                        pr_warn("ES insert assertion failed for inode: %lu "
                                "can't find an extent at block %d but we want "
-                               "to add an written/unwritten extent "
-                               "[%d/%d/%llu/%llx]\n", inode->i_ino,
+                               "to add a written/unwritten extent "
+                               "[%d/%d/%llu/%x]\n", inode->i_ino,
                                es->es_lblk, es->es_lblk, es->es_len,
                                ext4_es_pblock(es), ext4_es_status(es));
                }
@@ -524,7 +524,7 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
                         */
                        pr_warn("ES insert assertion failed for inode: %lu "
                                "We can find blocks but we want to add a "
-                               "delayed/hole extent [%d/%d/%llu/%llx]\n",
+                               "delayed/hole extent [%d/%d/%llu/%x]\n",
                                inode->i_ino, es->es_lblk, es->es_len,
                                ext4_es_pblock(es), ext4_es_status(es));
                        return;
@@ -554,7 +554,7 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
                if (ext4_es_is_written(es)) {
                        pr_warn("ES insert assertion failed for inode: %lu "
                                "We can't find the block but we want to add "
-                               "an written extent [%d/%d/%llu/%llx]\n",
+                               "a written extent [%d/%d/%llu/%x]\n",
                                inode->i_ino, es->es_lblk, es->es_len,
                                ext4_es_pblock(es), ext4_es_status(es));
                        return;
@@ -658,8 +658,7 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
 
        newes.es_lblk = lblk;
        newes.es_len = len;
-       ext4_es_store_pblock(&newes, pblk);
-       ext4_es_store_status(&newes, status);
+       ext4_es_store_pblock_status(&newes, pblk, status);
        trace_ext4_es_insert_extent(inode, &newes);
 
        ext4_es_insert_extent_check(inode, &newes);
@@ -699,8 +698,7 @@ void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk,
 
        newes.es_lblk = lblk;
        newes.es_len = len;
-       ext4_es_store_pblock(&newes, pblk);
-       ext4_es_store_status(&newes, status);
+       ext4_es_store_pblock_status(&newes, pblk, status);
        trace_ext4_es_cache_extent(inode, &newes);
 
        if (!len)
@@ -812,13 +810,13 @@ retry:
 
                        newes.es_lblk = end + 1;
                        newes.es_len = len2;
+                       block = 0x7FDEADBEEF;
                        if (ext4_es_is_written(&orig_es) ||
-                           ext4_es_is_unwritten(&orig_es)) {
+                           ext4_es_is_unwritten(&orig_es))
                                block = ext4_es_pblock(&orig_es) +
                                        orig_es.es_len - len2;
-                               ext4_es_store_pblock(&newes, block);
-                       }
-                       ext4_es_store_status(&newes, ext4_es_status(&orig_es));
+                       ext4_es_store_pblock_status(&newes, block,
+                                                   ext4_es_status(&orig_es));
                        err = __es_insert_extent(inode, &newes);
                        if (err) {
                                es->es_lblk = orig_es.es_lblk;
index 167f4ab8ecc35ed27a9af0d90e1f6ae6a315ef37..f1b62a41992059f3cbebd16ee6caaf25ee156283 100644 (file)
@@ -129,6 +129,15 @@ static inline void ext4_es_store_status(struct extent_status *es,
                       (es->es_pblk & ~ES_MASK));
 }
 
+static inline void ext4_es_store_pblock_status(struct extent_status *es,
+                                              ext4_fsblk_t pb,
+                                              unsigned int status)
+{
+       es->es_pblk = (((ext4_fsblk_t)
+                       (status & EXTENT_STATUS_FLAGS) << ES_SHIFT) |
+                      (pb & ~ES_MASK));
+}
+
 extern void ext4_es_register_shrinker(struct ext4_sb_info *sbi);
 extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi);
 extern void ext4_es_lru_add(struct inode *inode);
index 175c3f933816b72ecb02ebd1fa479cf5278fa142..5b0d2c7d54080dea4080909fe8ec6a74ecf19b56 100644 (file)
@@ -504,6 +504,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 {
        struct extent_status es;
        int retval;
+       int ret = 0;
 #ifdef ES_AGGRESSIVE_TEST
        struct ext4_map_blocks orig_map;
 
@@ -515,6 +516,12 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                  "logical block %lu\n", inode->i_ino, flags, map->m_len,
                  (unsigned long) map->m_lblk);
 
+       /*
+        * ext4_map_blocks returns an int, and m_len is an unsigned int
+        */
+       if (unlikely(map->m_len > INT_MAX))
+               map->m_len = INT_MAX;
+
        /* Lookup extent status tree firstly */
        if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
                ext4_es_lru_add(inode);
@@ -553,7 +560,6 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
                                             EXT4_GET_BLOCKS_KEEP_SIZE);
        }
        if (retval > 0) {
-               int ret;
                unsigned int status;
 
                if (unlikely(retval != map->m_len)) {
@@ -580,7 +586,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 
 found:
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
-               int ret = check_block_validity(inode, map);
+               ret = check_block_validity(inode, map);
                if (ret != 0)
                        return ret;
        }
@@ -597,7 +603,13 @@ found:
         * with buffer head unmapped.
         */
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED)
-               return retval;
+               /*
+                * If we need to convert extent to unwritten
+                * we continue and do the actual work in
+                * ext4_ext_map_blocks()
+                */
+               if (!(flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN))
+                       return retval;
 
        /*
         * Here we clear m_flags because after allocating an new extent,
@@ -653,7 +665,6 @@ found:
                ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED);
 
        if (retval > 0) {
-               int ret;
                unsigned int status;
 
                if (unlikely(retval != map->m_len)) {
@@ -688,7 +699,7 @@ found:
 has_zeroout:
        up_write((&EXT4_I(inode)->i_data_sem));
        if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
-               int ret = check_block_validity(inode, map);
+               ret = check_block_validity(inode, map);
                if (ret != 0)
                        return ret;
        }
@@ -3312,26 +3323,6 @@ void ext4_set_aops(struct inode *inode)
                inode->i_mapping->a_ops = &ext4_aops;
 }
 
-/*
- * ext4_block_truncate_page() zeroes out a mapping from file offset `from'
- * up to the end of the block which corresponds to `from'.
- * This required during truncate. We need to physically zero the tail end
- * of that block so it doesn't yield old data if the file is later grown.
- */
-int ext4_block_truncate_page(handle_t *handle,
-               struct address_space *mapping, loff_t from)
-{
-       unsigned offset = from & (PAGE_CACHE_SIZE-1);
-       unsigned length;
-       unsigned blocksize;
-       struct inode *inode = mapping->host;
-
-       blocksize = inode->i_sb->s_blocksize;
-       length = blocksize - (offset & (blocksize - 1));
-
-       return ext4_block_zero_page_range(handle, mapping, from, length);
-}
-
 /*
  * ext4_block_zero_page_range() zeros out a mapping of length 'length'
  * starting from file offset 'from'.  The range to be zero'd must
@@ -3339,7 +3330,7 @@ int ext4_block_truncate_page(handle_t *handle,
  * the end of the block it will be shortened to end of the block
  * that cooresponds to 'from'
  */
-int ext4_block_zero_page_range(handle_t *handle,
+static int ext4_block_zero_page_range(handle_t *handle,
                struct address_space *mapping, loff_t from, loff_t length)
 {
        ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
@@ -3429,6 +3420,26 @@ unlock:
        return err;
 }
 
+/*
+ * ext4_block_truncate_page() zeroes out a mapping from file offset `from'
+ * up to the end of the block which corresponds to `from'.
+ * This required during truncate. We need to physically zero the tail end
+ * of that block so it doesn't yield old data if the file is later grown.
+ */
+int ext4_block_truncate_page(handle_t *handle,
+               struct address_space *mapping, loff_t from)
+{
+       unsigned offset = from & (PAGE_CACHE_SIZE-1);
+       unsigned length;
+       unsigned blocksize;
+       struct inode *inode = mapping->host;
+
+       blocksize = inode->i_sb->s_blocksize;
+       length = blocksize - (offset & (blocksize - 1));
+
+       return ext4_block_zero_page_range(handle, mapping, from, length);
+}
+
 int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode,
                             loff_t lstart, loff_t length)
 {
@@ -3502,7 +3513,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
        if (!S_ISREG(inode->i_mode))
                return -EOPNOTSUPP;
 
-       trace_ext4_punch_hole(inode, offset, length);
+       trace_ext4_punch_hole(inode, offset, length, 0);
 
        /*
         * Write out all dirty pages to avoid race conditions
@@ -3609,6 +3620,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
        up_write(&EXT4_I(inode)->i_data_sem);
        if (IS_SYNC(inode))
                ext4_handle_sync(handle);
+
+       /* Now release the pages again to reduce race window */
+       if (last_block_offset > first_block_offset)
+               truncate_pagecache_range(inode, first_block_offset,
+                                        last_block_offset);
+
        inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
        ext4_mark_inode_dirty(handle, inode);
 out_stop:
@@ -3682,7 +3699,7 @@ void ext4_truncate(struct inode *inode)
 
        /*
         * There is a possibility that we're either freeing the inode
-        * or it completely new indode. In those cases we might not
+        * or it's a completely new inode. In those cases we might not
         * have i_mutex locked because it's not necessary.
         */
        if (!(inode->i_state & (I_NEW|I_FREEING)))
@@ -3934,8 +3951,8 @@ void ext4_set_inode_flags(struct inode *inode)
                new_fl |= S_NOATIME;
        if (flags & EXT4_DIRSYNC_FL)
                new_fl |= S_DIRSYNC;
-       set_mask_bits(&inode->i_flags,
-                     S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
+       inode_set_flags(inode, new_fl,
+                       S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
 }
 
 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
@@ -4154,11 +4171,13 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
        EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode);
        EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
 
-       inode->i_version = le32_to_cpu(raw_inode->i_disk_version);
-       if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
-               if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
-                       inode->i_version |=
-                       (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
+       if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
+               inode->i_version = le32_to_cpu(raw_inode->i_disk_version);
+               if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
+                       if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
+                               inode->i_version |=
+                   (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
+               }
        }
 
        ret = 0;
@@ -4328,8 +4347,7 @@ static int ext4_do_update_inode(handle_t *handle,
                goto out_brelse;
        raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
        raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF);
-       if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
-           cpu_to_le32(EXT4_OS_HURD))
+       if (likely(!test_opt2(inode->i_sb, HURD_COMPAT)))
                raw_inode->i_file_acl_high =
                        cpu_to_le16(ei->i_file_acl >> 32);
        raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl);
@@ -4374,12 +4392,15 @@ static int ext4_do_update_inode(handle_t *handle,
                        raw_inode->i_block[block] = ei->i_data[block];
        }
 
-       raw_inode->i_disk_version = cpu_to_le32(inode->i_version);
-       if (ei->i_extra_isize) {
-               if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
-                       raw_inode->i_version_hi =
-                       cpu_to_le32(inode->i_version >> 32);
-               raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
+       if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
+               raw_inode->i_disk_version = cpu_to_le32(inode->i_version);
+               if (ei->i_extra_isize) {
+                       if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
+                               raw_inode->i_version_hi =
+                                       cpu_to_le32(inode->i_version >> 32);
+                       raw_inode->i_extra_isize =
+                               cpu_to_le16(ei->i_extra_isize);
+               }
        }
 
        ext4_inode_csum_set(inode, raw_inode, ei);
@@ -4446,7 +4467,12 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
                        return -EIO;
                }
 
-               if (wbc->sync_mode != WB_SYNC_ALL)
+               /*
+                * No need to force transaction in WB_SYNC_NONE mode. Also
+                * ext4_sync_fs() will force the commit after everything is
+                * written.
+                */
+               if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync)
                        return 0;
 
                err = ext4_force_commit(inode->i_sb);
@@ -4456,7 +4482,11 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
                err = __ext4_get_inode_loc(inode, &iloc, 0);
                if (err)
                        return err;
-               if (wbc->sync_mode == WB_SYNC_ALL)
+               /*
+                * sync(2) will flush the whole buffer cache. No need to do
+                * it here separately for each inode.
+                */
+               if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync)
                        sync_dirty_buffer(iloc.bh);
                if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
                        EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr,
index a2a837f0040743d9e76608904c5b2cb429aaadd2..0f2252ec274d6c3bd0fc47a45a902ad043cd3ddf 100644 (file)
@@ -104,21 +104,15 @@ static long swap_inode_boot_loader(struct super_block *sb,
        struct ext4_inode_info *ei_bl;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
 
-       if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode)) {
-               err = -EINVAL;
-               goto swap_boot_out;
-       }
+       if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode))
+               return -EINVAL;
 
-       if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) {
-               err = -EPERM;
-               goto swap_boot_out;
-       }
+       if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
+               return -EPERM;
 
        inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO);
-       if (IS_ERR(inode_bl)) {
-               err = PTR_ERR(inode_bl);
-               goto swap_boot_out;
-       }
+       if (IS_ERR(inode_bl))
+               return PTR_ERR(inode_bl);
        ei_bl = EXT4_I(inode_bl);
 
        filemap_flush(inode->i_mapping);
@@ -193,20 +187,14 @@ static long swap_inode_boot_loader(struct super_block *sb,
                        ext4_mark_inode_dirty(handle, inode);
                }
        }
-
        ext4_journal_stop(handle);
-
        ext4_double_up_write_data_sem(inode, inode_bl);
 
 journal_err_out:
        ext4_inode_resume_unlocked_dio(inode);
        ext4_inode_resume_unlocked_dio(inode_bl);
-
        unlock_two_nondirectories(inode, inode_bl);
-
        iput(inode_bl);
-
-swap_boot_out:
        return err;
 }
 
index 04a5c7504be9d6dbe55174d451f559064a7a05cf..a888cac76e9c55c34002f930a7bc8a8df53376bf 100644 (file)
@@ -1808,6 +1808,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
        ext4_lock_group(ac->ac_sb, group);
        max = mb_find_extent(e4b, ac->ac_g_ex.fe_start,
                             ac->ac_g_ex.fe_len, &ex);
+       ex.fe_logical = 0xDEADFA11; /* debug value */
 
        if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
                ext4_fsblk_t start;
@@ -1936,7 +1937,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
                         */
                        break;
                }
-
+               ex.fe_logical = 0xDEADC0DE; /* debug value */
                ext4_mb_measure_extent(ac, &ex, e4b);
 
                i += ex.fe_len;
@@ -1977,6 +1978,7 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
                        max = mb_find_extent(e4b, i, sbi->s_stripe, &ex);
                        if (max >= sbi->s_stripe) {
                                ac->ac_found++;
+                               ex.fe_logical = 0xDEADF00D; /* debug value */
                                ac->ac_b_ex = ex;
                                ext4_mb_use_best_found(ac, e4b);
                                break;
@@ -4006,8 +4008,7 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
                        (unsigned long)ac->ac_b_ex.fe_len,
                        (unsigned long)ac->ac_b_ex.fe_logical,
                        (int)ac->ac_criteria);
-       ext4_msg(ac->ac_sb, KERN_ERR, "%lu scanned, %d found",
-                ac->ac_ex_scanned, ac->ac_found);
+       ext4_msg(ac->ac_sb, KERN_ERR, "%d found", ac->ac_found);
        ext4_msg(ac->ac_sb, KERN_ERR, "groups: ");
        ngroups = ext4_get_groups_count(sb);
        for (i = 0; i < ngroups; i++) {
index 08481ee84cd58028c694a5713be5a63ee54a8821..d634e183b4d4b3034c05520254c87a77bed90200 100644 (file)
@@ -48,7 +48,7 @@ extern ushort ext4_mballoc_debug;
                }                                                       \
        } while (0)
 #else
-#define mb_debug(n, fmt, a...)
+#define mb_debug(n, fmt, a...)         no_printk(fmt, ## a)
 #endif
 
 #define EXT4_MB_HISTORY_ALLOC          1       /* allocation */
@@ -175,8 +175,6 @@ struct ext4_allocation_context {
        /* copy of the best found extent taken before preallocation efforts */
        struct ext4_free_extent ac_f_ex;
 
-       /* number of iterations done. we have to track to limit searching */
-       unsigned long ac_ex_scanned;
        __u16 ac_groups_scanned;
        __u16 ac_found;
        __u16 ac_tail;
index 773b503bd18cf840a048788b4c536717fafbb7e6..58ee7dc87669d9f49961a4be47335ae5e4615638 100644 (file)
@@ -76,7 +76,7 @@ copy_extent_status(struct ext4_extent *src, struct ext4_extent *dest)
  * ext4_ext_path structure refers to the last extent, or a negative error
  * value on failure.
  */
-static int
+int
 mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
                      struct ext4_extent **extent)
 {
@@ -861,8 +861,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to)
                        }
                        if (!buffer_mapped(bh)) {
                                zero_user(page, block_start, blocksize);
-                               if (!err)
-                                       set_buffer_uptodate(bh);
+                               set_buffer_uptodate(bh);
                                continue;
                        }
                }
index d050e043e884c19120c8062a2ab2991ba71a9a86..1cb84f78909ee2d96a5721569cdbd383e9011a35 100644 (file)
@@ -3000,6 +3000,154 @@ static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
        return ext4_get_first_inline_block(inode, parent_de, retval);
 }
 
+struct ext4_renament {
+       struct inode *dir;
+       struct dentry *dentry;
+       struct inode *inode;
+       bool is_dir;
+       int dir_nlink_delta;
+
+       /* entry for "dentry" */
+       struct buffer_head *bh;
+       struct ext4_dir_entry_2 *de;
+       int inlined;
+
+       /* entry for ".." in inode if it's a directory */
+       struct buffer_head *dir_bh;
+       struct ext4_dir_entry_2 *parent_de;
+       int dir_inlined;
+};
+
+static int ext4_rename_dir_prepare(handle_t *handle, struct ext4_renament *ent)
+{
+       int retval;
+
+       ent->dir_bh = ext4_get_first_dir_block(handle, ent->inode,
+                                             &retval, &ent->parent_de,
+                                             &ent->dir_inlined);
+       if (!ent->dir_bh)
+               return retval;
+       if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino)
+               return -EIO;
+       BUFFER_TRACE(ent->dir_bh, "get_write_access");
+       return ext4_journal_get_write_access(handle, ent->dir_bh);
+}
+
+static int ext4_rename_dir_finish(handle_t *handle, struct ext4_renament *ent,
+                                 unsigned dir_ino)
+{
+       int retval;
+
+       ent->parent_de->inode = cpu_to_le32(dir_ino);
+       BUFFER_TRACE(ent->dir_bh, "call ext4_handle_dirty_metadata");
+       if (!ent->dir_inlined) {
+               if (is_dx(ent->inode)) {
+                       retval = ext4_handle_dirty_dx_node(handle,
+                                                          ent->inode,
+                                                          ent->dir_bh);
+               } else {
+                       retval = ext4_handle_dirty_dirent_node(handle,
+                                                              ent->inode,
+                                                              ent->dir_bh);
+               }
+       } else {
+               retval = ext4_mark_inode_dirty(handle, ent->inode);
+       }
+       if (retval) {
+               ext4_std_error(ent->dir->i_sb, retval);
+               return retval;
+       }
+       return 0;
+}
+
+static int ext4_setent(handle_t *handle, struct ext4_renament *ent,
+                      unsigned ino, unsigned file_type)
+{
+       int retval;
+
+       BUFFER_TRACE(ent->bh, "get write access");
+       retval = ext4_journal_get_write_access(handle, ent->bh);
+       if (retval)
+               return retval;
+       ent->de->inode = cpu_to_le32(ino);
+       if (EXT4_HAS_INCOMPAT_FEATURE(ent->dir->i_sb,
+                                     EXT4_FEATURE_INCOMPAT_FILETYPE))
+               ent->de->file_type = file_type;
+       ent->dir->i_version++;
+       ent->dir->i_ctime = ent->dir->i_mtime =
+               ext4_current_time(ent->dir);
+       ext4_mark_inode_dirty(handle, ent->dir);
+       BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata");
+       if (!ent->inlined) {
+               retval = ext4_handle_dirty_dirent_node(handle,
+                                                      ent->dir, ent->bh);
+               if (unlikely(retval)) {
+                       ext4_std_error(ent->dir->i_sb, retval);
+                       return retval;
+               }
+       }
+       brelse(ent->bh);
+       ent->bh = NULL;
+
+       return 0;
+}
+
+static int ext4_find_delete_entry(handle_t *handle, struct inode *dir,
+                                 const struct qstr *d_name)
+{
+       int retval = -ENOENT;
+       struct buffer_head *bh;
+       struct ext4_dir_entry_2 *de;
+
+       bh = ext4_find_entry(dir, d_name, &de, NULL);
+       if (bh) {
+               retval = ext4_delete_entry(handle, dir, de, bh);
+               brelse(bh);
+       }
+       return retval;
+}
+
+static void ext4_rename_delete(handle_t *handle, struct ext4_renament *ent)
+{
+       int retval;
+       /*
+        * ent->de could have moved from under us during htree split, so make
+        * sure that we are deleting the right entry.  We might also be pointing
+        * to a stale entry in the unused part of ent->bh so just checking inum
+        * and the name isn't enough.
+        */
+       if (le32_to_cpu(ent->de->inode) != ent->inode->i_ino ||
+           ent->de->name_len != ent->dentry->d_name.len ||
+           strncmp(ent->de->name, ent->dentry->d_name.name,
+                   ent->de->name_len)) {
+               retval = ext4_find_delete_entry(handle, ent->dir,
+                                               &ent->dentry->d_name);
+       } else {
+               retval = ext4_delete_entry(handle, ent->dir, ent->de, ent->bh);
+               if (retval == -ENOENT) {
+                       retval = ext4_find_delete_entry(handle, ent->dir,
+                                                       &ent->dentry->d_name);
+               }
+       }
+
+       if (retval) {
+               ext4_warning(ent->dir->i_sb,
+                               "Deleting old file (%lu), %d, error=%d",
+                               ent->dir->i_ino, ent->dir->i_nlink, retval);
+       }
+}
+
+static void ext4_update_dir_count(handle_t *handle, struct ext4_renament *ent)
+{
+       if (ent->dir_nlink_delta) {
+               if (ent->dir_nlink_delta == -1)
+                       ext4_dec_count(handle, ent->dir);
+               else
+                       ext4_inc_count(handle, ent->dir);
+               ext4_mark_inode_dirty(handle, ent->dir);
+       }
+}
+
 /*
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
@@ -3012,198 +3160,267 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
                       struct inode *new_dir, struct dentry *new_dentry)
 {
        handle_t *handle = NULL;
-       struct inode *old_inode, *new_inode;
-       struct buffer_head *old_bh, *new_bh, *dir_bh;
-       struct ext4_dir_entry_2 *old_de, *new_de;
+       struct ext4_renament old = {
+               .dir = old_dir,
+               .dentry = old_dentry,
+               .inode = old_dentry->d_inode,
+       };
+       struct ext4_renament new = {
+               .dir = new_dir,
+               .dentry = new_dentry,
+               .inode = new_dentry->d_inode,
+       };
        int retval;
-       int inlined = 0, new_inlined = 0;
-       struct ext4_dir_entry_2 *parent_de;
 
-       dquot_initialize(old_dir);
-       dquot_initialize(new_dir);
-
-       old_bh = new_bh = dir_bh = NULL;
+       dquot_initialize(old.dir);
+       dquot_initialize(new.dir);
 
        /* Initialize quotas before so that eventual writes go
         * in separate transaction */
-       if (new_dentry->d_inode)
-               dquot_initialize(new_dentry->d_inode);
+       if (new.inode)
+               dquot_initialize(new.inode);
 
-       old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de, NULL);
+       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL);
        /*
         *  Check for inode number is _not_ due to possible IO errors.
         *  We might rmdir the source, keep it as pwd of some process
         *  and merrily kill the link to whatever was created under the
         *  same name. Goodbye sticky bit ;-<
         */
-       old_inode = old_dentry->d_inode;
        retval = -ENOENT;
-       if (!old_bh || le32_to_cpu(old_de->inode) != old_inode->i_ino)
+       if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino)
                goto end_rename;
 
-       new_inode = new_dentry->d_inode;
-       new_bh = ext4_find_entry(new_dir, &new_dentry->d_name,
-                                &new_de, &new_inlined);
-       if (new_bh) {
-               if (!new_inode) {
-                       brelse(new_bh);
-                       new_bh = NULL;
+       new.bh = ext4_find_entry(new.dir, &new.dentry->d_name,
+                                &new.de, &new.inlined);
+       if (new.bh) {
+               if (!new.inode) {
+                       brelse(new.bh);
+                       new.bh = NULL;
                }
        }
-       if (new_inode && !test_opt(new_dir->i_sb, NO_AUTO_DA_ALLOC))
-               ext4_alloc_da_blocks(old_inode);
+       if (new.inode && !test_opt(new.dir->i_sb, NO_AUTO_DA_ALLOC))
+               ext4_alloc_da_blocks(old.inode);
 
-       handle = ext4_journal_start(old_dir, EXT4_HT_DIR,
-               (2 * EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) +
+       handle = ext4_journal_start(old.dir, EXT4_HT_DIR,
+               (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) +
                 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
-       if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
+       if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
                ext4_handle_sync(handle);
 
-       if (S_ISDIR(old_inode->i_mode)) {
-               if (new_inode) {
+       if (S_ISDIR(old.inode->i_mode)) {
+               if (new.inode) {
                        retval = -ENOTEMPTY;
-                       if (!empty_dir(new_inode))
+                       if (!empty_dir(new.inode))
+                               goto end_rename;
+               } else {
+                       retval = -EMLINK;
+                       if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir))
                                goto end_rename;
                }
-               retval = -EIO;
-               dir_bh = ext4_get_first_dir_block(handle, old_inode,
-                                                 &retval, &parent_de,
-                                                 &inlined);
-               if (!dir_bh)
-                       goto end_rename;
-               if (le32_to_cpu(parent_de->inode) != old_dir->i_ino)
-                       goto end_rename;
-               retval = -EMLINK;
-               if (!new_inode && new_dir != old_dir &&
-                   EXT4_DIR_LINK_MAX(new_dir))
-                       goto end_rename;
-               BUFFER_TRACE(dir_bh, "get_write_access");
-               retval = ext4_journal_get_write_access(handle, dir_bh);
+               retval = ext4_rename_dir_prepare(handle, &old);
                if (retval)
                        goto end_rename;
        }
-       if (!new_bh) {
-               retval = ext4_add_entry(handle, new_dentry, old_inode);
+       if (!new.bh) {
+               retval = ext4_add_entry(handle, new.dentry, old.inode);
                if (retval)
                        goto end_rename;
        } else {
-               BUFFER_TRACE(new_bh, "get write access");
-               retval = ext4_journal_get_write_access(handle, new_bh);
+               retval = ext4_setent(handle, &new,
+                                    old.inode->i_ino, old.de->file_type);
                if (retval)
                        goto end_rename;
-               new_de->inode = cpu_to_le32(old_inode->i_ino);
-               if (EXT4_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
-                                             EXT4_FEATURE_INCOMPAT_FILETYPE))
-                       new_de->file_type = old_de->file_type;
-               new_dir->i_version++;
-               new_dir->i_ctime = new_dir->i_mtime =
-                                       ext4_current_time(new_dir);
-               ext4_mark_inode_dirty(handle, new_dir);
-               BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata");
-               if (!new_inlined) {
-                       retval = ext4_handle_dirty_dirent_node(handle,
-                                                              new_dir, new_bh);
-                       if (unlikely(retval)) {
-                               ext4_std_error(new_dir->i_sb, retval);
-                               goto end_rename;
-                       }
-               }
-               brelse(new_bh);
-               new_bh = NULL;
        }
 
        /*
         * Like most other Unix systems, set the ctime for inodes on a
         * rename.
         */
-       old_inode->i_ctime = ext4_current_time(old_inode);
-       ext4_mark_inode_dirty(handle, old_inode);
+       old.inode->i_ctime = ext4_current_time(old.inode);
+       ext4_mark_inode_dirty(handle, old.inode);
 
        /*
         * ok, that's it
         */
-       if (le32_to_cpu(old_de->inode) != old_inode->i_ino ||
-           old_de->name_len != old_dentry->d_name.len ||
-           strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) ||
-           (retval = ext4_delete_entry(handle, old_dir,
-                                       old_de, old_bh)) == -ENOENT) {
-               /* old_de could have moved from under us during htree split, so
-                * make sure that we are deleting the right entry.  We might
-                * also be pointing to a stale entry in the unused part of
-                * old_bh so just checking inum and the name isn't enough. */
-               struct buffer_head *old_bh2;
-               struct ext4_dir_entry_2 *old_de2;
-
-               old_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name,
-                                         &old_de2, NULL);
-               if (old_bh2) {
-                       retval = ext4_delete_entry(handle, old_dir,
-                                                  old_de2, old_bh2);
-                       brelse(old_bh2);
-               }
+       ext4_rename_delete(handle, &old);
+
+       if (new.inode) {
+               ext4_dec_count(handle, new.inode);
+               new.inode->i_ctime = ext4_current_time(new.inode);
        }
-       if (retval) {
-               ext4_warning(old_dir->i_sb,
-                               "Deleting old file (%lu), %d, error=%d",
-                               old_dir->i_ino, old_dir->i_nlink, retval);
-       }
-
-       if (new_inode) {
-               ext4_dec_count(handle, new_inode);
-               new_inode->i_ctime = ext4_current_time(new_inode);
-       }
-       old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir);
-       ext4_update_dx_flag(old_dir);
-       if (dir_bh) {
-               parent_de->inode = cpu_to_le32(new_dir->i_ino);
-               BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
-               if (!inlined) {
-                       if (is_dx(old_inode)) {
-                               retval = ext4_handle_dirty_dx_node(handle,
-                                                                  old_inode,
-                                                                  dir_bh);
-                       } else {
-                               retval = ext4_handle_dirty_dirent_node(handle,
-                                                       old_inode, dir_bh);
-                       }
-               } else {
-                       retval = ext4_mark_inode_dirty(handle, old_inode);
-               }
-               if (retval) {
-                       ext4_std_error(old_dir->i_sb, retval);
+       old.dir->i_ctime = old.dir->i_mtime = ext4_current_time(old.dir);
+       ext4_update_dx_flag(old.dir);
+       if (old.dir_bh) {
+               retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino);
+               if (retval)
                        goto end_rename;
-               }
-               ext4_dec_count(handle, old_dir);
-               if (new_inode) {
+
+               ext4_dec_count(handle, old.dir);
+               if (new.inode) {
                        /* checked empty_dir above, can't have another parent,
                         * ext4_dec_count() won't work for many-linked dirs */
-                       clear_nlink(new_inode);
+                       clear_nlink(new.inode);
                } else {
-                       ext4_inc_count(handle, new_dir);
-                       ext4_update_dx_flag(new_dir);
-                       ext4_mark_inode_dirty(handle, new_dir);
+                       ext4_inc_count(handle, new.dir);
+                       ext4_update_dx_flag(new.dir);
+                       ext4_mark_inode_dirty(handle, new.dir);
                }
        }
-       ext4_mark_inode_dirty(handle, old_dir);
-       if (new_inode) {
-               ext4_mark_inode_dirty(handle, new_inode);
-               if (!new_inode->i_nlink)
-                       ext4_orphan_add(handle, new_inode);
+       ext4_mark_inode_dirty(handle, old.dir);
+       if (new.inode) {
+               ext4_mark_inode_dirty(handle, new.inode);
+               if (!new.inode->i_nlink)
+                       ext4_orphan_add(handle, new.inode);
        }
        retval = 0;
 
 end_rename:
-       brelse(dir_bh);
-       brelse(old_bh);
-       brelse(new_bh);
+       brelse(old.dir_bh);
+       brelse(old.bh);
+       brelse(new.bh);
        if (handle)
                ext4_journal_stop(handle);
        return retval;
 }
 
+static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
+                            struct inode *new_dir, struct dentry *new_dentry)
+{
+       handle_t *handle = NULL;
+       struct ext4_renament old = {
+               .dir = old_dir,
+               .dentry = old_dentry,
+               .inode = old_dentry->d_inode,
+       };
+       struct ext4_renament new = {
+               .dir = new_dir,
+               .dentry = new_dentry,
+               .inode = new_dentry->d_inode,
+       };
+       u8 new_file_type;
+       int retval;
+
+       dquot_initialize(old.dir);
+       dquot_initialize(new.dir);
+
+       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name,
+                                &old.de, &old.inlined);
+       /*
+        *  Check for inode number is _not_ due to possible IO errors.
+        *  We might rmdir the source, keep it as pwd of some process
+        *  and merrily kill the link to whatever was created under the
+        *  same name. Goodbye sticky bit ;-<
+        */
+       retval = -ENOENT;
+       if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino)
+               goto end_rename;
+
+       new.bh = ext4_find_entry(new.dir, &new.dentry->d_name,
+                                &new.de, &new.inlined);
+
+       /* RENAME_EXCHANGE case: old *and* new must both exist */
+       if (!new.bh || le32_to_cpu(new.de->inode) != new.inode->i_ino)
+               goto end_rename;
+
+       handle = ext4_journal_start(old.dir, EXT4_HT_DIR,
+               (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) +
+                2 * EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
+               ext4_handle_sync(handle);
+
+       if (S_ISDIR(old.inode->i_mode)) {
+               old.is_dir = true;
+               retval = ext4_rename_dir_prepare(handle, &old);
+               if (retval)
+                       goto end_rename;
+       }
+       if (S_ISDIR(new.inode->i_mode)) {
+               new.is_dir = true;
+               retval = ext4_rename_dir_prepare(handle, &new);
+               if (retval)
+                       goto end_rename;
+       }
+
+       /*
+        * Other than the special case of overwriting a directory, parents'
+        * nlink only needs to be modified if this is a cross directory rename.
+        */
+       if (old.dir != new.dir && old.is_dir != new.is_dir) {
+               old.dir_nlink_delta = old.is_dir ? -1 : 1;
+               new.dir_nlink_delta = -old.dir_nlink_delta;
+               retval = -EMLINK;
+               if ((old.dir_nlink_delta > 0 && EXT4_DIR_LINK_MAX(old.dir)) ||
+                   (new.dir_nlink_delta > 0 && EXT4_DIR_LINK_MAX(new.dir)))
+                       goto end_rename;
+       }
+
+       new_file_type = new.de->file_type;
+       retval = ext4_setent(handle, &new, old.inode->i_ino, old.de->file_type);
+       if (retval)
+               goto end_rename;
+
+       retval = ext4_setent(handle, &old, new.inode->i_ino, new_file_type);
+       if (retval)
+               goto end_rename;
+
+       /*
+        * Like most other Unix systems, set the ctime for inodes on a
+        * rename.
+        */
+       old.inode->i_ctime = ext4_current_time(old.inode);
+       new.inode->i_ctime = ext4_current_time(new.inode);
+       ext4_mark_inode_dirty(handle, old.inode);
+       ext4_mark_inode_dirty(handle, new.inode);
+
+       if (old.dir_bh) {
+               retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino);
+               if (retval)
+                       goto end_rename;
+       }
+       if (new.dir_bh) {
+               retval = ext4_rename_dir_finish(handle, &new, old.dir->i_ino);
+               if (retval)
+                       goto end_rename;
+       }
+       ext4_update_dir_count(handle, &old);
+       ext4_update_dir_count(handle, &new);
+       retval = 0;
+
+end_rename:
+       brelse(old.dir_bh);
+       brelse(new.dir_bh);
+       brelse(old.bh);
+       brelse(new.bh);
+       if (handle)
+               ext4_journal_stop(handle);
+       return retval;
+}
+
+static int ext4_rename2(struct inode *old_dir, struct dentry *old_dentry,
+                       struct inode *new_dir, struct dentry *new_dentry,
+                       unsigned int flags)
+{
+       if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
+               return -EINVAL;
+
+       if (flags & RENAME_EXCHANGE) {
+               return ext4_cross_rename(old_dir, old_dentry,
+                                        new_dir, new_dentry);
+       }
+       /*
+        * Existence checking was done by the VFS, otherwise "RENAME_NOREPLACE"
+        * is equivalent to regular rename.
+        */
+       return ext4_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
 /*
  * directories can handle most operations...
  */
@@ -3218,6 +3435,7 @@ const struct inode_operations ext4_dir_inode_operations = {
        .mknod          = ext4_mknod,
        .tmpfile        = ext4_tmpfile,
        .rename         = ext4_rename,
+       .rename2        = ext4_rename2,
        .setattr        = ext4_setattr,
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index 710fed2377d415a32b0658faabde9960ff639b84..f3c667091618d8b26e09964dafe2f673a4c6cbd3 100644 (file)
@@ -59,6 +59,7 @@ static struct kset *ext4_kset;
 static struct ext4_lazy_init *ext4_li_info;
 static struct mutex ext4_li_mtx;
 static struct ext4_features *ext4_feat;
+static int ext4_mballoc_ready;
 
 static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
                             unsigned long journal_devnum);
@@ -845,6 +846,10 @@ static void ext4_put_super(struct super_block *sb)
                invalidate_bdev(sbi->journal_bdev);
                ext4_blkdev_remove(sbi);
        }
+       if (sbi->s_mb_cache) {
+               ext4_xattr_destroy_cache(sbi->s_mb_cache);
+               sbi->s_mb_cache = NULL;
+       }
        if (sbi->s_mmp_tsk)
                kthread_stop(sbi->s_mmp_tsk);
        sb->s_fs_info = NULL;
@@ -940,7 +945,7 @@ static void init_once(void *foo)
        inode_init_once(&ei->vfs_inode);
 }
 
-static int init_inodecache(void)
+static int __init init_inodecache(void)
 {
        ext4_inode_cachep = kmem_cache_create("ext4_inode_cache",
                                             sizeof(struct ext4_inode_info),
@@ -3575,6 +3580,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                       "feature flags set on rev 0 fs, "
                       "running e2fsck is recommended");
 
+       if (es->s_creator_os == cpu_to_le32(EXT4_OS_HURD)) {
+               set_opt2(sb, HURD_COMPAT);
+               if (EXT4_HAS_INCOMPAT_FEATURE(sb,
+                                             EXT4_FEATURE_INCOMPAT_64BIT)) {
+                       ext4_msg(sb, KERN_ERR,
+                                "The Hurd can't support 64-bit file systems");
+                       goto failed_mount;
+               }
+       }
+
        if (IS_EXT2_SB(sb)) {
                if (ext2_feature_set_ok(sb))
                        ext4_msg(sb, KERN_INFO, "mounting ext2 file system "
@@ -4010,6 +4025,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        percpu_counter_set(&sbi->s_dirtyclusters_counter, 0);
 
 no_journal:
+       if (ext4_mballoc_ready) {
+               sbi->s_mb_cache = ext4_xattr_create_cache(sb->s_id);
+               if (!sbi->s_mb_cache) {
+                       ext4_msg(sb, KERN_ERR, "Failed to create an mb_cache");
+                       goto failed_mount_wq;
+               }
+       }
+
        /*
         * Get the # of file system overhead blocks from the
         * superblock if present.
@@ -4835,6 +4858,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                }
 
                if (*flags & MS_RDONLY) {
+                       err = sync_filesystem(sb);
+                       if (err < 0)
+                               goto restore_opts;
                        err = dquot_suspend(sb, -1);
                        if (err < 0)
                                goto restore_opts;
@@ -5515,12 +5541,10 @@ static int __init ext4_init_fs(void)
                goto out4;
 
        err = ext4_init_mballoc();
-       if (err)
-               goto out3;
-
-       err = ext4_init_xattr();
        if (err)
                goto out2;
+       else
+               ext4_mballoc_ready = 1;
        err = init_inodecache();
        if (err)
                goto out1;
@@ -5536,10 +5560,9 @@ out:
        unregister_as_ext3();
        destroy_inodecache();
 out1:
-       ext4_exit_xattr();
-out2:
+       ext4_mballoc_ready = 0;
        ext4_exit_mballoc();
-out3:
+out2:
        ext4_exit_feat_adverts();
 out4:
        if (ext4_proc_root)
@@ -5562,7 +5585,6 @@ static void __exit ext4_exit_fs(void)
        unregister_as_ext3();
        unregister_filesystem(&ext4_fs_type);
        destroy_inodecache();
-       ext4_exit_xattr();
        ext4_exit_mballoc();
        ext4_exit_feat_adverts();
        remove_proc_entry("fs/ext4", NULL);
index e175e94116acefdc7685896e5c8744f7bd677dc4..1f5cf5880718d28c8ca7893f7165807f78101c6b 100644 (file)
@@ -81,7 +81,7 @@
 # define ea_bdebug(bh, fmt, ...)       no_printk(fmt, ##__VA_ARGS__)
 #endif
 
-static void ext4_xattr_cache_insert(struct buffer_head *);
+static void ext4_xattr_cache_insert(struct mb_cache *, struct buffer_head *);
 static struct buffer_head *ext4_xattr_cache_find(struct inode *,
                                                 struct ext4_xattr_header *,
                                                 struct mb_cache_entry **);
@@ -90,8 +90,6 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *,
 static int ext4_xattr_list(struct dentry *dentry, char *buffer,
                           size_t buffer_size);
 
-static struct mb_cache *ext4_xattr_cache;
-
 static const struct xattr_handler *ext4_xattr_handler_map[] = {
        [EXT4_XATTR_INDEX_USER]              = &ext4_xattr_user_handler,
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
@@ -117,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
        NULL
 };
 
+#define EXT4_GET_MB_CACHE(inode)       (((struct ext4_sb_info *) \
+                               inode->i_sb->s_fs_info)->s_mb_cache)
+
 static __le32 ext4_xattr_block_csum(struct inode *inode,
                                    sector_t block_nr,
                                    struct ext4_xattr_header *hdr)
@@ -265,6 +266,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
        struct ext4_xattr_entry *entry;
        size_t size;
        int error;
+       struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
        ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
                  name_index, name, buffer, (long)buffer_size);
@@ -286,7 +288,7 @@ bad_block:
                error = -EIO;
                goto cleanup;
        }
-       ext4_xattr_cache_insert(bh);
+       ext4_xattr_cache_insert(ext4_mb_cache, bh);
        entry = BFIRST(bh);
        error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
        if (error == -EIO)
@@ -409,6 +411,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
        struct inode *inode = dentry->d_inode;
        struct buffer_head *bh = NULL;
        int error;
+       struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
        ea_idebug(inode, "buffer=%p, buffer_size=%ld",
                  buffer, (long)buffer_size);
@@ -430,7 +433,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
                error = -EIO;
                goto cleanup;
        }
-       ext4_xattr_cache_insert(bh);
+       ext4_xattr_cache_insert(ext4_mb_cache, bh);
        error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);
 
 cleanup:
@@ -526,8 +529,9 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
 {
        struct mb_cache_entry *ce = NULL;
        int error = 0;
+       struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
-       ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr);
+       ce = mb_cache_entry_get(ext4_mb_cache, bh->b_bdev, bh->b_blocknr);
        error = ext4_journal_get_write_access(handle, bh);
        if (error)
                goto out;
@@ -567,12 +571,13 @@ static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
                                    size_t *min_offs, void *base, int *total)
 {
        for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
-               *total += EXT4_XATTR_LEN(last->e_name_len);
                if (!last->e_value_block && last->e_value_size) {
                        size_t offs = le16_to_cpu(last->e_value_offs);
                        if (offs < *min_offs)
                                *min_offs = offs;
                }
+               if (total)
+                       *total += EXT4_XATTR_LEN(last->e_name_len);
        }
        return (*min_offs - ((void *)last - base) - sizeof(__u32));
 }
@@ -745,13 +750,14 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
        struct ext4_xattr_search *s = &bs->s;
        struct mb_cache_entry *ce = NULL;
        int error = 0;
+       struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
 #define header(x) ((struct ext4_xattr_header *)(x))
 
        if (i->value && i->value_len > sb->s_blocksize)
                return -ENOSPC;
        if (s->base) {
-               ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev,
+               ce = mb_cache_entry_get(ext4_mb_cache, bs->bh->b_bdev,
                                        bs->bh->b_blocknr);
                error = ext4_journal_get_write_access(handle, bs->bh);
                if (error)
@@ -769,7 +775,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                                if (!IS_LAST_ENTRY(s->first))
                                        ext4_xattr_rehash(header(s->base),
                                                          s->here);
-                               ext4_xattr_cache_insert(bs->bh);
+                               ext4_xattr_cache_insert(ext4_mb_cache,
+                                       bs->bh);
                        }
                        unlock_buffer(bs->bh);
                        if (error == -EIO)
@@ -905,7 +912,7 @@ getblk_failed:
                        memcpy(new_bh->b_data, s->base, new_bh->b_size);
                        set_buffer_uptodate(new_bh);
                        unlock_buffer(new_bh);
-                       ext4_xattr_cache_insert(new_bh);
+                       ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
                        error = ext4_handle_dirty_xattr_block(handle,
                                                              inode, new_bh);
                        if (error)
@@ -1228,7 +1235,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
        struct ext4_xattr_block_find *bs = NULL;
        char *buffer = NULL, *b_entry_name = NULL;
        size_t min_offs, free;
-       int total_ino, total_blk;
+       int total_ino;
        void *base, *start, *end;
        int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
        int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
@@ -1286,8 +1293,7 @@ retry:
                first = BFIRST(bh);
                end = bh->b_data + bh->b_size;
                min_offs = end - base;
-               free = ext4_xattr_free_space(first, &min_offs, base,
-                                            &total_blk);
+               free = ext4_xattr_free_space(first, &min_offs, base, NULL);
                if (free < new_extra_isize) {
                        if (!tried_min_extra_isize && s_min_extra_isize) {
                                tried_min_extra_isize++;
@@ -1495,13 +1501,13 @@ ext4_xattr_put_super(struct super_block *sb)
  * Returns 0, or a negative error number on failure.
  */
 static void
-ext4_xattr_cache_insert(struct buffer_head *bh)
+ext4_xattr_cache_insert(struct mb_cache *ext4_mb_cache, struct buffer_head *bh)
 {
        __u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
        struct mb_cache_entry *ce;
        int error;
 
-       ce = mb_cache_entry_alloc(ext4_xattr_cache, GFP_NOFS);
+       ce = mb_cache_entry_alloc(ext4_mb_cache, GFP_NOFS);
        if (!ce) {
                ea_bdebug(bh, "out of memory");
                return;
@@ -1573,12 +1579,13 @@ ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
 {
        __u32 hash = le32_to_cpu(header->h_hash);
        struct mb_cache_entry *ce;
+       struct mb_cache *ext4_mb_cache = EXT4_GET_MB_CACHE(inode);
 
        if (!header->h_hash)
                return NULL;  /* never share */
        ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
 again:
-       ce = mb_cache_entry_find_first(ext4_xattr_cache, inode->i_sb->s_bdev,
+       ce = mb_cache_entry_find_first(ext4_mb_cache, inode->i_sb->s_bdev,
                                       hash);
        while (ce) {
                struct buffer_head *bh;
@@ -1676,19 +1683,17 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *header,
 
 #undef BLOCK_HASH_SHIFT
 
-int __init
-ext4_init_xattr(void)
+#define        HASH_BUCKET_BITS        10
+
+struct mb_cache *
+ext4_xattr_create_cache(char *name)
 {
-       ext4_xattr_cache = mb_cache_create("ext4_xattr", 6);
-       if (!ext4_xattr_cache)
-               return -ENOMEM;
-       return 0;
+       return mb_cache_create(name, HASH_BUCKET_BITS);
 }
 
-void
-ext4_exit_xattr(void)
+void ext4_xattr_destroy_cache(struct mb_cache *cache)
 {
-       if (ext4_xattr_cache)
-               mb_cache_destroy(ext4_xattr_cache);
-       ext4_xattr_cache = NULL;
+       if (cache)
+               mb_cache_destroy(cache);
 }
+
index 819d6398833f9d98ea7a9e78552381f63f7b83fd..29bedf5589f6b2c0aba9830aacd27d6576276e66 100644 (file)
@@ -110,9 +110,6 @@ extern void ext4_xattr_put_super(struct super_block *);
 extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
                            struct ext4_inode *raw_inode, handle_t *handle);
 
-extern int __init ext4_init_xattr(void);
-extern void ext4_exit_xattr(void);
-
 extern const struct xattr_handler *ext4_xattr_handlers[];
 
 extern int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
@@ -124,6 +121,9 @@ extern int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
                                       struct ext4_xattr_info *i,
                                       struct ext4_xattr_ibody_find *is);
 
+extern struct mb_cache *ext4_xattr_create_cache(char *name);
+extern void ext4_xattr_destroy_cache(struct mb_cache *);
+
 #ifdef CONFIG_EXT4_FS_SECURITY
 extern int ext4_init_security(handle_t *handle, struct inode *inode,
                              struct inode *dir, const struct qstr *qstr);
index fa8da4cb8c4b9a3aa647f2a4f51467fc86549fc5..e93e4ec7d165afe85800bf6acf68f01178d9d836 100644 (file)
@@ -174,7 +174,7 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
 
        retval = f2fs_getxattr(inode, name_index, "", NULL, 0);
        if (retval > 0) {
-               value = kmalloc(retval, GFP_KERNEL);
+               value = kmalloc(retval, GFP_F2FS_ZERO);
                if (!value)
                        return ERR_PTR(-ENOMEM);
                retval = f2fs_getxattr(inode, name_index, "", value, retval);
@@ -203,6 +203,12 @@ static int __f2fs_set_acl(struct inode *inode, int type,
        size_t size = 0;
        int error;
 
+       if (acl) {
+               error = posix_acl_valid(acl);
+               if (error < 0)
+                       return error;
+       }
+
        switch (type) {
        case ACL_TYPE_ACCESS:
                name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
index 293d0486a40f7e8560b25d012a7a2398ef4e955c..4aa521aa9bc3a794fbe52625e689b93140ed38a5 100644 (file)
@@ -33,14 +33,12 @@ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
        struct address_space *mapping = META_MAPPING(sbi);
        struct page *page = NULL;
 repeat:
-       page = grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
        if (!page) {
                cond_resched();
                goto repeat;
        }
 
-       /* We wait writeback only inside grab_meta_page() */
-       wait_on_page_writeback(page);
        SetPageUptodate(page);
        return page;
 }
@@ -75,23 +73,102 @@ out:
        return page;
 }
 
+inline int get_max_meta_blks(struct f2fs_sb_info *sbi, int type)
+{
+       switch (type) {
+       case META_NAT:
+               return NM_I(sbi)->max_nid / NAT_ENTRY_PER_BLOCK;
+       case META_SIT:
+               return SIT_BLK_CNT(sbi);
+       case META_SSA:
+       case META_CP:
+               return 0;
+       default:
+               BUG();
+       }
+}
+
+/*
+ * Readahead CP/NAT/SIT/SSA pages
+ */
+int ra_meta_pages(struct f2fs_sb_info *sbi, int start, int nrpages, int type)
+{
+       block_t prev_blk_addr = 0;
+       struct page *page;
+       int blkno = start;
+       int max_blks = get_max_meta_blks(sbi, type);
+
+       struct f2fs_io_info fio = {
+               .type = META,
+               .rw = READ_SYNC | REQ_META | REQ_PRIO
+       };
+
+       for (; nrpages-- > 0; blkno++) {
+               block_t blk_addr;
+
+               switch (type) {
+               case META_NAT:
+                       /* get nat block addr */
+                       if (unlikely(blkno >= max_blks))
+                               blkno = 0;
+                       blk_addr = current_nat_addr(sbi,
+                                       blkno * NAT_ENTRY_PER_BLOCK);
+                       break;
+               case META_SIT:
+                       /* get sit block addr */
+                       if (unlikely(blkno >= max_blks))
+                               goto out;
+                       blk_addr = current_sit_addr(sbi,
+                                       blkno * SIT_ENTRY_PER_BLOCK);
+                       if (blkno != start && prev_blk_addr + 1 != blk_addr)
+                               goto out;
+                       prev_blk_addr = blk_addr;
+                       break;
+               case META_SSA:
+               case META_CP:
+                       /* get ssa/cp block addr */
+                       blk_addr = blkno;
+                       break;
+               default:
+                       BUG();
+               }
+
+               page = grab_cache_page(META_MAPPING(sbi), blk_addr);
+               if (!page)
+                       continue;
+               if (PageUptodate(page)) {
+                       mark_page_accessed(page);
+                       f2fs_put_page(page, 1);
+                       continue;
+               }
+
+               f2fs_submit_page_mbio(sbi, page, blk_addr, &fio);
+               mark_page_accessed(page);
+               f2fs_put_page(page, 0);
+       }
+out:
+       f2fs_submit_merged_bio(sbi, META, READ);
+       return blkno - start;
+}
+
 static int f2fs_write_meta_page(struct page *page,
                                struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
 
-       /* Should not write any meta pages, if any IO error was occurred */
-       if (unlikely(sbi->por_doing ||
-                       is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
+       if (unlikely(sbi->por_doing))
                goto redirty_out;
-
        if (wbc->for_reclaim)
                goto redirty_out;
 
-       wait_on_page_writeback(page);
+       /* Should not write any meta pages, if any IO error was occurred */
+       if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
+               goto no_write;
 
+       f2fs_wait_on_page_writeback(page, META);
        write_meta_page(sbi, page);
+no_write:
        dec_page_count(sbi, F2FS_DIRTY_META);
        unlock_page(page);
        return 0;
@@ -99,6 +176,7 @@ static int f2fs_write_meta_page(struct page *page,
 redirty_out:
        dec_page_count(sbi, F2FS_DIRTY_META);
        wbc->pages_skipped++;
+       account_page_redirty(page);
        set_page_dirty(page);
        return AOP_WRITEPAGE_ACTIVATE;
 }
@@ -107,21 +185,23 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
                                struct writeback_control *wbc)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb);
-       int nrpages = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
-       long written;
-
-       if (wbc->for_kupdate)
-               return 0;
+       long diff, written;
 
        /* collect a number of dirty meta pages and write together */
-       if (get_pages(sbi, F2FS_DIRTY_META) < nrpages)
-               return 0;
+       if (wbc->for_kupdate ||
+               get_pages(sbi, F2FS_DIRTY_META) < nr_pages_to_skip(sbi, META))
+               goto skip_write;
 
        /* if mounting is failed, skip writing node pages */
        mutex_lock(&sbi->cp_mutex);
-       written = sync_meta_pages(sbi, META, nrpages);
+       diff = nr_pages_to_write(sbi, META, wbc);
+       written = sync_meta_pages(sbi, META, wbc->nr_to_write);
        mutex_unlock(&sbi->cp_mutex);
-       wbc->nr_to_write -= written;
+       wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff);
+       return 0;
+
+skip_write:
+       wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_META);
        return 0;
 }
 
@@ -148,10 +228,22 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
 
                for (i = 0; i < nr_pages; i++) {
                        struct page *page = pvec.pages[i];
+
                        lock_page(page);
-                       f2fs_bug_on(page->mapping != mapping);
-                       f2fs_bug_on(!PageDirty(page));
-                       clear_page_dirty_for_io(page);
+
+                       if (unlikely(page->mapping != mapping)) {
+continue_unlock:
+                               unlock_page(page);
+                               continue;
+                       }
+                       if (!PageDirty(page)) {
+                               /* someone wrote it for us */
+                               goto continue_unlock;
+                       }
+
+                       if (!clear_page_dirty_for_io(page))
+                               goto continue_unlock;
+
                        if (f2fs_write_meta_page(page, &wbc)) {
                                unlock_page(page);
                                break;
@@ -216,16 +308,15 @@ void release_orphan_inode(struct f2fs_sb_info *sbi)
 
 void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 {
-       struct list_head *head, *this;
-       struct orphan_inode_entry *new = NULL, *orphan = NULL;
+       struct list_head *head;
+       struct orphan_inode_entry *new, *orphan;
 
        new = f2fs_kmem_cache_alloc(orphan_entry_slab, GFP_ATOMIC);
        new->ino = ino;
 
        spin_lock(&sbi->orphan_inode_lock);
        head = &sbi->orphan_inode_list;
-       list_for_each(this, head) {
-               orphan = list_entry(this, struct orphan_inode_entry, list);
+       list_for_each_entry(orphan, head, list) {
                if (orphan->ino == ino) {
                        spin_unlock(&sbi->orphan_inode_lock);
                        kmem_cache_free(orphan_entry_slab, new);
@@ -234,14 +325,10 @@ void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 
                if (orphan->ino > ino)
                        break;
-               orphan = NULL;
        }
 
-       /* add new_oentry into list which is sorted by inode number */
-       if (orphan)
-               list_add(&new->list, this->prev);
-       else
-               list_add_tail(&new->list, head);
+       /* add new orphan entry into list which is sorted by inode number */
+       list_add_tail(&new->list, &orphan->list);
        spin_unlock(&sbi->orphan_inode_lock);
 }
 
@@ -255,10 +342,11 @@ void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
        list_for_each_entry(orphan, head, list) {
                if (orphan->ino == ino) {
                        list_del(&orphan->list);
-                       kmem_cache_free(orphan_entry_slab, orphan);
                        f2fs_bug_on(sbi->n_orphans == 0);
                        sbi->n_orphans--;
-                       break;
+                       spin_unlock(&sbi->orphan_inode_lock);
+                       kmem_cache_free(orphan_entry_slab, orphan);
+                       return;
                }
        }
        spin_unlock(&sbi->orphan_inode_lock);
@@ -285,6 +373,8 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi)
        start_blk = __start_cp_addr(sbi) + 1;
        orphan_blkaddr = __start_sum_addr(sbi) - 1;
 
+       ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP);
+
        for (i = 0; i < orphan_blkaddr; i++) {
                struct page *page = get_meta_page(sbi, start_blk + i);
                struct f2fs_orphan_block *orphan_blk;
@@ -466,14 +556,12 @@ static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct list_head *head = &sbi->dir_inode_list;
-       struct list_head *this;
+       struct dir_inode_entry *entry;
 
-       list_for_each(this, head) {
-               struct dir_inode_entry *entry;
-               entry = list_entry(this, struct dir_inode_entry, list);
+       list_for_each_entry(entry, head, list)
                if (unlikely(entry->inode == inode))
                        return -EEXIST;
-       }
+
        list_add_tail(&new->list, head);
        stat_inc_dirty_dir(sbi);
        return 0;
@@ -483,6 +571,7 @@ void set_dirty_dir_page(struct inode *inode, struct page *page)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct dir_inode_entry *new;
+       int ret = 0;
 
        if (!S_ISDIR(inode->i_mode))
                return;
@@ -492,13 +581,13 @@ void set_dirty_dir_page(struct inode *inode, struct page *page)
        INIT_LIST_HEAD(&new->list);
 
        spin_lock(&sbi->dir_inode_lock);
-       if (__add_dirty_inode(inode, new))
-               kmem_cache_free(inode_entry_slab, new);
-
-       inc_page_count(sbi, F2FS_DIRTY_DENTS);
+       ret = __add_dirty_inode(inode, new);
        inode_inc_dirty_dents(inode);
        SetPagePrivate(page);
        spin_unlock(&sbi->dir_inode_lock);
+
+       if (ret)
+               kmem_cache_free(inode_entry_slab, new);
 }
 
 void add_dirty_dir_inode(struct inode *inode)
@@ -506,44 +595,47 @@ void add_dirty_dir_inode(struct inode *inode)
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct dir_inode_entry *new =
                        f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
+       int ret = 0;
 
        new->inode = inode;
        INIT_LIST_HEAD(&new->list);
 
        spin_lock(&sbi->dir_inode_lock);
-       if (__add_dirty_inode(inode, new))
-               kmem_cache_free(inode_entry_slab, new);
+       ret = __add_dirty_inode(inode, new);
        spin_unlock(&sbi->dir_inode_lock);
+
+       if (ret)
+               kmem_cache_free(inode_entry_slab, new);
 }
 
 void remove_dirty_dir_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-
-       struct list_head *this, *head;
+       struct list_head *head;
+       struct dir_inode_entry *entry;
 
        if (!S_ISDIR(inode->i_mode))
                return;
 
        spin_lock(&sbi->dir_inode_lock);
-       if (atomic_read(&F2FS_I(inode)->dirty_dents)) {
+       if (get_dirty_dents(inode)) {
                spin_unlock(&sbi->dir_inode_lock);
                return;
        }
 
        head = &sbi->dir_inode_list;
-       list_for_each(this, head) {
-               struct dir_inode_entry *entry;
-               entry = list_entry(this, struct dir_inode_entry, list);
+       list_for_each_entry(entry, head, list) {
                if (entry->inode == inode) {
                        list_del(&entry->list);
-                       kmem_cache_free(inode_entry_slab, entry);
                        stat_dec_dirty_dir(sbi);
-                       break;
+                       spin_unlock(&sbi->dir_inode_lock);
+                       kmem_cache_free(inode_entry_slab, entry);
+                       goto done;
                }
        }
        spin_unlock(&sbi->dir_inode_lock);
 
+done:
        /* Only from the recovery routine */
        if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) {
                clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT);
@@ -554,15 +646,14 @@ void remove_dirty_dir_inode(struct inode *inode)
 struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino)
 {
 
-       struct list_head *this, *head;
+       struct list_head *head;
        struct inode *inode = NULL;
+       struct dir_inode_entry *entry;
 
        spin_lock(&sbi->dir_inode_lock);
 
        head = &sbi->dir_inode_list;
-       list_for_each(this, head) {
-               struct dir_inode_entry *entry;
-               entry = list_entry(this, struct dir_inode_entry, list);
+       list_for_each_entry(entry, head, list) {
                if (entry->inode->i_ino == ino) {
                        inode = entry->inode;
                        break;
@@ -589,7 +680,7 @@ retry:
        inode = igrab(entry->inode);
        spin_unlock(&sbi->dir_inode_lock);
        if (inode) {
-               filemap_flush(inode->i_mapping);
+               filemap_fdatawrite(inode->i_mapping);
                iput(inode);
        } else {
                /*
@@ -824,6 +915,7 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
        unblock_operations(sbi);
        mutex_unlock(&sbi->cp_mutex);
 
+       stat_inc_cp_count(sbi->stat_info);
        trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish checkpoint");
 }
 
@@ -845,11 +937,11 @@ void init_orphan_info(struct f2fs_sb_info *sbi)
 int __init create_checkpoint_caches(void)
 {
        orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry",
-                       sizeof(struct orphan_inode_entry), NULL);
+                       sizeof(struct orphan_inode_entry));
        if (!orphan_entry_slab)
                return -ENOMEM;
        inode_entry_slab = f2fs_kmem_cache_create("f2fs_dirty_dir_entry",
-                       sizeof(struct dir_inode_entry), NULL);
+                       sizeof(struct dir_inode_entry));
        if (!inode_entry_slab) {
                kmem_cache_destroy(orphan_entry_slab);
                return -ENOMEM;
index 2261ccdd0b5f04a37be390f1b28c8703fafa86b4..45abd60e2bff54323139b037ed1bccd1e534e96e 100644 (file)
@@ -45,7 +45,7 @@ static void f2fs_read_end_io(struct bio *bio, int err)
 
 static void f2fs_write_end_io(struct bio *bio, int err)
 {
-       struct f2fs_sb_info *sbi = F2FS_SB(bio->bi_io_vec->bv_page->mapping->host->i_sb);
+       struct f2fs_sb_info *sbi = bio->bi_private;
        struct bio_vec *bvec;
        int i;
 
@@ -55,15 +55,16 @@ static void f2fs_write_end_io(struct bio *bio, int err)
                if (unlikely(err)) {
                        SetPageError(page);
                        set_bit(AS_EIO, &page->mapping->flags);
-                       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
-                       sbi->sb->s_flags |= MS_RDONLY;
+                       f2fs_stop_checkpoint(sbi);
                }
                end_page_writeback(page);
                dec_page_count(sbi, F2FS_WRITEBACK);
        }
 
-       if (bio->bi_private)
-               complete(bio->bi_private);
+       if (sbi->wait_io) {
+               complete(sbi->wait_io);
+               sbi->wait_io = NULL;
+       }
 
        if (!get_pages(sbi, F2FS_WRITEBACK) &&
                        !list_empty(&sbi->cp_wait.task_list))
@@ -86,6 +87,7 @@ static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr,
        bio->bi_bdev = sbi->sb->s_bdev;
        bio->bi_iter.bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
        bio->bi_end_io = is_read ? f2fs_read_end_io : f2fs_write_end_io;
+       bio->bi_private = sbi;
 
        return bio;
 }
@@ -113,7 +115,7 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
                 */
                if (fio->type == META_FLUSH) {
                        DECLARE_COMPLETION_ONSTACK(wait);
-                       io->bio->bi_private = &wait;
+                       io->sbi->wait_io = &wait;
                        submit_bio(rw, io->bio);
                        wait_for_completion(&wait);
                } else {
@@ -132,7 +134,7 @@ void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
 
        io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype];
 
-       mutex_lock(&io->io_mutex);
+       down_write(&io->io_rwsem);
 
        /* change META to META_FLUSH in the checkpoint procedure */
        if (type >= META_FLUSH) {
@@ -140,7 +142,7 @@ void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
                io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO;
        }
        __submit_merged_bio(io);
-       mutex_unlock(&io->io_mutex);
+       up_write(&io->io_rwsem);
 }
 
 /*
@@ -178,7 +180,7 @@ void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page,
 
        verify_block_addr(sbi, blk_addr);
 
-       mutex_lock(&io->io_mutex);
+       down_write(&io->io_rwsem);
 
        if (!is_read)
                inc_page_count(sbi, F2FS_WRITEBACK);
@@ -202,7 +204,7 @@ alloc_new:
 
        io->last_block_in_bio = blk_addr;
 
-       mutex_unlock(&io->io_mutex);
+       up_write(&io->io_rwsem);
        trace_f2fs_submit_page_mbio(page, fio->rw, fio->type, blk_addr);
 }
 
@@ -797,48 +799,36 @@ static int f2fs_write_data_page(struct page *page,
         */
        offset = i_size & (PAGE_CACHE_SIZE - 1);
        if ((page->index >= end_index + 1) || !offset) {
-               if (S_ISDIR(inode->i_mode)) {
-                       dec_page_count(sbi, F2FS_DIRTY_DENTS);
-                       inode_dec_dirty_dents(inode);
-               }
+               inode_dec_dirty_dents(inode);
                goto out;
        }
 
        zero_user_segment(page, offset, PAGE_CACHE_SIZE);
 write:
-       if (unlikely(sbi->por_doing)) {
-               err = AOP_WRITEPAGE_ACTIVATE;
+       if (unlikely(sbi->por_doing))
                goto redirty_out;
-       }
 
        /* Dentry blocks are controlled by checkpoint */
        if (S_ISDIR(inode->i_mode)) {
-               dec_page_count(sbi, F2FS_DIRTY_DENTS);
                inode_dec_dirty_dents(inode);
                err = do_write_data_page(page, &fio);
-       } else {
-               f2fs_lock_op(sbi);
-
-               if (f2fs_has_inline_data(inode) || f2fs_may_inline(inode)) {
-                       err = f2fs_write_inline_data(inode, page, offset);
-                       f2fs_unlock_op(sbi);
-                       goto out;
-               } else {
-                       err = do_write_data_page(page, &fio);
-               }
+               goto done;
+       }
 
-               f2fs_unlock_op(sbi);
+       if (!wbc->for_reclaim)
                need_balance_fs = true;
-       }
-       if (err == -ENOENT)
-               goto out;
-       else if (err)
+       else if (has_not_enough_free_secs(sbi, 0))
                goto redirty_out;
 
-       if (wbc->for_reclaim) {
-               f2fs_submit_merged_bio(sbi, DATA, WRITE);
-               need_balance_fs = false;
-       }
+       f2fs_lock_op(sbi);
+       if (f2fs_has_inline_data(inode) || f2fs_may_inline(inode))
+               err = f2fs_write_inline_data(inode, page, offset);
+       else
+               err = do_write_data_page(page, &fio);
+       f2fs_unlock_op(sbi);
+done:
+       if (err && err != -ENOENT)
+               goto redirty_out;
 
        clear_cold_data(page);
 out:
@@ -849,12 +839,11 @@ out:
 
 redirty_out:
        wbc->pages_skipped++;
+       account_page_redirty(page);
        set_page_dirty(page);
-       return err;
+       return AOP_WRITEPAGE_ACTIVATE;
 }
 
-#define MAX_DESIRED_PAGES_WP   4096
-
 static int __f2fs_writepage(struct page *page, struct writeback_control *wbc,
                        void *data)
 {
@@ -871,17 +860,17 @@ static int f2fs_write_data_pages(struct address_space *mapping,
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        bool locked = false;
        int ret;
-       long excess_nrtw = 0, desired_nrtw;
+       long diff;
 
        /* deal with chardevs and other special file */
        if (!mapping->a_ops->writepage)
                return 0;
 
-       if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) {
-               desired_nrtw = MAX_DESIRED_PAGES_WP;
-               excess_nrtw = desired_nrtw - wbc->nr_to_write;
-               wbc->nr_to_write = desired_nrtw;
-       }
+       if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
+                       get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA))
+               goto skip_write;
+
+       diff = nr_pages_to_write(sbi, DATA, wbc);
 
        if (!S_ISDIR(inode->i_mode)) {
                mutex_lock(&sbi->writepages);
@@ -895,8 +884,12 @@ static int f2fs_write_data_pages(struct address_space *mapping,
 
        remove_dirty_dir_inode(inode);
 
-       wbc->nr_to_write -= excess_nrtw;
+       wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff);
        return ret;
+
+skip_write:
+       wbc->pages_skipped += get_dirty_dents(inode);
+       return 0;
 }
 
 static int f2fs_write_begin(struct file *file, struct address_space *mapping,
@@ -949,13 +942,19 @@ inline_data:
        if (dn.data_blkaddr == NEW_ADDR) {
                zero_user_segment(page, 0, PAGE_CACHE_SIZE);
        } else {
-               if (f2fs_has_inline_data(inode))
+               if (f2fs_has_inline_data(inode)) {
                        err = f2fs_read_inline_data(inode, page);
-               else
+                       if (err) {
+                               page_cache_release(page);
+                               return err;
+                       }
+               } else {
                        err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr,
                                                        READ_SYNC);
-               if (err)
-                       return err;
+                       if (err)
+                               return err;
+               }
+
                lock_page(page);
                if (unlikely(!PageUptodate(page))) {
                        f2fs_put_page(page, 1);
@@ -1031,11 +1030,8 @@ static void f2fs_invalidate_data_page(struct page *page, unsigned int offset,
                                      unsigned int length)
 {
        struct inode *inode = page->mapping->host;
-       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       if (S_ISDIR(inode->i_mode) && PageDirty(page)) {
-               dec_page_count(sbi, F2FS_DIRTY_DENTS);
+       if (PageDirty(page))
                inode_dec_dirty_dents(inode);
-       }
        ClearPagePrivate(page);
 }
 
index 3de9d20d0c14afcc6f96462bae23be6c488df570..b52c12cf5873af10702f7b1afce7ed3b53f0c709 100644 (file)
@@ -86,7 +86,6 @@ static void update_sit_info(struct f2fs_sb_info *sbi)
 {
        struct f2fs_stat_info *si = F2FS_STAT(sbi);
        unsigned int blks_per_sec, hblks_per_sec, total_vblocks, bimodal, dist;
-       struct sit_info *sit_i = SIT_I(sbi);
        unsigned int segno, vblocks;
        int ndirty = 0;
 
@@ -94,7 +93,6 @@ static void update_sit_info(struct f2fs_sb_info *sbi)
        total_vblocks = 0;
        blks_per_sec = sbi->segs_per_sec * (1 << sbi->log_blocks_per_seg);
        hblks_per_sec = blks_per_sec / 2;
-       mutex_lock(&sit_i->sentry_lock);
        for (segno = 0; segno < TOTAL_SEGS(sbi); segno += sbi->segs_per_sec) {
                vblocks = get_valid_blocks(sbi, segno, sbi->segs_per_sec);
                dist = abs(vblocks - hblks_per_sec);
@@ -105,7 +103,6 @@ static void update_sit_info(struct f2fs_sb_info *sbi)
                        ndirty++;
                }
        }
-       mutex_unlock(&sit_i->sentry_lock);
        dist = TOTAL_SECS(sbi) * hblks_per_sec * hblks_per_sec / 100;
        si->bimodal = bimodal / dist;
        if (si->dirty_count)
@@ -236,6 +233,7 @@ static int stat_show(struct seq_file *s, void *v)
                           si->dirty_count);
                seq_printf(s, "  - Prefree: %d\n  - Free: %d (%d)\n\n",
                           si->prefree_count, si->free_segs, si->free_secs);
+               seq_printf(s, "CP calls: %d\n", si->cp_count);
                seq_printf(s, "GC calls: %d (BG: %d)\n",
                           si->call_count, si->bg_gc);
                seq_printf(s, "  - data segments : %d\n", si->data_segs);
@@ -252,10 +250,10 @@ static int stat_show(struct seq_file *s, void *v)
                           si->ndirty_dent, si->ndirty_dirs);
                seq_printf(s, "  - meta: %4d in %4d\n",
                           si->ndirty_meta, si->meta_pages);
-               seq_printf(s, "  - NATs: %5d > %lu\n",
-                          si->nats, NM_WOUT_THRESHOLD);
-               seq_printf(s, "  - SITs: %5d\n  - free_nids: %5d\n",
-                          si->sits, si->fnids);
+               seq_printf(s, "  - NATs: %9d\n  - SITs: %9d\n",
+                          si->nats, si->sits);
+               seq_printf(s, "  - free_nids: %9d\n",
+                          si->fnids);
                seq_puts(s, "\nDistribution of User Blocks:");
                seq_puts(s, " [ valid | invalid | free ]\n");
                seq_puts(s, "  [");
index 2b7c255bcbdfffa259a5d0a45b9207626e455d79..972fd0ef230f9aff12f877a4f056980ad07757f3 100644 (file)
@@ -21,12 +21,12 @@ static unsigned long dir_blocks(struct inode *inode)
                                                        >> PAGE_CACHE_SHIFT;
 }
 
-static unsigned int dir_buckets(unsigned int level)
+static unsigned int dir_buckets(unsigned int level, int dir_level)
 {
        if (level < MAX_DIR_HASH_DEPTH / 2)
-               return 1 << level;
+               return 1 << (level + dir_level);
        else
-               return 1 << ((MAX_DIR_HASH_DEPTH / 2) - 1);
+               return 1 << ((MAX_DIR_HASH_DEPTH / 2 + dir_level) - 1);
 }
 
 static unsigned int bucket_blocks(unsigned int level)
@@ -65,13 +65,14 @@ static void set_de_type(struct f2fs_dir_entry *de, struct inode *inode)
        de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
 }
 
-static unsigned long dir_block_index(unsigned int level, unsigned int idx)
+static unsigned long dir_block_index(unsigned int level,
+                               int dir_level, unsigned int idx)
 {
        unsigned long i;
        unsigned long bidx = 0;
 
        for (i = 0; i < level; i++)
-               bidx += dir_buckets(i) * bucket_blocks(i);
+               bidx += dir_buckets(i, dir_level) * bucket_blocks(i);
        bidx += idx * bucket_blocks(level);
        return bidx;
 }
@@ -93,16 +94,21 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
                        f2fs_hash_t namehash, struct page **res_page)
 {
        struct f2fs_dir_entry *de;
-       unsigned long bit_pos, end_pos, next_pos;
+       unsigned long bit_pos = 0;
        struct f2fs_dentry_block *dentry_blk = kmap(dentry_page);
-       int slots;
+       const void *dentry_bits = &dentry_blk->dentry_bitmap;
+       int max_len = 0;
 
-       bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
-                                       NR_DENTRY_IN_BLOCK, 0);
        while (bit_pos < NR_DENTRY_IN_BLOCK) {
+               if (!test_bit_le(bit_pos, dentry_bits)) {
+                       if (bit_pos == 0)
+                               max_len = 1;
+                       else if (!test_bit_le(bit_pos - 1, dentry_bits))
+                               max_len++;
+                       bit_pos++;
+                       continue;
+               }
                de = &dentry_blk->dentry[bit_pos];
-               slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
-
                if (early_match_name(name, namelen, namehash, de)) {
                        if (!memcmp(dentry_blk->filename[bit_pos],
                                                        name, namelen)) {
@@ -110,20 +116,18 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
                                goto found;
                        }
                }
-               next_pos = bit_pos + slots;
-               bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
-                               NR_DENTRY_IN_BLOCK, next_pos);
-               if (bit_pos >= NR_DENTRY_IN_BLOCK)
-                       end_pos = NR_DENTRY_IN_BLOCK;
-               else
-                       end_pos = bit_pos;
-               if (*max_slots < end_pos - next_pos)
-                       *max_slots = end_pos - next_pos;
+               if (max_len > *max_slots) {
+                       *max_slots = max_len;
+                       max_len = 0;
+               }
+               bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
        }
 
        de = NULL;
        kunmap(dentry_page);
 found:
+       if (max_len > *max_slots)
+               *max_slots = max_len;
        return de;
 }
 
@@ -141,10 +145,11 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
 
        f2fs_bug_on(level > MAX_DIR_HASH_DEPTH);
 
-       nbucket = dir_buckets(level);
+       nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level);
        nblock = bucket_blocks(level);
 
-       bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket);
+       bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level,
+                                       le32_to_cpu(namehash) % nbucket);
        end_block = bidx + nblock;
 
        for (; bidx < end_block; bidx++) {
@@ -248,7 +253,7 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
                struct page *page, struct inode *inode)
 {
        lock_page(page);
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
        de->ino = cpu_to_le32(inode->i_ino);
        set_de_type(de, inode);
        kunmap(page);
@@ -347,14 +352,11 @@ static struct page *init_inode_metadata(struct inode *inode,
                err = f2fs_init_security(inode, dir, name, page);
                if (err)
                        goto put_error;
-
-               wait_on_page_writeback(page);
        } else {
                page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
                if (IS_ERR(page))
                        return page;
 
-               wait_on_page_writeback(page);
                set_cold_node(inode, page);
        }
 
@@ -372,6 +374,10 @@ static struct page *init_inode_metadata(struct inode *inode,
 
 put_error:
        f2fs_put_page(page, 1);
+       /* once the failed inode becomes a bad inode, i_mode is S_IFREG */
+       truncate_inode_pages(&inode->i_data, 0);
+       truncate_blocks(inode, 0);
+       remove_dirty_dir_inode(inode);
 error:
        remove_inode_page(inode);
        return ERR_PTR(err);
@@ -395,9 +401,6 @@ static void update_parent_metadata(struct inode *dir, struct inode *inode,
                set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
        }
 
-       if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR))
-               update_inode_page(dir);
-
        if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK))
                clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
 }
@@ -464,10 +467,11 @@ start:
        if (level == current_depth)
                ++current_depth;
 
-       nbucket = dir_buckets(level);
+       nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level);
        nblock = bucket_blocks(level);
 
-       bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket));
+       bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level,
+                               (le32_to_cpu(dentry_hash) % nbucket));
 
        for (block = bidx; block <= (bidx + nblock - 1); block++) {
                dentry_page = get_new_data_page(dir, NULL, block, true);
@@ -487,8 +491,9 @@ start:
        ++level;
        goto start;
 add_dentry:
-       wait_on_page_writeback(dentry_page);
+       f2fs_wait_on_page_writeback(dentry_page, DATA);
 
+       down_write(&F2FS_I(inode)->i_sem);
        page = init_inode_metadata(inode, dir, name);
        if (IS_ERR(page)) {
                err = PTR_ERR(page);
@@ -511,7 +516,12 @@ add_dentry:
 
        update_parent_metadata(dir, inode, current_depth);
 fail:
-       clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
+       up_write(&F2FS_I(inode)->i_sem);
+
+       if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) {
+               update_inode_page(dir);
+               clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
+       }
        kunmap(dentry_page);
        f2fs_put_page(dentry_page, 1);
        return err;
@@ -528,13 +538,12 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
        unsigned int bit_pos;
        struct address_space *mapping = page->mapping;
        struct inode *dir = mapping->host;
-       struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
        int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
        void *kaddr = page_address(page);
        int i;
 
        lock_page(page);
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
 
        dentry_blk = (struct f2fs_dentry_block *)kaddr;
        bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry;
@@ -551,6 +560,10 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 
        if (inode) {
+               struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
+
+               down_write(&F2FS_I(inode)->i_sem);
+
                if (S_ISDIR(inode->i_mode)) {
                        drop_nlink(dir);
                        update_inode_page(dir);
@@ -561,6 +574,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
                        drop_nlink(inode);
                        i_size_write(inode, 0);
                }
+               up_write(&F2FS_I(inode)->i_sem);
                update_inode_page(inode);
 
                if (inode->i_nlink == 0)
@@ -573,7 +587,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
                truncate_hole(dir, page->index, page->index + 1);
                clear_page_dirty_for_io(page);
                ClearPageUptodate(page);
-               dec_page_count(sbi, F2FS_DIRTY_DENTS);
                inode_dec_dirty_dents(dir);
        }
        f2fs_put_page(page, 1);
index fc3c558cb4f3d5a71b8ed03016e838cf5ec84cdf..2ecac8312359062268986adfe894f6320379bdd4 100644 (file)
@@ -40,6 +40,7 @@
 #define F2FS_MOUNT_DISABLE_EXT_IDENTIFY        0x00000040
 #define F2FS_MOUNT_INLINE_XATTR                0x00000080
 #define F2FS_MOUNT_INLINE_DATA         0x00000100
+#define F2FS_MOUNT_FLUSH_MERGE         0x00000200
 
 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option)
 #define set_opt(sbi, option)   (sbi->mount_opt.opt |= F2FS_MOUNT_##option)
@@ -88,6 +89,16 @@ enum {
        SIT_BITMAP
 };
 
+/*
+ * For CP/NAT/SIT/SSA readahead
+ */
+enum {
+       META_CP,
+       META_NAT,
+       META_SIT,
+       META_SSA
+};
+
 /* for the list of orphan inodes */
 struct orphan_inode_entry {
        struct list_head list;  /* list head */
@@ -187,16 +198,20 @@ struct extent_info {
 #define FADVISE_COLD_BIT       0x01
 #define FADVISE_LOST_PINO_BIT  0x02
 
+#define DEF_DIR_LEVEL          0
+
 struct f2fs_inode_info {
        struct inode vfs_inode;         /* serve a vfs inode */
        unsigned long i_flags;          /* keep an inode flags for ioctl */
        unsigned char i_advise;         /* use to give file attribute hints */
+       unsigned char i_dir_level;      /* use for dentry level for large dir */
        unsigned int i_current_depth;   /* use only in directory structure */
        unsigned int i_pino;            /* parent inode number */
        umode_t i_acl_mode;             /* keep file acl mode temporarily */
 
        /* Use below internally in f2fs*/
        unsigned long flags;            /* use to pass per-file flags */
+       struct rw_semaphore i_sem;      /* protect fi info */
        atomic_t dirty_dents;           /* # of dirty dentry pages */
        f2fs_hash_t chash;              /* hash value of given file name */
        unsigned int clevel;            /* maximum level of given file name */
@@ -229,6 +244,7 @@ struct f2fs_nm_info {
        block_t nat_blkaddr;            /* base disk address of NAT */
        nid_t max_nid;                  /* maximum possible node ids */
        nid_t next_scan_nid;            /* the next nid to be scanned */
+       unsigned int ram_thresh;        /* control the memory footprint */
 
        /* NAT cache management */
        struct radix_tree_root nat_root;/* root of the nat entry cache */
@@ -238,6 +254,7 @@ struct f2fs_nm_info {
        struct list_head dirty_nat_entries; /* cached nat entry list (dirty) */
 
        /* free node ids management */
+       struct radix_tree_root free_nid_root;/* root of the free_nid cache */
        struct list_head free_nid_list; /* a list for free nids */
        spinlock_t free_nid_list_lock;  /* protect free nid list */
        unsigned int fcnt;              /* the number of free node id */
@@ -300,6 +317,12 @@ enum {
        NO_CHECK_TYPE
 };
 
+struct flush_cmd {
+       struct flush_cmd *next;
+       struct completion wait;
+       int ret;
+};
+
 struct f2fs_sm_info {
        struct sit_info *sit_info;              /* whole segment information */
        struct free_segmap_info *free_info;     /* free segment information */
@@ -328,6 +351,14 @@ struct f2fs_sm_info {
 
        unsigned int ipu_policy;        /* in-place-update policy */
        unsigned int min_ipu_util;      /* in-place-update threshold */
+
+       /* for flush command control */
+       struct task_struct *f2fs_issue_flush;   /* flush thread */
+       wait_queue_head_t flush_wait_queue;     /* waiting queue for wake-up */
+       struct flush_cmd *issue_list;           /* list for command issue */
+       struct flush_cmd *dispatch_list;        /* list for command dispatch */
+       spinlock_t issue_lock;                  /* for issue list lock */
+       struct flush_cmd *issue_tail;           /* list tail of issue list */
 };
 
 /*
@@ -378,7 +409,7 @@ struct f2fs_bio_info {
        struct bio *bio;                /* bios to merge */
        sector_t last_block_in_bio;     /* last block number */
        struct f2fs_io_info fio;        /* store buffered io info. */
-       struct mutex io_mutex;          /* mutex for bio */
+       struct rw_semaphore io_rwsem;   /* blocking op for bio */
 };
 
 struct f2fs_sb_info {
@@ -398,6 +429,7 @@ struct f2fs_sb_info {
        /* for bio operations */
        struct f2fs_bio_info read_io;                   /* for read bios */
        struct f2fs_bio_info write_io[NR_PAGE_TYPE];    /* for write bios */
+       struct completion *wait_io;             /* for completion bios */
 
        /* for checkpoint */
        struct f2fs_checkpoint *ckpt;           /* raw checkpoint pointer */
@@ -407,7 +439,6 @@ struct f2fs_sb_info {
        struct mutex node_write;                /* locking node writes */
        struct mutex writepages;                /* mutex for writepages() */
        bool por_doing;                         /* recovery is doing or not */
-       bool on_build_free_nids;                /* build_free_nids is doing */
        wait_queue_head_t cp_wait;
 
        /* for orphan inode management */
@@ -436,6 +467,7 @@ struct f2fs_sb_info {
        unsigned int total_valid_node_count;    /* valid node block count */
        unsigned int total_valid_inode_count;   /* valid inode count */
        int active_logs;                        /* # of active logs */
+       int dir_level;                          /* directory level */
 
        block_t user_block_count;               /* # of user blocks */
        block_t total_valid_block_count;        /* # of valid blocks */
@@ -622,6 +654,11 @@ static inline int F2FS_HAS_BLOCKS(struct inode *inode)
                return inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS;
 }
 
+static inline bool f2fs_has_xattr_block(unsigned int ofs)
+{
+       return ofs == XATTR_NODE_OFFSET;
+}
+
 static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
                                 struct inode *inode, blkcnt_t count)
 {
@@ -661,6 +698,7 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
 
 static inline void inode_inc_dirty_dents(struct inode *inode)
 {
+       inc_page_count(F2FS_SB(inode->i_sb), F2FS_DIRTY_DENTS);
        atomic_inc(&F2FS_I(inode)->dirty_dents);
 }
 
@@ -671,6 +709,10 @@ static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
 
 static inline void inode_dec_dirty_dents(struct inode *inode)
 {
+       if (!S_ISDIR(inode->i_mode))
+               return;
+
+       dec_page_count(F2FS_SB(inode->i_sb), F2FS_DIRTY_DENTS);
        atomic_dec(&F2FS_I(inode)->dirty_dents);
 }
 
@@ -679,6 +721,11 @@ static inline int get_pages(struct f2fs_sb_info *sbi, int count_type)
        return atomic_read(&sbi->nr_pages[count_type]);
 }
 
+static inline int get_dirty_dents(struct inode *inode)
+{
+       return atomic_read(&F2FS_I(inode)->dirty_dents);
+}
+
 static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
 {
        unsigned int pages_per_sec = sbi->segs_per_sec *
@@ -689,11 +736,7 @@ static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
 
 static inline block_t valid_user_blocks(struct f2fs_sb_info *sbi)
 {
-       block_t ret;
-       spin_lock(&sbi->stat_lock);
-       ret = sbi->total_valid_block_count;
-       spin_unlock(&sbi->stat_lock);
-       return ret;
+       return sbi->total_valid_block_count;
 }
 
 static inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag)
@@ -789,11 +832,7 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
 
 static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi)
 {
-       unsigned int ret;
-       spin_lock(&sbi->stat_lock);
-       ret = sbi->total_valid_node_count;
-       spin_unlock(&sbi->stat_lock);
-       return ret;
+       return sbi->total_valid_node_count;
 }
 
 static inline void inc_valid_inode_count(struct f2fs_sb_info *sbi)
@@ -814,11 +853,7 @@ static inline void dec_valid_inode_count(struct f2fs_sb_info *sbi)
 
 static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
 {
-       unsigned int ret;
-       spin_lock(&sbi->stat_lock);
-       ret = sbi->total_valid_inode_count;
-       spin_unlock(&sbi->stat_lock);
-       return ret;
+       return sbi->total_valid_inode_count;
 }
 
 static inline void f2fs_put_page(struct page *page, int unlock)
@@ -844,9 +879,9 @@ static inline void f2fs_put_dnode(struct dnode_of_data *dn)
 }
 
 static inline struct kmem_cache *f2fs_kmem_cache_create(const char *name,
-                                       size_t size, void (*ctor)(void *))
+                                       size_t size)
 {
-       return kmem_cache_create(name, size, 0, SLAB_RECLAIM_ACCOUNT, ctor);
+       return kmem_cache_create(name, size, 0, SLAB_RECLAIM_ACCOUNT, NULL);
 }
 
 static inline void *f2fs_kmem_cache_alloc(struct kmem_cache *cachep,
@@ -983,24 +1018,28 @@ static inline void set_raw_inline(struct f2fs_inode_info *fi,
                ri->i_inline |= F2FS_INLINE_DATA;
 }
 
+static inline int f2fs_has_inline_xattr(struct inode *inode)
+{
+       return is_inode_flag_set(F2FS_I(inode), FI_INLINE_XATTR);
+}
+
 static inline unsigned int addrs_per_inode(struct f2fs_inode_info *fi)
 {
-       if (is_inode_flag_set(fi, FI_INLINE_XATTR))
+       if (f2fs_has_inline_xattr(&fi->vfs_inode))
                return DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS;
        return DEF_ADDRS_PER_INODE;
 }
 
 static inline void *inline_xattr_addr(struct page *page)
 {
-       struct f2fs_inode *ri;
-       ri = (struct f2fs_inode *)page_address(page);
+       struct f2fs_inode *ri = F2FS_INODE(page);
        return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE -
                                        F2FS_INLINE_XATTR_ADDRS]);
 }
 
 static inline int inline_xattr_size(struct inode *inode)
 {
-       if (is_inode_flag_set(F2FS_I(inode), FI_INLINE_XATTR))
+       if (f2fs_has_inline_xattr(inode))
                return F2FS_INLINE_XATTR_ADDRS << 2;
        else
                return 0;
@@ -1013,8 +1052,7 @@ static inline int f2fs_has_inline_data(struct inode *inode)
 
 static inline void *inline_data_addr(struct page *page)
 {
-       struct f2fs_inode *ri;
-       ri = (struct f2fs_inode *)page_address(page);
+       struct f2fs_inode *ri = F2FS_INODE(page);
        return (void *)&(ri->i_addr[1]);
 }
 
@@ -1023,6 +1061,12 @@ static inline int f2fs_readonly(struct super_block *sb)
        return sb->s_flags & MS_RDONLY;
 }
 
+static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi)
+{
+       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
+       sbi->sb->s_flags |= MS_RDONLY;
+}
+
 #define get_inode_mode(i) \
        ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
         (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
@@ -1048,7 +1092,7 @@ void f2fs_set_inode_flags(struct inode *);
 struct inode *f2fs_iget(struct super_block *, unsigned long);
 int try_to_free_nats(struct f2fs_sb_info *, int);
 void update_inode(struct inode *, struct page *);
-int update_inode_page(struct inode *);
+void update_inode_page(struct inode *);
 int f2fs_write_inode(struct inode *, struct writeback_control *);
 void f2fs_evict_inode(struct inode *);
 
@@ -1097,6 +1141,7 @@ struct dnode_of_data;
 struct node_info;
 
 int is_checkpointed_node(struct f2fs_sb_info *, nid_t);
+bool fsync_mark_done(struct f2fs_sb_info *, nid_t);
 void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
 int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
 int truncate_inode_blocks(struct inode *, pgoff_t);
@@ -1115,6 +1160,7 @@ void alloc_nid_done(struct f2fs_sb_info *, nid_t);
 void alloc_nid_failed(struct f2fs_sb_info *, nid_t);
 void recover_node_page(struct f2fs_sb_info *, struct page *,
                struct f2fs_summary *, struct node_info *, block_t);
+bool recover_xattr_data(struct inode *, struct page *, block_t);
 int recover_inode_page(struct f2fs_sb_info *, struct page *);
 int restore_node_summary(struct f2fs_sb_info *, unsigned int,
                                struct f2fs_summary_block *);
@@ -1129,7 +1175,9 @@ void destroy_node_manager_caches(void);
  */
 void f2fs_balance_fs(struct f2fs_sb_info *);
 void f2fs_balance_fs_bg(struct f2fs_sb_info *);
+int f2fs_issue_flush(struct f2fs_sb_info *);
 void invalidate_blocks(struct f2fs_sb_info *, block_t);
+void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t);
 void clear_prefree_segments(struct f2fs_sb_info *);
 int npages_for_summary_flush(struct f2fs_sb_info *);
 void allocate_new_segments(struct f2fs_sb_info *);
@@ -1162,6 +1210,7 @@ void destroy_segment_manager_caches(void);
  */
 struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t);
+int ra_meta_pages(struct f2fs_sb_info *, int, int, int);
 long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
 int acquire_orphan_inode(struct f2fs_sb_info *);
 void release_orphan_inode(struct f2fs_sb_info *);
@@ -1231,7 +1280,7 @@ struct f2fs_stat_info {
        int util_free, util_valid, util_invalid;
        int rsvd_segs, overp_segs;
        int dirty_count, node_pages, meta_pages;
-       int prefree_count, call_count;
+       int prefree_count, call_count, cp_count;
        int tot_segs, node_segs, data_segs, free_segs, free_secs;
        int tot_blks, data_blks, node_blks;
        int curseg[NR_CURSEG_TYPE];
@@ -1248,6 +1297,7 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
        return (struct f2fs_stat_info *)sbi->stat_info;
 }
 
+#define stat_inc_cp_count(si)          ((si)->cp_count++)
 #define stat_inc_call_count(si)                ((si)->call_count++)
 #define stat_inc_bggc_count(sbi)       ((sbi)->bg_gc++)
 #define stat_inc_dirty_dir(sbi)                ((sbi)->n_dirty_dirs++)
@@ -1302,6 +1352,7 @@ void f2fs_destroy_stats(struct f2fs_sb_info *);
 void __init f2fs_create_root_stats(void);
 void f2fs_destroy_root_stats(void);
 #else
+#define stat_inc_cp_count(si)
 #define stat_inc_call_count(si)
 #define stat_inc_bggc_count(si)
 #define stat_inc_dirty_dir(sbi)
index 0dfcef53a6ed830e442f8c174ea166b0d1b2eabd..302d552afea5c161624d0e1caaa90c2d3f1f75d7 100644 (file)
@@ -76,7 +76,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        trace_f2fs_vm_page_mkwrite(page, DATA);
 mapped:
        /* fill the page */
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
 out:
        sb_end_pagefault(inode->i_sb);
        return block_page_mkwrite_return(err);
@@ -111,11 +111,12 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)
 int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 {
        struct inode *inode = file->f_mapping->host;
+       struct f2fs_inode_info *fi = F2FS_I(inode);
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        int ret = 0;
        bool need_cp = false;
        struct writeback_control wbc = {
-               .sync_mode = WB_SYNC_NONE,
+               .sync_mode = WB_SYNC_ALL,
                .nr_to_write = LONG_MAX,
                .for_reclaim = 0,
        };
@@ -133,7 +134,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        /* guarantee free sections for fsync */
        f2fs_balance_fs(sbi);
 
-       mutex_lock(&inode->i_mutex);
+       down_read(&fi->i_sem);
 
        /*
         * Both of fdatasync() and fsync() are able to be recovered from
@@ -150,25 +151,33 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        else if (F2FS_I(inode)->xattr_ver == cur_cp_version(F2FS_CKPT(sbi)))
                need_cp = true;
 
+       up_read(&fi->i_sem);
+
        if (need_cp) {
                nid_t pino;
 
-               F2FS_I(inode)->xattr_ver = 0;
-
                /* all the dirty node pages should be flushed for POR */
                ret = f2fs_sync_fs(inode->i_sb, 1);
+
+               down_write(&fi->i_sem);
+               F2FS_I(inode)->xattr_ver = 0;
                if (file_wrong_pino(inode) && inode->i_nlink == 1 &&
                                        get_parent_ino(inode, &pino)) {
                        F2FS_I(inode)->i_pino = pino;
                        file_got_pino(inode);
+                       up_write(&fi->i_sem);
                        mark_inode_dirty_sync(inode);
                        ret = f2fs_write_inode(inode, NULL);
                        if (ret)
                                goto out;
+               } else {
+                       up_write(&fi->i_sem);
                }
        } else {
                /* if there is no written node page, write its inode page */
                while (!sync_node_pages(sbi, inode->i_ino, &wbc)) {
+                       if (fsync_mark_done(sbi, inode->i_ino))
+                               goto out;
                        mark_inode_dirty_sync(inode);
                        ret = f2fs_write_inode(inode, NULL);
                        if (ret)
@@ -177,10 +186,9 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                ret = wait_on_node_pages_writeback(sbi, inode->i_ino);
                if (ret)
                        goto out;
-               ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+               ret = f2fs_issue_flush(F2FS_SB(inode->i_sb));
        }
 out:
-       mutex_unlock(&inode->i_mutex);
        trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret);
        return ret;
 }
@@ -245,7 +253,7 @@ static void truncate_partial_data_page(struct inode *inode, u64 from)
                f2fs_put_page(page, 1);
                return;
        }
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
        zero_user(page, offset, PAGE_CACHE_SIZE - offset);
        set_page_dirty(page);
        f2fs_put_page(page, 1);
@@ -422,7 +430,7 @@ static void fill_zero(struct inode *inode, pgoff_t index,
        f2fs_unlock_op(sbi);
 
        if (!IS_ERR(page)) {
-               wait_on_page_writeback(page);
+               f2fs_wait_on_page_writeback(page, DATA);
                zero_user(page, start, len);
                set_page_dirty(page);
                f2fs_put_page(page, 1);
@@ -560,6 +568,8 @@ static long f2fs_fallocate(struct file *file, int mode,
        if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
                return -EOPNOTSUPP;
 
+       mutex_lock(&inode->i_mutex);
+
        if (mode & FALLOC_FL_PUNCH_HOLE)
                ret = punch_hole(inode, offset, len);
        else
@@ -569,6 +579,9 @@ static long f2fs_fallocate(struct file *file, int mode,
                inode->i_mtime = inode->i_ctime = CURRENT_TIME;
                mark_inode_dirty(inode);
        }
+
+       mutex_unlock(&inode->i_mutex);
+
        trace_f2fs_fallocate(inode, mode, offset, len, ret);
        return ret;
 }
index ea0371e854b4e0244537cf3d33f5f17e147e8a25..b90dbe55403a4dbd0c1504c399a2285d416b6063 100644 (file)
@@ -531,15 +531,10 @@ static void move_data_page(struct inode *inode, struct page *page, int gc_type)
                set_page_dirty(page);
                set_cold_data(page);
        } else {
-               struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-
                f2fs_wait_on_page_writeback(page, DATA);
 
-               if (clear_page_dirty_for_io(page) &&
-                       S_ISDIR(inode->i_mode)) {
-                       dec_page_count(sbi, F2FS_DIRTY_DENTS);
+               if (clear_page_dirty_for_io(page))
                        inode_dec_dirty_dents(inode);
-               }
                set_cold_data(page);
                do_write_data_page(page, &fio);
                clear_cold_data(page);
@@ -701,6 +696,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi)
 gc_more:
        if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE)))
                goto stop;
+       if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
+               goto stop;
 
        if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) {
                gc_type = FG_GC;
@@ -711,6 +708,11 @@ gc_more:
                goto stop;
        ret = 0;
 
+       /* readahead multi ssa blocks those have contiguous address */
+       if (sbi->segs_per_sec > 1)
+               ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), sbi->segs_per_sec,
+                                                               META_SSA);
+
        for (i = 0; i < sbi->segs_per_sec; i++)
                do_garbage_collect(sbi, segno + i, &ilist, gc_type);
 
@@ -740,7 +742,7 @@ void build_gc_manager(struct f2fs_sb_info *sbi)
 int __init create_gc_caches(void)
 {
        winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes",
-                       sizeof(struct inode_entry), NULL);
+                       sizeof(struct inode_entry));
        if (!winode_slab)
                return -ENOMEM;
        return 0;
index 31ee5b164ff9f0ee27fa291bbd45df49e0da8d80..383db1fabcf4447637fd4153915e9512054b27ac 100644 (file)
@@ -45,8 +45,10 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
        }
 
        ipage = get_node_page(sbi, inode->i_ino);
-       if (IS_ERR(ipage))
+       if (IS_ERR(ipage)) {
+               unlock_page(page);
                return PTR_ERR(ipage);
+       }
 
        zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE);
 
index 28cea76d78c610eb0b5584aacda41e5ea975de5a..ee829d360468597f3619b5ef1b3719b1fd942516 100644 (file)
@@ -107,6 +107,7 @@ static int do_read_inode(struct inode *inode)
        fi->flags = 0;
        fi->i_advise = ri->i_advise;
        fi->i_pino = le32_to_cpu(ri->i_pino);
+       fi->i_dir_level = ri->i_dir_level;
 
        get_extent_info(&fi->ext, ri->i_ext);
        get_inline_info(fi, ri);
@@ -204,6 +205,7 @@ void update_inode(struct inode *inode, struct page *node_page)
        ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags);
        ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino);
        ri->i_generation = cpu_to_le32(inode->i_generation);
+       ri->i_dir_level = F2FS_I(inode)->i_dir_level;
 
        __set_inode_rdev(inode, ri);
        set_cold_node(inode, node_page);
@@ -212,24 +214,29 @@ void update_inode(struct inode *inode, struct page *node_page)
        clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE);
 }
 
-int update_inode_page(struct inode *inode)
+void update_inode_page(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct page *node_page;
-
+retry:
        node_page = get_node_page(sbi, inode->i_ino);
-       if (IS_ERR(node_page))
-               return PTR_ERR(node_page);
-
+       if (IS_ERR(node_page)) {
+               int err = PTR_ERR(node_page);
+               if (err == -ENOMEM) {
+                       cond_resched();
+                       goto retry;
+               } else if (err != -ENOENT) {
+                       f2fs_stop_checkpoint(sbi);
+               }
+               return;
+       }
        update_inode(inode, node_page);
        f2fs_put_page(node_page, 1);
-       return 0;
 }
 
 int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
-       int ret;
 
        if (inode->i_ino == F2FS_NODE_INO(sbi) ||
                        inode->i_ino == F2FS_META_INO(sbi))
@@ -243,13 +250,13 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
         * during the urgent cleaning time when runing out of free sections.
         */
        f2fs_lock_op(sbi);
-       ret = update_inode_page(inode);
+       update_inode_page(inode);
        f2fs_unlock_op(sbi);
 
        if (wbc)
                f2fs_balance_fs(sbi);
 
-       return ret;
+       return 0;
 }
 
 /*
@@ -266,7 +273,7 @@ void f2fs_evict_inode(struct inode *inode)
                        inode->i_ino == F2FS_META_INO(sbi))
                goto no_delete;
 
-       f2fs_bug_on(atomic_read(&F2FS_I(inode)->dirty_dents));
+       f2fs_bug_on(get_dirty_dents(inode));
        remove_dirty_dir_inode(inode);
 
        if (inode->i_nlink || is_bad_inode(inode))
index 397d459e97bf9f1ee2107c1079f02a282a47e5fa..a9409d19dfd4815f38907b93f84ad3428383b07a 100644 (file)
@@ -207,6 +207,8 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
                inode = f2fs_iget(dir->i_sb, ino);
                if (IS_ERR(inode))
                        return ERR_CAST(inode);
+
+               stat_inc_inline_inode(inode);
        }
 
        return d_splice_alias(inode, dentry);
@@ -424,12 +426,17 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                }
 
                f2fs_set_link(new_dir, new_entry, new_page, old_inode);
+               down_write(&F2FS_I(old_inode)->i_sem);
                F2FS_I(old_inode)->i_pino = new_dir->i_ino;
+               up_write(&F2FS_I(old_inode)->i_sem);
 
                new_inode->i_ctime = CURRENT_TIME;
+               down_write(&F2FS_I(new_inode)->i_sem);
                if (old_dir_entry)
                        drop_nlink(new_inode);
                drop_nlink(new_inode);
+               up_write(&F2FS_I(new_inode)->i_sem);
+
                mark_inode_dirty(new_inode);
 
                if (!new_inode->i_nlink)
@@ -459,7 +466,9 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (old_dir != new_dir) {
                        f2fs_set_link(old_inode, old_dir_entry,
                                                old_dir_page, new_dir);
+                       down_write(&F2FS_I(old_inode)->i_sem);
                        F2FS_I(old_inode)->i_pino = new_dir->i_ino;
+                       up_write(&F2FS_I(old_inode)->i_sem);
                        update_inode_page(old_inode);
                } else {
                        kunmap(old_dir_page);
index b0649b76eb4f390bea393344af07a9e65dd32211..a161e955c4c808f01ba69b5c93eaf4943344b316 100644 (file)
 #include "segment.h"
 #include <trace/events/f2fs.h>
 
+#define on_build_free_nids(nmi) mutex_is_locked(&nm_i->build_lock)
+
 static struct kmem_cache *nat_entry_slab;
 static struct kmem_cache *free_nid_slab;
 
+static inline bool available_free_memory(struct f2fs_nm_info *nm_i, int type)
+{
+       struct sysinfo val;
+       unsigned long mem_size = 0;
+
+       si_meminfo(&val);
+       if (type == FREE_NIDS)
+               mem_size = nm_i->fcnt * sizeof(struct free_nid);
+       else if (type == NAT_ENTRIES)
+               mem_size += nm_i->nat_cnt * sizeof(struct nat_entry);
+       mem_size >>= 12;
+
+       /* give 50:50 memory for free nids and nat caches respectively */
+       return (mem_size < ((val.totalram * nm_i->ram_thresh) >> 11));
+}
+
 static void clear_node_page_dirty(struct page *page)
 {
        struct address_space *mapping = page->mapping;
@@ -82,42 +100,6 @@ static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
        return dst_page;
 }
 
-/*
- * Readahead NAT pages
- */
-static void ra_nat_pages(struct f2fs_sb_info *sbi, int nid)
-{
-       struct address_space *mapping = META_MAPPING(sbi);
-       struct f2fs_nm_info *nm_i = NM_I(sbi);
-       struct page *page;
-       pgoff_t index;
-       int i;
-       struct f2fs_io_info fio = {
-               .type = META,
-               .rw = READ_SYNC | REQ_META | REQ_PRIO
-       };
-
-
-       for (i = 0; i < FREE_NID_PAGES; i++, nid += NAT_ENTRY_PER_BLOCK) {
-               if (unlikely(nid >= nm_i->max_nid))
-                       nid = 0;
-               index = current_nat_addr(sbi, nid);
-
-               page = grab_cache_page(mapping, index);
-               if (!page)
-                       continue;
-               if (PageUptodate(page)) {
-                       mark_page_accessed(page);
-                       f2fs_put_page(page, 1);
-                       continue;
-               }
-               f2fs_submit_page_mbio(sbi, page, index, &fio);
-               mark_page_accessed(page);
-               f2fs_put_page(page, 0);
-       }
-       f2fs_submit_merged_bio(sbi, META, READ);
-}
-
 static struct nat_entry *__lookup_nat_cache(struct f2fs_nm_info *nm_i, nid_t n)
 {
        return radix_tree_lookup(&nm_i->nat_root, n);
@@ -151,6 +133,20 @@ int is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid)
        return is_cp;
 }
 
+bool fsync_mark_done(struct f2fs_sb_info *sbi, nid_t nid)
+{
+       struct f2fs_nm_info *nm_i = NM_I(sbi);
+       struct nat_entry *e;
+       bool fsync_done = false;
+
+       read_lock(&nm_i->nat_tree_lock);
+       e = __lookup_nat_cache(nm_i, nid);
+       if (e)
+               fsync_done = e->fsync_done;
+       read_unlock(&nm_i->nat_tree_lock);
+       return fsync_done;
+}
+
 static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid)
 {
        struct nat_entry *new;
@@ -164,6 +160,7 @@ static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid)
        }
        memset(new, 0, sizeof(struct nat_entry));
        nat_set_nid(new, nid);
+       new->checkpointed = true;
        list_add_tail(&new->list, &nm_i->nat_entries);
        nm_i->nat_cnt++;
        return new;
@@ -185,13 +182,12 @@ retry:
                nat_set_blkaddr(e, le32_to_cpu(ne->block_addr));
                nat_set_ino(e, le32_to_cpu(ne->ino));
                nat_set_version(e, ne->version);
-               e->checkpointed = true;
        }
        write_unlock(&nm_i->nat_tree_lock);
 }
 
 static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
-                       block_t new_blkaddr)
+                       block_t new_blkaddr, bool fsync_done)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct nat_entry *e;
@@ -205,7 +201,6 @@ retry:
                        goto retry;
                }
                e->ni = *ni;
-               e->checkpointed = true;
                f2fs_bug_on(ni->blk_addr == NEW_ADDR);
        } else if (new_blkaddr == NEW_ADDR) {
                /*
@@ -217,9 +212,6 @@ retry:
                f2fs_bug_on(ni->blk_addr != NULL_ADDR);
        }
 
-       if (new_blkaddr == NEW_ADDR)
-               e->checkpointed = false;
-
        /* sanity check */
        f2fs_bug_on(nat_get_blkaddr(e) != ni->blk_addr);
        f2fs_bug_on(nat_get_blkaddr(e) == NULL_ADDR &&
@@ -239,6 +231,11 @@ retry:
        /* change address */
        nat_set_blkaddr(e, new_blkaddr);
        __set_nat_cache_dirty(nm_i, e);
+
+       /* update fsync_mark if its inode nat entry is still alive */
+       e = __lookup_nat_cache(nm_i, ni->ino);
+       if (e)
+               e->fsync_done = fsync_done;
        write_unlock(&nm_i->nat_tree_lock);
 }
 
@@ -246,7 +243,7 @@ int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
 
-       if (nm_i->nat_cnt <= NM_WOUT_THRESHOLD)
+       if (available_free_memory(nm_i, NAT_ENTRIES))
                return 0;
 
        write_lock(&nm_i->nat_tree_lock);
@@ -505,7 +502,7 @@ static void truncate_node(struct dnode_of_data *dn)
        /* Deallocate node address */
        invalidate_blocks(sbi, ni.blk_addr);
        dec_valid_node_count(sbi, dn->inode);
-       set_node_addr(sbi, &ni, NULL_ADDR);
+       set_node_addr(sbi, &ni, NULL_ADDR, false);
 
        if (dn->nid == dn->inode->i_ino) {
                remove_orphan_inode(sbi, dn->nid);
@@ -763,7 +760,7 @@ skip_partial:
                                f2fs_put_page(page, 1);
                                goto restart;
                        }
-                       wait_on_page_writeback(page);
+                       f2fs_wait_on_page_writeback(page, NODE);
                        ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0;
                        set_page_dirty(page);
                        unlock_page(page);
@@ -852,7 +849,8 @@ struct page *new_node_page(struct dnode_of_data *dn,
        if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
                return ERR_PTR(-EPERM);
 
-       page = grab_cache_page(NODE_MAPPING(sbi), dn->nid);
+       page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
+                                       dn->nid, AOP_FLAG_NOFS);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -867,14 +865,14 @@ struct page *new_node_page(struct dnode_of_data *dn,
        f2fs_bug_on(old_ni.blk_addr != NULL_ADDR);
        new_ni = old_ni;
        new_ni.ino = dn->inode->i_ino;
-       set_node_addr(sbi, &new_ni, NEW_ADDR);
+       set_node_addr(sbi, &new_ni, NEW_ADDR, false);
 
        fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true);
        set_cold_node(dn->inode, page);
        SetPageUptodate(page);
        set_page_dirty(page);
 
-       if (ofs == XATTR_NODE_OFFSET)
+       if (f2fs_has_xattr_block(ofs))
                F2FS_I(dn->inode)->i_xattr_nid = dn->nid;
 
        dn->node_page = page;
@@ -948,7 +946,8 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
        struct page *page;
        int err;
 repeat:
-       page = grab_cache_page(NODE_MAPPING(sbi), nid);
+       page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
+                                       nid, AOP_FLAG_NOFS);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -959,7 +958,7 @@ repeat:
                goto got_it;
 
        lock_page(page);
-       if (unlikely(!PageUptodate(page))) {
+       if (unlikely(!PageUptodate(page) || nid != nid_of_node(page))) {
                f2fs_put_page(page, 1);
                return ERR_PTR(-EIO);
        }
@@ -968,7 +967,6 @@ repeat:
                goto repeat;
        }
 got_it:
-       f2fs_bug_on(nid != nid_of_node(page));
        mark_page_accessed(page);
        return page;
 }
@@ -1168,7 +1166,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
                                continue;
 
                        if (ino && ino_of_node(page) == ino) {
-                               wait_on_page_writeback(page);
+                               f2fs_wait_on_page_writeback(page, NODE);
                                if (TestClearPageError(page))
                                        ret = -EIO;
                        }
@@ -1201,7 +1199,7 @@ static int f2fs_write_node_page(struct page *page,
        if (unlikely(sbi->por_doing))
                goto redirty_out;
 
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, NODE);
 
        /* get old block addr of this node page */
        nid = nid_of_node(page);
@@ -1222,7 +1220,7 @@ static int f2fs_write_node_page(struct page *page,
        mutex_lock(&sbi->node_write);
        set_page_writeback(page);
        write_node_page(sbi, page, &fio, nid, ni.blk_addr, &new_addr);
-       set_node_addr(sbi, &ni, new_addr);
+       set_node_addr(sbi, &ni, new_addr, is_fsync_dnode(page));
        dec_page_count(sbi, F2FS_DIRTY_NODES);
        mutex_unlock(&sbi->node_write);
        unlock_page(page);
@@ -1231,35 +1229,32 @@ static int f2fs_write_node_page(struct page *page,
 redirty_out:
        dec_page_count(sbi, F2FS_DIRTY_NODES);
        wbc->pages_skipped++;
+       account_page_redirty(page);
        set_page_dirty(page);
        return AOP_WRITEPAGE_ACTIVATE;
 }
 
-/*
- * It is very important to gather dirty pages and write at once, so that we can
- * submit a big bio without interfering other data writes.
- * Be default, 512 pages (2MB) * 3 node types, is more reasonable.
- */
-#define COLLECT_DIRTY_NODES    1536
 static int f2fs_write_node_pages(struct address_space *mapping,
                            struct writeback_control *wbc)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb);
-       long nr_to_write = wbc->nr_to_write;
+       long diff;
 
        /* balancing f2fs's metadata in background */
        f2fs_balance_fs_bg(sbi);
 
        /* collect a number of dirty node pages and write together */
-       if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES)
-               return 0;
+       if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
+               goto skip_write;
 
-       /* if mounting is failed, skip writing node pages */
-       wbc->nr_to_write = 3 * max_hw_blocks(sbi);
+       diff = nr_pages_to_write(sbi, NODE, wbc);
        wbc->sync_mode = WB_SYNC_NONE;
        sync_node_pages(sbi, 0, wbc);
-       wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) -
-                                               wbc->nr_to_write);
+       wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff);
+       return 0;
+
+skip_write:
+       wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_NODES);
        return 0;
 }
 
@@ -1307,22 +1302,17 @@ const struct address_space_operations f2fs_node_aops = {
        .releasepage    = f2fs_release_node_page,
 };
 
-static struct free_nid *__lookup_free_nid_list(nid_t n, struct list_head *head)
+static struct free_nid *__lookup_free_nid_list(struct f2fs_nm_info *nm_i,
+                                               nid_t n)
 {
-       struct list_head *this;
-       struct free_nid *i;
-       list_for_each(this, head) {
-               i = list_entry(this, struct free_nid, list);
-               if (i->nid == n)
-                       return i;
-       }
-       return NULL;
+       return radix_tree_lookup(&nm_i->free_nid_root, n);
 }
 
-static void __del_from_free_nid_list(struct free_nid *i)
+static void __del_from_free_nid_list(struct f2fs_nm_info *nm_i,
+                                               struct free_nid *i)
 {
        list_del(&i->list);
-       kmem_cache_free(free_nid_slab, i);
+       radix_tree_delete(&nm_i->free_nid_root, i->nid);
 }
 
 static int add_free_nid(struct f2fs_nm_info *nm_i, nid_t nid, bool build)
@@ -1331,7 +1321,7 @@ static int add_free_nid(struct f2fs_nm_info *nm_i, nid_t nid, bool build)
        struct nat_entry *ne;
        bool allocated = false;
 
-       if (nm_i->fcnt > 2 * MAX_FREE_NIDS)
+       if (!available_free_memory(nm_i, FREE_NIDS))
                return -1;
 
        /* 0 nid should not be used */
@@ -1342,7 +1332,8 @@ static int add_free_nid(struct f2fs_nm_info *nm_i, nid_t nid, bool build)
                /* do not add allocated nids */
                read_lock(&nm_i->nat_tree_lock);
                ne = __lookup_nat_cache(nm_i, nid);
-               if (ne && nat_get_blkaddr(ne) != NULL_ADDR)
+               if (ne &&
+                       (!ne->checkpointed || nat_get_blkaddr(ne) != NULL_ADDR))
                        allocated = true;
                read_unlock(&nm_i->nat_tree_lock);
                if (allocated)
@@ -1354,7 +1345,7 @@ static int add_free_nid(struct f2fs_nm_info *nm_i, nid_t nid, bool build)
        i->state = NID_NEW;
 
        spin_lock(&nm_i->free_nid_list_lock);
-       if (__lookup_free_nid_list(nid, &nm_i->free_nid_list)) {
+       if (radix_tree_insert(&nm_i->free_nid_root, i->nid, i)) {
                spin_unlock(&nm_i->free_nid_list_lock);
                kmem_cache_free(free_nid_slab, i);
                return 0;
@@ -1368,13 +1359,19 @@ static int add_free_nid(struct f2fs_nm_info *nm_i, nid_t nid, bool build)
 static void remove_free_nid(struct f2fs_nm_info *nm_i, nid_t nid)
 {
        struct free_nid *i;
+       bool need_free = false;
+
        spin_lock(&nm_i->free_nid_list_lock);
-       i = __lookup_free_nid_list(nid, &nm_i->free_nid_list);
+       i = __lookup_free_nid_list(nm_i, nid);
        if (i && i->state == NID_NEW) {
-               __del_from_free_nid_list(i);
+               __del_from_free_nid_list(nm_i, i);
                nm_i->fcnt--;
+               need_free = true;
        }
        spin_unlock(&nm_i->free_nid_list_lock);
+
+       if (need_free)
+               kmem_cache_free(free_nid_slab, i);
 }
 
 static void scan_nat_page(struct f2fs_nm_info *nm_i,
@@ -1413,7 +1410,7 @@ static void build_free_nids(struct f2fs_sb_info *sbi)
                return;
 
        /* readahead nat pages to be scanned */
-       ra_nat_pages(sbi, nid);
+       ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT);
 
        while (1) {
                struct page *page = get_current_nat_page(sbi, nid);
@@ -1454,7 +1451,6 @@ bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct free_nid *i = NULL;
-       struct list_head *this;
 retry:
        if (unlikely(sbi->total_valid_node_count + 1 >= nm_i->max_nid))
                return false;
@@ -1462,13 +1458,11 @@ retry:
        spin_lock(&nm_i->free_nid_list_lock);
 
        /* We should not use stale free nids created by build_free_nids */
-       if (nm_i->fcnt && !sbi->on_build_free_nids) {
+       if (nm_i->fcnt && !on_build_free_nids(nm_i)) {
                f2fs_bug_on(list_empty(&nm_i->free_nid_list));
-               list_for_each(this, &nm_i->free_nid_list) {
-                       i = list_entry(this, struct free_nid, list);
+               list_for_each_entry(i, &nm_i->free_nid_list, list)
                        if (i->state == NID_NEW)
                                break;
-               }
 
                f2fs_bug_on(i->state != NID_NEW);
                *nid = i->nid;
@@ -1481,9 +1475,7 @@ retry:
 
        /* Let's scan nat pages and its caches to get free nids */
        mutex_lock(&nm_i->build_lock);
-       sbi->on_build_free_nids = true;
        build_free_nids(sbi);
-       sbi->on_build_free_nids = false;
        mutex_unlock(&nm_i->build_lock);
        goto retry;
 }
@@ -1497,10 +1489,12 @@ void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid)
        struct free_nid *i;
 
        spin_lock(&nm_i->free_nid_list_lock);
-       i = __lookup_free_nid_list(nid, &nm_i->free_nid_list);
+       i = __lookup_free_nid_list(nm_i, nid);
        f2fs_bug_on(!i || i->state != NID_ALLOC);
-       __del_from_free_nid_list(i);
+       __del_from_free_nid_list(nm_i, i);
        spin_unlock(&nm_i->free_nid_list_lock);
+
+       kmem_cache_free(free_nid_slab, i);
 }
 
 /*
@@ -1510,20 +1504,25 @@ void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct free_nid *i;
+       bool need_free = false;
 
        if (!nid)
                return;
 
        spin_lock(&nm_i->free_nid_list_lock);
-       i = __lookup_free_nid_list(nid, &nm_i->free_nid_list);
+       i = __lookup_free_nid_list(nm_i, nid);
        f2fs_bug_on(!i || i->state != NID_ALLOC);
-       if (nm_i->fcnt > 2 * MAX_FREE_NIDS) {
-               __del_from_free_nid_list(i);
+       if (!available_free_memory(nm_i, FREE_NIDS)) {
+               __del_from_free_nid_list(nm_i, i);
+               need_free = true;
        } else {
                i->state = NID_NEW;
                nm_i->fcnt++;
        }
        spin_unlock(&nm_i->free_nid_list_lock);
+
+       if (need_free)
+               kmem_cache_free(free_nid_slab, i);
 }
 
 void recover_node_page(struct f2fs_sb_info *sbi, struct page *page,
@@ -1531,10 +1530,83 @@ void recover_node_page(struct f2fs_sb_info *sbi, struct page *page,
                block_t new_blkaddr)
 {
        rewrite_node_page(sbi, page, sum, ni->blk_addr, new_blkaddr);
-       set_node_addr(sbi, ni, new_blkaddr);
+       set_node_addr(sbi, ni, new_blkaddr, false);
        clear_node_page_dirty(page);
 }
 
+void recover_inline_xattr(struct inode *inode, struct page *page)
+{
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       void *src_addr, *dst_addr;
+       size_t inline_size;
+       struct page *ipage;
+       struct f2fs_inode *ri;
+
+       if (!f2fs_has_inline_xattr(inode))
+               return;
+
+       if (!IS_INODE(page))
+               return;
+
+       ri = F2FS_INODE(page);
+       if (!(ri->i_inline & F2FS_INLINE_XATTR))
+               return;
+
+       ipage = get_node_page(sbi, inode->i_ino);
+       f2fs_bug_on(IS_ERR(ipage));
+
+       dst_addr = inline_xattr_addr(ipage);
+       src_addr = inline_xattr_addr(page);
+       inline_size = inline_xattr_size(inode);
+
+       memcpy(dst_addr, src_addr, inline_size);
+
+       update_inode(inode, ipage);
+       f2fs_put_page(ipage, 1);
+}
+
+bool recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr)
+{
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid;
+       nid_t new_xnid = nid_of_node(page);
+       struct node_info ni;
+
+       recover_inline_xattr(inode, page);
+
+       if (!f2fs_has_xattr_block(ofs_of_node(page)))
+               return false;
+
+       /* 1: invalidate the previous xattr nid */
+       if (!prev_xnid)
+               goto recover_xnid;
+
+       /* Deallocate node address */
+       get_node_info(sbi, prev_xnid, &ni);
+       f2fs_bug_on(ni.blk_addr == NULL_ADDR);
+       invalidate_blocks(sbi, ni.blk_addr);
+       dec_valid_node_count(sbi, inode);
+       set_node_addr(sbi, &ni, NULL_ADDR, false);
+
+recover_xnid:
+       /* 2: allocate new xattr nid */
+       if (unlikely(!inc_valid_node_count(sbi, inode)))
+               f2fs_bug_on(1);
+
+       remove_free_nid(NM_I(sbi), new_xnid);
+       get_node_info(sbi, new_xnid, &ni);
+       ni.ino = inode->i_ino;
+       set_node_addr(sbi, &ni, NEW_ADDR, false);
+       F2FS_I(inode)->i_xattr_nid = new_xnid;
+
+       /* 3: update xattr blkaddr */
+       refresh_sit_entry(sbi, NEW_ADDR, blkaddr);
+       set_node_addr(sbi, &ni, blkaddr, false);
+
+       update_inode_page(inode);
+       return true;
+}
+
 int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
 {
        struct f2fs_inode *src, *dst;
@@ -1567,7 +1639,7 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
 
        if (unlikely(!inc_valid_node_count(sbi, NULL)))
                WARN_ON(1);
-       set_node_addr(sbi, &new_ni, NEW_ADDR);
+       set_node_addr(sbi, &new_ni, NEW_ADDR, false);
        inc_valid_inode_count(sbi);
        f2fs_put_page(ipage, 1);
        return 0;
@@ -1590,15 +1662,8 @@ static int ra_sum_pages(struct f2fs_sb_info *sbi, struct list_head *pages,
        for (; page_idx < start + nrpages; page_idx++) {
                /* alloc temporal page for read node summary info*/
                page = alloc_page(GFP_F2FS_ZERO);
-               if (!page) {
-                       struct page *tmp;
-                       list_for_each_entry_safe(page, tmp, pages, lru) {
-                               list_del(&page->lru);
-                               unlock_page(page);
-                               __free_pages(page, 0);
-                       }
-                       return -ENOMEM;
-               }
+               if (!page)
+                       break;
 
                lock_page(page);
                page->index = page_idx;
@@ -1609,7 +1674,8 @@ static int ra_sum_pages(struct f2fs_sb_info *sbi, struct list_head *pages,
                f2fs_submit_page_mbio(sbi, page, page->index, &fio);
 
        f2fs_submit_merged_bio(sbi, META, READ);
-       return 0;
+
+       return page_idx - start;
 }
 
 int restore_node_summary(struct f2fs_sb_info *sbi,
@@ -1628,15 +1694,17 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
        addr = START_BLOCK(sbi, segno);
        sum_entry = &sum->entries[0];
 
-       for (i = 0; i < last_offset; i += nrpages, addr += nrpages) {
+       for (i = 0; !err && i < last_offset; i += nrpages, addr += nrpages) {
                nrpages = min(last_offset - i, bio_blocks);
 
                /* read ahead node pages */
-               err = ra_sum_pages(sbi, &page_list, addr, nrpages);
-               if (err)
-                       return err;
+               nrpages = ra_sum_pages(sbi, &page_list, addr, nrpages);
+               if (!nrpages)
+                       return -ENOMEM;
 
                list_for_each_entry_safe(page, tmp, &page_list, lru) {
+                       if (err)
+                               goto skip;
 
                        lock_page(page);
                        if (unlikely(!PageUptodate(page))) {
@@ -1648,9 +1716,9 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
                                sum_entry->ofs_in_node = 0;
                                sum_entry++;
                        }
-
-                       list_del(&page->lru);
                        unlock_page(page);
+skip:
+                       list_del(&page->lru);
                        __free_pages(page, 0);
                }
        }
@@ -1709,7 +1777,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi)
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
        struct f2fs_summary_block *sum = curseg->sum_blk;
-       struct list_head *cur, *n;
+       struct nat_entry *ne, *cur;
        struct page *page = NULL;
        struct f2fs_nat_block *nat_blk = NULL;
        nid_t start_nid = 0, end_nid = 0;
@@ -1721,18 +1789,17 @@ void flush_nat_entries(struct f2fs_sb_info *sbi)
                mutex_lock(&curseg->curseg_mutex);
 
        /* 1) flush dirty nat caches */
-       list_for_each_safe(cur, n, &nm_i->dirty_nat_entries) {
-               struct nat_entry *ne;
+       list_for_each_entry_safe(ne, cur, &nm_i->dirty_nat_entries, list) {
                nid_t nid;
                struct f2fs_nat_entry raw_ne;
                int offset = -1;
                block_t new_blkaddr;
 
-               ne = list_entry(cur, struct nat_entry, list);
-               nid = nat_get_nid(ne);
-
                if (nat_get_blkaddr(ne) == NEW_ADDR)
                        continue;
+
+               nid = nat_get_nid(ne);
+
                if (flushed)
                        goto to_nat_page;
 
@@ -1783,16 +1850,12 @@ flush_now:
                } else {
                        write_lock(&nm_i->nat_tree_lock);
                        __clear_nat_cache_dirty(nm_i, ne);
-                       ne->checkpointed = true;
                        write_unlock(&nm_i->nat_tree_lock);
                }
        }
        if (!flushed)
                mutex_unlock(&curseg->curseg_mutex);
        f2fs_put_page(page, 1);
-
-       /* 2) shrink nat caches if necessary */
-       try_to_free_nats(sbi, nm_i->nat_cnt - NM_WOUT_THRESHOLD);
 }
 
 static int init_node_manager(struct f2fs_sb_info *sbi)
@@ -1807,10 +1870,14 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
        /* segment_count_nat includes pair segment so divide to 2. */
        nat_segs = le32_to_cpu(sb_raw->segment_count_nat) >> 1;
        nat_blocks = nat_segs << le32_to_cpu(sb_raw->log_blocks_per_seg);
-       nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks;
+
+       /* not used nids: 0, node, meta, (and root counted as valid node) */
+       nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks - 3;
        nm_i->fcnt = 0;
        nm_i->nat_cnt = 0;
+       nm_i->ram_thresh = DEF_RAM_THRESHOLD;
 
+       INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC);
        INIT_LIST_HEAD(&nm_i->free_nid_list);
        INIT_RADIX_TREE(&nm_i->nat_root, GFP_ATOMIC);
        INIT_LIST_HEAD(&nm_i->nat_entries);
@@ -1864,8 +1931,11 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
        spin_lock(&nm_i->free_nid_list_lock);
        list_for_each_entry_safe(i, next_i, &nm_i->free_nid_list, list) {
                f2fs_bug_on(i->state == NID_ALLOC);
-               __del_from_free_nid_list(i);
+               __del_from_free_nid_list(nm_i, i);
                nm_i->fcnt--;
+               spin_unlock(&nm_i->free_nid_list_lock);
+               kmem_cache_free(free_nid_slab, i);
+               spin_lock(&nm_i->free_nid_list_lock);
        }
        f2fs_bug_on(nm_i->fcnt);
        spin_unlock(&nm_i->free_nid_list_lock);
@@ -1875,11 +1945,9 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
        while ((found = __gang_lookup_nat_cache(nm_i,
                                        nid, NATVEC_SIZE, natvec))) {
                unsigned idx;
-               for (idx = 0; idx < found; idx++) {
-                       struct nat_entry *e = natvec[idx];
-                       nid = nat_get_nid(e) + 1;
-                       __del_from_nat_cache(nm_i, e);
-               }
+               nid = nat_get_nid(natvec[found - 1]) + 1;
+               for (idx = 0; idx < found; idx++)
+                       __del_from_nat_cache(nm_i, natvec[idx]);
        }
        f2fs_bug_on(nm_i->nat_cnt);
        write_unlock(&nm_i->nat_tree_lock);
@@ -1892,12 +1960,12 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
 int __init create_node_manager_caches(void)
 {
        nat_entry_slab = f2fs_kmem_cache_create("nat_entry",
-                       sizeof(struct nat_entry), NULL);
+                       sizeof(struct nat_entry));
        if (!nat_entry_slab)
                return -ENOMEM;
 
        free_nid_slab = f2fs_kmem_cache_create("free_nid",
-                       sizeof(struct free_nid), NULL);
+                       sizeof(struct free_nid));
        if (!free_nid_slab) {
                kmem_cache_destroy(nat_entry_slab);
                return -ENOMEM;
index c4c79885c99344aa9e999b5562fea34954356276..5decc1a375f0071ca00a81bd5d891b507e86ffba 100644 (file)
 /* # of pages to perform readahead before building free nids */
 #define FREE_NID_PAGES 4
 
-/* maximum # of free node ids to produce during build_free_nids */
-#define MAX_FREE_NIDS (NAT_ENTRY_PER_BLOCK * FREE_NID_PAGES)
-
 /* maximum readahead size for node during getting data blocks */
 #define MAX_RA_NODE            128
 
-/* maximum cached nat entries to manage memory footprint */
-#define NM_WOUT_THRESHOLD      (64 * NAT_ENTRY_PER_BLOCK)
+/* control the memory footprint threshold (10MB per 1GB ram) */
+#define DEF_RAM_THRESHOLD      10
 
 /* vector size for gang look-up from nat cache that consists of radix tree */
 #define NATVEC_SIZE    64
@@ -45,6 +42,7 @@ struct node_info {
 struct nat_entry {
        struct list_head list;  /* for clean or dirty nat list */
        bool checkpointed;      /* whether it is checkpointed or not */
+       bool fsync_done;        /* whether the latest node has fsync mark */
        struct node_info ni;    /* in-memory node information */
 };
 
@@ -58,9 +56,15 @@ struct nat_entry {
 #define nat_set_version(nat, v)                (nat->ni.version = v)
 
 #define __set_nat_cache_dirty(nm_i, ne)                                        \
-       list_move_tail(&ne->list, &nm_i->dirty_nat_entries);
+       do {                                                            \
+               ne->checkpointed = false;                               \
+               list_move_tail(&ne->list, &nm_i->dirty_nat_entries);    \
+       } while (0);
 #define __clear_nat_cache_dirty(nm_i, ne)                              \
-       list_move_tail(&ne->list, &nm_i->nat_entries);
+       do {                                                            \
+               ne->checkpointed = true;                                \
+               list_move_tail(&ne->list, &nm_i->nat_entries);          \
+       } while (0);
 #define inc_node_version(version)      (++version)
 
 static inline void node_info_from_raw_nat(struct node_info *ni,
@@ -71,6 +75,11 @@ static inline void node_info_from_raw_nat(struct node_info *ni,
        ni->version = raw_ne->version;
 }
 
+enum nid_type {
+       FREE_NIDS,      /* indicates the free nid list */
+       NAT_ENTRIES     /* indicates the cached nat entry */
+};
+
 /*
  * For free nid mangement
  */
@@ -236,7 +245,7 @@ static inline bool IS_DNODE(struct page *node_page)
 {
        unsigned int ofs = ofs_of_node(node_page);
 
-       if (ofs == XATTR_NODE_OFFSET)
+       if (f2fs_has_xattr_block(ofs))
                return false;
 
        if (ofs == 3 || ofs == 4 + NIDS_PER_BLOCK ||
index 976a7a934db5ddf8ba7843f28cc8e1311c86a632..b1ae89f0f44e53878a7e37aea926c4e3a201c2a3 100644 (file)
@@ -27,14 +27,12 @@ bool space_for_roll_forward(struct f2fs_sb_info *sbi)
 static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
                                                                nid_t ino)
 {
-       struct list_head *this;
        struct fsync_inode_entry *entry;
 
-       list_for_each(this, head) {
-               entry = list_entry(this, struct fsync_inode_entry, list);
+       list_for_each_entry(entry, head, list)
                if (entry->inode->i_ino == ino)
                        return entry;
-       }
+
        return NULL;
 }
 
@@ -136,7 +134,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
 
        /* get node pages in the current segment */
        curseg = CURSEG_I(sbi, CURSEG_WARM_NODE);
-       blkaddr = START_BLOCK(sbi, curseg->segno) + curseg->next_blkoff;
+       blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
 
        /* read node page */
        page = alloc_page(GFP_F2FS_ZERO);
@@ -218,13 +216,12 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
 {
        struct seg_entry *sentry;
        unsigned int segno = GET_SEGNO(sbi, blkaddr);
-       unsigned short blkoff = GET_SEGOFF_FROM_SEG0(sbi, blkaddr) &
-                                       (sbi->blocks_per_seg - 1);
+       unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
+       struct f2fs_summary_block *sum_node;
        struct f2fs_summary sum;
+       struct page *sum_page, *node_page;
        nid_t ino, nid;
-       void *kaddr;
        struct inode *inode;
-       struct page *node_page;
        unsigned int offset;
        block_t bidx;
        int i;
@@ -238,18 +235,15 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
                struct curseg_info *curseg = CURSEG_I(sbi, i);
                if (curseg->segno == segno) {
                        sum = curseg->sum_blk->entries[blkoff];
-                       break;
+                       goto got_it;
                }
        }
-       if (i > CURSEG_COLD_DATA) {
-               struct page *sum_page = get_sum_page(sbi, segno);
-               struct f2fs_summary_block *sum_node;
-               kaddr = page_address(sum_page);
-               sum_node = (struct f2fs_summary_block *)kaddr;
-               sum = sum_node->entries[blkoff];
-               f2fs_put_page(sum_page, 1);
-       }
 
+       sum_page = get_sum_page(sbi, segno);
+       sum_node = (struct f2fs_summary_block *)page_address(sum_page);
+       sum = sum_node->entries[blkoff];
+       f2fs_put_page(sum_page, 1);
+got_it:
        /* Use the locked dnode page and inode */
        nid = le32_to_cpu(sum.nid);
        if (dn->inode->i_ino == nid) {
@@ -301,6 +295,9 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
        if (recover_inline_data(inode, page))
                goto out;
 
+       if (recover_xattr_data(inode, page, blkaddr))
+               goto out;
+
        start = start_bidx_of_node(ofs_of_node(page), fi);
        if (IS_INODE(page))
                end = start + ADDRS_PER_INODE(fi);
@@ -317,7 +314,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
                goto out;
        }
 
-       wait_on_page_writeback(dn.node_page);
+       f2fs_wait_on_page_writeback(dn.node_page, NODE);
 
        get_node_info(sbi, dn.nid, &ni);
        f2fs_bug_on(ni.ino != ino_of_node(page));
@@ -437,7 +434,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
        bool need_writecp = false;
 
        fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry",
-                       sizeof(struct fsync_inode_entry), NULL);
+                       sizeof(struct fsync_inode_entry));
        if (!fsync_entry_slab)
                return -ENOMEM;
 
index 7caac5f2ca9eec01fe1c92a494c8f32ce238e72e..085f548be7a31e53539f844f29c0ea74f87c2a83 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/prefetch.h>
+#include <linux/kthread.h>
 #include <linux/vmalloc.h>
 #include <linux/swap.h>
 
@@ -24,6 +25,7 @@
 #define __reverse_ffz(x) __reverse_ffs(~(x))
 
 static struct kmem_cache *discard_entry_slab;
+static struct kmem_cache *flush_cmd_slab;
 
 /*
  * __reverse_ffs is copied from include/asm-generic/bitops/__ffs.h since
@@ -195,6 +197,73 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
                f2fs_sync_fs(sbi->sb, true);
 }
 
+static int issue_flush_thread(void *data)
+{
+       struct f2fs_sb_info *sbi = data;
+       struct f2fs_sm_info *sm_i = SM_I(sbi);
+       wait_queue_head_t *q = &sm_i->flush_wait_queue;
+repeat:
+       if (kthread_should_stop())
+               return 0;
+
+       spin_lock(&sm_i->issue_lock);
+       if (sm_i->issue_list) {
+               sm_i->dispatch_list = sm_i->issue_list;
+               sm_i->issue_list = sm_i->issue_tail = NULL;
+       }
+       spin_unlock(&sm_i->issue_lock);
+
+       if (sm_i->dispatch_list) {
+               struct bio *bio = bio_alloc(GFP_NOIO, 0);
+               struct flush_cmd *cmd, *next;
+               int ret;
+
+               bio->bi_bdev = sbi->sb->s_bdev;
+               ret = submit_bio_wait(WRITE_FLUSH, bio);
+
+               for (cmd = sm_i->dispatch_list; cmd; cmd = next) {
+                       cmd->ret = ret;
+                       next = cmd->next;
+                       complete(&cmd->wait);
+               }
+               sm_i->dispatch_list = NULL;
+       }
+
+       wait_event_interruptible(*q, kthread_should_stop() || sm_i->issue_list);
+       goto repeat;
+}
+
+int f2fs_issue_flush(struct f2fs_sb_info *sbi)
+{
+       struct f2fs_sm_info *sm_i = SM_I(sbi);
+       struct flush_cmd *cmd;
+       int ret;
+
+       if (!test_opt(sbi, FLUSH_MERGE))
+               return blkdev_issue_flush(sbi->sb->s_bdev, GFP_KERNEL, NULL);
+
+       cmd = f2fs_kmem_cache_alloc(flush_cmd_slab, GFP_ATOMIC);
+       cmd->next = NULL;
+       cmd->ret = 0;
+       init_completion(&cmd->wait);
+
+       spin_lock(&sm_i->issue_lock);
+       if (sm_i->issue_list)
+               sm_i->issue_tail->next = cmd;
+       else
+               sm_i->issue_list = cmd;
+       sm_i->issue_tail = cmd;
+       spin_unlock(&sm_i->issue_lock);
+
+       if (!sm_i->dispatch_list)
+               wake_up(&sm_i->flush_wait_queue);
+
+       wait_for_completion(&cmd->wait);
+       ret = cmd->ret;
+       kmem_cache_free(flush_cmd_slab, cmd);
+       return ret;
+}
+
 static void __locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno,
                enum dirty_type dirty_type)
 {
@@ -340,8 +409,7 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
 void clear_prefree_segments(struct f2fs_sb_info *sbi)
 {
        struct list_head *head = &(SM_I(sbi)->discard_list);
-       struct list_head *this, *next;
-       struct discard_entry *entry;
+       struct discard_entry *entry, *this;
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
        unsigned long *prefree_map = dirty_i->dirty_segmap[PRE];
        unsigned int total_segs = TOTAL_SEGS(sbi);
@@ -370,8 +438,7 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi)
        mutex_unlock(&dirty_i->seglist_lock);
 
        /* send small discards */
-       list_for_each_safe(this, next, head) {
-               entry = list_entry(this, struct discard_entry, list);
+       list_for_each_entry_safe(entry, this, head, list) {
                f2fs_issue_discard(sbi, entry->blkaddr, entry->len);
                list_del(&entry->list);
                SM_I(sbi)->nr_discards -= entry->len;
@@ -405,7 +472,7 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
 
        se = get_seg_entry(sbi, segno);
        new_vblocks = se->valid_blocks + del;
-       offset = GET_SEGOFF_FROM_SEG0(sbi, blkaddr) & (sbi->blocks_per_seg - 1);
+       offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
 
        f2fs_bug_on((new_vblocks >> (sizeof(unsigned short) << 3) ||
                                (new_vblocks > sbi->blocks_per_seg)));
@@ -434,12 +501,14 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
                get_sec_entry(sbi, segno)->valid_blocks += del;
 }
 
-static void refresh_sit_entry(struct f2fs_sb_info *sbi,
-                       block_t old_blkaddr, block_t new_blkaddr)
+void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t new)
 {
-       update_sit_entry(sbi, new_blkaddr, 1);
-       if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
-               update_sit_entry(sbi, old_blkaddr, -1);
+       update_sit_entry(sbi, new, 1);
+       if (GET_SEGNO(sbi, old) != NULL_SEGNO)
+               update_sit_entry(sbi, old, -1);
+
+       locate_dirty_segment(sbi, GET_SEGNO(sbi, old));
+       locate_dirty_segment(sbi, GET_SEGNO(sbi, new));
 }
 
 void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
@@ -881,17 +950,15 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 
        stat_inc_block_count(sbi, curseg);
 
+       if (!__has_curseg_space(sbi, type))
+               sit_i->s_ops->allocate_segment(sbi, type, false);
        /*
         * SIT information should be updated before segment allocation,
         * since SSR needs latest valid block information.
         */
        refresh_sit_entry(sbi, old_blkaddr, *new_blkaddr);
-
-       if (!__has_curseg_space(sbi, type))
-               sit_i->s_ops->allocate_segment(sbi, type, false);
-
        locate_dirty_segment(sbi, old_cursegno);
-       locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
+
        mutex_unlock(&sit_i->sentry_lock);
 
        if (page && IS_NODESEG(type))
@@ -987,14 +1054,11 @@ void recover_data_page(struct f2fs_sb_info *sbi,
                change_curseg(sbi, type, true);
        }
 
-       curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, new_blkaddr) &
-                                       (sbi->blocks_per_seg - 1);
+       curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr);
        __add_sum_entry(sbi, type, sum);
 
        refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
-
        locate_dirty_segment(sbi, old_cursegno);
-       locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
 
        mutex_unlock(&sit_i->sentry_lock);
        mutex_unlock(&curseg->curseg_mutex);
@@ -1028,8 +1092,7 @@ void rewrite_node_page(struct f2fs_sb_info *sbi,
                curseg->next_segno = segno;
                change_curseg(sbi, type, true);
        }
-       curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, new_blkaddr) &
-                                       (sbi->blocks_per_seg - 1);
+       curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr);
        __add_sum_entry(sbi, type, sum);
 
        /* change the current log to the next block addr in advance */
@@ -1037,28 +1100,50 @@ void rewrite_node_page(struct f2fs_sb_info *sbi,
                curseg->next_segno = next_segno;
                change_curseg(sbi, type, true);
        }
-       curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, next_blkaddr) &
-                                       (sbi->blocks_per_seg - 1);
+       curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, next_blkaddr);
 
        /* rewrite node page */
        set_page_writeback(page);
        f2fs_submit_page_mbio(sbi, page, new_blkaddr, &fio);
        f2fs_submit_merged_bio(sbi, NODE, WRITE);
        refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
-
        locate_dirty_segment(sbi, old_cursegno);
-       locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
 
        mutex_unlock(&sit_i->sentry_lock);
        mutex_unlock(&curseg->curseg_mutex);
 }
 
+static inline bool is_merged_page(struct f2fs_sb_info *sbi,
+                                       struct page *page, enum page_type type)
+{
+       enum page_type btype = PAGE_TYPE_OF_BIO(type);
+       struct f2fs_bio_info *io = &sbi->write_io[btype];
+       struct bio_vec *bvec;
+       int i;
+
+       down_read(&io->io_rwsem);
+       if (!io->bio)
+               goto out;
+
+       bio_for_each_segment_all(bvec, io->bio, i) {
+               if (page == bvec->bv_page) {
+                       up_read(&io->io_rwsem);
+                       return true;
+               }
+       }
+
+out:
+       up_read(&io->io_rwsem);
+       return false;
+}
+
 void f2fs_wait_on_page_writeback(struct page *page,
                                enum page_type type)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
        if (PageWriteback(page)) {
-               f2fs_submit_merged_bio(sbi, type, WRITE);
+               if (is_merged_page(sbi, page, type))
+                       f2fs_submit_merged_bio(sbi, type, WRITE);
                wait_on_page_writeback(page);
        }
 }
@@ -1167,9 +1252,12 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
                                ns->ofs_in_node = 0;
                        }
                } else {
-                       if (restore_node_summary(sbi, segno, sum)) {
+                       int err;
+
+                       err = restore_node_summary(sbi, segno, sum);
+                       if (err) {
                                f2fs_put_page(new, 1);
-                               return -EINVAL;
+                               return err;
                        }
                }
        }
@@ -1190,6 +1278,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
 static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 {
        int type = CURSEG_HOT_DATA;
+       int err;
 
        if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) {
                /* restore for compacted data summary */
@@ -1198,9 +1287,12 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
                type = CURSEG_HOT_NODE;
        }
 
-       for (; type <= CURSEG_COLD_NODE; type++)
-               if (read_normal_summaries(sbi, type))
-                       return -EINVAL;
+       for (; type <= CURSEG_COLD_NODE; type++) {
+               err = read_normal_summaries(sbi, type);
+               if (err)
+                       return err;
+       }
+
        return 0;
 }
 
@@ -1583,47 +1675,6 @@ static int build_curseg(struct f2fs_sb_info *sbi)
        return restore_curseg_summaries(sbi);
 }
 
-static int ra_sit_pages(struct f2fs_sb_info *sbi, int start, int nrpages)
-{
-       struct address_space *mapping = META_MAPPING(sbi);
-       struct page *page;
-       block_t blk_addr, prev_blk_addr = 0;
-       int sit_blk_cnt = SIT_BLK_CNT(sbi);
-       int blkno = start;
-       struct f2fs_io_info fio = {
-               .type = META,
-               .rw = READ_SYNC | REQ_META | REQ_PRIO
-       };
-
-       for (; blkno < start + nrpages && blkno < sit_blk_cnt; blkno++) {
-
-               blk_addr = current_sit_addr(sbi, blkno * SIT_ENTRY_PER_BLOCK);
-
-               if (blkno != start && prev_blk_addr + 1 != blk_addr)
-                       break;
-               prev_blk_addr = blk_addr;
-repeat:
-               page = grab_cache_page(mapping, blk_addr);
-               if (!page) {
-                       cond_resched();
-                       goto repeat;
-               }
-               if (PageUptodate(page)) {
-                       mark_page_accessed(page);
-                       f2fs_put_page(page, 1);
-                       continue;
-               }
-
-               f2fs_submit_page_mbio(sbi, page, blk_addr, &fio);
-
-               mark_page_accessed(page);
-               f2fs_put_page(page, 0);
-       }
-
-       f2fs_submit_merged_bio(sbi, META, READ);
-       return blkno - start;
-}
-
 static void build_sit_entries(struct f2fs_sb_info *sbi)
 {
        struct sit_info *sit_i = SIT_I(sbi);
@@ -1635,7 +1686,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)
        int nrpages = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
 
        do {
-               readed = ra_sit_pages(sbi, start_blk, nrpages);
+               readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT);
 
                start = start_blk * sit_i->sents_per_block;
                end = (start_blk + readed) * sit_i->sents_per_block;
@@ -1781,6 +1832,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
 {
        struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
+       dev_t dev = sbi->sb->s_bdev->bd_dev;
        struct f2fs_sm_info *sm_info;
        int err;
 
@@ -1799,7 +1851,8 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
        sm_info->ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
        sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main);
        sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
-       sm_info->rec_prefree_segments = DEF_RECLAIM_PREFREE_SEGMENTS;
+       sm_info->rec_prefree_segments = sm_info->main_segments *
+                                       DEF_RECLAIM_PREFREE_SEGMENTS / 100;
        sm_info->ipu_policy = F2FS_IPU_DISABLE;
        sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
 
@@ -1807,6 +1860,16 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
        sm_info->nr_discards = 0;
        sm_info->max_discards = 0;
 
+       if (test_opt(sbi, FLUSH_MERGE)) {
+               spin_lock_init(&sm_info->issue_lock);
+               init_waitqueue_head(&sm_info->flush_wait_queue);
+
+               sm_info->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi,
+                               "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev));
+               if (IS_ERR(sm_info->f2fs_issue_flush))
+                       return PTR_ERR(sm_info->f2fs_issue_flush);
+       }
+
        err = build_sit_info(sbi);
        if (err)
                return err;
@@ -1915,6 +1978,8 @@ void destroy_segment_manager(struct f2fs_sb_info *sbi)
        struct f2fs_sm_info *sm_info = SM_I(sbi);
        if (!sm_info)
                return;
+       if (sm_info->f2fs_issue_flush)
+               kthread_stop(sm_info->f2fs_issue_flush);
        destroy_dirty_segmap(sbi);
        destroy_curseg(sbi);
        destroy_free_segmap(sbi);
@@ -1926,13 +1991,20 @@ void destroy_segment_manager(struct f2fs_sb_info *sbi)
 int __init create_segment_manager_caches(void)
 {
        discard_entry_slab = f2fs_kmem_cache_create("discard_entry",
-                       sizeof(struct discard_entry), NULL);
+                       sizeof(struct discard_entry));
        if (!discard_entry_slab)
                return -ENOMEM;
+       flush_cmd_slab = f2fs_kmem_cache_create("flush_command",
+                       sizeof(struct flush_cmd));
+       if (!flush_cmd_slab) {
+               kmem_cache_destroy(discard_entry_slab);
+               return -ENOMEM;
+       }
        return 0;
 }
 
 void destroy_segment_manager_caches(void)
 {
        kmem_cache_destroy(discard_entry_slab);
+       kmem_cache_destroy(flush_cmd_slab);
 }
index 5731682d7516aaefccefd96f0c70798f478d0c5c..7091204680f49383ff269f0b8c35834e2c5297d8 100644 (file)
@@ -14,7 +14,7 @@
 #define NULL_SEGNO                     ((unsigned int)(~0))
 #define NULL_SECNO                     ((unsigned int)(~0))
 
-#define DEF_RECLAIM_PREFREE_SEGMENTS   100     /* 200MB of prefree segments */
+#define DEF_RECLAIM_PREFREE_SEGMENTS   5       /* 5% over total segments */
 
 /* L: Logical segment # in volume, R: Relative segment # in main area */
 #define GET_L2R_SEGNO(free_i, segno)   (segno - free_i->start_segno)
@@ -57,6 +57,9 @@
        ((blk_addr) - SM_I(sbi)->seg0_blkaddr)
 #define GET_SEGNO_FROM_SEG0(sbi, blk_addr)                             \
        (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) >> sbi->log_blocks_per_seg)
+#define GET_BLKOFF_FROM_SEG0(sbi, blk_addr)                            \
+       (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (sbi->blocks_per_seg - 1))
+
 #define GET_SEGNO(sbi, blk_addr)                                       \
        (((blk_addr == NULL_ADDR) || (blk_addr == NEW_ADDR)) ?          \
        NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi),                 \
@@ -377,26 +380,12 @@ static inline void get_sit_bitmap(struct f2fs_sb_info *sbi,
 
 static inline block_t written_block_count(struct f2fs_sb_info *sbi)
 {
-       struct sit_info *sit_i = SIT_I(sbi);
-       block_t vblocks;
-
-       mutex_lock(&sit_i->sentry_lock);
-       vblocks = sit_i->written_valid_blocks;
-       mutex_unlock(&sit_i->sentry_lock);
-
-       return vblocks;
+       return SIT_I(sbi)->written_valid_blocks;
 }
 
 static inline unsigned int free_segments(struct f2fs_sb_info *sbi)
 {
-       struct free_segmap_info *free_i = FREE_I(sbi);
-       unsigned int free_segs;
-
-       read_lock(&free_i->segmap_lock);
-       free_segs = free_i->free_segments;
-       read_unlock(&free_i->segmap_lock);
-
-       return free_segs;
+       return FREE_I(sbi)->free_segments;
 }
 
 static inline int reserved_segments(struct f2fs_sb_info *sbi)
@@ -406,14 +395,7 @@ static inline int reserved_segments(struct f2fs_sb_info *sbi)
 
 static inline unsigned int free_sections(struct f2fs_sb_info *sbi)
 {
-       struct free_segmap_info *free_i = FREE_I(sbi);
-       unsigned int free_secs;
-
-       read_lock(&free_i->segmap_lock);
-       free_secs = free_i->free_sections;
-       read_unlock(&free_i->segmap_lock);
-
-       return free_secs;
+       return FREE_I(sbi)->free_sections;
 }
 
 static inline unsigned int prefree_segments(struct f2fs_sb_info *sbi)
@@ -682,3 +664,46 @@ static inline unsigned int max_hw_blocks(struct f2fs_sb_info *sbi)
        struct request_queue *q = bdev_get_queue(bdev);
        return SECTOR_TO_BLOCK(sbi, queue_max_sectors(q));
 }
+
+/*
+ * It is very important to gather dirty pages and write at once, so that we can
+ * submit a big bio without interfering other data writes.
+ * By default, 512 pages for directory data,
+ * 512 pages (2MB) * 3 for three types of nodes, and
+ * max_bio_blocks for meta are set.
+ */
+static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type)
+{
+       if (type == DATA)
+               return sbi->blocks_per_seg;
+       else if (type == NODE)
+               return 3 * sbi->blocks_per_seg;
+       else if (type == META)
+               return MAX_BIO_BLOCKS(max_hw_blocks(sbi));
+       else
+               return 0;
+}
+
+/*
+ * When writing pages, it'd better align nr_to_write for segment size.
+ */
+static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type,
+                                       struct writeback_control *wbc)
+{
+       long nr_to_write, desired;
+
+       if (wbc->sync_mode != WB_SYNC_NONE)
+               return 0;
+
+       nr_to_write = wbc->nr_to_write;
+
+       if (type == DATA)
+               desired = 4096;
+       else if (type == NODE)
+               desired = 3 * max_hw_blocks(sbi);
+       else
+               desired = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
+
+       wbc->nr_to_write = desired;
+       return desired - nr_to_write;
+}
index 1a85f83abd53262f9f1e7c5b71cb38919e85ab22..c756923a7302cc6dc144e108a11a4d2ceb5800ed 100644 (file)
@@ -51,6 +51,7 @@ enum {
        Opt_disable_ext_identify,
        Opt_inline_xattr,
        Opt_inline_data,
+       Opt_flush_merge,
        Opt_err,
 };
 
@@ -67,6 +68,7 @@ static match_table_t f2fs_tokens = {
        {Opt_disable_ext_identify, "disable_ext_identify"},
        {Opt_inline_xattr, "inline_xattr"},
        {Opt_inline_data, "inline_data"},
+       {Opt_flush_merge, "flush_merge"},
        {Opt_err, NULL},
 };
 
@@ -74,6 +76,7 @@ static match_table_t f2fs_tokens = {
 enum {
        GC_THREAD,      /* struct f2fs_gc_thread */
        SM_INFO,        /* struct f2fs_sm_info */
+       NM_INFO,        /* struct f2fs_nm_info */
        F2FS_SBI,       /* struct f2fs_sb_info */
 };
 
@@ -92,6 +95,8 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
                return (unsigned char *)sbi->gc_thread;
        else if (struct_type == SM_INFO)
                return (unsigned char *)SM_I(sbi);
+       else if (struct_type == NM_INFO)
+               return (unsigned char *)NM_I(sbi);
        else if (struct_type == F2FS_SBI)
                return (unsigned char *)sbi;
        return NULL;
@@ -183,7 +188,9 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util);
+F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
@@ -196,6 +203,8 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(ipu_policy),
        ATTR_LIST(min_ipu_util),
        ATTR_LIST(max_victim_search),
+       ATTR_LIST(dir_level),
+       ATTR_LIST(ram_thresh),
        NULL,
 };
 
@@ -256,9 +265,9 @@ static int parse_options(struct super_block *sb, char *options)
 
                        if (!name)
                                return -ENOMEM;
-                       if (!strncmp(name, "on", 2))
+                       if (strlen(name) == 2 && !strncmp(name, "on", 2))
                                set_opt(sbi, BG_GC);
-                       else if (!strncmp(name, "off", 3))
+                       else if (strlen(name) == 3 && !strncmp(name, "off", 3))
                                clear_opt(sbi, BG_GC);
                        else {
                                kfree(name);
@@ -327,6 +336,9 @@ static int parse_options(struct super_block *sb, char *options)
                case Opt_inline_data:
                        set_opt(sbi, INLINE_DATA);
                        break;
+               case Opt_flush_merge:
+                       set_opt(sbi, FLUSH_MERGE);
+                       break;
                default:
                        f2fs_msg(sb, KERN_ERR,
                                "Unrecognized mount option \"%s\" or missing value",
@@ -353,12 +365,16 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
        fi->i_current_depth = 1;
        fi->i_advise = 0;
        rwlock_init(&fi->ext.ext_lock);
+       init_rwsem(&fi->i_sem);
 
        set_inode_flag(fi, FI_NEW_INODE);
 
        if (test_opt(F2FS_SB(sb), INLINE_XATTR))
                set_inode_flag(fi, FI_INLINE_XATTR);
 
+       /* Will be used by directory only */
+       fi->i_dir_level = F2FS_SB(sb)->dir_level;
+
        return &fi->vfs_inode;
 }
 
@@ -526,6 +542,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
                seq_puts(seq, ",disable_ext_identify");
        if (test_opt(sbi, INLINE_DATA))
                seq_puts(seq, ",inline_data");
+       if (test_opt(sbi, FLUSH_MERGE))
+               seq_puts(seq, ",flush_merge");
        seq_printf(seq, ",active_logs=%u", sbi->active_logs);
 
        return 0;
@@ -539,13 +557,22 @@ static int segment_info_seq_show(struct seq_file *seq, void *offset)
                        le32_to_cpu(sbi->raw_super->segment_count_main);
        int i;
 
+       seq_puts(seq, "format: segment_type|valid_blocks\n"
+               "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
+
        for (i = 0; i < total_segs; i++) {
-               seq_printf(seq, "%u", get_valid_blocks(sbi, i, 1));
-               if (i != 0 && (i % 10) == 0)
-                       seq_puts(seq, "\n");
+               struct seg_entry *se = get_seg_entry(sbi, i);
+
+               if ((i % 10) == 0)
+                       seq_printf(seq, "%-5d", i);
+               seq_printf(seq, "%d|%-3u", se->type,
+                                       get_valid_blocks(sbi, i, 1));
+               if ((i % 10) == 9 || i == (total_segs - 1))
+                       seq_putc(seq, '\n');
                else
-                       seq_puts(seq, " ");
+                       seq_putc(seq, ' ');
        }
+
        return 0;
 }
 
@@ -568,6 +595,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
        struct f2fs_mount_info org_mount_opt;
        int err, active_logs;
 
+       sync_filesystem(sb);
+
        /*
         * Save the old mount options in case we
         * need to restore them.
@@ -638,6 +667,8 @@ static struct inode *f2fs_nfs_get_inode(struct super_block *sb,
 
        if (unlikely(ino < F2FS_ROOT_INO(sbi)))
                return ERR_PTR(-ESTALE);
+       if (unlikely(ino >= NM_I(sbi)->max_nid))
+               return ERR_PTR(-ESTALE);
 
        /*
         * f2fs_iget isn't quite right if the inode is currently unallocated!
@@ -785,6 +816,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 
        for (i = 0; i < NR_COUNT_TYPE; i++)
                atomic_set(&sbi->nr_pages[i], 0);
+
+       sbi->dir_level = DEF_DIR_LEVEL;
 }
 
 /*
@@ -896,11 +929,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
        sbi->por_doing = false;
        spin_lock_init(&sbi->stat_lock);
 
-       mutex_init(&sbi->read_io.io_mutex);
+       init_rwsem(&sbi->read_io.io_rwsem);
        sbi->read_io.sbi = sbi;
        sbi->read_io.bio = NULL;
        for (i = 0; i < NR_PAGE_TYPE; i++) {
-               mutex_init(&sbi->write_io[i].io_mutex);
+               init_rwsem(&sbi->write_io[i].io_rwsem);
                sbi->write_io[i].sbi = sbi;
                sbi->write_io[i].bio = NULL;
        }
@@ -989,28 +1022,9 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
                goto free_root_inode;
        }
 
-       /* recover fsynced data */
-       if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {
-               err = recover_fsync_data(sbi);
-               if (err)
-                       f2fs_msg(sb, KERN_ERR,
-                               "Cannot recover all fsync data errno=%ld", err);
-       }
-
-       /*
-        * If filesystem is not mounted as read-only then
-        * do start the gc_thread.
-        */
-       if (!(sb->s_flags & MS_RDONLY)) {
-               /* After POR, we can run background GC thread.*/
-               err = start_gc_thread(sbi);
-               if (err)
-                       goto free_gc;
-       }
-
        err = f2fs_build_stats(sbi);
        if (err)
-               goto free_gc;
+               goto free_root_inode;
 
        if (f2fs_proc_root)
                sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
@@ -1032,17 +1046,36 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
        err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL,
                                                        "%s", sb->s_id);
        if (err)
-               goto fail;
+               goto free_proc;
+
+       /* recover fsynced data */
+       if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {
+               err = recover_fsync_data(sbi);
+               if (err)
+                       f2fs_msg(sb, KERN_ERR,
+                               "Cannot recover all fsync data errno=%ld", err);
+       }
 
+       /*
+        * If filesystem is not mounted as read-only then
+        * do start the gc_thread.
+        */
+       if (!(sb->s_flags & MS_RDONLY)) {
+               /* After POR, we can run background GC thread.*/
+               err = start_gc_thread(sbi);
+               if (err)
+                       goto free_kobj;
+       }
        return 0;
-fail:
+
+free_kobj:
+       kobject_del(&sbi->s_kobj);
+free_proc:
        if (sbi->s_proc) {
                remove_proc_entry("segment_info", sbi->s_proc);
                remove_proc_entry(sb->s_id, f2fs_proc_root);
        }
        f2fs_destroy_stats(sbi);
-free_gc:
-       stop_gc_thread(sbi);
 free_root_inode:
        dput(sb->s_root);
        sb->s_root = NULL;
@@ -1082,7 +1115,7 @@ MODULE_ALIAS_FS("f2fs");
 static int __init init_inodecache(void)
 {
        f2fs_inode_cachep = f2fs_kmem_cache_create("f2fs_inode_cache",
-                       sizeof(struct f2fs_inode_info), NULL);
+                       sizeof(struct f2fs_inode_info));
        if (!f2fs_inode_cachep)
                return -ENOMEM;
        return 0;
index 89d0422a91a88fea51ecf5935d31c2920545f8a6..503c2451131e5ba78b26fcce09870b0ca1a3d9bb 100644 (file)
@@ -275,7 +275,7 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage)
 
        inline_size = inline_xattr_size(inode);
 
-       txattr_addr = kzalloc(inline_size + size, GFP_KERNEL);
+       txattr_addr = kzalloc(inline_size + size, GFP_F2FS_ZERO);
        if (!txattr_addr)
                return NULL;
 
@@ -407,6 +407,8 @@ int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
        if (name == NULL)
                return -EINVAL;
        name_len = strlen(name);
+       if (name_len > F2FS_NAME_LEN)
+               return -ERANGE;
 
        base_addr = read_all_xattrs(inode, NULL);
        if (!base_addr)
@@ -590,7 +592,10 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
        f2fs_balance_fs(sbi);
 
        f2fs_lock_op(sbi);
+       /* protect xattr_ver */
+       down_write(&F2FS_I(inode)->i_sem);
        err = __f2fs_setxattr(inode, name_index, name, value, value_len, ipage);
+       up_write(&F2FS_I(inode)->i_sem);
        f2fs_unlock_op(sbi);
 
        return err;
index c68d9f27135e4b72a41ba63bc9d3e758fbd81c98..b3361fe2bcb590183150fac820d6ffbc1f46e9f9 100644 (file)
@@ -635,6 +635,8 @@ static int fat_remount(struct super_block *sb, int *flags, char *data)
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        *flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME);
 
+       sync_filesystem(sb);
+
        /* make sure we update state on remount. */
        new_rdonly = *flags & MS_RDONLY;
        if (new_rdonly != (sb->s_flags & MS_RDONLY)) {
index ef6866592a0f68c390f2ecededd785fb21e4a659..9ead1596399a12ef66ecf5f087b59463424ccf5d 100644 (file)
@@ -272,9 +272,19 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
        case F_SETFL:
                err = setfl(fd, filp, arg);
                break;
+#if BITS_PER_LONG != 32
+       /* 32-bit arches must use fcntl64() */
+       case F_GETLKP:
+#endif
        case F_GETLK:
-               err = fcntl_getlk(filp, (struct flock __user *) arg);
+               err = fcntl_getlk(filp, cmd, (struct flock __user *) arg);
                break;
+#if BITS_PER_LONG != 32
+       /* 32-bit arches must use fcntl64() */
+       case F_SETLKP:
+       case F_SETLKPW:
+#endif
+               /* Fallthrough */
        case F_SETLK:
        case F_SETLKW:
                err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg);
@@ -388,17 +398,20 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
                goto out1;
        
        switch (cmd) {
-               case F_GETLK64:
-                       err = fcntl_getlk64(f.file, (struct flock64 __user *) arg);
-                       break;
-               case F_SETLK64:
-               case F_SETLKW64:
-                       err = fcntl_setlk64(fd, f.file, cmd,
-                                       (struct flock64 __user *) arg);
-                       break;
-               default:
-                       err = do_fcntl(fd, cmd, arg, f.file);
-                       break;
+       case F_GETLK64:
+       case F_GETLKP:
+               err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg);
+               break;
+       case F_SETLK64:
+       case F_SETLKW64:
+       case F_SETLKP:
+       case F_SETLKPW:
+               err = fcntl_setlk64(fd, f.file, cmd,
+                               (struct flock64 __user *) arg);
+               break;
+       default:
+               err = do_fcntl(fd, cmd, arg, f.file);
+               break;
        }
 out1:
        fdput(f);
index 5b24008ea4f678b668ff2a52fa41f1812b579645..01071c4d752e1e41099c8082a31a55305c5c647d 100644 (file)
@@ -235,7 +235,7 @@ static void __fput(struct file *file)
         * in the file cleanup chain.
         */
        eventpoll_release(file);
-       locks_remove_flock(file);
+       locks_remove_file(file);
 
        if (unlikely(file->f_flags & FASYNC)) {
                if (file->f_op->fasync)
index e37eb274e492a9dfd36d4f717d363b6932ae90b5..7ca8c75d50d3fdc5f9079599465e04f99058d45d 100644 (file)
@@ -124,6 +124,7 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
 
 static int vxfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index a16315957ef3d3e6b41fcf760a54ec8e25df54d7..be568b7311d6f5236099dc23bc84d3ecab750801 100644 (file)
@@ -89,6 +89,8 @@ static inline struct inode *wb_inode(struct list_head *head)
 #define CREATE_TRACE_POINTS
 #include <trace/events/writeback.h>
 
+EXPORT_TRACEPOINT_SYMBOL_GPL(wbc_writepage);
+
 static void bdi_wakeup_thread(struct backing_dev_info *bdi)
 {
        spin_lock_bh(&bdi->wb_lock);
index b96a49b37d663e747d1caec30add48c84fdda14e..13b691a8a7d2ea4403161213486538dadf75a217 100644 (file)
@@ -95,7 +95,7 @@ static ssize_t cuse_read(struct file *file, char __user *buf, size_t count,
        struct iovec iov = { .iov_base = buf, .iov_len = count };
        struct fuse_io_priv io = { .async = 0, .file = file };
 
-       return fuse_direct_io(&io, &iov, 1, count, &pos, 0);
+       return fuse_direct_io(&io, &iov, 1, count, &pos, FUSE_DIO_CUSE);
 }
 
 static ssize_t cuse_write(struct file *file, const char __user *buf,
@@ -109,7 +109,8 @@ static ssize_t cuse_write(struct file *file, const char __user *buf,
         * No locking or generic_write_checks(), the server is
         * responsible for locking and sanity checks.
         */
-       return fuse_direct_io(&io, &iov, 1, count, &pos, 1);
+       return fuse_direct_io(&io, &iov, 1, count, &pos,
+                             FUSE_DIO_WRITE | FUSE_DIO_CUSE);
 }
 
 static int cuse_open(struct inode *inode, struct file *file)
@@ -568,7 +569,7 @@ static ssize_t cuse_class_waiting_show(struct device *dev,
 
        return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting));
 }
-static DEVICE_ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL);
+static DEVICE_ATTR(waiting, 0400, cuse_class_waiting_show, NULL);
 
 static ssize_t cuse_class_abort_store(struct device *dev,
                                      struct device_attribute *attr,
@@ -579,7 +580,7 @@ static ssize_t cuse_class_abort_store(struct device *dev,
        fuse_abort_conn(&cc->fc);
        return count;
 }
-static DEVICE_ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store);
+static DEVICE_ATTR(abort, 0200, NULL, cuse_class_abort_store);
 
 static struct attribute *cuse_class_dev_attrs[] = {
        &dev_attr_waiting.attr,
index 1d1292c581c317ebaa16c54de9f9b85a75086f28..5b4e035b364cc604d68e72411337ef061a766fea 100644 (file)
@@ -839,6 +839,14 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
                          struct kstat *stat)
 {
        unsigned int blkbits;
+       struct fuse_conn *fc = get_fuse_conn(inode);
+
+       /* see the comment in fuse_change_attributes() */
+       if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
+               attr->size = i_size_read(inode);
+               attr->mtime = inode->i_mtime.tv_sec;
+               attr->mtimensec = inode->i_mtime.tv_nsec;
+       }
 
        stat->dev = inode->i_sb->s_dev;
        stat->ino = attr->ino;
@@ -1477,12 +1485,16 @@ static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
                                 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
 }
 
-static bool update_mtime(unsigned ivalid)
+static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
 {
        /* Always update if mtime is explicitly set  */
        if (ivalid & ATTR_MTIME_SET)
                return true;
 
+       /* Or if kernel i_mtime is the official one */
+       if (trust_local_mtime)
+               return true;
+
        /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
        if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
                return false;
@@ -1491,7 +1503,8 @@ static bool update_mtime(unsigned ivalid)
        return true;
 }
 
-static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
+                          bool trust_local_mtime)
 {
        unsigned ivalid = iattr->ia_valid;
 
@@ -1510,11 +1523,11 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
                if (!(ivalid & ATTR_ATIME_SET))
                        arg->valid |= FATTR_ATIME_NOW;
        }
-       if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
+       if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_mtime)) {
                arg->valid |= FATTR_MTIME;
                arg->mtime = iattr->ia_mtime.tv_sec;
                arg->mtimensec = iattr->ia_mtime.tv_nsec;
-               if (!(ivalid & ATTR_MTIME_SET))
+               if (!(ivalid & ATTR_MTIME_SET) && !trust_local_mtime)
                        arg->valid |= FATTR_MTIME_NOW;
        }
 }
@@ -1563,6 +1576,63 @@ void fuse_release_nowrite(struct inode *inode)
        spin_unlock(&fc->lock);
 }
 
+static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req,
+                             struct inode *inode,
+                             struct fuse_setattr_in *inarg_p,
+                             struct fuse_attr_out *outarg_p)
+{
+       req->in.h.opcode = FUSE_SETATTR;
+       req->in.h.nodeid = get_node_id(inode);
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(*inarg_p);
+       req->in.args[0].value = inarg_p;
+       req->out.numargs = 1;
+       if (fc->minor < 9)
+               req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+       else
+               req->out.args[0].size = sizeof(*outarg_p);
+       req->out.args[0].value = outarg_p;
+}
+
+/*
+ * Flush inode->i_mtime to the server
+ */
+int fuse_flush_mtime(struct file *file, bool nofail)
+{
+       struct inode *inode = file->f_mapping->host;
+       struct fuse_inode *fi = get_fuse_inode(inode);
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_req *req = NULL;
+       struct fuse_setattr_in inarg;
+       struct fuse_attr_out outarg;
+       int err;
+
+       if (nofail) {
+               req = fuse_get_req_nofail_nopages(fc, file);
+       } else {
+               req = fuse_get_req_nopages(fc);
+               if (IS_ERR(req))
+                       return PTR_ERR(req);
+       }
+
+       memset(&inarg, 0, sizeof(inarg));
+       memset(&outarg, 0, sizeof(outarg));
+
+       inarg.valid |= FATTR_MTIME;
+       inarg.mtime = inode->i_mtime.tv_sec;
+       inarg.mtimensec = inode->i_mtime.tv_nsec;
+
+       fuse_setattr_fill(fc, req, inode, &inarg, &outarg);
+       fuse_request_send(fc, req);
+       err = req->out.h.error;
+       fuse_put_request(fc, req);
+
+       if (!err)
+               clear_bit(FUSE_I_MTIME_DIRTY, &fi->state);
+
+       return err;
+}
+
 /*
  * Set attributes, and at the same time refresh them.
  *
@@ -1580,8 +1650,10 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
        struct fuse_setattr_in inarg;
        struct fuse_attr_out outarg;
        bool is_truncate = false;
+       bool is_wb = fc->writeback_cache;
        loff_t oldsize;
        int err;
+       bool trust_local_mtime = is_wb && S_ISREG(inode->i_mode);
 
        if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
                attr->ia_valid |= ATTR_FORCE;
@@ -1610,7 +1682,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
 
        memset(&inarg, 0, sizeof(inarg));
        memset(&outarg, 0, sizeof(outarg));
-       iattr_to_fattr(attr, &inarg);
+       iattr_to_fattr(attr, &inarg, trust_local_mtime);
        if (file) {
                struct fuse_file *ff = file->private_data;
                inarg.valid |= FATTR_FH;
@@ -1621,17 +1693,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
                inarg.valid |= FATTR_LOCKOWNER;
                inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
        }
-       req->in.h.opcode = FUSE_SETATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       if (fc->minor < 9)
-               req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
-       else
-               req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
+       fuse_setattr_fill(fc, req, inode, &inarg, &outarg);
        fuse_request_send(fc, req);
        err = req->out.h.error;
        fuse_put_request(fc, req);
@@ -1648,10 +1710,18 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
        }
 
        spin_lock(&fc->lock);
+       /* the kernel maintains i_mtime locally */
+       if (trust_local_mtime && (attr->ia_valid & ATTR_MTIME)) {
+               inode->i_mtime = attr->ia_mtime;
+               clear_bit(FUSE_I_MTIME_DIRTY, &fi->state);
+       }
+
        fuse_change_attributes_common(inode, &outarg.attr,
                                      attr_timeout(&outarg));
        oldsize = inode->i_size;
-       i_size_write(inode, outarg.attr.size);
+       /* see the comment in fuse_change_attributes() */
+       if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
+               i_size_write(inode, outarg.attr.size);
 
        if (is_truncate) {
                /* NOTE: this may release/reacquire fc->lock */
@@ -1663,7 +1733,8 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
         * Only call invalidate_inode_pages2() after removing
         * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
         */
-       if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
+       if ((is_truncate || !is_wb) &&
+           S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
                truncate_pagecache(inode, outarg.attr.size);
                invalidate_inode_pages2(inode->i_mapping);
        }
@@ -1875,6 +1946,17 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
        return err;
 }
 
+static int fuse_update_time(struct inode *inode, struct timespec *now,
+                           int flags)
+{
+       if (flags & S_MTIME) {
+               inode->i_mtime = *now;
+               set_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state);
+               BUG_ON(!S_ISREG(inode->i_mode));
+       }
+       return 0;
+}
+
 static const struct inode_operations fuse_dir_inode_operations = {
        .lookup         = fuse_lookup,
        .mkdir          = fuse_mkdir,
@@ -1914,6 +1996,7 @@ static const struct inode_operations fuse_common_inode_operations = {
        .getxattr       = fuse_getxattr,
        .listxattr      = fuse_listxattr,
        .removexattr    = fuse_removexattr,
+       .update_time    = fuse_update_time,
 };
 
 static const struct inode_operations fuse_symlink_inode_operations = {
index 77bcc303c3aeb9214ba4b13098da14fb8bcbe20b..65df7d8be4f587cbc703e3885b6f9a1d4050ffe0 100644 (file)
@@ -188,6 +188,22 @@ int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
 }
 EXPORT_SYMBOL_GPL(fuse_do_open);
 
+static void fuse_link_write_file(struct file *file)
+{
+       struct inode *inode = file_inode(file);
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_inode *fi = get_fuse_inode(inode);
+       struct fuse_file *ff = file->private_data;
+       /*
+        * file may be written through mmap, so chain it onto the
+        * inodes's write_file list
+        */
+       spin_lock(&fc->lock);
+       if (list_empty(&ff->write_entry))
+               list_add(&ff->write_entry, &fi->write_files);
+       spin_unlock(&fc->lock);
+}
+
 void fuse_finish_open(struct inode *inode, struct file *file)
 {
        struct fuse_file *ff = file->private_data;
@@ -208,6 +224,8 @@ void fuse_finish_open(struct inode *inode, struct file *file)
                spin_unlock(&fc->lock);
                fuse_invalidate_attr(inode);
        }
+       if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
+               fuse_link_write_file(file);
 }
 
 int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
@@ -292,6 +310,15 @@ static int fuse_open(struct inode *inode, struct file *file)
 
 static int fuse_release(struct inode *inode, struct file *file)
 {
+       struct fuse_conn *fc = get_fuse_conn(inode);
+
+       /* see fuse_vma_close() for !writeback_cache case */
+       if (fc->writeback_cache)
+               filemap_write_and_wait(file->f_mapping);
+
+       if (test_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state))
+               fuse_flush_mtime(file, true);
+
        fuse_release_common(file, FUSE_RELEASE);
 
        /* return value is ignored by VFS */
@@ -333,12 +360,13 @@ u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
 }
 
 /*
- * Check if page is under writeback
+ * Check if any page in a range is under writeback
  *
  * This is currently done by walking the list of writepage requests
  * for the inode, which can be pretty inefficient.
  */
-static bool fuse_page_is_writeback(struct inode *inode, pgoff_t index)
+static bool fuse_range_is_writeback(struct inode *inode, pgoff_t idx_from,
+                                  pgoff_t idx_to)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
@@ -351,8 +379,8 @@ static bool fuse_page_is_writeback(struct inode *inode, pgoff_t index)
 
                BUG_ON(req->inode != inode);
                curr_index = req->misc.write.in.offset >> PAGE_CACHE_SHIFT;
-               if (curr_index <= index &&
-                   index < curr_index + req->num_pages) {
+               if (idx_from < curr_index + req->num_pages &&
+                   curr_index <= idx_to) {
                        found = true;
                        break;
                }
@@ -362,6 +390,11 @@ static bool fuse_page_is_writeback(struct inode *inode, pgoff_t index)
        return found;
 }
 
+static inline bool fuse_page_is_writeback(struct inode *inode, pgoff_t index)
+{
+       return fuse_range_is_writeback(inode, index, index);
+}
+
 /*
  * Wait for page writeback to be completed.
  *
@@ -376,6 +409,21 @@ static int fuse_wait_on_page_writeback(struct inode *inode, pgoff_t index)
        return 0;
 }
 
+/*
+ * Wait for all pending writepages on the inode to finish.
+ *
+ * This is currently done by blocking further writes with FUSE_NOWRITE
+ * and waiting for all sent writes to complete.
+ *
+ * This must be called under i_mutex, otherwise the FUSE_NOWRITE usage
+ * could conflict with truncation.
+ */
+static void fuse_sync_writes(struct inode *inode)
+{
+       fuse_set_nowrite(inode);
+       fuse_release_nowrite(inode);
+}
+
 static int fuse_flush(struct file *file, fl_owner_t id)
 {
        struct inode *inode = file_inode(file);
@@ -391,6 +439,14 @@ static int fuse_flush(struct file *file, fl_owner_t id)
        if (fc->no_flush)
                return 0;
 
+       err = filemap_write_and_wait(file->f_mapping);
+       if (err)
+               return err;
+
+       mutex_lock(&inode->i_mutex);
+       fuse_sync_writes(inode);
+       mutex_unlock(&inode->i_mutex);
+
        req = fuse_get_req_nofail_nopages(fc, file);
        memset(&inarg, 0, sizeof(inarg));
        inarg.fh = ff->fh;
@@ -411,21 +467,6 @@ static int fuse_flush(struct file *file, fl_owner_t id)
        return err;
 }
 
-/*
- * Wait for all pending writepages on the inode to finish.
- *
- * This is currently done by blocking further writes with FUSE_NOWRITE
- * and waiting for all sent writes to complete.
- *
- * This must be called under i_mutex, otherwise the FUSE_NOWRITE usage
- * could conflict with truncation.
- */
-static void fuse_sync_writes(struct inode *inode)
-{
-       fuse_set_nowrite(inode);
-       fuse_release_nowrite(inode);
-}
-
 int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
                      int datasync, int isdir)
 {
@@ -459,6 +500,12 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
 
        fuse_sync_writes(inode);
 
+       if (test_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state)) {
+               int err = fuse_flush_mtime(file, false);
+               if (err)
+                       goto out;
+       }
+
        req = fuse_get_req_nopages(fc);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
@@ -655,7 +702,33 @@ static void fuse_read_update_size(struct inode *inode, loff_t size,
        spin_unlock(&fc->lock);
 }
 
-static int fuse_readpage(struct file *file, struct page *page)
+static void fuse_short_read(struct fuse_req *req, struct inode *inode,
+                           u64 attr_ver)
+{
+       size_t num_read = req->out.args[0].size;
+       struct fuse_conn *fc = get_fuse_conn(inode);
+
+       if (fc->writeback_cache) {
+               /*
+                * A hole in a file. Some data after the hole are in page cache,
+                * but have not reached the client fs yet. So, the hole is not
+                * present there.
+                */
+               int i;
+               int start_idx = num_read >> PAGE_CACHE_SHIFT;
+               size_t off = num_read & (PAGE_CACHE_SIZE - 1);
+
+               for (i = start_idx; i < req->num_pages; i++) {
+                       zero_user_segment(req->pages[i], off, PAGE_CACHE_SIZE);
+                       off = 0;
+               }
+       } else {
+               loff_t pos = page_offset(req->pages[0]) + num_read;
+               fuse_read_update_size(inode, pos, attr_ver);
+       }
+}
+
+static int fuse_do_readpage(struct file *file, struct page *page)
 {
        struct fuse_io_priv io = { .async = 0, .file = file };
        struct inode *inode = page->mapping->host;
@@ -667,10 +740,6 @@ static int fuse_readpage(struct file *file, struct page *page)
        u64 attr_ver;
        int err;
 
-       err = -EIO;
-       if (is_bad_inode(inode))
-               goto out;
-
        /*
         * Page writeback can extend beyond the lifetime of the
         * page-cache page, so make sure we read a properly synced
@@ -679,9 +748,8 @@ static int fuse_readpage(struct file *file, struct page *page)
        fuse_wait_on_page_writeback(inode, page->index);
 
        req = fuse_get_req(fc, 1);
-       err = PTR_ERR(req);
        if (IS_ERR(req))
-               goto out;
+               return PTR_ERR(req);
 
        attr_ver = fuse_get_attr_version(fc);
 
@@ -692,18 +760,32 @@ static int fuse_readpage(struct file *file, struct page *page)
        req->page_descs[0].length = count;
        num_read = fuse_send_read(req, &io, pos, count, NULL);
        err = req->out.h.error;
-       fuse_put_request(fc, req);
 
        if (!err) {
                /*
                 * Short read means EOF.  If file size is larger, truncate it
                 */
                if (num_read < count)
-                       fuse_read_update_size(inode, pos + num_read, attr_ver);
+                       fuse_short_read(req, inode, attr_ver);
 
                SetPageUptodate(page);
        }
 
+       fuse_put_request(fc, req);
+
+       return err;
+}
+
+static int fuse_readpage(struct file *file, struct page *page)
+{
+       struct inode *inode = page->mapping->host;
+       int err;
+
+       err = -EIO;
+       if (is_bad_inode(inode))
+               goto out;
+
+       err = fuse_do_readpage(file, page);
        fuse_invalidate_atime(inode);
  out:
        unlock_page(page);
@@ -726,13 +808,9 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
                /*
                 * Short read means EOF. If file size is larger, truncate it
                 */
-               if (!req->out.h.error && num_read < count) {
-                       loff_t pos;
+               if (!req->out.h.error && num_read < count)
+                       fuse_short_read(req, inode, req->misc.read.attr_ver);
 
-                       pos = page_offset(req->pages[0]) + num_read;
-                       fuse_read_update_size(inode, pos,
-                                             req->misc.read.attr_ver);
-               }
                fuse_invalidate_atime(inode);
        }
 
@@ -922,16 +1000,21 @@ static size_t fuse_send_write(struct fuse_req *req, struct fuse_io_priv *io,
        return req->misc.write.out.size;
 }
 
-void fuse_write_update_size(struct inode *inode, loff_t pos)
+bool fuse_write_update_size(struct inode *inode, loff_t pos)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
+       bool ret = false;
 
        spin_lock(&fc->lock);
        fi->attr_version = ++fc->attr_version;
-       if (pos > inode->i_size)
+       if (pos > inode->i_size) {
                i_size_write(inode, pos);
+               ret = true;
+       }
        spin_unlock(&fc->lock);
+
+       return ret;
 }
 
 static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file,
@@ -1116,6 +1199,15 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        struct iov_iter i;
        loff_t endbyte = 0;
 
+       if (get_fuse_conn(inode)->writeback_cache) {
+               /* Update size (EOF optimization) and mode (SUID clearing) */
+               err = fuse_update_attributes(mapping->host, NULL, file, NULL);
+               if (err)
+                       return err;
+
+               return generic_file_aio_write(iocb, iov, nr_segs, pos);
+       }
+
        WARN_ON(iocb->ki_pos != pos);
 
        ocount = 0;
@@ -1289,13 +1381,18 @@ static inline int fuse_iter_npages(const struct iov_iter *ii_p)
 
 ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
                       unsigned long nr_segs, size_t count, loff_t *ppos,
-                      int write)
+                      int flags)
 {
+       int write = flags & FUSE_DIO_WRITE;
+       int cuse = flags & FUSE_DIO_CUSE;
        struct file *file = io->file;
+       struct inode *inode = file->f_mapping->host;
        struct fuse_file *ff = file->private_data;
        struct fuse_conn *fc = ff->fc;
        size_t nmax = write ? fc->max_write : fc->max_read;
        loff_t pos = *ppos;
+       pgoff_t idx_from = pos >> PAGE_CACHE_SHIFT;
+       pgoff_t idx_to = (pos + count - 1) >> PAGE_CACHE_SHIFT;
        ssize_t res = 0;
        struct fuse_req *req;
        struct iov_iter ii;
@@ -1309,6 +1406,14 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
+       if (!cuse && fuse_range_is_writeback(inode, idx_from, idx_to)) {
+               if (!write)
+                       mutex_lock(&inode->i_mutex);
+               fuse_sync_writes(inode);
+               if (!write)
+                       mutex_unlock(&inode->i_mutex);
+       }
+
        while (count) {
                size_t nres;
                fl_owner_t owner = current->files;
@@ -1397,7 +1502,8 @@ static ssize_t __fuse_direct_write(struct fuse_io_priv *io,
 
        res = generic_write_checks(file, ppos, &count, 0);
        if (!res)
-               res = fuse_direct_io(io, iov, nr_segs, count, ppos, 1);
+               res = fuse_direct_io(io, iov, nr_segs, count, ppos,
+                                    FUSE_DIO_WRITE);
 
        fuse_invalidate_attr(inode);
 
@@ -1885,6 +1991,77 @@ out:
        return err;
 }
 
+/*
+ * It's worthy to make sure that space is reserved on disk for the write,
+ * but how to implement it without killing performance need more thinking.
+ */
+static int fuse_write_begin(struct file *file, struct address_space *mapping,
+               loff_t pos, unsigned len, unsigned flags,
+               struct page **pagep, void **fsdata)
+{
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+       struct fuse_conn *fc = get_fuse_conn(file->f_dentry->d_inode);
+       struct page *page;
+       loff_t fsize;
+       int err = -ENOMEM;
+
+       WARN_ON(!fc->writeback_cache);
+
+       page = grab_cache_page_write_begin(mapping, index, flags);
+       if (!page)
+               goto error;
+
+       fuse_wait_on_page_writeback(mapping->host, page->index);
+
+       if (PageUptodate(page) || len == PAGE_CACHE_SIZE)
+               goto success;
+       /*
+        * Check if the start this page comes after the end of file, in which
+        * case the readpage can be optimized away.
+        */
+       fsize = i_size_read(mapping->host);
+       if (fsize <= (pos & PAGE_CACHE_MASK)) {
+               size_t off = pos & ~PAGE_CACHE_MASK;
+               if (off)
+                       zero_user_segment(page, 0, off);
+               goto success;
+       }
+       err = fuse_do_readpage(file, page);
+       if (err)
+               goto cleanup;
+success:
+       *pagep = page;
+       return 0;
+
+cleanup:
+       unlock_page(page);
+       page_cache_release(page);
+error:
+       return err;
+}
+
+static int fuse_write_end(struct file *file, struct address_space *mapping,
+               loff_t pos, unsigned len, unsigned copied,
+               struct page *page, void *fsdata)
+{
+       struct inode *inode = page->mapping->host;
+
+       if (!PageUptodate(page)) {
+               /* Zero any unwritten bytes at the end of the page */
+               size_t endoff = (pos + copied) & ~PAGE_CACHE_MASK;
+               if (endoff)
+                       zero_user_segment(page, endoff, PAGE_CACHE_SIZE);
+               SetPageUptodate(page);
+       }
+
+       fuse_write_update_size(inode, pos + copied);
+       set_page_dirty(page);
+       unlock_page(page);
+       page_cache_release(page);
+
+       return copied;
+}
+
 static int fuse_launder_page(struct page *page)
 {
        int err = 0;
@@ -1946,20 +2123,9 @@ static const struct vm_operations_struct fuse_file_vm_ops = {
 
 static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
-               struct inode *inode = file_inode(file);
-               struct fuse_conn *fc = get_fuse_conn(inode);
-               struct fuse_inode *fi = get_fuse_inode(inode);
-               struct fuse_file *ff = file->private_data;
-               /*
-                * file may be written through mmap, so chain it onto the
-                * inodes's write_file list
-                */
-               spin_lock(&fc->lock);
-               if (list_empty(&ff->write_entry))
-                       list_add(&ff->write_entry, &fi->write_files);
-               spin_unlock(&fc->lock);
-       }
+       if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
+               fuse_link_write_file(file);
+
        file_accessed(file);
        vma->vm_ops = &fuse_file_vm_ops;
        return 0;
@@ -2606,7 +2772,7 @@ static void fuse_register_polled_file(struct fuse_conn *fc,
 {
        spin_lock(&fc->lock);
        if (RB_EMPTY_NODE(&ff->polled_node)) {
-               struct rb_node **link, *parent;
+               struct rb_node **link, *uninitialized_var(parent);
 
                link = fuse_find_polled_node(fc, ff->kh, &parent);
                BUG_ON(*link);
@@ -2850,8 +3016,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
                goto out;
 
        /* we could have extended the file */
-       if (!(mode & FALLOC_FL_KEEP_SIZE))
-               fuse_write_update_size(inode, offset + length);
+       if (!(mode & FALLOC_FL_KEEP_SIZE)) {
+               bool changed = fuse_write_update_size(inode, offset + length);
+
+               if (changed && fc->writeback_cache) {
+                       struct fuse_inode *fi = get_fuse_inode(inode);
+
+                       inode->i_mtime = current_fs_time(inode->i_sb);
+                       set_bit(FUSE_I_MTIME_DIRTY, &fi->state);
+               }
+       }
 
        if (mode & FALLOC_FL_PUNCH_HOLE)
                truncate_pagecache_range(inode, offset, offset + length - 1);
@@ -2915,6 +3089,8 @@ static const struct address_space_operations fuse_file_aops  = {
        .set_page_dirty = __set_page_dirty_nobuffers,
        .bmap           = fuse_bmap,
        .direct_IO      = fuse_direct_IO,
+       .write_begin    = fuse_write_begin,
+       .write_end      = fuse_write_end,
 };
 
 void fuse_init_file_inode(struct inode *inode)
index 2da5db2c8bdb8da6752eca718cff89232f1f75a5..a257ed8ebee6c6db62339e1a8d3f2f87479310ea 100644 (file)
@@ -119,6 +119,8 @@ enum {
        FUSE_I_INIT_RDPLUS,
        /** An operation changing file size is in progress  */
        FUSE_I_SIZE_UNSTABLE,
+       /** i_mtime has been updated locally; a flush to userspace needed */
+       FUSE_I_MTIME_DIRTY,
 };
 
 struct fuse_conn;
@@ -480,6 +482,9 @@ struct fuse_conn {
        /** Set if bdi is valid */
        unsigned bdi_initialized:1;
 
+       /** write-back cache policy (default is write-through) */
+       unsigned writeback_cache:1;
+
        /*
         * The following bitfields are only for optimization purposes
         * and hence races in setting them will not cause malfunction
@@ -863,9 +868,20 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
 
 int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
                 bool isdir);
+
+/**
+ * fuse_direct_io() flags
+ */
+
+/** If set, it is WRITE; otherwise - READ */
+#define FUSE_DIO_WRITE (1 << 0)
+
+/** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */
+#define FUSE_DIO_CUSE  (1 << 1)
+
 ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
                       unsigned long nr_segs, size_t count, loff_t *ppos,
-                      int write);
+                      int flags);
 long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                   unsigned int flags);
 long fuse_ioctl_common(struct file *file, unsigned int cmd,
@@ -873,7 +889,9 @@ long fuse_ioctl_common(struct file *file, unsigned int cmd,
 unsigned fuse_file_poll(struct file *file, poll_table *wait);
 int fuse_dev_release(struct inode *inode, struct file *file);
 
-void fuse_write_update_size(struct inode *inode, loff_t pos);
+bool fuse_write_update_size(struct inode *inode, loff_t pos);
+
+int fuse_flush_mtime(struct file *file, bool nofail);
 
 int fuse_do_setattr(struct inode *inode, struct iattr *attr,
                    struct file *file);
index 9c761b611c5418b1fcc8b08d7b144a3a1689cdf0..8d611696fcad303dfe4137a2ff9bc9e1d2a5b97d 100644 (file)
@@ -135,6 +135,7 @@ static void fuse_evict_inode(struct inode *inode)
 
 static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if (*flags & MS_MANDLOCK)
                return -EINVAL;
 
@@ -170,8 +171,11 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
        inode->i_blocks  = attr->blocks;
        inode->i_atime.tv_sec   = attr->atime;
        inode->i_atime.tv_nsec  = attr->atimensec;
-       inode->i_mtime.tv_sec   = attr->mtime;
-       inode->i_mtime.tv_nsec  = attr->mtimensec;
+       /* mtime from server may be stale due to local buffered write */
+       if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
+               inode->i_mtime.tv_sec   = attr->mtime;
+               inode->i_mtime.tv_nsec  = attr->mtimensec;
+       }
        inode->i_ctime.tv_sec   = attr->ctime;
        inode->i_ctime.tv_nsec  = attr->ctimensec;
 
@@ -197,6 +201,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
+       bool is_wb = fc->writeback_cache;
        loff_t oldsize;
        struct timespec old_mtime;
 
@@ -211,10 +216,16 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
        fuse_change_attributes_common(inode, attr, attr_valid);
 
        oldsize = inode->i_size;
-       i_size_write(inode, attr->size);
+       /*
+        * In case of writeback_cache enabled, the cached writes beyond EOF
+        * extend local i_size without keeping userspace server in sync. So,
+        * attr->size coming from server can be stale. We cannot trust it.
+        */
+       if (!is_wb || !S_ISREG(inode->i_mode))
+               i_size_write(inode, attr->size);
        spin_unlock(&fc->lock);
 
-       if (S_ISREG(inode->i_mode)) {
+       if (!is_wb && S_ISREG(inode->i_mode)) {
                bool inval = false;
 
                if (oldsize != attr->size) {
@@ -243,6 +254,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 {
        inode->i_mode = attr->mode & S_IFMT;
        inode->i_size = attr->size;
+       inode->i_mtime.tv_sec  = attr->mtime;
+       inode->i_mtime.tv_nsec = attr->mtimensec;
        if (S_ISREG(inode->i_mode)) {
                fuse_init_common(inode);
                fuse_init_file_inode(inode);
@@ -289,7 +302,9 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
                return NULL;
 
        if ((inode->i_state & I_NEW)) {
-               inode->i_flags |= S_NOATIME|S_NOCMTIME;
+               inode->i_flags |= S_NOATIME;
+               if (!fc->writeback_cache || !S_ISREG(inode->i_mode))
+                       inode->i_flags |= S_NOCMTIME;
                inode->i_generation = generation;
                inode->i_data.backing_dev_info = &fc->bdi;
                fuse_init_inode(inode, attr);
@@ -873,6 +888,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                        }
                        if (arg->flags & FUSE_ASYNC_DIO)
                                fc->async_dio = 1;
+                       if (arg->flags & FUSE_WRITEBACK_CACHE)
+                               fc->writeback_cache = 1;
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -900,7 +917,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
                FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
                FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
                FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
-               FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO;
+               FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
+               FUSE_WRITEBACK_CACHE;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
index ba9456685f47d761d51afae92a55328e2d54d78a..3088e2a38e30185ef5dfb21355ea840fc3ed4bc8 100644 (file)
@@ -64,18 +64,6 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
        return acl;
 }
 
-static int gfs2_set_mode(struct inode *inode, umode_t mode)
-{
-       int error = 0;
-
-       if (mode != inode->i_mode) {
-               inode->i_mode = mode;
-               mark_inode_dirty(inode);
-       }
-
-       return error;
-}
-
 int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
        int error;
@@ -85,8 +73,8 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 
        BUG_ON(name == NULL);
 
-       if (acl->a_count > GFS2_ACL_MAX_ENTRIES)
-               return -EINVAL;
+       if (acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode)))
+               return -E2BIG;
 
        if (type == ACL_TYPE_ACCESS) {
                umode_t mode = inode->i_mode;
@@ -98,9 +86,10 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
                if (error == 0)
                        acl = NULL;
 
-               error = gfs2_set_mode(inode, mode);
-               if (error)
-                       return error;
+               if (mode != inode->i_mode) {
+                       inode->i_mode = mode;
+                       mark_inode_dirty(inode);
+               }
        }
 
        if (acl) {
index 301260c999ba994bbcab3af270962cd93058dcd9..2d65ec4cd4bef60b87c0291c9ef84ce3abcf65a2 100644 (file)
@@ -14,7 +14,7 @@
 
 #define GFS2_POSIX_ACL_ACCESS          "posix_acl_access"
 #define GFS2_POSIX_ACL_DEFAULT         "posix_acl_default"
-#define GFS2_ACL_MAX_ENTRIES           25
+#define GFS2_ACL_MAX_ENTRIES(sdp) ((300 << (sdp)->sd_sb.sb_bsize_shift) >> 12)
 
 extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type);
 extern int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
index 49436fa7cd4fdcf87fb9f9dae13743173df2ab52..ce62dcac90b6ffbe8d3bbb20806a16a922291873 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/backing-dev.h>
 #include <linux/aio.h>
+#include <trace/events/writeback.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -230,13 +231,11 @@ static int gfs2_writepages(struct address_space *mapping,
 static int gfs2_write_jdata_pagevec(struct address_space *mapping,
                                    struct writeback_control *wbc,
                                    struct pagevec *pvec,
-                                   int nr_pages, pgoff_t end)
+                                   int nr_pages, pgoff_t end,
+                                   pgoff_t *done_index)
 {
        struct inode *inode = mapping->host;
        struct gfs2_sbd *sdp = GFS2_SB(inode);
-       loff_t i_size = i_size_read(inode);
-       pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
-       unsigned offset = i_size & (PAGE_CACHE_SIZE-1);
        unsigned nrblocks = nr_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize);
        int i;
        int ret;
@@ -248,40 +247,83 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
        for(i = 0; i < nr_pages; i++) {
                struct page *page = pvec->pages[i];
 
+               /*
+                * At this point, the page may be truncated or
+                * invalidated (changing page->mapping to NULL), or
+                * even swizzled back from swapper_space to tmpfs file
+                * mapping. However, page->index will not change
+                * because we have a reference on the page.
+                */
+               if (page->index > end) {
+                       /*
+                        * can't be range_cyclic (1st pass) because
+                        * end == -1 in that case.
+                        */
+                       ret = 1;
+                       break;
+               }
+
+               *done_index = page->index;
+
                lock_page(page);
 
                if (unlikely(page->mapping != mapping)) {
+continue_unlock:
                        unlock_page(page);
                        continue;
                }
 
-               if (!wbc->range_cyclic && page->index > end) {
-                       ret = 1;
-                       unlock_page(page);
-                       continue;
+               if (!PageDirty(page)) {
+                       /* someone wrote it for us */
+                       goto continue_unlock;
                }
 
-               if (wbc->sync_mode != WB_SYNC_NONE)
-                       wait_on_page_writeback(page);
-
-               if (PageWriteback(page) ||
-                   !clear_page_dirty_for_io(page)) {
-                       unlock_page(page);
-                       continue;
+               if (PageWriteback(page)) {
+                       if (wbc->sync_mode != WB_SYNC_NONE)
+                               wait_on_page_writeback(page);
+                       else
+                               goto continue_unlock;
                }
 
-               /* Is the page fully outside i_size? (truncate in progress) */
-               if (page->index > end_index || (page->index == end_index && !offset)) {
-                       page->mapping->a_ops->invalidatepage(page, 0,
-                                                            PAGE_CACHE_SIZE);
-                       unlock_page(page);
-                       continue;
-               }
+               BUG_ON(PageWriteback(page));
+               if (!clear_page_dirty_for_io(page))
+                       goto continue_unlock;
+
+               trace_wbc_writepage(wbc, mapping->backing_dev_info);
 
                ret = __gfs2_jdata_writepage(page, wbc);
+               if (unlikely(ret)) {
+                       if (ret == AOP_WRITEPAGE_ACTIVATE) {
+                               unlock_page(page);
+                               ret = 0;
+                       } else {
+
+                               /*
+                                * done_index is set past this page,
+                                * so media errors will not choke
+                                * background writeout for the entire
+                                * file. This has consequences for
+                                * range_cyclic semantics (ie. it may
+                                * not be suitable for data integrity
+                                * writeout).
+                                */
+                               *done_index = page->index + 1;
+                               ret = 1;
+                               break;
+                       }
+               }
 
-               if (ret || (--(wbc->nr_to_write) <= 0))
+               /*
+                * We stop writing back only if we are not doing
+                * integrity sync. In case of integrity sync we have to
+                * keep going until we have written all the pages
+                * we tagged for writeback prior to entering this loop.
+                */
+               if (--wbc->nr_to_write <= 0 && wbc->sync_mode == WB_SYNC_NONE) {
                        ret = 1;
+                       break;
+               }
+
        }
        gfs2_trans_end(sdp);
        return ret;
@@ -306,51 +348,69 @@ static int gfs2_write_cache_jdata(struct address_space *mapping,
        int done = 0;
        struct pagevec pvec;
        int nr_pages;
+       pgoff_t uninitialized_var(writeback_index);
        pgoff_t index;
        pgoff_t end;
-       int scanned = 0;
+       pgoff_t done_index;
+       int cycled;
        int range_whole = 0;
+       int tag;
 
        pagevec_init(&pvec, 0);
        if (wbc->range_cyclic) {
-               index = mapping->writeback_index; /* Start from prev offset */
+               writeback_index = mapping->writeback_index; /* prev offset */
+               index = writeback_index;
+               if (index == 0)
+                       cycled = 1;
+               else
+                       cycled = 0;
                end = -1;
        } else {
                index = wbc->range_start >> PAGE_CACHE_SHIFT;
                end = wbc->range_end >> PAGE_CACHE_SHIFT;
                if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
                        range_whole = 1;
-               scanned = 1;
+               cycled = 1; /* ignore range_cyclic tests */
        }
+       if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
+               tag = PAGECACHE_TAG_TOWRITE;
+       else
+               tag = PAGECACHE_TAG_DIRTY;
 
 retry:
-        while (!done && (index <= end) &&
-               (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-                                              PAGECACHE_TAG_DIRTY,
-                                              min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
-               scanned = 1;
-               ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, end);
+       if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
+               tag_pages_for_writeback(mapping, index, end);
+       done_index = index;
+       while (!done && (index <= end)) {
+               nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
+                             min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+               if (nr_pages == 0)
+                       break;
+
+               ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, end, &done_index);
                if (ret)
                        done = 1;
                if (ret > 0)
                        ret = 0;
-
                pagevec_release(&pvec);
                cond_resched();
        }
 
-       if (!scanned && !done) {
+       if (!cycled && !done) {
                /*
+                * range_cyclic:
                 * We hit the last page and there is more work to be done: wrap
                 * back to the start of the file
                 */
-               scanned = 1;
+               cycled = 1;
                index = 0;
+               end = writeback_index - 1;
                goto retry;
        }
 
        if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
-               mapping->writeback_index = index;
+               mapping->writeback_index = done_index;
+
        return ret;
 }
 
index fe0500c0af7aab88ca4276234df6894cca7290b3..c62d4b9f51dcfd1cd744716798e8ed6880c7df4c 100644 (file)
@@ -1327,6 +1327,121 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
        return trunc_dealloc(ip, 0);
 }
 
+/**
+ * gfs2_free_journal_extents - Free cached journal bmap info
+ * @jd: The journal
+ *
+ */
+
+void gfs2_free_journal_extents(struct gfs2_jdesc *jd)
+{
+       struct gfs2_journal_extent *jext;
+
+       while(!list_empty(&jd->extent_list)) {
+               jext = list_entry(jd->extent_list.next, struct gfs2_journal_extent, list);
+               list_del(&jext->list);
+               kfree(jext);
+       }
+}
+
+/**
+ * gfs2_add_jextent - Add or merge a new extent to extent cache
+ * @jd: The journal descriptor
+ * @lblock: The logical block at start of new extent
+ * @pblock: The physical block at start of new extent
+ * @blocks: Size of extent in fs blocks
+ *
+ * Returns: 0 on success or -ENOMEM
+ */
+
+static int gfs2_add_jextent(struct gfs2_jdesc *jd, u64 lblock, u64 dblock, u64 blocks)
+{
+       struct gfs2_journal_extent *jext;
+
+       if (!list_empty(&jd->extent_list)) {
+               jext = list_entry(jd->extent_list.prev, struct gfs2_journal_extent, list);
+               if ((jext->dblock + jext->blocks) == dblock) {
+                       jext->blocks += blocks;
+                       return 0;
+               }
+       }
+
+       jext = kzalloc(sizeof(struct gfs2_journal_extent), GFP_NOFS);
+       if (jext == NULL)
+               return -ENOMEM;
+       jext->dblock = dblock;
+       jext->lblock = lblock;
+       jext->blocks = blocks;
+       list_add_tail(&jext->list, &jd->extent_list);
+       jd->nr_extents++;
+       return 0;
+}
+
+/**
+ * gfs2_map_journal_extents - Cache journal bmap info
+ * @sdp: The super block
+ * @jd: The journal to map
+ *
+ * Create a reusable "extent" mapping from all logical
+ * blocks to all physical blocks for the given journal.  This will save
+ * us time when writing journal blocks.  Most journals will have only one
+ * extent that maps all their logical blocks.  That's because gfs2.mkfs
+ * arranges the journal blocks sequentially to maximize performance.
+ * So the extent would map the first block for the entire file length.
+ * However, gfs2_jadd can happen while file activity is happening, so
+ * those journals may not be sequential.  Less likely is the case where
+ * the users created their own journals by mounting the metafs and
+ * laying it out.  But it's still possible.  These journals might have
+ * several extents.
+ *
+ * Returns: 0 on success, or error on failure
+ */
+
+int gfs2_map_journal_extents(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
+{
+       u64 lblock = 0;
+       u64 lblock_stop;
+       struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+       struct buffer_head bh;
+       unsigned int shift = sdp->sd_sb.sb_bsize_shift;
+       u64 size;
+       int rc;
+
+       lblock_stop = i_size_read(jd->jd_inode) >> shift;
+       size = (lblock_stop - lblock) << shift;
+       jd->nr_extents = 0;
+       WARN_ON(!list_empty(&jd->extent_list));
+
+       do {
+               bh.b_state = 0;
+               bh.b_blocknr = 0;
+               bh.b_size = size;
+               rc = gfs2_block_map(jd->jd_inode, lblock, &bh, 0);
+               if (rc || !buffer_mapped(&bh))
+                       goto fail;
+               rc = gfs2_add_jextent(jd, lblock, bh.b_blocknr, bh.b_size >> shift);
+               if (rc)
+                       goto fail;
+               size -= bh.b_size;
+               lblock += (bh.b_size >> ip->i_inode.i_blkbits);
+       } while(size > 0);
+
+       fs_info(sdp, "journal %d mapped with %u extents\n", jd->jd_jid,
+               jd->nr_extents);
+       return 0;
+
+fail:
+       fs_warn(sdp, "error %d mapping journal %u at offset %llu (extent %u)\n",
+               rc, jd->jd_jid,
+               (unsigned long long)(i_size_read(jd->jd_inode) - size),
+               jd->nr_extents);
+       fs_warn(sdp, "bmap=%d lblock=%llu block=%llu, state=0x%08lx, size=%llu\n",
+               rc, (unsigned long long)lblock, (unsigned long long)bh.b_blocknr,
+               bh.b_state, (unsigned long long)bh.b_size);
+       gfs2_free_journal_extents(jd);
+       return rc;
+}
+
 /**
  * gfs2_write_alloc_required - figure out if a write will require an allocation
  * @ip: the file being written to
index 42fea03e2bd962b6674747967ac00499009d923f..81ded5e2aaa25bd340182e82eee20e793c30ea9a 100644 (file)
@@ -55,5 +55,7 @@ extern int gfs2_truncatei_resume(struct gfs2_inode *ip);
 extern int gfs2_file_dealloc(struct gfs2_inode *ip);
 extern int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
                                     unsigned int len);
+extern int gfs2_map_journal_extents(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd);
+extern void gfs2_free_journal_extents(struct gfs2_jdesc *jd);
 
 #endif /* __BMAP_DOT_H__ */
index fa32655449c800eef7768f97ae11e54fc75a6dfb..1a349f9a9685a88c7dc67141ed0cee0c2374fec9 100644 (file)
@@ -53,6 +53,8 @@
  * but never before the maximum hash table size has been reached.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/buffer_head.h>
@@ -507,8 +509,8 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset,
                goto error;
        return 0;
 error:
-       printk(KERN_WARNING "gfs2_check_dirent: %s (%s)\n", msg,
-              first ? "first in block" : "not first in block");
+       pr_warn("%s: %s (%s)\n",
+               __func__, msg, first ? "first in block" : "not first in block");
        return -EIO;
 }
 
@@ -531,8 +533,7 @@ static int gfs2_dirent_offset(const void *buf)
        }
        return offset;
 wrong_type:
-       printk(KERN_WARNING "gfs2_scan_dirent: wrong block type %u\n",
-              be32_to_cpu(h->mh_type));
+       pr_warn("%s: wrong block type %u\n", __func__, be32_to_cpu(h->mh_type));
        return -1;
 }
 
@@ -728,7 +729,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
 
        error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp);
        if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
-               /* printk(KERN_INFO "block num=%llu\n", leaf_no); */
+               /* pr_info("block num=%llu\n", leaf_no); */
                error = -EIO;
        }
 
@@ -1006,7 +1007,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
        len = 1 << (dip->i_depth - be16_to_cpu(oleaf->lf_depth));
        half_len = len >> 1;
        if (!half_len) {
-               printk(KERN_WARNING "i_depth %u lf_depth %u index %u\n", dip->i_depth, be16_to_cpu(oleaf->lf_depth), index);
+               pr_warn("i_depth %u lf_depth %u index %u\n",
+                       dip->i_depth, be16_to_cpu(oleaf->lf_depth), index);
                gfs2_consist_inode(dip);
                error = -EIO;
                goto fail_brelse;
@@ -1684,6 +1686,14 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
        return 0;
 }
 
+static u16 gfs2_inode_ra_len(const struct gfs2_inode *ip)
+{
+       u64 where = ip->i_no_addr + 1;
+       if (ip->i_eattr == where)
+               return 1;
+       return 0;
+}
+
 /**
  * gfs2_dir_add - Add new filename into directory
  * @inode: The directory inode
@@ -1721,6 +1731,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
                        dent = gfs2_init_dirent(inode, dent, name, bh);
                        gfs2_inum_out(nip, dent);
                        dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode));
+                       dent->de_rahead = cpu_to_be16(gfs2_inode_ra_len(nip));
                        tv = CURRENT_TIME;
                        if (ip->i_diskflags & GFS2_DIF_EXHASH) {
                                leaf = (struct gfs2_leaf *)bh->b_data;
index efc078f0ee4ed5464646841a4035b933756b562e..6c794085abaca594ddde671bdea5f6b79dbbb072 100644 (file)
@@ -811,6 +811,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
        loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1);
        loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift;
        loff_t max_chunk_size = UINT_MAX & bsize_mask;
+       struct gfs2_holder gh;
+
        next = (next + 1) << sdp->sd_sb.sb_bsize_shift;
 
        /* We only support the FALLOC_FL_KEEP_SIZE mode */
@@ -831,8 +833,10 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
        if (error)
                return error;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
-       error = gfs2_glock_nq(&ip->i_gh);
+       mutex_lock(&inode->i_mutex);
+
+       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       error = gfs2_glock_nq(&gh);
        if (unlikely(error))
                goto out_uninit;
 
@@ -900,9 +904,10 @@ out_trans_fail:
 out_qunlock:
        gfs2_quota_unlock(ip);
 out_unlock:
-       gfs2_glock_dq(&ip->i_gh);
+       gfs2_glock_dq(&gh);
 out_uninit:
-       gfs2_holder_uninit(&ip->i_gh);
+       gfs2_holder_uninit(&gh);
+       mutex_unlock(&inode->i_mutex);
        return error;
 }
 
index ca0be6c69a26dd0e46d07ddbdc149fb301e5a4b6..aec7f73832f080c3fd5288cdc3722162b72257bd 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -468,7 +470,7 @@ retry:
                        do_xmote(gl, gh, LM_ST_UNLOCKED);
                        break;
                default: /* Everything else */
-                       printk(KERN_ERR "GFS2: wanted %u got %u\n", gl->gl_target, state);
+                       pr_err("wanted %u got %u\n", gl->gl_target, state);
                        GLOCK_BUG_ON(gl, 1);
                }
                spin_unlock(&gl->gl_spin);
@@ -542,7 +544,7 @@ __acquires(&gl->gl_spin)
                /* lock_dlm */
                ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags);
                if (ret) {
-                       printk(KERN_ERR "GFS2: lm_lock ret %d\n", ret);
+                       pr_err("lm_lock ret %d\n", ret);
                        GLOCK_BUG_ON(gl, 1);
                }
        } else { /* lock_nolock */
@@ -935,7 +937,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
                vaf.fmt = fmt;
                vaf.va = &args;
 
-               printk(KERN_ERR " %pV", &vaf);
+               pr_err("%pV", &vaf);
        }
 
        va_end(args);
@@ -1010,13 +1012,13 @@ do_cancel:
        return;
 
 trap_recursive:
-       printk(KERN_ERR "original: %pSR\n", (void *)gh2->gh_ip);
-       printk(KERN_ERR "pid: %d\n", pid_nr(gh2->gh_owner_pid));
-       printk(KERN_ERR "lock type: %d req lock state : %d\n",
+       pr_err("original: %pSR\n", (void *)gh2->gh_ip);
+       pr_err("pid: %d\n", pid_nr(gh2->gh_owner_pid));
+       pr_err("lock type: %d req lock state : %d\n",
               gh2->gh_gl->gl_name.ln_type, gh2->gh_state);
-       printk(KERN_ERR "new: %pSR\n", (void *)gh->gh_ip);
-       printk(KERN_ERR "pid: %d\n", pid_nr(gh->gh_owner_pid));
-       printk(KERN_ERR "lock type: %d req lock state : %d\n",
+       pr_err("new: %pSR\n", (void *)gh->gh_ip);
+       pr_err("pid: %d\n", pid_nr(gh->gh_owner_pid));
+       pr_err("lock type: %d req lock state : %d\n",
               gh->gh_gl->gl_name.ln_type, gh->gh_state);
        gfs2_dump_glock(NULL, gl);
        BUG();
@@ -1045,9 +1047,13 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
 
        spin_lock(&gl->gl_spin);
        add_to_queue(gh);
-       if ((LM_FLAG_NOEXP & gh->gh_flags) &&
-           test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))
+       if (unlikely((LM_FLAG_NOEXP & gh->gh_flags) &&
+                    test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))) {
                set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
+               gl->gl_lockref.count++;
+               if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
+                       gl->gl_lockref.count--;
+       }
        run_queue(gl, 1);
        spin_unlock(&gl->gl_spin);
 
index 3bf0631b5d56d8a76a17b9f70e3fa1cc4b9ee2f0..54b66809e818e4fbffd46c186f7409948e35e3a2 100644 (file)
@@ -82,6 +82,8 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
        struct gfs2_trans tr;
 
        memset(&tr, 0, sizeof(tr));
+       INIT_LIST_HEAD(&tr.tr_buf);
+       INIT_LIST_HEAD(&tr.tr_databuf);
        tr.tr_revokes = atomic_read(&gl->gl_ail_count);
 
        if (!tr.tr_revokes)
index cf0e34400f71e5588ffb476fa3f4667012e218f9..bdf70c18610cfafd26d8d475e7ea939d54487a44 100644 (file)
@@ -52,7 +52,7 @@ struct gfs2_log_header_host {
  */
 
 struct gfs2_log_operations {
-       void (*lo_before_commit) (struct gfs2_sbd *sdp);
+       void (*lo_before_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr);
        void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr);
        void (*lo_before_scan) (struct gfs2_jdesc *jd,
                                struct gfs2_log_header_host *head, int pass);
@@ -371,6 +371,7 @@ enum {
        GIF_ALLOC_FAILED        = 2,
        GIF_SW_PAGED            = 3,
        GIF_ORDERED             = 4,
+       GIF_FREE_VFS_INODE      = 5,
 };
 
 struct gfs2_inode {
@@ -462,11 +463,11 @@ struct gfs2_trans {
        unsigned int tr_blocks;
        unsigned int tr_revokes;
        unsigned int tr_reserved;
+       unsigned int tr_touched:1;
+       unsigned int tr_attached:1;
 
        struct gfs2_holder tr_t_gh;
 
-       int tr_touched;
-       int tr_attached;
 
        unsigned int tr_num_buf_new;
        unsigned int tr_num_databuf_new;
@@ -476,6 +477,8 @@ struct gfs2_trans {
        unsigned int tr_num_revoke_rm;
 
        struct list_head tr_list;
+       struct list_head tr_databuf;
+       struct list_head tr_buf;
 
        unsigned int tr_first;
        struct list_head tr_ail1_list;
@@ -483,7 +486,7 @@ struct gfs2_trans {
 };
 
 struct gfs2_journal_extent {
-       struct list_head extent_list;
+       struct list_head list;
 
        unsigned int lblock; /* First logical block */
        u64 dblock; /* First disk block */
@@ -493,6 +496,7 @@ struct gfs2_journal_extent {
 struct gfs2_jdesc {
        struct list_head jd_list;
        struct list_head extent_list;
+       unsigned int nr_extents;
        struct work_struct jd_work;
        struct inode *jd_inode;
        unsigned long jd_flags;
@@ -500,6 +504,15 @@ struct gfs2_jdesc {
        unsigned int jd_jid;
        unsigned int jd_blocks;
        int jd_recover_error;
+       /* Replay stuff */
+
+       unsigned int jd_found_blocks;
+       unsigned int jd_found_revokes;
+       unsigned int jd_replayed_blocks;
+
+       struct list_head jd_revoke_list;
+       unsigned int jd_replay_tail;
+
 };
 
 struct gfs2_statfs_change_host {
@@ -746,19 +759,12 @@ struct gfs2_sbd {
 
        struct gfs2_trans *sd_log_tr;
        unsigned int sd_log_blks_reserved;
-       unsigned int sd_log_commited_buf;
-       unsigned int sd_log_commited_databuf;
        int sd_log_commited_revoke;
 
        atomic_t sd_log_pinned;
-       unsigned int sd_log_num_buf;
        unsigned int sd_log_num_revoke;
-       unsigned int sd_log_num_rg;
-       unsigned int sd_log_num_databuf;
 
-       struct list_head sd_log_le_buf;
        struct list_head sd_log_le_revoke;
-       struct list_head sd_log_le_databuf;
        struct list_head sd_log_le_ordered;
        spinlock_t sd_ordered_lock;
 
@@ -786,15 +792,6 @@ struct gfs2_sbd {
        struct list_head sd_ail1_list;
        struct list_head sd_ail2_list;
 
-       /* Replay stuff */
-
-       struct list_head sd_revoke_list;
-       unsigned int sd_replay_tail;
-
-       unsigned int sd_found_blocks;
-       unsigned int sd_found_revokes;
-       unsigned int sd_replayed_blocks;
-
        /* For quiescing the filesystem */
        struct gfs2_holder sd_freeze_gh;
 
index 5c524180c98e85a50e8e4c63ce233f71ff82ea39..28cc7bf6575a2147820bb2d67be0a1ba8bbb0b6d 100644 (file)
@@ -376,12 +376,11 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip,
                inode->i_gid = current_fsgid();
 }
 
-static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
+static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-       struct gfs2_alloc_parms ap = { .target = RES_DINODE, .aflags = flags, };
+       struct gfs2_alloc_parms ap = { .target = *dblocks, .aflags = flags, };
        int error;
-       int dblocks = 1;
 
        error = gfs2_quota_lock_check(ip);
        if (error)
@@ -391,11 +390,11 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
        if (error)
                goto out_quota;
 
-       error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 0);
+       error = gfs2_trans_begin(sdp, (*dblocks * RES_RG_BIT) + RES_STATFS + RES_QUOTA, 0);
        if (error)
                goto out_ipreserv;
 
-       error = gfs2_alloc_blocks(ip, &ip->i_no_addr, &dblocks, 1, &ip->i_generation);
+       error = gfs2_alloc_blocks(ip, &ip->i_no_addr, dblocks, 1, &ip->i_generation);
        ip->i_no_formal_ino = ip->i_generation;
        ip->i_inode.i_ino = ip->i_no_addr;
        ip->i_goal = ip->i_no_addr;
@@ -427,6 +426,33 @@ static void gfs2_init_dir(struct buffer_head *dibh,
        
 }
 
+/**
+ * gfs2_init_xattr - Initialise an xattr block for a new inode
+ * @ip: The inode in question
+ *
+ * This sets up an empty xattr block for a new inode, ready to
+ * take any ACLs, LSM xattrs, etc.
+ */
+
+static void gfs2_init_xattr(struct gfs2_inode *ip)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       struct buffer_head *bh;
+       struct gfs2_ea_header *ea;
+
+       bh = gfs2_meta_new(ip->i_gl, ip->i_eattr);
+       gfs2_trans_add_meta(ip->i_gl, bh);
+       gfs2_metatype_set(bh, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
+       gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
+
+       ea = GFS2_EA_BH2FIRST(bh);
+       ea->ea_rec_len = cpu_to_be32(sdp->sd_jbsize);
+       ea->ea_type = GFS2_EATYPE_UNUSED;
+       ea->ea_flags = GFS2_EAFLAG_LAST;
+
+       brelse(bh);
+}
+
 /**
  * init_dinode - Fill in a new dinode structure
  * @dip: The directory this inode is being created in
@@ -545,13 +571,6 @@ static int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
        return err;
 }
 
-static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
-                             const struct qstr *qstr)
-{
-       return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
-                                           &gfs2_initxattrs, NULL);
-}
-
 /**
  * gfs2_create_inode - Create a new inode
  * @dir: The parent directory
@@ -578,8 +597,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
        struct gfs2_glock *io_gl;
        struct dentry *d;
-       int error;
+       int error, free_vfs_inode = 0;
        u32 aflags = 0;
+       unsigned blocks = 1;
        struct gfs2_diradd da = { .bh = NULL, };
 
        if (!name->len || name->len > GFS2_FNAMESIZE)
@@ -676,10 +696,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
            (dip->i_diskflags & GFS2_DIF_TOPDIR))
                aflags |= GFS2_AF_ORLOV;
 
-       error = alloc_dinode(ip, aflags);
+       if (default_acl || acl)
+               blocks++;
+
+       error = alloc_dinode(ip, aflags, &blocks);
        if (error)
                goto fail_free_inode;
 
+       gfs2_set_inode_blocks(inode, blocks);
+
        error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
        if (error)
                goto fail_free_inode;
@@ -689,10 +714,14 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        if (error)
                goto fail_free_inode;
 
-       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
+       error = gfs2_trans_begin(sdp, blocks, 0);
        if (error)
                goto fail_gunlock2;
 
+       if (blocks > 1) {
+               ip->i_eattr = ip->i_no_addr + 1;
+               gfs2_init_xattr(ip);
+       }
        init_dinode(dip, ip, symname);
        gfs2_trans_end(sdp);
 
@@ -722,7 +751,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        if (error)
                goto fail_gunlock3;
 
-       error = gfs2_security_init(dip, ip, name);
+       error = security_inode_init_security(&ip->i_inode, &dip->i_inode, name,
+                                            &gfs2_initxattrs, NULL);
        if (error)
                goto fail_gunlock3;
 
@@ -758,15 +788,16 @@ fail_free_acls:
        if (acl)
                posix_acl_release(acl);
 fail_free_vfs_inode:
-       free_inode_nonrcu(inode);
-       inode = NULL;
+       free_vfs_inode = 1;
 fail_gunlock:
        gfs2_dir_no_add(&da);
        gfs2_glock_dq_uninit(ghs);
        if (inode && !IS_ERR(inode)) {
                clear_nlink(inode);
-               mark_inode_dirty(inode);
-               set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags);
+               if (!free_vfs_inode)
+                       mark_inode_dirty(inode);
+               set_bit(free_vfs_inode ? GIF_FREE_VFS_INODE : GIF_ALLOC_FAILED,
+                       &GFS2_I(inode)->i_flags);
                iput(inode);
        }
 fail:
@@ -1263,6 +1294,10 @@ static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
                }
 
                tmp = gfs2_lookupi(dir, &gfs2_qdotdot, 1);
+               if (!tmp) {
+                       error = -ENOENT;
+                       break;
+               }
                if (IS_ERR(tmp)) {
                        error = PTR_ERR(tmp);
                        break;
index 2a6ba06bee6fca0ffada9c155ca243466fcf1f62..c1eb555dc588e178cbbeee5e6771563a29f4a81a 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/fs.h>
 #include <linux/dlm.h>
 #include <linux/slab.h>
@@ -176,7 +178,7 @@ static void gdlm_bast(void *arg, int mode)
                gfs2_glock_cb(gl, LM_ST_SHARED);
                break;
        default:
-               printk(KERN_ERR "unknown bast mode %d", mode);
+               pr_err("unknown bast mode %d\n", mode);
                BUG();
        }
 }
@@ -195,7 +197,7 @@ static int make_mode(const unsigned int lmstate)
        case LM_ST_SHARED:
                return DLM_LOCK_PR;
        }
-       printk(KERN_ERR "unknown LM state %d", lmstate);
+       pr_err("unknown LM state %d\n", lmstate);
        BUG();
        return -1;
 }
@@ -308,7 +310,7 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
        error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK,
                           NULL, gl);
        if (error) {
-               printk(KERN_ERR "gdlm_unlock %x,%llx err=%d\n",
+               pr_err("gdlm_unlock %x,%llx err=%d\n",
                       gl->gl_name.ln_type,
                       (unsigned long long)gl->gl_name.ln_number, error);
                return;
@@ -1102,7 +1104,7 @@ static void gdlm_recover_slot(void *arg, struct dlm_slot *slot)
        }
 
        if (ls->ls_recover_submit[jid]) {
-               fs_info(sdp, "recover_slot jid %d gen %u prev %u",
+               fs_info(sdp, "recover_slot jid %d gen %u prev %u\n",
                        jid, ls->ls_recover_block, ls->ls_recover_submit[jid]);
        }
        ls->ls_recover_submit[jid] = ls->ls_recover_block;
index 9dcb9777a5f80eb32bcfce88aca3a8026776f047..4a14d504ef835e1ad6b46c315c20272356347d34 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/bio.h>
+#include <linux/blkdev.h>
 #include <linux/writeback.h>
 #include <linux/list_sort.h>
 
@@ -145,8 +146,10 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
 {
        struct list_head *head = &sdp->sd_ail1_list;
        struct gfs2_trans *tr;
+       struct blk_plug plug;
 
        trace_gfs2_ail_flush(sdp, wbc, 1);
+       blk_start_plug(&plug);
        spin_lock(&sdp->sd_ail_lock);
 restart:
        list_for_each_entry_reverse(tr, head, tr_list) {
@@ -156,6 +159,7 @@ restart:
                        goto restart;
        }
        spin_unlock(&sdp->sd_ail_lock);
+       blk_finish_plug(&plug);
        trace_gfs2_ail_flush(sdp, wbc, 0);
 }
 
@@ -410,24 +414,22 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer
 static unsigned int calc_reserved(struct gfs2_sbd *sdp)
 {
        unsigned int reserved = 0;
-       unsigned int mbuf_limit, metabufhdrs_needed;
-       unsigned int dbuf_limit, databufhdrs_needed;
-       unsigned int revokes = 0;
+       unsigned int mbuf;
+       unsigned int dbuf;
+       struct gfs2_trans *tr = sdp->sd_log_tr;
 
-       mbuf_limit = buf_limit(sdp);
-       metabufhdrs_needed = (sdp->sd_log_commited_buf +
-                             (mbuf_limit - 1)) / mbuf_limit;
-       dbuf_limit = databuf_limit(sdp);
-       databufhdrs_needed = (sdp->sd_log_commited_databuf +
-                             (dbuf_limit - 1)) / dbuf_limit;
+       if (tr) {
+               mbuf = tr->tr_num_buf_new - tr->tr_num_buf_rm;
+               dbuf = tr->tr_num_databuf_new - tr->tr_num_databuf_rm;
+               reserved = mbuf + dbuf;
+               /* Account for header blocks */
+               reserved += DIV_ROUND_UP(mbuf, buf_limit(sdp));
+               reserved += DIV_ROUND_UP(dbuf, databuf_limit(sdp));
+       }
 
        if (sdp->sd_log_commited_revoke > 0)
-               revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
+               reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
                                          sizeof(u64));
-
-       reserved = sdp->sd_log_commited_buf + metabufhdrs_needed +
-               sdp->sd_log_commited_databuf + databufhdrs_needed +
-               revokes;
        /* One for the overall header */
        if (reserved)
                reserved++;
@@ -682,36 +684,25 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
        }
        trace_gfs2_log_flush(sdp, 1);
 
+       sdp->sd_log_flush_head = sdp->sd_log_head;
+       sdp->sd_log_flush_wrapped = 0;
        tr = sdp->sd_log_tr;
        if (tr) {
                sdp->sd_log_tr = NULL;
                INIT_LIST_HEAD(&tr->tr_ail1_list);
                INIT_LIST_HEAD(&tr->tr_ail2_list);
+               tr->tr_first = sdp->sd_log_flush_head;
        }
 
-       if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) {
-               printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf,
-                      sdp->sd_log_commited_buf);
-               gfs2_assert_withdraw(sdp, 0);
-       }
-       if (sdp->sd_log_num_databuf != sdp->sd_log_commited_databuf) {
-               printk(KERN_INFO "GFS2: log databuf %u %u\n",
-                      sdp->sd_log_num_databuf, sdp->sd_log_commited_databuf);
-               gfs2_assert_withdraw(sdp, 0);
-       }
        gfs2_assert_withdraw(sdp,
                        sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);
 
-       sdp->sd_log_flush_head = sdp->sd_log_head;
-       sdp->sd_log_flush_wrapped = 0;
-       if (tr)
-               tr->tr_first = sdp->sd_log_flush_head;
-
        gfs2_ordered_write(sdp);
-       lops_before_commit(sdp);
+       lops_before_commit(sdp, tr);
        gfs2_log_flush_bio(sdp, WRITE);
 
        if (sdp->sd_log_head != sdp->sd_log_flush_head) {
+               log_flush_wait(sdp);
                log_write_header(sdp, 0);
        } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
                atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
@@ -723,8 +714,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
        gfs2_log_lock(sdp);
        sdp->sd_log_head = sdp->sd_log_flush_head;
        sdp->sd_log_blks_reserved = 0;
-       sdp->sd_log_commited_buf = 0;
-       sdp->sd_log_commited_databuf = 0;
        sdp->sd_log_commited_revoke = 0;
 
        spin_lock(&sdp->sd_ail_lock);
@@ -740,34 +729,54 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
        kfree(tr);
 }
 
+/**
+ * gfs2_merge_trans - Merge a new transaction into a cached transaction
+ * @old: Original transaction to be expanded
+ * @new: New transaction to be merged
+ */
+
+static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new)
+{
+       WARN_ON_ONCE(old->tr_attached != 1);
+
+       old->tr_num_buf_new     += new->tr_num_buf_new;
+       old->tr_num_databuf_new += new->tr_num_databuf_new;
+       old->tr_num_buf_rm      += new->tr_num_buf_rm;
+       old->tr_num_databuf_rm  += new->tr_num_databuf_rm;
+       old->tr_num_revoke      += new->tr_num_revoke;
+       old->tr_num_revoke_rm   += new->tr_num_revoke_rm;
+
+       list_splice_tail_init(&new->tr_databuf, &old->tr_databuf);
+       list_splice_tail_init(&new->tr_buf, &old->tr_buf);
+}
+
 static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
        unsigned int reserved;
        unsigned int unused;
+       unsigned int maxres;
 
        gfs2_log_lock(sdp);
 
-       sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm;
-       sdp->sd_log_commited_databuf += tr->tr_num_databuf_new -
-               tr->tr_num_databuf_rm;
-       gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) ||
-                            (((int)sdp->sd_log_commited_databuf) >= 0));
+       if (sdp->sd_log_tr) {
+               gfs2_merge_trans(sdp->sd_log_tr, tr);
+       } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) {
+               gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl);
+               sdp->sd_log_tr = tr;
+               tr->tr_attached = 1;
+       }
+
        sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
        reserved = calc_reserved(sdp);
-       gfs2_assert_withdraw(sdp, sdp->sd_log_blks_reserved + tr->tr_reserved >= reserved);
-       unused = sdp->sd_log_blks_reserved - reserved + tr->tr_reserved;
+       maxres = sdp->sd_log_blks_reserved + tr->tr_reserved;
+       gfs2_assert_withdraw(sdp, maxres >= reserved);
+       unused = maxres - reserved;
        atomic_add(unused, &sdp->sd_log_blks_free);
        trace_gfs2_log_blocks(sdp, unused);
        gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
                             sdp->sd_jdesc->jd_blocks);
        sdp->sd_log_blks_reserved = reserved;
 
-       if (sdp->sd_log_tr == NULL &&
-           (tr->tr_num_buf_new || tr->tr_num_databuf_new)) {
-               gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl);
-               sdp->sd_log_tr = tr;
-               tr->tr_attached = 1;
-       }
        gfs2_log_unlock(sdp);
 }
 
@@ -807,10 +816,7 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
        down_write(&sdp->sd_log_flush_lock);
 
        gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved);
-       gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf);
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
-       gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg);
-       gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf);
        gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
 
        sdp->sd_log_flush_head = sdp->sd_log_head;
index 76693793ceddfe7f936c360a6c3494d1882a849a..a294d8d8bcd47f8d6b3a26c17a3b6077e5e681c5 100644 (file)
@@ -146,8 +146,8 @@ static u64 gfs2_log_bmap(struct gfs2_sbd *sdp)
        struct gfs2_journal_extent *je;
        u64 block;
 
-       list_for_each_entry(je, &sdp->sd_jdesc->extent_list, extent_list) {
-               if (lbn >= je->lblock && lbn < je->lblock + je->blocks) {
+       list_for_each_entry(je, &sdp->sd_jdesc->extent_list, list) {
+               if ((lbn >= je->lblock) && (lbn < (je->lblock + je->blocks))) {
                        block = je->dblock + lbn - je->lblock;
                        gfs2_log_incr_head(sdp);
                        return block;
@@ -491,44 +491,40 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
        gfs2_log_unlock(sdp);
 }
 
-static void buf_lo_before_commit(struct gfs2_sbd *sdp)
+static void buf_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
        unsigned int limit = buf_limit(sdp); /* 503 for 4k blocks */
-
-       gfs2_before_commit(sdp, limit, sdp->sd_log_num_buf,
-                          &sdp->sd_log_le_buf, 0);
+       unsigned int nbuf;
+       if (tr == NULL)
+               return;
+       nbuf = tr->tr_num_buf_new - tr->tr_num_buf_rm;
+       gfs2_before_commit(sdp, limit, nbuf, &tr->tr_buf, 0);
 }
 
 static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
-       struct list_head *head = &sdp->sd_log_le_buf;
+       struct list_head *head;
        struct gfs2_bufdata *bd;
 
-       if (tr == NULL) {
-               gfs2_assert(sdp, list_empty(head));
+       if (tr == NULL)
                return;
-       }
 
+       head = &tr->tr_buf;
        while (!list_empty(head)) {
                bd = list_entry(head->next, struct gfs2_bufdata, bd_list);
                list_del_init(&bd->bd_list);
-               sdp->sd_log_num_buf--;
-
                gfs2_unpin(sdp, bd->bd_bh, tr);
        }
-       gfs2_assert_warn(sdp, !sdp->sd_log_num_buf);
 }
 
 static void buf_lo_before_scan(struct gfs2_jdesc *jd,
                               struct gfs2_log_header_host *head, int pass)
 {
-       struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
-
        if (pass != 0)
                return;
 
-       sdp->sd_found_blocks = 0;
-       sdp->sd_replayed_blocks = 0;
+       jd->jd_found_blocks = 0;
+       jd->jd_replayed_blocks = 0;
 }
 
 static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
@@ -551,9 +547,9 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
        for (; blks; gfs2_replay_incr_blk(sdp, &start), blks--) {
                blkno = be64_to_cpu(*ptr++);
 
-               sdp->sd_found_blocks++;
+               jd->jd_found_blocks++;
 
-               if (gfs2_revoke_check(sdp, blkno, start))
+               if (gfs2_revoke_check(jd, blkno, start))
                        continue;
 
                error = gfs2_replay_read_block(jd, start, &bh_log);
@@ -574,7 +570,7 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
                if (error)
                        break;
 
-               sdp->sd_replayed_blocks++;
+               jd->jd_replayed_blocks++;
        }
 
        return error;
@@ -617,10 +613,10 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
        gfs2_meta_sync(ip->i_gl);
 
        fs_info(sdp, "jid=%u: Replayed %u of %u blocks\n",
-               jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks);
+               jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
 }
 
-static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
+static void revoke_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
        struct gfs2_meta_header *mh;
        unsigned int offset;
@@ -679,13 +675,11 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
                                  struct gfs2_log_header_host *head, int pass)
 {
-       struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
-
        if (pass != 0)
                return;
 
-       sdp->sd_found_revokes = 0;
-       sdp->sd_replay_tail = head->lh_tail;
+       jd->jd_found_revokes = 0;
+       jd->jd_replay_tail = head->lh_tail;
 }
 
 static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
@@ -717,13 +711,13 @@ static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
                while (offset + sizeof(u64) <= sdp->sd_sb.sb_bsize) {
                        blkno = be64_to_cpu(*(__be64 *)(bh->b_data + offset));
 
-                       error = gfs2_revoke_add(sdp, blkno, start);
+                       error = gfs2_revoke_add(jd, blkno, start);
                        if (error < 0) {
                                brelse(bh);
                                return error;
                        }
                        else if (error)
-                               sdp->sd_found_revokes++;
+                               jd->jd_found_revokes++;
 
                        if (!--revokes)
                                break;
@@ -743,16 +737,16 @@ static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
        struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
 
        if (error) {
-               gfs2_revoke_clean(sdp);
+               gfs2_revoke_clean(jd);
                return;
        }
        if (pass != 1)
                return;
 
        fs_info(sdp, "jid=%u: Found %u revoke tags\n",
-               jd->jd_jid, sdp->sd_found_revokes);
+               jd->jd_jid, jd->jd_found_revokes);
 
-       gfs2_revoke_clean(sdp);
+       gfs2_revoke_clean(jd);
 }
 
 /**
@@ -760,12 +754,14 @@ static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
  *
  */
 
-static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
+static void databuf_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
-       unsigned int limit = buf_limit(sdp) / 2;
-
-       gfs2_before_commit(sdp, limit, sdp->sd_log_num_databuf,
-                          &sdp->sd_log_le_databuf, 1);
+       unsigned int limit = databuf_limit(sdp);
+       unsigned int nbuf;
+       if (tr == NULL)
+               return;
+       nbuf = tr->tr_num_databuf_new - tr->tr_num_databuf_rm;
+       gfs2_before_commit(sdp, limit, nbuf, &tr->tr_databuf, 1);
 }
 
 static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
@@ -789,9 +785,9 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
                blkno = be64_to_cpu(*ptr++);
                esc = be64_to_cpu(*ptr++);
 
-               sdp->sd_found_blocks++;
+               jd->jd_found_blocks++;
 
-               if (gfs2_revoke_check(sdp, blkno, start))
+               if (gfs2_revoke_check(jd, blkno, start))
                        continue;
 
                error = gfs2_replay_read_block(jd, start, &bh_log);
@@ -811,7 +807,7 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
                brelse(bh_log);
                brelse(bh_ip);
 
-               sdp->sd_replayed_blocks++;
+               jd->jd_replayed_blocks++;
        }
 
        return error;
@@ -835,26 +831,23 @@ static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
        gfs2_meta_sync(ip->i_gl);
 
        fs_info(sdp, "jid=%u: Replayed %u of %u data blocks\n",
-               jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks);
+               jd->jd_jid, jd->jd_replayed_blocks, jd->jd_found_blocks);
 }
 
 static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
 {
-       struct list_head *head = &sdp->sd_log_le_databuf;
+       struct list_head *head;
        struct gfs2_bufdata *bd;
 
-       if (tr == NULL) {
-               gfs2_assert(sdp, list_empty(head));
+       if (tr == NULL)
                return;
-       }
 
+       head = &tr->tr_databuf;
        while (!list_empty(head)) {
                bd = list_entry(head->next, struct gfs2_bufdata, bd_list);
                list_del_init(&bd->bd_list);
-               sdp->sd_log_num_databuf--;
                gfs2_unpin(sdp, bd->bd_bh, tr);
        }
-       gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf);
 }
 
 
index 9ca2e6438419a93f0100f16e26405a4e86097922..a65a7ba32ffdf5f9eaaa4be0d25bad4c67db3c74 100644 (file)
@@ -46,12 +46,13 @@ static inline unsigned int databuf_limit(struct gfs2_sbd *sdp)
        return limit;
 }
 
-static inline void lops_before_commit(struct gfs2_sbd *sdp)
+static inline void lops_before_commit(struct gfs2_sbd *sdp,
+                                     struct gfs2_trans *tr)
 {
        int x;
        for (x = 0; gfs2_log_ops[x]; x++)
                if (gfs2_log_ops[x]->lo_before_commit)
-                       gfs2_log_ops[x]->lo_before_commit(sdp);
+                       gfs2_log_ops[x]->lo_before_commit(sdp, tr);
 }
 
 static inline void lops_after_commit(struct gfs2_sbd *sdp,
index c272e73063dede68b4e36c4a3ffc63b682a0c898..82b6ac829656985e4f38c0a6f1ca66db9a7fe395 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -165,7 +167,7 @@ static int __init init_gfs2_fs(void)
 
        gfs2_register_debugfs();
 
-       printk("GFS2 installed\n");
+       pr_info("GFS2 installed\n");
 
        return 0;
 
index c7f24690ed054b0195568ac1762b4401a2e96ac6..2cf09b63a6b4433a2f35095b53a8141325f1bb5f 100644 (file)
@@ -97,6 +97,11 @@ const struct address_space_operations gfs2_meta_aops = {
        .releasepage = gfs2_releasepage,
 };
 
+const struct address_space_operations gfs2_rgrp_aops = {
+       .writepage = gfs2_aspace_writepage,
+       .releasepage = gfs2_releasepage,
+};
+
 /**
  * gfs2_getbuf - Get a buffer with a given address space
  * @gl: the glock
@@ -267,15 +272,10 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int
                trace_gfs2_pin(bd, 0);
                atomic_dec(&sdp->sd_log_pinned);
                list_del_init(&bd->bd_list);
-               if (meta) {
-                       gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
-                       sdp->sd_log_num_buf--;
+               if (meta)
                        tr->tr_num_buf_rm++;
-               } else {
-                       gfs2_assert_warn(sdp, sdp->sd_log_num_databuf);
-                       sdp->sd_log_num_databuf--;
+               else
                        tr->tr_num_databuf_rm++;
-               }
                tr->tr_touched = 1;
                was_pinned = 1;
                brelse(bh);
index 4823b934208a2be6012a71ded8f4e950fca753fb..ac5d8027d33569437f42b76808f8103903c5c3de 100644 (file)
@@ -38,12 +38,15 @@ static inline void gfs2_buffer_copy_tail(struct buffer_head *to_bh,
 }
 
 extern const struct address_space_operations gfs2_meta_aops;
+extern const struct address_space_operations gfs2_rgrp_aops;
 
 static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
 {
        struct inode *inode = mapping->host;
        if (mapping->a_ops == &gfs2_meta_aops)
                return (((struct gfs2_glock *)mapping) - 1)->gl_sbd;
+       else if (mapping->a_ops == &gfs2_rgrp_aops)
+               return container_of(mapping, struct gfs2_sbd, sd_aspace);
        else
                return inode->i_sb->s_fs_info;
 }
index c6872d09561a2d53c8e57374eb700f4fb578ae78..22f954051bb89bd47990c47f6dc986b4dd011561 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -104,7 +106,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
        mapping = &sdp->sd_aspace;
 
        address_space_init_once(mapping);
-       mapping->a_ops = &gfs2_meta_aops;
+       mapping->a_ops = &gfs2_rgrp_aops;
        mapping->host = sb->s_bdev->bd_inode;
        mapping->flags = 0;
        mapping_set_gfp_mask(mapping, GFP_NOFS);
@@ -114,9 +116,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
        spin_lock_init(&sdp->sd_log_lock);
        atomic_set(&sdp->sd_log_pinned, 0);
-       INIT_LIST_HEAD(&sdp->sd_log_le_buf);
        INIT_LIST_HEAD(&sdp->sd_log_le_revoke);
-       INIT_LIST_HEAD(&sdp->sd_log_le_databuf);
        INIT_LIST_HEAD(&sdp->sd_log_le_ordered);
        spin_lock_init(&sdp->sd_ordered_lock);
 
@@ -130,8 +130,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
        atomic_set(&sdp->sd_log_in_flight, 0);
        init_waitqueue_head(&sdp->sd_log_flush_wait);
 
-       INIT_LIST_HEAD(&sdp->sd_revoke_list);
-
        return sdp;
 }
 
@@ -154,7 +152,7 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
        if (sb->sb_magic != GFS2_MAGIC ||
            sb->sb_type != GFS2_METATYPE_SB) {
                if (!silent)
-                       printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n");
+                       pr_warn("not a GFS2 filesystem\n");
                return -EINVAL;
        }
 
@@ -176,7 +174,7 @@ static void end_bio_io_page(struct bio *bio, int error)
        if (!error)
                SetPageUptodate(page);
        else
-               printk(KERN_WARNING "gfs2: error %d reading superblock\n", error);
+               pr_warn("error %d reading superblock\n", error);
        unlock_page(page);
 }
 
@@ -519,67 +517,6 @@ out:
        return ret;
 }
 
-/**
- * map_journal_extents - create a reusable "extent" mapping from all logical
- * blocks to all physical blocks for the given journal.  This will save
- * us time when writing journal blocks.  Most journals will have only one
- * extent that maps all their logical blocks.  That's because gfs2.mkfs
- * arranges the journal blocks sequentially to maximize performance.
- * So the extent would map the first block for the entire file length.
- * However, gfs2_jadd can happen while file activity is happening, so
- * those journals may not be sequential.  Less likely is the case where
- * the users created their own journals by mounting the metafs and
- * laying it out.  But it's still possible.  These journals might have
- * several extents.
- *
- * TODO: This should be done in bigger chunks rather than one block at a time,
- *       but since it's only done at mount time, I'm not worried about the
- *       time it takes.
- */
-static int map_journal_extents(struct gfs2_sbd *sdp)
-{
-       struct gfs2_jdesc *jd = sdp->sd_jdesc;
-       unsigned int lb;
-       u64 db, prev_db; /* logical block, disk block, prev disk block */
-       struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
-       struct gfs2_journal_extent *jext = NULL;
-       struct buffer_head bh;
-       int rc = 0;
-
-       prev_db = 0;
-
-       for (lb = 0; lb < i_size_read(jd->jd_inode) >> sdp->sd_sb.sb_bsize_shift; lb++) {
-               bh.b_state = 0;
-               bh.b_blocknr = 0;
-               bh.b_size = 1 << ip->i_inode.i_blkbits;
-               rc = gfs2_block_map(jd->jd_inode, lb, &bh, 0);
-               db = bh.b_blocknr;
-               if (rc || !db) {
-                       printk(KERN_INFO "GFS2 journal mapping error %d: lb="
-                              "%u db=%llu\n", rc, lb, (unsigned long long)db);
-                       break;
-               }
-               if (!prev_db || db != prev_db + 1) {
-                       jext = kzalloc(sizeof(struct gfs2_journal_extent),
-                                      GFP_KERNEL);
-                       if (!jext) {
-                               printk(KERN_INFO "GFS2 error: out of memory "
-                                      "mapping journal extents.\n");
-                               rc = -ENOMEM;
-                               break;
-                       }
-                       jext->dblock = db;
-                       jext->lblock = lb;
-                       jext->blocks = 1;
-                       list_add_tail(&jext->extent_list, &jd->extent_list);
-               } else {
-                       jext->blocks++;
-               }
-               prev_db = db;
-       }
-       return rc;
-}
-
 static void gfs2_others_may_mount(struct gfs2_sbd *sdp)
 {
        char *message = "FIRSTMOUNT=Done";
@@ -638,6 +575,8 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
                        break;
 
                INIT_LIST_HEAD(&jd->extent_list);
+               INIT_LIST_HEAD(&jd->jd_revoke_list);
+
                INIT_WORK(&jd->jd_work, gfs2_recover_func);
                jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1);
                if (!jd->jd_inode || IS_ERR(jd->jd_inode)) {
@@ -781,7 +720,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
                atomic_set(&sdp->sd_log_thresh2, 4*sdp->sd_jdesc->jd_blocks/5);
 
                /* Map the extents for this journal's blocks */
-               map_journal_extents(sdp);
+               gfs2_map_journal_extents(sdp, sdp->sd_jdesc);
        }
        trace_gfs2_log_blocks(sdp, atomic_read(&sdp->sd_log_blks_free));
 
@@ -1008,7 +947,7 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
                lm = &gfs2_dlm_ops;
 #endif
        } else {
-               printk(KERN_INFO "GFS2: can't find protocol %s\n", proto);
+               pr_info("can't find protocol %s\n", proto);
                return -ENOENT;
        }
 
@@ -1115,7 +1054,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
 
        sdp = init_sbd(sb);
        if (!sdp) {
-               printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
+               pr_warn("can't alloc struct gfs2_sbd\n");
                return -ENOMEM;
        }
        sdp->sd_args = *args;
@@ -1363,7 +1302,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
 
        error = gfs2_mount_args(&args, data);
        if (error) {
-               printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
+               pr_warn("can't parse mount arguments\n");
                goto error_super;
        }
 
@@ -1413,15 +1352,15 @@ static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type,
 
        error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
        if (error) {
-               printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
-                      dev_name, error);
+               pr_warn("path_lookup on %s returned error %d\n",
+                       dev_name, error);
                return ERR_PTR(error);
        }
        s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, flags,
                 path.dentry->d_inode->i_sb->s_bdev);
        path_put(&path);
        if (IS_ERR(s)) {
-               printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
+               pr_warn("gfs2 mount does not exist\n");
                return ERR_CAST(s);
        }
        if ((flags ^ s->s_flags) & MS_RDONLY) {
index 8bec0e3192ddec78a0e04c3f3872de5b622105b5..c4effff7cf559c701e890e804cef81dfb1cac30e 100644 (file)
@@ -36,6 +36,8 @@
  * the quota file, so it is not being constantly read.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
@@ -330,6 +332,7 @@ static int slot_get(struct gfs2_quota_data *qd)
        if (bit < sdp->sd_quota_slots) {
                set_bit(bit, sdp->sd_quota_bitmap);
                qd->qd_slot = bit;
+               error = 0;
 out:
                qd->qd_slot_count++;
        }
@@ -1081,10 +1084,10 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
 {
        struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
 
-       printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n",
-              sdp->sd_fsname, type,
-              (qd->qd_id.type == USRQUOTA) ? "user" : "group",
-              from_kqid(&init_user_ns, qd->qd_id));
+       fs_info(sdp, "quota %s for %s %u\n",
+               type,
+               (qd->qd_id.type == USRQUOTA) ? "user" : "group",
+               from_kqid(&init_user_ns, qd->qd_id));
 
        return 0;
 }
@@ -1242,14 +1245,13 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
        bm_size = DIV_ROUND_UP(sdp->sd_quota_slots, 8 * sizeof(unsigned long));
        bm_size *= sizeof(unsigned long);
        error = -ENOMEM;
-       sdp->sd_quota_bitmap = kmalloc(bm_size, GFP_NOFS|__GFP_NOWARN);
+       sdp->sd_quota_bitmap = kzalloc(bm_size, GFP_NOFS | __GFP_NOWARN);
        if (sdp->sd_quota_bitmap == NULL)
-               sdp->sd_quota_bitmap = __vmalloc(bm_size, GFP_NOFS, PAGE_KERNEL);
+               sdp->sd_quota_bitmap = __vmalloc(bm_size, GFP_NOFS |
+                                                __GFP_ZERO, PAGE_KERNEL);
        if (!sdp->sd_quota_bitmap)
                return error;
 
-       memset(sdp->sd_quota_bitmap, 0, bm_size);
-
        for (x = 0; x < blocks; x++) {
                struct buffer_head *bh;
                const struct gfs2_quota_change *qc;
index 963b2d75200c7fc5ae62591f458133540178db30..7ad4094d68c0243981ea244b4ac75914e66f0ab7 100644 (file)
@@ -52,9 +52,9 @@ int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
        return error;
 }
 
-int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where)
+int gfs2_revoke_add(struct gfs2_jdesc *jd, u64 blkno, unsigned int where)
 {
-       struct list_head *head = &sdp->sd_revoke_list;
+       struct list_head *head = &jd->jd_revoke_list;
        struct gfs2_revoke_replay *rr;
        int found = 0;
 
@@ -81,13 +81,13 @@ int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where)
        return 1;
 }
 
-int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where)
+int gfs2_revoke_check(struct gfs2_jdesc *jd, u64 blkno, unsigned int where)
 {
        struct gfs2_revoke_replay *rr;
        int wrap, a, b, revoke;
        int found = 0;
 
-       list_for_each_entry(rr, &sdp->sd_revoke_list, rr_list) {
+       list_for_each_entry(rr, &jd->jd_revoke_list, rr_list) {
                if (rr->rr_blkno == blkno) {
                        found = 1;
                        break;
@@ -97,17 +97,17 @@ int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where)
        if (!found)
                return 0;
 
-       wrap = (rr->rr_where < sdp->sd_replay_tail);
-       a = (sdp->sd_replay_tail < where);
+       wrap = (rr->rr_where < jd->jd_replay_tail);
+       a = (jd->jd_replay_tail < where);
        b = (where < rr->rr_where);
        revoke = (wrap) ? (a || b) : (a && b);
 
        return revoke;
 }
 
-void gfs2_revoke_clean(struct gfs2_sbd *sdp)
+void gfs2_revoke_clean(struct gfs2_jdesc *jd)
 {
-       struct list_head *head = &sdp->sd_revoke_list;
+       struct list_head *head = &jd->jd_revoke_list;
        struct gfs2_revoke_replay *rr;
 
        while (!list_empty(head)) {
index 2226136c7647372c2e2a80fc20ebf439a8809dcf..6142836cce961484acb8139d4d86683f7b8daa15 100644 (file)
@@ -23,9 +23,9 @@ static inline void gfs2_replay_incr_blk(struct gfs2_sbd *sdp, unsigned int *blk)
 extern int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
                           struct buffer_head **bh);
 
-extern int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where);
-extern int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where);
-extern void gfs2_revoke_clean(struct gfs2_sbd *sdp);
+extern int gfs2_revoke_add(struct gfs2_jdesc *jd, u64 blkno, unsigned int where);
+extern int gfs2_revoke_check(struct gfs2_jdesc *jd, u64 blkno, unsigned int where);
+extern void gfs2_revoke_clean(struct gfs2_jdesc *jd);
 
 extern int gfs2_find_jhead(struct gfs2_jdesc *jd,
                    struct gfs2_log_header_host *head);
index a1da2134923592e7ca9feaa1a3c1a6b707946df2..281a7716e3f3703bf6cd97902330118521e85625 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -99,12 +101,12 @@ static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone,
        cur_state = (*byte1 >> bit) & GFS2_BIT_MASK;
 
        if (unlikely(!valid_change[new_state * 4 + cur_state])) {
-               printk(KERN_WARNING "GFS2: buf_blk = 0x%x old_state=%d, "
-                      "new_state=%d\n", rbm->offset, cur_state, new_state);
-               printk(KERN_WARNING "GFS2: rgrp=0x%llx bi_start=0x%x\n",
-                      (unsigned long long)rbm->rgd->rd_addr, bi->bi_start);
-               printk(KERN_WARNING "GFS2: bi_offset=0x%x bi_len=0x%x\n",
-                      bi->bi_offset, bi->bi_len);
+               pr_warn("buf_blk = 0x%x old_state=%d, new_state=%d\n",
+                       rbm->offset, cur_state, new_state);
+               pr_warn("rgrp=0x%llx bi_start=0x%x\n",
+                       (unsigned long long)rbm->rgd->rd_addr, bi->bi_start);
+               pr_warn("bi_offset=0x%x bi_len=0x%x\n",
+                       bi->bi_offset, bi->bi_len);
                dump_stack();
                gfs2_consist_rgrpd(rbm->rgd);
                return;
@@ -736,11 +738,11 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
 
 static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd)
 {
-       printk(KERN_INFO "  ri_addr = %llu\n", (unsigned long long)rgd->rd_addr);
-       printk(KERN_INFO "  ri_length = %u\n", rgd->rd_length);
-       printk(KERN_INFO "  ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0);
-       printk(KERN_INFO "  ri_data = %u\n", rgd->rd_data);
-       printk(KERN_INFO "  ri_bitbytes = %u\n", rgd->rd_bitbytes);
+       pr_info("ri_addr = %llu\n", (unsigned long long)rgd->rd_addr);
+       pr_info("ri_length = %u\n", rgd->rd_length);
+       pr_info("ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0);
+       pr_info("ri_data = %u\n", rgd->rd_data);
+       pr_info("ri_bitbytes = %u\n", rgd->rd_bitbytes);
 }
 
 /**
@@ -1102,7 +1104,7 @@ static u32 count_unlinked(struct gfs2_rgrpd *rgd)
  * Returns: errno
  */
 
-int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
+static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
 {
        struct gfs2_sbd *sdp = rgd->rd_sbd;
        struct gfs2_glock *gl = rgd->rd_gl;
@@ -1169,7 +1171,7 @@ fail:
        return error;
 }
 
-int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
+static int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
 {
        u32 rl_flags;
 
@@ -2278,7 +2280,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
                }
        }
        if (rbm.rgd->rd_free < *nblocks) {
-               printk(KERN_WARNING "nblocks=%u\n", *nblocks);
+               pr_warn("nblocks=%u\n", *nblocks);
                goto rgrp_error;
        }
 
@@ -2296,7 +2298,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
 
        gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0);
        if (dinode)
-               gfs2_trans_add_unrevoke(sdp, block, 1);
+               gfs2_trans_add_unrevoke(sdp, block, *nblocks);
 
        gfs2_quota_change(ip, *nblocks, ip->i_inode.i_uid, ip->i_inode.i_gid);
 
index 24410cd9a82a117b020dbaee02728eb06e7baed2..de8afad89e5103fe495a1e416bd0714e6e3762b4 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/bio.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -175,8 +177,7 @@ int gfs2_mount_args(struct gfs2_args *args, char *options)
                        break;
                case Opt_debug:
                        if (args->ar_errors == GFS2_ERRORS_PANIC) {
-                               printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
-                                      "are mutually exclusive.\n");
+                               pr_warn("-o debug and -o errors=panic are mutually exclusive\n");
                                return -EINVAL;
                        }
                        args->ar_debug = 1;
@@ -228,21 +229,21 @@ int gfs2_mount_args(struct gfs2_args *args, char *options)
                case Opt_commit:
                        rv = match_int(&tmp[0], &args->ar_commit);
                        if (rv || args->ar_commit <= 0) {
-                               printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n");
+                               pr_warn("commit mount option requires a positive numeric argument\n");
                                return rv ? rv : -EINVAL;
                        }
                        break;
                case Opt_statfs_quantum:
                        rv = match_int(&tmp[0], &args->ar_statfs_quantum);
                        if (rv || args->ar_statfs_quantum < 0) {
-                               printk(KERN_WARNING "GFS2: statfs_quantum mount option requires a non-negative numeric argument\n");
+                               pr_warn("statfs_quantum mount option requires a non-negative numeric argument\n");
                                return rv ? rv : -EINVAL;
                        }
                        break;
                case Opt_quota_quantum:
                        rv = match_int(&tmp[0], &args->ar_quota_quantum);
                        if (rv || args->ar_quota_quantum <= 0) {
-                               printk(KERN_WARNING "GFS2: quota_quantum mount option requires a positive numeric argument\n");
+                               pr_warn("quota_quantum mount option requires a positive numeric argument\n");
                                return rv ? rv : -EINVAL;
                        }
                        break;
@@ -250,7 +251,7 @@ int gfs2_mount_args(struct gfs2_args *args, char *options)
                        rv = match_int(&tmp[0], &args->ar_statfs_percent);
                        if (rv || args->ar_statfs_percent < 0 ||
                            args->ar_statfs_percent > 100) {
-                               printk(KERN_WARNING "statfs_percent mount option requires a numeric argument between 0 and 100\n");
+                               pr_warn("statfs_percent mount option requires a numeric argument between 0 and 100\n");
                                return rv ? rv : -EINVAL;
                        }
                        break;
@@ -259,8 +260,7 @@ int gfs2_mount_args(struct gfs2_args *args, char *options)
                        break;
                case Opt_err_panic:
                        if (args->ar_debug) {
-                               printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
-                                       "are mutually exclusive.\n");
+                               pr_warn("-o debug and -o errors=panic are mutually exclusive\n");
                                return -EINVAL;
                        }
                        args->ar_errors = GFS2_ERRORS_PANIC;
@@ -279,7 +279,7 @@ int gfs2_mount_args(struct gfs2_args *args, char *options)
                        break;
                case Opt_error:
                default:
-                       printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o);
+                       pr_warn("invalid mount option: %s\n", o);
                        return -EINVAL;
                }
        }
@@ -295,9 +295,8 @@ int gfs2_mount_args(struct gfs2_args *args, char *options)
 
 void gfs2_jindex_free(struct gfs2_sbd *sdp)
 {
-       struct list_head list, *head;
+       struct list_head list;
        struct gfs2_jdesc *jd;
-       struct gfs2_journal_extent *jext;
 
        spin_lock(&sdp->sd_jindex_spin);
        list_add(&list, &sdp->sd_jindex_list);
@@ -307,14 +306,7 @@ void gfs2_jindex_free(struct gfs2_sbd *sdp)
 
        while (!list_empty(&list)) {
                jd = list_entry(list.next, struct gfs2_jdesc, jd_list);
-               head = &jd->extent_list;
-               while (!list_empty(head)) {
-                       jext = list_entry(head->next,
-                                         struct gfs2_journal_extent,
-                                         extent_list);
-                       list_del(&jext->extent_list);
-                       kfree(jext);
-               }
+               gfs2_free_journal_extents(jd);
                list_del(&jd->jd_list);
                iput(jd->jd_inode);
                kfree(jd);
@@ -1175,6 +1167,8 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
        struct gfs2_tune *gt = &sdp->sd_tune;
        int error;
 
+       sync_filesystem(sb);
+
        spin_lock(&gt->gt_spin);
        args.ar_commit = gt->gt_logd_secs;
        args.ar_quota_quantum = gt->gt_quota_quantum;
@@ -1256,7 +1250,7 @@ static int gfs2_drop_inode(struct inode *inode)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
 
-       if (inode->i_nlink) {
+       if (!test_bit(GIF_FREE_VFS_INODE, &ip->i_flags) && inode->i_nlink) {
                struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
                if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
                        clear_nlink(inode);
@@ -1471,6 +1465,11 @@ static void gfs2_evict_inode(struct inode *inode)
        struct gfs2_holder gh;
        int error;
 
+       if (test_bit(GIF_FREE_VFS_INODE, &ip->i_flags)) {
+               clear_inode(inode);
+               return;
+       }
+
        if (inode->i_nlink || (sb->s_flags & MS_RDONLY))
                goto out;
 
index d09f6edda0ff8d55f31ef04dba7f4720852f7a8d..de25d5577e5dd48869354f8e1e1a2e0ec514e35d 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -138,9 +140,8 @@ static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
        if (simple_strtol(buf, NULL, 0) != 1)
                return -EINVAL;
 
-       gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: withdrawing from cluster at user's request\n",
-               sdp->sd_fsname);
+       gfs2_lm_withdraw(sdp, "withdrawing from cluster at user's request\n");
+
        return len;
 }
 
index 2b20d7046bf353ff58381821d1fea363010f3716..bead90d27badd3b708c88e75d4e8867ed2da805f 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -51,6 +53,9 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
        if (revokes)
                tr->tr_reserved += gfs2_struct2blk(sdp, revokes,
                                                   sizeof(u64));
+       INIT_LIST_HEAD(&tr->tr_databuf);
+       INIT_LIST_HEAD(&tr->tr_buf);
+
        sb_start_intwrite(sdp->sd_vfs);
        gfs2_holder_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &tr->tr_t_gh);
 
@@ -96,14 +101,13 @@ static void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
 
 static void gfs2_print_trans(const struct gfs2_trans *tr)
 {
-       printk(KERN_WARNING "GFS2: Transaction created at: %pSR\n",
-              (void *)tr->tr_ip);
-       printk(KERN_WARNING "GFS2: blocks=%u revokes=%u reserved=%u touched=%d\n",
-              tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_touched);
-       printk(KERN_WARNING "GFS2: Buf %u/%u Databuf %u/%u Revoke %u/%u\n",
-              tr->tr_num_buf_new, tr->tr_num_buf_rm,
-              tr->tr_num_databuf_new, tr->tr_num_databuf_rm,
-              tr->tr_num_revoke, tr->tr_num_revoke_rm);
+       pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip);
+       pr_warn("blocks=%u revokes=%u reserved=%u touched=%u\n",
+               tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_touched);
+       pr_warn("Buf %u/%u Databuf %u/%u Revoke %u/%u\n",
+               tr->tr_num_buf_new, tr->tr_num_buf_rm,
+               tr->tr_num_databuf_new, tr->tr_num_databuf_rm,
+               tr->tr_num_revoke, tr->tr_num_revoke_rm);
 }
 
 void gfs2_trans_end(struct gfs2_sbd *sdp)
@@ -210,8 +214,7 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh)
                set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
                gfs2_pin(sdp, bd->bd_bh);
                tr->tr_num_databuf_new++;
-               sdp->sd_log_num_databuf++;
-               list_add_tail(&bd->bd_list, &sdp->sd_log_le_databuf);
+               list_add_tail(&bd->bd_list, &tr->tr_databuf);
        }
        gfs2_log_unlock(sdp);
        unlock_buffer(bh);
@@ -230,16 +233,14 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
        set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
        mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
        if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) {
-               printk(KERN_ERR
-                      "Attempting to add uninitialised block to journal (inplace block=%lld)\n",
+               pr_err("Attempting to add uninitialised block to journal (inplace block=%lld)\n",
                       (unsigned long long)bd->bd_bh->b_blocknr);
                BUG();
        }
        gfs2_pin(sdp, bd->bd_bh);
        mh->__pad0 = cpu_to_be64(0);
        mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
-       sdp->sd_log_num_buf++;
-       list_add(&bd->bd_list, &sdp->sd_log_le_buf);
+       list_add(&bd->bd_list, &tr->tr_buf);
        tr->tr_num_buf_new++;
 }
 
index f7109f689e6132d08b7fcfc6a0c69db63dc0c24f..86d2035ac669bf42cbcad16c9baa72baaf27ca1b 100644 (file)
@@ -7,6 +7,8 @@
  * of the GNU General Public License version 2.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
@@ -30,22 +32,27 @@ mempool_t *gfs2_page_pool __read_mostly;
 
 void gfs2_assert_i(struct gfs2_sbd *sdp)
 {
-       printk(KERN_EMERG "GFS2: fsid=%s: fatal assertion failed\n",
-              sdp->sd_fsname);
+       fs_emerg(sdp, "fatal assertion failed\n");
 }
 
-int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...)
+int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...)
 {
        struct lm_lockstruct *ls = &sdp->sd_lockstruct;
        const struct lm_lockops *lm = ls->ls_ops;
        va_list args;
+       struct va_format vaf;
 
        if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
            test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
                return 0;
 
        va_start(args, fmt);
-       vprintk(fmt, args);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       fs_err(sdp, "%pV", &vaf);
+
        va_end(args);
 
        if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
@@ -66,7 +73,7 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...)
        }
 
        if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
-               panic("GFS2: fsid=%s: panic requested.\n", sdp->sd_fsname);
+               panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname);
 
        return -1;
 }
@@ -82,10 +89,9 @@ int gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
 {
        int me;
        me = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: assertion \"%s\" failed\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname, assertion,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: assertion \"%s\" failed\n"
+                             "   function = %s, file = %s, line = %u\n",
+                             assertion, function, file, line);
        dump_stack();
        return (me) ? -1 : -2;
 }
@@ -105,11 +111,8 @@ int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
                return -2;
 
        if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
-               printk(KERN_WARNING
-                      "GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
-                      "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-                      sdp->sd_fsname, assertion,
-                      sdp->sd_fsname, function, file, line);
+               fs_warn(sdp, "warning: assertion \"%s\" failed at function = %s, file = %s, line = %u\n",
+                       assertion, function, file, line);
 
        if (sdp->sd_args.ar_debug)
                BUG();
@@ -138,10 +141,8 @@ int gfs2_consist_i(struct gfs2_sbd *sdp, int cluster_wide, const char *function,
 {
        int rv;
        rv = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: filesystem consistency error\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: filesystem consistency error - function = %s, file = %s, line = %u\n",
+                             function, file, line);
        return rv;
 }
 
@@ -157,13 +158,12 @@ int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        int rv;
        rv = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: filesystem consistency error\n"
-               "GFS2: fsid=%s:   inode = %llu %llu\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino,
-               (unsigned long long)ip->i_no_addr,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: filesystem consistency error\n"
+                             "  inode = %llu %llu\n"
+                             "  function = %s, file = %s, line = %u\n",
+                             (unsigned long long)ip->i_no_formal_ino,
+                             (unsigned long long)ip->i_no_addr,
+                             function, file, line);
        return rv;
 }
 
@@ -179,12 +179,11 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide,
        struct gfs2_sbd *sdp = rgd->rd_sbd;
        int rv;
        rv = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: filesystem consistency error\n"
-               "GFS2: fsid=%s:   RG = %llu\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)rgd->rd_addr,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: filesystem consistency error\n"
+                             "  RG = %llu\n"
+                             "  function = %s, file = %s, line = %u\n",
+                             (unsigned long long)rgd->rd_addr,
+                             function, file, line);
        return rv;
 }
 
@@ -200,12 +199,11 @@ int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
 {
        int me;
        me = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: invalid metadata block\n"
-               "GFS2: fsid=%s:   bh = %llu (%s)\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)bh->b_blocknr, type,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: invalid metadata block\n"
+                             "  bh = %llu (%s)\n"
+                             "  function = %s, file = %s, line = %u\n",
+                             (unsigned long long)bh->b_blocknr, type,
+                             function, file, line);
        return (me) ? -1 : -2;
 }
 
@@ -221,12 +219,11 @@ int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
 {
        int me;
        me = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: invalid metadata block\n"
-               "GFS2: fsid=%s:   bh = %llu (type: exp=%u, found=%u)\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)bh->b_blocknr, type, t,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: invalid metadata block\n"
+                             "  bh = %llu (type: exp=%u, found=%u)\n"
+                             "  function = %s, file = %s, line = %u\n",
+                             (unsigned long long)bh->b_blocknr, type, t,
+                             function, file, line);
        return (me) ? -1 : -2;
 }
 
@@ -241,10 +238,9 @@ int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
 {
        int rv;
        rv = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: I/O error\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: I/O error\n"
+                             "  function = %s, file = %s, line = %u\n",
+                             function, file, line);
        return rv;
 }
 
@@ -259,12 +255,11 @@ int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
 {
        int rv;
        rv = gfs2_lm_withdraw(sdp,
-               "GFS2: fsid=%s: fatal: I/O error\n"
-               "GFS2: fsid=%s:   block = %llu\n"
-               "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-               sdp->sd_fsname,
-               sdp->sd_fsname, (unsigned long long)bh->b_blocknr,
-               sdp->sd_fsname, function, file, line);
+                             "fatal: I/O error\n"
+                             "  block = %llu\n"
+                             "  function = %s, file = %s, line = %u\n",
+                             (unsigned long long)bh->b_blocknr,
+                             function, file, line);
        return rv;
 }
 
index b7ffb09b99ea2d231011b92c21fa64a3e0bcfa6d..cbdcbdf39614815cbba5b01e82d566706d31d851 100644 (file)
 #ifndef __UTIL_DOT_H__
 #define __UTIL_DOT_H__
 
+#ifdef pr_fmt
+#undef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#endif
+
 #include <linux/mempool.h>
 
 #include "incore.h"
 
-#define fs_printk(level, fs, fmt, arg...) \
-       printk(level "GFS2: fsid=%s: " fmt , (fs)->sd_fsname , ## arg)
-
-#define fs_info(fs, fmt, arg...) \
-       fs_printk(KERN_INFO , fs , fmt , ## arg)
-
-#define fs_warn(fs, fmt, arg...) \
-       fs_printk(KERN_WARNING , fs , fmt , ## arg)
-
-#define fs_err(fs, fmt, arg...) \
-       fs_printk(KERN_ERR, fs , fmt , ## arg)
-
+#define fs_emerg(fs, fmt, ...)                                         \
+       pr_emerg("fsid=%s: " fmt, (fs)->sd_fsname, ##__VA_ARGS__)
+#define fs_warn(fs, fmt, ...)                                          \
+       pr_warn("fsid=%s: " fmt, (fs)->sd_fsname, ##__VA_ARGS__)
+#define fs_err(fs, fmt, ...)                                           \
+       pr_err("fsid=%s: " fmt, (fs)->sd_fsname, ##__VA_ARGS__)
+#define fs_info(fs, fmt, ...)                                          \
+       pr_info("fsid=%s: " fmt, (fs)->sd_fsname, ##__VA_ARGS__)
 
 void gfs2_assert_i(struct gfs2_sbd *sdp);
 
@@ -85,7 +86,7 @@ static inline int gfs2_meta_check(struct gfs2_sbd *sdp,
        struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data;
        u32 magic = be32_to_cpu(mh->mh_magic);
        if (unlikely(magic != GFS2_MAGIC)) {
-               printk(KERN_ERR "GFS2: Magic number missing at %llu\n",
+               pr_err("Magic number missing at %llu\n",
                       (unsigned long long)bh->b_blocknr);
                return -EIO;
        }
@@ -164,7 +165,7 @@ static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
 #define gfs2_tune_get(sdp, field) \
 gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field)
 
-int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...);
+__printf(2, 3)
+int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...);
 
 #endif /* __UTIL_DOT_H__ */
-
index 2d2039e754cdb8e7182053ea5666ed64d14ca488..eee7206c38d18e1a3d3b1697fd429763e3fe9f5b 100644 (file)
@@ -112,6 +112,7 @@ static int hfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int hfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
index a6abf87d79d0b4b6fb75e2cdfe15613e9def2c93..a513d2d36be956c0a82314d786941ceb0b9f8990 100644 (file)
@@ -323,6 +323,7 @@ static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
        if (!(*flags & MS_RDONLY)) {
index 4534ff688b767e56b08302b6cedb199cdafeff4d..fe3463a432365f5ba3596dd4d1db0f7bb1d95c6f 100644 (file)
@@ -421,6 +421,8 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
        struct hpfs_sb_info *sbi = hpfs_sb(s);
        char *new_opts = kstrdup(data, GFP_KERNEL);
        
+       sync_filesystem(s);
+
        *flags |= MS_NOATIME;
        
        hpfs_lock(s);
index e6905152c39fcc4abbb52190585ff2c6d2b300a2..f96d2a6f88cca3a2e7c6e40bd122a7edeb43fc35 100644 (file)
@@ -944,24 +944,22 @@ EXPORT_SYMBOL(unlock_new_inode);
 
 /**
  * lock_two_nondirectories - take two i_mutexes on non-directory objects
+ *
+ * Lock any non-NULL argument that is not a directory.
+ * Zero, one or two objects may be locked by this function.
+ *
  * @inode1: first inode to lock
  * @inode2: second inode to lock
  */
 void lock_two_nondirectories(struct inode *inode1, struct inode *inode2)
 {
-       WARN_ON_ONCE(S_ISDIR(inode1->i_mode));
-       if (inode1 == inode2 || !inode2) {
-               mutex_lock(&inode1->i_mutex);
-               return;
-       }
-       WARN_ON_ONCE(S_ISDIR(inode2->i_mode));
-       if (inode1 < inode2) {
+       if (inode1 > inode2)
+               swap(inode1, inode2);
+
+       if (inode1 && !S_ISDIR(inode1->i_mode))
                mutex_lock(&inode1->i_mutex);
+       if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1)
                mutex_lock_nested(&inode2->i_mutex, I_MUTEX_NONDIR2);
-       } else {
-               mutex_lock(&inode2->i_mutex);
-               mutex_lock_nested(&inode1->i_mutex, I_MUTEX_NONDIR2);
-       }
 }
 EXPORT_SYMBOL(lock_two_nondirectories);
 
@@ -972,8 +970,9 @@ EXPORT_SYMBOL(lock_two_nondirectories);
  */
 void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2)
 {
-       mutex_unlock(&inode1->i_mutex);
-       if (inode2 && inode2 != inode1)
+       if (inode1 && !S_ISDIR(inode1->i_mode))
+               mutex_unlock(&inode1->i_mutex);
+       if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1)
                mutex_unlock(&inode2->i_mutex);
 }
 EXPORT_SYMBOL(unlock_two_nondirectories);
@@ -1899,3 +1898,34 @@ void inode_dio_done(struct inode *inode)
                wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
 }
 EXPORT_SYMBOL(inode_dio_done);
+
+/*
+ * inode_set_flags - atomically set some inode flags
+ *
+ * Note: the caller should be holding i_mutex, or else be sure that
+ * they have exclusive access to the inode structure (i.e., while the
+ * inode is being instantiated).  The reason for the cmpxchg() loop
+ * --- which wouldn't be necessary if all code paths which modify
+ * i_flags actually followed this rule, is that there is at least one
+ * code path which doesn't today --- for example,
+ * __generic_file_aio_write() calls file_remove_suid() without holding
+ * i_mutex --- so we use cmpxchg() out of an abundance of caution.
+ *
+ * In the long run, i_mutex is overkill, and we should probably look
+ * at using the i_lock spinlock to protect i_flags, and then make sure
+ * it is so documented in include/linux/fs.h and that all code follows
+ * the locking convention!!
+ */
+void inode_set_flags(struct inode *inode, unsigned int flags,
+                    unsigned int mask)
+{
+       unsigned int old_flags, new_flags;
+
+       WARN_ON_ONCE(flags & ~mask);
+       do {
+               old_flags = ACCESS_ONCE(inode->i_flags);
+               new_flags = (old_flags & ~mask) | flags;
+       } while (unlikely(cmpxchg(&inode->i_flags, old_flags,
+                                 new_flags) != old_flags));
+}
+EXPORT_SYMBOL(inode_set_flags);
index 4a9e10ea13f2910570e989bdb2746fcc9ab796b1..6af66ee56390793ed3b1f718f2cb07cba8b92a50 100644 (file)
@@ -117,6 +117,7 @@ static void destroy_inodecache(void)
 
 static int isofs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if (!(*flags & MS_RDONLY))
                return -EROFS;
        return 0;
index cf2fc0594063f04210f036fc0024db1b1d7491e3..5f26139a165a7081dd2f835222f26dcbc5d3bf4a 100644 (file)
@@ -555,7 +555,6 @@ void jbd2_journal_commit_transaction(journal_t *journal)
        blk_start_plug(&plug);
        jbd2_journal_write_revoke_records(journal, commit_transaction,
                                          &log_bufs, WRITE_SYNC);
-       blk_finish_plug(&plug);
 
        jbd_debug(3, "JBD2: commit phase 2b\n");
 
@@ -582,7 +581,6 @@ void jbd2_journal_commit_transaction(journal_t *journal)
        err = 0;
        bufs = 0;
        descriptor = NULL;
-       blk_start_plug(&plug);
        while (commit_transaction->t_buffers) {
 
                /* Find the next buffer to be journaled... */
@@ -1067,6 +1065,25 @@ restart_loop:
                goto restart_loop;
        }
 
+       /* Add the transaction to the checkpoint list
+        * __journal_remove_checkpoint() can not destroy transaction
+        * under us because it is not marked as T_FINISHED yet */
+       if (journal->j_checkpoint_transactions == NULL) {
+               journal->j_checkpoint_transactions = commit_transaction;
+               commit_transaction->t_cpnext = commit_transaction;
+               commit_transaction->t_cpprev = commit_transaction;
+       } else {
+               commit_transaction->t_cpnext =
+                       journal->j_checkpoint_transactions;
+               commit_transaction->t_cpprev =
+                       commit_transaction->t_cpnext->t_cpprev;
+               commit_transaction->t_cpnext->t_cpprev =
+                       commit_transaction;
+               commit_transaction->t_cpprev->t_cpnext =
+                               commit_transaction;
+       }
+       spin_unlock(&journal->j_list_lock);
+
        /* Done with this transaction! */
 
        jbd_debug(3, "JBD2: commit phase 7\n");
@@ -1085,24 +1102,7 @@ restart_loop:
                atomic_read(&commit_transaction->t_handle_count);
        trace_jbd2_run_stats(journal->j_fs_dev->bd_dev,
                             commit_transaction->t_tid, &stats.run);
-
-       /*
-        * Calculate overall stats
-        */
-       spin_lock(&journal->j_history_lock);
-       journal->j_stats.ts_tid++;
-       if (commit_transaction->t_requested)
-               journal->j_stats.ts_requested++;
-       journal->j_stats.run.rs_wait += stats.run.rs_wait;
-       journal->j_stats.run.rs_request_delay += stats.run.rs_request_delay;
-       journal->j_stats.run.rs_running += stats.run.rs_running;
-       journal->j_stats.run.rs_locked += stats.run.rs_locked;
-       journal->j_stats.run.rs_flushing += stats.run.rs_flushing;
-       journal->j_stats.run.rs_logging += stats.run.rs_logging;
-       journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count;
-       journal->j_stats.run.rs_blocks += stats.run.rs_blocks;
-       journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
-       spin_unlock(&journal->j_history_lock);
+       stats.ts_requested = (commit_transaction->t_requested) ? 1 : 0;
 
        commit_transaction->t_state = T_COMMIT_CALLBACK;
        J_ASSERT(commit_transaction == journal->j_committing_transaction);
@@ -1122,24 +1122,6 @@ restart_loop:
 
        write_unlock(&journal->j_state_lock);
 
-       if (journal->j_checkpoint_transactions == NULL) {
-               journal->j_checkpoint_transactions = commit_transaction;
-               commit_transaction->t_cpnext = commit_transaction;
-               commit_transaction->t_cpprev = commit_transaction;
-       } else {
-               commit_transaction->t_cpnext =
-                       journal->j_checkpoint_transactions;
-               commit_transaction->t_cpprev =
-                       commit_transaction->t_cpnext->t_cpprev;
-               commit_transaction->t_cpnext->t_cpprev =
-                       commit_transaction;
-               commit_transaction->t_cpprev->t_cpnext =
-                               commit_transaction;
-       }
-       spin_unlock(&journal->j_list_lock);
-       /* Drop all spin_locks because commit_callback may be block.
-        * __journal_remove_checkpoint() can not destroy transaction
-        * under us because it is not marked as T_FINISHED yet */
        if (journal->j_commit_callback)
                journal->j_commit_callback(journal, commit_transaction);
 
@@ -1150,7 +1132,7 @@ restart_loop:
        write_lock(&journal->j_state_lock);
        spin_lock(&journal->j_list_lock);
        commit_transaction->t_state = T_FINISHED;
-       /* Recheck checkpoint lists after j_list_lock was dropped */
+       /* Check if the transaction can be dropped now that we are finished */
        if (commit_transaction->t_checkpoint_list == NULL &&
            commit_transaction->t_checkpoint_io_list == NULL) {
                __jbd2_journal_drop_transaction(journal, commit_transaction);
@@ -1159,4 +1141,21 @@ restart_loop:
        spin_unlock(&journal->j_list_lock);
        write_unlock(&journal->j_state_lock);
        wake_up(&journal->j_wait_done_commit);
+
+       /*
+        * Calculate overall stats
+        */
+       spin_lock(&journal->j_history_lock);
+       journal->j_stats.ts_tid++;
+       journal->j_stats.ts_requested += stats.ts_requested;
+       journal->j_stats.run.rs_wait += stats.run.rs_wait;
+       journal->j_stats.run.rs_request_delay += stats.run.rs_request_delay;
+       journal->j_stats.run.rs_running += stats.run.rs_running;
+       journal->j_stats.run.rs_locked += stats.run.rs_locked;
+       journal->j_stats.run.rs_flushing += stats.run.rs_flushing;
+       journal->j_stats.run.rs_logging += stats.run.rs_logging;
+       journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count;
+       journal->j_stats.run.rs_blocks += stats.run.rs_blocks;
+       journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
+       spin_unlock(&journal->j_history_lock);
 }
index 5fa344afb49ae8642be889ce2b3f69d176af548e..67b8e303946ceaa79a0fd0d39ecd8ca428b67f1f 100644 (file)
@@ -122,7 +122,7 @@ EXPORT_SYMBOL(__jbd2_debug);
 #endif
 
 /* Checksumming functions */
-int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb)
+static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb)
 {
        if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
                return 1;
@@ -143,7 +143,7 @@ static __be32 jbd2_superblock_csum(journal_t *j, journal_superblock_t *sb)
        return cpu_to_be32(csum);
 }
 
-int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb)
+static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb)
 {
        if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
                return 1;
@@ -151,7 +151,7 @@ int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb)
        return sb->s_checksum == jbd2_superblock_csum(j, sb);
 }
 
-void jbd2_superblock_csum_set(journal_t *j, journal_superblock_t *sb)
+static void jbd2_superblock_csum_set(journal_t *j, journal_superblock_t *sb)
 {
        if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
                return;
@@ -302,8 +302,8 @@ static void journal_kill_thread(journal_t *journal)
        journal->j_flags |= JBD2_UNMOUNT;
 
        while (journal->j_task) {
-               wake_up(&journal->j_wait_commit);
                write_unlock(&journal->j_state_lock);
+               wake_up(&journal->j_wait_commit);
                wait_event(journal->j_wait_done_commit, journal->j_task == NULL);
                write_lock(&journal->j_state_lock);
        }
@@ -710,8 +710,8 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
        while (tid_gt(tid, journal->j_commit_sequence)) {
                jbd_debug(1, "JBD2: want %d, j_commit_sequence=%d\n",
                                  tid, journal->j_commit_sequence);
-               wake_up(&journal->j_wait_commit);
                read_unlock(&journal->j_state_lock);
+               wake_up(&journal->j_wait_commit);
                wait_event(journal->j_wait_done_commit,
                                !tid_gt(tid, journal->j_commit_sequence));
                read_lock(&journal->j_state_lock);
index 60bb365f54a52efb8ff859ff746ac1af201bb7d2..38cfcf5f6fce6127807da86c8e5d6a9be867fb98 100644 (file)
@@ -1073,7 +1073,6 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
         * reused here.
         */
        jbd_lock_bh_state(bh);
-       spin_lock(&journal->j_list_lock);
        J_ASSERT_JH(jh, (jh->b_transaction == transaction ||
                jh->b_transaction == NULL ||
                (jh->b_transaction == journal->j_committing_transaction &&
@@ -1096,12 +1095,14 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
                jh->b_modified = 0;
 
                JBUFFER_TRACE(jh, "file as BJ_Reserved");
+               spin_lock(&journal->j_list_lock);
                __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
        } else if (jh->b_transaction == journal->j_committing_transaction) {
                /* first access by this transaction */
                jh->b_modified = 0;
 
                JBUFFER_TRACE(jh, "set next transaction");
+               spin_lock(&journal->j_list_lock);
                jh->b_next_transaction = transaction;
        }
        spin_unlock(&journal->j_list_lock);
@@ -1312,7 +1313,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
                             journal->j_running_transaction)) {
                        printk(KERN_ERR "JBD2: %s: "
                               "jh->b_transaction (%llu, %p, %u) != "
-                              "journal->j_running_transaction (%p, %u)",
+                              "journal->j_running_transaction (%p, %u)\n",
                               journal->j_devname,
                               (unsigned long long) bh->b_blocknr,
                               jh->b_transaction,
@@ -1335,30 +1336,25 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
         */
        if (jh->b_transaction != transaction) {
                JBUFFER_TRACE(jh, "already on other transaction");
-               if (unlikely(jh->b_transaction !=
-                            journal->j_committing_transaction)) {
-                       printk(KERN_ERR "JBD2: %s: "
-                              "jh->b_transaction (%llu, %p, %u) != "
-                              "journal->j_committing_transaction (%p, %u)",
+               if (unlikely(((jh->b_transaction !=
+                              journal->j_committing_transaction)) ||
+                            (jh->b_next_transaction != transaction))) {
+                       printk(KERN_ERR "jbd2_journal_dirty_metadata: %s: "
+                              "bad jh for block %llu: "
+                              "transaction (%p, %u), "
+                              "jh->b_transaction (%p, %u), "
+                              "jh->b_next_transaction (%p, %u), jlist %u\n",
                               journal->j_devname,
                               (unsigned long long) bh->b_blocknr,
+                              transaction, transaction->t_tid,
                               jh->b_transaction,
-                              jh->b_transaction ? jh->b_transaction->t_tid : 0,
-                              journal->j_committing_transaction,
-                              journal->j_committing_transaction ?
-                              journal->j_committing_transaction->t_tid : 0);
-                       ret = -EINVAL;
-               }
-               if (unlikely(jh->b_next_transaction != transaction)) {
-                       printk(KERN_ERR "JBD2: %s: "
-                              "jh->b_next_transaction (%llu, %p, %u) != "
-                              "transaction (%p, %u)",
-                              journal->j_devname,
-                              (unsigned long long) bh->b_blocknr,
+                              jh->b_transaction ?
+                              jh->b_transaction->t_tid : 0,
                               jh->b_next_transaction,
                               jh->b_next_transaction ?
                               jh->b_next_transaction->t_tid : 0,
-                              transaction, transaction->t_tid);
+                              jh->b_jlist);
+                       WARN_ON(1);
                        ret = -EINVAL;
                }
                /* And this case is illegal: we can't reuse another
@@ -1415,7 +1411,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
        BUFFER_TRACE(bh, "entry");
 
        jbd_lock_bh_state(bh);
-       spin_lock(&journal->j_list_lock);
 
        if (!buffer_jbd(bh))
                goto not_jbd;
@@ -1468,6 +1463,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
                 * we know to remove the checkpoint after we commit.
                 */
 
+               spin_lock(&journal->j_list_lock);
                if (jh->b_cp_transaction) {
                        __jbd2_journal_temp_unlink_buffer(jh);
                        __jbd2_journal_file_buffer(jh, transaction, BJ_Forget);
@@ -1480,6 +1476,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
                                goto drop;
                        }
                }
+               spin_unlock(&journal->j_list_lock);
        } else if (jh->b_transaction) {
                J_ASSERT_JH(jh, (jh->b_transaction ==
                                 journal->j_committing_transaction));
@@ -1491,7 +1488,9 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
 
                if (jh->b_next_transaction) {
                        J_ASSERT(jh->b_next_transaction == transaction);
+                       spin_lock(&journal->j_list_lock);
                        jh->b_next_transaction = NULL;
+                       spin_unlock(&journal->j_list_lock);
 
                        /*
                         * only drop a reference if this transaction modified
@@ -1503,7 +1502,6 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
        }
 
 not_jbd:
-       spin_unlock(&journal->j_list_lock);
        jbd_unlock_bh_state(bh);
        __brelse(bh);
 drop:
@@ -1821,11 +1819,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
        if (buffer_locked(bh) || buffer_dirty(bh))
                goto out;
 
-       if (jh->b_next_transaction != NULL)
+       if (jh->b_next_transaction != NULL || jh->b_transaction != NULL)
                goto out;
 
        spin_lock(&journal->j_list_lock);
-       if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) {
+       if (jh->b_cp_transaction != NULL) {
                /* written-back checkpointed metadata buffer */
                JBUFFER_TRACE(jh, "remove from checkpoint list");
                __jbd2_journal_remove_checkpoint(jh);
index 16a5047903a6ef3a89e031e61e4a9044fa9b99c9..406d9cc84ba8d99b7520b4ee931d9c010f9e5bea 100644 (file)
@@ -33,7 +33,7 @@ static int jffs2_rtime_compress(unsigned char *data_in,
                                unsigned char *cpage_out,
                                uint32_t *sourcelen, uint32_t *dstlen)
 {
-       short positions[256];
+       unsigned short positions[256];
        int outpos = 0;
        int pos=0;
 
@@ -74,7 +74,7 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
                                  unsigned char *cpage_out,
                                  uint32_t srclen, uint32_t destlen)
 {
-       short positions[256];
+       unsigned short positions[256];
        int outpos = 0;
        int pos=0;
 
index f73991522672a665e92b13ac4433e6ce35935764..601afd1afddf5bca94fb35f993e61919b6bbdcd4 100644 (file)
@@ -457,12 +457,14 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r
           The umask is only applied if there's no default ACL */
        ret = jffs2_init_acl_pre(dir_i, inode, &mode);
        if (ret) {
-           make_bad_inode(inode);
-           iput(inode);
-           return ERR_PTR(ret);
+               mutex_unlock(&f->sem);
+               make_bad_inode(inode);
+               iput(inode);
+               return ERR_PTR(ret);
        }
        ret = jffs2_do_new_inode (c, f, mode, ri);
        if (ret) {
+               mutex_unlock(&f->sem);
                make_bad_inode(inode);
                iput(inode);
                return ERR_PTR(ret);
@@ -479,6 +481,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r
        inode->i_size = 0;
 
        if (insert_inode_locked(inode) < 0) {
+               mutex_unlock(&f->sem);
                make_bad_inode(inode);
                iput(inode);
                return ERR_PTR(-EINVAL);
index e4619b00f7c5dec65669f0b1dd9acdf135392185..fa35ff79ab358fe79c734f54ff51ebcb21ab9f7f 100644 (file)
@@ -231,7 +231,7 @@ struct jffs2_tmp_dnode_info
        uint32_t version;
        uint32_t data_crc;
        uint32_t partial_crc;
-       uint16_t csize;
+       uint32_t csize;
        uint16_t overlapped;
 };
 
index 03310721712f7885aa043c1c2f88421d0a80649b..b6bd4affd9adb102d7d169aadc42e34da27e53ea 100644 (file)
@@ -179,6 +179,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
                                        spin_unlock(&c->erase_completion_lock);
 
                                        schedule();
+                                       remove_wait_queue(&c->erase_wait, &wait);
                                } else
                                        spin_unlock(&c->erase_completion_lock);
                        } else if (ret)
@@ -211,20 +212,25 @@ out:
 int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
                           uint32_t *len, uint32_t sumsize)
 {
-       int ret = -EAGAIN;
+       int ret;
        minsize = PAD(minsize);
 
        jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize);
 
-       spin_lock(&c->erase_completion_lock);
-       while(ret == -EAGAIN) {
+       while (true) {
+               spin_lock(&c->erase_completion_lock);
                ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
                if (ret) {
                        jffs2_dbg(1, "%s(): looping, ret is %d\n",
                                  __func__, ret);
                }
+               spin_unlock(&c->erase_completion_lock);
+
+               if (ret == -EAGAIN)
+                       cond_resched();
+               else
+                       break;
        }
-       spin_unlock(&c->erase_completion_lock);
        if (!ret)
                ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
 
index 0defb1cc2a3520d6f5f67cc880f91d0e9fe5b244..0918f0e2e26608467356235c4267c336cccee87c 100644 (file)
@@ -243,6 +243,7 @@ static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
        int err;
 
+       sync_filesystem(sb);
        err = jffs2_parse_options(c, data);
        if (err)
                return -EINVAL;
index e2b7483444fd0dc7163cf1d4ab651917b824965e..97f7fda51890b28d11bad813bd1d3c03bc331c16 100644 (file)
@@ -418,6 +418,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
        int flag = JFS_SBI(sb)->flag;
        int ret;
 
+       sync_filesystem(sb);
        if (!parse_options(data, sb, &newLVSize, &flag)) {
                return -EINVAL;
        }
index 92a0f0a52b06522e69b9452693a3f7f52cef5b40..13fc7a6d380ae6648945c8956cc53901de2d0ccc 100644 (file)
 #define IS_POSIX(fl)   (fl->fl_flags & FL_POSIX)
 #define IS_FLOCK(fl)   (fl->fl_flags & FL_FLOCK)
 #define IS_LEASE(fl)   (fl->fl_flags & (FL_LEASE|FL_DELEG))
+#define IS_FILE_PVT(fl)        (fl->fl_flags & FL_FILE_PVT)
 
 static bool lease_breaking(struct file_lock *fl)
 {
@@ -344,48 +345,43 @@ static int assign_type(struct file_lock *fl, long type)
        return 0;
 }
 
-/* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
- * style lock.
- */
-static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
-                              struct flock *l)
+static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
+                                struct flock64 *l)
 {
-       off_t start, end;
-
        switch (l->l_whence) {
        case SEEK_SET:
-               start = 0;
+               fl->fl_start = 0;
                break;
        case SEEK_CUR:
-               start = filp->f_pos;
+               fl->fl_start = filp->f_pos;
                break;
        case SEEK_END:
-               start = i_size_read(file_inode(filp));
+               fl->fl_start = i_size_read(file_inode(filp));
                break;
        default:
                return -EINVAL;
        }
+       if (l->l_start > OFFSET_MAX - fl->fl_start)
+               return -EOVERFLOW;
+       fl->fl_start += l->l_start;
+       if (fl->fl_start < 0)
+               return -EINVAL;
 
        /* POSIX-1996 leaves the case l->l_len < 0 undefined;
           POSIX-2001 defines it. */
-       start += l->l_start;
-       if (start < 0)
-               return -EINVAL;
-       fl->fl_end = OFFSET_MAX;
        if (l->l_len > 0) {
-               end = start + l->l_len - 1;
-               fl->fl_end = end;
+               if (l->l_len - 1 > OFFSET_MAX - fl->fl_start)
+                       return -EOVERFLOW;
+               fl->fl_end = fl->fl_start + l->l_len - 1;
+
        } else if (l->l_len < 0) {
-               end = start - 1;
-               fl->fl_end = end;
-               start += l->l_len;
-               if (start < 0)
+               if (fl->fl_start + l->l_len < 0)
                        return -EINVAL;
-       }
-       fl->fl_start = start;   /* we record the absolute position */
-       if (fl->fl_end < fl->fl_start)
-               return -EOVERFLOW;
-       
+               fl->fl_end = fl->fl_start - 1;
+               fl->fl_start += l->l_len;
+       } else
+               fl->fl_end = OFFSET_MAX;
+
        fl->fl_owner = current->files;
        fl->fl_pid = current->tgid;
        fl->fl_file = filp;
@@ -393,55 +389,36 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
        fl->fl_ops = NULL;
        fl->fl_lmops = NULL;
 
-       return assign_type(fl, l->l_type);
-}
-
-#if BITS_PER_LONG == 32
-static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
-                                struct flock64 *l)
-{
-       loff_t start;
-
-       switch (l->l_whence) {
-       case SEEK_SET:
-               start = 0;
-               break;
-       case SEEK_CUR:
-               start = filp->f_pos;
+       /* Ensure that fl->fl_filp has compatible f_mode */
+       switch (l->l_type) {
+       case F_RDLCK:
+               if (!(filp->f_mode & FMODE_READ))
+                       return -EBADF;
                break;
-       case SEEK_END:
-               start = i_size_read(file_inode(filp));
+       case F_WRLCK:
+               if (!(filp->f_mode & FMODE_WRITE))
+                       return -EBADF;
                break;
-       default:
-               return -EINVAL;
        }
 
-       start += l->l_start;
-       if (start < 0)
-               return -EINVAL;
-       fl->fl_end = OFFSET_MAX;
-       if (l->l_len > 0) {
-               fl->fl_end = start + l->l_len - 1;
-       } else if (l->l_len < 0) {
-               fl->fl_end = start - 1;
-               start += l->l_len;
-               if (start < 0)
-                       return -EINVAL;
-       }
-       fl->fl_start = start;   /* we record the absolute position */
-       if (fl->fl_end < fl->fl_start)
-               return -EOVERFLOW;
-       
-       fl->fl_owner = current->files;
-       fl->fl_pid = current->tgid;
-       fl->fl_file = filp;
-       fl->fl_flags = FL_POSIX;
-       fl->fl_ops = NULL;
-       fl->fl_lmops = NULL;
-
        return assign_type(fl, l->l_type);
 }
-#endif
+
+/* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
+ * style lock.
+ */
+static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
+                              struct flock *l)
+{
+       struct flock64 ll = {
+               .l_type = l->l_type,
+               .l_whence = l->l_whence,
+               .l_start = l->l_start,
+               .l_len = l->l_len,
+       };
+
+       return flock64_to_posix_lock(filp, fl, &ll);
+}
 
 /* default lease lock manager operations */
 static void lease_break_callback(struct file_lock *fl)
@@ -511,8 +488,7 @@ static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
 }
 
 /* Must be called with the i_lock held! */
-static inline void
-locks_insert_global_locks(struct file_lock *fl)
+static void locks_insert_global_locks(struct file_lock *fl)
 {
        lg_local_lock(&file_lock_lglock);
        fl->fl_link_cpu = smp_processor_id();
@@ -521,8 +497,7 @@ locks_insert_global_locks(struct file_lock *fl)
 }
 
 /* Must be called with the i_lock held! */
-static inline void
-locks_delete_global_locks(struct file_lock *fl)
+static void locks_delete_global_locks(struct file_lock *fl)
 {
        /*
         * Avoid taking lock if already unhashed. This is safe since this check
@@ -544,14 +519,12 @@ posix_owner_key(struct file_lock *fl)
        return (unsigned long)fl->fl_owner;
 }
 
-static inline void
-locks_insert_global_blocked(struct file_lock *waiter)
+static void locks_insert_global_blocked(struct file_lock *waiter)
 {
        hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter));
 }
 
-static inline void
-locks_delete_global_blocked(struct file_lock *waiter)
+static void locks_delete_global_blocked(struct file_lock *waiter)
 {
        hash_del(&waiter->fl_link);
 }
@@ -581,7 +554,7 @@ static void locks_delete_block(struct file_lock *waiter)
  * it seems like the reasonable thing to do.
  *
  * Must be called with both the i_lock and blocked_lock_lock held. The fl_block
- * list itself is protected by the file_lock_list, but by ensuring that the
+ * list itself is protected by the blocked_lock_lock, but by ensuring that the
  * i_lock is also held on insertions we can avoid taking the blocked_lock_lock
  * in some cases when we see that the fl_block list is empty.
  */
@@ -591,7 +564,7 @@ static void __locks_insert_block(struct file_lock *blocker,
        BUG_ON(!list_empty(&waiter->fl_block));
        waiter->fl_next = blocker;
        list_add_tail(&waiter->fl_block, &blocker->fl_block);
-       if (IS_POSIX(blocker))
+       if (IS_POSIX(blocker) && !IS_FILE_PVT(blocker))
                locks_insert_global_blocked(waiter);
 }
 
@@ -652,15 +625,18 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
        locks_insert_global_locks(fl);
 }
 
-/*
- * Delete a lock and then free it.
- * Wake up processes that are blocked waiting for this lock,
- * notify the FS that the lock has been cleared and
- * finally free the lock.
+/**
+ * locks_delete_lock - Delete a lock and then free it.
+ * @thisfl_p: pointer that points to the fl_next field of the previous
+ *           inode->i_flock list entry
+ *
+ * Unlink a lock from all lists and free the namespace reference, but don't
+ * free it yet. Wake up processes that are blocked waiting for this lock and
+ * notify the FS that the lock has been cleared.
  *
  * Must be called with the i_lock held!
  */
-static void locks_delete_lock(struct file_lock **thisfl_p)
+static void locks_unlink_lock(struct file_lock **thisfl_p)
 {
        struct file_lock *fl = *thisfl_p;
 
@@ -675,6 +651,18 @@ static void locks_delete_lock(struct file_lock **thisfl_p)
        }
 
        locks_wake_up_blocks(fl);
+}
+
+/*
+ * Unlink a lock from all lists and free it.
+ *
+ * Must be called with i_lock held!
+ */
+static void locks_delete_lock(struct file_lock **thisfl_p)
+{
+       struct file_lock *fl = *thisfl_p;
+
+       locks_unlink_lock(thisfl_p);
        locks_free_lock(fl);
 }
 
@@ -769,8 +757,16 @@ EXPORT_SYMBOL(posix_test_lock);
  * Note: the above assumption may not be true when handling lock
  * requests from a broken NFS client. It may also fail in the presence
  * of tasks (such as posix threads) sharing the same open file table.
- *
  * To handle those cases, we just bail out after a few iterations.
+ *
+ * For FL_FILE_PVT locks, the owner is the filp, not the files_struct.
+ * Because the owner is not even nominally tied to a thread of
+ * execution, the deadlock detection below can't reasonably work well. Just
+ * skip it for those.
+ *
+ * In principle, we could do a more limited deadlock detection on FL_FILE_PVT
+ * locks that just checks for the case where two tasks are attempting to
+ * upgrade from read to write locks on the same inode.
  */
 
 #define MAX_DEADLK_ITERATIONS 10
@@ -793,6 +789,13 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
 {
        int i = 0;
 
+       /*
+        * This deadlock detector can't reasonably detect deadlocks with
+        * FL_FILE_PVT locks, since they aren't owned by a process, per-se.
+        */
+       if (IS_FILE_PVT(caller_fl))
+               return 0;
+
        while ((block_fl = what_owner_is_waiting_for(block_fl))) {
                if (i++ > MAX_DEADLK_ITERATIONS)
                        return 0;
@@ -1152,13 +1155,14 @@ EXPORT_SYMBOL(posix_lock_file_wait);
 
 /**
  * locks_mandatory_locked - Check for an active lock
- * @inode: the file to check
+ * @file: the file to check
  *
  * Searches the inode's list of locks to find any POSIX locks which conflict.
  * This function is called from locks_verify_locked() only.
  */
-int locks_mandatory_locked(struct inode *inode)
+int locks_mandatory_locked(struct file *file)
 {
+       struct inode *inode = file_inode(file);
        fl_owner_t owner = current->files;
        struct file_lock *fl;
 
@@ -1169,7 +1173,7 @@ int locks_mandatory_locked(struct inode *inode)
        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
                if (!IS_POSIX(fl))
                        continue;
-               if (fl->fl_owner != owner)
+               if (fl->fl_owner != owner && fl->fl_owner != (fl_owner_t)file)
                        break;
        }
        spin_unlock(&inode->i_lock);
@@ -1195,19 +1199,30 @@ int locks_mandatory_area(int read_write, struct inode *inode,
 {
        struct file_lock fl;
        int error;
+       bool sleep = false;
 
        locks_init_lock(&fl);
-       fl.fl_owner = current->files;
        fl.fl_pid = current->tgid;
        fl.fl_file = filp;
        fl.fl_flags = FL_POSIX | FL_ACCESS;
        if (filp && !(filp->f_flags & O_NONBLOCK))
-               fl.fl_flags |= FL_SLEEP;
+               sleep = true;
        fl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;
        fl.fl_start = offset;
        fl.fl_end = offset + count - 1;
 
        for (;;) {
+               if (filp) {
+                       fl.fl_owner = (fl_owner_t)filp;
+                       fl.fl_flags &= ~FL_SLEEP;
+                       error = __posix_lock_file(inode, &fl, NULL);
+                       if (!error)
+                               break;
+               }
+
+               if (sleep)
+                       fl.fl_flags |= FL_SLEEP;
+               fl.fl_owner = current->files;
                error = __posix_lock_file(inode, &fl, NULL);
                if (error != FILE_LOCK_DEFERRED)
                        break;
@@ -1472,6 +1487,32 @@ int fcntl_getlease(struct file *filp)
        return type;
 }
 
+/**
+ * check_conflicting_open - see if the given dentry points to a file that has
+ *                         an existing open that would conflict with the
+ *                         desired lease.
+ * @dentry:    dentry to check
+ * @arg:       type of lease that we're trying to acquire
+ *
+ * Check to see if there's an existing open fd on this file that would
+ * conflict with the lease we're trying to set.
+ */
+static int
+check_conflicting_open(const struct dentry *dentry, const long arg)
+{
+       int ret = 0;
+       struct inode *inode = dentry->d_inode;
+
+       if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
+               return -EAGAIN;
+
+       if ((arg == F_WRLCK) && ((d_count(dentry) > 1) ||
+           (atomic_read(&inode->i_count) > 1)))
+               ret = -EAGAIN;
+
+       return ret;
+}
+
 static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp)
 {
        struct file_lock *fl, **before, **my_before = NULL, *lease;
@@ -1499,12 +1540,8 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
                return -EINVAL;
        }
 
-       error = -EAGAIN;
-       if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
-               goto out;
-       if ((arg == F_WRLCK)
-           && ((d_count(dentry) > 1)
-               || (atomic_read(&inode->i_count) > 1)))
+       error = check_conflicting_open(dentry, arg);
+       if (error)
                goto out;
 
        /*
@@ -1549,7 +1586,19 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
                goto out;
 
        locks_insert_lock(before, lease);
-       error = 0;
+       /*
+        * The check in break_lease() is lockless. It's possible for another
+        * open to race in after we did the earlier check for a conflicting
+        * open but before the lease was inserted. Check again for a
+        * conflicting open and cancel the lease if there is one.
+        *
+        * We also add a barrier here to ensure that the insertion of the lock
+        * precedes these checks.
+        */
+       smp_mb();
+       error = check_conflicting_open(dentry, arg);
+       if (error)
+               locks_unlink_lock(flp);
 out:
        if (is_deleg)
                mutex_unlock(&inode->i_mutex);
@@ -1842,7 +1891,7 @@ EXPORT_SYMBOL_GPL(vfs_test_lock);
 
 static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
 {
-       flock->l_pid = fl->fl_pid;
+       flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid;
 #if BITS_PER_LONG == 32
        /*
         * Make sure we can represent the posix lock via
@@ -1864,7 +1913,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
 #if BITS_PER_LONG == 32
 static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
 {
-       flock->l_pid = fl->fl_pid;
+       flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid;
        flock->l_start = fl->fl_start;
        flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
                fl->fl_end - fl->fl_start + 1;
@@ -1876,7 +1925,7 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
-int fcntl_getlk(struct file *filp, struct flock __user *l)
+int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
 {
        struct file_lock file_lock;
        struct flock flock;
@@ -1893,6 +1942,16 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
        if (error)
                goto out;
 
+       if (cmd == F_GETLKP) {
+               error = -EINVAL;
+               if (flock.l_pid != 0)
+                       goto out;
+
+               cmd = F_GETLK;
+               file_lock.fl_flags |= FL_FILE_PVT;
+               file_lock.fl_owner = (fl_owner_t)filp;
+       }
+
        error = vfs_test_lock(filp, &file_lock);
        if (error)
                goto out;
@@ -2012,25 +2071,32 @@ again:
        error = flock_to_posix_lock(filp, file_lock, &flock);
        if (error)
                goto out;
-       if (cmd == F_SETLKW) {
-               file_lock->fl_flags |= FL_SLEEP;
-       }
-       
-       error = -EBADF;
-       switch (flock.l_type) {
-       case F_RDLCK:
-               if (!(filp->f_mode & FMODE_READ))
-                       goto out;
-               break;
-       case F_WRLCK:
-               if (!(filp->f_mode & FMODE_WRITE))
+
+       /*
+        * If the cmd is requesting file-private locks, then set the
+        * FL_FILE_PVT flag and override the owner.
+        */
+       switch (cmd) {
+       case F_SETLKP:
+               error = -EINVAL;
+               if (flock.l_pid != 0)
                        goto out;
+
+               cmd = F_SETLK;
+               file_lock->fl_flags |= FL_FILE_PVT;
+               file_lock->fl_owner = (fl_owner_t)filp;
                break;
-       case F_UNLCK:
-               break;
-       default:
+       case F_SETLKPW:
                error = -EINVAL;
-               goto out;
+               if (flock.l_pid != 0)
+                       goto out;
+
+               cmd = F_SETLKW;
+               file_lock->fl_flags |= FL_FILE_PVT;
+               file_lock->fl_owner = (fl_owner_t)filp;
+               /* Fallthrough */
+       case F_SETLKW:
+               file_lock->fl_flags |= FL_SLEEP;
        }
 
        error = do_lock_file_wait(filp, cmd, file_lock);
@@ -2061,7 +2127,7 @@ out:
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
-int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
+int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
 {
        struct file_lock file_lock;
        struct flock64 flock;
@@ -2078,6 +2144,16 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
        if (error)
                goto out;
 
+       if (cmd == F_GETLKP) {
+               error = -EINVAL;
+               if (flock.l_pid != 0)
+                       goto out;
+
+               cmd = F_GETLK64;
+               file_lock.fl_flags |= FL_FILE_PVT;
+               file_lock.fl_owner = (fl_owner_t)filp;
+       }
+
        error = vfs_test_lock(filp, &file_lock);
        if (error)
                goto out;
@@ -2130,25 +2206,32 @@ again:
        error = flock64_to_posix_lock(filp, file_lock, &flock);
        if (error)
                goto out;
-       if (cmd == F_SETLKW64) {
-               file_lock->fl_flags |= FL_SLEEP;
-       }
-       
-       error = -EBADF;
-       switch (flock.l_type) {
-       case F_RDLCK:
-               if (!(filp->f_mode & FMODE_READ))
-                       goto out;
-               break;
-       case F_WRLCK:
-               if (!(filp->f_mode & FMODE_WRITE))
+
+       /*
+        * If the cmd is requesting file-private locks, then set the
+        * FL_FILE_PVT flag and override the owner.
+        */
+       switch (cmd) {
+       case F_SETLKP:
+               error = -EINVAL;
+               if (flock.l_pid != 0)
                        goto out;
+
+               cmd = F_SETLK64;
+               file_lock->fl_flags |= FL_FILE_PVT;
+               file_lock->fl_owner = (fl_owner_t)filp;
                break;
-       case F_UNLCK:
-               break;
-       default:
+       case F_SETLKPW:
                error = -EINVAL;
-               goto out;
+               if (flock.l_pid != 0)
+                       goto out;
+
+               cmd = F_SETLKW64;
+               file_lock->fl_flags |= FL_FILE_PVT;
+               file_lock->fl_owner = (fl_owner_t)filp;
+               /* Fallthrough */
+       case F_SETLKW64:
+               file_lock->fl_flags |= FL_SLEEP;
        }
 
        error = do_lock_file_wait(filp, cmd, file_lock);
@@ -2209,7 +2292,7 @@ EXPORT_SYMBOL(locks_remove_posix);
 /*
  * This function is called on the last close of an open file.
  */
-void locks_remove_flock(struct file *filp)
+void locks_remove_file(struct file *filp)
 {
        struct inode * inode = file_inode(filp);
        struct file_lock *fl;
@@ -2218,6 +2301,8 @@ void locks_remove_flock(struct file *filp)
        if (!inode->i_flock)
                return;
 
+       locks_remove_posix(filp, (fl_owner_t)filp);
+
        if (filp->f_op->flock) {
                struct file_lock fl = {
                        .fl_pid = current->tgid,
@@ -2236,16 +2321,28 @@ void locks_remove_flock(struct file *filp)
 
        while ((fl = *before) != NULL) {
                if (fl->fl_file == filp) {
-                       if (IS_FLOCK(fl)) {
-                               locks_delete_lock(before);
-                               continue;
-                       }
                        if (IS_LEASE(fl)) {
                                lease_modify(before, F_UNLCK);
                                continue;
                        }
-                       /* What? */
-                       BUG();
+
+                       /*
+                        * There's a leftover lock on the list of a type that
+                        * we didn't expect to see. Most likely a classic
+                        * POSIX lock that ended up not getting released
+                        * properly, or that raced onto the list somehow. Log
+                        * some info about it and then just remove it from
+                        * the list.
+                        */
+                       WARN(!IS_FLOCK(fl),
+                               "leftover lock: dev=%u:%u ino=%lu type=%hhd flags=0x%x start=%lld end=%lld\n",
+                               MAJOR(inode->i_sb->s_dev),
+                               MINOR(inode->i_sb->s_dev), inode->i_ino,
+                               fl->fl_type, fl->fl_flags,
+                               fl->fl_start, fl->fl_end);
+
+                       locks_delete_lock(before);
+                       continue;
                }
                before = &fl->fl_next;
        }
@@ -2314,8 +2411,14 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
 
        seq_printf(f, "%lld:%s ", id, pfx);
        if (IS_POSIX(fl)) {
-               seq_printf(f, "%6s %s ",
-                            (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ",
+               if (fl->fl_flags & FL_ACCESS)
+                       seq_printf(f, "ACCESS");
+               else if (IS_FILE_PVT(fl))
+                       seq_printf(f, "FLPVT ");
+               else
+                       seq_printf(f, "POSIX ");
+
+               seq_printf(f, " %s ",
                             (inode == NULL) ? "*NOINODE*" :
                             mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
        } else if (IS_FLOCK(fl)) {
@@ -2385,6 +2488,7 @@ static int locks_show(struct seq_file *f, void *v)
 }
 
 static void *locks_start(struct seq_file *f, loff_t *pos)
+       __acquires(&blocked_lock_lock)
 {
        struct locks_iterator *iter = f->private;
 
@@ -2403,6 +2507,7 @@ static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
 }
 
 static void locks_stop(struct seq_file *f, void *v)
+       __releases(&blocked_lock_lock)
 {
        spin_unlock(&blocked_lock_lock);
        lg_global_unlock(&file_lock_lglock);
index e519e45bf6735e7f59dc7fef969451791e5e1cef..bf166e388f0d4cb8b8826698df51fe759aa6f99f 100644 (file)
  * back on the lru list.
  */
 
+/*
+ * Lock descriptions and usage:
+ *
+ * Each hash chain of both the block and index hash tables now contains
+ * a built-in lock used to serialize accesses to the hash chain.
+ *
+ * Accesses to global data structures mb_cache_list and mb_cache_lru_list
+ * are serialized via the global spinlock mb_cache_spinlock.
+ *
+ * Each mb_cache_entry contains a spinlock, e_entry_lock, to serialize
+ * accesses to its local data, such as e_used and e_queued.
+ *
+ * Lock ordering:
+ *
+ * Each block hash chain's lock has the highest lock order, followed by an
+ * index hash chain's lock, mb_cache_bg_lock (used to implement mb_cache_entry's
+ * lock), and mb_cach_spinlock, with the lowest order.  While holding
+ * either a block or index hash chain lock, a thread can acquire an
+ * mc_cache_bg_lock, which in turn can also acquire mb_cache_spinlock.
+ *
+ * Synchronization:
+ *
+ * Since both mb_cache_entry_get and mb_cache_entry_find scan the block and
+ * index hash chian, it needs to lock the corresponding hash chain.  For each
+ * mb_cache_entry within the chain, it needs to lock the mb_cache_entry to
+ * prevent either any simultaneous release or free on the entry and also
+ * to serialize accesses to either the e_used or e_queued member of the entry.
+ *
+ * To avoid having a dangling reference to an already freed
+ * mb_cache_entry, an mb_cache_entry is only freed when it is not on a
+ * block hash chain and also no longer being referenced, both e_used,
+ * and e_queued are 0's.  When an mb_cache_entry is explicitly freed it is
+ * first removed from a block hash chain.
+ */
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <linux/init.h>
+#include <linux/list_bl.h>
 #include <linux/mbcache.h>
-
+#include <linux/init.h>
+#include <linux/blockgroup_lock.h>
 
 #ifdef MB_CACHE_DEBUG
 # define mb_debug(f...) do { \
 
 #define MB_CACHE_WRITER ((unsigned short)~0U >> 1)
 
+#define MB_CACHE_ENTRY_LOCK_BITS       __builtin_log2(NR_BG_LOCKS)
+#define        MB_CACHE_ENTRY_LOCK_INDEX(ce)                   \
+       (hash_long((unsigned long)ce, MB_CACHE_ENTRY_LOCK_BITS))
+
 static DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
-               
+static struct blockgroup_lock *mb_cache_bg_lock;
+static struct kmem_cache *mb_cache_kmem_cache;
+
 MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
 MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
 MODULE_LICENSE("GPL");
@@ -86,58 +128,110 @@ static LIST_HEAD(mb_cache_list);
 static LIST_HEAD(mb_cache_lru_list);
 static DEFINE_SPINLOCK(mb_cache_spinlock);
 
+static inline void
+__spin_lock_mb_cache_entry(struct mb_cache_entry *ce)
+{
+       spin_lock(bgl_lock_ptr(mb_cache_bg_lock,
+               MB_CACHE_ENTRY_LOCK_INDEX(ce)));
+}
+
+static inline void
+__spin_unlock_mb_cache_entry(struct mb_cache_entry *ce)
+{
+       spin_unlock(bgl_lock_ptr(mb_cache_bg_lock,
+               MB_CACHE_ENTRY_LOCK_INDEX(ce)));
+}
+
 static inline int
-__mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
+__mb_cache_entry_is_block_hashed(struct mb_cache_entry *ce)
 {
-       return !list_empty(&ce->e_block_list);
+       return !hlist_bl_unhashed(&ce->e_block_list);
 }
 
 
-static void
-__mb_cache_entry_unhash(struct mb_cache_entry *ce)
+static inline void
+__mb_cache_entry_unhash_block(struct mb_cache_entry *ce)
 {
-       if (__mb_cache_entry_is_hashed(ce)) {
-               list_del_init(&ce->e_block_list);
-               list_del(&ce->e_index.o_list);
-       }
+       if (__mb_cache_entry_is_block_hashed(ce))
+               hlist_bl_del_init(&ce->e_block_list);
 }
 
+static inline int
+__mb_cache_entry_is_index_hashed(struct mb_cache_entry *ce)
+{
+       return !hlist_bl_unhashed(&ce->e_index.o_list);
+}
+
+static inline void
+__mb_cache_entry_unhash_index(struct mb_cache_entry *ce)
+{
+       if (__mb_cache_entry_is_index_hashed(ce))
+               hlist_bl_del_init(&ce->e_index.o_list);
+}
+
+/*
+ * __mb_cache_entry_unhash_unlock()
+ *
+ * This function is called to unhash both the block and index hash
+ * chain.
+ * It assumes both the block and index hash chain is locked upon entry.
+ * It also unlock both hash chains both exit
+ */
+static inline void
+__mb_cache_entry_unhash_unlock(struct mb_cache_entry *ce)
+{
+       __mb_cache_entry_unhash_index(ce);
+       hlist_bl_unlock(ce->e_index_hash_p);
+       __mb_cache_entry_unhash_block(ce);
+       hlist_bl_unlock(ce->e_block_hash_p);
+}
 
 static void
 __mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
 {
        struct mb_cache *cache = ce->e_cache;
 
-       mb_assert(!(ce->e_used || ce->e_queued));
+       mb_assert(!(ce->e_used || ce->e_queued || atomic_read(&ce->e_refcnt)));
        kmem_cache_free(cache->c_entry_cache, ce);
        atomic_dec(&cache->c_entry_count);
 }
 
-
 static void
-__mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
-       __releases(mb_cache_spinlock)
+__mb_cache_entry_release(struct mb_cache_entry *ce)
 {
+       /* First lock the entry to serialize access to its local data. */
+       __spin_lock_mb_cache_entry(ce);
        /* Wake up all processes queuing for this cache entry. */
        if (ce->e_queued)
                wake_up_all(&mb_cache_queue);
        if (ce->e_used >= MB_CACHE_WRITER)
                ce->e_used -= MB_CACHE_WRITER;
+       /*
+        * Make sure that all cache entries on lru_list have
+        * both e_used and e_qued of 0s.
+        */
        ce->e_used--;
-       if (!(ce->e_used || ce->e_queued)) {
-               if (!__mb_cache_entry_is_hashed(ce))
+       if (!(ce->e_used || ce->e_queued || atomic_read(&ce->e_refcnt))) {
+               if (!__mb_cache_entry_is_block_hashed(ce)) {
+                       __spin_unlock_mb_cache_entry(ce);
                        goto forget;
-               mb_assert(list_empty(&ce->e_lru_list));
-               list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
+               }
+               /*
+                * Need access to lru list, first drop entry lock,
+                * then reacquire the lock in the proper order.
+                */
+               spin_lock(&mb_cache_spinlock);
+               if (list_empty(&ce->e_lru_list))
+                       list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
+               spin_unlock(&mb_cache_spinlock);
        }
-       spin_unlock(&mb_cache_spinlock);
+       __spin_unlock_mb_cache_entry(ce);
        return;
 forget:
-       spin_unlock(&mb_cache_spinlock);
+       mb_assert(list_empty(&ce->e_lru_list));
        __mb_cache_entry_forget(ce, GFP_KERNEL);
 }
 
-
 /*
  * mb_cache_shrink_scan()  memory pressure callback
  *
@@ -160,17 +254,34 @@ mb_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
 
        mb_debug("trying to free %d entries", nr_to_scan);
        spin_lock(&mb_cache_spinlock);
-       while (nr_to_scan-- && !list_empty(&mb_cache_lru_list)) {
+       while ((nr_to_scan-- > 0) && !list_empty(&mb_cache_lru_list)) {
                struct mb_cache_entry *ce =
                        list_entry(mb_cache_lru_list.next,
-                                  struct mb_cache_entry, e_lru_list);
-               list_move_tail(&ce->e_lru_list, &free_list);
-               __mb_cache_entry_unhash(ce);
-               freed++;
+                               struct mb_cache_entry, e_lru_list);
+               list_del_init(&ce->e_lru_list);
+               if (ce->e_used || ce->e_queued || atomic_read(&ce->e_refcnt))
+                       continue;
+               spin_unlock(&mb_cache_spinlock);
+               /* Prevent any find or get operation on the entry */
+               hlist_bl_lock(ce->e_block_hash_p);
+               hlist_bl_lock(ce->e_index_hash_p);
+               /* Ignore if it is touched by a find/get */
+               if (ce->e_used || ce->e_queued || atomic_read(&ce->e_refcnt) ||
+                       !list_empty(&ce->e_lru_list)) {
+                       hlist_bl_unlock(ce->e_index_hash_p);
+                       hlist_bl_unlock(ce->e_block_hash_p);
+                       spin_lock(&mb_cache_spinlock);
+                       continue;
+               }
+               __mb_cache_entry_unhash_unlock(ce);
+               list_add_tail(&ce->e_lru_list, &free_list);
+               spin_lock(&mb_cache_spinlock);
        }
        spin_unlock(&mb_cache_spinlock);
+
        list_for_each_entry_safe(entry, tmp, &free_list, e_lru_list) {
                __mb_cache_entry_forget(entry, gfp_mask);
+               freed++;
        }
        return freed;
 }
@@ -215,29 +326,40 @@ mb_cache_create(const char *name, int bucket_bits)
        int n, bucket_count = 1 << bucket_bits;
        struct mb_cache *cache = NULL;
 
+       if (!mb_cache_bg_lock) {
+               mb_cache_bg_lock = kmalloc(sizeof(struct blockgroup_lock),
+                       GFP_KERNEL);
+               if (!mb_cache_bg_lock)
+                       return NULL;
+               bgl_lock_init(mb_cache_bg_lock);
+       }
+
        cache = kmalloc(sizeof(struct mb_cache), GFP_KERNEL);
        if (!cache)
                return NULL;
        cache->c_name = name;
        atomic_set(&cache->c_entry_count, 0);
        cache->c_bucket_bits = bucket_bits;
-       cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
-                                     GFP_KERNEL);
+       cache->c_block_hash = kmalloc(bucket_count *
+               sizeof(struct hlist_bl_head), GFP_KERNEL);
        if (!cache->c_block_hash)
                goto fail;
        for (n=0; n<bucket_count; n++)
-               INIT_LIST_HEAD(&cache->c_block_hash[n]);
-       cache->c_index_hash = kmalloc(bucket_count * sizeof(struct list_head),
-                                     GFP_KERNEL);
+               INIT_HLIST_BL_HEAD(&cache->c_block_hash[n]);
+       cache->c_index_hash = kmalloc(bucket_count *
+               sizeof(struct hlist_bl_head), GFP_KERNEL);
        if (!cache->c_index_hash)
                goto fail;
        for (n=0; n<bucket_count; n++)
-               INIT_LIST_HEAD(&cache->c_index_hash[n]);
-       cache->c_entry_cache = kmem_cache_create(name,
-               sizeof(struct mb_cache_entry), 0,
-               SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
-       if (!cache->c_entry_cache)
-               goto fail2;
+               INIT_HLIST_BL_HEAD(&cache->c_index_hash[n]);
+       if (!mb_cache_kmem_cache) {
+               mb_cache_kmem_cache = kmem_cache_create(name,
+                       sizeof(struct mb_cache_entry), 0,
+                       SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
+               if (!mb_cache_kmem_cache)
+                       goto fail2;
+       }
+       cache->c_entry_cache = mb_cache_kmem_cache;
 
        /*
         * Set an upper limit on the number of cache entries so that the hash
@@ -273,21 +395,47 @@ void
 mb_cache_shrink(struct block_device *bdev)
 {
        LIST_HEAD(free_list);
-       struct list_head *l, *ltmp;
+       struct list_head *l;
+       struct mb_cache_entry *ce, *tmp;
 
+       l = &mb_cache_lru_list;
        spin_lock(&mb_cache_spinlock);
-       list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-               struct mb_cache_entry *ce =
-                       list_entry(l, struct mb_cache_entry, e_lru_list);
+       while (!list_is_last(l, &mb_cache_lru_list)) {
+               l = l->next;
+               ce = list_entry(l, struct mb_cache_entry, e_lru_list);
                if (ce->e_bdev == bdev) {
-                       list_move_tail(&ce->e_lru_list, &free_list);
-                       __mb_cache_entry_unhash(ce);
+                       list_del_init(&ce->e_lru_list);
+                       if (ce->e_used || ce->e_queued ||
+                               atomic_read(&ce->e_refcnt))
+                               continue;
+                       spin_unlock(&mb_cache_spinlock);
+                       /*
+                        * Prevent any find or get operation on the entry.
+                        */
+                       hlist_bl_lock(ce->e_block_hash_p);
+                       hlist_bl_lock(ce->e_index_hash_p);
+                       /* Ignore if it is touched by a find/get */
+                       if (ce->e_used || ce->e_queued ||
+                               atomic_read(&ce->e_refcnt) ||
+                               !list_empty(&ce->e_lru_list)) {
+                               hlist_bl_unlock(ce->e_index_hash_p);
+                               hlist_bl_unlock(ce->e_block_hash_p);
+                               l = &mb_cache_lru_list;
+                               spin_lock(&mb_cache_spinlock);
+                               continue;
+                       }
+                       __mb_cache_entry_unhash_unlock(ce);
+                       mb_assert(!(ce->e_used || ce->e_queued ||
+                               atomic_read(&ce->e_refcnt)));
+                       list_add_tail(&ce->e_lru_list, &free_list);
+                       l = &mb_cache_lru_list;
+                       spin_lock(&mb_cache_spinlock);
                }
        }
        spin_unlock(&mb_cache_spinlock);
-       list_for_each_safe(l, ltmp, &free_list) {
-               __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-                                                  e_lru_list), GFP_KERNEL);
+
+       list_for_each_entry_safe(ce, tmp, &free_list, e_lru_list) {
+               __mb_cache_entry_forget(ce, GFP_KERNEL);
        }
 }
 
@@ -303,23 +451,27 @@ void
 mb_cache_destroy(struct mb_cache *cache)
 {
        LIST_HEAD(free_list);
-       struct list_head *l, *ltmp;
+       struct mb_cache_entry *ce, *tmp;
 
        spin_lock(&mb_cache_spinlock);
-       list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
-               struct mb_cache_entry *ce =
-                       list_entry(l, struct mb_cache_entry, e_lru_list);
-               if (ce->e_cache == cache) {
+       list_for_each_entry_safe(ce, tmp, &mb_cache_lru_list, e_lru_list) {
+               if (ce->e_cache == cache)
                        list_move_tail(&ce->e_lru_list, &free_list);
-                       __mb_cache_entry_unhash(ce);
-               }
        }
        list_del(&cache->c_cache_list);
        spin_unlock(&mb_cache_spinlock);
 
-       list_for_each_safe(l, ltmp, &free_list) {
-               __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
-                                                  e_lru_list), GFP_KERNEL);
+       list_for_each_entry_safe(ce, tmp, &free_list, e_lru_list) {
+               list_del_init(&ce->e_lru_list);
+               /*
+                * Prevent any find or get operation on the entry.
+                */
+               hlist_bl_lock(ce->e_block_hash_p);
+               hlist_bl_lock(ce->e_index_hash_p);
+               mb_assert(!(ce->e_used || ce->e_queued ||
+                       atomic_read(&ce->e_refcnt)));
+               __mb_cache_entry_unhash_unlock(ce);
+               __mb_cache_entry_forget(ce, GFP_KERNEL);
        }
 
        if (atomic_read(&cache->c_entry_count) > 0) {
@@ -328,8 +480,10 @@ mb_cache_destroy(struct mb_cache *cache)
                          atomic_read(&cache->c_entry_count));
        }
 
-       kmem_cache_destroy(cache->c_entry_cache);
-
+       if (list_empty(&mb_cache_list)) {
+               kmem_cache_destroy(mb_cache_kmem_cache);
+               mb_cache_kmem_cache = NULL;
+       }
        kfree(cache->c_index_hash);
        kfree(cache->c_block_hash);
        kfree(cache);
@@ -346,28 +500,61 @@ mb_cache_destroy(struct mb_cache *cache)
 struct mb_cache_entry *
 mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags)
 {
-       struct mb_cache_entry *ce = NULL;
+       struct mb_cache_entry *ce;
 
        if (atomic_read(&cache->c_entry_count) >= cache->c_max_entries) {
+               struct list_head *l;
+
+               l = &mb_cache_lru_list;
                spin_lock(&mb_cache_spinlock);
-               if (!list_empty(&mb_cache_lru_list)) {
-                       ce = list_entry(mb_cache_lru_list.next,
-                                       struct mb_cache_entry, e_lru_list);
-                       list_del_init(&ce->e_lru_list);
-                       __mb_cache_entry_unhash(ce);
+               while (!list_is_last(l, &mb_cache_lru_list)) {
+                       l = l->next;
+                       ce = list_entry(l, struct mb_cache_entry, e_lru_list);
+                       if (ce->e_cache == cache) {
+                               list_del_init(&ce->e_lru_list);
+                               if (ce->e_used || ce->e_queued ||
+                                       atomic_read(&ce->e_refcnt))
+                                       continue;
+                               spin_unlock(&mb_cache_spinlock);
+                               /*
+                                * Prevent any find or get operation on the
+                                * entry.
+                                */
+                               hlist_bl_lock(ce->e_block_hash_p);
+                               hlist_bl_lock(ce->e_index_hash_p);
+                               /* Ignore if it is touched by a find/get */
+                               if (ce->e_used || ce->e_queued ||
+                                       atomic_read(&ce->e_refcnt) ||
+                                       !list_empty(&ce->e_lru_list)) {
+                                       hlist_bl_unlock(ce->e_index_hash_p);
+                                       hlist_bl_unlock(ce->e_block_hash_p);
+                                       l = &mb_cache_lru_list;
+                                       spin_lock(&mb_cache_spinlock);
+                                       continue;
+                               }
+                               mb_assert(list_empty(&ce->e_lru_list));
+                               mb_assert(!(ce->e_used || ce->e_queued ||
+                                       atomic_read(&ce->e_refcnt)));
+                               __mb_cache_entry_unhash_unlock(ce);
+                               goto found;
+                       }
                }
                spin_unlock(&mb_cache_spinlock);
        }
-       if (!ce) {
-               ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
-               if (!ce)
-                       return NULL;
-               atomic_inc(&cache->c_entry_count);
-               INIT_LIST_HEAD(&ce->e_lru_list);
-               INIT_LIST_HEAD(&ce->e_block_list);
-               ce->e_cache = cache;
-               ce->e_queued = 0;
-       }
+
+       ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
+       if (!ce)
+               return NULL;
+       atomic_inc(&cache->c_entry_count);
+       INIT_LIST_HEAD(&ce->e_lru_list);
+       INIT_HLIST_BL_NODE(&ce->e_block_list);
+       INIT_HLIST_BL_NODE(&ce->e_index.o_list);
+       ce->e_cache = cache;
+       ce->e_queued = 0;
+       atomic_set(&ce->e_refcnt, 0);
+found:
+       ce->e_block_hash_p = &cache->c_block_hash[0];
+       ce->e_index_hash_p = &cache->c_index_hash[0];
        ce->e_used = 1 + MB_CACHE_WRITER;
        return ce;
 }
@@ -393,29 +580,38 @@ mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev,
 {
        struct mb_cache *cache = ce->e_cache;
        unsigned int bucket;
-       struct list_head *l;
-       int error = -EBUSY;
+       struct hlist_bl_node *l;
+       struct hlist_bl_head *block_hash_p;
+       struct hlist_bl_head *index_hash_p;
+       struct mb_cache_entry *lce;
 
+       mb_assert(ce);
        bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), 
                           cache->c_bucket_bits);
-       spin_lock(&mb_cache_spinlock);
-       list_for_each_prev(l, &cache->c_block_hash[bucket]) {
-               struct mb_cache_entry *ce =
-                       list_entry(l, struct mb_cache_entry, e_block_list);
-               if (ce->e_bdev == bdev && ce->e_block == block)
-                       goto out;
+       block_hash_p = &cache->c_block_hash[bucket];
+       hlist_bl_lock(block_hash_p);
+       hlist_bl_for_each_entry(lce, l, block_hash_p, e_block_list) {
+               if (lce->e_bdev == bdev && lce->e_block == block) {
+                       hlist_bl_unlock(block_hash_p);
+                       return -EBUSY;
+               }
        }
-       __mb_cache_entry_unhash(ce);
+       mb_assert(!__mb_cache_entry_is_block_hashed(ce));
+       __mb_cache_entry_unhash_block(ce);
+       __mb_cache_entry_unhash_index(ce);
        ce->e_bdev = bdev;
        ce->e_block = block;
-       list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
+       ce->e_block_hash_p = block_hash_p;
        ce->e_index.o_key = key;
+       hlist_bl_add_head(&ce->e_block_list, block_hash_p);
+       hlist_bl_unlock(block_hash_p);
        bucket = hash_long(key, cache->c_bucket_bits);
-       list_add(&ce->e_index.o_list, &cache->c_index_hash[bucket]);
-       error = 0;
-out:
-       spin_unlock(&mb_cache_spinlock);
-       return error;
+       index_hash_p = &cache->c_index_hash[bucket];
+       hlist_bl_lock(index_hash_p);
+       ce->e_index_hash_p = index_hash_p;
+       hlist_bl_add_head(&ce->e_index.o_list, index_hash_p);
+       hlist_bl_unlock(index_hash_p);
+       return 0;
 }
 
 
@@ -429,24 +625,26 @@ out:
 void
 mb_cache_entry_release(struct mb_cache_entry *ce)
 {
-       spin_lock(&mb_cache_spinlock);
-       __mb_cache_entry_release_unlock(ce);
+       __mb_cache_entry_release(ce);
 }
 
 
 /*
  * mb_cache_entry_free()
  *
- * This is equivalent to the sequence mb_cache_entry_takeout() --
- * mb_cache_entry_release().
  */
 void
 mb_cache_entry_free(struct mb_cache_entry *ce)
 {
-       spin_lock(&mb_cache_spinlock);
+       mb_assert(ce);
        mb_assert(list_empty(&ce->e_lru_list));
-       __mb_cache_entry_unhash(ce);
-       __mb_cache_entry_release_unlock(ce);
+       hlist_bl_lock(ce->e_index_hash_p);
+       __mb_cache_entry_unhash_index(ce);
+       hlist_bl_unlock(ce->e_index_hash_p);
+       hlist_bl_lock(ce->e_block_hash_p);
+       __mb_cache_entry_unhash_block(ce);
+       hlist_bl_unlock(ce->e_block_hash_p);
+       __mb_cache_entry_release(ce);
 }
 
 
@@ -463,84 +661,110 @@ mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev,
                   sector_t block)
 {
        unsigned int bucket;
-       struct list_head *l;
+       struct hlist_bl_node *l;
        struct mb_cache_entry *ce;
+       struct hlist_bl_head *block_hash_p;
 
        bucket = hash_long((unsigned long)bdev + (block & 0xffffffff),
                           cache->c_bucket_bits);
-       spin_lock(&mb_cache_spinlock);
-       list_for_each(l, &cache->c_block_hash[bucket]) {
-               ce = list_entry(l, struct mb_cache_entry, e_block_list);
+       block_hash_p = &cache->c_block_hash[bucket];
+       /* First serialize access to the block corresponding hash chain. */
+       hlist_bl_lock(block_hash_p);
+       hlist_bl_for_each_entry(ce, l, block_hash_p, e_block_list) {
+               mb_assert(ce->e_block_hash_p == block_hash_p);
                if (ce->e_bdev == bdev && ce->e_block == block) {
-                       DEFINE_WAIT(wait);
+                       /*
+                        * Prevent a free from removing the entry.
+                        */
+                       atomic_inc(&ce->e_refcnt);
+                       hlist_bl_unlock(block_hash_p);
+                       __spin_lock_mb_cache_entry(ce);
+                       atomic_dec(&ce->e_refcnt);
+                       if (ce->e_used > 0) {
+                               DEFINE_WAIT(wait);
+                               while (ce->e_used > 0) {
+                                       ce->e_queued++;
+                                       prepare_to_wait(&mb_cache_queue, &wait,
+                                                       TASK_UNINTERRUPTIBLE);
+                                       __spin_unlock_mb_cache_entry(ce);
+                                       schedule();
+                                       __spin_lock_mb_cache_entry(ce);
+                                       ce->e_queued--;
+                               }
+                               finish_wait(&mb_cache_queue, &wait);
+                       }
+                       ce->e_used += 1 + MB_CACHE_WRITER;
+                       __spin_unlock_mb_cache_entry(ce);
 
-                       if (!list_empty(&ce->e_lru_list))
+                       if (!list_empty(&ce->e_lru_list)) {
+                               spin_lock(&mb_cache_spinlock);
                                list_del_init(&ce->e_lru_list);
-
-                       while (ce->e_used > 0) {
-                               ce->e_queued++;
-                               prepare_to_wait(&mb_cache_queue, &wait,
-                                               TASK_UNINTERRUPTIBLE);
                                spin_unlock(&mb_cache_spinlock);
-                               schedule();
-                               spin_lock(&mb_cache_spinlock);
-                               ce->e_queued--;
                        }
-                       finish_wait(&mb_cache_queue, &wait);
-                       ce->e_used += 1 + MB_CACHE_WRITER;
-
-                       if (!__mb_cache_entry_is_hashed(ce)) {
-                               __mb_cache_entry_release_unlock(ce);
+                       if (!__mb_cache_entry_is_block_hashed(ce)) {
+                               __mb_cache_entry_release(ce);
                                return NULL;
                        }
-                       goto cleanup;
+                       return ce;
                }
        }
-       ce = NULL;
-
-cleanup:
-       spin_unlock(&mb_cache_spinlock);
-       return ce;
+       hlist_bl_unlock(block_hash_p);
+       return NULL;
 }
 
 #if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
 
 static struct mb_cache_entry *
-__mb_cache_entry_find(struct list_head *l, struct list_head *head,
+__mb_cache_entry_find(struct hlist_bl_node *l, struct hlist_bl_head *head,
                      struct block_device *bdev, unsigned int key)
 {
-       while (l != head) {
+
+       /* The index hash chain is alredy acquire by caller. */
+       while (l != NULL) {
                struct mb_cache_entry *ce =
-                       list_entry(l, struct mb_cache_entry, e_index.o_list);
+                       hlist_bl_entry(l, struct mb_cache_entry,
+                               e_index.o_list);
+               mb_assert(ce->e_index_hash_p == head);
                if (ce->e_bdev == bdev && ce->e_index.o_key == key) {
-                       DEFINE_WAIT(wait);
-
-                       if (!list_empty(&ce->e_lru_list))
-                               list_del_init(&ce->e_lru_list);
-
+                       /*
+                        * Prevent a free from removing the entry.
+                        */
+                       atomic_inc(&ce->e_refcnt);
+                       hlist_bl_unlock(head);
+                       __spin_lock_mb_cache_entry(ce);
+                       atomic_dec(&ce->e_refcnt);
+                       ce->e_used++;
                        /* Incrementing before holding the lock gives readers
                           priority over writers. */
-                       ce->e_used++;
-                       while (ce->e_used >= MB_CACHE_WRITER) {
-                               ce->e_queued++;
-                               prepare_to_wait(&mb_cache_queue, &wait,
-                                               TASK_UNINTERRUPTIBLE);
-                               spin_unlock(&mb_cache_spinlock);
-                               schedule();
-                               spin_lock(&mb_cache_spinlock);
-                               ce->e_queued--;
+                       if (ce->e_used >= MB_CACHE_WRITER) {
+                               DEFINE_WAIT(wait);
+
+                               while (ce->e_used >= MB_CACHE_WRITER) {
+                                       ce->e_queued++;
+                                       prepare_to_wait(&mb_cache_queue, &wait,
+                                                       TASK_UNINTERRUPTIBLE);
+                                       __spin_unlock_mb_cache_entry(ce);
+                                       schedule();
+                                       __spin_lock_mb_cache_entry(ce);
+                                       ce->e_queued--;
+                               }
+                               finish_wait(&mb_cache_queue, &wait);
                        }
-                       finish_wait(&mb_cache_queue, &wait);
-
-                       if (!__mb_cache_entry_is_hashed(ce)) {
-                               __mb_cache_entry_release_unlock(ce);
+                       __spin_unlock_mb_cache_entry(ce);
+                       if (!list_empty(&ce->e_lru_list)) {
                                spin_lock(&mb_cache_spinlock);
+                               list_del_init(&ce->e_lru_list);
+                               spin_unlock(&mb_cache_spinlock);
+                       }
+                       if (!__mb_cache_entry_is_block_hashed(ce)) {
+                               __mb_cache_entry_release(ce);
                                return ERR_PTR(-EAGAIN);
                        }
                        return ce;
                }
                l = l->next;
        }
+       hlist_bl_unlock(head);
        return NULL;
 }
 
@@ -562,13 +786,17 @@ mb_cache_entry_find_first(struct mb_cache *cache, struct block_device *bdev,
                          unsigned int key)
 {
        unsigned int bucket = hash_long(key, cache->c_bucket_bits);
-       struct list_head *l;
-       struct mb_cache_entry *ce;
-
-       spin_lock(&mb_cache_spinlock);
-       l = cache->c_index_hash[bucket].next;
-       ce = __mb_cache_entry_find(l, &cache->c_index_hash[bucket], bdev, key);
-       spin_unlock(&mb_cache_spinlock);
+       struct hlist_bl_node *l;
+       struct mb_cache_entry *ce = NULL;
+       struct hlist_bl_head *index_hash_p;
+
+       index_hash_p = &cache->c_index_hash[bucket];
+       hlist_bl_lock(index_hash_p);
+       if (!hlist_bl_empty(index_hash_p)) {
+               l = hlist_bl_first(index_hash_p);
+               ce = __mb_cache_entry_find(l, index_hash_p, bdev, key);
+       } else
+               hlist_bl_unlock(index_hash_p);
        return ce;
 }
 
@@ -597,13 +825,17 @@ mb_cache_entry_find_next(struct mb_cache_entry *prev,
 {
        struct mb_cache *cache = prev->e_cache;
        unsigned int bucket = hash_long(key, cache->c_bucket_bits);
-       struct list_head *l;
+       struct hlist_bl_node *l;
        struct mb_cache_entry *ce;
+       struct hlist_bl_head *index_hash_p;
 
-       spin_lock(&mb_cache_spinlock);
+       index_hash_p = &cache->c_index_hash[bucket];
+       mb_assert(prev->e_index_hash_p == index_hash_p);
+       hlist_bl_lock(index_hash_p);
+       mb_assert(!hlist_bl_empty(index_hash_p));
        l = prev->e_index.o_list.next;
-       ce = __mb_cache_entry_find(l, &cache->c_index_hash[bucket], bdev, key);
-       __mb_cache_entry_release_unlock(prev);
+       ce = __mb_cache_entry_find(l, index_hash_p, bdev, key);
+       __mb_cache_entry_release(prev);
        return ce;
 }
 
index 0ad2ec9601de1b2bfee9b1d4c202df6627f7f751..f007a3355570b38de89b57343407ccafad6cbe21 100644 (file)
@@ -123,6 +123,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
        struct minix_sb_info * sbi = minix_sb(sb);
        struct minix_super_block * ms;
 
+       sync_filesystem(sb);
        ms = sbi->s_ms;
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
index 4b491b4319905b2dd6698d3f58aae1d0d0141499..88339f59efb5d9b3691f5ebbad7e5ef6eb59c4db 100644 (file)
@@ -1796,7 +1796,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
                        if (err)
                                return err;
                }
-               if (!d_is_directory(nd->path.dentry)) {
+               if (!d_can_lookup(nd->path.dentry)) {
                        err = -ENOTDIR; 
                        break;
                }
@@ -1817,7 +1817,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
                struct dentry *root = nd->root.dentry;
                struct inode *inode = root->d_inode;
                if (*name) {
-                       if (!d_is_directory(root))
+                       if (!d_can_lookup(root))
                                return -ENOTDIR;
                        retval = inode_permission(inode, MAY_EXEC);
                        if (retval)
@@ -1873,7 +1873,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
                dentry = f.file->f_path.dentry;
 
                if (*name) {
-                       if (!d_is_directory(dentry)) {
+                       if (!d_can_lookup(dentry)) {
                                fdput(f);
                                return -ENOTDIR;
                        }
@@ -1955,7 +1955,7 @@ static int path_lookupat(int dfd, const char *name,
                err = complete_walk(nd);
 
        if (!err && nd->flags & LOOKUP_DIRECTORY) {
-               if (!d_is_directory(nd->path.dentry)) {
+               if (!d_can_lookup(nd->path.dentry)) {
                        path_put(&nd->path);
                        err = -ENOTDIR;
                }
@@ -2414,11 +2414,11 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
            IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
                return -EPERM;
        if (isdir) {
-               if (!d_is_directory(victim) && !d_is_autodir(victim))
+               if (!d_is_dir(victim))
                        return -ENOTDIR;
                if (IS_ROOT(victim))
                        return -EBUSY;
-       } else if (d_is_directory(victim) || d_is_autodir(victim))
+       } else if (d_is_dir(victim))
                return -EISDIR;
        if (IS_DEADDIR(dir))
                return -ENOENT;
@@ -2569,7 +2569,7 @@ static int handle_truncate(struct file *filp)
        /*
         * Refuse to truncate files with mandatory locks held on them.
         */
-       error = locks_verify_locked(inode);
+       error = locks_verify_locked(filp);
        if (!error)
                error = security_path_truncate(path);
        if (!error) {
@@ -3016,11 +3016,10 @@ finish_open:
        }
        audit_inode(name, nd->path.dentry, 0);
        error = -EISDIR;
-       if ((open_flag & O_CREAT) &&
-           (d_is_directory(nd->path.dentry) || d_is_autodir(nd->path.dentry)))
+       if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
                goto out;
        error = -ENOTDIR;
-       if ((nd->flags & LOOKUP_DIRECTORY) && !d_is_directory(nd->path.dentry))
+       if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
                goto out;
        if (!S_ISREG(nd->inode->i_mode))
                will_truncate = false;
@@ -3744,7 +3743,7 @@ exit1:
 slashes:
        if (d_is_negative(dentry))
                error = -ENOENT;
-       else if (d_is_directory(dentry) || d_is_autodir(dentry))
+       else if (d_is_dir(dentry))
                error = -EISDIR;
        else
                error = -ENOTDIR;
@@ -3974,7 +3973,28 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
        return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
 }
 
-/*
+/**
+ * vfs_rename - rename a filesystem object
+ * @old_dir:   parent of source
+ * @old_dentry:        source
+ * @new_dir:   parent of destination
+ * @new_dentry:        destination
+ * @delegated_inode: returns an inode needing a delegation break
+ * @flags:     rename flags
+ *
+ * The caller must hold multiple mutexes--see lock_rename()).
+ *
+ * If vfs_rename discovers a delegation in need of breaking at either
+ * the source or destination, it will return -EWOULDBLOCK and return a
+ * reference to the inode in delegated_inode.  The caller should then
+ * break the delegation and retry.  Because breaking a delegation may
+ * take a long time, the caller should drop all locks before doing
+ * so.
+ *
+ * Alternatively, a caller may pass NULL for delegated_inode.  This may
+ * be appropriate for callers that expect the underlying filesystem not
+ * to be NFS exported.
+ *
  * The worst of all namespace operations - renaming directory. "Perverted"
  * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
  * Problems:
@@ -4002,163 +4022,139 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
  *        ->i_mutex on parents, which works but leads to some truly excessive
  *        locking].
  */
-static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
-                         struct inode *new_dir, struct dentry *new_dentry)
+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+              struct inode *new_dir, struct dentry *new_dentry,
+              struct inode **delegated_inode, unsigned int flags)
 {
-       int error = 0;
+       int error;
+       bool is_dir = d_is_dir(old_dentry);
+       const unsigned char *old_name;
+       struct inode *source = old_dentry->d_inode;
        struct inode *target = new_dentry->d_inode;
+       bool new_is_dir = false;
        unsigned max_links = new_dir->i_sb->s_max_links;
 
+       if (source == target)
+               return 0;
+
+       error = may_delete(old_dir, old_dentry, is_dir);
+       if (error)
+               return error;
+
+       if (!target) {
+               error = may_create(new_dir, new_dentry);
+       } else {
+               new_is_dir = d_is_dir(new_dentry);
+
+               if (!(flags & RENAME_EXCHANGE))
+                       error = may_delete(new_dir, new_dentry, is_dir);
+               else
+                       error = may_delete(new_dir, new_dentry, new_is_dir);
+       }
+       if (error)
+               return error;
+
+       if (!old_dir->i_op->rename)
+               return -EPERM;
+
+       if (flags && !old_dir->i_op->rename2)
+               return -EINVAL;
+
        /*
         * If we are going to change the parent - check write permissions,
         * we'll need to flip '..'.
         */
        if (new_dir != old_dir) {
-               error = inode_permission(old_dentry->d_inode, MAY_WRITE);
-               if (error)
-                       return error;
+               if (is_dir) {
+                       error = inode_permission(source, MAY_WRITE);
+                       if (error)
+                               return error;
+               }
+               if ((flags & RENAME_EXCHANGE) && new_is_dir) {
+                       error = inode_permission(target, MAY_WRITE);
+                       if (error)
+                               return error;
+               }
        }
 
-       error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
+       error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry,
+                                     flags);
        if (error)
                return error;
 
+       old_name = fsnotify_oldname_init(old_dentry->d_name.name);
        dget(new_dentry);
-       if (target)
+       if (!is_dir || (flags & RENAME_EXCHANGE))
+               lock_two_nondirectories(source, target);
+       else if (target)
                mutex_lock(&target->i_mutex);
 
        error = -EBUSY;
        if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry))
                goto out;
 
-       error = -EMLINK;
-       if (max_links && !target && new_dir != old_dir &&
-           new_dir->i_nlink >= max_links)
-               goto out;
-
-       if (target)
+       if (max_links && new_dir != old_dir) {
+               error = -EMLINK;
+               if (is_dir && !new_is_dir && new_dir->i_nlink >= max_links)
+                       goto out;
+               if ((flags & RENAME_EXCHANGE) && !is_dir && new_is_dir &&
+                   old_dir->i_nlink >= max_links)
+                       goto out;
+       }
+       if (is_dir && !(flags & RENAME_EXCHANGE) && target)
                shrink_dcache_parent(new_dentry);
-       error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
-       if (error)
-               goto out;
-
-       if (target) {
-               target->i_flags |= S_DEAD;
-               dont_mount(new_dentry);
+       if (!is_dir) {
+               error = try_break_deleg(source, delegated_inode);
+               if (error)
+                       goto out;
        }
-out:
-       if (target)
-               mutex_unlock(&target->i_mutex);
-       dput(new_dentry);
-       if (!error)
-               if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
-                       d_move(old_dentry,new_dentry);
-       return error;
-}
-
-static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
-                           struct inode *new_dir, struct dentry *new_dentry,
-                           struct inode **delegated_inode)
-{
-       struct inode *target = new_dentry->d_inode;
-       struct inode *source = old_dentry->d_inode;
-       int error;
-
-       error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
-       if (error)
-               return error;
-
-       dget(new_dentry);
-       lock_two_nondirectories(source, target);
-
-       error = -EBUSY;
-       if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
-               goto out;
-
-       error = try_break_deleg(source, delegated_inode);
-       if (error)
-               goto out;
-       if (target) {
+       if (target && !new_is_dir) {
                error = try_break_deleg(target, delegated_inode);
                if (error)
                        goto out;
        }
-       error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
+       if (!flags) {
+               error = old_dir->i_op->rename(old_dir, old_dentry,
+                                             new_dir, new_dentry);
+       } else {
+               error = old_dir->i_op->rename2(old_dir, old_dentry,
+                                              new_dir, new_dentry, flags);
+       }
        if (error)
                goto out;
 
-       if (target)
+       if (!(flags & RENAME_EXCHANGE) && target) {
+               if (is_dir)
+                       target->i_flags |= S_DEAD;
                dont_mount(new_dentry);
-       if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
-               d_move(old_dentry, new_dentry);
+       }
+       if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) {
+               if (!(flags & RENAME_EXCHANGE))
+                       d_move(old_dentry, new_dentry);
+               else
+                       d_exchange(old_dentry, new_dentry);
+       }
 out:
-       unlock_two_nondirectories(source, target);
+       if (!is_dir || (flags & RENAME_EXCHANGE))
+               unlock_two_nondirectories(source, target);
+       else if (target)
+               mutex_unlock(&target->i_mutex);
        dput(new_dentry);
-       return error;
-}
-
-/**
- * vfs_rename - rename a filesystem object
- * @old_dir:   parent of source
- * @old_dentry:        source
- * @new_dir:   parent of destination
- * @new_dentry:        destination
- * @delegated_inode: returns an inode needing a delegation break
- *
- * The caller must hold multiple mutexes--see lock_rename()).
- *
- * If vfs_rename discovers a delegation in need of breaking at either
- * the source or destination, it will return -EWOULDBLOCK and return a
- * reference to the inode in delegated_inode.  The caller should then
- * break the delegation and retry.  Because breaking a delegation may
- * take a long time, the caller should drop all locks before doing
- * so.
- *
- * Alternatively, a caller may pass NULL for delegated_inode.  This may
- * be appropriate for callers that expect the underlying filesystem not
- * to be NFS exported.
- */
-int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-              struct inode *new_dir, struct dentry *new_dentry,
-              struct inode **delegated_inode)
-{
-       int error;
-       int is_dir = d_is_directory(old_dentry) || d_is_autodir(old_dentry);
-       const unsigned char *old_name;
-
-       if (old_dentry->d_inode == new_dentry->d_inode)
-               return 0;
-       error = may_delete(old_dir, old_dentry, is_dir);
-       if (error)
-               return error;
-
-       if (!new_dentry->d_inode)
-               error = may_create(new_dir, new_dentry);
-       else
-               error = may_delete(new_dir, new_dentry, is_dir);
-       if (error)
-               return error;
-
-       if (!old_dir->i_op->rename)
-               return -EPERM;
-
-       old_name = fsnotify_oldname_init(old_dentry->d_name.name);
-
-       if (is_dir)
-               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
-       else
-               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,delegated_inode);
-       if (!error)
+       if (!error) {
                fsnotify_move(old_dir, new_dir, old_name, is_dir,
-                             new_dentry->d_inode, old_dentry);
+                             !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry);
+               if (flags & RENAME_EXCHANGE) {
+                       fsnotify_move(new_dir, old_dir, old_dentry->d_name.name,
+                                     new_is_dir, NULL, new_dentry);
+               }
+       }
        fsnotify_oldname_free(old_name);
 
        return error;
 }
 
-SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
-               int, newdfd, const char __user *, newname)
+SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
+               int, newdfd, const char __user *, newname, unsigned int, flags)
 {
        struct dentry *old_dir, *new_dir;
        struct dentry *old_dentry, *new_dentry;
@@ -4170,6 +4166,13 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
        unsigned int lookup_flags = 0;
        bool should_retry = false;
        int error;
+
+       if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
+               return -EINVAL;
+
+       if ((flags & RENAME_NOREPLACE) && (flags & RENAME_EXCHANGE))
+               return -EINVAL;
+
 retry:
        from = user_path_parent(olddfd, oldname, &oldnd, lookup_flags);
        if (IS_ERR(from)) {
@@ -4193,6 +4196,8 @@ retry:
                goto exit2;
 
        new_dir = newnd.path.dentry;
+       if (flags & RENAME_NOREPLACE)
+               error = -EEXIST;
        if (newnd.last_type != LAST_NORM)
                goto exit2;
 
@@ -4202,7 +4207,8 @@ retry:
 
        oldnd.flags &= ~LOOKUP_PARENT;
        newnd.flags &= ~LOOKUP_PARENT;
-       newnd.flags |= LOOKUP_RENAME_TARGET;
+       if (!(flags & RENAME_EXCHANGE))
+               newnd.flags |= LOOKUP_RENAME_TARGET;
 
 retry_deleg:
        trap = lock_rename(new_dir, old_dir);
@@ -4215,34 +4221,49 @@ retry_deleg:
        error = -ENOENT;
        if (d_is_negative(old_dentry))
                goto exit4;
+       new_dentry = lookup_hash(&newnd);
+       error = PTR_ERR(new_dentry);
+       if (IS_ERR(new_dentry))
+               goto exit4;
+       error = -EEXIST;
+       if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry))
+               goto exit5;
+       if (flags & RENAME_EXCHANGE) {
+               error = -ENOENT;
+               if (d_is_negative(new_dentry))
+                       goto exit5;
+
+               if (!d_is_dir(new_dentry)) {
+                       error = -ENOTDIR;
+                       if (newnd.last.name[newnd.last.len])
+                               goto exit5;
+               }
+       }
        /* unless the source is a directory trailing slashes give -ENOTDIR */
-       if (!d_is_directory(old_dentry) && !d_is_autodir(old_dentry)) {
+       if (!d_is_dir(old_dentry)) {
                error = -ENOTDIR;
                if (oldnd.last.name[oldnd.last.len])
-                       goto exit4;
-               if (newnd.last.name[newnd.last.len])
-                       goto exit4;
+                       goto exit5;
+               if (!(flags & RENAME_EXCHANGE) && newnd.last.name[newnd.last.len])
+                       goto exit5;
        }
        /* source should not be ancestor of target */
        error = -EINVAL;
        if (old_dentry == trap)
-               goto exit4;
-       new_dentry = lookup_hash(&newnd);
-       error = PTR_ERR(new_dentry);
-       if (IS_ERR(new_dentry))
-               goto exit4;
+               goto exit5;
        /* target should not be an ancestor of source */
-       error = -ENOTEMPTY;
+       if (!(flags & RENAME_EXCHANGE))
+               error = -ENOTEMPTY;
        if (new_dentry == trap)
                goto exit5;
 
        error = security_path_rename(&oldnd.path, old_dentry,
-                                    &newnd.path, new_dentry);
+                                    &newnd.path, new_dentry, flags);
        if (error)
                goto exit5;
        error = vfs_rename(old_dir->d_inode, old_dentry,
-                                  new_dir->d_inode, new_dentry,
-                                  &delegated_inode);
+                          new_dir->d_inode, new_dentry,
+                          &delegated_inode, flags);
 exit5:
        dput(new_dentry);
 exit4:
@@ -4272,9 +4293,15 @@ exit:
        return error;
 }
 
+SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
+               int, newdfd, const char __user *, newname)
+{
+       return sys_renameat2(olddfd, oldname, newdfd, newname, 0);
+}
+
 SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
 {
-       return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
+       return sys_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
 }
 
 int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
index ee59d35ff069821bcc00160a0f104fada6865861..647d86d2db395028a47eed98be3f5264b715e8cb 100644 (file)
@@ -99,6 +99,7 @@ static void destroy_inodecache(void)
 
 static int ncp_remount(struct super_block *sb, int *flags, char* data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        return 0;
 }
index ae2e87b95453d2b21f746bdb931da675197ad0ba..41db5258e7a7a5ef837ebd11ae605f7144bd4e65 100644 (file)
@@ -112,7 +112,8 @@ out:
  * TODO: keep track of all layouts (and delegations) in a hash table
  * hashed by filehandle.
  */
-static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, struct nfs_fh *fh)
+static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
+               struct nfs_fh *fh, nfs4_stateid *stateid)
 {
        struct nfs_server *server;
        struct inode *ino;
@@ -120,17 +121,19 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
 
        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
                list_for_each_entry(lo, &server->layouts, plh_layouts) {
+                       if (!nfs4_stateid_match_other(&lo->plh_stateid, stateid))
+                               continue;
                        if (nfs_compare_fh(fh, &NFS_I(lo->plh_inode)->fh))
                                continue;
                        ino = igrab(lo->plh_inode);
                        if (!ino)
-                               continue;
+                               break;
                        spin_lock(&ino->i_lock);
                        /* Is this layout in the process of being freed? */
                        if (NFS_I(ino)->layout != lo) {
                                spin_unlock(&ino->i_lock);
                                iput(ino);
-                               continue;
+                               break;
                        }
                        pnfs_get_layout_hdr(lo);
                        spin_unlock(&ino->i_lock);
@@ -141,13 +144,14 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
        return NULL;
 }
 
-static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, struct nfs_fh *fh)
+static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp,
+               struct nfs_fh *fh, nfs4_stateid *stateid)
 {
        struct pnfs_layout_hdr *lo;
 
        spin_lock(&clp->cl_lock);
        rcu_read_lock();
-       lo = get_layout_by_fh_locked(clp, fh);
+       lo = get_layout_by_fh_locked(clp, fh, stateid);
        rcu_read_unlock();
        spin_unlock(&clp->cl_lock);
 
@@ -162,9 +166,9 @@ static u32 initiate_file_draining(struct nfs_client *clp,
        u32 rv = NFS4ERR_NOMATCHING_LAYOUT;
        LIST_HEAD(free_me_list);
 
-       lo = get_layout_by_fh(clp, &args->cbl_fh);
+       lo = get_layout_by_fh(clp, &args->cbl_fh, &args->cbl_stateid);
        if (!lo)
-               return NFS4ERR_NOMATCHING_LAYOUT;
+               goto out;
 
        ino = lo->plh_inode;
        spin_lock(&ino->i_lock);
@@ -179,6 +183,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
        pnfs_free_lseg_list(&free_me_list);
        pnfs_put_layout_hdr(lo);
        iput(ino);
+out:
        return rv;
 }
 
index 4a48fe4b84b68c4e704aea84ea761e101a5ad0df..d9f3d067cd15635ffd0bb569ef76a156a2d84630 100644 (file)
@@ -69,21 +69,28 @@ const struct address_space_operations nfs_dir_aops = {
 
 static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred)
 {
+       struct nfs_inode *nfsi = NFS_I(dir);
        struct nfs_open_dir_context *ctx;
        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
        if (ctx != NULL) {
                ctx->duped = 0;
-               ctx->attr_gencount = NFS_I(dir)->attr_gencount;
+               ctx->attr_gencount = nfsi->attr_gencount;
                ctx->dir_cookie = 0;
                ctx->dup_cookie = 0;
                ctx->cred = get_rpccred(cred);
+               spin_lock(&dir->i_lock);
+               list_add(&ctx->list, &nfsi->open_files);
+               spin_unlock(&dir->i_lock);
                return ctx;
        }
        return  ERR_PTR(-ENOMEM);
 }
 
-static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx)
+static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_context *ctx)
 {
+       spin_lock(&dir->i_lock);
+       list_del(&ctx->list);
+       spin_unlock(&dir->i_lock);
        put_rpccred(ctx->cred);
        kfree(ctx);
 }
@@ -126,7 +133,7 @@ out:
 static int
 nfs_closedir(struct inode *inode, struct file *filp)
 {
-       put_nfs_open_dir_context(filp->private_data);
+       put_nfs_open_dir_context(filp->f_path.dentry->d_inode, filp->private_data);
        return 0;
 }
 
@@ -306,10 +313,9 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
                                        if (printk_ratelimit()) {
                                                pr_notice("NFS: directory %pD2 contains a readdir loop."
                                                                "Please contact your server vendor.  "
-                                                               "The file: %s has duplicate cookie %llu\n",
-                                                               desc->file,
-                                                               array->array[i].string.name,
-                                                               *desc->dir_cookie);
+                                                               "The file: %.*s has duplicate cookie %llu\n",
+                                                               desc->file, array->array[i].string.len,
+                                                               array->array[i].string.name, *desc->dir_cookie);
                                        }
                                        status = -ELOOP;
                                        goto out;
@@ -437,6 +443,22 @@ void nfs_advise_use_readdirplus(struct inode *dir)
        set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags);
 }
 
+/*
+ * This function is mainly for use by nfs_getattr().
+ *
+ * If this is an 'ls -l', we want to force use of readdirplus.
+ * Do this by checking if there is an active file descriptor
+ * and calling nfs_advise_use_readdirplus, then forcing a
+ * cache flush.
+ */
+void nfs_force_use_readdirplus(struct inode *dir)
+{
+       if (!list_empty(&NFS_I(dir)->open_files)) {
+               nfs_advise_use_readdirplus(dir);
+               nfs_zap_mapping(dir, dir->i_mapping);
+       }
+}
+
 static
 void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
 {
@@ -815,6 +837,17 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc)
        goto out;
 }
 
+static bool nfs_dir_mapping_need_revalidate(struct inode *dir)
+{
+       struct nfs_inode *nfsi = NFS_I(dir);
+
+       if (nfs_attribute_cache_expired(dir))
+               return true;
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               return true;
+       return false;
+}
+
 /* The file offset position represents the dirent entry number.  A
    last cookie cache takes care of the common case of reading the
    whole directory.
@@ -847,7 +880,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
        desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;
 
        nfs_block_sillyrename(dentry);
-       if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
+       if (ctx->pos == 0 || nfs_dir_mapping_need_revalidate(inode))
                res = nfs_revalidate_mapping(inode, file->f_mapping);
        if (res < 0)
                goto out;
@@ -1911,6 +1944,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct inode *old_inode = old_dentry->d_inode;
        struct inode *new_inode = new_dentry->d_inode;
        struct dentry *dentry = NULL, *rehash = NULL;
+       struct rpc_task *task;
        int error = -EBUSY;
 
        dfprintk(VFS, "NFS: rename(%pd2 -> %pd2, ct=%d)\n",
@@ -1958,8 +1992,16 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (new_inode != NULL)
                NFS_PROTO(new_inode)->return_delegation(new_inode);
 
-       error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
-                                          new_dir, &new_dentry->d_name);
+       task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
+       if (IS_ERR(task)) {
+               error = PTR_ERR(task);
+               goto out;
+       }
+
+       error = rpc_wait_for_completion_task(task);
+       if (error == 0)
+               error = task->tk_status;
+       rpc_put_task(task);
        nfs_mark_for_revalidate(old_inode);
 out:
        if (rehash)
index c4702baa22b83355efdb327335bd1a6af512affc..0c438973f3c8687836fc16bae3fb9aa89a767727 100644 (file)
@@ -588,6 +588,25 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
 }
 EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
 
+static void nfs_request_parent_use_readdirplus(struct dentry *dentry)
+{
+       struct dentry *parent;
+
+       parent = dget_parent(dentry);
+       nfs_force_use_readdirplus(parent->d_inode);
+       dput(parent);
+}
+
+static bool nfs_need_revalidate_inode(struct inode *inode)
+{
+       if (NFS_I(inode)->cache_validity &
+                       (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
+               return true;
+       if (nfs_attribute_cache_expired(inode))
+               return true;
+       return false;
+}
+
 int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
        struct inode *inode = dentry->d_inode;
@@ -616,10 +635,13 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
            ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
                need_atime = 0;
 
-       if (need_atime)
-               err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
-       else
-               err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+       if (need_atime || nfs_need_revalidate_inode(inode)) {
+               struct nfs_server *server = NFS_SERVER(inode);
+
+               if (server->caps & NFS_CAP_READDIRPLUS)
+                       nfs_request_parent_use_readdirplus(dentry);
+               err = __nfs_revalidate_inode(server, inode);
+       }
        if (!err) {
                generic_fillattr(inode, stat);
                stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
@@ -961,9 +983,7 @@ int nfs_attribute_cache_expired(struct inode *inode)
  */
 int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
-       if (!(NFS_I(inode)->cache_validity &
-                       (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
-                       && !nfs_attribute_cache_expired(inode))
+       if (!nfs_need_revalidate_inode(inode))
                return NFS_STALE(inode) ? -ESTALE : 0;
        return __nfs_revalidate_inode(server, inode);
 }
index b46cf5a6732952460c68f6faeeb5479f355868d7..dd8bfc2e2464609dd7fa755afcff2b6f436f5def 100644 (file)
@@ -301,6 +301,7 @@ extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
                           const char *ip_addr);
 
 /* dir.c */
+extern void nfs_force_use_readdirplus(struct inode *dir);
 extern unsigned long nfs_access_cache_count(struct shrinker *shrink,
                                            struct shrink_control *sc);
 extern unsigned long nfs_access_cache_scan(struct shrinker *shrink,
@@ -474,6 +475,13 @@ extern int nfs_migrate_page(struct address_space *,
 #define nfs_migrate_page NULL
 #endif
 
+/* unlink.c */
+extern struct rpc_task *
+nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
+                struct dentry *old_dentry, struct dentry *new_dentry,
+                void (*complete)(struct rpc_task *, struct nfs_renamedata *));
+extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);
+
 /* direct.c */
 void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
                              struct nfs_direct_req *dreq);
index a462ef0fb5d6dcda8bab6f211e8122d7d972b070..db60149c4579a9cfd9409ec355da9eeb2f254359 100644 (file)
@@ -478,41 +478,6 @@ nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
        return 1;
 }
 
-static int
-nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
-                struct inode *new_dir, struct qstr *new_name)
-{
-       struct nfs_renameargs   arg = {
-               .old_dir        = NFS_FH(old_dir),
-               .old_name       = old_name,
-               .new_dir        = NFS_FH(new_dir),
-               .new_name       = new_name,
-       };
-       struct nfs_renameres res;
-       struct rpc_message msg = {
-               .rpc_proc       = &nfs3_procedures[NFS3PROC_RENAME],
-               .rpc_argp       = &arg,
-               .rpc_resp       = &res,
-       };
-       int status = -ENOMEM;
-
-       dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
-
-       res.old_fattr = nfs_alloc_fattr();
-       res.new_fattr = nfs_alloc_fattr();
-       if (res.old_fattr == NULL || res.new_fattr == NULL)
-               goto out;
-
-       status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
-       nfs_post_op_update_inode(old_dir, res.old_fattr);
-       nfs_post_op_update_inode(new_dir, res.new_fattr);
-out:
-       nfs_free_fattr(res.old_fattr);
-       nfs_free_fattr(res.new_fattr);
-       dprintk("NFS reply rename: %d\n", status);
-       return status;
-}
-
 static int
 nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 {
@@ -968,7 +933,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
        .unlink_setup   = nfs3_proc_unlink_setup,
        .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare,
        .unlink_done    = nfs3_proc_unlink_done,
-       .rename         = nfs3_proc_rename,
        .rename_setup   = nfs3_proc_rename_setup,
        .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare,
        .rename_done    = nfs3_proc_rename_done,
index a5b27c2d9689f86704857b55365347e2f5c515d6..e1d1badbe53c32a1a4d9f9d4e4b83eb4c83a1b05 100644 (file)
@@ -427,6 +427,7 @@ extern void nfs4_close_sync(struct nfs4_state *, fmode_t);
 extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
 extern void nfs_inode_find_state_and_recover(struct inode *inode,
                const nfs4_stateid *stateid);
+extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *, struct nfs4_state *);
 extern void nfs4_schedule_lease_recovery(struct nfs_client *);
 extern int nfs4_wait_clnt_recover(struct nfs_client *clp);
 extern int nfs4_client_recover_expired_lease(struct nfs_client *clp);
@@ -500,6 +501,16 @@ static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_statei
        return memcmp(dst, src, sizeof(*dst)) == 0;
 }
 
+static inline bool nfs4_stateid_match_other(const nfs4_stateid *dst, const nfs4_stateid *src)
+{
+       return memcmp(dst->other, src->other, NFS4_STATEID_OTHER_SIZE) == 0;
+}
+
+static inline bool nfs4_stateid_is_newer(const nfs4_stateid *s1, const nfs4_stateid *s2)
+{
+       return (s32)(be32_to_cpu(s1->seqid) - be32_to_cpu(s2->seqid)) > 0;
+}
+
 static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
 {
        return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0;
index 0e46d3d1b6cc6c06854517c66ab4aa5f783cfb9e..aa9ef4876046aa17cc43c201d33ba6dbe49f1b8f 100644 (file)
@@ -531,6 +531,13 @@ int nfs40_walk_client_list(struct nfs_client *new,
                        *result = pos;
                        dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
                                __func__, pos, atomic_read(&pos->cl_count));
+                       goto out;
+               case -ERESTARTSYS:
+               case -ETIMEDOUT:
+                       /* The callback path may have been inadvertently
+                        * changed. Schedule recovery!
+                        */
+                       nfs4_schedule_path_down_recovery(pos);
                default:
                        goto out;
                }
index 450bfedbe2f4c0f88cacc44ec504872487279faa..397be39c6dc86623c27e08f2240efaecc2ec7722 100644 (file)
@@ -1068,6 +1068,7 @@ static void nfs4_opendata_free(struct kref *kref)
        dput(p->dentry);
        nfs_sb_deactive(sb);
        nfs_fattr_free_names(&p->f_attr);
+       kfree(p->f_attr.mdsthreshold);
        kfree(p);
 }
 
@@ -1137,12 +1138,71 @@ static void update_open_stateflags(struct nfs4_state *state, fmode_t fmode)
        nfs4_state_set_mode_locked(state, state->state | fmode);
 }
 
-static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *stateid, fmode_t fmode)
+static void nfs_test_and_clear_all_open_stateid(struct nfs4_state *state)
+{
+       struct nfs_client *clp = state->owner->so_server->nfs_client;
+       bool need_recover = false;
+
+       if (test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags) && state->n_rdonly)
+               need_recover = true;
+       if (test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags) && state->n_wronly)
+               need_recover = true;
+       if (test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags) && state->n_rdwr)
+               need_recover = true;
+       if (need_recover)
+               nfs4_state_mark_reclaim_nograce(clp, state);
+}
+
+static bool nfs_need_update_open_stateid(struct nfs4_state *state,
+               nfs4_stateid *stateid)
+{
+       if (test_and_set_bit(NFS_OPEN_STATE, &state->flags) == 0)
+               return true;
+       if (!nfs4_stateid_match_other(stateid, &state->open_stateid)) {
+               nfs_test_and_clear_all_open_stateid(state);
+               return true;
+       }
+       if (nfs4_stateid_is_newer(stateid, &state->open_stateid))
+               return true;
+       return false;
+}
+
+static void nfs_clear_open_stateid_locked(struct nfs4_state *state,
+               nfs4_stateid *stateid, fmode_t fmode)
 {
+       clear_bit(NFS_O_RDWR_STATE, &state->flags);
+       switch (fmode & (FMODE_READ|FMODE_WRITE)) {
+       case FMODE_WRITE:
+               clear_bit(NFS_O_RDONLY_STATE, &state->flags);
+               break;
+       case FMODE_READ:
+               clear_bit(NFS_O_WRONLY_STATE, &state->flags);
+               break;
+       case 0:
+               clear_bit(NFS_O_RDONLY_STATE, &state->flags);
+               clear_bit(NFS_O_WRONLY_STATE, &state->flags);
+               clear_bit(NFS_OPEN_STATE, &state->flags);
+       }
+       if (stateid == NULL)
+               return;
+       if (!nfs_need_update_open_stateid(state, stateid))
+               return;
        if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
                nfs4_stateid_copy(&state->stateid, stateid);
        nfs4_stateid_copy(&state->open_stateid, stateid);
-       set_bit(NFS_OPEN_STATE, &state->flags);
+}
+
+static void nfs_clear_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, fmode_t fmode)
+{
+       write_seqlock(&state->seqlock);
+       nfs_clear_open_stateid_locked(state, stateid, fmode);
+       write_sequnlock(&state->seqlock);
+       if (test_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags))
+               nfs4_schedule_state_manager(state->owner->so_server->nfs_client);
+}
+
+static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *stateid, fmode_t fmode)
+{
        switch (fmode) {
                case FMODE_READ:
                        set_bit(NFS_O_RDONLY_STATE, &state->flags);
@@ -1153,13 +1213,11 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *
                case FMODE_READ|FMODE_WRITE:
                        set_bit(NFS_O_RDWR_STATE, &state->flags);
        }
-}
-
-static void nfs_set_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, fmode_t fmode)
-{
-       write_seqlock(&state->seqlock);
-       nfs_set_open_stateid_locked(state, stateid, fmode);
-       write_sequnlock(&state->seqlock);
+       if (!nfs_need_update_open_stateid(state, stateid))
+               return;
+       if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
+               nfs4_stateid_copy(&state->stateid, stateid);
+       nfs4_stateid_copy(&state->open_stateid, stateid);
 }
 
 static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stateid, const nfs4_stateid *deleg_stateid, fmode_t fmode)
@@ -1217,6 +1275,8 @@ no_delegation:
                __update_open_stateid(state, open_stateid, NULL, fmode);
                ret = 1;
        }
+       if (test_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags))
+               nfs4_schedule_state_manager(state->owner->so_server->nfs_client);
 
        return ret;
 }
@@ -1450,12 +1510,15 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
        struct nfs4_state *newstate;
        int ret;
 
+       /* Don't trigger recovery in nfs_test_and_clear_all_open_stateid */
+       clear_bit(NFS_O_RDWR_STATE, &state->flags);
+       clear_bit(NFS_O_WRONLY_STATE, &state->flags);
+       clear_bit(NFS_O_RDONLY_STATE, &state->flags);
        /* memory barrier prior to reading state->n_* */
        clear_bit(NFS_DELEGATED_STATE, &state->flags);
        clear_bit(NFS_OPEN_STATE, &state->flags);
        smp_rmb();
        if (state->n_rdwr != 0) {
-               clear_bit(NFS_O_RDWR_STATE, &state->flags);
                ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate);
                if (ret != 0)
                        return ret;
@@ -1463,7 +1526,6 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
                        return -ESTALE;
        }
        if (state->n_wronly != 0) {
-               clear_bit(NFS_O_WRONLY_STATE, &state->flags);
                ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate);
                if (ret != 0)
                        return ret;
@@ -1471,7 +1533,6 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
                        return -ESTALE;
        }
        if (state->n_rdonly != 0) {
-               clear_bit(NFS_O_RDONLY_STATE, &state->flags);
                ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate);
                if (ret != 0)
                        return ret;
@@ -2244,10 +2305,12 @@ static int _nfs4_do_open(struct inode *dir,
                }
        }
 
-       if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
-               opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
-               if (!opendata->f_attr.mdsthreshold)
-                       goto err_free_label;
+       if (server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
+               if (!opendata->f_attr.mdsthreshold) {
+                       opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
+                       if (!opendata->f_attr.mdsthreshold)
+                               goto err_free_label;
+               }
                opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
        }
        if (dentry->d_inode != NULL)
@@ -2275,11 +2338,10 @@ static int _nfs4_do_open(struct inode *dir,
        if (opendata->file_created)
                *opened |= FILE_CREATED;
 
-       if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server))
+       if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) {
                *ctx_th = opendata->f_attr.mdsthreshold;
-       else
-               kfree(opendata->f_attr.mdsthreshold);
-       opendata->f_attr.mdsthreshold = NULL;
+               opendata->f_attr.mdsthreshold = NULL;
+       }
 
        nfs4_label_free(olabel);
 
@@ -2289,7 +2351,6 @@ static int _nfs4_do_open(struct inode *dir,
 err_free_label:
        nfs4_label_free(olabel);
 err_opendata_put:
-       kfree(opendata->f_attr.mdsthreshold);
        nfs4_opendata_put(opendata);
 err_put_state_owner:
        nfs4_put_state_owner(sp);
@@ -2479,26 +2540,6 @@ static void nfs4_free_closedata(void *data)
        kfree(calldata);
 }
 
-static void nfs4_close_clear_stateid_flags(struct nfs4_state *state,
-               fmode_t fmode)
-{
-       spin_lock(&state->owner->so_lock);
-       clear_bit(NFS_O_RDWR_STATE, &state->flags);
-       switch (fmode & (FMODE_READ|FMODE_WRITE)) {
-       case FMODE_WRITE:
-               clear_bit(NFS_O_RDONLY_STATE, &state->flags);
-               break;
-       case FMODE_READ:
-               clear_bit(NFS_O_WRONLY_STATE, &state->flags);
-               break;
-       case 0:
-               clear_bit(NFS_O_RDONLY_STATE, &state->flags);
-               clear_bit(NFS_O_WRONLY_STATE, &state->flags);
-               clear_bit(NFS_OPEN_STATE, &state->flags);
-       }
-       spin_unlock(&state->owner->so_lock);
-}
-
 static void nfs4_close_done(struct rpc_task *task, void *data)
 {
        struct nfs4_closedata *calldata = data;
@@ -2517,9 +2558,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
                        if (calldata->roc)
                                pnfs_roc_set_barrier(state->inode,
                                                     calldata->roc_barrier);
-                       nfs_set_open_stateid(state, &calldata->res.stateid, 0);
+                       nfs_clear_open_stateid(state, &calldata->res.stateid, 0);
                        renew_lease(server, calldata->timestamp);
-                       break;
+                       goto out_release;
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_STALE_STATEID:
                case -NFS4ERR_OLD_STATEID:
@@ -2533,7 +2574,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
                                goto out_release;
                        }
        }
-       nfs4_close_clear_stateid_flags(state, calldata->arg.fmode);
+       nfs_clear_open_stateid(state, NULL, calldata->arg.fmode);
 out_release:
        nfs_release_seqid(calldata->arg.seqid);
        nfs_refresh_inode(calldata->inode, calldata->res.fattr);
@@ -3507,49 +3548,6 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
        return 1;
 }
 
-static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
-               struct inode *new_dir, struct qstr *new_name)
-{
-       struct nfs_server *server = NFS_SERVER(old_dir);
-       struct nfs_renameargs arg = {
-               .old_dir = NFS_FH(old_dir),
-               .new_dir = NFS_FH(new_dir),
-               .old_name = old_name,
-               .new_name = new_name,
-       };
-       struct nfs_renameres res = {
-               .server = server,
-       };
-       struct rpc_message msg = {
-               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
-               .rpc_argp = &arg,
-               .rpc_resp = &res,
-       };
-       int status = -ENOMEM;
-
-       status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
-       if (!status) {
-               update_changeattr(old_dir, &res.old_cinfo);
-               update_changeattr(new_dir, &res.new_cinfo);
-       }
-       return status;
-}
-
-static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
-               struct inode *new_dir, struct qstr *new_name)
-{
-       struct nfs4_exception exception = { };
-       int err;
-       do {
-               err = _nfs4_proc_rename(old_dir, old_name,
-                                       new_dir, new_name);
-               trace_nfs4_rename(old_dir, old_name, new_dir, new_name, err);
-               err = nfs4_handle_exception(NFS_SERVER(old_dir), err,
-                               &exception);
-       } while (exception.retry);
-       return err;
-}
-
 static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 {
        struct nfs_server *server = NFS_SERVER(inode);
@@ -4884,6 +4882,20 @@ nfs4_init_uniform_client_string(const struct nfs_client *clp,
                                nodename);
 }
 
+/*
+ * nfs4_callback_up_net() starts only "tcp" and "tcp6" callback
+ * services.  Advertise one based on the address family of the
+ * clientaddr.
+ */
+static unsigned int
+nfs4_init_callback_netid(const struct nfs_client *clp, char *buf, size_t len)
+{
+       if (strchr(clp->cl_ipaddr, ':') != NULL)
+               return scnprintf(buf, len, "tcp6");
+       else
+               return scnprintf(buf, len, "tcp");
+}
+
 /**
  * nfs4_proc_setclientid - Negotiate client ID
  * @clp: state data structure
@@ -4925,12 +4937,10 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                                                setclientid.sc_name,
                                                sizeof(setclientid.sc_name));
        /* cb_client4 */
-       rcu_read_lock();
-       setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
-                               sizeof(setclientid.sc_netid), "%s",
-                               rpc_peeraddr2str(clp->cl_rpcclient,
-                                                       RPC_DISPLAY_NETID));
-       rcu_read_unlock();
+       setclientid.sc_netid_len =
+                               nfs4_init_callback_netid(clp,
+                                               setclientid.sc_netid,
+                                               sizeof(setclientid.sc_netid));
        setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr,
                                sizeof(setclientid.sc_uaddr), "%s.%u.%u",
                                clp->cl_ipaddr, port >> 8, port & 255);
@@ -8408,7 +8418,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
        .unlink_setup   = nfs4_proc_unlink_setup,
        .unlink_rpc_prepare = nfs4_proc_unlink_rpc_prepare,
        .unlink_done    = nfs4_proc_unlink_done,
-       .rename         = nfs4_proc_rename,
        .rename_setup   = nfs4_proc_rename_setup,
        .rename_rpc_prepare = nfs4_proc_rename_rpc_prepare,
        .rename_done    = nfs4_proc_rename_done,
index 0deb32105ccf3cb8b40fe95365f91f8b4b9c4da4..2349518eef2c28c9c74692335252b4a3877f4d22 100644 (file)
@@ -1316,7 +1316,7 @@ static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_st
        return 1;
 }
 
-static int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state)
+int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state)
 {
        set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags);
        clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
@@ -2075,8 +2075,10 @@ again:
        switch (status) {
        case 0:
                break;
-       case -NFS4ERR_DELAY:
        case -ETIMEDOUT:
+               if (clnt->cl_softrtry)
+                       break;
+       case -NFS4ERR_DELAY:
        case -EAGAIN:
                ssleep(1);
        case -NFS4ERR_STALE_CLIENTID:
index 72f3bf1754ef770c3c7b2f1346225e1440ec968b..73ce8d4fe2c8e2a34677efdeccccfd8e936195f4 100644 (file)
@@ -203,8 +203,7 @@ static int nfs4_stat_to_errno(int);
                                 2 + encode_verifier_maxsz + 5 + \
                                nfs4_label_maxsz)
 #define decode_readdir_maxsz   (op_decode_hdr_maxsz + \
-                                decode_verifier_maxsz + \
-                               nfs4_label_maxsz + nfs4_fattr_maxsz)
+                                decode_verifier_maxsz)
 #define encode_readlink_maxsz  (op_encode_hdr_maxsz)
 #define decode_readlink_maxsz  (op_decode_hdr_maxsz + 1)
 #define encode_write_maxsz     (op_encode_hdr_maxsz + \
index 4755858e37a0b93f64643811f683b0de7f0d6def..cb53d450ae321e4464e9dee7d9a4aa6ef2074b9e 100644 (file)
@@ -662,7 +662,18 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
  */
 static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
 {
-       return (s32)s1 - (s32)s2 > 0;
+       return (s32)(s1 - s2) > 0;
+}
+
+static void
+pnfs_verify_layout_stateid(struct pnfs_layout_hdr *lo,
+               const nfs4_stateid *new,
+               struct list_head *free_me_list)
+{
+       if (nfs4_stateid_match_other(&lo->plh_stateid, new))
+               return;
+       /* Layout is new! Kill existing layout segments */
+       pnfs_mark_matching_lsegs_invalid(lo, free_me_list, NULL);
 }
 
 /* update lo->plh_stateid with new if is more recent */
@@ -1315,6 +1326,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
        struct nfs4_layoutget_res *res = &lgp->res;
        struct pnfs_layout_segment *lseg;
        struct inode *ino = lo->plh_inode;
+       LIST_HEAD(free_me);
        int status = 0;
 
        /* Inject layout blob into I/O device driver */
@@ -1341,6 +1353,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
                goto out_forget_reply;
        }
 
+       /* Check that the new stateid matches the old stateid */
+       pnfs_verify_layout_stateid(lo, &res->stateid, &free_me);
        /* Done processing layoutget. Set the layout stateid */
        pnfs_set_layout_stateid(lo, &res->stateid, false);
 
@@ -1355,6 +1369,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
        }
 
        spin_unlock(&ino->i_lock);
+       pnfs_free_lseg_list(&free_me);
        return lseg;
 out:
        return ERR_PTR(status);
index fddbba2d9eff028fa5c15e12b799aedf35f40e4d..e55ce9e8b034e0c9372b209ac34213577cdd516a 100644 (file)
@@ -356,30 +356,6 @@ nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
        return 1;
 }
 
-static int
-nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
-               struct inode *new_dir, struct qstr *new_name)
-{
-       struct nfs_renameargs   arg = {
-               .old_dir        = NFS_FH(old_dir),
-               .old_name       = old_name,
-               .new_dir        = NFS_FH(new_dir),
-               .new_name       = new_name,
-       };
-       struct rpc_message msg = {
-               .rpc_proc       = &nfs_procedures[NFSPROC_RENAME],
-               .rpc_argp       = &arg,
-       };
-       int                     status;
-
-       dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
-       status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
-       nfs_mark_for_revalidate(old_dir);
-       nfs_mark_for_revalidate(new_dir);
-       dprintk("NFS reply rename: %d\n", status);
-       return status;
-}
-
 static int
 nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 {
@@ -745,7 +721,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
        .unlink_setup   = nfs_proc_unlink_setup,
        .unlink_rpc_prepare = nfs_proc_unlink_rpc_prepare,
        .unlink_done    = nfs_proc_unlink_done,
-       .rename         = nfs_proc_rename,
        .rename_setup   = nfs_proc_rename_setup,
        .rename_rpc_prepare = nfs_proc_rename_rpc_prepare,
        .rename_done    = nfs_proc_rename_done,
index 910ed906eb82f0465eb9317f8c8d4c7640bc7e17..2cb56943e2322a00e65c433d0f592ae6f32c4360 100644 (file)
@@ -2215,6 +2215,8 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
        struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
        u32 nfsvers = nfss->nfs_client->rpc_ops->version;
 
+       sync_filesystem(sb);
+
        /*
         * Userspace mount programs that send binary options generally send
         * them populated with default values. We have no way to know which
index 11d78944de795be25d3232b795f677fd0fe64efa..de54129336c6d095984fd34c548491a2916e902b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/namei.h>
+#include <linux/fsnotify.h>
 
 #include "internal.h"
 #include "nfs4_fs.h"
@@ -353,8 +354,8 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
                return;
        }
 
-       if (task->tk_status != 0)
-               nfs_cancel_async_unlink(old_dentry);
+       if (data->complete)
+               data->complete(task, data);
 }
 
 /**
@@ -399,9 +400,10 @@ static const struct rpc_call_ops nfs_rename_ops = {
  *
  * It's expected that valid references to the dentries and inodes are held
  */
-static struct rpc_task *
+struct rpc_task *
 nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
-                struct dentry *old_dentry, struct dentry *new_dentry)
+                struct dentry *old_dentry, struct dentry *new_dentry,
+                void (*complete)(struct rpc_task *, struct nfs_renamedata *))
 {
        struct nfs_renamedata *data;
        struct rpc_message msg = { };
@@ -438,6 +440,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
        data->new_dentry = dget(new_dentry);
        nfs_fattr_init(&data->old_fattr);
        nfs_fattr_init(&data->new_fattr);
+       data->complete = complete;
 
        /* set up nfs_renameargs */
        data->args.old_dir = NFS_FH(old_dir);
@@ -456,6 +459,27 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
        return rpc_run_task(&task_setup_data);
 }
 
+/*
+ * Perform tasks needed when a sillyrename is done such as cancelling the
+ * queued async unlink if it failed.
+ */
+static void
+nfs_complete_sillyrename(struct rpc_task *task, struct nfs_renamedata *data)
+{
+       struct dentry *dentry = data->old_dentry;
+
+       if (task->tk_status != 0) {
+               nfs_cancel_async_unlink(dentry);
+               return;
+       }
+
+       /*
+        * vfs_unlink and the like do not issue this when a file is
+        * sillyrenamed, so do it here.
+        */
+       fsnotify_nameremove(dentry, 0);
+}
+
 #define SILLYNAME_PREFIX ".nfs"
 #define SILLYNAME_PREFIX_LEN ((unsigned)sizeof(SILLYNAME_PREFIX) - 1)
 #define SILLYNAME_FILEID_LEN ((unsigned)sizeof(u64) << 1)
@@ -548,7 +572,8 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
        }
 
        /* run the rename task, undo unlink if it fails */
-       task = nfs_async_rename(dir, dir, dentry, sdentry);
+       task = nfs_async_rename(dir, dir, dentry, sdentry,
+                                       nfs_complete_sillyrename);
        if (IS_ERR(task)) {
                error = -EBUSY;
                nfs_cancel_async_unlink(dentry);
index 6d7be3f8035631cb207a5733c71dbfc2f800fa4c..915808b36df76142634478b02832c90676202275 100644 (file)
@@ -1694,7 +1694,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry)
                goto out_dput_new;
 
-       host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
+       host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL, 0);
        if (!host_err) {
                host_err = commit_metadata(tfhp);
                if (!host_err)
index 7ac2a122ca1dd1ce042005600d1396990d0ec3a4..8c532b2ca3aba1c1a4c6e162641e3eb7d009f91c 100644 (file)
@@ -1129,6 +1129,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        unsigned long old_mount_opt;
        int err;
 
+       sync_filesystem(sb);
        old_sb_flags = sb->s_flags;
        old_mount_opt = nilfs->ns_mount_opt;
 
index 82650d52d9168ee4f1e1b4282813afdaca5c7ec6..bd5610d482423a0ddf8efaf865f368d66d005e9f 100644 (file)
@@ -468,6 +468,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 
        ntfs_debug("Entering with remount options string: %s", opt);
 
+       sync_filesystem(sb);
+
 #ifndef NTFS_RW
        /* For read-only compiled driver, enforce read-only flag. */
        *flags |= MS_RDONLY;
index a4b07730b2e1d0abb257a126fce7f3911ae1d434..b7f57271d49c7030f81de8779a78d0d64478ede6 100644 (file)
@@ -41,7 +41,7 @@ static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr,
        return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION);
 }
 static struct kobj_attribute attr_version =
-       __ATTR(interface_revision, S_IFREG | S_IRUGO, version_show, NULL);
+       __ATTR(interface_revision, S_IRUGO, version_show, NULL);
 
 static struct attribute *o2cb_attrs[] = {
        &attr_version.attr,
index 5c8343fe74382e24a4a42c28ae30c1292ea4355a..83f1a665ae977634fa17ee8b15b9d4ae98abb5af 100644 (file)
@@ -496,7 +496,7 @@ static ssize_t ocfs2_max_locking_protocol_show(struct kobject *kobj,
 }
 
 static struct kobj_attribute ocfs2_attr_max_locking_protocol =
-       __ATTR(max_locking_protocol, S_IFREG | S_IRUGO,
+       __ATTR(max_locking_protocol, S_IRUGO,
               ocfs2_max_locking_protocol_show, NULL);
 
 static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj,
@@ -528,7 +528,7 @@ static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj,
 }
 
 static struct kobj_attribute ocfs2_attr_loaded_cluster_plugins =
-       __ATTR(loaded_cluster_plugins, S_IFREG | S_IRUGO,
+       __ATTR(loaded_cluster_plugins, S_IRUGO,
               ocfs2_loaded_cluster_plugins_show, NULL);
 
 static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj,
@@ -550,7 +550,7 @@ static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj,
 }
 
 static struct kobj_attribute ocfs2_attr_active_cluster_plugin =
-       __ATTR(active_cluster_plugin, S_IFREG | S_IRUGO,
+       __ATTR(active_cluster_plugin, S_IRUGO,
               ocfs2_active_cluster_plugin_show, NULL);
 
 static ssize_t ocfs2_cluster_stack_show(struct kobject *kobj,
@@ -599,7 +599,7 @@ static ssize_t ocfs2_cluster_stack_store(struct kobject *kobj,
 
 
 static struct kobj_attribute ocfs2_attr_cluster_stack =
-       __ATTR(cluster_stack, S_IFREG | S_IRUGO | S_IWUSR,
+       __ATTR(cluster_stack, S_IRUGO | S_IWUSR,
               ocfs2_cluster_stack_show,
               ocfs2_cluster_stack_store);
 
index 1aecd626e645a7cf6be82f8dbf062dd1232be072..a7cdd56f4c79baa4139807c3082d8e81507fbcdc 100644 (file)
@@ -634,6 +634,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
        struct ocfs2_super *osb = OCFS2_SB(sb);
        u32 tmp;
 
+       sync_filesystem(sb);
+
        if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
            !ocfs2_check_set_options(sb, &parsed_options)) {
                ret = -EINVAL;
index b9ed8b25c108c69d68889b5b6eadac9878eb7bd9..631aea815def32946433b8aebed9a312d0fc872c 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -231,7 +231,13 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
                return -EINVAL;
 
        /* Return error if mode is not supported */
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+                    FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE))
+               return -EOPNOTSUPP;
+
+       /* Punch hole and zero range are mutually exclusive */
+       if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) ==
+           (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
                return -EOPNOTSUPP;
 
        /* Punch hole must have keep size set */
@@ -239,11 +245,20 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
            !(mode & FALLOC_FL_KEEP_SIZE))
                return -EOPNOTSUPP;
 
+       /* Collapse range should only be used exclusively. */
+       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
+           (mode & ~FALLOC_FL_COLLAPSE_RANGE))
+               return -EINVAL;
+
        if (!(file->f_mode & FMODE_WRITE))
                return -EBADF;
 
-       /* It's not possible punch hole on append only file */
-       if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode))
+       /*
+        * It's not possible to punch hole or perform collapse range
+        * on append only file
+        */
+       if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)
+           && IS_APPEND(inode))
                return -EPERM;
 
        if (IS_IMMUTABLE(inode))
@@ -271,6 +286,14 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
                return -EFBIG;
 
+       /*
+        * There is no need to overlap collapse range with EOF, in which case
+        * it is effectively a truncate operation
+        */
+       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
+           (offset + len >= i_size_read(inode)))
+               return -EINVAL;
+
        if (!file->f_op->fallocate)
                return -EOPNOTSUPP;
 
index 8c0ceb8dd1f709a6b3b6427eabc28718f23f9a50..15e4500cda3ee28f56957d03adf120ae8d9f73fb 100644 (file)
@@ -368,6 +368,7 @@ static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
 
 static int openprom_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NOATIME;
        return 0;
 }
index 11c54fd51e16d6248926287c407b06da39495231..9e363e41dacc8c2ebc007661a598c01e84da45c9 100644 (file)
@@ -723,7 +723,7 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
                   void *buffer, size_t size)
 {
        posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
-       posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
+       posix_acl_xattr_entry *ext_entry;
        int real_size, n;
 
        real_size = posix_acl_xattr_size(acl->a_count);
@@ -731,7 +731,8 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
                return real_size;
        if (real_size > size)
                return -ERANGE;
-       
+
+       ext_entry = ext_acl->a_entries;
        ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
 
        for (n=0; n < acl->a_count; n++, ext_entry++) {
index 7bbeb5257af166bb5a39f5cb02f5be481c779240..5dbadecb234da01be9cc7eb5705e71363da7dfea 100644 (file)
@@ -92,6 +92,8 @@ static int proc_parse_options(char *options, struct pid_namespace *pid)
 int proc_remount(struct super_block *sb, int *flags, char *data)
 {
        struct pid_namespace *pid = sb->s_fs_info;
+
+       sync_filesystem(sb);
        return !proc_parse_options(data, pid);
 }
 
index 12823845d32490d220d795ee46e1a328491a1585..192297b0090da25026bb5ee9b8033b48ccca927e 100644 (file)
@@ -249,6 +249,7 @@ static void parse_options(char *options)
 
 static int pstore_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        parse_options(data);
 
        return 0;
index 78c3c2097787a1be2ea2bd1757a6c6e5554df72c..46d269e3870652104f2f4b2d52d6643a9250b15b 100644 (file)
@@ -497,6 +497,7 @@ void pstore_get_records(int quiet)
                                                        big_oops_buf_sz);
 
                        if (unzipped_len > 0) {
+                               kfree(buf);
                                buf = big_oops_buf;
                                size = unzipped_len;
                                compressed = false;
index fa8cef2cca3af73044cec32e409302895ea4891d..3b5744306ed82e812b71f55dc31e5e495d05a028 100644 (file)
@@ -86,6 +86,7 @@ struct ramoops_context {
        struct persistent_ram_ecc_info ecc_info;
        unsigned int max_dump_cnt;
        unsigned int dump_write_cnt;
+       /* _read_cnt need clear on ramoops_pstore_open */
        unsigned int dump_read_cnt;
        unsigned int console_read_cnt;
        unsigned int ftrace_read_cnt;
@@ -101,6 +102,7 @@ static int ramoops_pstore_open(struct pstore_info *psi)
 
        cxt->dump_read_cnt = 0;
        cxt->console_read_cnt = 0;
+       cxt->ftrace_read_cnt = 0;
        return 0;
 }
 
@@ -117,13 +119,15 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
                return NULL;
 
        prz = przs[i];
+       if (!prz)
+               return NULL;
 
-       if (update) {
-               /* Update old/shadowed buffer. */
+       /* Update old/shadowed buffer. */
+       if (update)
                persistent_ram_save_old(prz);
-               if (!persistent_ram_old_size(prz))
-                       return NULL;
-       }
+
+       if (!persistent_ram_old_size(prz))
+               return NULL;
 
        *typep = type;
        *id = i;
@@ -316,6 +320,7 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
 {
        int i;
 
+       cxt->max_dump_cnt = 0;
        if (!cxt->przs)
                return;
 
@@ -346,7 +351,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
                             GFP_KERNEL);
        if (!cxt->przs) {
                dev_err(dev, "failed to initialize a prz array for dumps\n");
-               return -ENOMEM;
+               goto fail_prz;
        }
 
        for (i = 0; i < cxt->max_dump_cnt; i++) {
@@ -428,7 +433,6 @@ static int ramoops_probe(struct platform_device *pdev)
        if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
                pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
 
-       cxt->dump_read_cnt = 0;
        cxt->size = pdata->mem_size;
        cxt->phys_addr = pdata->mem_address;
        cxt->record_size = pdata->record_size;
@@ -505,7 +509,6 @@ fail_buf:
        kfree(cxt->pstore.buf);
 fail_clear:
        cxt->pstore.bufsize = 0;
-       cxt->max_dump_cnt = 0;
 fail_cnt:
        kfree(cxt->fprz);
 fail_init_fprz:
index de272d4267634f220e61a436c9fc5a7d9f5d3083..ff7e3d4df5a15a4673b630812985d6164c5dfd21 100644 (file)
@@ -54,7 +54,7 @@ static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
        do {
                old = atomic_read(&prz->buffer->start);
                new = old + a;
-               while (unlikely(new > prz->buffer_size))
+               while (unlikely(new >= prz->buffer_size))
                        new -= prz->buffer_size;
        } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);
 
@@ -91,7 +91,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
 
        old = atomic_read(&prz->buffer->start);
        new = old + a;
-       while (unlikely(new > prz->buffer_size))
+       while (unlikely(new >= prz->buffer_size))
                new -= prz->buffer_size;
        atomic_set(&prz->buffer->start, new);
 
index 89558810381c497389c184856d30efd0a2ce9717..c4bcb778886e5c79c4dcc9381cf13f0a76358838 100644 (file)
@@ -44,6 +44,7 @@ static int qnx4_remount(struct super_block *sb, int *flags, char *data)
 {
        struct qnx4_sb_info *qs;
 
+       sync_filesystem(sb);
        qs = qnx4_sb(sb);
        qs->Version = QNX4_VERSION;
        *flags |= MS_RDONLY;
index 8d941edfefa156bedb93a1a074ccda0e9a042fad..65cdaab3ed49d554e4d618202e4d41d11718c714 100644 (file)
@@ -55,6 +55,7 @@ static int qnx6_show_options(struct seq_file *seq, struct dentry *root)
 
 static int qnx6_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index ed54a04c33bd27dd33c5ea35f70a76cd22293be4..9fb20426005e4ff3a0af37f675bdc4d5a29ffb84 100644 (file)
@@ -1318,6 +1318,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
        int i;
 #endif
 
+       sync_filesystem(s);
        reiserfs_write_lock(s);
 
 #ifdef CONFIG_QUOTA
index d8418782862b60fe2b96b4bd131281417c2adc24..ef90e8bca95ac77e6808a300eb053d36911db523 100644 (file)
@@ -432,6 +432,7 @@ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
  */
 static int romfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 202df6312d4e8517a63bb9ff10b385738e54ab6e..031c8d67fd5178bb5afca2b04c71637254b46873 100644 (file)
@@ -371,6 +371,7 @@ static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int squashfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 80d5cf2ca76518a450a31cb7cad340794a525ed8..e9dc3c3fe159cc2e59bfb27f0beb8bd30e92188b 100644 (file)
@@ -719,8 +719,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
                }
        }
 
-       sync_filesystem(sb);
-
        if (sb->s_op->remount_fs) {
                retval = sb->s_op->remount_fs(sb, &flags, data);
                if (retval) {
index 5625ca920f5eae1236a85b01557a577b96c3a146..88956309cc86ab6d6d614315651ced6778647347 100644 (file)
@@ -60,6 +60,7 @@ static int sysv_remount(struct super_block *sb, int *flags, char *data)
 {
        struct sysv_sb_info *sbi = SYSV_SB(sb);
 
+       sync_filesystem(sb);
        if (sbi->s_forced_ro)
                *flags |= MS_RDONLY;
        return 0;
index 48f943f7f5d5592737fdad71744834ce7b802af2..a1266089eca1fc0054065dfc723e697daf5691e6 100644 (file)
@@ -1827,6 +1827,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
        int err;
        struct ubifs_info *c = sb->s_fs_info;
 
+       sync_filesystem(sb);
        dbg_gen("old flags %#lx, new flags %#x", sb->s_flags, *flags);
 
        err = ubifs_parse_options(c, data, 1);
index 3306b9f69bedbb5ba2cb4e11b180b2b75e947dd5..64f2b7334d08bf41f6ec9ed0910393eb680d9fbc 100644 (file)
@@ -646,6 +646,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
        int error = 0;
        struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb);
 
+       sync_filesystem(sb);
        if (lvidiu) {
                int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
                if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY))
index 329f2f53b7ed655b2ef525331f7c75a714d58de9..b8c6791f046fbe4195d97697bbe8a6ba29be03a0 100644 (file)
@@ -1280,6 +1280,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
        unsigned new_mount_opt, ufstype;
        unsigned flags;
 
+       sync_filesystem(sb);
        lock_ufs(sb);
        mutex_lock(&UFS_SB(sb)->s_lock);
        uspi = UFS_SB(sb)->s_uspi;
index 66a36befc5c0723d217bdd5aa1a61b1b610e42a4..844e288b9576d1202d88e6628ca5731149fb9b92 100644 (file)
@@ -65,12 +65,31 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
 void *
 kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
 {
+       unsigned noio_flag = 0;
        void    *ptr;
+       gfp_t   lflags;
 
        ptr = kmem_zalloc(size, flags | KM_MAYFAIL);
        if (ptr)
                return ptr;
-       return vzalloc(size);
+
+       /*
+        * __vmalloc() will allocate data pages and auxillary structures (e.g.
+        * pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context
+        * here. Hence we need to tell memory reclaim that we are in such a
+        * context via PF_MEMALLOC_NOIO to prevent memory reclaim re-entering
+        * the filesystem here and potentially deadlocking.
+        */
+       if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
+               noio_flag = memalloc_noio_save();
+
+       lflags = kmem_flags_convert(flags);
+       ptr = __vmalloc(size, lflags | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+
+       if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
+               memalloc_noio_restore(noio_flag);
+
+       return ptr;
 }
 
 void
index 0ecec1896f25439f198c53c93bc058ff3bff9c89..6888ad886ff6205cc0baf0aa36352fa92f9d93ea 100644 (file)
@@ -281,7 +281,7 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        if (!acl)
                goto set_acl;
 
-       error = -EINVAL;
+       error = -E2BIG;
        if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
                return error;
 
index 3fc109819c34eb7a42973d7640525fefe66cc08e..0fdd4109c62439b7471b46135a068148b1006d87 100644 (file)
@@ -89,6 +89,8 @@ typedef struct xfs_agf {
        /* structure must be padded to 64 bit alignment */
 } xfs_agf_t;
 
+#define XFS_AGF_CRC_OFF                offsetof(struct xfs_agf, agf_crc)
+
 #define        XFS_AGF_MAGICNUM        0x00000001
 #define        XFS_AGF_VERSIONNUM      0x00000002
 #define        XFS_AGF_SEQNO           0x00000004
@@ -167,6 +169,8 @@ typedef struct xfs_agi {
        /* structure must be padded to 64 bit alignment */
 } xfs_agi_t;
 
+#define XFS_AGI_CRC_OFF                offsetof(struct xfs_agi, agi_crc)
+
 #define        XFS_AGI_MAGICNUM        0x00000001
 #define        XFS_AGI_VERSIONNUM      0x00000002
 #define        XFS_AGI_SEQNO           0x00000004
@@ -222,6 +226,8 @@ typedef struct xfs_agfl {
        __be32          agfl_bno[];     /* actually XFS_AGFL_SIZE(mp) */
 } xfs_agfl_t;
 
+#define XFS_AGFL_CRC_OFF       offsetof(struct xfs_agfl, agfl_crc)
+
 /*
  * tags for inode radix tree
  */
index 9eab2dfdcbb54cc1337f4d6f248c808fcb2cc426..c1cf6a336a72fb178602ad10908825caeecc20b7 100644 (file)
@@ -474,7 +474,6 @@ xfs_agfl_read_verify(
        struct xfs_buf  *bp)
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
-       int             agfl_ok = 1;
 
        /*
         * There is no verification of non-crc AGFLs because mkfs does not
@@ -485,15 +484,13 @@ xfs_agfl_read_verify(
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return;
 
-       agfl_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                  offsetof(struct xfs_agfl, agfl_crc));
-
-       agfl_ok = agfl_ok && xfs_agfl_verify(bp);
-
-       if (!agfl_ok) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_agfl_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -508,16 +505,15 @@ xfs_agfl_write_verify(
                return;
 
        if (!xfs_agfl_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
        if (bip)
                XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        offsetof(struct xfs_agfl, agfl_crc));
+       xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_agfl_buf_ops = {
@@ -2238,19 +2234,17 @@ xfs_agf_read_verify(
        struct xfs_buf  *bp)
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
-       int             agf_ok = 1;
-
-       if (xfs_sb_version_hascrc(&mp->m_sb))
-               agf_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         offsetof(struct xfs_agf, agf_crc));
 
-       agf_ok = agf_ok && xfs_agf_verify(mp, bp);
-
-       if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
-                       XFS_RANDOM_ALLOC_READ_AGF))) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+           !xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (XFS_TEST_ERROR(!xfs_agf_verify(mp, bp), mp,
+                               XFS_ERRTAG_ALLOC_READ_AGF,
+                               XFS_RANDOM_ALLOC_READ_AGF))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -2261,8 +2255,8 @@ xfs_agf_write_verify(
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
        if (!xfs_agf_verify(mp, bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -2272,8 +2266,7 @@ xfs_agf_write_verify(
        if (bip)
                XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        offsetof(struct xfs_agf, agf_crc));
+       xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_agf_buf_ops = {
index 13085429e5234783c93e40c3a31492ec7d560428..cc1eadcbb0497ea6163b045dacb740481db27fe6 100644 (file)
@@ -355,12 +355,14 @@ static void
 xfs_allocbt_read_verify(
        struct xfs_buf  *bp)
 {
-       if (!(xfs_btree_sblock_verify_crc(bp) &&
-             xfs_allocbt_verify(bp))) {
-               trace_xfs_btree_corrupt(bp, _RET_IP_);
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+       if (!xfs_btree_sblock_verify_crc(bp))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_allocbt_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+
+       if (bp->b_error) {
+               trace_xfs_btree_corrupt(bp, _RET_IP_);
+               xfs_verifier_error(bp);
        }
 }
 
@@ -370,9 +372,9 @@ xfs_allocbt_write_verify(
 {
        if (!xfs_allocbt_verify(bp)) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
+               return;
        }
        xfs_btree_sblock_calc_crc(bp);
 
index db2cfb067d0b1ea88f8b64875ceb174d3ae582d2..75df77d09f757d4786c889679c35c5cac2ca00b3 100644 (file)
@@ -632,38 +632,46 @@ xfs_map_at_offset(
 }
 
 /*
- * Test if a given page is suitable for writing as part of an unwritten
- * or delayed allocate extent.
+ * Test if a given page contains at least one buffer of a given @type.
+ * If @check_all_buffers is true, then we walk all the buffers in the page to
+ * try to find one of the type passed in. If it is not set, then the caller only
+ * needs to check the first buffer on the page for a match.
  */
-STATIC int
+STATIC bool
 xfs_check_page_type(
        struct page             *page,
-       unsigned int            type)
+       unsigned int            type,
+       bool                    check_all_buffers)
 {
-       if (PageWriteback(page))
-               return 0;
+       struct buffer_head      *bh;
+       struct buffer_head      *head;
 
-       if (page->mapping && page_has_buffers(page)) {
-               struct buffer_head      *bh, *head;
-               int                     acceptable = 0;
+       if (PageWriteback(page))
+               return false;
+       if (!page->mapping)
+               return false;
+       if (!page_has_buffers(page))
+               return false;
 
-               bh = head = page_buffers(page);
-               do {
-                       if (buffer_unwritten(bh))
-                               acceptable += (type == XFS_IO_UNWRITTEN);
-                       else if (buffer_delay(bh))
-                               acceptable += (type == XFS_IO_DELALLOC);
-                       else if (buffer_dirty(bh) && buffer_mapped(bh))
-                               acceptable += (type == XFS_IO_OVERWRITE);
-                       else
-                               break;
-               } while ((bh = bh->b_this_page) != head);
+       bh = head = page_buffers(page);
+       do {
+               if (buffer_unwritten(bh)) {
+                       if (type == XFS_IO_UNWRITTEN)
+                               return true;
+               } else if (buffer_delay(bh)) {
+                       if (type == XFS_IO_DELALLOC)
+                               return true;
+               } else if (buffer_dirty(bh) && buffer_mapped(bh)) {
+                       if (type == XFS_IO_OVERWRITE)
+                               return true;
+               }
 
-               if (acceptable)
-                       return 1;
-       }
+               /* If we are only checking the first buffer, we are done now. */
+               if (!check_all_buffers)
+                       break;
+       } while ((bh = bh->b_this_page) != head);
 
-       return 0;
+       return false;
 }
 
 /*
@@ -697,7 +705,7 @@ xfs_convert_page(
                goto fail_unlock_page;
        if (page->mapping != inode->i_mapping)
                goto fail_unlock_page;
-       if (!xfs_check_page_type(page, (*ioendp)->io_type))
+       if (!xfs_check_page_type(page, (*ioendp)->io_type, false))
                goto fail_unlock_page;
 
        /*
@@ -742,6 +750,15 @@ xfs_convert_page(
        p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;
        page_dirty = p_offset / len;
 
+       /*
+        * The moment we find a buffer that doesn't match our current type
+        * specification or can't be written, abort the loop and start
+        * writeback. As per the above xfs_imap_valid() check, only
+        * xfs_vm_writepage() can handle partial page writeback fully - we are
+        * limited here to the buffers that are contiguous with the current
+        * ioend, and hence a buffer we can't write breaks that contiguity and
+        * we have to defer the rest of the IO to xfs_vm_writepage().
+        */
        bh = head = page_buffers(page);
        do {
                if (offset >= end_offset)
@@ -750,7 +767,7 @@ xfs_convert_page(
                        uptodate = 0;
                if (!(PageUptodate(page) || buffer_uptodate(bh))) {
                        done = 1;
-                       continue;
+                       break;
                }
 
                if (buffer_unwritten(bh) || buffer_delay(bh) ||
@@ -762,10 +779,11 @@ xfs_convert_page(
                        else
                                type = XFS_IO_OVERWRITE;
 
-                       if (!xfs_imap_valid(inode, imap, offset)) {
-                               done = 1;
-                               continue;
-                       }
+                       /*
+                        * imap should always be valid because of the above
+                        * partial page end_offset check on the imap.
+                        */
+                       ASSERT(xfs_imap_valid(inode, imap, offset));
 
                        lock_buffer(bh);
                        if (type != XFS_IO_OVERWRITE)
@@ -777,6 +795,7 @@ xfs_convert_page(
                        count++;
                } else {
                        done = 1;
+                       break;
                }
        } while (offset += len, (bh = bh->b_this_page) != head);
 
@@ -868,7 +887,7 @@ xfs_aops_discard_page(
        struct buffer_head      *bh, *head;
        loff_t                  offset = page_offset(page);
 
-       if (!xfs_check_page_type(page, XFS_IO_DELALLOC))
+       if (!xfs_check_page_type(page, XFS_IO_DELALLOC, true))
                goto out_invalidate;
 
        if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -1441,7 +1460,8 @@ xfs_vm_direct_IO(
                ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov,
                                            offset, nr_segs,
                                            xfs_get_blocks_direct,
-                                           xfs_end_io_direct_write, NULL, 0);
+                                           xfs_end_io_direct_write, NULL,
+                                           DIO_ASYNC_EXTEND);
                if (ret != -EIOCBQUEUED && iocb->private)
                        goto out_destroy_ioend;
        } else {
index 7b126f46a2f99689cf0bee0efba6c026c0e23186..fe9587fab17a6822d9bec1b5862a6a133adf9dc7 100644 (file)
@@ -213,8 +213,8 @@ xfs_attr3_leaf_write_verify(
        struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
 
        if (!xfs_attr3_leaf_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -224,7 +224,7 @@ xfs_attr3_leaf_write_verify(
        if (bip)
                hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_ATTR3_LEAF_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF);
 }
 
 /*
@@ -239,13 +239,14 @@ xfs_attr3_leaf_read_verify(
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
-       if ((xfs_sb_version_hascrc(&mp->m_sb) &&
-            !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         XFS_ATTR3_LEAF_CRC_OFF)) ||
-           !xfs_attr3_leaf_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+            !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_attr3_leaf_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
index 5549d69ddb45a2038ece8e24085e0f9ef6ce9984..6e37823e2932aeb45d112b55010ab627adb5bde2 100644 (file)
@@ -125,7 +125,6 @@ xfs_attr3_rmt_read_verify(
        struct xfs_mount *mp = bp->b_target->bt_mount;
        char            *ptr;
        int             len;
-       bool            corrupt = false;
        xfs_daddr_t     bno;
 
        /* no verification of non-crc buffers */
@@ -140,11 +139,11 @@ xfs_attr3_rmt_read_verify(
        while (len > 0) {
                if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp),
                                      XFS_ATTR3_RMT_CRC_OFF)) {
-                       corrupt = true;
+                       xfs_buf_ioerror(bp, EFSBADCRC);
                        break;
                }
                if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
-                       corrupt = true;
+                       xfs_buf_ioerror(bp, EFSCORRUPTED);
                        break;
                }
                len -= XFS_LBSIZE(mp);
@@ -152,10 +151,9 @@ xfs_attr3_rmt_read_verify(
                bno += mp->m_bsize;
        }
 
-       if (corrupt) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
-               xfs_buf_ioerror(bp, EFSCORRUPTED);
-       } else
+       if (bp->b_error)
+               xfs_verifier_error(bp);
+       else
                ASSERT(len == 0);
 }
 
@@ -180,9 +178,8 @@ xfs_attr3_rmt_write_verify(
 
        while (len > 0) {
                if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
-                       XFS_CORRUPTION_ERROR(__func__,
-                                           XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                        xfs_buf_ioerror(bp, EFSCORRUPTED);
+                       xfs_verifier_error(bp);
                        return;
                }
                if (bip) {
index 152543c4ca7031e718bc921b82e9e0a72955de11..5b6092ef51efa9eb6e02c980980c6aa99e486170 100644 (file)
@@ -5378,3 +5378,196 @@ error0:
        }
        return error;
 }
+
+/*
+ * Shift extent records to the left to cover a hole.
+ *
+ * The maximum number of extents to be shifted in a single operation
+ * is @num_exts, and @current_ext keeps track of the current extent
+ * index we have shifted. @offset_shift_fsb is the length by which each
+ * extent is shifted. If there is no hole to shift the extents
+ * into, this will be considered invalid operation and we abort immediately.
+ */
+int
+xfs_bmap_shift_extents(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       int                     *done,
+       xfs_fileoff_t           start_fsb,
+       xfs_fileoff_t           offset_shift_fsb,
+       xfs_extnum_t            *current_ext,
+       xfs_fsblock_t           *firstblock,
+       struct xfs_bmap_free    *flist,
+       int                     num_exts)
+{
+       struct xfs_btree_cur            *cur;
+       struct xfs_bmbt_rec_host        *gotp;
+       struct xfs_bmbt_irec            got;
+       struct xfs_bmbt_irec            left;
+       struct xfs_mount                *mp = ip->i_mount;
+       struct xfs_ifork                *ifp;
+       xfs_extnum_t                    nexts = 0;
+       xfs_fileoff_t                   startoff;
+       int                             error = 0;
+       int                             i;
+       int                             whichfork = XFS_DATA_FORK;
+       int                             logflags;
+       xfs_filblks_t                   blockcount = 0;
+
+       if (unlikely(XFS_TEST_ERROR(
+           (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
+            XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
+            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+               XFS_ERROR_REPORT("xfs_bmap_shift_extents",
+                                XFS_ERRLEVEL_LOW, mp);
+               return XFS_ERROR(EFSCORRUPTED);
+       }
+
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return XFS_ERROR(EIO);
+
+       ASSERT(current_ext != NULL);
+
+       ifp = XFS_IFORK_PTR(ip, whichfork);
+
+       if (!(ifp->if_flags & XFS_IFEXTENTS)) {
+               /* Read in all the extents */
+               error = xfs_iread_extents(tp, ip, whichfork);
+               if (error)
+                       return error;
+       }
+
+       /*
+        * If *current_ext is 0, we would need to lookup the extent
+        * from where we would start shifting and store it in gotp.
+        */
+       if (!*current_ext) {
+               gotp = xfs_iext_bno_to_ext(ifp, start_fsb, current_ext);
+               /*
+                * gotp can be null in 2 cases: 1) if there are no extents
+                * or 2) start_fsb lies in a hole beyond which there are
+                * no extents. Either way, we are done.
+                */
+               if (!gotp) {
+                       *done = 1;
+                       return 0;
+               }
+       }
+
+       /* We are going to change core inode */
+       logflags = XFS_ILOG_CORE;
+
+       if (ifp->if_flags & XFS_IFBROOT) {
+               cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
+               cur->bc_private.b.firstblock = *firstblock;
+               cur->bc_private.b.flist = flist;
+               cur->bc_private.b.flags = 0;
+       } else {
+               cur = NULL;
+               logflags |= XFS_ILOG_DEXT;
+       }
+
+       while (nexts++ < num_exts &&
+              *current_ext <  XFS_IFORK_NEXTENTS(ip, whichfork)) {
+
+               gotp = xfs_iext_get_ext(ifp, *current_ext);
+               xfs_bmbt_get_all(gotp, &got);
+               startoff = got.br_startoff - offset_shift_fsb;
+
+               /*
+                * Before shifting extent into hole, make sure that the hole
+                * is large enough to accomodate the shift.
+                */
+               if (*current_ext) {
+                       xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
+                                               *current_ext - 1), &left);
+
+                       if (startoff < left.br_startoff + left.br_blockcount)
+                               error = XFS_ERROR(EINVAL);
+               } else if (offset_shift_fsb > got.br_startoff) {
+                       /*
+                        * When first extent is shifted, offset_shift_fsb
+                        * should be less than the stating offset of
+                        * the first extent.
+                        */
+                       error = XFS_ERROR(EINVAL);
+               }
+
+               if (error)
+                       goto del_cursor;
+
+               if (cur) {
+                       error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
+                                                  got.br_startblock,
+                                                  got.br_blockcount,
+                                                  &i);
+                       if (error)
+                               goto del_cursor;
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
+               }
+
+               /* Check if we can merge 2 adjacent extents */
+               if (*current_ext &&
+                   left.br_startoff + left.br_blockcount == startoff &&
+                   left.br_startblock + left.br_blockcount ==
+                               got.br_startblock &&
+                   left.br_state == got.br_state &&
+                   left.br_blockcount + got.br_blockcount <= MAXEXTLEN) {
+                       blockcount = left.br_blockcount +
+                               got.br_blockcount;
+                       xfs_iext_remove(ip, *current_ext, 1, 0);
+                       if (cur) {
+                               error = xfs_btree_delete(cur, &i);
+                               if (error)
+                                       goto del_cursor;
+                               XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
+                       }
+                       XFS_IFORK_NEXT_SET(ip, whichfork,
+                               XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
+                       gotp = xfs_iext_get_ext(ifp, --*current_ext);
+                       xfs_bmbt_get_all(gotp, &got);
+
+                       /* Make cursor point to the extent we will update */
+                       if (cur) {
+                               error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
+                                                          got.br_startblock,
+                                                          got.br_blockcount,
+                                                          &i);
+                               if (error)
+                                       goto del_cursor;
+                               XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
+                       }
+
+                       xfs_bmbt_set_blockcount(gotp, blockcount);
+                       got.br_blockcount = blockcount;
+               } else {
+                       /* We have to update the startoff */
+                       xfs_bmbt_set_startoff(gotp, startoff);
+                       got.br_startoff = startoff;
+               }
+
+               if (cur) {
+                       error = xfs_bmbt_update(cur, got.br_startoff,
+                                               got.br_startblock,
+                                               got.br_blockcount,
+                                               got.br_state);
+                       if (error)
+                               goto del_cursor;
+               }
+
+               (*current_ext)++;
+       }
+
+       /* Check if we are done */
+       if (*current_ext ==  XFS_IFORK_NEXTENTS(ip, whichfork))
+               *done = 1;
+
+del_cursor:
+       if (cur)
+               xfs_btree_del_cursor(cur,
+                       error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
+
+       xfs_trans_log_inode(tp, ip, logflags);
+
+       return error;
+}
index 33b41f35122574e0b1cf7ad7a2a9ae23ecfadddb..f84bd7af43bec38bd4493c473f95d32e7f590337 100644 (file)
@@ -127,6 +127,16 @@ static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
        { BMAP_RIGHT_FILLING,   "RF" }, \
        { BMAP_ATTRFORK,        "ATTR" }
 
+
+/*
+ * This macro is used to determine how many extents will be shifted
+ * in one write transaction. We could require two splits,
+ * an extent move on the first and an extent merge on the second,
+ * So it is proper that one extent is shifted inside write transaction
+ * at a time.
+ */
+#define XFS_BMAP_MAX_SHIFT_EXTENTS     1
+
 #ifdef DEBUG
 void   xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt,
                int whichfork, unsigned long caller_ip);
@@ -169,5 +179,10 @@ int        xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
 int    xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx,
                xfs_extnum_t num);
 uint   xfs_default_attroffset(struct xfs_inode *ip);
+int    xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip,
+               int *done, xfs_fileoff_t start_fsb,
+               xfs_fileoff_t offset_shift_fsb, xfs_extnum_t *current_ext,
+               xfs_fsblock_t *firstblock, struct xfs_bmap_free *flist,
+               int num_exts);
 
 #endif /* __XFS_BMAP_H__ */
index 706bc3f777cb390cacd78988b8b8ebe1a63799a6..818d546664e7575d4affe27b3e90c178ccd85315 100644 (file)
@@ -780,12 +780,14 @@ static void
 xfs_bmbt_read_verify(
        struct xfs_buf  *bp)
 {
-       if (!(xfs_btree_lblock_verify_crc(bp) &&
-             xfs_bmbt_verify(bp))) {
-               trace_xfs_btree_corrupt(bp, _RET_IP_);
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+       if (!xfs_btree_lblock_verify_crc(bp))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_bmbt_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+
+       if (bp->b_error) {
+               trace_xfs_btree_corrupt(bp, _RET_IP_);
+               xfs_verifier_error(bp);
        }
 }
 
@@ -794,11 +796,9 @@ xfs_bmbt_write_verify(
        struct xfs_buf  *bp)
 {
        if (!xfs_bmbt_verify(bp)) {
-               xfs_warn(bp->b_target->bt_mount, "bmbt daddr 0x%llx failed", bp->b_bn);
                trace_xfs_btree_corrupt(bp, _RET_IP_);
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
        xfs_btree_lblock_calc_crc(bp);
index f264616080cac0c6bdfdc084c188b15505aa92e7..01f6a646caa121895265cfe33a7d97860f786a18 100644 (file)
@@ -1349,7 +1349,6 @@ xfs_free_file_space(
                 * the freeing of the space succeeds at ENOSPC.
                 */
                tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-               tp->t_flags |= XFS_TRANS_RESERVE;
                error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0);
 
                /*
@@ -1467,6 +1466,102 @@ out:
 
 }
 
+/*
+ * xfs_collapse_file_space()
+ *     This routine frees disk space and shift extent for the given file.
+ *     The first thing we do is to free data blocks in the specified range
+ *     by calling xfs_free_file_space(). It would also sync dirty data
+ *     and invalidate page cache over the region on which collapse range
+ *     is working. And Shift extent records to the left to cover a hole.
+ * RETURNS:
+ *     0 on success
+ *     errno on error
+ *
+ */
+int
+xfs_collapse_file_space(
+       struct xfs_inode        *ip,
+       xfs_off_t               offset,
+       xfs_off_t               len)
+{
+       int                     done = 0;
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_trans        *tp;
+       int                     error;
+       xfs_extnum_t            current_ext = 0;
+       struct xfs_bmap_free    free_list;
+       xfs_fsblock_t           first_block;
+       int                     committed;
+       xfs_fileoff_t           start_fsb;
+       xfs_fileoff_t           shift_fsb;
+
+       ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
+
+       trace_xfs_collapse_file_space(ip);
+
+       start_fsb = XFS_B_TO_FSB(mp, offset + len);
+       shift_fsb = XFS_B_TO_FSB(mp, len);
+
+       error = xfs_free_file_space(ip, offset, len);
+       if (error)
+               return error;
+
+       while (!error && !done) {
+               tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
+               tp->t_flags |= XFS_TRANS_RESERVE;
+               /*
+                * We would need to reserve permanent block for transaction.
+                * This will come into picture when after shifting extent into
+                * hole we found that adjacent extents can be merged which
+                * may lead to freeing of a block during record update.
+                */
+               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
+                               XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
+               if (error) {
+                       ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
+                       xfs_trans_cancel(tp, 0);
+                       break;
+               }
+
+               xfs_ilock(ip, XFS_ILOCK_EXCL);
+               error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot,
+                               ip->i_gdquot, ip->i_pdquot,
+                               XFS_DIOSTRAT_SPACE_RES(mp, 0), 0,
+                               XFS_QMOPT_RES_REGBLKS);
+               if (error)
+                       goto out;
+
+               xfs_trans_ijoin(tp, ip, 0);
+
+               xfs_bmap_init(&free_list, &first_block);
+
+               /*
+                * We are using the write transaction in which max 2 bmbt
+                * updates are allowed
+                */
+               error = xfs_bmap_shift_extents(tp, ip, &done, start_fsb,
+                                              shift_fsb, &current_ext,
+                                              &first_block, &free_list,
+                                              XFS_BMAP_MAX_SHIFT_EXTENTS);
+               if (error)
+                       goto out;
+
+               error = xfs_bmap_finish(&tp, &free_list, &committed);
+               if (error)
+                       goto out;
+
+               error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+               xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       }
+
+       return error;
+
+out:
+       xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       return error;
+}
+
 /*
  * We need to check that the format of the data fork in the temporary inode is
  * valid for the target inode before doing the swap. This is not a problem with
index 900747b25772c2b1a41821fba8e99c3cde2b3ffc..935ed2b24edfb05b4d5893dccf7cebdb09a374ed 100644 (file)
@@ -99,6 +99,8 @@ int   xfs_free_file_space(struct xfs_inode *ip, xfs_off_t offset,
                            xfs_off_t len);
 int    xfs_zero_file_space(struct xfs_inode *ip, xfs_off_t offset,
                            xfs_off_t len);
+int    xfs_collapse_file_space(struct xfs_inode *, xfs_off_t offset,
+                               xfs_off_t len);
 
 /* EOF block manipulation functions */
 bool   xfs_can_free_eofblocks(struct xfs_inode *ip, bool force);
index 9adaae4f3e2fd21c647c9e7fa023a120e5012272..e80d59fdf89a8b222f05fd69e7bc970c7586c5b9 100644 (file)
@@ -234,8 +234,7 @@ xfs_btree_lblock_calc_crc(
                return;
        if (bip)
                block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        XFS_BTREE_LBLOCK_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
 }
 
 bool
@@ -243,8 +242,8 @@ xfs_btree_lblock_verify_crc(
        struct xfs_buf          *bp)
 {
        if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
-               return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                       XFS_BTREE_LBLOCK_CRC_OFF);
+               return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
+
        return true;
 }
 
@@ -267,8 +266,7 @@ xfs_btree_sblock_calc_crc(
                return;
        if (bip)
                block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        XFS_BTREE_SBLOCK_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
 }
 
 bool
@@ -276,8 +274,8 @@ xfs_btree_sblock_verify_crc(
        struct xfs_buf          *bp)
 {
        if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
-               return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                       XFS_BTREE_SBLOCK_CRC_OFF);
+               return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
+
        return true;
 }
 
index 9c061ef2b0d973c913a1baaee4a43bc27523b244..107f2fdfe41fb9ef0e6941bd60542ee12a0510e3 100644 (file)
@@ -396,7 +396,17 @@ _xfs_buf_map_pages(
                bp->b_addr = NULL;
        } else {
                int retried = 0;
+               unsigned noio_flag;
 
+               /*
+                * vm_map_ram() will allocate auxillary structures (e.g.
+                * pagetables) with GFP_KERNEL, yet we are likely to be under
+                * GFP_NOFS context here. Hence we need to tell memory reclaim
+                * that we are in such a context via PF_MEMALLOC_NOIO to prevent
+                * memory reclaim re-entering the filesystem here and
+                * potentially deadlocking.
+                */
+               noio_flag = memalloc_noio_save();
                do {
                        bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count,
                                                -1, PAGE_KERNEL);
@@ -404,6 +414,7 @@ _xfs_buf_map_pages(
                                break;
                        vm_unmap_aliases();
                } while (retried++ <= 1);
+               memalloc_noio_restore(noio_flag);
 
                if (!bp->b_addr)
                        return -ENOMEM;
index 995339534db6a4b65c6ec332055734f7415ca621..b8a3abf6cf475ee86a5d45f95d70a19a031d889f 100644 (file)
@@ -369,6 +369,20 @@ static inline void xfs_buf_relse(xfs_buf_t *bp)
        xfs_buf_rele(bp);
 }
 
+static inline int
+xfs_buf_verify_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
+{
+       return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
+                               cksum_offset);
+}
+
+static inline void
+xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
+{
+       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
+                        cksum_offset);
+}
+
 /*
  *     Handling of buftargs.
  */
index 33149113e333bd8b536d71c80b234b5d39fcb53e..8752821443bee039bd7d1f0691afaa9e4515da84 100644 (file)
@@ -796,20 +796,6 @@ xfs_buf_item_init(
                bip->bli_formats[i].blf_map_size = map_size;
        }
 
-#ifdef XFS_TRANS_DEBUG
-       /*
-        * Allocate the arrays for tracking what needs to be logged
-        * and what our callers request to be logged.  bli_orig
-        * holds a copy of the original, clean buffer for comparison
-        * against, and bli_logged keeps a 1 bit flag per byte in
-        * the buffer to indicate which bytes the callers have asked
-        * to have logged.
-        */
-       bip->bli_orig = kmem_alloc(BBTOB(bp->b_length), KM_SLEEP);
-       memcpy(bip->bli_orig, bp->b_addr, BBTOB(bp->b_length));
-       bip->bli_logged = kmem_zalloc(BBTOB(bp->b_length) / NBBY, KM_SLEEP);
-#endif
-
        /*
         * Put the buf item into the list of items attached to the
         * buffer at the front.
@@ -957,11 +943,6 @@ STATIC void
 xfs_buf_item_free(
        xfs_buf_log_item_t      *bip)
 {
-#ifdef XFS_TRANS_DEBUG
-       kmem_free(bip->bli_orig);
-       kmem_free(bip->bli_logged);
-#endif /* XFS_TRANS_DEBUG */
-
        xfs_buf_item_free_format(bip);
        kmem_zone_free(xfs_buf_item_zone, bip);
 }
index 796272a2e1298fca3a5cc08ef4c6b226d6eec15c..6cc5f6785a774045aa5290a530cba441a71d460f 100644 (file)
@@ -185,8 +185,8 @@ xfs_da3_node_write_verify(
        struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
 
        if (!xfs_da3_node_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -196,7 +196,7 @@ xfs_da3_node_write_verify(
        if (bip)
                hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DA3_NODE_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_DA3_NODE_CRC_OFF);
 }
 
 /*
@@ -209,18 +209,20 @@ static void
 xfs_da3_node_read_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
        struct xfs_da_blkinfo   *info = bp->b_addr;
 
        switch (be16_to_cpu(info->magic)) {
                case XFS_DA3_NODE_MAGIC:
-                       if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                             XFS_DA3_NODE_CRC_OFF))
+                       if (!xfs_buf_verify_cksum(bp, XFS_DA3_NODE_CRC_OFF)) {
+                               xfs_buf_ioerror(bp, EFSBADCRC);
                                break;
+                       }
                        /* fall through */
                case XFS_DA_NODE_MAGIC:
-                       if (!xfs_da3_node_verify(bp))
+                       if (!xfs_da3_node_verify(bp)) {
+                               xfs_buf_ioerror(bp, EFSCORRUPTED);
                                break;
+                       }
                        return;
                case XFS_ATTR_LEAF_MAGIC:
                case XFS_ATTR3_LEAF_MAGIC:
@@ -237,8 +239,7 @@ xfs_da3_node_read_verify(
        }
 
        /* corrupt block */
-       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
-       xfs_buf_ioerror(bp, EFSCORRUPTED);
+       xfs_verifier_error(bp);
 }
 
 const struct xfs_buf_ops xfs_da3_node_buf_ops = {
@@ -1295,7 +1296,7 @@ xfs_da3_fixhashpath(
                node = blk->bp->b_addr;
                dp->d_ops->node_hdr_from_disk(&nodehdr, node);
                btree = dp->d_ops->node_tree_p(node);
-               if (be32_to_cpu(btree->hashval) == lasthash)
+               if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
                        break;
                blk->hashval = lasthash;
                btree[blk->index].hashval = cpu_to_be32(lasthash);
index e5869b50dc41acd1788123e0cd49ea2670101e3f..623bbe8fd921d1fa8e3b994dabbf2014be5e7c6c 100644 (file)
@@ -89,6 +89,8 @@ typedef struct xfs_dinode {
        /* structure must be padded to 64 bit alignment */
 } xfs_dinode_t;
 
+#define XFS_DINODE_CRC_OFF     offsetof(struct xfs_dinode, di_crc)
+
 #define DI_MAX_FLUSH 0xffff
 
 /*
index ce16ef02997a9b27e77293033f84366919fe0e48..fda46253966a5cac252e593e14181da56f252700 100644 (file)
@@ -180,16 +180,23 @@ xfs_dir_init(
        xfs_inode_t     *dp,
        xfs_inode_t     *pdp)
 {
-       xfs_da_args_t   args;
+       struct xfs_da_args *args;
        int             error;
 
-       memset((char *)&args, 0, sizeof(args));
-       args.dp = dp;
-       args.trans = tp;
        ASSERT(S_ISDIR(dp->i_d.di_mode));
-       if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
+       error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino);
+       if (error)
                return error;
-       return xfs_dir2_sf_create(&args, pdp->i_ino);
+
+       args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
+       if (!args)
+               return ENOMEM;
+
+       args->dp = dp;
+       args->trans = tp;
+       error = xfs_dir2_sf_create(args, pdp->i_ino);
+       kmem_free(args);
+       return error;
 }
 
 /*
@@ -205,41 +212,56 @@ xfs_dir_createname(
        xfs_bmap_free_t         *flist,         /* bmap's freeblock list */
        xfs_extlen_t            total)          /* bmap's total block count */
 {
-       xfs_da_args_t           args;
+       struct xfs_da_args      *args;
        int                     rval;
        int                     v;              /* type-checking value */
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
-       if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
+       rval = xfs_dir_ino_validate(tp->t_mountp, inum);
+       if (rval)
                return rval;
        XFS_STATS_INC(xs_dir_create);
 
-       memset(&args, 0, sizeof(xfs_da_args_t));
-       args.name = name->name;
-       args.namelen = name->len;
-       args.filetype = name->type;
-       args.hashval = dp->i_mount->m_dirnameops->hashname(name);
-       args.inumber = inum;
-       args.dp = dp;
-       args.firstblock = first;
-       args.flist = flist;
-       args.total = total;
-       args.whichfork = XFS_DATA_FORK;
-       args.trans = tp;
-       args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
-
-       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_addname(&args);
-       else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_block_addname(&args);
-       else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_leaf_addname(&args);
+       args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
+       if (!args)
+               return ENOMEM;
+
+       args->name = name->name;
+       args->namelen = name->len;
+       args->filetype = name->type;
+       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->inumber = inum;
+       args->dp = dp;
+       args->firstblock = first;
+       args->flist = flist;
+       args->total = total;
+       args->whichfork = XFS_DATA_FORK;
+       args->trans = tp;
+       args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
+
+       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
+               rval = xfs_dir2_sf_addname(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isblock(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v) {
+               rval = xfs_dir2_block_addname(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isleaf(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v)
+               rval = xfs_dir2_leaf_addname(args);
        else
-               rval = xfs_dir2_node_addname(&args);
+               rval = xfs_dir2_node_addname(args);
+
+out_free:
+       kmem_free(args);
        return rval;
 }
 
@@ -282,46 +304,66 @@ xfs_dir_lookup(
        xfs_ino_t       *inum,          /* out: inode number */
        struct xfs_name *ci_name)       /* out: actual name if CI match */
 {
-       xfs_da_args_t   args;
+       struct xfs_da_args *args;
        int             rval;
        int             v;              /* type-checking value */
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
        XFS_STATS_INC(xs_dir_lookup);
 
-       memset(&args, 0, sizeof(xfs_da_args_t));
-       args.name = name->name;
-       args.namelen = name->len;
-       args.filetype = name->type;
-       args.hashval = dp->i_mount->m_dirnameops->hashname(name);
-       args.dp = dp;
-       args.whichfork = XFS_DATA_FORK;
-       args.trans = tp;
-       args.op_flags = XFS_DA_OP_OKNOENT;
+       /*
+        * We need to use KM_NOFS here so that lockdep will not throw false
+        * positive deadlock warnings on a non-transactional lookup path. It is
+        * safe to recurse into inode recalim in that case, but lockdep can't
+        * easily be taught about it. Hence KM_NOFS avoids having to add more
+        * lockdep Doing this avoids having to add a bunch of lockdep class
+        * annotations into the reclaim path for the ilock.
+        */
+       args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
+       args->name = name->name;
+       args->namelen = name->len;
+       args->filetype = name->type;
+       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->dp = dp;
+       args->whichfork = XFS_DATA_FORK;
+       args->trans = tp;
+       args->op_flags = XFS_DA_OP_OKNOENT;
        if (ci_name)
-               args.op_flags |= XFS_DA_OP_CILOOKUP;
+               args->op_flags |= XFS_DA_OP_CILOOKUP;
 
-       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_lookup(&args);
-       else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_block_lookup(&args);
-       else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_leaf_lookup(&args);
+       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
+               rval = xfs_dir2_sf_lookup(args);
+               goto out_check_rval;
+       }
+
+       rval = xfs_dir2_isblock(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v) {
+               rval = xfs_dir2_block_lookup(args);
+               goto out_check_rval;
+       }
+
+       rval = xfs_dir2_isleaf(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v)
+               rval = xfs_dir2_leaf_lookup(args);
        else
-               rval = xfs_dir2_node_lookup(&args);
+               rval = xfs_dir2_node_lookup(args);
+
+out_check_rval:
        if (rval == EEXIST)
                rval = 0;
        if (!rval) {
-               *inum = args.inumber;
+               *inum = args->inumber;
                if (ci_name) {
-                       ci_name->name = args.value;
-                       ci_name->len = args.valuelen;
+                       ci_name->name = args->value;
+                       ci_name->len = args->valuelen;
                }
        }
+out_free:
+       kmem_free(args);
        return rval;
 }
 
@@ -338,38 +380,51 @@ xfs_dir_removename(
        xfs_bmap_free_t *flist,         /* bmap's freeblock list */
        xfs_extlen_t    total)          /* bmap's total block count */
 {
-       xfs_da_args_t   args;
+       struct xfs_da_args *args;
        int             rval;
        int             v;              /* type-checking value */
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
        XFS_STATS_INC(xs_dir_remove);
 
-       memset(&args, 0, sizeof(xfs_da_args_t));
-       args.name = name->name;
-       args.namelen = name->len;
-       args.filetype = name->type;
-       args.hashval = dp->i_mount->m_dirnameops->hashname(name);
-       args.inumber = ino;
-       args.dp = dp;
-       args.firstblock = first;
-       args.flist = flist;
-       args.total = total;
-       args.whichfork = XFS_DATA_FORK;
-       args.trans = tp;
-
-       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_removename(&args);
-       else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_block_removename(&args);
-       else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_leaf_removename(&args);
+       args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
+       if (!args)
+               return ENOMEM;
+
+       args->name = name->name;
+       args->namelen = name->len;
+       args->filetype = name->type;
+       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->inumber = ino;
+       args->dp = dp;
+       args->firstblock = first;
+       args->flist = flist;
+       args->total = total;
+       args->whichfork = XFS_DATA_FORK;
+       args->trans = tp;
+
+       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
+               rval = xfs_dir2_sf_removename(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isblock(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v) {
+               rval = xfs_dir2_block_removename(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isleaf(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v)
+               rval = xfs_dir2_leaf_removename(args);
        else
-               rval = xfs_dir2_node_removename(&args);
+               rval = xfs_dir2_node_removename(args);
+out_free:
+       kmem_free(args);
        return rval;
 }
 
@@ -386,40 +441,54 @@ xfs_dir_replace(
        xfs_bmap_free_t *flist,         /* bmap's freeblock list */
        xfs_extlen_t    total)          /* bmap's total block count */
 {
-       xfs_da_args_t   args;
+       struct xfs_da_args *args;
        int             rval;
        int             v;              /* type-checking value */
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
 
-       if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
+       rval = xfs_dir_ino_validate(tp->t_mountp, inum);
+       if (rval)
                return rval;
 
-       memset(&args, 0, sizeof(xfs_da_args_t));
-       args.name = name->name;
-       args.namelen = name->len;
-       args.filetype = name->type;
-       args.hashval = dp->i_mount->m_dirnameops->hashname(name);
-       args.inumber = inum;
-       args.dp = dp;
-       args.firstblock = first;
-       args.flist = flist;
-       args.total = total;
-       args.whichfork = XFS_DATA_FORK;
-       args.trans = tp;
-
-       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_replace(&args);
-       else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_block_replace(&args);
-       else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_leaf_replace(&args);
+       args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
+       if (!args)
+               return ENOMEM;
+
+       args->name = name->name;
+       args->namelen = name->len;
+       args->filetype = name->type;
+       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->inumber = inum;
+       args->dp = dp;
+       args->firstblock = first;
+       args->flist = flist;
+       args->total = total;
+       args->whichfork = XFS_DATA_FORK;
+       args->trans = tp;
+
+       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
+               rval = xfs_dir2_sf_replace(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isblock(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v) {
+               rval = xfs_dir2_block_replace(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isleaf(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v)
+               rval = xfs_dir2_leaf_replace(args);
        else
-               rval = xfs_dir2_node_replace(&args);
+               rval = xfs_dir2_node_replace(args);
+out_free:
+       kmem_free(args);
        return rval;
 }
 
@@ -434,7 +503,7 @@ xfs_dir_canenter(
        struct xfs_name *name,          /* name of entry to add */
        uint            resblks)
 {
-       xfs_da_args_t   args;
+       struct xfs_da_args *args;
        int             rval;
        int             v;              /* type-checking value */
 
@@ -443,29 +512,42 @@ xfs_dir_canenter(
 
        ASSERT(S_ISDIR(dp->i_d.di_mode));
 
-       memset(&args, 0, sizeof(xfs_da_args_t));
-       args.name = name->name;
-       args.namelen = name->len;
-       args.filetype = name->type;
-       args.hashval = dp->i_mount->m_dirnameops->hashname(name);
-       args.dp = dp;
-       args.whichfork = XFS_DATA_FORK;
-       args.trans = tp;
-       args.op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME |
+       args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
+       if (!args)
+               return ENOMEM;
+
+       args->name = name->name;
+       args->namelen = name->len;
+       args->filetype = name->type;
+       args->hashval = dp->i_mount->m_dirnameops->hashname(name);
+       args->dp = dp;
+       args->whichfork = XFS_DATA_FORK;
+       args->trans = tp;
+       args->op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME |
                                                        XFS_DA_OP_OKNOENT;
 
-       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
-               rval = xfs_dir2_sf_addname(&args);
-       else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_block_addname(&args);
-       else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
-               return rval;
-       else if (v)
-               rval = xfs_dir2_leaf_addname(&args);
+       if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
+               rval = xfs_dir2_sf_addname(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isblock(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v) {
+               rval = xfs_dir2_block_addname(args);
+               goto out_free;
+       }
+
+       rval = xfs_dir2_isleaf(tp, dp, &v);
+       if (rval)
+               goto out_free;
+       if (v)
+               rval = xfs_dir2_leaf_addname(args);
        else
-               rval = xfs_dir2_node_addname(&args);
+               rval = xfs_dir2_node_addname(args);
+out_free:
+       kmem_free(args);
        return rval;
 }
 
index 90cdbf4b5f1902f983f504b6b704cd2a433ddfbb..4f6a38cb83a4ee9f467896deabeefb059cbe8d10 100644 (file)
@@ -89,13 +89,14 @@ xfs_dir3_block_read_verify(
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
-       if ((xfs_sb_version_hascrc(&mp->m_sb) &&
-            !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         XFS_DIR3_DATA_CRC_OFF)) ||
-           !xfs_dir3_block_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+            !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_dir3_block_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -107,8 +108,8 @@ xfs_dir3_block_write_verify(
        struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 
        if (!xfs_dir3_block_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -118,7 +119,7 @@ xfs_dir3_block_write_verify(
        if (bip)
                hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_DATA_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
index 70acff4ee1739860a4ed8a311aa8ff2f2b33aafe..afa4ad523f3f0278cf7de73a93a25c3b8b191e1d 100644 (file)
@@ -241,7 +241,6 @@ static void
 xfs_dir3_data_reada_verify(
        struct xfs_buf          *bp)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
 
        switch (hdr->magic) {
@@ -255,8 +254,8 @@ xfs_dir3_data_reada_verify(
                xfs_dir3_data_verify(bp);
                return;
        default:
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                break;
        }
 }
@@ -267,13 +266,14 @@ xfs_dir3_data_read_verify(
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
-       if ((xfs_sb_version_hascrc(&mp->m_sb) &&
-            !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         XFS_DIR3_DATA_CRC_OFF)) ||
-           !xfs_dir3_data_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+            !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
+                xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_dir3_data_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -285,8 +285,8 @@ xfs_dir3_data_write_verify(
        struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 
        if (!xfs_dir3_data_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -296,7 +296,7 @@ xfs_dir3_data_write_verify(
        if (bip)
                hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_DATA_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
index ae47ec6e16c4031e50ba9ef63884ce216757d41e..d36e97df1187ebc866e9c3885d6f848ca3373c5a 100644 (file)
@@ -179,13 +179,14 @@ __read_verify(
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
-       if ((xfs_sb_version_hascrc(&mp->m_sb) &&
-            !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         XFS_DIR3_LEAF_CRC_OFF)) ||
-           !xfs_dir3_leaf_verify(bp, magic)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+            !xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_dir3_leaf_verify(bp, magic))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -198,8 +199,8 @@ __write_verify(
        struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr;
 
        if (!xfs_dir3_leaf_verify(bp, magic)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -209,7 +210,7 @@ __write_verify(
        if (bip)
                hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_LEAF_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_DIR3_LEAF_CRC_OFF);
 }
 
 static void
index 48c7d18f68c3fb23a89a31a955fc9250fbd63108..cb434d732681a33e9e798278670b0b2ba99bdfbc 100644 (file)
@@ -115,13 +115,14 @@ xfs_dir3_free_read_verify(
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
-       if ((xfs_sb_version_hascrc(&mp->m_sb) &&
-            !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         XFS_DIR3_FREE_CRC_OFF)) ||
-           !xfs_dir3_free_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+           !xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_dir3_free_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -133,8 +134,8 @@ xfs_dir3_free_write_verify(
        struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 
        if (!xfs_dir3_free_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -144,7 +145,7 @@ xfs_dir3_free_write_verify(
        if (bip)
                hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF);
+       xfs_buf_update_cksum(bp, XFS_DIR3_FREE_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
index 7aeb4c895b3294e84731b44f6f75487d6a655c3e..868b19f096bfa412223b72ad6d75fd72c909647d 100644 (file)
@@ -615,7 +615,7 @@ xfs_qm_dqread(
 
        if (flags & XFS_QMOPT_DQALLOC) {
                tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC);
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_attrsetm,
+               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_dqalloc,
                                          XFS_QM_DQALLOC_SPACE_RES(mp), 0);
                if (error)
                        goto error1;
index d401457d2f258ac409dfbc4cbfb1af45c6bb07a2..610da81777374587e75c1333435590fe3651c92f 100644 (file)
@@ -257,10 +257,13 @@ xfs_dquot_buf_read_verify(
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
-       if (!xfs_dquot_buf_verify_crc(mp, bp) || !xfs_dquot_buf_verify(mp, bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (!xfs_dquot_buf_verify_crc(mp, bp))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_dquot_buf_verify(mp, bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 /*
@@ -275,8 +278,8 @@ xfs_dquot_buf_write_verify(
        struct xfs_mount        *mp = bp->b_target->bt_mount;
 
        if (!xfs_dquot_buf_verify(mp, bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 }
index 9995b807d627eb564da0747124359caa6141ee57..edac5b057d28790b5f0c6f767b12b1360a1488b7 100644 (file)
@@ -156,7 +156,7 @@ xfs_error_report(
 {
        if (level <= xfs_error_level) {
                xfs_alert_tag(mp, XFS_PTAG_ERROR_REPORT,
-               "Internal error %s at line %d of file %s.  Caller 0x%p",
+               "Internal error %s at line %d of file %s.  Caller %pF",
                            tag, linenum, filename, ra);
 
                xfs_stack_trace();
@@ -178,3 +178,28 @@ xfs_corruption_error(
        xfs_error_report(tag, level, mp, filename, linenum, ra);
        xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
 }
+
+/*
+ * Warnings specifically for verifier errors.  Differentiate CRC vs. invalid
+ * values, and omit the stack trace unless the error level is tuned high.
+ */
+void
+xfs_verifier_error(
+       struct xfs_buf          *bp)
+{
+       struct xfs_mount *mp = bp->b_target->bt_mount;
+
+       xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx",
+                 bp->b_error == EFSBADCRC ? "CRC error" : "corruption",
+                 __return_address, bp->b_bn);
+
+       xfs_alert(mp, "Unmount and run xfs_repair");
+
+       if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
+               xfs_alert(mp, "First 64 bytes of corrupted metadata buffer:");
+               xfs_hex_dump(xfs_buf_offset(bp, 0), 64);
+       }
+
+       if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
+               xfs_stack_trace();
+}
index 079a367f44eeb6f67c16666c695a5fd3a246637d..c1c57d4a4b5db6f37a626d7e78a48f32facf8dcd 100644 (file)
@@ -34,6 +34,7 @@ extern void xfs_error_report(const char *tag, int level, struct xfs_mount *mp,
 extern void xfs_corruption_error(const char *tag, int level,
                        struct xfs_mount *mp, void *p, const char *filename,
                        int linenum, inst_t *ra);
+extern void xfs_verifier_error(struct xfs_buf *bp);
 
 #define        XFS_ERROR_REPORT(e, lvl, mp)    \
        xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
index 64b48eade91d14c79408b6863f199e9181350f81..f7abff8c16ca7361d3e32f1842ae1daed15e651e 100644 (file)
@@ -823,7 +823,8 @@ xfs_file_fallocate(
 
        if (!S_ISREG(inode->i_mode))
                return -EINVAL;
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+                    FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE))
                return -EOPNOTSUPP;
 
        xfs_ilock(ip, XFS_IOLOCK_EXCL);
@@ -831,6 +832,20 @@ xfs_file_fallocate(
                error = xfs_free_file_space(ip, offset, len);
                if (error)
                        goto out_unlock;
+       } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
+               unsigned blksize_mask = (1 << inode->i_blkbits) - 1;
+
+               if (offset & blksize_mask || len & blksize_mask) {
+                       error = -EINVAL;
+                       goto out_unlock;
+               }
+
+               ASSERT(offset + len < i_size_read(inode));
+               new_size = i_size_read(inode) - len;
+
+               error = xfs_collapse_file_space(ip, offset, len);
+               if (error)
+                       goto out_unlock;
        } else {
                if (!(mode & FALLOC_FL_KEEP_SIZE) &&
                    offset + len > i_size_read(inode)) {
@@ -840,8 +855,11 @@ xfs_file_fallocate(
                                goto out_unlock;
                }
 
-               error = xfs_alloc_file_space(ip, offset, len,
-                                            XFS_BMAPI_PREALLOC);
+               if (mode & FALLOC_FL_ZERO_RANGE)
+                       error = xfs_zero_file_space(ip, offset, len);
+               else
+                       error = xfs_alloc_file_space(ip, offset, len,
+                                                    XFS_BMAPI_PREALLOC);
                if (error)
                        goto out_unlock;
        }
@@ -859,7 +877,7 @@ xfs_file_fallocate(
        if (ip->i_d.di_mode & S_IXGRP)
                ip->i_d.di_mode &= ~S_ISGID;
 
-       if (!(mode & FALLOC_FL_PUNCH_HOLE))
+       if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)))
                ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
 
        xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
index b6ab5a3cfa125d2204d19760dccac917d0ad957f..9898f31d05d8c2f7096647b8750ede07808b5a54 100644 (file)
@@ -145,6 +145,8 @@ struct xfs_dsymlink_hdr {
        __be64  sl_lsn;
 };
 
+#define XFS_SYMLINK_CRC_OFF    offsetof(struct xfs_dsymlink_hdr, sl_crc)
+
 /*
  * The maximum pathlen is 1024 bytes. Since the minimum file system
  * blocksize is 512 bytes, we can get a max of 3 extents back from
index 5d7f105a1c82e932175ce61b3dfce66b2282966e..8f711db61a0c2148ecfd98c22bed1509fa437e11 100644 (file)
@@ -363,6 +363,18 @@ xfs_ialloc_ag_alloc(
                args.minleft = args.mp->m_in_maxlevels - 1;
                if ((error = xfs_alloc_vextent(&args)))
                        return error;
+
+               /*
+                * This request might have dirtied the transaction if the AG can
+                * satisfy the request, but the exact block was not available.
+                * If the allocation did fail, subsequent requests will relax
+                * the exact agbno requirement and increase the alignment
+                * instead. It is critical that the total size of the request
+                * (len + alignment + slop) does not increase from this point
+                * on, so reset minalignslop to ensure it is not included in
+                * subsequent requests.
+                */
+               args.minalignslop = 0;
        } else
                args.fsbno = NULLFSBLOCK;
 
@@ -1568,18 +1580,17 @@ xfs_agi_read_verify(
        struct xfs_buf  *bp)
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
-       int             agi_ok = 1;
-
-       if (xfs_sb_version_hascrc(&mp->m_sb))
-               agi_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                         offsetof(struct xfs_agi, agi_crc));
-       agi_ok = agi_ok && xfs_agi_verify(bp);
 
-       if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
-                       XFS_RANDOM_IALLOC_READ_AGI))) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+           !xfs_buf_verify_cksum(bp, XFS_AGI_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (XFS_TEST_ERROR(!xfs_agi_verify(bp), mp,
+                               XFS_ERRTAG_IALLOC_READ_AGI,
+                               XFS_RANDOM_IALLOC_READ_AGI))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -1590,8 +1601,8 @@ xfs_agi_write_verify(
        struct xfs_buf_log_item *bip = bp->b_fspriv;
 
        if (!xfs_agi_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -1600,8 +1611,7 @@ xfs_agi_write_verify(
 
        if (bip)
                XFS_BUF_TO_AGI(bp)->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn);
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        offsetof(struct xfs_agi, agi_crc));
+       xfs_buf_update_cksum(bp, XFS_AGI_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_agi_buf_ops = {
index c8fa5bbb36de3163b9fc798fc80025815f46182e..7e309b11e87d75240cfdb41428d1f13dc7d470b8 100644 (file)
@@ -243,12 +243,14 @@ static void
 xfs_inobt_read_verify(
        struct xfs_buf  *bp)
 {
-       if (!(xfs_btree_sblock_verify_crc(bp) &&
-             xfs_inobt_verify(bp))) {
-               trace_xfs_btree_corrupt(bp, _RET_IP_);
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
+       if (!xfs_btree_sblock_verify_crc(bp))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_inobt_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+
+       if (bp->b_error) {
+               trace_xfs_btree_corrupt(bp, _RET_IP_);
+               xfs_verifier_error(bp);
        }
 }
 
@@ -258,9 +260,9 @@ xfs_inobt_write_verify(
 {
        if (!xfs_inobt_verify(bp)) {
                trace_xfs_btree_corrupt(bp, _RET_IP_);
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    bp->b_target->bt_mount, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
+               return;
        }
        xfs_btree_sblock_calc_crc(bp);
 
index 3a137e9f9a7dac3fb72f1687bf086b1273d83890..5e7a38fa6ee6bd82e43c05f66cdc6d4b8404225e 100644 (file)
@@ -42,7 +42,6 @@
 #include "xfs_bmap_util.h"
 #include "xfs_error.h"
 #include "xfs_quota.h"
-#include "xfs_dinode.h"
 #include "xfs_filestream.h"
 #include "xfs_cksum.h"
 #include "xfs_trace.h"
@@ -62,6 +61,8 @@ kmem_zone_t *xfs_inode_zone;
 
 STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);
 
+STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *);
+
 /*
  * helper function to extract extent size hint from inode
  */
@@ -1115,7 +1116,7 @@ xfs_bumplink(
 {
        xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
 
-       ASSERT(ip->i_d.di_nlink > 0);
+       ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
        ip->i_d.di_nlink++;
        inc_nlink(VFS_I(ip));
        if ((ip->i_d.di_version == 1) &&
@@ -1165,10 +1166,7 @@ xfs_create(
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
-       if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
-               prid = xfs_get_projid(dp);
-       else
-               prid = XFS_PROJID_DEFAULT;
+       prid = xfs_get_initial_prid(dp);
 
        /*
         * Make sure that we have allocated dquot(s) on disk.
@@ -1332,6 +1330,113 @@ xfs_create(
        return error;
 }
 
+int
+xfs_create_tmpfile(
+       struct xfs_inode        *dp,
+       struct dentry           *dentry,
+       umode_t                 mode)
+{
+       struct xfs_mount        *mp = dp->i_mount;
+       struct xfs_inode        *ip = NULL;
+       struct xfs_trans        *tp = NULL;
+       int                     error;
+       uint                    cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
+       prid_t                  prid;
+       struct xfs_dquot        *udqp = NULL;
+       struct xfs_dquot        *gdqp = NULL;
+       struct xfs_dquot        *pdqp = NULL;
+       struct xfs_trans_res    *tres;
+       uint                    resblks;
+
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return XFS_ERROR(EIO);
+
+       prid = xfs_get_initial_prid(dp);
+
+       /*
+        * Make sure that we have allocated dquot(s) on disk.
+        */
+       error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
+                               xfs_kgid_to_gid(current_fsgid()), prid,
+                               XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
+                               &udqp, &gdqp, &pdqp);
+       if (error)
+               return error;
+
+       resblks = XFS_IALLOC_SPACE_RES(mp);
+       tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
+
+       tres = &M_RES(mp)->tr_create_tmpfile;
+       error = xfs_trans_reserve(tp, tres, resblks, 0);
+       if (error == ENOSPC) {
+               /* No space at all so try a "no-allocation" reservation */
+               resblks = 0;
+               error = xfs_trans_reserve(tp, tres, 0, 0);
+       }
+       if (error) {
+               cancel_flags = 0;
+               goto out_trans_cancel;
+       }
+
+       error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
+                                               pdqp, resblks, 1, 0);
+       if (error)
+               goto out_trans_cancel;
+
+       error = xfs_dir_ialloc(&tp, dp, mode, 1, 0,
+                               prid, resblks > 0, &ip, NULL);
+       if (error) {
+               if (error == ENOSPC)
+                       goto out_trans_cancel;
+               goto out_trans_abort;
+       }
+
+       if (mp->m_flags & XFS_MOUNT_WSYNC)
+               xfs_trans_set_sync(tp);
+
+       /*
+        * Attach the dquot(s) to the inodes and modify them incore.
+        * These ids of the inode couldn't have changed since the new
+        * inode has been locked ever since it was created.
+        */
+       xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
+
+       ip->i_d.di_nlink--;
+       d_tmpfile(dentry, VFS_I(ip));
+       error = xfs_iunlink(tp, ip);
+       if (error)
+               goto out_trans_abort;
+
+       error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+       if (error)
+               goto out_release_inode;
+
+       xfs_qm_dqrele(udqp);
+       xfs_qm_dqrele(gdqp);
+       xfs_qm_dqrele(pdqp);
+
+       return 0;
+
+ out_trans_abort:
+       cancel_flags |= XFS_TRANS_ABORT;
+ out_trans_cancel:
+       xfs_trans_cancel(tp, cancel_flags);
+ out_release_inode:
+       /*
+        * Wait until after the current transaction is aborted to
+        * release the inode.  This prevents recursive transactions
+        * and deadlocks from xfs_inactive.
+        */
+       if (ip)
+               IRELE(ip);
+
+       xfs_qm_dqrele(udqp);
+       xfs_qm_dqrele(gdqp);
+       xfs_qm_dqrele(pdqp);
+
+       return error;
+}
+
 int
 xfs_link(
        xfs_inode_t             *tdp,
@@ -1397,6 +1502,12 @@ xfs_link(
 
        xfs_bmap_init(&free_list, &first_block);
 
+       if (sip->i_d.di_nlink == 0) {
+               error = xfs_iunlink_remove(tp, sip);
+               if (error)
+                       goto abort_return;
+       }
+
        error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
                                        &first_block, &free_list, resblks);
        if (error)
index 65e2350f449c9c4c086b8e6cd0de1f07f82c7fc8..396cc1fafd0d5e358c5ea8ccc21d3525d2396bfa 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "xfs_inode_buf.h"
 #include "xfs_inode_fork.h"
+#include "xfs_dinode.h"
 
 /*
  * Kernel only inode definitions
@@ -192,6 +193,15 @@ xfs_set_projid(struct xfs_inode *ip,
        ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff);
 }
 
+static inline prid_t
+xfs_get_initial_prid(struct xfs_inode *dp)
+{
+       if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+               return xfs_get_projid(dp);
+
+       return XFS_PROJID_DEFAULT;
+}
+
 /*
  * In-core inode flags.
  */
@@ -323,6 +333,8 @@ int         xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
                           struct xfs_inode **ipp, struct xfs_name *ci_name);
 int            xfs_create(struct xfs_inode *dp, struct xfs_name *name,
                           umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp);
+int            xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry,
+                          umode_t mode);
 int            xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
                           struct xfs_inode *ip);
 int            xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
index 4fc9f39dd89e7b8ed64e271ca6ced6bc43a191f6..24e993996bdcf90f9f955ed139d2783840082927 100644 (file)
@@ -102,8 +102,7 @@ xfs_inode_buf_verify(
                        }
 
                        xfs_buf_ioerror(bp, EFSCORRUPTED);
-                       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
-                                            mp, dip);
+                       xfs_verifier_error(bp);
 #ifdef DEBUG
                        xfs_alert(mp,
                                "bad inode magic/vsn daddr %lld #%d (magic=%x)",
@@ -306,7 +305,7 @@ xfs_dinode_verify(
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return false;
        if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
-                             offsetof(struct xfs_dinode, di_crc)))
+                             XFS_DINODE_CRC_OFF))
                return false;
        if (be64_to_cpu(dip->di_ino) != ip->i_ino)
                return false;
@@ -327,7 +326,7 @@ xfs_dinode_calc_crc(
 
        ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
        crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
-                             offsetof(struct xfs_dinode, di_crc));
+                             XFS_DINODE_CRC_OFF);
        dip->di_crc = xfs_end_cksum(crc);
 }
 
index 22d1cbea283d4734515218ef65b23ec78bfdeff6..3b80ebae05f52eb7d3593b0df92ec834f319948c 100644 (file)
@@ -128,7 +128,6 @@ xfs_iomap_write_direct(
        xfs_fsblock_t   firstfsb;
        xfs_extlen_t    extsz, temp;
        int             nimaps;
-       int             bmapi_flag;
        int             quota_flag;
        int             rt;
        xfs_trans_t     *tp;
@@ -200,18 +199,15 @@ xfs_iomap_write_direct(
 
        xfs_trans_ijoin(tp, ip, 0);
 
-       bmapi_flag = 0;
-       if (offset < XFS_ISIZE(ip) || extsz)
-               bmapi_flag |= XFS_BMAPI_PREALLOC;
-
        /*
         * From this point onwards we overwrite the imap pointer that the
         * caller gave to us.
         */
        xfs_bmap_init(&free_list, &firstfsb);
        nimaps = 1;
-       error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flag,
-                               &firstfsb, 0, imap, &nimaps, &free_list);
+       error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
+                               XFS_BMAPI_PREALLOC, &firstfsb, 0,
+                               imap, &nimaps, &free_list);
        if (error)
                goto out_bmap_cancel;
 
index 9ddfb8190ca1cd56b5f1cd2247e9f54925fce68f..89b07e43ca28811349db39aa1ab2534de220fd87 100644 (file)
@@ -39,6 +39,7 @@
 #include "xfs_da_btree.h"
 #include "xfs_dir2_priv.h"
 #include "xfs_dinode.h"
+#include "xfs_trans_space.h"
 
 #include <linux/capability.h>
 #include <linux/xattr.h>
 #include <linux/fiemap.h>
 #include <linux/slab.h>
 
+/*
+ * Directories have different lock order w.r.t. mmap_sem compared to regular
+ * files. This is due to readdir potentially triggering page faults on a user
+ * buffer inside filldir(), and this happens with the ilock on the directory
+ * held. For regular files, the lock order is the other way around - the
+ * mmap_sem is taken during the page fault, and then we lock the ilock to do
+ * block mapping. Hence we need a different class for the directory ilock so
+ * that lockdep can tell them apart.
+ */
+static struct lock_class_key xfs_nondir_ilock_class;
+static struct lock_class_key xfs_dir_ilock_class;
+
 static int
 xfs_initxattrs(
        struct inode            *inode,
@@ -1034,6 +1047,19 @@ xfs_vn_fiemap(
        return 0;
 }
 
+STATIC int
+xfs_vn_tmpfile(
+       struct inode    *dir,
+       struct dentry   *dentry,
+       umode_t         mode)
+{
+       int             error;
+
+       error = xfs_create_tmpfile(XFS_I(dir), dentry, mode);
+
+       return -error;
+}
+
 static const struct inode_operations xfs_inode_operations = {
        .get_acl                = xfs_get_acl,
        .set_acl                = xfs_set_acl,
@@ -1072,6 +1098,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
        .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
        .update_time            = xfs_vn_update_time,
+       .tmpfile                = xfs_vn_tmpfile,
 };
 
 static const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -1099,6 +1126,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
        .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
        .update_time            = xfs_vn_update_time,
+       .tmpfile                = xfs_vn_tmpfile,
 };
 
 static const struct inode_operations xfs_symlink_inode_operations = {
@@ -1191,6 +1219,7 @@ xfs_setup_inode(
        xfs_diflags_to_iflags(inode, ip);
 
        ip->d_ops = ip->i_mount->m_nondir_inode_ops;
+       lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
        switch (inode->i_mode & S_IFMT) {
        case S_IFREG:
                inode->i_op = &xfs_inode_operations;
@@ -1198,6 +1227,7 @@ xfs_setup_inode(
                inode->i_mapping->a_ops = &xfs_address_space_operations;
                break;
        case S_IFDIR:
+               lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
                if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
                        inode->i_op = &xfs_dir_ci_inode_operations;
                else
index f9bb590acc0ebfd38a4aaaee3baaa5b0bf6ec505..825249d2dfc1a740b6c5523ac1808af53776efb0 100644 (file)
@@ -119,6 +119,7 @@ typedef __uint64_t __psunsigned_t;
 #include "xfs_iops.h"
 #include "xfs_aops.h"
 #include "xfs_super.h"
+#include "xfs_cksum.h"
 #include "xfs_buf.h"
 #include "xfs_message.h"
 
@@ -178,6 +179,7 @@ typedef __uint64_t __psunsigned_t;
 #define ENOATTR                ENODATA         /* Attribute not found */
 #define EWRONGFS       EINVAL          /* Mount with wrong filesystem type */
 #define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
+#define EFSBADCRC      EBADMSG         /* Bad CRC detected */
 
 #define SYNCHRONIZE()  barrier()
 #define __return_address __builtin_return_address(0)
index b0f4ef77fa70bd698749e2509e64d79f782fa8aa..2c4004475e71af25dbfa4a6e853af5cfd09bac75 100644 (file)
@@ -175,7 +175,7 @@ void          xlog_iodone(struct xfs_buf *);
 struct xlog_ticket *xfs_log_ticket_get(struct xlog_ticket *ticket);
 void     xfs_log_ticket_put(struct xlog_ticket *ticket);
 
-int    xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
+void   xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
                                xfs_lsn_t *commit_lsn, int flags);
 bool   xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);
 
index 4ef6fdbced78b7e99680f9e4e8afbb502a7bce92..7e54553911764e556637855bea0d4dcfdc3e50fd 100644 (file)
@@ -498,13 +498,6 @@ xlog_cil_push(
        new_ctx->cil = cil;
        cil->xc_ctx = new_ctx;
 
-       /*
-        * mirror the new sequence into the cil structure so that we can do
-        * unlocked checks against the current sequence in log forces without
-        * risking deferencing a freed context pointer.
-        */
-       cil->xc_current_sequence = new_ctx->sequence;
-
        /*
         * The switch is now done, so we can drop the context lock and move out
         * of a shared context. We can't just go straight to the commit record,
@@ -523,8 +516,15 @@ xlog_cil_push(
         * Hence we need to add this context to the committing context list so
         * that higher sequences will wait for us to write out a commit record
         * before they do.
+        *
+        * xfs_log_force_lsn requires us to mirror the new sequence into the cil
+        * structure atomically with the addition of this sequence to the
+        * committing list. This also ensures that we can do unlocked checks
+        * against the current sequence in log forces without risking
+        * deferencing a freed context pointer.
         */
        spin_lock(&cil->xc_push_lock);
+       cil->xc_current_sequence = new_ctx->sequence;
        list_add(&ctx->committing, &cil->xc_committing);
        spin_unlock(&cil->xc_push_lock);
        up_write(&cil->xc_ctx_lock);
@@ -662,8 +662,14 @@ xlog_cil_push_background(
 
 }
 
+/*
+ * xlog_cil_push_now() is used to trigger an immediate CIL push to the sequence
+ * number that is passed. When it returns, the work will be queued for
+ * @push_seq, but it won't be completed. The caller is expected to do any
+ * waiting for push_seq to complete if it is required.
+ */
 static void
-xlog_cil_push_foreground(
+xlog_cil_push_now(
        struct xlog     *log,
        xfs_lsn_t       push_seq)
 {
@@ -688,10 +694,8 @@ xlog_cil_push_foreground(
        }
 
        cil->xc_push_seq = push_seq;
+       queue_work(log->l_mp->m_cil_workqueue, &cil->xc_push_work);
        spin_unlock(&cil->xc_push_lock);
-
-       /* do the push now */
-       xlog_cil_push(log);
 }
 
 bool
@@ -721,7 +725,7 @@ xlog_cil_empty(
  * background commit, returns without it held once background commits are
  * allowed again.
  */
-int
+void
 xfs_log_commit_cil(
        struct xfs_mount        *mp,
        struct xfs_trans        *tp,
@@ -767,7 +771,6 @@ xfs_log_commit_cil(
        xlog_cil_push_background(log);
 
        up_read(&cil->xc_ctx_lock);
-       return 0;
 }
 
 /*
@@ -796,7 +799,8 @@ xlog_cil_force_lsn(
         * xlog_cil_push() handles racing pushes for the same sequence,
         * so no need to deal with it here.
         */
-       xlog_cil_push_foreground(log, sequence);
+restart:
+       xlog_cil_push_now(log, sequence);
 
        /*
         * See if we can find a previous sequence still committing.
@@ -804,7 +808,6 @@ xlog_cil_force_lsn(
         * before allowing the force of push_seq to go ahead. Hence block
         * on commits for those as well.
         */
-restart:
        spin_lock(&cil->xc_push_lock);
        list_for_each_entry(ctx, &cil->xc_committing, committing) {
                if (ctx->sequence > sequence)
@@ -822,6 +825,28 @@ restart:
                /* found it! */
                commit_lsn = ctx->commit_lsn;
        }
+
+       /*
+        * The call to xlog_cil_push_now() executes the push in the background.
+        * Hence by the time we have got here it our sequence may not have been
+        * pushed yet. This is true if the current sequence still matches the
+        * push sequence after the above wait loop and the CIL still contains
+        * dirty objects.
+        *
+        * When the push occurs, it will empty the CIL and
+        * atomically increment the currect sequence past the push sequence and
+        * move it into the committing list. Of course, if the CIL is clean at
+        * the time of the push, it won't have pushed the CIL at all, so in that
+        * case we should try the push for this sequence again from the start
+        * just in case.
+        */
+
+       if (sequence == cil->xc_current_sequence &&
+           !list_empty(&cil->xc_cil)) {
+               spin_unlock(&cil->xc_push_lock);
+               goto restart;
+       }
+
        spin_unlock(&cil->xc_push_lock);
        return commit_lsn;
 }
index f96c05669a9e06298980bd14e377e34536d0119b..993cb19e7d390e03220f265e9ba97e0f0c8dc7fa 100644 (file)
@@ -314,6 +314,9 @@ reread:
                error = bp->b_error;
                if (loud)
                        xfs_warn(mp, "SB validate failed with error %d.", error);
+               /* bad CRC means corrupted metadata */
+               if (error == EFSBADCRC)
+                       error = EFSCORRUPTED;
                goto release_buf;
        }
 
index a6a76b2b6a85db9ece8acb0565e82e310319ec9d..ec5ca65c62116e62d509b987c92c983e79d3cbb6 100644 (file)
@@ -842,7 +842,7 @@ xfs_growfs_rt_alloc(
                /*
                 * Reserve space & log for one extent added to the file.
                 */
-               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growdata,
+               error = xfs_trans_reserve(tp, &M_RES(mp)->tr_growrtalloc,
                                          resblks, 0);
                if (error)
                        goto error_cancel;
index 1e116794bb6622d686487f36a461f8f644fd27c2..0c0e41bbe4e369d7bf5267ed906e59159a4e2ff7 100644 (file)
@@ -288,6 +288,7 @@ xfs_mount_validate_sb(
            sbp->sb_inodelog < XFS_DINODE_MIN_LOG                       ||
            sbp->sb_inodelog > XFS_DINODE_MAX_LOG                       ||
            sbp->sb_inodesize != (1 << sbp->sb_inodelog)                ||
+           sbp->sb_inopblock != howmany(sbp->sb_blocksize,sbp->sb_inodesize) ||
            (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog)   ||
            (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE)  ||
            (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE)  ||
@@ -610,12 +611,11 @@ xfs_sb_read_verify(
                                                XFS_SB_VERSION_5) ||
             dsb->sb_crc != 0)) {
 
-               if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                     offsetof(struct xfs_sb, sb_crc))) {
+               if (!xfs_buf_verify_cksum(bp, XFS_SB_CRC_OFF)) {
                        /* Only fail bad secondaries on a known V5 filesystem */
                        if (bp->b_bn == XFS_SB_DADDR ||
                            xfs_sb_version_hascrc(&mp->m_sb)) {
-                               error = EFSCORRUPTED;
+                               error = EFSBADCRC;
                                goto out_error;
                        }
                }
@@ -624,10 +624,9 @@ xfs_sb_read_verify(
 
 out_error:
        if (error) {
-               if (error == EFSCORRUPTED)
-                       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                            mp, bp->b_addr);
                xfs_buf_ioerror(bp, error);
+               if (error == EFSCORRUPTED || error == EFSBADCRC)
+                       xfs_verifier_error(bp);
        }
 }
 
@@ -662,9 +661,8 @@ xfs_sb_write_verify(
 
        error = xfs_sb_verify(bp, false);
        if (error) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
-                                    mp, bp->b_addr);
                xfs_buf_ioerror(bp, error);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -674,8 +672,7 @@ xfs_sb_write_verify(
        if (bip)
                XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
 
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        offsetof(struct xfs_sb, sb_crc));
+       xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_sb_buf_ops = {
index 35061d4b614c7ab9fabb80e1b93ffb6bc8b586d2..f7b2fe77c5a5bf095a8b01e793fda242c2968cc4 100644 (file)
@@ -182,6 +182,8 @@ typedef struct xfs_sb {
        /* must be padded to 64 bit alignment */
 } xfs_sb_t;
 
+#define XFS_SB_CRC_OFF         offsetof(struct xfs_sb, sb_crc)
+
 /*
  * Superblock - on disk version.  Must match the in core version above.
  * Must be padded to 64 bit alignment.
index 8c5035a13df1a0fd6033a8f222703a9ff50e20c5..4484e515139507fe9e69912da6eb9df6c50e7402 100644 (file)
@@ -104,7 +104,8 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
 #define        XFS_TRANS_SB_COUNT              41
 #define        XFS_TRANS_CHECKPOINT            42
 #define        XFS_TRANS_ICREATE               43
-#define        XFS_TRANS_TYPE_MAX              43
+#define        XFS_TRANS_CREATE_TMPFILE        44
+#define        XFS_TRANS_TYPE_MAX              44
 /* new transaction types need to be reflected in xfs_logprint(8) */
 
 #define XFS_TRANS_TYPES \
@@ -112,6 +113,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
        { XFS_TRANS_SETATTR_SIZE,       "SETATTR_SIZE" }, \
        { XFS_TRANS_INACTIVE,           "INACTIVE" }, \
        { XFS_TRANS_CREATE,             "CREATE" }, \
+       { XFS_TRANS_CREATE_TMPFILE,     "CREATE_TMPFILE" }, \
        { XFS_TRANS_CREATE_TRUNC,       "CREATE_TRUNC" }, \
        { XFS_TRANS_TRUNCATE_FILE,      "TRUNCATE_FILE" }, \
        { XFS_TRANS_REMOVE,             "REMOVE" }, \
index 0ef5992189913a93f82ed7e83ef2aefffac64287..2053767763773b60d7b7f8aca31f3b31a9219785 100644 (file)
@@ -1197,6 +1197,7 @@ xfs_fs_remount(
        char                    *p;
        int                     error;
 
+       sync_filesystem(sb);
        while ((p = strsep(&options, ",")) != NULL) {
                int token;
 
index 14e58f2c96bd71708f1c608536b835b25f05e795..52979aa90986ca3a1a6caada967a460567245265 100644 (file)
@@ -80,6 +80,10 @@ xfs_readlink_bmap(
                if (error) {
                        xfs_buf_ioerror_alert(bp, __func__);
                        xfs_buf_relse(bp);
+
+                       /* bad CRC means corrupted metadata */
+                       if (error == EFSBADCRC)
+                               error = EFSCORRUPTED;
                        goto out;
                }
                byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
@@ -208,10 +212,7 @@ xfs_symlink(
                return XFS_ERROR(ENAMETOOLONG);
 
        udqp = gdqp = NULL;
-       if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
-               prid = xfs_get_projid(dp);
-       else
-               prid = XFS_PROJID_DEFAULT;
+       prid = xfs_get_initial_prid(dp);
 
        /*
         * Make sure that we have allocated dquot(s) on disk.
index bf59a2b45f8c40c431de3e8f52f3131d80d68a1c..9b32052ff65e771c55814afa8dcb26a8d2f0e42c 100644 (file)
@@ -133,12 +133,13 @@ xfs_symlink_read_verify(
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return;
 
-       if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                                 offsetof(struct xfs_dsymlink_hdr, sl_crc)) ||
-           !xfs_symlink_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+       if (!xfs_buf_verify_cksum(bp, XFS_SYMLINK_CRC_OFF))
+               xfs_buf_ioerror(bp, EFSBADCRC);
+       else if (!xfs_symlink_verify(bp))
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+
+       if (bp->b_error)
+               xfs_verifier_error(bp);
 }
 
 static void
@@ -153,8 +154,8 @@ xfs_symlink_write_verify(
                return;
 
        if (!xfs_symlink_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_verifier_error(bp);
                return;
        }
 
@@ -162,8 +163,7 @@ xfs_symlink_write_verify(
                struct xfs_dsymlink_hdr *dsl = bp->b_addr;
                dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
        }
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        offsetof(struct xfs_dsymlink_hdr, sl_crc));
+       xfs_buf_update_cksum(bp, XFS_SYMLINK_CRC_OFF);
 }
 
 const struct xfs_buf_ops xfs_symlink_buf_ops = {
index 425dfa45b9a087472676cf4f832138316d4b0fa4..a4ae41c179a8a66a5772914a61642b8a53be1c4b 100644 (file)
@@ -603,6 +603,7 @@ DEFINE_INODE_EVENT(xfs_readlink);
 DEFINE_INODE_EVENT(xfs_inactive_symlink);
 DEFINE_INODE_EVENT(xfs_alloc_file_space);
 DEFINE_INODE_EVENT(xfs_free_file_space);
+DEFINE_INODE_EVENT(xfs_collapse_file_space);
 DEFINE_INODE_EVENT(xfs_readdir);
 #ifdef CONFIG_XFS_POSIX_ACL
 DEFINE_INODE_EVENT(xfs_get_acl);
index c812c5c060de1caa7532f1cdcc63766a4a227207..54a57326d85b1e7b2fc84b5761773453a6c02eaf 100644 (file)
@@ -887,12 +887,7 @@ xfs_trans_commit(
                xfs_trans_apply_sb_deltas(tp);
        xfs_trans_apply_dquot_deltas(tp);
 
-       error = xfs_log_commit_cil(mp, tp, &commit_lsn, flags);
-       if (error == ENOMEM) {
-               xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
-               error = XFS_ERROR(EIO);
-               goto out_unreserve;
-       }
+       xfs_log_commit_cil(mp, tp, &commit_lsn, flags);
 
        current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
        xfs_trans_free(tp);
@@ -902,10 +897,7 @@ xfs_trans_commit(
         * log out now and wait for it.
         */
        if (sync) {
-               if (!error) {
-                       error = _xfs_log_force_lsn(mp, commit_lsn,
-                                     XFS_LOG_SYNC, NULL);
-               }
+               error = _xfs_log_force_lsn(mp, commit_lsn, XFS_LOG_SYNC, NULL);
                XFS_STATS_INC(xs_trans_sync);
        } else {
                XFS_STATS_INC(xs_trans_async);
index 647b6f1d8923fee484ada5eea3e2e68d47df8286..b8eef0549f3f9a39cc68d06cf7a9cbcb04af469f 100644 (file)
@@ -275,6 +275,10 @@ xfs_trans_read_buf_map(
                        XFS_BUF_UNDONE(bp);
                        xfs_buf_stale(bp);
                        xfs_buf_relse(bp);
+
+                       /* bad CRC means corrupted metadata */
+                       if (error == EFSBADCRC)
+                               error = EFSCORRUPTED;
                        return error;
                }
 #ifdef DEBUG
@@ -338,6 +342,9 @@ xfs_trans_read_buf_map(
                                if (tp->t_flags & XFS_TRANS_DIRTY)
                                        xfs_force_shutdown(tp->t_mountp,
                                                        SHUTDOWN_META_IO_ERROR);
+                               /* bad CRC means corrupted metadata */
+                               if (error == EFSBADCRC)
+                                       error = EFSCORRUPTED;
                                return error;
                        }
                }
@@ -375,6 +382,10 @@ xfs_trans_read_buf_map(
                if (tp->t_flags & XFS_TRANS_DIRTY)
                        xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
                xfs_buf_relse(bp);
+
+               /* bad CRC means corrupted metadata */
+               if (error == EFSBADCRC)
+                       error = EFSCORRUPTED;
                return error;
        }
 #ifdef DEBUG
index 2ffd3e331b496ae3f366b6669e3207f15becbd4f..ae368165244d49458bd4db2cc4688d196f2e2098 100644 (file)
@@ -81,20 +81,28 @@ xfs_calc_buf_res(
  * on disk. Hence we need an inode reservation function that calculates all this
  * correctly. So, we log:
  *
- * - log op headers for object
+ * - 4 log op headers for object
+ *     - for the ilf, the inode core and 2 forks
  * - inode log format object
- * - the entire inode contents (core + 2 forks)
- * - two bmap btree block headers
+ * - the inode core
+ * - two inode forks containing bmap btree root blocks.
+ *     - the btree data contained by both forks will fit into the inode size,
+ *       hence when combined with the inode core above, we have a total of the
+ *       actual inode size.
+ *     - the BMBT headers need to be accounted separately, as they are
+ *       additional to the records and pointers that fit inside the inode
+ *       forks.
  */
 STATIC uint
 xfs_calc_inode_res(
        struct xfs_mount        *mp,
        uint                    ninodes)
 {
-       return ninodes * (sizeof(struct xlog_op_header) +
-                         sizeof(struct xfs_inode_log_format) +
-                         mp->m_sb.sb_inodesize +
-                         2 * XFS_BMBT_BLOCK_LEN(mp));
+       return ninodes *
+               (4 * sizeof(struct xlog_op_header) +
+                sizeof(struct xfs_inode_log_format) +
+                mp->m_sb.sb_inodesize +
+                2 * XFS_BMBT_BLOCK_LEN(mp));
 }
 
 /*
@@ -203,6 +211,19 @@ xfs_calc_rename_reservation(
                                      XFS_FSB_TO_B(mp, 1))));
 }
 
+/*
+ * For removing an inode from unlinked list at first, we can modify:
+ *    the agi hash list and counters: sector size
+ *    the on disk inode before ours in the agi hash list: inode cluster size
+ */
+STATIC uint
+xfs_calc_iunlink_remove_reservation(
+       struct xfs_mount        *mp)
+{
+       return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+              max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size);
+}
+
 /*
  * For creating a link to an inode:
  *    the parent directory inode: inode size
@@ -220,6 +241,7 @@ xfs_calc_link_reservation(
        struct xfs_mount        *mp)
 {
        return XFS_DQUOT_LOGRES(mp) +
+               xfs_calc_iunlink_remove_reservation(mp) +
                MAX((xfs_calc_inode_res(mp, 2) +
                     xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
                                      XFS_FSB_TO_B(mp, 1))),
@@ -228,6 +250,18 @@ xfs_calc_link_reservation(
                                      XFS_FSB_TO_B(mp, 1))));
 }
 
+/*
+ * For adding an inode to unlinked list we can modify:
+ *    the agi hash list: sector size
+ *    the unlinked inode: inode size
+ */
+STATIC uint
+xfs_calc_iunlink_add_reservation(xfs_mount_t *mp)
+{
+       return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+               xfs_calc_inode_res(mp, 1);
+}
+
 /*
  * For removing a directory entry we can modify:
  *    the parent directory inode: inode size
@@ -245,10 +279,11 @@ xfs_calc_remove_reservation(
        struct xfs_mount        *mp)
 {
        return XFS_DQUOT_LOGRES(mp) +
-               MAX((xfs_calc_inode_res(mp, 2) +
+               xfs_calc_iunlink_add_reservation(mp) +
+               MAX((xfs_calc_inode_res(mp, 1) +
                     xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
                                      XFS_FSB_TO_B(mp, 1))),
-                   (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
+                   (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) +
                     xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
                                      XFS_FSB_TO_B(mp, 1))));
 }
@@ -343,6 +378,20 @@ xfs_calc_create_reservation(
 
 }
 
+STATIC uint
+xfs_calc_create_tmpfile_reservation(
+       struct xfs_mount        *mp)
+{
+       uint    res = XFS_DQUOT_LOGRES(mp);
+
+       if (xfs_sb_version_hascrc(&mp->m_sb))
+               res += xfs_calc_icreate_resv_alloc(mp);
+       else
+               res += xfs_calc_create_resv_alloc(mp);
+
+       return res + xfs_calc_iunlink_add_reservation(mp);
+}
+
 /*
  * Making a new directory is the same as creating a new file.
  */
@@ -383,9 +432,9 @@ xfs_calc_ifree_reservation(
 {
        return XFS_DQUOT_LOGRES(mp) +
                xfs_calc_inode_res(mp, 1) +
-               xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+               xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
                xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
-               max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size) +
+               xfs_calc_iunlink_remove_reservation(mp) +
                xfs_calc_buf_res(1, 0) +
                xfs_calc_buf_res(2 + mp->m_ialloc_blks +
                                 mp->m_in_maxlevels, 0) +
@@ -644,15 +693,14 @@ xfs_calc_qm_setqlim_reservation(
 
 /*
  * Allocating quota on disk if needed.
- *     the write transaction log space: M_RES(mp)->tr_write.tr_logres
+ *     the write transaction log space for quota file extent allocation
  *     the unit of quota allocation: one system block size
  */
 STATIC uint
 xfs_calc_qm_dqalloc_reservation(
        struct xfs_mount        *mp)
 {
-       ASSERT(M_RES(mp)->tr_write.tr_logres);
-       return M_RES(mp)->tr_write.tr_logres +
+       return xfs_calc_write_reservation(mp) +
                xfs_calc_buf_res(1,
                        XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1);
 }
@@ -729,6 +777,11 @@ xfs_trans_resv_calc(
        resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT;
        resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
 
+       resp->tr_create_tmpfile.tr_logres =
+                       xfs_calc_create_tmpfile_reservation(mp);
+       resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT;
+       resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
        resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp);
        resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT;
        resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
@@ -784,7 +837,6 @@ xfs_trans_resv_calc(
        /* The following transaction are logged in logical format */
        resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp);
        resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp);
-       resp->tr_swrite.tr_logres = xfs_calc_swrite_reservation(mp);
        resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp);
        resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp);
        resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp);
index de7de9aaad8a7bef18a18ca54ecc2a909d0ef466..1097d14cd583f974559b33c170467220c8cae2c7 100644 (file)
@@ -38,11 +38,11 @@ struct xfs_trans_resv {
        struct xfs_trans_res    tr_remove;      /* unlink trans */
        struct xfs_trans_res    tr_symlink;     /* symlink trans */
        struct xfs_trans_res    tr_create;      /* create trans */
+       struct xfs_trans_res    tr_create_tmpfile; /* create O_TMPFILE trans */
        struct xfs_trans_res    tr_mkdir;       /* mkdir trans */
        struct xfs_trans_res    tr_ifree;       /* inode free trans */
        struct xfs_trans_res    tr_ichange;     /* inode update trans */
        struct xfs_trans_res    tr_growdata;    /* fs data section grow trans */
-       struct xfs_trans_res    tr_swrite;      /* sync write inode trans */
        struct xfs_trans_res    tr_addafork;    /* add inode attr fork trans */
        struct xfs_trans_res    tr_writeid;     /* write setuid/setgid file */
        struct xfs_trans_res    tr_attrinval;   /* attr fork buffer
@@ -100,6 +100,7 @@ struct xfs_trans_resv {
 #define        XFS_ITRUNCATE_LOG_COUNT         2
 #define XFS_INACTIVE_LOG_COUNT         2
 #define        XFS_CREATE_LOG_COUNT            2
+#define        XFS_CREATE_TMPFILE_LOG_COUNT    2
 #define        XFS_MKDIR_LOG_COUNT             3
 #define        XFS_SYMLINK_LOG_COUNT           3
 #define        XFS_REMOVE_LOG_COUNT            2
index f3372441e3a5269d8f9d593a5917df9e5ce04368..c8adad9c6b6a73e7d9834c5e19bc988b51b5dfa8 100644 (file)
@@ -424,7 +424,8 @@ enum acpi_dmar_type {
        ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
        ACPI_DMAR_TYPE_ATSR = 2,
        ACPI_DMAR_HARDWARE_AFFINITY = 3,
-       ACPI_DMAR_TYPE_RESERVED = 4     /* 4 and greater are reserved */
+       ACPI_DMAR_TYPE_ANDD = 4,
+       ACPI_DMAR_TYPE_RESERVED = 5     /* 5 and greater are reserved */
 };
 
 /* DMAR Device Scope structure */
@@ -445,7 +446,8 @@ enum acpi_dmar_scope_type {
        ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
        ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
        ACPI_DMAR_SCOPE_TYPE_HPET = 4,
-       ACPI_DMAR_SCOPE_TYPE_RESERVED = 5       /* 5 and greater are reserved */
+       ACPI_DMAR_SCOPE_TYPE_ACPI = 5,
+       ACPI_DMAR_SCOPE_TYPE_RESERVED = 6       /* 6 and greater are reserved */
 };
 
 struct acpi_dmar_pci_path {
@@ -507,6 +509,15 @@ struct acpi_dmar_rhsa {
        u32 proximity_domain;
 };
 
+/* 4: ACPI Namespace Device Declaration Structure */
+
+struct acpi_dmar_andd {
+       struct acpi_dmar_header header;
+       u8 reserved[3];
+       u8 device_number;
+       u8 object_name[];
+};
+
 /*******************************************************************************
  *
  * HPET - High Precision Event Timer table
index f10f64fcc8159554a9f270ace2b661207c3e339d..146e4fffd710cadeee498228c0a1ff1c498c32e2 100644 (file)
 #define RESERVEDMEM_OF_TABLES()
 #endif
 
+#ifdef CONFIG_SMP
+#define CPU_METHOD_OF_TABLES() . = ALIGN(8);                               \
+                          VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
+                          *(__cpu_method_of_table)                         \
+                          VMLINUX_SYMBOL(__cpu_method_of_table_end) = .;
+#else
+#define CPU_METHOD_OF_TABLES()
+#endif
+
 #define KERNEL_DTB()                                                   \
        STRUCT_ALIGN();                                                 \
        VMLINUX_SYMBOL(__dtb_start) = .;                                \
        CLK_OF_TABLES()                                                 \
        RESERVEDMEM_OF_TABLES()                                         \
        CLKSRC_OF_TABLES()                                              \
+       CPU_METHOD_OF_TABLES()                                          \
        KERNEL_DTB()                                                    \
        IRQCHIP_OF_MATCH_TABLE()
 
diff --git a/include/dt-bindings/clk/exynos-audss-clk.h b/include/dt-bindings/clk/exynos-audss-clk.h
deleted file mode 100644 (file)
index 0ae6f5a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This header provides constants for Samsung audio subsystem
- * clock controller.
- *
- * The constants defined in this header are being used in dts
- * and exynos audss driver.
- */
-
-#ifndef _DT_BINDINGS_CLK_EXYNOS_AUDSS_H
-#define _DT_BINDINGS_CLK_EXYNOS_AUDSS_H
-
-#define EXYNOS_MOUT_AUDSS      0
-#define EXYNOS_MOUT_I2S        1
-#define EXYNOS_DOUT_SRP        2
-#define EXYNOS_DOUT_AUD_BUS    3
-#define EXYNOS_DOUT_I2S        4
-#define EXYNOS_SRP_CLK         5
-#define EXYNOS_I2S_BUS         6
-#define EXYNOS_SCLK_I2S        7
-#define EXYNOS_PCM_BUS         8
-#define EXYNOS_SCLK_PCM        9
-#define EXYNOS_ADMA            10
-
-#define EXYNOS_AUDSS_MAX_CLKS  11
-
-#endif
diff --git a/include/dt-bindings/clock/bcm281xx.h b/include/dt-bindings/clock/bcm281xx.h
new file mode 100644 (file)
index 0000000..e009694
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ * Copyright 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CLOCK_BCM281XX_H
+#define _CLOCK_BCM281XX_H
+
+/*
+ * This file defines the values used to specify clocks provided by
+ * the clock control units (CCUs) on Broadcom BCM281XX family SoCs.
+ */
+
+/* root CCU clock ids */
+
+#define BCM281XX_ROOT_CCU_FRAC_1M              0
+#define BCM281XX_ROOT_CCU_CLOCK_COUNT          1
+
+/* aon CCU clock ids */
+
+#define BCM281XX_AON_CCU_HUB_TIMER             0
+#define BCM281XX_AON_CCU_PMU_BSC               1
+#define BCM281XX_AON_CCU_PMU_BSC_VAR           2
+#define BCM281XX_AON_CCU_CLOCK_COUNT           3
+
+/* hub CCU clock ids */
+
+#define BCM281XX_HUB_CCU_TMON_1M               0
+#define BCM281XX_HUB_CCU_CLOCK_COUNT           1
+
+/* master CCU clock ids */
+
+#define BCM281XX_MASTER_CCU_SDIO1              0
+#define BCM281XX_MASTER_CCU_SDIO2              1
+#define BCM281XX_MASTER_CCU_SDIO3              2
+#define BCM281XX_MASTER_CCU_SDIO4              3
+#define BCM281XX_MASTER_CCU_USB_IC             4
+#define BCM281XX_MASTER_CCU_HSIC2_48M          5
+#define BCM281XX_MASTER_CCU_HSIC2_12M          6
+#define BCM281XX_MASTER_CCU_CLOCK_COUNT                7
+
+/* slave CCU clock ids */
+
+#define BCM281XX_SLAVE_CCU_UARTB               0
+#define BCM281XX_SLAVE_CCU_UARTB2              1
+#define BCM281XX_SLAVE_CCU_UARTB3              2
+#define BCM281XX_SLAVE_CCU_UARTB4              3
+#define BCM281XX_SLAVE_CCU_SSP0                        4
+#define BCM281XX_SLAVE_CCU_SSP2                        5
+#define BCM281XX_SLAVE_CCU_BSC1                        6
+#define BCM281XX_SLAVE_CCU_BSC2                        7
+#define BCM281XX_SLAVE_CCU_BSC3                        8
+#define BCM281XX_SLAVE_CCU_PWM                 9
+#define BCM281XX_SLAVE_CCU_CLOCK_COUNT         10
+
+#endif /* _CLOCK_BCM281XX_H */
diff --git a/include/dt-bindings/clock/exynos-audss-clk.h b/include/dt-bindings/clock/exynos-audss-clk.h
new file mode 100644 (file)
index 0000000..0ae6f5a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * This header provides constants for Samsung audio subsystem
+ * clock controller.
+ *
+ * The constants defined in this header are being used in dts
+ * and exynos audss driver.
+ */
+
+#ifndef _DT_BINDINGS_CLK_EXYNOS_AUDSS_H
+#define _DT_BINDINGS_CLK_EXYNOS_AUDSS_H
+
+#define EXYNOS_MOUT_AUDSS      0
+#define EXYNOS_MOUT_I2S        1
+#define EXYNOS_DOUT_SRP        2
+#define EXYNOS_DOUT_AUD_BUS    3
+#define EXYNOS_DOUT_I2S        4
+#define EXYNOS_SRP_CLK         5
+#define EXYNOS_I2S_BUS         6
+#define EXYNOS_SCLK_I2S        7
+#define EXYNOS_PCM_BUS         8
+#define EXYNOS_SCLK_PCM        9
+#define EXYNOS_ADMA            10
+
+#define EXYNOS_AUDSS_MAX_CLKS  11
+
+#endif
index 6eaa6a45e1100ff0a95e6f13b4c56fb8446cedea..21b9d0e2eb0cd0e018d9cb531e768ed6e849ccc3 100644 (file)
 #define HI3620_MMC_CLK3                217
 #define HI3620_MCU_CLK         218
 
+#define HI3620_SD_CIUCLK       0
+#define HI3620_MMC_CIUCLK1     1
+#define HI3620_MMC_CIUCLK2     2
+#define HI3620_MMC_CIUCLK3     3
+
 #define HI3620_NR_CLKS         219
 
 #endif /* __DTS_HI3620_CLOCK_H */
diff --git a/include/dt-bindings/clock/hip04-clock.h b/include/dt-bindings/clock/hip04-clock.h
new file mode 100644 (file)
index 0000000..695e61c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013-2014 Hisilicon Limited.
+ * Copyright (c) 2013-2014 Linaro Limited.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.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.
+ *
+ */
+
+#ifndef __DTS_HIP04_CLOCK_H
+#define __DTS_HIP04_CLOCK_H
+
+#define HIP04_NONE_CLOCK       0
+
+/* fixed rate & fixed factor clocks */
+#define HIP04_OSC50M           1
+#define HIP04_CLK_50M          2
+#define HIP04_CLK_168M         3
+
+#define HIP04_NR_CLKS          64
+
+#endif /* __DTS_HIP04_CLOCK_H */
index 859e9be511d9251b7e7033a5a9489a9091237b5f..6548a5fbcf4a4854ec3afec3c8d1be5cf19952a1 100644 (file)
@@ -46,8 +46,8 @@
 #define R8A7790_CLK_MSIOF1             8
 #define R8A7790_CLK_MSIOF3             15
 #define R8A7790_CLK_SCIFB2             16
-#define R8A7790_CLK_SYS_DMAC0          18
-#define R8A7790_CLK_SYS_DMAC1          19
+#define R8A7790_CLK_SYS_DMAC1          18
+#define R8A7790_CLK_SYS_DMAC0          19
 
 /* MSTP3 */
 #define R8A7790_CLK_TPU0               4
index eb6c366adfbaa26662a6031a8dd33e98bbb21320..9c2e4f82381e8abc7b21ac59447fefb84d5a1ea3 100644 (file)
@@ -13,6 +13,7 @@
 #define MUX_MODE5      5
 #define MUX_MODE6      6
 #define MUX_MODE7      7
+#define MUX_MODE8      8
 
 #define PULL_DISABLE           (1 << 16)
 #define PULL_UP                        (1 << 17)
diff --git a/include/dt-bindings/reset-controller/stih415-resets.h b/include/dt-bindings/reset-controller/stih415-resets.h
new file mode 100644 (file)
index 0000000..c2f8a66
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * This header provides constants for the reset controller
+ * based peripheral powerdown requests on the STMicroelectronics
+ * STiH415 SoC.
+ */
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_STIH415
+#define _DT_BINDINGS_RESET_CONTROLLER_STIH415
+
+#define STIH415_EMISS_POWERDOWN                0
+#define STIH415_NAND_POWERDOWN         1
+#define STIH415_KEYSCAN_POWERDOWN      2
+#define STIH415_USB0_POWERDOWN         3
+#define STIH415_USB1_POWERDOWN         4
+#define STIH415_USB2_POWERDOWN         5
+#define STIH415_SATA0_POWERDOWN                6
+#define STIH415_SATA1_POWERDOWN                7
+#define STIH415_PCIE_POWERDOWN         8
+
+#define STIH415_ETH0_SOFTRESET         0
+#define STIH415_ETH1_SOFTRESET         1
+#define STIH415_IRB_SOFTRESET          2
+#define STIH415_USB0_SOFTRESET         3
+#define STIH415_USB1_SOFTRESET         4
+#define STIH415_USB2_SOFTRESET         5
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_STIH415 */
diff --git a/include/dt-bindings/reset-controller/stih416-resets.h b/include/dt-bindings/reset-controller/stih416-resets.h
new file mode 100644 (file)
index 0000000..2127743
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * This header provides constants for the reset controller
+ * based peripheral powerdown requests on the STMicroelectronics
+ * STiH416 SoC.
+ */
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_STIH416
+#define _DT_BINDINGS_RESET_CONTROLLER_STIH416
+
+#define STIH416_EMISS_POWERDOWN                0
+#define STIH416_NAND_POWERDOWN         1
+#define STIH416_KEYSCAN_POWERDOWN      2
+#define STIH416_USB0_POWERDOWN         3
+#define STIH416_USB1_POWERDOWN         4
+#define STIH416_USB2_POWERDOWN         5
+#define STIH416_USB3_POWERDOWN         6
+#define STIH416_SATA0_POWERDOWN                7
+#define STIH416_SATA1_POWERDOWN                8
+#define STIH416_PCIE0_POWERDOWN                9
+#define STIH416_PCIE1_POWERDOWN                10
+
+#define STIH416_ETH0_SOFTRESET         0
+#define STIH416_ETH1_SOFTRESET         1
+#define STIH416_IRB_SOFTRESET          2
+#define STIH416_USB0_SOFTRESET         3
+#define STIH416_USB1_SOFTRESET         4
+#define STIH416_USB2_SOFTRESET         5
+#define STIH416_USB3_SOFTRESET         6
+#define STIH416_SATA0_SOFTRESET                7
+#define STIH416_SATA1_SOFTRESET                8
+#define STIH416_PCIE0_SOFTRESET                9
+#define STIH416_PCIE1_SOFTRESET                10
+#define STIH416_AUD_DAC_SOFTRESET      11
+#define STIH416_HDTVOUT_SOFTRESET      12
+#define STIH416_VTAC_M_RX_SOFTRESET    13
+#define STIH416_VTAC_A_RX_SOFTRESET    14
+#define STIH416_SYNC_HD_SOFTRESET      15
+#define STIH416_SYNC_SD_SOFTRESET      16
+#define STIH416_BLITTER_SOFTRESET      17
+#define STIH416_GPU_SOFTRESET          18
+#define STIH416_VTAC_M_TX_SOFTRESET    19
+#define STIH416_VTAC_A_TX_SOFTRESET    20
+#define STIH416_VTG_AUX_SOFTRESET      21
+#define STIH416_JPEG_DEC_SOFTRESET     22
+#define STIH416_HVA_SOFTRESET          23
+#define STIH416_COMPO_M_SOFTRESET      24
+#define STIH416_COMPO_A_SOFTRESET      25
+#define STIH416_VP8_DEC_SOFTRESET      26
+#define STIH416_VTG_MAIN_SOFTRESET     27
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_STIH416 */
index 138448f766b44fdf2939ac0eff1cad12c205240c..d12659ce550d2f160cf7a0bebdc51160b39a6c3a 100644 (file)
 #define CEPH_FEATURE_CRUSH_V2      (1ULL<<36)  /* new indep; SET_* steps */
 #define CEPH_FEATURE_EXPORT_PEER   (1ULL<<37)
 #define CEPH_FEATURE_OSD_ERASURE_CODES (1ULL<<38)
+#define CEPH_FEATURE_OSD_TMAP2OMAP (1ULL<<38)   /* overlap with EC */
+/* The process supports new-style OSDMap encoding. Monitors also use
+   this bit to determine if peers support NAK messages. */
+#define CEPH_FEATURE_OSDMAP_ENC    (1ULL<<39)
+#define CEPH_FEATURE_MDS_INLINE_DATA     (1ULL<<40)
+#define CEPH_FEATURE_CRUSH_TUNABLES3     (1ULL<<41)
+#define CEPH_FEATURE_OSD_PRIMARY_AFFINITY (1ULL<<41)  /* overlap w/ tunables3 */
 
 /*
  * The introduction of CEPH_FEATURE_OSD_SNAPMAPPER caused the feature
@@ -82,7 +89,10 @@ static inline u64 ceph_sanitize_features(u64 features)
         CEPH_FEATURE_OSDHASHPSPOOL |           \
         CEPH_FEATURE_OSD_CACHEPOOL |           \
         CEPH_FEATURE_CRUSH_V2 |                \
-        CEPH_FEATURE_EXPORT_PEER)
+        CEPH_FEATURE_EXPORT_PEER |             \
+        CEPH_FEATURE_OSDMAP_ENC |              \
+        CEPH_FEATURE_CRUSH_TUNABLES3 |         \
+        CEPH_FEATURE_OSD_PRIMARY_AFFINITY)
 
 #define CEPH_FEATURES_REQUIRED_DEFAULT   \
        (CEPH_FEATURE_NOSRCADDR |        \
index 25bfb0eff7720b459ffefa45ec035ec0229c8b1c..5f6db18d72e8845748a5b506949a1d7d1247cf06 100644 (file)
@@ -332,6 +332,7 @@ enum {
        CEPH_MDS_OP_LOOKUPHASH = 0x00102,
        CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
        CEPH_MDS_OP_LOOKUPINO  = 0x00104,
+       CEPH_MDS_OP_LOOKUPNAME = 0x00105,
 
        CEPH_MDS_OP_SETXATTR   = 0x01105,
        CEPH_MDS_OP_RMXATTR    = 0x01106,
@@ -420,8 +421,8 @@ union ceph_mds_request_args {
        struct {
                __u8 rule; /* currently fcntl or flock */
                __u8 type; /* shared, exclusive, remove*/
+               __le64 owner; /* owner of the lock */
                __le64 pid; /* process id requesting the lock */
-               __le64 pid_namespace;
                __le64 start; /* initial location to lock */
                __le64 length; /* num bytes to lock from start */
                __u8 wait; /* will caller wait for lock to become available? */
@@ -532,8 +533,8 @@ struct ceph_filelock {
        __le64 start;/* file offset to start lock at */
        __le64 length; /* num bytes to lock; 0 for all following start */
        __le64 client; /* which client holds the lock */
+       __le64 owner; /* owner the lock */
        __le64 pid; /* process id holding the lock on the client */
-       __le64 pid_namespace;
        __u8 type; /* shared lock, exclusive lock, or unlock */
 } __attribute__ ((packed));
 
index fd47e872ebcc7a35380160dbf2f83ab1563dd878..94ec69672164c9dd84b41c1ab3a7c995a761c1fc 100644 (file)
@@ -43,7 +43,7 @@ struct ceph_osd {
 };
 
 
-#define CEPH_OSD_MAX_OP        2
+#define CEPH_OSD_MAX_OP        3
 
 enum ceph_osd_data_type {
        CEPH_OSD_DATA_TYPE_NONE = 0,
@@ -76,6 +76,7 @@ struct ceph_osd_data {
 
 struct ceph_osd_req_op {
        u16 op;           /* CEPH_OSD_OP_* */
+       u32 flags;        /* CEPH_OSD_OP_FLAG_* */
        u32 payload_len;
        union {
                struct ceph_osd_data raw_data_in;
@@ -102,6 +103,10 @@ struct ceph_osd_req_op {
                        u32 timeout;
                        __u8 flag;
                } watch;
+               struct {
+                       u64 expected_object_size;
+                       u64 expected_write_size;
+               } alloc_hint;
        };
 };
 
@@ -293,6 +298,10 @@ extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req,
 extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req,
                                        unsigned int which, u16 opcode,
                                        u64 cookie, u64 version, int flag);
+extern void osd_req_op_alloc_hint_init(struct ceph_osd_request *osd_req,
+                                      unsigned int which,
+                                      u64 expected_object_size,
+                                      u64 expected_write_size);
 
 extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
                                               struct ceph_snap_context *snapc,
index 49ff69f0746bd6f28ee517ac6146716ff0e27fa5..561ea896c65701ec009fd4e860ed824a36e080de 100644 (file)
@@ -41,6 +41,18 @@ struct ceph_pg_pool_info {
        char *name;
 };
 
+static inline bool ceph_can_shift_osds(struct ceph_pg_pool_info *pool)
+{
+       switch (pool->type) {
+       case CEPH_POOL_TYPE_REP:
+               return true;
+       case CEPH_POOL_TYPE_EC:
+               return false;
+       default:
+               BUG_ON(1);
+       }
+}
+
 struct ceph_object_locator {
        s64 pool;
 };
@@ -60,8 +72,16 @@ struct ceph_object_id {
 struct ceph_pg_mapping {
        struct rb_node node;
        struct ceph_pg pgid;
-       int len;
-       int osds[];
+
+       union {
+               struct {
+                       int len;
+                       int osds[];
+               } pg_temp;
+               struct {
+                       int osd;
+               } primary_temp;
+       };
 };
 
 struct ceph_osdmap {
@@ -78,12 +98,19 @@ struct ceph_osdmap {
        struct ceph_entity_addr *osd_addr;
 
        struct rb_root pg_temp;
+       struct rb_root primary_temp;
+
+       u32 *osd_primary_affinity;
+
        struct rb_root pg_pools;
        u32 pool_max;
 
        /* the CRUSH map specifies the mapping of placement groups to
         * the list of osds that store+replicate them. */
        struct crush_map *crush;
+
+       struct mutex crush_scratch_mutex;
+       int crush_scratch_ary[CEPH_PG_MAX_SIZE * 3];
 };
 
 static inline void ceph_oid_set_name(struct ceph_object_id *oid,
@@ -110,9 +137,21 @@ static inline void ceph_oid_copy(struct ceph_object_id *dest,
        dest->name_len = src->name_len;
 }
 
+static inline int ceph_osd_exists(struct ceph_osdmap *map, int osd)
+{
+       return osd >= 0 && osd < map->max_osd &&
+              (map->osd_state[osd] & CEPH_OSD_EXISTS);
+}
+
 static inline int ceph_osd_is_up(struct ceph_osdmap *map, int osd)
 {
-       return (osd < map->max_osd) && (map->osd_state[osd] & CEPH_OSD_UP);
+       return ceph_osd_exists(map, osd) &&
+              (map->osd_state[osd] & CEPH_OSD_UP);
+}
+
+static inline int ceph_osd_is_down(struct ceph_osdmap *map, int osd)
+{
+       return !ceph_osd_is_up(map, osd);
 }
 
 static inline bool ceph_osdmap_flag(struct ceph_osdmap *map, int flag)
@@ -121,6 +160,7 @@ static inline bool ceph_osdmap_flag(struct ceph_osdmap *map, int flag)
 }
 
 extern char *ceph_osdmap_state_str(char *str, int len, int state);
+extern u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd);
 
 static inline struct ceph_entity_addr *ceph_osd_addr(struct ceph_osdmap *map,
                                                     int osd)
@@ -153,7 +193,7 @@ static inline int ceph_decode_pgid(void **p, void *end, struct ceph_pg *pgid)
        return 0;
 }
 
-extern struct ceph_osdmap *osdmap_decode(void **p, void *end);
+extern struct ceph_osdmap *ceph_osdmap_decode(void **p, void *end);
 extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                                            struct ceph_osdmap *map,
                                            struct ceph_messenger *msgr);
@@ -172,7 +212,7 @@ extern int ceph_oloc_oid_to_pg(struct ceph_osdmap *osdmap,
 
 extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap,
                               struct ceph_pg pgid,
-                              int *acting);
+                              int *osds, int *primary);
 extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap,
                                struct ceph_pg pgid);
 
index 96292df4041ba2aaebe32caa2dae5f731b4fb02c..f20e0d8a2155dc0f5d95ee248c2ed1aa56af1df1 100644 (file)
@@ -81,8 +81,9 @@ struct ceph_pg_v1 {
  */
 #define CEPH_NOPOOL  ((__u64) (-1))  /* pool id not defined */
 
-#define CEPH_PG_TYPE_REP     1
-#define CEPH_PG_TYPE_RAID4   2
+#define CEPH_POOL_TYPE_REP     1
+#define CEPH_POOL_TYPE_RAID4   2 /* never implemented */
+#define CEPH_POOL_TYPE_EC      3
 
 /*
  * stable_mod func is used to control number of placement groups.
@@ -133,6 +134,10 @@ extern const char *ceph_osd_state_name(int s);
 #define CEPH_OSD_IN  0x10000
 #define CEPH_OSD_OUT 0
 
+/* osd primary-affinity.  fixed point value: 0x10000 == baseline */
+#define CEPH_OSD_MAX_PRIMARY_AFFINITY 0x10000
+#define CEPH_OSD_DEFAULT_PRIMARY_AFFINITY 0x10000
+
 
 /*
  * osd map flag bits
@@ -227,6 +232,9 @@ enum {
        CEPH_OSD_OP_OMAPRMKEYS    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 24,
        CEPH_OSD_OP_OMAP_CMP      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 25,
 
+       /* hints */
+       CEPH_OSD_OP_SETALLOCHINT = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 35,
+
        /** multi **/
        CEPH_OSD_OP_CLONERANGE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_MULTI | 1,
        CEPH_OSD_OP_ASSERT_SRC_VERSION = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_MULTI | 2,
@@ -382,7 +390,7 @@ enum {
  */
 struct ceph_osd_op {
        __le16 op;           /* CEPH_OSD_OP_* */
-       __le32 flags;        /* CEPH_OSD_FLAG_* */
+       __le32 flags;        /* CEPH_OSD_OP_FLAG_* */
        union {
                struct {
                        __le64 offset, length;
@@ -416,6 +424,10 @@ struct ceph_osd_op {
                        __le64 offset, length;
                        __le64 src_offset;
                } __attribute__ ((packed)) clonerange;
+               struct {
+                       __le64 expected_object_size;
+                       __le64 expected_write_size;
+               } __attribute__ ((packed)) alloc_hint;
        };
        __le32 payload_len;
 } __attribute__ ((packed));
index 939533da93a7355be0a40422627090f1aad751b2..511917416fb003bd27ba5817fb6c8ee1af8cf498 100644 (file)
@@ -32,6 +32,7 @@
 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
 
 struct clk_hw;
+struct dentry;
 
 /**
  * struct clk_ops -  Callback operations for hardware clocks; these are to
@@ -127,6 +128,12 @@ struct clk_hw;
  *             separately via calls to .set_parent and .set_rate.
  *             Returns 0 on success, -EERROR otherwise.
  *
+ * @debug_init:        Set up type-specific debugfs entries for this clock.  This
+ *             is called once, after the debugfs directory entry for this
+ *             clock has been created.  The dentry pointer representing that
+ *             directory is provided as an argument.  Called with
+ *             prepare_lock held.  Returns 0 on success, -EERROR otherwise.
+ *
  *
  * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
  * implementations to split any work between atomic (enable) and sleepable
@@ -165,6 +172,7 @@ struct clk_ops {
        unsigned long   (*recalc_accuracy)(struct clk_hw *hw,
                                           unsigned long parent_accuracy);
        void            (*init)(struct clk_hw *hw);
+       int             (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
 };
 
 /**
index 0dd91148165e4e7df78beb5582b89910c1615f26..fb5e097d8f72b07fb34e480bb817593284dccdd2 100644 (file)
@@ -78,8 +78,22 @@ struct clk_notifier_data {
        unsigned long           new_rate;
 };
 
+/**
+ * clk_notifier_register: register a clock rate-change notifier callback
+ * @clk: clock whose rate we are interested in
+ * @nb: notifier block with callback function pointer
+ *
+ * ProTip: debugging across notifier chains can be frustrating. Make sure that
+ * your notifier callback function prints a nice big warning in case of
+ * failure.
+ */
 int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
 
+/**
+ * clk_notifier_unregister: unregister a clock rate-change notifier callback
+ * @clk: clock whose rate we are no longer interested in
+ * @nb: notifier block which will be unregistered
+ */
 int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
 
 /**
index e062d317cccea96d5e6f6c236fc2cec8ef3108a1..7a5633b71533932c54bc69a22d33d503b8d6e772 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <linux/spinlock.h>
 
-void zynq_clock_init(void __iomem *slcr);
+void zynq_clock_init(void);
 
 struct clk *clk_register_zynq_pll(const char *name, const char *parent,
                void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
index 03e962e23eaf65aad5d161c528ae6a43cdc0ffed..81887120395c81347c6a74ad3c92d847f3c4c90d 100644 (file)
@@ -115,26 +115,46 @@ enum {
                { .notifier_call = fn, .priority = pri };       \
        register_cpu_notifier(&fn##_nb);                        \
 }
+
+#define __cpu_notifier(fn, pri) {                              \
+       static struct notifier_block fn##_nb =                  \
+               { .notifier_call = fn, .priority = pri };       \
+       __register_cpu_notifier(&fn##_nb);                      \
+}
 #else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
 #define cpu_notifier(fn, pri)  do { (void)(fn); } while (0)
+#define __cpu_notifier(fn, pri)        do { (void)(fn); } while (0)
 #endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
+
 #ifdef CONFIG_HOTPLUG_CPU
 extern int register_cpu_notifier(struct notifier_block *nb);
+extern int __register_cpu_notifier(struct notifier_block *nb);
 extern void unregister_cpu_notifier(struct notifier_block *nb);
+extern void __unregister_cpu_notifier(struct notifier_block *nb);
 #else
 
 #ifndef MODULE
 extern int register_cpu_notifier(struct notifier_block *nb);
+extern int __register_cpu_notifier(struct notifier_block *nb);
 #else
 static inline int register_cpu_notifier(struct notifier_block *nb)
 {
        return 0;
 }
+
+static inline int __register_cpu_notifier(struct notifier_block *nb)
+{
+       return 0;
+}
 #endif
 
 static inline void unregister_cpu_notifier(struct notifier_block *nb)
 {
 }
+
+static inline void __unregister_cpu_notifier(struct notifier_block *nb)
+{
+}
 #endif
 
 int cpu_up(unsigned int cpu);
@@ -142,19 +162,32 @@ void notify_cpu_starting(unsigned int cpu);
 extern void cpu_maps_update_begin(void);
 extern void cpu_maps_update_done(void);
 
+#define cpu_notifier_register_begin    cpu_maps_update_begin
+#define cpu_notifier_register_done     cpu_maps_update_done
+
 #else  /* CONFIG_SMP */
 
 #define cpu_notifier(fn, pri)  do { (void)(fn); } while (0)
+#define __cpu_notifier(fn, pri)        do { (void)(fn); } while (0)
 
 static inline int register_cpu_notifier(struct notifier_block *nb)
 {
        return 0;
 }
 
+static inline int __register_cpu_notifier(struct notifier_block *nb)
+{
+       return 0;
+}
+
 static inline void unregister_cpu_notifier(struct notifier_block *nb)
 {
 }
 
+static inline void __unregister_cpu_notifier(struct notifier_block *nb)
+{
+}
+
 static inline void cpu_maps_update_begin(void)
 {
 }
@@ -163,6 +196,14 @@ static inline void cpu_maps_update_done(void)
 {
 }
 
+static inline void cpu_notifier_register_begin(void)
+{
+}
+
+static inline void cpu_notifier_register_done(void)
+{
+}
+
 #endif /* CONFIG_SMP */
 extern struct bus_type cpu_subsys;
 
@@ -176,8 +217,11 @@ extern void put_online_cpus(void);
 extern void cpu_hotplug_disable(void);
 extern void cpu_hotplug_enable(void);
 #define hotcpu_notifier(fn, pri)       cpu_notifier(fn, pri)
+#define __hotcpu_notifier(fn, pri)     __cpu_notifier(fn, pri)
 #define register_hotcpu_notifier(nb)   register_cpu_notifier(nb)
+#define __register_hotcpu_notifier(nb) __register_cpu_notifier(nb)
 #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb)
+#define __unregister_hotcpu_notifier(nb)       __unregister_cpu_notifier(nb)
 void clear_tasks_mm_cpumask(int cpu);
 int cpu_down(unsigned int cpu);
 
@@ -190,9 +234,12 @@ static inline void cpu_hotplug_done(void) {}
 #define cpu_hotplug_disable()  do { } while (0)
 #define cpu_hotplug_enable()   do { } while (0)
 #define hotcpu_notifier(fn, pri)       do { (void)(fn); } while (0)
+#define __hotcpu_notifier(fn, pri)     do { (void)(fn); } while (0)
 /* These aren't inline functions due to a GCC bug. */
 #define register_hotcpu_notifier(nb)   ({ (void)(nb); 0; })
+#define __register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
 #define unregister_hotcpu_notifier(nb) ({ (void)(nb); })
+#define __unregister_hotcpu_notifier(nb)       ({ (void)(nb); })
 #endif         /* CONFIG_HOTPLUG_CPU */
 
 #ifdef CONFIG_PM_SLEEP_SMP
index acaa5615d6343906ab05e528bb10ea3e76bf0fac..4fad5f8ee01d3457974551ef1f874fc61f0524f9 100644 (file)
@@ -51,6 +51,7 @@ enum {
        CRUSH_RULE_SET_CHOOSELEAF_TRIES = 9, /* override chooseleaf_descend_once */
        CRUSH_RULE_SET_CHOOSE_LOCAL_TRIES = 10,
        CRUSH_RULE_SET_CHOOSE_LOCAL_FALLBACK_TRIES = 11,
+       CRUSH_RULE_SET_CHOOSELEAF_VARY_R = 12
 };
 
 /*
@@ -173,6 +174,12 @@ struct crush_map {
         * apply to a collision: in that case we will retry as we used
         * to. */
        __u32 chooseleaf_descend_once;
+
+       /* if non-zero, feed r into chooseleaf, bit-shifted right by (r-1)
+        * bits.  a value of 1 is best for new clusters.  for legacy clusters
+        * that want to limit reshuffling, a value of 3 or 4 will make the
+        * mappings line up a bit better with previous mappings. */
+       __u8 chooseleaf_vary_r;
 };
 
 
index bf72e9ac6de01d1b1783b0b4adfd441c9c9ac58c..3b9bfdb83ba6f698cbe1ddf8409f8b6e0dc17427 100644 (file)
@@ -308,6 +308,7 @@ extern void dentry_update_name_case(struct dentry *, struct qstr *);
 
 /* used for rename() and baskets */
 extern void d_move(struct dentry *, struct dentry *);
+extern void d_exchange(struct dentry *, struct dentry *);
 extern struct dentry *d_ancestor(struct dentry *, struct dentry *);
 
 /* appendix may either be NULL or be used for transname suffixes */
@@ -429,7 +430,7 @@ static inline unsigned __d_entry_type(const struct dentry *dentry)
        return dentry->d_flags & DCACHE_ENTRY_TYPE;
 }
 
-static inline bool d_is_directory(const struct dentry *dentry)
+static inline bool d_can_lookup(const struct dentry *dentry)
 {
        return __d_entry_type(dentry) == DCACHE_DIRECTORY_TYPE;
 }
@@ -439,6 +440,11 @@ static inline bool d_is_autodir(const struct dentry *dentry)
        return __d_entry_type(dentry) == DCACHE_AUTODIR_TYPE;
 }
 
+static inline bool d_is_dir(const struct dentry *dentry)
+{
+       return d_can_lookup(dentry) || d_is_autodir(dentry);
+}
+
 static inline bool d_is_symlink(const struct dentry *dentry)
 {
        return __d_entry_type(dentry) == DCACHE_SYMLINK_TYPE;
index ed419c62dde1876f4561179b6b4bc3052a50ed14..63da56ed979620b5fb8275f847fafb9e8e5212ba 100644 (file)
@@ -23,7 +23,6 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
 
 union map_info {
        void *ptr;
-       unsigned long long ll;
 };
 
 /*
@@ -291,7 +290,6 @@ struct dm_target_callbacks {
 struct dm_target_io {
        struct dm_io *io;
        struct dm_target *ti;
-       union map_info info;
        unsigned target_bio_nr;
        struct bio clone;
 };
@@ -403,7 +401,6 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid);
 struct gendisk *dm_disk(struct mapped_device *md);
 int dm_suspended(struct dm_target *ti);
 int dm_noflush_suspending(struct dm_target *ti);
-union map_info *dm_get_mapinfo(struct bio *bio);
 union map_info *dm_get_rq_mapinfo(struct request *rq);
 
 struct queue_limits *dm_get_queue_limits(struct mapped_device *md);
@@ -465,6 +462,11 @@ struct mapped_device *dm_table_get_md(struct dm_table *t);
  */
 void dm_table_event(struct dm_table *t);
 
+/*
+ * Run the queue for request-based targets.
+ */
+void dm_table_run_md_queue_async(struct dm_table *t);
+
 /*
  * The device must be suspended before calling this method.
  * Returns the previous table, which the caller must destroy.
index eccb0c0c6cf633c35e7a0ebfd5b9b5511a19bf39..23c8db129560c6b1b2646aae1068702ef643f3fb 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/types.h>
 #include <linux/msi.h>
 #include <linux/irqreturn.h>
+#include <linux/rwsem.h>
+#include <linux/rcupdate.h>
 
 struct acpi_dmar_header;
 
@@ -34,13 +36,19 @@ struct acpi_dmar_header;
 
 struct intel_iommu;
 
+struct dmar_dev_scope {
+       struct device __rcu *dev;
+       u8 bus;
+       u8 devfn;
+};
+
 #ifdef CONFIG_DMAR_TABLE
 extern struct acpi_table_header *dmar_tbl;
 struct dmar_drhd_unit {
        struct list_head list;          /* list of drhd units   */
        struct  acpi_dmar_header *hdr;  /* ACPI header          */
        u64     reg_base_addr;          /* register base address*/
-       struct  pci_dev **devices;      /* target device array  */
+       struct  dmar_dev_scope *devices;/* target device array  */
        int     devices_cnt;            /* target device count  */
        u16     segment;                /* PCI domain           */
        u8      ignored:1;              /* ignore drhd          */
@@ -48,33 +56,66 @@ struct dmar_drhd_unit {
        struct intel_iommu *iommu;
 };
 
+struct dmar_pci_notify_info {
+       struct pci_dev                  *dev;
+       unsigned long                   event;
+       int                             bus;
+       u16                             seg;
+       u16                             level;
+       struct acpi_dmar_pci_path       path[];
+}  __attribute__((packed));
+
+extern struct rw_semaphore dmar_global_lock;
 extern struct list_head dmar_drhd_units;
 
 #define for_each_drhd_unit(drhd) \
-       list_for_each_entry(drhd, &dmar_drhd_units, list)
+       list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)
 
 #define for_each_active_drhd_unit(drhd)                                        \
-       list_for_each_entry(drhd, &dmar_drhd_units, list)               \
+       list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)           \
                if (drhd->ignored) {} else
 
 #define for_each_active_iommu(i, drhd)                                 \
-       list_for_each_entry(drhd, &dmar_drhd_units, list)               \
+       list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)           \
                if (i=drhd->iommu, drhd->ignored) {} else
 
 #define for_each_iommu(i, drhd)                                                \
-       list_for_each_entry(drhd, &dmar_drhd_units, list)               \
+       list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)           \
                if (i=drhd->iommu, 0) {} else 
 
+static inline bool dmar_rcu_check(void)
+{
+       return rwsem_is_locked(&dmar_global_lock) ||
+              system_state == SYSTEM_BOOTING;
+}
+
+#define        dmar_rcu_dereference(p) rcu_dereference_check((p), dmar_rcu_check())
+
+#define        for_each_dev_scope(a, c, p, d)  \
+       for ((p) = 0; ((d) = (p) < (c) ? dmar_rcu_dereference((a)[(p)].dev) : \
+                       NULL, (p) < (c)); (p)++)
+
+#define        for_each_active_dev_scope(a, c, p, d)   \
+       for_each_dev_scope((a), (c), (p), (d))  if (!(d)) { continue; } else
+
 extern int dmar_table_init(void);
 extern int dmar_dev_scope_init(void);
 extern int dmar_parse_dev_scope(void *start, void *end, int *cnt,
-                               struct pci_dev ***devices, u16 segment);
-extern void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt);
-
+                               struct dmar_dev_scope **devices, u16 segment);
+extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt);
+extern void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt);
+extern int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
+                                void *start, void*end, u16 segment,
+                                struct dmar_dev_scope *devices,
+                                int devices_cnt);
+extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info,
+                                u16 segment, struct dmar_dev_scope *devices,
+                                int count);
 /* Intel IOMMU detection */
 extern int detect_intel_iommu(void);
 extern int enable_drhd_fault_handling(void);
 #else
+struct dmar_pci_notify_info;
 static inline int detect_intel_iommu(void)
 {
        return -ENODEV;
@@ -138,30 +179,9 @@ extern int arch_setup_dmar_msi(unsigned int irq);
 
 #ifdef CONFIG_INTEL_IOMMU
 extern int iommu_detected, no_iommu;
-extern struct list_head dmar_rmrr_units;
-struct dmar_rmrr_unit {
-       struct list_head list;          /* list of rmrr units   */
-       struct acpi_dmar_header *hdr;   /* ACPI header          */
-       u64     base_address;           /* reserved base address*/
-       u64     end_address;            /* reserved end address */
-       struct pci_dev **devices;       /* target devices */
-       int     devices_cnt;            /* target device count */
-};
-
-#define for_each_rmrr_units(rmrr) \
-       list_for_each_entry(rmrr, &dmar_rmrr_units, list)
-
-struct dmar_atsr_unit {
-       struct list_head list;          /* list of ATSR units */
-       struct acpi_dmar_header *hdr;   /* ACPI header */
-       struct pci_dev **devices;       /* target devices */
-       int devices_cnt;                /* target device count */
-       u8 include_all:1;               /* include all ports */
-};
-
-int dmar_parse_rmrr_atsr_dev(void);
 extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header);
 extern int dmar_parse_one_atsr(struct acpi_dmar_header *header);
+extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info);
 extern int intel_iommu_init(void);
 #else /* !CONFIG_INTEL_IOMMU: */
 static inline int intel_iommu_init(void) { return -ENODEV; }
@@ -173,7 +193,7 @@ static inline int dmar_parse_one_atsr(struct acpi_dmar_header *header)
 {
        return 0;
 }
-static inline int dmar_parse_rmrr_atsr_dev(void)
+static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
 {
        return 0;
 }
index da74d878dc4f87ab64faba5981b8ad8edc6dbda6..df53e1753a76bffe0ff8fefa8c5a2a0ab8ad0790 100644 (file)
@@ -183,7 +183,7 @@ struct f2fs_inode {
        __le32 i_pino;                  /* parent inode number */
        __le32 i_namelen;               /* file name length */
        __u8 i_name[F2FS_NAME_LEN];     /* file name for SPOR */
-       __u8 i_reserved2;               /* for backward compatibility */
+       __u8 i_dir_level;               /* dentry_level for large dir */
 
        struct f2fs_extent i_ext;       /* caching a largest extent */
 
index 3ca9420f627eb9c860f8f0c1f29a7dcdfd9a8982..81048f9bc7837e3ce32fb12dddf158a09fbaf302 100644 (file)
@@ -893,6 +893,7 @@ static inline int file_check_writeable(struct file *filp)
 #define FL_SLEEP       128     /* A blocking lock */
 #define FL_DOWNGRADE_PENDING   256 /* Lease is being downgraded */
 #define FL_UNLOCK_PENDING      512 /* Lease is being broken */
+#define FL_FILE_PVT    1024    /* lock is private to the file */
 
 /*
  * Special return value from posix_lock_file() and vfs_lock_file() for
@@ -997,12 +998,12 @@ struct file_lock {
 extern void send_sigio(struct fown_struct *fown, int fd, int band);
 
 #ifdef CONFIG_FILE_LOCKING
-extern int fcntl_getlk(struct file *, struct flock __user *);
+extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *);
 extern int fcntl_setlk(unsigned int, struct file *, unsigned int,
                        struct flock __user *);
 
 #if BITS_PER_LONG == 32
-extern int fcntl_getlk64(struct file *, struct flock64 __user *);
+extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 __user *);
 extern int fcntl_setlk64(unsigned int, struct file *, unsigned int,
                        struct flock64 __user *);
 #endif
@@ -1017,7 +1018,7 @@ extern struct file_lock * locks_alloc_lock(void);
 extern void locks_copy_lock(struct file_lock *, struct file_lock *);
 extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
 extern void locks_remove_posix(struct file *, fl_owner_t);
-extern void locks_remove_flock(struct file *);
+extern void locks_remove_file(struct file *);
 extern void locks_release_private(struct file_lock *);
 extern void posix_test_lock(struct file *, struct file_lock *);
 extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
@@ -1035,7 +1036,8 @@ extern int lease_modify(struct file_lock **, int);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
 extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
 #else /* !CONFIG_FILE_LOCKING */
-static inline int fcntl_getlk(struct file *file, struct flock __user *user)
+static inline int fcntl_getlk(struct file *file, unsigned int cmd,
+                             struct flock __user *user)
 {
        return -EINVAL;
 }
@@ -1047,7 +1049,8 @@ static inline int fcntl_setlk(unsigned int fd, struct file *file,
 }
 
 #if BITS_PER_LONG == 32
-static inline int fcntl_getlk64(struct file *file, struct flock64 __user *user)
+static inline int fcntl_getlk64(struct file *file, unsigned int cmd,
+                               struct flock64 __user *user)
 {
        return -EINVAL;
 }
@@ -1088,7 +1091,7 @@ static inline void locks_remove_posix(struct file *filp, fl_owner_t owner)
        return;
 }
 
-static inline void locks_remove_flock(struct file *filp)
+static inline void locks_remove_file(struct file *filp)
 {
        return;
 }
@@ -1461,7 +1464,7 @@ extern int vfs_symlink(struct inode *, struct dentry *, const char *);
 extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **);
 extern int vfs_rmdir(struct inode *, struct dentry *);
 extern int vfs_unlink(struct inode *, struct dentry *, struct inode **);
-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **);
+extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int);
 
 /*
  * VFS dentry helper functions.
@@ -1572,6 +1575,8 @@ struct inode_operations {
        int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
+       int (*rename2) (struct inode *, struct dentry *,
+                       struct inode *, struct dentry *, unsigned int);
        int (*setattr) (struct dentry *, struct iattr *);
        int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
        int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1914,6 +1919,11 @@ extern int current_umask(void);
 extern void ihold(struct inode * inode);
 extern void iput(struct inode *);
 
+static inline struct inode *file_inode(struct file *f)
+{
+       return f->f_inode;
+}
+
 /* /sys/fs */
 extern struct kobject *fs_kobj;
 
@@ -1923,7 +1933,7 @@ extern struct kobject *fs_kobj;
 #define FLOCK_VERIFY_WRITE 2
 
 #ifdef CONFIG_FILE_LOCKING
-extern int locks_mandatory_locked(struct inode *);
+extern int locks_mandatory_locked(struct file *);
 extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
 
 /*
@@ -1946,10 +1956,10 @@ static inline int mandatory_lock(struct inode *ino)
        return IS_MANDLOCK(ino) && __mandatory_lock(ino);
 }
 
-static inline int locks_verify_locked(struct inode *inode)
+static inline int locks_verify_locked(struct file *file)
 {
-       if (mandatory_lock(inode))
-               return locks_mandatory_locked(inode);
+       if (mandatory_lock(file_inode(file)))
+               return locks_mandatory_locked(file);
        return 0;
 }
 
@@ -1969,6 +1979,12 @@ static inline int locks_verify_truncate(struct inode *inode,
 
 static inline int break_lease(struct inode *inode, unsigned int mode)
 {
+       /*
+        * Since this check is lockless, we must ensure that any refcounts
+        * taken are done before checking inode->i_flock. Otherwise, we could
+        * end up racing with tasks trying to set a new lease on this file.
+        */
+       smp_mb();
        if (inode->i_flock)
                return __break_lease(inode, mode, FL_LEASE);
        return 0;
@@ -2004,7 +2020,7 @@ static inline int break_deleg_wait(struct inode **delegated_inode)
 }
 
 #else /* !CONFIG_FILE_LOCKING */
-static inline int locks_mandatory_locked(struct inode *inode)
+static inline int locks_mandatory_locked(struct file *file)
 {
        return 0;
 }
@@ -2026,7 +2042,7 @@ static inline int mandatory_lock(struct inode *inode)
        return 0;
 }
 
-static inline int locks_verify_locked(struct inode *inode)
+static inline int locks_verify_locked(struct file *file)
 {
        return 0;
 }
@@ -2300,11 +2316,6 @@ static inline bool execute_ok(struct inode *inode)
        return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
 }
 
-static inline struct inode *file_inode(struct file *f)
-{
-       return f->f_inode;
-}
-
 static inline void file_start_write(struct file *file)
 {
        if (!S_ISREG(file_inode(file)->i_mode))
@@ -2539,6 +2550,9 @@ enum {
 
        /* filesystem does not support filling holes */
        DIO_SKIP_HOLES  = 0x02,
+
+       /* filesystem can handle aio writes beyond i_size */
+       DIO_ASYNC_EXTEND = 0x04,
 };
 
 void dio_end_io(struct bio *bio, int error);
@@ -2561,6 +2575,9 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
 void inode_dio_wait(struct inode *inode);
 void inode_dio_done(struct inode *inode);
 
+extern void inode_set_flags(struct inode *inode, unsigned int flags,
+                           unsigned int mask);
+
 extern const struct file_operations generic_ro_fops;
 
 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
index ade1c06d4cebed9c30b47ea98c69fe51df89508c..d2b16704624c6c6122a09457e00ef716ef8d0393 100644 (file)
@@ -195,6 +195,18 @@ static inline int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg) {
        return twl_i2c_read(mod_no, val, reg, 1);
 }
 
+static inline int twl_i2c_write_u16(u8 mod_no, u16 val, u8 reg) {
+       val = cpu_to_le16(val);
+       return twl_i2c_write(mod_no, (u8*) &val, reg, 2);
+}
+
+static inline int twl_i2c_read_u16(u8 mod_no, u16 *val, u8 reg) {
+       int ret;
+       ret = twl_i2c_read(mod_no, (u8*) val, reg, 2);
+       *val = le16_to_cpu(*val);
+       return ret;
+}
+
 int twl_get_type(void);
 int twl_get_version(void);
 int twl_get_hfclk_rate(void);
index 01f5951070489c0a48eeacc290b4428c203ed852..1c0134dd32718f1561c3ced6704f6b65edcad817 100644 (file)
@@ -44,7 +44,7 @@ struct twl4030_madc_conversion_method {
 
 struct twl4030_madc_request {
        unsigned long channels;
-       u16 do_avg;
+       bool do_avg;
        u16 method;
        u16 type;
        bool active;
index 2c4bed593b32367559cc2aff89e40b88306bab90..0a2da518821706baf5345e76e1490c55953a9f8f 100644 (file)
@@ -319,6 +319,7 @@ struct intel_iommu {
        int             agaw; /* agaw of this iommu */
        int             msagaw; /* max sagaw of this iommu */
        unsigned int    irq;
+       u16             segment;     /* PCI segment# */
        unsigned char   name[13];    /* Device Name */
 
 #ifdef CONFIG_INTEL_IOMMU
index 76a0759e88ec4650fe554ddb1988bbeff99dfc26..3277f4711349570745822d86152725c3eeaba24c 100644 (file)
@@ -47,5 +47,7 @@ void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
 void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit);
 struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
 void put_iova_domain(struct iova_domain *iovad);
+struct iova *split_and_remove_iova(struct iova_domain *iovad,
+       struct iova *iova, unsigned long pfn_lo, unsigned long pfn_hi);
 
 #endif
index 0ceb389dba6c4136ecf718f661ede11ea9e271ab..7ed92d0560d59de9f4db4eab3d9940312807c417 100644 (file)
@@ -93,6 +93,11 @@ int gic_get_cpu_id(unsigned int cpu);
 void gic_migrate_target(unsigned int new_cpu_id);
 unsigned long gic_get_sgir_physaddr(void);
 
+extern const struct irq_domain_ops *gic_routable_irq_domain_ops;
+static inline void __init register_routable_domain_ops
+                                       (const struct irq_domain_ops *ops)
+{
+       gic_routable_irq_domain_ops = ops;
+}
 #endif /* __ASSEMBLY */
-
 #endif
index e3c82dc95756c4efb71a907c663ecf1d93cd7618..ba46c794b4e5772cc0bbdea36915960d5315f13a 100644 (file)
 struct device_node;
 struct pt_regs;
 
-void __vic_init(void __iomem *base, int irq_start, u32 vic_sources,
-               u32 resume_sources, struct device_node *node);
+void __vic_init(void __iomem *base, int parent_irq, int irq_start,
+               u32 vic_sources, u32 resume_sources, struct device_node *node);
 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
+int vic_init_cascaded(void __iomem *base, unsigned int parent_irq,
+                     u32 vic_sources, u32 resume_sources);
 
 #endif
diff --git a/include/linux/irqchip/irq-crossbar.h b/include/linux/irqchip/irq-crossbar.h
new file mode 100644 (file)
index 0000000..e5537b8
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ *  drivers/irqchip/irq-crossbar.h
+ *
+ *  Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+int irqcrossbar_init(void);
index e2d28b026a8ca3fb362341decd8f1a6f64904ea5..3c77bf9b1efd03384d0c5527ce93431762252f65 100644 (file)
 #define ISAPNP_DEVICE_ID(_va, _vb, _vc, _function) \
                { .vendor = ISAPNP_VENDOR(_va, _vb, _vc), .function = ISAPNP_FUNCTION(_function) }
 
-/* export used IDs outside module */
-#define ISAPNP_CARD_TABLE(name) \
-               MODULE_GENERIC_TABLE(isapnp_card, name)
-
 struct isapnp_card_id {
        unsigned long driver_data;      /* data private to the driver */
        unsigned short card_vendor, card_device;
index 08fb0247764177a8b96f83f5181a17c9d33b099c..4c52907a6d8b54d41fbd63cc1839f159c0ed5207 100644 (file)
@@ -469,6 +469,7 @@ extern enum system_states {
 #define TAINT_CRAP                     10
 #define TAINT_FIRMWARE_WORKAROUND      11
 #define TAINT_OOT_MODULE               12
+#define TAINT_UNSIGNED_MODULE          13
 
 extern const char hex_asc[];
 #define hex_asc_lo(x)  hex_asc[((x) & 0x0f)]
@@ -841,4 +842,12 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
 #endif
 
+/* Permissions on a sysfs file: you didn't miss the 0 prefix did you? */
+#define VERIFY_OCTAL_PERMISSIONS(perms)                                        \
+       (BUILD_BUG_ON_ZERO((perms) < 0) +                               \
+        BUILD_BUG_ON_ZERO((perms) > 0777) +                            \
+        /* User perms >= group perms >= other perms */                 \
+        BUILD_BUG_ON_ZERO(((perms) >> 6) < (((perms) >> 3) & 7)) +     \
+        BUILD_BUG_ON_ZERO((((perms) >> 3) & 7) < ((perms) & 7)) +      \
+        (perms))
 #endif
index 5525d370701db049e176456292cdb725366d59f7..6a392e7a723a46d4c6f00715e81b21cbcaac1007 100644 (file)
@@ -3,19 +3,21 @@
 
   (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
 */
-
 struct mb_cache_entry {
        struct list_head                e_lru_list;
        struct mb_cache                 *e_cache;
        unsigned short                  e_used;
        unsigned short                  e_queued;
+       atomic_t                        e_refcnt;
        struct block_device             *e_bdev;
        sector_t                        e_block;
-       struct list_head                e_block_list;
+       struct hlist_bl_node            e_block_list;
        struct {
-               struct list_head        o_list;
+               struct hlist_bl_node    o_list;
                unsigned int            o_key;
        } e_index;
+       struct hlist_bl_head            *e_block_hash_p;
+       struct hlist_bl_head            *e_index_hash_p;
 };
 
 struct mb_cache {
@@ -25,8 +27,8 @@ struct mb_cache {
        int                             c_max_entries;
        int                             c_bucket_bits;
        struct kmem_cache               *c_entry_cache;
-       struct list_head                *c_block_hash;
-       struct list_head                *c_index_hash;
+       struct hlist_bl_head            *c_block_hash;
+       struct hlist_bl_head            *c_index_hash;
 };
 
 /* Functions on caches */
index 1ef66360f0b092b751f430bf31ca693a8a85ed46..8a20a51ed42d9c53c1b57153106fe33a0a61d78c 100644 (file)
@@ -252,6 +252,8 @@ static inline void memblock_dump_all(void)
 void memblock_set_current_limit(phys_addr_t limit);
 
 
+phys_addr_t memblock_get_current_limit(void);
+
 /*
  * pfn conversion functions
  *
index a86ca1406fb87ca11a656c72047b073a22c23e1b..4e7fe7417fc96daf9ffc166b26e2d1be34482c56 100644 (file)
@@ -347,7 +347,6 @@ struct ab8500 {
        struct mutex    lock;
        struct mutex    irq_lock;
        atomic_t        transfer_ongoing;
-       int             irq_base;
        int             irq;
        struct irq_domain  *domain;
        enum ab8500_version version;
@@ -378,7 +377,6 @@ struct ab8500_sysctrl_platform_data;
  * @regulator: machine-specific constraints for regulators
  */
 struct ab8500_platform_data {
-       int irq_base;
        void (*init) (struct ab8500 *);
        struct ab8500_regulator_platform_data *regulator;
        struct ab8500_codec_platform_data *codec;
index 3ddaa634b19d45102de7579169a5c50d05abe74b..7b35c21170d5938e86eda0d4541057bca0ede81b 100644 (file)
 #define ARIZONA_DSP1_STATUS_1                    0x1104
 #define ARIZONA_DSP1_STATUS_2                    0x1105
 #define ARIZONA_DSP1_STATUS_3                    0x1106
+#define ARIZONA_DSP1_STATUS_4                    0x1107
+#define ARIZONA_DSP1_WDMA_BUFFER_1               0x1110
+#define ARIZONA_DSP1_WDMA_BUFFER_2               0x1111
+#define ARIZONA_DSP1_WDMA_BUFFER_3               0x1112
+#define ARIZONA_DSP1_WDMA_BUFFER_4               0x1113
+#define ARIZONA_DSP1_WDMA_BUFFER_5               0x1114
+#define ARIZONA_DSP1_WDMA_BUFFER_6               0x1115
+#define ARIZONA_DSP1_WDMA_BUFFER_7               0x1116
+#define ARIZONA_DSP1_WDMA_BUFFER_8               0x1117
+#define ARIZONA_DSP1_RDMA_BUFFER_1               0x1120
+#define ARIZONA_DSP1_RDMA_BUFFER_2               0x1121
+#define ARIZONA_DSP1_RDMA_BUFFER_3               0x1122
+#define ARIZONA_DSP1_RDMA_BUFFER_4               0x1123
+#define ARIZONA_DSP1_RDMA_BUFFER_5               0x1124
+#define ARIZONA_DSP1_RDMA_BUFFER_6               0x1125
+#define ARIZONA_DSP1_WDMA_CONFIG_1               0x1130
+#define ARIZONA_DSP1_WDMA_CONFIG_2               0x1131
+#define ARIZONA_DSP1_WDMA_OFFSET_1               0x1132
+#define ARIZONA_DSP1_RDMA_CONFIG_1               0x1134
+#define ARIZONA_DSP1_RDMA_OFFSET_1               0x1135
+#define ARIZONA_DSP1_EXTERNAL_START_SELECT_1     0x1138
 #define ARIZONA_DSP1_SCRATCH_0                   0x1140
 #define ARIZONA_DSP1_SCRATCH_1                   0x1141
 #define ARIZONA_DSP1_SCRATCH_2                   0x1142
 #define ARIZONA_DSP2_STATUS_1                    0x1204
 #define ARIZONA_DSP2_STATUS_2                    0x1205
 #define ARIZONA_DSP2_STATUS_3                    0x1206
+#define ARIZONA_DSP2_STATUS_4                    0x1207
+#define ARIZONA_DSP2_WDMA_BUFFER_1               0x1210
+#define ARIZONA_DSP2_WDMA_BUFFER_2               0x1211
+#define ARIZONA_DSP2_WDMA_BUFFER_3               0x1212
+#define ARIZONA_DSP2_WDMA_BUFFER_4               0x1213
+#define ARIZONA_DSP2_WDMA_BUFFER_5               0x1214
+#define ARIZONA_DSP2_WDMA_BUFFER_6               0x1215
+#define ARIZONA_DSP2_WDMA_BUFFER_7               0x1216
+#define ARIZONA_DSP2_WDMA_BUFFER_8               0x1217
+#define ARIZONA_DSP2_RDMA_BUFFER_1               0x1220
+#define ARIZONA_DSP2_RDMA_BUFFER_2               0x1221
+#define ARIZONA_DSP2_RDMA_BUFFER_3               0x1222
+#define ARIZONA_DSP2_RDMA_BUFFER_4               0x1223
+#define ARIZONA_DSP2_RDMA_BUFFER_5               0x1224
+#define ARIZONA_DSP2_RDMA_BUFFER_6               0x1225
+#define ARIZONA_DSP2_WDMA_CONFIG_1               0x1230
+#define ARIZONA_DSP2_WDMA_CONFIG_2               0x1231
+#define ARIZONA_DSP2_WDMA_OFFSET_1               0x1232
+#define ARIZONA_DSP2_RDMA_CONFIG_1               0x1234
+#define ARIZONA_DSP2_RDMA_OFFSET_1               0x1235
+#define ARIZONA_DSP2_EXTERNAL_START_SELECT_1     0x1238
 #define ARIZONA_DSP2_SCRATCH_0                   0x1240
 #define ARIZONA_DSP2_SCRATCH_1                   0x1241
 #define ARIZONA_DSP2_SCRATCH_2                   0x1242
 #define ARIZONA_DSP3_STATUS_1                    0x1304
 #define ARIZONA_DSP3_STATUS_2                    0x1305
 #define ARIZONA_DSP3_STATUS_3                    0x1306
+#define ARIZONA_DSP3_STATUS_4                    0x1307
+#define ARIZONA_DSP3_WDMA_BUFFER_1               0x1310
+#define ARIZONA_DSP3_WDMA_BUFFER_2               0x1311
+#define ARIZONA_DSP3_WDMA_BUFFER_3               0x1312
+#define ARIZONA_DSP3_WDMA_BUFFER_4               0x1313
+#define ARIZONA_DSP3_WDMA_BUFFER_5               0x1314
+#define ARIZONA_DSP3_WDMA_BUFFER_6               0x1315
+#define ARIZONA_DSP3_WDMA_BUFFER_7               0x1316
+#define ARIZONA_DSP3_WDMA_BUFFER_8               0x1317
+#define ARIZONA_DSP3_RDMA_BUFFER_1               0x1320
+#define ARIZONA_DSP3_RDMA_BUFFER_2               0x1321
+#define ARIZONA_DSP3_RDMA_BUFFER_3               0x1322
+#define ARIZONA_DSP3_RDMA_BUFFER_4               0x1323
+#define ARIZONA_DSP3_RDMA_BUFFER_5               0x1324
+#define ARIZONA_DSP3_RDMA_BUFFER_6               0x1325
+#define ARIZONA_DSP3_WDMA_CONFIG_1               0x1330
+#define ARIZONA_DSP3_WDMA_CONFIG_2               0x1331
+#define ARIZONA_DSP3_WDMA_OFFSET_1               0x1332
+#define ARIZONA_DSP3_RDMA_CONFIG_1               0x1334
+#define ARIZONA_DSP3_RDMA_OFFSET_1               0x1335
+#define ARIZONA_DSP3_EXTERNAL_START_SELECT_1     0x1338
 #define ARIZONA_DSP3_SCRATCH_0                   0x1340
 #define ARIZONA_DSP3_SCRATCH_1                   0x1341
 #define ARIZONA_DSP3_SCRATCH_2                   0x1342
 #define ARIZONA_DSP4_STATUS_1                    0x1404
 #define ARIZONA_DSP4_STATUS_2                    0x1405
 #define ARIZONA_DSP4_STATUS_3                    0x1406
+#define ARIZONA_DSP4_STATUS_4                    0x1407
+#define ARIZONA_DSP4_WDMA_BUFFER_1               0x1410
+#define ARIZONA_DSP4_WDMA_BUFFER_2               0x1411
+#define ARIZONA_DSP4_WDMA_BUFFER_3               0x1412
+#define ARIZONA_DSP4_WDMA_BUFFER_4               0x1413
+#define ARIZONA_DSP4_WDMA_BUFFER_5               0x1414
+#define ARIZONA_DSP4_WDMA_BUFFER_6               0x1415
+#define ARIZONA_DSP4_WDMA_BUFFER_7               0x1416
+#define ARIZONA_DSP4_WDMA_BUFFER_8               0x1417
+#define ARIZONA_DSP4_RDMA_BUFFER_1               0x1420
+#define ARIZONA_DSP4_RDMA_BUFFER_2               0x1421
+#define ARIZONA_DSP4_RDMA_BUFFER_3               0x1422
+#define ARIZONA_DSP4_RDMA_BUFFER_4               0x1423
+#define ARIZONA_DSP4_RDMA_BUFFER_5               0x1424
+#define ARIZONA_DSP4_RDMA_BUFFER_6               0x1425
+#define ARIZONA_DSP4_WDMA_CONFIG_1               0x1430
+#define ARIZONA_DSP4_WDMA_CONFIG_2               0x1431
+#define ARIZONA_DSP4_WDMA_OFFSET_1               0x1432
+#define ARIZONA_DSP4_RDMA_CONFIG_1               0x1434
+#define ARIZONA_DSP4_RDMA_OFFSET_1               0x1435
+#define ARIZONA_DSP4_EXTERNAL_START_SELECT_1     0x1438
 #define ARIZONA_DSP4_SCRATCH_0                   0x1440
 #define ARIZONA_DSP4_SCRATCH_1                   0x1441
 #define ARIZONA_DSP4_SCRATCH_2                   0x1442
diff --git a/include/linux/mfd/bcm590xx.h b/include/linux/mfd/bcm590xx.h
new file mode 100644 (file)
index 0000000..434df2d
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Broadcom BCM590xx PMU
+ *
+ * Copyright 2014 Linaro Limited
+ * Author: Matt Porter <mporter@linaro.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.
+ *
+ */
+
+#ifndef __LINUX_MFD_BCM590XX_H
+#define __LINUX_MFD_BCM590XX_H
+
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+
+/* max register address */
+#define BCM590XX_MAX_REGISTER  0xe7
+
+struct bcm590xx {
+       struct device *dev;
+       struct i2c_client *i2c_client;
+       struct regmap *regmap;
+       unsigned int id;
+};
+
+#endif /*  __LINUX_MFD_BCM590XX_H */
index 21e21b81cc7551db7203b7d027b688feebd3577c..bba65f51a0b542c526e253a237e33eef0045c785 100644 (file)
@@ -83,6 +83,7 @@ enum da9052_chip_id {
        DA9053_AA,
        DA9053_BA,
        DA9053_BB,
+       DA9053_BC,
 };
 
 struct da9052_pdata;
index 2d2a0af675fd3f03f1354268c8afd884a94b2592..00a9aac5d1e87fe5a6fa53a00fc9390392c5b6c9 100644 (file)
@@ -33,6 +33,10 @@ enum da9063_models {
        PMIC_DA9063 = 0x61,
 };
 
+enum da9063_variant_codes {
+       PMIC_DA9063_BB = 0x5
+};
+
 /* Interrupts */
 enum da9063_irqs {
        DA9063_IRQ_ONKEY = 0,
@@ -72,7 +76,7 @@ struct da9063 {
        /* Device */
        struct device   *dev;
        unsigned short  model;
-       unsigned short  revision;
+       unsigned char   variant_code;
        unsigned int    flags;
 
        /* Control interface */
index 5834813fb5f31e69889b8b07c3d52fdf68257b8f..09a85c699da1d2f28abc88ecea590077c4c5edad 100644 (file)
 #define        _DA9063_REG_H
 
 #define DA9063_I2C_PAGE_SEL_SHIFT      1
-
 #define        DA9063_EVENT_REG_NUM            4
-#define        DA9210_EVENT_REG_NUM            2
-#define        DA9063_EXT_EVENT_REG_NUM        (DA9063_EVENT_REG_NUM + \
-                                               DA9210_EVENT_REG_NUM)
 
 /* Page selection I2C or SPI always in the begining of any page. */
 /* Page 0 : I2C access 0x000 - 0x0FF   SPI access 0x000 - 0x07F */
@@ -61,9 +57,9 @@
 #define        DA9063_REG_GPIO_10_11           0x1A
 #define        DA9063_REG_GPIO_12_13           0x1B
 #define        DA9063_REG_GPIO_14_15           0x1C
-#define        DA9063_REG_GPIO_MODE_0_7        0x1D
-#define        DA9063_REG_GPIO_MODE_8_15       0x1E
-#define        DA9063_REG_GPIO_SWITCH_CONT     0x1F
+#define        DA9063_REG_GPIO_MODE0_7         0x1D
+#define        DA9063_REG_GPIO_MODE8_15        0x1E
+#define        DA9063_REG_SWITCH_CONT          0x1F
 
 /* Regulator Control Registers */
 #define        DA9063_REG_BCORE2_CONT          0x20
@@ -83,7 +79,7 @@
 #define        DA9063_REG_LDO9_CONT            0x2E
 #define        DA9063_REG_LDO10_CONT           0x2F
 #define        DA9063_REG_LDO11_CONT           0x30
-#define        DA9063_REG_VIB                  0x31
+#define        DA9063_REG_SUPPLIES             0x31
 #define        DA9063_REG_DVC_1                0x32
 #define        DA9063_REG_DVC_2                0x33
 
@@ -97,9 +93,9 @@
 #define        DA9063_REG_ADCIN1_RES           0x3A
 #define        DA9063_REG_ADCIN2_RES           0x3B
 #define        DA9063_REG_ADCIN3_RES           0x3C
-#define        DA9063_REG_MON1_RES             0x3D
-#define        DA9063_REG_MON2_RES             0x3E
-#define        DA9063_REG_MON3_RES             0x3F
+#define        DA9063_REG_MON_A8_RES           0x3D
+#define        DA9063_REG_MON_A9_RES           0x3E
+#define        DA9063_REG_MON_A10_RES          0x3F
 
 /* RTC Calendar and Alarm Registers */
 #define        DA9063_REG_COUNT_S              0x40
 #define        DA9063_REG_COUNT_D              0x43
 #define        DA9063_REG_COUNT_MO             0x44
 #define        DA9063_REG_COUNT_Y              0x45
-#define        DA9063_REG_ALARM_MI             0x46
-#define        DA9063_REG_ALARM_H              0x47
-#define        DA9063_REG_ALARM_D              0x48
-#define        DA9063_REG_ALARM_MO             0x49
-#define        DA9063_REG_ALARM_Y              0x4A
-#define        DA9063_REG_SECOND_A             0x4B
-#define        DA9063_REG_SECOND_B             0x4C
-#define        DA9063_REG_SECOND_C             0x4D
-#define        DA9063_REG_SECOND_D             0x4E
+#define        DA9063_REG_ALARM_S              0x46
+#define        DA9063_REG_ALARM_MI             0x47
+#define        DA9063_REG_ALARM_H              0x48
+#define        DA9063_REG_ALARM_D              0x49
+#define        DA9063_REG_ALARM_MO             0x4A
+#define        DA9063_REG_ALARM_Y              0x4B
+#define        DA9063_REG_SECOND_A             0x4C
+#define        DA9063_REG_SECOND_B             0x4D
+#define        DA9063_REG_SECOND_C             0x4E
+#define        DA9063_REG_SECOND_D             0x4F
 
 /* Sequencer Control Registers */
 #define        DA9063_REG_SEQ                  0x81
 #define        DA9063_REG_CONFIG_J             0x10F
 #define        DA9063_REG_CONFIG_K             0x110
 #define        DA9063_REG_CONFIG_L             0x111
-#define        DA9063_REG_MON_REG_1            0x112
-#define        DA9063_REG_MON_REG_2            0x113
-#define        DA9063_REG_MON_REG_3            0x114
-#define        DA9063_REG_MON_REG_4            0x115
-#define        DA9063_REG_MON_REG_5            0x116
-#define        DA9063_REG_MON_REG_6            0x117
-#define        DA9063_REG_TRIM_CLDR            0x118
-
+#define        DA9063_REG_CONFIG_M             0x112
+#define        DA9063_REG_CONFIG_N             0x113
+
+#define        DA9063_REG_MON_REG_1            0x114
+#define        DA9063_REG_MON_REG_2            0x115
+#define        DA9063_REG_MON_REG_3            0x116
+#define        DA9063_REG_MON_REG_4            0x117
+#define        DA9063_REG_MON_REG_5            0x11E
+#define        DA9063_REG_MON_REG_6            0x11F
+#define        DA9063_REG_TRIM_CLDR            0x120
 /* General Purpose Registers */
-#define        DA9063_REG_GP_ID_0              0x119
-#define        DA9063_REG_GP_ID_1              0x11A
-#define        DA9063_REG_GP_ID_2              0x11B
-#define        DA9063_REG_GP_ID_3              0x11C
-#define        DA9063_REG_GP_ID_4              0x11D
-#define        DA9063_REG_GP_ID_5              0x11E
-#define        DA9063_REG_GP_ID_6              0x11F
-#define        DA9063_REG_GP_ID_7              0x120
-#define        DA9063_REG_GP_ID_8              0x121
-#define        DA9063_REG_GP_ID_9              0x122
-#define        DA9063_REG_GP_ID_10             0x123
-#define        DA9063_REG_GP_ID_11             0x124
-#define        DA9063_REG_GP_ID_12             0x125
-#define        DA9063_REG_GP_ID_13             0x126
-#define        DA9063_REG_GP_ID_14             0x127
-#define        DA9063_REG_GP_ID_15             0x128
-#define        DA9063_REG_GP_ID_16             0x129
-#define        DA9063_REG_GP_ID_17             0x12A
-#define        DA9063_REG_GP_ID_18             0x12B
-#define        DA9063_REG_GP_ID_19             0x12C
+#define        DA9063_REG_GP_ID_0              0x121
+#define        DA9063_REG_GP_ID_1              0x122
+#define        DA9063_REG_GP_ID_2              0x123
+#define        DA9063_REG_GP_ID_3              0x124
+#define        DA9063_REG_GP_ID_4              0x125
+#define        DA9063_REG_GP_ID_5              0x126
+#define        DA9063_REG_GP_ID_6              0x127
+#define        DA9063_REG_GP_ID_7              0x128
+#define        DA9063_REG_GP_ID_8              0x129
+#define        DA9063_REG_GP_ID_9              0x12A
+#define        DA9063_REG_GP_ID_10             0x12B
+#define        DA9063_REG_GP_ID_11             0x12C
+#define        DA9063_REG_GP_ID_12             0x12D
+#define        DA9063_REG_GP_ID_13             0x12E
+#define        DA9063_REG_GP_ID_14             0x12F
+#define        DA9063_REG_GP_ID_15             0x130
+#define        DA9063_REG_GP_ID_16             0x131
+#define        DA9063_REG_GP_ID_17             0x132
+#define        DA9063_REG_GP_ID_18             0x133
+#define        DA9063_REG_GP_ID_19             0x134
 
 /* Chip ID and variant */
 #define        DA9063_REG_CHIP_ID              0x181
 /* DA9063_REG_CONTROL_B (addr=0x0F) */
 #define        DA9063_CHG_SEL                          0x01
 #define        DA9063_WATCHDOG_PD                      0x02
+#define        DA9063_RESET_BLINKING                   0x04
 #define        DA9063_NRES_MODE                        0x08
 #define        DA9063_NONKEY_LOCK                      0x10
+#define        DA9063_BUCK_SLOWSTART                   0x80
 
 /* DA9063_REG_CONTROL_C (addr=0x10) */
 #define        DA9063_DEBOUNCING_MASK                  0x07
 #define        DA9063_GPADC_PAUSE                      0x02
 #define        DA9063_PMIF_DIS                         0x04
 #define        DA9063_HS2WIRE_DIS                      0x08
+#define        DA9063_CLDR_PAUSE                       0x10
 #define        DA9063_BBAT_DIS                         0x20
 #define        DA9063_OUT_32K_PAUSE                    0x40
 #define        DA9063_PMCONT_DIS                       0x80
 #define                DA9063_GPIO15_TYPE_GPO          0x04
 #define        DA9063_GPIO15_NO_WAKEUP                 0x80
 
-/* DA9063_REG_GPIO_MODE_0_7 (addr=0x1D) */
+/* DA9063_REG_GPIO_MODE0_7 (addr=0x1D) */
 #define        DA9063_GPIO0_MODE                       0x01
 #define        DA9063_GPIO1_MODE                       0x02
 #define        DA9063_GPIO2_MODE                       0x04
 #define        DA9063_GPIO6_MODE                       0x40
 #define        DA9063_GPIO7_MODE                       0x80
 
-/* DA9063_REG_GPIO_MODE_8_15 (addr=0x1E) */
+/* DA9063_REG_GPIO_MODE8_15 (addr=0x1E) */
 #define        DA9063_GPIO8_MODE                       0x01
 #define        DA9063_GPIO9_MODE                       0x02
 #define        DA9063_GPIO10_MODE                      0x04
 #define                DA9063_SWITCH_SR_5MV            0x10
 #define                DA9063_SWITCH_SR_10MV           0x20
 #define                DA9063_SWITCH_SR_50MV           0x30
-#define        DA9063_SWITCH_SR_DIS                    0x40
+#define        DA9063_CORE_SW_INTERNAL                 0x40
 #define        DA9063_CP_EN_MODE                       0x80
 
 /* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */
 #define        DA9063_BUCK_EN                          0x01
-#define DA9063_BUCK_GPI_MASK                   0x06
+#define        DA9063_BUCK_GPI_MASK                    0x06
 #define                DA9063_BUCK_GPI_OFF             0x00
 #define                DA9063_BUCK_GPI_GPIO1           0x02
 #define                DA9063_BUCK_GPI_GPIO2           0x04
 #define DA9063_COUNT_YEAR_MASK                 0x3F
 #define DA9063_MONITOR                         0x40
 
-/* DA9063_REG_ALARM_MI (addr=0x46) */
+/* DA9063_REG_ALARM_S (addr=0x46) */
+#define DA9063_ALARM_S_MASK                    0x3F
 #define DA9063_ALARM_STATUS_ALARM              0x80
 #define DA9063_ALARM_STATUS_TICK               0x40
+/* DA9063_REG_ALARM_MI (addr=0x47) */
 #define DA9063_ALARM_MIN_MASK                  0x3F
 
-/* DA9063_REG_ALARM_H (addr=0x47) */
+/* DA9063_REG_ALARM_H (addr=0x48) */
 #define DA9063_ALARM_HOUR_MASK                 0x1F
 
-/* DA9063_REG_ALARM_D (addr=0x48) */
+/* DA9063_REG_ALARM_D (addr=0x49) */
 #define DA9063_ALARM_DAY_MASK                  0x1F
 
-/* DA9063_REG_ALARM_MO (addr=0x49) */
+/* DA9063_REG_ALARM_MO (addr=0x4A) */
 #define DA9063_TICK_WAKE                       0x20
 #define DA9063_TICK_TYPE                       0x10
 #define                DA9063_TICK_TYPE_SEC            0x00
 #define                DA9063_TICK_TYPE_MIN            0x10
 #define DA9063_ALARM_MONTH_MASK                        0x0F
 
-/* DA9063_REG_ALARM_Y (addr=0x4A) */
+/* DA9063_REG_ALARM_Y (addr=0x4B) */
 #define DA9063_TICK_ON                         0x80
 #define DA9063_ALARM_ON                                0x40
 #define DA9063_ALARM_YEAR_MASK                 0x3F
 
 /* DA9063_REG_Bxxxx_CFG common bits (addr=0x9D-0xA2) */
 #define DA9063_BUCK_FB_MASK                    0x07
-#define DA9063_BUCK_PD_DIS_SHIFT               5
+#define DA9063_BUCK_PD_DIS_MASK                0x20
 #define DA9063_BUCK_MODE_MASK                  0xC0
 #define                DA9063_BUCK_MODE_MANUAL         0x00
 #define                DA9063_BUCK_MODE_SLEEP          0x40
index 060e11256fbcf8866afc23d900134d4040c7a59a..bf5109d38a26f93ffdbe3a2007ebaa99336a6cd8 100644 (file)
@@ -183,8 +183,6 @@ struct prcmu_pdata
        bool enable_set_ddr_opp;
        bool enable_ape_opp_100_voltage;
        struct ab8500_platform_data *ab_platdata;
-       int ab_irq;
-       int irq_base;
        u32 version_offset;
        u32 legacy_offset;
        u32 adt_offset;
index 3e1df644c407ed6d6965dc62908cb620421ca70a..8feac782fa835e8a78c6b6b6ae65e5e4da6602eb 100644 (file)
 #define LPC_ICH_H
 
 /* Watchdog resources */
-#define ICH_RES_IO_TCO 0
-#define ICH_RES_IO_SMI 1
-#define ICH_RES_MEM_OFF        2
-#define ICH_RES_MEM_GCS        0
+#define ICH_RES_IO_TCO         0
+#define ICH_RES_IO_SMI         1
+#define ICH_RES_MEM_OFF                2
+#define ICH_RES_MEM_GCS_PMC    0
 
 /* GPIO resources */
 #define ICH_RES_GPIO   0
 #define ICH_RES_GPE0   1
 
 /* GPIO compatibility */
-#define ICH_I3100_GPIO         0x401
-#define ICH_V5_GPIO            0x501
-#define ICH_V6_GPIO            0x601
-#define ICH_V7_GPIO            0x701
-#define ICH_V9_GPIO            0x801
-#define ICH_V10CORP_GPIO       0xa01
-#define ICH_V10CONS_GPIO       0xa11
+enum {
+       ICH_I3100_GPIO,
+       ICH_V5_GPIO,
+       ICH_V6_GPIO,
+       ICH_V7_GPIO,
+       ICH_V9_GPIO,
+       ICH_V10CORP_GPIO,
+       ICH_V10CONS_GPIO,
+       AVOTON_GPIO,
+};
 
 struct lpc_ich_info {
        char name[32];
index a3d0185196d36799ffc974b63148665316818718..c9b332fb0d5da1e11c0ac42c06bf62521541d55e 100644 (file)
@@ -248,14 +248,6 @@ enum max14577_charger_reg {
 /* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
 #define MAX14577_REGULATOR_SAFEOUT_VOLTAGE             4900000
 
-enum max14577_irq_source {
-       MAX14577_IRQ_INT1 = 0,
-       MAX14577_IRQ_INT2,
-       MAX14577_IRQ_INT3,
-
-       MAX14577_IRQ_REGS_NUM,
-};
-
 enum max14577_irq {
        /* INT1 */
        MAX14577_IRQ_INT1_ADC,
index 247b021dfaaf5de7b036917be4124742e00ea201..736d39c3ec0d7a4b115df93d97d60d84c4979a85 100644 (file)
 #ifndef __MAX14577_H__
 #define __MAX14577_H__
 
-#include <linux/mfd/max14577-private.h>
 #include <linux/regulator/consumer.h>
 
-/*
- * MAX14577 Regulator
- */
-
 /* MAX14577 regulator IDs */
 enum max14577_regulators {
        MAX14577_SAFEOUT = 0,
diff --git a/include/linux/mfd/pm8xxx/irq.h b/include/linux/mfd/pm8xxx/irq.h
deleted file mode 100644 (file)
index f83d6b4..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011, Code Aurora Forum. 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.
- */
-/*
- * Qualcomm PMIC irq 8xxx driver header file
- *
- */
-
-#ifndef __MFD_PM8XXX_IRQ_H
-#define __MFD_PM8XXX_IRQ_H
-
-#include <linux/errno.h>
-#include <linux/err.h>
-
-struct pm8xxx_irq_core_data {
-       u32             rev;
-       int             nirqs;
-};
-
-struct pm8xxx_irq_platform_data {
-       int                             irq_base;
-       struct pm8xxx_irq_core_data     irq_cdata;
-       int                             devirq;
-       int                             irq_trigger_flag;
-};
-
-struct pm_irq_chip;
-
-#ifdef CONFIG_MFD_PM8XXX_IRQ
-int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq);
-struct pm_irq_chip *pm8xxx_irq_init(struct device *dev,
-                               const struct pm8xxx_irq_platform_data *pdata);
-int pm8xxx_irq_exit(struct pm_irq_chip *chip);
-#else
-static inline int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
-{
-       return -ENXIO;
-}
-static inline struct pm_irq_chip *pm8xxx_irq_init(
-                               const struct device *dev,
-                               const struct pm8xxx_irq_platform_data *pdata)
-{
-       return ERR_PTR(-ENXIO);
-}
-static inline int pm8xxx_irq_exit(struct pm_irq_chip *chip)
-{
-       return -ENXIO;
-}
-#endif /* CONFIG_MFD_PM8XXX_IRQ */
-#endif /* __MFD_PM8XXX_IRQ_H */
diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h
deleted file mode 100644 (file)
index 00fa3de..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011, Code Aurora Forum. 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.
- */
-/*
- * Qualcomm PMIC 8921 driver header file
- *
- */
-
-#ifndef __MFD_PM8921_H
-#define __MFD_PM8921_H
-
-#include <linux/mfd/pm8xxx/irq.h>
-
-#define PM8921_NR_IRQS         256
-
-struct pm8921_platform_data {
-       int                                     irq_base;
-       struct pm8xxx_irq_platform_data         *irq_pdata;
-};
-
-#endif
diff --git a/include/linux/mfd/rtsx_usb.h b/include/linux/mfd/rtsx_usb.h
new file mode 100644 (file)
index 0000000..c446e4f
--- /dev/null
@@ -0,0 +1,628 @@
+/* Driver for Realtek RTS5139 USB card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Roger Tseng <rogerable@realtek.com>
+ */
+
+#ifndef __RTSX_USB_H
+#define __RTSX_USB_H
+
+#include <linux/usb.h>
+
+/* related module names */
+#define RTSX_USB_SD_CARD       0
+#define RTSX_USB_MS_CARD       1
+
+/* endpoint numbers */
+#define EP_BULK_OUT            1
+#define EP_BULK_IN             2
+#define EP_INTR_IN             3
+
+/* USB vendor requests */
+#define RTSX_USB_REQ_REG_OP    0x00
+#define RTSX_USB_REQ_POLL      0x02
+
+/* miscellaneous parameters */
+#define MIN_DIV_N              60
+#define MAX_DIV_N              120
+
+#define MAX_PHASE              15
+#define RX_TUNING_CNT          3
+
+#define QFN24                  0
+#define LQFP48                 1
+#define CHECK_PKG(ucr, pkg)    ((ucr)->package == (pkg))
+
+/* data structures */
+struct rtsx_ucr {
+       u16                     vendor_id;
+       u16                     product_id;
+
+       int                     package;
+       u8                      ic_version;
+       bool                    is_rts5179;
+
+       unsigned int            cur_clk;
+
+       u8                      *cmd_buf;
+       unsigned int            cmd_idx;
+       u8                      *rsp_buf;
+
+       struct usb_device       *pusb_dev;
+       struct usb_interface    *pusb_intf;
+       struct usb_sg_request   current_sg;
+       unsigned char           *iobuf;
+       dma_addr_t              iobuf_dma;
+
+       struct timer_list       sg_timer;
+       struct mutex            dev_mutex;
+};
+
+/* buffer size */
+#define IOBUF_SIZE             1024
+
+/* prototypes of exported functions */
+extern int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status);
+
+extern int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data);
+extern int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask,
+               u8 data);
+
+extern int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask,
+               u8 data);
+extern int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr,
+               u8 *data);
+
+extern void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type,
+               u16 reg_addr, u8 mask, u8 data);
+extern int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout);
+extern int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout);
+extern int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+                             void *buf, unsigned int len, int use_sg,
+                             unsigned int *act_len, int timeout);
+
+extern int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len);
+extern int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len);
+extern int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock,
+               u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
+extern int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card);
+
+/* card status */
+#define SD_CD          0x01
+#define MS_CD          0x02
+#define XD_CD          0x04
+#define CD_MASK                (SD_CD | MS_CD | XD_CD)
+#define SD_WP          0x08
+
+/* reader command field offset & parameters */
+#define READ_REG_CMD           0
+#define WRITE_REG_CMD          1
+#define CHECK_REG_CMD          2
+
+#define PACKET_TYPE            4
+#define CNT_H                  5
+#define CNT_L                  6
+#define STAGE_FLAG             7
+#define CMD_OFFSET             8
+#define SEQ_WRITE_DATA_OFFSET  12
+
+#define BATCH_CMD              0
+#define SEQ_READ               1
+#define SEQ_WRITE              2
+
+#define STAGE_R                        0x01
+#define STAGE_DI               0x02
+#define STAGE_DO               0x04
+#define STAGE_MS_STATUS                0x08
+#define STAGE_XD_STATUS                0x10
+#define MODE_C                 0x00
+#define MODE_CR                        (STAGE_R)
+#define MODE_CDIR              (STAGE_R | STAGE_DI)
+#define MODE_CDOR              (STAGE_R | STAGE_DO)
+
+#define EP0_OP_SHIFT           14
+#define EP0_READ_REG_CMD       2
+#define EP0_WRITE_REG_CMD      3
+
+#define rtsx_usb_cmd_hdr_tag(ucr)              \
+       do {                                    \
+               ucr->cmd_buf[0] = 'R';          \
+               ucr->cmd_buf[1] = 'T';          \
+               ucr->cmd_buf[2] = 'C';          \
+               ucr->cmd_buf[3] = 'R';          \
+       } while (0)
+
+static inline void rtsx_usb_init_cmd(struct rtsx_ucr *ucr)
+{
+       rtsx_usb_cmd_hdr_tag(ucr);
+       ucr->cmd_idx = 0;
+       ucr->cmd_buf[PACKET_TYPE] = BATCH_CMD;
+}
+
+/* internal register address */
+#define FPDCTL                         0xFC00
+#define SSC_DIV_N_0                    0xFC07
+#define SSC_CTL1                       0xFC09
+#define SSC_CTL2                       0xFC0A
+#define CFG_MODE                       0xFC0E
+#define CFG_MODE_1                     0xFC0F
+#define RCCTL                          0xFC14
+#define SOF_WDOG                       0xFC28
+#define SYS_DUMMY0                     0xFC30
+
+#define MS_BLKEND                      0xFD30
+#define MS_READ_START                  0xFD31
+#define MS_READ_COUNT                  0xFD32
+#define MS_WRITE_START                 0xFD33
+#define MS_WRITE_COUNT                 0xFD34
+#define MS_COMMAND                     0xFD35
+#define MS_OLD_BLOCK_0                 0xFD36
+#define MS_OLD_BLOCK_1                 0xFD37
+#define MS_NEW_BLOCK_0                 0xFD38
+#define MS_NEW_BLOCK_1                 0xFD39
+#define MS_LOG_BLOCK_0                 0xFD3A
+#define MS_LOG_BLOCK_1                 0xFD3B
+#define MS_BUS_WIDTH                   0xFD3C
+#define MS_PAGE_START                  0xFD3D
+#define MS_PAGE_LENGTH                 0xFD3E
+#define MS_CFG                         0xFD40
+#define MS_TPC                         0xFD41
+#define MS_TRANS_CFG                   0xFD42
+#define MS_TRANSFER                    0xFD43
+#define MS_INT_REG                     0xFD44
+#define MS_BYTE_CNT                    0xFD45
+#define MS_SECTOR_CNT_L                        0xFD46
+#define MS_SECTOR_CNT_H                        0xFD47
+#define MS_DBUS_H                      0xFD48
+
+#define CARD_DMA1_CTL                  0xFD5C
+#define CARD_PULL_CTL1                 0xFD60
+#define CARD_PULL_CTL2                 0xFD61
+#define CARD_PULL_CTL3                 0xFD62
+#define CARD_PULL_CTL4                 0xFD63
+#define CARD_PULL_CTL5                 0xFD64
+#define CARD_PULL_CTL6                 0xFD65
+#define CARD_EXIST                     0xFD6F
+#define CARD_INT_PEND                  0xFD71
+
+#define LDO_POWER_CFG                  0xFD7B
+
+#define SD_CFG1                                0xFDA0
+#define SD_CFG2                                0xFDA1
+#define SD_CFG3                                0xFDA2
+#define SD_STAT1                       0xFDA3
+#define SD_STAT2                       0xFDA4
+#define SD_BUS_STAT                    0xFDA5
+#define SD_PAD_CTL                     0xFDA6
+#define SD_SAMPLE_POINT_CTL            0xFDA7
+#define SD_PUSH_POINT_CTL              0xFDA8
+#define SD_CMD0                                0xFDA9
+#define SD_CMD1                                0xFDAA
+#define SD_CMD2                                0xFDAB
+#define SD_CMD3                                0xFDAC
+#define SD_CMD4                                0xFDAD
+#define SD_CMD5                                0xFDAE
+#define SD_BYTE_CNT_L                  0xFDAF
+#define SD_BYTE_CNT_H                  0xFDB0
+#define SD_BLOCK_CNT_L                 0xFDB1
+#define SD_BLOCK_CNT_H                 0xFDB2
+#define SD_TRANSFER                    0xFDB3
+#define SD_CMD_STATE                   0xFDB5
+#define SD_DATA_STATE                  0xFDB6
+#define SD_VPCLK0_CTL                  0xFC2A
+#define SD_VPCLK1_CTL                  0xFC2B
+#define SD_DCMPS0_CTL                  0xFC2C
+#define SD_DCMPS1_CTL                  0xFC2D
+
+#define CARD_DMA1_CTL                  0xFD5C
+
+#define HW_VERSION                     0xFC01
+
+#define SSC_CLK_FPGA_SEL               0xFC02
+#define CLK_DIV                                0xFC03
+#define SFSM_ED                                0xFC04
+
+#define CD_DEGLITCH_WIDTH              0xFC20
+#define CD_DEGLITCH_EN                 0xFC21
+#define AUTO_DELINK_EN                 0xFC23
+
+#define FPGA_PULL_CTL                  0xFC1D
+#define CARD_CLK_SOURCE                        0xFC2E
+
+#define CARD_SHARE_MODE                        0xFD51
+#define CARD_DRIVE_SEL                 0xFD52
+#define CARD_STOP                      0xFD53
+#define CARD_OE                                0xFD54
+#define CARD_AUTO_BLINK                        0xFD55
+#define CARD_GPIO                      0xFD56
+#define SD30_DRIVE_SEL                 0xFD57
+
+#define CARD_DATA_SOURCE               0xFD5D
+#define CARD_SELECT                    0xFD5E
+
+#define CARD_CLK_EN                    0xFD79
+#define CARD_PWR_CTL                   0xFD7A
+
+#define OCPCTL                         0xFD80
+#define OCPPARA1                       0xFD81
+#define OCPPARA2                       0xFD82
+#define OCPSTAT                                0xFD83
+
+#define HS_USB_STAT                    0xFE01
+#define HS_VCONTROL                    0xFE26
+#define HS_VSTAIN                      0xFE27
+#define HS_VLOADM                      0xFE28
+#define HS_VSTAOUT                     0xFE29
+
+#define MC_IRQ                         0xFF00
+#define MC_IRQEN                       0xFF01
+#define MC_FIFO_CTL                    0xFF02
+#define MC_FIFO_BC0                    0xFF03
+#define MC_FIFO_BC1                    0xFF04
+#define MC_FIFO_STAT                   0xFF05
+#define MC_FIFO_MODE                   0xFF06
+#define MC_FIFO_RD_PTR0                        0xFF07
+#define MC_FIFO_RD_PTR1                        0xFF08
+#define MC_DMA_CTL                     0xFF10
+#define MC_DMA_TC0                     0xFF11
+#define MC_DMA_TC1                     0xFF12
+#define MC_DMA_TC2                     0xFF13
+#define MC_DMA_TC3                     0xFF14
+#define MC_DMA_RST                     0xFF15
+
+#define RBUF_SIZE_MASK                 0xFBFF
+#define RBUF_BASE                      0xF000
+#define PPBUF_BASE1                    0xF800
+#define PPBUF_BASE2                    0xFA00
+
+/* internal register value macros */
+#define POWER_OFF                      0x03
+#define PARTIAL_POWER_ON               0x02
+#define POWER_ON                       0x00
+#define POWER_MASK                     0x03
+#define LDO3318_PWR_MASK               0x0C
+#define LDO_ON                         0x00
+#define LDO_SUSPEND                    0x08
+#define LDO_OFF                                0x0C
+#define DV3318_AUTO_PWR_OFF            0x10
+#define FORCE_LDO_POWERB               0x60
+
+/* LDO_POWER_CFG */
+#define TUNE_SD18_MASK                 0x1C
+#define TUNE_SD18_1V7                  0x00
+#define TUNE_SD18_1V8                  (0x01 << 2)
+#define TUNE_SD18_1V9                  (0x02 << 2)
+#define TUNE_SD18_2V0                  (0x03 << 2)
+#define TUNE_SD18_2V7                  (0x04 << 2)
+#define TUNE_SD18_2V8                  (0x05 << 2)
+#define TUNE_SD18_2V9                  (0x06 << 2)
+#define TUNE_SD18_3V3                  (0x07 << 2)
+
+/* CLK_DIV */
+#define CLK_CHANGE                     0x80
+#define CLK_DIV_1                      0x00
+#define CLK_DIV_2                      0x01
+#define CLK_DIV_4                      0x02
+#define CLK_DIV_8                      0x03
+
+#define SSC_POWER_MASK                 0x01
+#define SSC_POWER_DOWN                 0x01
+#define SSC_POWER_ON                   0x00
+
+#define FPGA_VER                       0x80
+#define HW_VER_MASK                    0x0F
+
+#define EXTEND_DMA1_ASYNC_SIGNAL       0x02
+
+/* CFG_MODE*/
+#define XTAL_FREE                      0x80
+#define CLK_MODE_MASK                  0x03
+#define CLK_MODE_12M_XTAL              0x00
+#define CLK_MODE_NON_XTAL              0x01
+#define CLK_MODE_24M_OSC               0x02
+#define CLK_MODE_48M_OSC               0x03
+
+/* CFG_MODE_1*/
+#define RTS5179                                0x02
+
+#define NYET_EN                                0x01
+#define NYET_MSAK                      0x01
+
+#define SD30_DRIVE_MASK                        0x07
+#define SD20_DRIVE_MASK                        0x03
+
+#define DISABLE_SD_CD                  0x08
+#define DISABLE_MS_CD                  0x10
+#define DISABLE_XD_CD                  0x20
+#define SD_CD_DEGLITCH_EN              0x01
+#define MS_CD_DEGLITCH_EN              0x02
+#define XD_CD_DEGLITCH_EN              0x04
+
+#define        CARD_SHARE_LQFP48               0x04
+#define        CARD_SHARE_QFN24                0x00
+#define CARD_SHARE_LQFP_SEL            0x04
+#define        CARD_SHARE_XD                   0x00
+#define        CARD_SHARE_SD                   0x01
+#define        CARD_SHARE_MS                   0x02
+#define CARD_SHARE_MASK                        0x03
+
+
+/* SD30_DRIVE_SEL */
+#define DRIVER_TYPE_A                  0x05
+#define DRIVER_TYPE_B                  0x03
+#define DRIVER_TYPE_C                  0x02
+#define DRIVER_TYPE_D                  0x01
+
+/* SD_BUS_STAT */
+#define        SD_CLK_TOGGLE_EN                0x80
+#define        SD_CLK_FORCE_STOP               0x40
+#define        SD_DAT3_STATUS                  0x10
+#define        SD_DAT2_STATUS                  0x08
+#define        SD_DAT1_STATUS                  0x04
+#define        SD_DAT0_STATUS                  0x02
+#define        SD_CMD_STATUS                   0x01
+
+/* SD_PAD_CTL */
+#define        SD_IO_USING_1V8                 0x80
+#define        SD_IO_USING_3V3                 0x7F
+#define        TYPE_A_DRIVING                  0x00
+#define        TYPE_B_DRIVING                  0x01
+#define        TYPE_C_DRIVING                  0x02
+#define        TYPE_D_DRIVING                  0x03
+
+/* CARD_CLK_EN */
+#define SD_CLK_EN                      0x04
+#define MS_CLK_EN                      0x08
+
+/* CARD_SELECT */
+#define SD_MOD_SEL                     2
+#define MS_MOD_SEL                     3
+
+/* CARD_SHARE_MODE */
+#define        CARD_SHARE_LQFP48               0x04
+#define        CARD_SHARE_QFN24                0x00
+#define CARD_SHARE_LQFP_SEL            0x04
+#define        CARD_SHARE_XD                   0x00
+#define        CARD_SHARE_SD                   0x01
+#define        CARD_SHARE_MS                   0x02
+#define CARD_SHARE_MASK                        0x03
+
+/* SSC_CTL1 */
+#define SSC_RSTB                       0x80
+#define SSC_8X_EN                      0x40
+#define SSC_FIX_FRAC                   0x20
+#define SSC_SEL_1M                     0x00
+#define SSC_SEL_2M                     0x08
+#define SSC_SEL_4M                     0x10
+#define SSC_SEL_8M                     0x18
+
+/* SSC_CTL2 */
+#define SSC_DEPTH_MASK                 0x03
+#define SSC_DEPTH_DISALBE              0x00
+#define SSC_DEPTH_2M                   0x01
+#define SSC_DEPTH_1M                   0x02
+#define SSC_DEPTH_512K                 0x03
+
+/* SD_VPCLK0_CTL */
+#define PHASE_CHANGE                   0x80
+#define PHASE_NOT_RESET                        0x40
+
+/* SD_TRANSFER */
+#define        SD_TRANSFER_START               0x80
+#define        SD_TRANSFER_END                 0x40
+#define SD_STAT_IDLE                   0x20
+#define        SD_TRANSFER_ERR                 0x10
+#define        SD_TM_NORMAL_WRITE              0x00
+#define        SD_TM_AUTO_WRITE_3              0x01
+#define        SD_TM_AUTO_WRITE_4              0x02
+#define        SD_TM_AUTO_READ_3               0x05
+#define        SD_TM_AUTO_READ_4               0x06
+#define        SD_TM_CMD_RSP                   0x08
+#define        SD_TM_AUTO_WRITE_1              0x09
+#define        SD_TM_AUTO_WRITE_2              0x0A
+#define        SD_TM_NORMAL_READ               0x0C
+#define        SD_TM_AUTO_READ_1               0x0D
+#define        SD_TM_AUTO_READ_2               0x0E
+#define        SD_TM_AUTO_TUNING               0x0F
+
+/* SD_CFG1 */
+#define SD_CLK_DIVIDE_0                        0x00
+#define        SD_CLK_DIVIDE_256               0xC0
+#define        SD_CLK_DIVIDE_128               0x80
+#define SD_CLK_DIVIDE_MASK             0xC0
+#define        SD_BUS_WIDTH_1BIT               0x00
+#define        SD_BUS_WIDTH_4BIT               0x01
+#define        SD_BUS_WIDTH_8BIT               0x02
+#define        SD_ASYNC_FIFO_RST               0x10
+#define        SD_20_MODE                      0x00
+#define        SD_DDR_MODE                     0x04
+#define        SD_30_MODE                      0x08
+
+/* SD_CFG2 */
+#define        SD_CALCULATE_CRC7               0x00
+#define        SD_NO_CALCULATE_CRC7            0x80
+#define        SD_CHECK_CRC16                  0x00
+#define        SD_NO_CHECK_CRC16               0x40
+#define SD_WAIT_CRC_TO_EN              0x20
+#define        SD_WAIT_BUSY_END                0x08
+#define        SD_NO_WAIT_BUSY_END             0x00
+#define        SD_CHECK_CRC7                   0x00
+#define        SD_NO_CHECK_CRC7                0x04
+#define        SD_RSP_LEN_0                    0x00
+#define        SD_RSP_LEN_6                    0x01
+#define        SD_RSP_LEN_17                   0x02
+#define        SD_RSP_TYPE_R0                  0x04
+#define        SD_RSP_TYPE_R1                  0x01
+#define        SD_RSP_TYPE_R1b                 0x09
+#define        SD_RSP_TYPE_R2                  0x02
+#define        SD_RSP_TYPE_R3                  0x05
+#define        SD_RSP_TYPE_R4                  0x05
+#define        SD_RSP_TYPE_R5                  0x01
+#define        SD_RSP_TYPE_R6                  0x01
+#define        SD_RSP_TYPE_R7                  0x01
+
+/* SD_STAT1 */
+#define        SD_CRC7_ERR                     0x80
+#define        SD_CRC16_ERR                    0x40
+#define        SD_CRC_WRITE_ERR                0x20
+#define        SD_CRC_WRITE_ERR_MASK           0x1C
+#define        GET_CRC_TIME_OUT                0x02
+#define        SD_TUNING_COMPARE_ERR           0x01
+
+/* SD_DATA_STATE */
+#define SD_DATA_IDLE                   0x80
+
+/* CARD_DATA_SOURCE */
+#define PINGPONG_BUFFER                        0x01
+#define RING_BUFFER                    0x00
+
+/* CARD_OE */
+#define SD_OUTPUT_EN                   0x04
+#define MS_OUTPUT_EN                   0x08
+
+/* CARD_STOP */
+#define SD_STOP                                0x04
+#define MS_STOP                                0x08
+#define SD_CLR_ERR                     0x40
+#define MS_CLR_ERR                     0x80
+
+/* CARD_CLK_SOURCE */
+#define CRC_FIX_CLK                    (0x00 << 0)
+#define CRC_VAR_CLK0                   (0x01 << 0)
+#define CRC_VAR_CLK1                   (0x02 << 0)
+#define SD30_FIX_CLK                   (0x00 << 2)
+#define SD30_VAR_CLK0                  (0x01 << 2)
+#define SD30_VAR_CLK1                  (0x02 << 2)
+#define SAMPLE_FIX_CLK                 (0x00 << 4)
+#define SAMPLE_VAR_CLK0                        (0x01 << 4)
+#define SAMPLE_VAR_CLK1                        (0x02 << 4)
+
+/* SD_SAMPLE_POINT_CTL */
+#define        DDR_FIX_RX_DAT                  0x00
+#define        DDR_VAR_RX_DAT                  0x80
+#define        DDR_FIX_RX_DAT_EDGE             0x00
+#define        DDR_FIX_RX_DAT_14_DELAY         0x40
+#define        DDR_FIX_RX_CMD                  0x00
+#define        DDR_VAR_RX_CMD                  0x20
+#define        DDR_FIX_RX_CMD_POS_EDGE         0x00
+#define        DDR_FIX_RX_CMD_14_DELAY         0x10
+#define        SD20_RX_POS_EDGE                0x00
+#define        SD20_RX_14_DELAY                0x08
+#define SD20_RX_SEL_MASK               0x08
+
+/* SD_PUSH_POINT_CTL */
+#define        DDR_FIX_TX_CMD_DAT              0x00
+#define        DDR_VAR_TX_CMD_DAT              0x80
+#define        DDR_FIX_TX_DAT_14_TSU           0x00
+#define        DDR_FIX_TX_DAT_12_TSU           0x40
+#define        DDR_FIX_TX_CMD_NEG_EDGE         0x00
+#define        DDR_FIX_TX_CMD_14_AHEAD         0x20
+#define        SD20_TX_NEG_EDGE                0x00
+#define        SD20_TX_14_AHEAD                0x10
+#define SD20_TX_SEL_MASK               0x10
+#define        DDR_VAR_SDCLK_POL_SWAP          0x01
+
+/* MS_CFG */
+#define        SAMPLE_TIME_RISING              0x00
+#define        SAMPLE_TIME_FALLING             0x80
+#define        PUSH_TIME_DEFAULT               0x00
+#define        PUSH_TIME_ODD                   0x40
+#define        NO_EXTEND_TOGGLE                0x00
+#define        EXTEND_TOGGLE_CHK               0x20
+#define        MS_BUS_WIDTH_1                  0x00
+#define        MS_BUS_WIDTH_4                  0x10
+#define        MS_BUS_WIDTH_8                  0x18
+#define        MS_2K_SECTOR_MODE               0x04
+#define        MS_512_SECTOR_MODE              0x00
+#define        MS_TOGGLE_TIMEOUT_EN            0x00
+#define        MS_TOGGLE_TIMEOUT_DISEN         0x01
+#define MS_NO_CHECK_INT                        0x02
+
+/* MS_TRANS_CFG */
+#define        WAIT_INT                        0x80
+#define        NO_WAIT_INT                     0x00
+#define        NO_AUTO_READ_INT_REG            0x00
+#define        AUTO_READ_INT_REG               0x40
+#define        MS_CRC16_ERR                    0x20
+#define        MS_RDY_TIMEOUT                  0x10
+#define        MS_INT_CMDNK                    0x08
+#define        MS_INT_BREQ                     0x04
+#define        MS_INT_ERR                      0x02
+#define        MS_INT_CED                      0x01
+
+/* MS_TRANSFER */
+#define        MS_TRANSFER_START               0x80
+#define        MS_TRANSFER_END                 0x40
+#define        MS_TRANSFER_ERR                 0x20
+#define        MS_BS_STATE                     0x10
+#define        MS_TM_READ_BYTES                0x00
+#define        MS_TM_NORMAL_READ               0x01
+#define        MS_TM_WRITE_BYTES               0x04
+#define        MS_TM_NORMAL_WRITE              0x05
+#define        MS_TM_AUTO_READ                 0x08
+#define        MS_TM_AUTO_WRITE                0x0C
+#define MS_TM_SET_CMD                  0x06
+#define MS_TM_COPY_PAGE                        0x07
+#define MS_TM_MULTI_READ               0x02
+#define MS_TM_MULTI_WRITE              0x03
+
+/* MC_FIFO_CTL */
+#define FIFO_FLUSH                     0x01
+
+/* MC_DMA_RST */
+#define DMA_RESET  0x01
+
+/* MC_DMA_CTL */
+#define DMA_TC_EQ_0                    0x80
+#define DMA_DIR_TO_CARD                        0x00
+#define DMA_DIR_FROM_CARD              0x02
+#define DMA_EN                         0x01
+#define DMA_128                                (0 << 2)
+#define DMA_256                                (1 << 2)
+#define DMA_512                                (2 << 2)
+#define DMA_1024                       (3 << 2)
+#define DMA_PACK_SIZE_MASK             0x0C
+
+/* CARD_INT_PEND */
+#define XD_INT                         0x10
+#define MS_INT                         0x08
+#define SD_INT                         0x04
+
+/* LED operations*/
+static inline int rtsx_usb_turn_on_led(struct rtsx_ucr *ucr)
+{
+       return  rtsx_usb_ep0_write_register(ucr, CARD_GPIO, 0x03, 0x02);
+}
+
+static inline int rtsx_usb_turn_off_led(struct rtsx_ucr *ucr)
+{
+       return rtsx_usb_ep0_write_register(ucr, CARD_GPIO, 0x03, 0x03);
+}
+
+/* HW error clearing */
+static inline void rtsx_usb_clear_fsm_err(struct rtsx_ucr *ucr)
+{
+       rtsx_usb_ep0_write_register(ucr, SFSM_ED, 0xf8, 0xf8);
+}
+
+static inline void rtsx_usb_clear_dma_err(struct rtsx_ucr *ucr)
+{
+       rtsx_usb_ep0_write_register(ucr, MC_FIFO_CTL,
+                       FIFO_FLUSH, FIFO_FLUSH);
+       rtsx_usb_ep0_write_register(ucr, MC_DMA_RST, DMA_RESET, DMA_RESET);
+}
+#endif /* __RTS51139_H */
index 866e355fa409135a78a374122b590035cb09a5b0..ff44374a1a4e0ea4b90418c49514f7f39a7b79e8 100644 (file)
 
 #define IMX6Q_GPR5_L2_CLK_STOP                 BIT(8)
 
+#define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK       (0xf << 0)
+#define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK       (0xf << 4)
+#define IMX6Q_GPR6_IPU1_ID10_WR_QOS_MASK       (0xf << 8)
+#define IMX6Q_GPR6_IPU1_ID11_WR_QOS_MASK       (0xf << 12)
+#define IMX6Q_GPR6_IPU1_ID00_RD_QOS_MASK       (0xf << 16)
+#define IMX6Q_GPR6_IPU1_ID01_RD_QOS_MASK       (0xf << 20)
+#define IMX6Q_GPR6_IPU1_ID10_RD_QOS_MASK       (0xf << 24)
+#define IMX6Q_GPR6_IPU1_ID11_RD_QOS_MASK       (0xf << 28)
+
+#define IMX6Q_GPR7_IPU2_ID00_WR_QOS_MASK       (0xf << 0)
+#define IMX6Q_GPR7_IPU2_ID01_WR_QOS_MASK       (0xf << 4)
+#define IMX6Q_GPR7_IPU2_ID10_WR_QOS_MASK       (0xf << 8)
+#define IMX6Q_GPR7_IPU2_ID11_WR_QOS_MASK       (0xf << 12)
+#define IMX6Q_GPR7_IPU2_ID00_RD_QOS_MASK       (0xf << 16)
+#define IMX6Q_GPR7_IPU2_ID01_RD_QOS_MASK       (0xf << 20)
+#define IMX6Q_GPR7_IPU2_ID10_RD_QOS_MASK       (0xf << 24)
+#define IMX6Q_GPR7_IPU2_ID11_RD_QOS_MASK       (0xf << 28)
+
 #define IMX6Q_GPR8_TX_SWING_LOW                        (0x7f << 25)
 #define IMX6Q_GPR8_TX_SWING_FULL               (0x7f << 18)
 #define IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB          (0x3f << 12)
diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h
new file mode 100644 (file)
index 0000000..d2e357d
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * linux/mfd/tps65218.h
+ *
+ * Functions to access TPS65219 power management chip.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ */
+
+#ifndef __LINUX_MFD_TPS65218_H
+#define __LINUX_MFD_TPS65218_H
+
+#include <linux/i2c.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/bitops.h>
+
+/* TPS chip id list */
+#define TPS65218                       0xF0
+
+/* I2C ID for TPS65218 part */
+#define TPS65218_I2C_ID                        0x24
+
+/* All register addresses */
+#define TPS65218_REG_CHIPID            0x00
+#define TPS65218_REG_INT1              0x01
+#define TPS65218_REG_INT2              0x02
+#define TPS65218_REG_INT_MASK1         0x03
+#define TPS65218_REG_INT_MASK2         0x04
+#define TPS65218_REG_STATUS            0x05
+#define TPS65218_REG_CONTROL           0x06
+#define TPS65218_REG_FLAG              0x07
+
+#define TPS65218_REG_PASSWORD          0x10
+#define TPS65218_REG_ENABLE1           0x11
+#define TPS65218_REG_ENABLE2           0x12
+#define TPS65218_REG_CONFIG1           0x13
+#define TPS65218_REG_CONFIG2           0x14
+#define TPS65218_REG_CONFIG3           0x15
+#define TPS65218_REG_CONTROL_DCDC1     0x16
+#define TPS65218_REG_CONTROL_DCDC2     0x17
+#define TPS65218_REG_CONTROL_DCDC3     0x18
+#define TPS65218_REG_CONTROL_DCDC4     0x19
+#define TPS65218_REG_CONTRL_SLEW_RATE  0x1A
+#define TPS65218_REG_CONTROL_LDO1      0x1B
+#define TPS65218_REG_SEQ1              0x20
+#define TPS65218_REG_SEQ2              0x21
+#define TPS65218_REG_SEQ3              0x22
+#define TPS65218_REG_SEQ4              0x23
+#define TPS65218_REG_SEQ5              0x24
+#define TPS65218_REG_SEQ6              0x25
+#define TPS65218_REG_SEQ7              0x26
+
+/* Register field definitions */
+#define TPS65218_CHIPID_CHIP_MASK      0xF8
+#define TPS65218_CHIPID_REV_MASK       0x07
+
+#define TPS65218_INT1_VPRG             BIT(5)
+#define TPS65218_INT1_AC               BIT(4)
+#define TPS65218_INT1_PB               BIT(3)
+#define TPS65218_INT1_HOT              BIT(2)
+#define TPS65218_INT1_CC_AQC           BIT(1)
+#define TPS65218_INT1_PRGC             BIT(0)
+
+#define TPS65218_INT2_LS3_F            BIT(5)
+#define TPS65218_INT2_LS2_F            BIT(4)
+#define TPS65218_INT2_LS1_F            BIT(3)
+#define TPS65218_INT2_LS3_I            BIT(2)
+#define TPS65218_INT2_LS2_I            BIT(1)
+#define TPS65218_INT2_LS1_I            BIT(0)
+
+#define TPS65218_INT_MASK1_VPRG                BIT(5)
+#define TPS65218_INT_MASK1_AC          BIT(4)
+#define TPS65218_INT_MASK1_PB          BIT(3)
+#define TPS65218_INT_MASK1_HOT         BIT(2)
+#define TPS65218_INT_MASK1_CC_AQC      BIT(1)
+#define TPS65218_INT_MASK1_PRGC                BIT(0)
+
+#define TPS65218_INT_MASK2_LS3_F       BIT(5)
+#define TPS65218_INT_MASK2_LS2_F       BIT(4)
+#define TPS65218_INT_MASK2_LS1_F       BIT(3)
+#define TPS65218_INT_MASK2_LS3_I       BIT(2)
+#define TPS65218_INT_MASK2_LS2_I       BIT(1)
+#define TPS65218_INT_MASK2_LS1_I       BIT(0)
+
+#define TPS65218_STATUS_FSEAL          BIT(7)
+#define TPS65218_STATUS_EE             BIT(6)
+#define TPS65218_STATUS_AC_STATE       BIT(5)
+#define TPS65218_STATUS_PB_STATE       BIT(4)
+#define TPS65218_STATUS_STATE_MASK     0xC
+#define TPS65218_STATUS_CC_STAT                0x3
+
+#define TPS65218_CONTROL_OFFNPFO       BIT(1)
+#define TPS65218_CONTROL_CC_AQ BIT(0)
+
+#define TPS65218_FLAG_GPO3_FLG         BIT(7)
+#define TPS65218_FLAG_GPO2_FLG         BIT(6)
+#define TPS65218_FLAG_GPO1_FLG         BIT(5)
+#define TPS65218_FLAG_LDO1_FLG         BIT(4)
+#define TPS65218_FLAG_DC4_FLG          BIT(3)
+#define TPS65218_FLAG_DC3_FLG          BIT(2)
+#define TPS65218_FLAG_DC2_FLG          BIT(1)
+#define TPS65218_FLAG_DC1_FLG          BIT(0)
+
+#define TPS65218_ENABLE1_DC6_EN                BIT(5)
+#define TPS65218_ENABLE1_DC5_EN                BIT(4)
+#define TPS65218_ENABLE1_DC4_EN                BIT(3)
+#define TPS65218_ENABLE1_DC3_EN                BIT(2)
+#define TPS65218_ENABLE1_DC2_EN                BIT(1)
+#define TPS65218_ENABLE1_DC1_EN                BIT(0)
+
+#define TPS65218_ENABLE2_GPIO3         BIT(6)
+#define TPS65218_ENABLE2_GPIO2         BIT(5)
+#define TPS65218_ENABLE2_GPIO1         BIT(4)
+#define TPS65218_ENABLE2_LS3_EN                BIT(3)
+#define TPS65218_ENABLE2_LS2_EN                BIT(2)
+#define TPS65218_ENABLE2_LS1_EN                BIT(1)
+#define TPS65218_ENABLE2_LDO1_EN       BIT(0)
+
+
+#define TPS65218_CONFIG1_TRST          BIT(7)
+#define TPS65218_CONFIG1_GPO2_BUF      BIT(6)
+#define TPS65218_CONFIG1_IO1_SEL       BIT(5)
+#define TPS65218_CONFIG1_PGDLY_MASK    0x18
+#define TPS65218_CONFIG1_STRICT                BIT(2)
+#define TPS65218_CONFIG1_UVLO_MASK     0x3
+
+#define TPS65218_CONFIG2_DC12_RST      BIT(7)
+#define TPS65218_CONFIG2_UVLOHYS       BIT(6)
+#define TPS65218_CONFIG2_LS3ILIM_MASK  0xC
+#define TPS65218_CONFIG2_LS2ILIM_MASK  0x3
+
+#define TPS65218_CONFIG3_LS3NPFO       BIT(5)
+#define TPS65218_CONFIG3_LS2NPFO       BIT(4)
+#define TPS65218_CONFIG3_LS1NPFO       BIT(3)
+#define TPS65218_CONFIG3_LS3DCHRG      BIT(2)
+#define TPS65218_CONFIG3_LS2DCHRG      BIT(1)
+#define TPS65218_CONFIG3_LS1DCHRG      BIT(0)
+
+#define TPS65218_CONTROL_DCDC1_PFM     BIT(7)
+#define TPS65218_CONTROL_DCDC1_MASK    0x7F
+
+#define TPS65218_CONTROL_DCDC2_PFM     BIT(7)
+#define TPS65218_CONTROL_DCDC2_MASK    0x3F
+
+#define TPS65218_CONTROL_DCDC3_PFM     BIT(7)
+#define TPS65218_CONTROL_DCDC3_MASK    0x3F
+
+#define TPS65218_CONTROL_DCDC4_PFM     BIT(7)
+#define TPS65218_CONTROL_DCDC4_MASK    0x3F
+
+#define TPS65218_SLEW_RATE_GO          BIT(7)
+#define TPS65218_SLEW_RATE_GODSBL      BIT(6)
+#define TPS65218_SLEW_RATE_SLEW_MASK   0x7
+
+#define TPS65218_CONTROL_LDO1_MASK     0x3F
+
+#define TPS65218_SEQ1_DLY8             BIT(7)
+#define TPS65218_SEQ1_DLY7             BIT(6)
+#define TPS65218_SEQ1_DLY6             BIT(5)
+#define TPS65218_SEQ1_DLY5             BIT(4)
+#define TPS65218_SEQ1_DLY4             BIT(3)
+#define TPS65218_SEQ1_DLY3             BIT(2)
+#define TPS65218_SEQ1_DLY2             BIT(1)
+#define TPS65218_SEQ1_DLY1             BIT(0)
+
+#define TPS65218_SEQ2_DLYFCTR          BIT(7)
+#define TPS65218_SEQ2_DLY9             BIT(0)
+
+#define TPS65218_SEQ3_DC2_SEQ_MASK     0xF0
+#define TPS65218_SEQ3_DC1_SEQ_MASK     0xF
+
+#define TPS65218_SEQ4_DC4_SEQ_MASK     0xF0
+#define TPS65218_SEQ4_DC3_SEQ_MASK     0xF
+
+#define TPS65218_SEQ5_DC6_SEQ_MASK     0xF0
+#define TPS65218_SEQ5_DC5_SEQ_MASK     0xF
+
+#define TPS65218_SEQ6_LS1_SEQ_MASK     0xF0
+#define TPS65218_SEQ6_LDO1_SEQ_MASK    0xF
+
+#define TPS65218_SEQ7_GPO3_SEQ_MASK    0xF0
+#define TPS65218_SEQ7_GPO1_SEQ_MASK    0xF
+#define TPS65218_PROTECT_NONE          0
+#define TPS65218_PROTECT_L1            1
+
+enum tps65218_regulator_id {
+       /* DCDC's */
+       TPS65218_DCDC_1,
+       TPS65218_DCDC_2,
+       TPS65218_DCDC_3,
+       TPS65218_DCDC_4,
+       TPS65218_DCDC_5,
+       TPS65218_DCDC_6,
+       /* LDOs */
+       TPS65218_LDO_1,
+};
+
+#define TPS65218_MAX_REG_ID            TPS65218_LDO_1
+
+/* Number of step-down converters available */
+#define TPS65218_NUM_DCDC              6
+/* Number of LDO voltage regulators available */
+#define TPS65218_NUM_LDO               1
+/* Number of total regulators available */
+#define TPS65218_NUM_REGULATOR         (TPS65218_NUM_DCDC + TPS65218_NUM_LDO)
+
+/* Define the TPS65218 IRQ numbers */
+enum tps65218_irqs {
+       /* INT1 registers */
+       TPS65218_PRGC_IRQ,
+       TPS65218_CC_AQC_IRQ,
+       TPS65218_HOT_IRQ,
+       TPS65218_PB_IRQ,
+       TPS65218_AC_IRQ,
+       TPS65218_VPRG_IRQ,
+       TPS65218_INVALID1_IRQ,
+       TPS65218_INVALID2_IRQ,
+       /* INT2 registers */
+       TPS65218_LS1_I_IRQ,
+       TPS65218_LS2_I_IRQ,
+       TPS65218_LS3_I_IRQ,
+       TPS65218_LS1_F_IRQ,
+       TPS65218_LS2_F_IRQ,
+       TPS65218_LS3_F_IRQ,
+       TPS65218_INVALID3_IRQ,
+       TPS65218_INVALID4_IRQ,
+};
+
+/**
+ * struct tps_info - packages regulator constraints
+ * @id:                        Id of the regulator
+ * @name:              Voltage regulator name
+ * @min_uV:            minimum micro volts
+ * @max_uV:            minimum micro volts
+ *
+ * This data is used to check the regualtor voltage limits while setting.
+ */
+struct tps_info {
+       int id;
+       const char *name;
+       int min_uV;
+       int max_uV;
+};
+
+/**
+ * struct tps65218 - tps65218 sub-driver chip access routines
+ *
+ * Device data may be used to access the TPS65218 chip
+ */
+
+struct tps65218 {
+       struct device *dev;
+       unsigned int id;
+
+       struct mutex tps_lock;          /* lock guarding the data structure */
+       /* IRQ Data */
+       int irq;
+       u32 irq_mask;
+       struct regmap_irq_chip_data *irq_data;
+       struct regulator_desc desc[TPS65218_NUM_REGULATOR];
+       struct regulator_dev *rdev[TPS65218_NUM_REGULATOR];
+       struct tps_info *info[TPS65218_NUM_REGULATOR];
+       struct regmap *regmap;
+};
+
+int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
+                                       unsigned int *val);
+int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
+                       unsigned int val, unsigned int level);
+int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
+               unsigned int mask, unsigned int val, unsigned int level);
+int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg,
+               unsigned int mask, unsigned int level);
+
+#endif /*  __LINUX_MFD_TPS65218_H */
index 5a5053975114c962dd1d1cd1e9adc3e71da9bd23..f520a767c86ca7eb4e91a92d84f0c3f08c70e899 100644 (file)
@@ -82,15 +82,6 @@ void sort_extable(struct exception_table_entry *start,
 void sort_main_extable(void);
 void trim_init_extable(struct module *m);
 
-#ifdef MODULE
-#define MODULE_GENERIC_TABLE(gtype, name)                      \
-extern const struct gtype##_id __mod_##gtype##_table           \
-  __attribute__ ((unused, alias(__stringify(name))))
-
-#else  /* !MODULE */
-#define MODULE_GENERIC_TABLE(gtype, name)
-#endif
-
 /* Generic info of form tag = "info" */
 #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
 
@@ -141,8 +132,14 @@ extern const struct gtype##_id __mod_##gtype##_table               \
 /* What your module does. */
 #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
 
-#define MODULE_DEVICE_TABLE(type, name)                \
-  MODULE_GENERIC_TABLE(type##_device, name)
+#ifdef MODULE
+/* Creates an alias so file2alias.c can find device table. */
+#define MODULE_DEVICE_TABLE(type, name)                                        \
+  extern const struct type##_device_id __mod_##type##__##name##_device_table \
+  __attribute__ ((unused, alias(__stringify(name))))
+#else  /* !MODULE */
+#define MODULE_DEVICE_TABLE(type, name)
+#endif
 
 /* Version of form [<epoch>:]<version>[-<extra-version>].
  * Or for CVS/RCS ID version, everything but the number is stripped.
index c3eb102a9cc81d8ed97f11deb9584aa71830b1c5..204a677438049b13570e779f36078e0450298614 100644 (file)
@@ -186,14 +186,12 @@ struct kparam_array
    parameters. */
 #define __module_param_call(prefix, name, ops, arg, perm, level)       \
        /* Default value instead of permissions? */                     \
-       static int __param_perm_check_##name __attribute__((unused)) =  \
-       BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))  \
-       + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);   \
-       static const char __param_str_##name[] = prefix #name;          \
+       static const char __param_str_##name[] = prefix #name; \
        static struct kernel_param __moduleparam_const __param_##name   \
        __used                                                          \
     __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
-       = { __param_str_##name, ops, perm, level, { arg } }
+       = { __param_str_##name, ops, VERIFY_OCTAL_PERMISSIONS(perm),    \
+           level, { arg } }
 
 /* Obsolete - use module_param_cb() */
 #define module_param_call(name, set, get, arg, perm)                   \
@@ -346,7 +344,7 @@ static inline void destroy_params(const struct kernel_param *params,
 /* The macros to do compile-time type checking stolen from Jakub
    Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
 #define __param_check(name, p, type) \
-       static inline type *__check_##name(void) { return(p); }
+       static inline type __always_unused *__check_##name(void) { return(p); }
 
 extern struct kernel_param_ops param_ops_byte;
 extern int param_set_byte(const char *val, const struct kernel_param *kp);
index 8cc0e2fb68941f5169593076ad50411bb8939c85..a1b0b4c8fd79cd87bda46f1b15866a78dde89724 100644 (file)
@@ -204,12 +204,12 @@ struct mtd_info {
                          struct mtd_oob_ops *ops);
        int (*_write_oob) (struct mtd_info *mtd, loff_t to,
                           struct mtd_oob_ops *ops);
-       int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
-                                   size_t len);
+       int (*_get_fact_prot_info) (struct mtd_info *mtd, size_t len,
+                                   size_t *retlen, struct otp_info *buf);
        int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
                                    size_t len, size_t *retlen, u_char *buf);
-       int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
-                                   size_t len);
+       int (*_get_user_prot_info) (struct mtd_info *mtd, size_t len,
+                                   size_t *retlen, struct otp_info *buf);
        int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
                                    size_t len, size_t *retlen, u_char *buf);
        int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
@@ -278,12 +278,12 @@ static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
        return mtd->_write_oob(mtd, to, ops);
 }
 
-int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-                          size_t len);
+int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+                          struct otp_info *buf);
 int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
                           size_t *retlen, u_char *buf);
-int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-                          size_t len);
+int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+                          struct otp_info *buf);
 int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
                           size_t *retlen, u_char *buf);
 int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
index 32f8612469d8d2d2c5a659f9326551bcbbd8806b..450d61ec7f060982ff65bea2de2d35e275028877 100644 (file)
@@ -51,14 +51,6 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS         8
 
-/*
- * This constant declares the max. oobsize / page, which
- * is supported now. If you add a chip with bigger oobsize/page
- * adjust this accordingly.
- */
-#define NAND_MAX_OOBSIZE       744
-#define NAND_MAX_PAGESIZE      8192
-
 /*
  * Constants for hardware specific CLE/ALE/NCE function
  *
@@ -350,6 +342,84 @@ struct nand_onfi_vendor_micron {
        u8 param_revision;
 } __packed;
 
+struct jedec_ecc_info {
+       u8 ecc_bits;
+       u8 codeword_size;
+       __le16 bb_per_lun;
+       __le16 block_endurance;
+       u8 reserved[2];
+} __packed;
+
+/* JEDEC features */
+#define JEDEC_FEATURE_16_BIT_BUS       (1 << 0)
+
+struct nand_jedec_params {
+       /* rev info and features block */
+       /* 'J' 'E' 'S' 'D'  */
+       u8 sig[4];
+       __le16 revision;
+       __le16 features;
+       u8 opt_cmd[3];
+       __le16 sec_cmd;
+       u8 num_of_param_pages;
+       u8 reserved0[18];
+
+       /* manufacturer information block */
+       char manufacturer[12];
+       char model[20];
+       u8 jedec_id[6];
+       u8 reserved1[10];
+
+       /* memory organization block */
+       __le32 byte_per_page;
+       __le16 spare_bytes_per_page;
+       u8 reserved2[6];
+       __le32 pages_per_block;
+       __le32 blocks_per_lun;
+       u8 lun_count;
+       u8 addr_cycles;
+       u8 bits_per_cell;
+       u8 programs_per_page;
+       u8 multi_plane_addr;
+       u8 multi_plane_op_attr;
+       u8 reserved3[38];
+
+       /* electrical parameter block */
+       __le16 async_sdr_speed_grade;
+       __le16 toggle_ddr_speed_grade;
+       __le16 sync_ddr_speed_grade;
+       u8 async_sdr_features;
+       u8 toggle_ddr_features;
+       u8 sync_ddr_features;
+       __le16 t_prog;
+       __le16 t_bers;
+       __le16 t_r;
+       __le16 t_r_multi_plane;
+       __le16 t_ccs;
+       __le16 io_pin_capacitance_typ;
+       __le16 input_pin_capacitance_typ;
+       __le16 clk_pin_capacitance_typ;
+       u8 driver_strength_support;
+       __le16 t_ald;
+       u8 reserved4[36];
+
+       /* ECC and endurance block */
+       u8 guaranteed_good_blocks;
+       __le16 guaranteed_block_endurance;
+       struct jedec_ecc_info ecc_info[4];
+       u8 reserved5[29];
+
+       /* reserved */
+       u8 reserved6[148];
+
+       /* vendor */
+       __le16 vendor_rev_num;
+       u8 reserved7[88];
+
+       /* CRC for Parameter Page */
+       __le16 crc;
+} __packed;
+
 /**
  * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
  * @lock:               protection lock
@@ -418,7 +488,7 @@ struct nand_ecc_ctrl {
        int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
                        uint8_t *buf, int oob_required, int page);
        int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
-                       uint32_t offs, uint32_t len, uint8_t *buf);
+                       uint32_t offs, uint32_t len, uint8_t *buf, int page);
        int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
                        uint32_t offset, uint32_t data_len,
                        const uint8_t *data_buf, int oob_required);
@@ -435,17 +505,17 @@ struct nand_ecc_ctrl {
 
 /**
  * struct nand_buffers - buffer structure for read/write
- * @ecccalc:   buffer for calculated ECC
- * @ecccode:   buffer for ECC read from flash
- * @databuf:   buffer for data - dynamically sized
+ * @ecccalc:   buffer pointer for calculated ECC, size is oobsize.
+ * @ecccode:   buffer pointer for ECC read from flash, size is oobsize.
+ * @databuf:   buffer pointer for data, size is (page size + oobsize).
  *
  * Do not change the order of buffers. databuf and oobrbuf must be in
  * consecutive order.
  */
 struct nand_buffers {
-       uint8_t ecccalc[NAND_MAX_OOBSIZE];
-       uint8_t ecccode[NAND_MAX_OOBSIZE];
-       uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
+       uint8_t *ecccalc;
+       uint8_t *ecccode;
+       uint8_t *databuf;
 };
 
 /**
@@ -523,8 +593,12 @@ struct nand_buffers {
  * @subpagesize:       [INTERN] holds the subpagesize
  * @onfi_version:      [INTERN] holds the chip ONFI version (BCD encoded),
  *                     non 0 if ONFI supported.
+ * @jedec_version:     [INTERN] holds the chip JEDEC version (BCD encoded),
+ *                     non 0 if JEDEC supported.
  * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
  *                     supported, 0 otherwise.
+ * @jedec_params:      [INTERN] holds the JEDEC parameter page when JEDEC is
+ *                     supported, 0 otherwise.
  * @read_retries:      [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
@@ -597,7 +671,11 @@ struct nand_chip {
        int badblockbits;
 
        int onfi_version;
-       struct nand_onfi_params onfi_params;
+       int jedec_version;
+       union {
+               struct nand_onfi_params onfi_params;
+               struct nand_jedec_params jedec_params;
+       };
 
        int read_retries;
 
@@ -840,4 +918,29 @@ static inline bool nand_is_slc(struct nand_chip *chip)
 {
        return chip->bits_per_cell == 1;
 }
+
+/**
+ * Check if the opcode's address should be sent only on the lower 8 bits
+ * @command: opcode to check
+ */
+static inline int nand_opcode_8bits(unsigned int command)
+{
+       switch (command) {
+       case NAND_CMD_READID:
+       case NAND_CMD_PARAM:
+       case NAND_CMD_GET_FEATURES:
+       case NAND_CMD_SET_FEATURES:
+               return 1;
+       default:
+               break;
+       }
+       return 0;
+}
+
+/* return the supported JEDEC features. */
+static inline int jedec_feature(struct nand_chip *chip)
+{
+       return chip->jedec_version ? le16_to_cpu(chip->jedec_params.features)
+               : 0;
+}
 #endif /* __LINUX_MTD_NAND_H */
index 0ae5807480f466af6fc9de106b29207bc03f9752..fa6918b0f8295296a04e89c01c3b685dd360e1aa 100644 (file)
@@ -92,6 +92,7 @@ struct nfs_open_context {
 };
 
 struct nfs_open_dir_context {
+       struct list_head list;
        struct rpc_cred *cred;
        unsigned long attr_gencount;
        __u64 dir_cookie;
@@ -510,7 +511,6 @@ extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
 extern void nfs_wait_on_sillyrename(struct dentry *dentry);
 extern void nfs_block_sillyrename(struct dentry *dentry);
 extern void nfs_unblock_sillyrename(struct dentry *dentry);
-extern int  nfs_sillyrename(struct inode *dir, struct dentry *dentry);
 
 /*
  * linux/fs/nfs/write.c
index 5624e4e2763c2eb3d73f4e02d2752661ccd9c6b9..6fb5b2335b59041fbc9b2b62ca063aa6235de470 100644 (file)
@@ -1402,6 +1402,7 @@ struct nfs_renamedata {
        struct inode            *new_dir;
        struct dentry           *new_dentry;
        struct nfs_fattr        new_fattr;
+       void (*complete)(struct rpc_task *, struct nfs_renamedata *);
 };
 
 struct nfs_access_entry;
@@ -1444,8 +1445,6 @@ struct nfs_rpc_ops {
        void    (*unlink_setup)  (struct rpc_message *, struct inode *dir);
        void    (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *);
        int     (*unlink_done) (struct rpc_task *, struct inode *);
-       int     (*rename)  (struct inode *, struct qstr *,
-                           struct inode *, struct qstr *);
        void    (*rename_setup)  (struct rpc_message *msg, struct inode *dir);
        void    (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *);
        int     (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir);
index cb32d9c1e8dc83502e39143a8c25913bab3193d5..e266caa364029fafba52d443931f76d3758cc099 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <linux/of.h>
 int of_get_nand_ecc_mode(struct device_node *np);
+int of_get_nand_ecc_step_size(struct device_node *np);
+int of_get_nand_ecc_strength(struct device_node *np);
 int of_get_nand_bus_width(struct device_node *np);
 bool of_get_nand_on_flash_bbt(struct device_node *np);
 
@@ -23,6 +25,16 @@ static inline int of_get_nand_ecc_mode(struct device_node *np)
        return -ENOSYS;
 }
 
+static inline int of_get_nand_ecc_step_size(struct device_node *np)
+{
+       return -ENOSYS;
+}
+
+static inline int of_get_nand_ecc_strength(struct device_node *np)
+{
+       return -ENOSYS;
+}
+
 static inline int of_get_nand_bus_width(struct device_node *np)
 {
        return -ENOSYS;
index 7af25a9c9c5172b92a31e3626901971521530398..41a13e70f41f5ade5228404ec6557ea2be7d113c 100644 (file)
@@ -268,14 +268,27 @@ struct omap_dma_dev_attr {
        u32 dev_caps;
        u16 lch_count;
        u16 chan_count;
-       struct omap_dma_lch *chan;
+};
+
+enum {
+       OMAP_DMA_REG_NONE,
+       OMAP_DMA_REG_16BIT,
+       OMAP_DMA_REG_2X16BIT,
+       OMAP_DMA_REG_32BIT,
+};
+
+struct omap_dma_reg {
+       u16     offset;
+       u8      stride;
+       u8      type;
 };
 
 /* System DMA platform data structure */
 struct omap_system_dma_plat_info {
+       const struct omap_dma_reg *reg_map;
+       unsigned channel_stride;
        struct omap_dma_dev_attr *dma_attr;
        u32 errata;
-       void (*disable_irq_lch)(int lch);
        void (*show_dma_caps)(void);
        void (*clear_lch_regs)(int lch);
        void (*clear_dma)(int lch);
@@ -289,8 +302,12 @@ struct omap_system_dma_plat_info {
 #define dma_omap2plus()        0
 #endif
 #define dma_omap1()    (!dma_omap2plus())
-#define dma_omap15xx() ((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE)))
-#define dma_omap16xx() ((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE)))
+#define __dma_omap15xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_1510_MODE)
+#define __dma_omap16xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_16XX_MODE)
+#define dma_omap15xx() __dma_omap15xx(d)
+#define dma_omap16xx() __dma_omap16xx(d)
+
+extern struct omap_system_dma_plat_info *omap_get_plat_info(void);
 
 extern void omap_set_dma_priority(int lch, int dst_port, int priority);
 extern int omap_request_dma(int dev_id, const char *dev_name,
index e56b07f5c9b67f0119d874b60a8a6bed9fda7e99..3356abcfff184e707eccb08d6f99042a8fd51acc 100644 (file)
@@ -835,6 +835,8 @@ do {                                                                        \
                { .notifier_call = fn, .priority = CPU_PRI_PERF };      \
        unsigned long cpu = smp_processor_id();                         \
        unsigned long flags;                                            \
+                                                                       \
+       cpu_notifier_register_begin();                                  \
        fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,                     \
                (void *)(unsigned long)cpu);                            \
        local_irq_save(flags);                                          \
@@ -843,9 +845,21 @@ do {                                                                       \
        local_irq_restore(flags);                                       \
        fn(&fn##_nb, (unsigned long)CPU_ONLINE,                         \
                (void *)(unsigned long)cpu);                            \
-       register_cpu_notifier(&fn##_nb);                                \
+       __register_cpu_notifier(&fn##_nb);                              \
+       cpu_notifier_register_done();                                   \
 } while (0)
 
+/*
+ * Bare-bones version of perf_cpu_notifier(), which doesn't invoke the
+ * callback for already online CPUs.
+ */
+#define __perf_cpu_notifier(fn)                                                \
+do {                                                                   \
+       static struct notifier_block fn##_nb =                          \
+               { .notifier_call = fn, .priority = CPU_PRI_PERF };      \
+                                                                       \
+       __register_cpu_notifier(&fn##_nb);                              \
+} while (0)
 
 struct perf_pmu_events_attr {
        struct device_attribute attr;
index cea9f70133c521f1d5fb2a0d459f3e30ca3f9576..e26b0c14edea9c0864e6ebc4178537dc7a8eee75 100644 (file)
@@ -84,6 +84,7 @@ struct atmel_uart_data {
        short                   use_dma_rx;     /* use receive DMA? */
        void __iomem            *regs;          /* virt. base address, if any */
        struct serial_rs485     rs485;          /* rs485 settings */
+       int                     rts_gpio;       /* optional RTS GPIO */
 };
 
  /* Touchscreen Controller */
index 280edac9d0a5ca75185f151eb88cc3f362c695b7..addd48cac625b3fea87f3b8e989582d63cd50130 100644 (file)
@@ -1,3 +1,2 @@
-void integrator_clk_init(bool is_cp);
 void integrator_impd1_clk_init(void __iomem *base, unsigned int id);
 void integrator_impd1_clk_exit(unsigned int id);
index bf0a83b7ed9d3e0538cc09c57f7d498065931501..4edb40676b3f9b8b909e43a5b5af2bf6bb64efd6 100644 (file)
@@ -26,13 +26,6 @@ enum bch_ecc {
 /* ELM support 8 error syndrome process */
 #define ERROR_VECTOR_MAX               8
 
-#define BCH8_ECC_OOB_BYTES             13
-#define BCH4_ECC_OOB_BYTES             7
-/* RBL requires 14 byte even though BCH8 uses only 13 byte */
-#define BCH8_SIZE                      (BCH8_ECC_OOB_BYTES + 1)
-/* Uses 1 extra byte to handle erased pages */
-#define BCH4_SIZE                      (BCH4_ECC_OOB_BYTES + 1)
-
 /**
  * struct elm_errorvec - error vector for elm
  * @error_reported:            set true for vectors error is reported
@@ -50,5 +43,6 @@ struct elm_errorvec {
 
 void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
                struct elm_errorvec *err_vec);
-int elm_config(struct device *dev, enum bch_ecc bch_type);
+int elm_config(struct device *dev, enum bch_ecc bch_type,
+       int ecc_steps, int ecc_step_size, int ecc_syndrome_size);
 #endif /* __ELM_H */
index 05b293443097220a80a33f98ce2ed9cd44ad26be..97948ac2bb9be9de784ad7f14e73602f8793e670 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef _MACH_DAVINCI_AEMIF_H
 #define _MACH_DAVINCI_AEMIF_H
 
+#include <linux/platform_device.h>
+
 #define NRCSR_OFFSET           0x00
 #define AWCCR_OFFSET           0x04
 #define A1CR_OFFSET            0x10
@@ -31,6 +33,5 @@ struct davinci_aemif_timing {
        u8      ta;
 };
 
-int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
-                                       void __iomem *base, unsigned cs);
+int davinci_aemif_setup(struct platform_device *pdev);
 #endif
index b64115fa93a4dcff04adc74e24c8573388ac2db3..36bb92172f4795ff806275f8777d5ecf0bd93b1a 100644 (file)
@@ -1,5 +1,4 @@
-/* arch/arm/mach-s3c2410/include/mach/nand.h
- *
+/*
  * Copyright (c) 2004 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
@@ -10,6 +9,9 @@
  * published by the Free Software Foundation.
 */
 
+#ifndef __MTD_NAND_S3C2410_H
+#define __MTD_NAND_S3C2410_H
+
 /**
  * struct s3c2410_nand_set - define a set of one or more nand chips
  * @disable_ecc:       Entirely disable ECC - Dangerous
@@ -65,3 +67,5 @@ struct s3c2410_platform_nand {
  * it with the s3c_device_nand. This allows @nand to be __initdata.
 */
 extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
+
+#endif /*__MTD_NAND_S3C2410_H */
index 9de8f062ad5de01d77aed0641be39509db093ca9..18e908324549d47e82de5f5017842e1e2d14a432 100644 (file)
@@ -61,24 +61,12 @@ struct imx_fb_platform_data {
        struct imx_fb_videomode *mode;
        int             num_modes;
 
-       u_int           cmap_greyscale:1,
-                       cmap_inverse:1,
-                       cmap_static:1,
-                       unused:29;
-
        u_int           pwmr;
        u_int           lscr1;
        u_int           dmacr;
 
-       u_char * fixed_screen_cpu;
-       dma_addr_t fixed_screen_dma;
-
        int (*init)(struct platform_device *);
        void (*exit)(struct platform_device *);
-
-       void (*lcd_power)(int);
-       void (*backlight_power)(int);
 };
 
-void set_imx_fb_info(struct imx_fb_platform_data *);
 #endif /* ifndef __MACH_IMXFB_H__ */
index f0feafd184a0d655fff326bc979eebd21a7a28ab..4717f54051cb70543c745ff7ebba1aad5ed23a7f 100644 (file)
@@ -7,7 +7,7 @@
 struct pwm_device;
 struct seq_file;
 
-#if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
+#if IS_ENABLED(CONFIG_PWM)
 /*
  * pwm_request - request a PWM device
  */
index 49444203328ad8546b4299fb702d0155897bc0d0..f2b405116166c8f267cc7f7e5d53dc0277263212 100644 (file)
@@ -219,7 +219,7 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
        return __raw_readl(dev->mmio_base + reg);
 }
 
-#ifdef CONFIG_ARCH_PXA
+#if IS_ENABLED(CONFIG_PXA_SSP)
 struct ssp_device *pxa_ssp_request(int port, const char *label);
 void pxa_ssp_free(struct ssp_device *);
 struct ssp_device *pxa_ssp_request_of(const struct device_node *of_node,
index 1cfce0e24dbdb09a527d914ab511e6b6280fa364..57fbbffd77a0406fe57ce2abb5c2a24d819c45f9 100644 (file)
@@ -88,6 +88,22 @@ static inline int arch_get_random_int(unsigned int *v)
 {
        return 0;
 }
+static inline int arch_has_random(void)
+{
+       return 0;
+}
+static inline int arch_get_random_seed_long(unsigned long *v)
+{
+       return 0;
+}
+static inline int arch_get_random_seed_int(unsigned int *v)
+{
+       return 0;
+}
+static inline int arch_has_random_seed(void)
+{
+       return 0;
+}
 #endif
 
 /* Pseudo random number generator from numerical recipes. */
index 6082247feab11013e6b1f0faa3e2721bf6a643bc..c0eda5023d74351fd951e8f434a94a609cb10f4d 100644 (file)
@@ -4,6 +4,8 @@
 struct device;
 struct reset_control;
 
+#ifdef CONFIG_RESET_CONTROLLER
+
 int reset_control_reset(struct reset_control *rstc);
 int reset_control_assert(struct reset_control *rstc);
 int reset_control_deassert(struct reset_control *rstc);
@@ -12,6 +14,67 @@ struct reset_control *reset_control_get(struct device *dev, const char *id);
 void reset_control_put(struct reset_control *rstc);
 struct reset_control *devm_reset_control_get(struct device *dev, const char *id);
 
-int device_reset(struct device *dev);
+int __must_check device_reset(struct device *dev);
+
+static inline int device_reset_optional(struct device *dev)
+{
+       return device_reset(dev);
+}
+
+static inline struct reset_control *reset_control_get_optional(
+                                       struct device *dev, const char *id)
+{
+       return reset_control_get(dev, id);
+}
+
+static inline struct reset_control *devm_reset_control_get_optional(
+                                       struct device *dev, const char *id)
+{
+       return devm_reset_control_get(dev, id);
+}
+
+#else
+
+static inline int reset_control_reset(struct reset_control *rstc)
+{
+       WARN_ON(1);
+       return 0;
+}
+
+static inline int reset_control_assert(struct reset_control *rstc)
+{
+       WARN_ON(1);
+       return 0;
+}
+
+static inline int reset_control_deassert(struct reset_control *rstc)
+{
+       WARN_ON(1);
+       return 0;
+}
+
+static inline void reset_control_put(struct reset_control *rstc)
+{
+       WARN_ON(1);
+}
+
+static inline int device_reset_optional(struct device *dev)
+{
+       return -ENOSYS;
+}
+
+static inline struct reset_control *reset_control_get_optional(
+                                       struct device *dev, const char *id)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct reset_control *devm_reset_control_get_optional(
+                                       struct device *dev, const char *id)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+#endif /* CONFIG_RESET_CONTROLLER */
 
 #endif
index 2fc42d191f79f77236b843a70775129c01207333..6478ce3252c7d83fdd853ff2797a54d3cc591db6 100644 (file)
@@ -1793,7 +1793,8 @@ int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
 int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev);
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-                         struct inode *new_dir, struct dentry *new_dentry);
+                         struct inode *new_dir, struct dentry *new_dentry,
+                         unsigned int flags);
 int security_inode_readlink(struct dentry *dentry);
 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
 int security_inode_permission(struct inode *inode, int mask);
@@ -2161,7 +2162,8 @@ static inline int security_inode_mknod(struct inode *dir,
 static inline int security_inode_rename(struct inode *old_dir,
                                         struct dentry *old_dentry,
                                         struct inode *new_dir,
-                                        struct dentry *new_dentry)
+                                        struct dentry *new_dentry,
+                                        unsigned int flags)
 {
        return 0;
 }
@@ -2955,7 +2957,8 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
                       struct dentry *new_dentry);
 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
-                        struct path *new_dir, struct dentry *new_dentry);
+                        struct path *new_dir, struct dentry *new_dentry,
+                        unsigned int flags);
 int security_path_chmod(struct path *path, umode_t mode);
 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid);
 int security_path_chroot(struct path *path);
@@ -3003,7 +3006,8 @@ static inline int security_path_link(struct dentry *old_dentry,
 static inline int security_path_rename(struct path *old_dir,
                                       struct dentry *old_dentry,
                                       struct path *new_dir,
-                                      struct dentry *new_dentry)
+                                      struct dentry *new_dentry,
+                                      unsigned int flags)
 {
        return 0;
 }
index 907d9d1d56cf012cdbb04ed39e9aa3f1bd2cd2ad..e6fc9567690bc6d5fe59ac0dfcc88cbeaac01fc8 100644 (file)
 
 #ifndef __ASSEMBLY__
 
+#include <linux/serial_core.h>
+
 /* configuration structure for per-machine configurations for the
  * serial port
  *
index 60c72395ec6bf9f90a98b79f2698c72e161ae41e..1f208b2a1ed63d4aa7e45a91cd12f666c3ae5612 100644 (file)
@@ -52,6 +52,7 @@ struct clk {
        unsigned long           flags;
 
        void __iomem            *enable_reg;
+       void __iomem            *status_reg;
        unsigned int            enable_bit;
        void __iomem            *mapped_reg;
 
@@ -116,22 +117,26 @@ long clk_round_parent(struct clk *clk, unsigned long target,
                      unsigned long *best_freq, unsigned long *parent_freq,
                      unsigned int div_min, unsigned int div_max);
 
-#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags)         \
+#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _status_reg, _flags) \
 {                                                                      \
        .parent         = _parent,                                      \
        .enable_reg     = (void __iomem *)_enable_reg,                  \
        .enable_bit     = _enable_bit,                                  \
+       .status_reg     = _status_reg,                                  \
        .flags          = _flags,                                       \
 }
 
-#define SH_CLK_MSTP32(_p, _r, _b, _f)                                  \
-       SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT)
+#define SH_CLK_MSTP32(_p, _r, _b, _f)                          \
+       SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_32BIT)
 
-#define SH_CLK_MSTP16(_p, _r, _b, _f)                                  \
-       SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT)
+#define SH_CLK_MSTP32_STS(_p, _r, _b, _s, _f)                  \
+       SH_CLK_MSTP(_p, _r, _b, _s, _f | CLK_ENABLE_REG_32BIT)
 
-#define SH_CLK_MSTP8(_p, _r, _b, _f)                                   \
-       SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT)
+#define SH_CLK_MSTP16(_p, _r, _b, _f)                          \
+       SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_16BIT)
+
+#define SH_CLK_MSTP8(_p, _r, _b, _f)                           \
+       SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_8BIT)
 
 int sh_clk_mstp_register(struct clk *clks, int nr);
 
index bcbb642a7641d936c441e8c2211e9dc287513b6b..087b08a4d333a53f09b2e2bfcd0ea2fa68a608d3 100644 (file)
 int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len);
 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len);
 
+static inline int
+ssbi_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+       int ret;
+       u8 v;
+
+       ret = ssbi_read(context, reg, &v, 1);
+       if (!ret)
+               *val = v;
+
+       return ret;
+}
+
+static inline int
+ssbi_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+       u8 v = val;
+       return ssbi_write(context, reg, &v, 1);
+}
+
 #endif
index 969c0a671dbfbbab399f7472d501a93d75bbd8fc..2ca67b55e0fe2f0abf7e432ee8402608b6d57201 100644 (file)
@@ -32,7 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <linux/sunrpc/sched.h>
 
 #ifdef CONFIG_SUNRPC_BACKCHANNEL
-struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt);
+struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid);
+void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied);
 void xprt_free_bc_request(struct rpc_rqst *req);
 int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
 void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
index e0bf210ddffde0108e77820d81adc318332e2f19..084354b0e81451c651120afebdc75dfbaaec02f8 100644 (file)
@@ -71,7 +71,8 @@ struct attribute_group {
  */
 
 #define __ATTR(_name, _mode, _show, _store) {                          \
-       .attr = {.name = __stringify(_name), .mode = _mode },           \
+       .attr = {.name = __stringify(_name),                            \
+                .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },             \
        .show   = _show,                                                \
        .store  = _store,                                               \
 }
index e32251e00e62f0b2629c0ef7658d1445e6647586..edff2b97b86436a615895177b54b3de4a3f06aaa 100644 (file)
@@ -126,6 +126,7 @@ extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
 extern int  arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
 extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
 extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs);
+extern bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
index 559044c79232dcd27b18a3203d82295866fe949f..e7d9d9ed14f56252e5efe0a529e80f4dd050e1ab 100644 (file)
@@ -803,17 +803,6 @@ do {                                                                       \
        __ret;                                                          \
 })
 
-
-/*
- * These are the old interfaces to sleep waiting for an event.
- * They are racy.  DO NOT use them, use the wait_event* interfaces above.
- * We plan to remove these interfaces.
- */
-extern void sleep_on(wait_queue_head_t *q);
-extern long sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
-extern void interruptible_sleep_on(wait_queue_head_t *q);
-extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
-
 /*
  * Waitqueues which are removed from the waitqueue_head at wakeup time
  */
diff --git a/include/linux/xilinxfb.h b/include/linux/xilinxfb.h
deleted file mode 100644 (file)
index 5a155a9..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Platform device data for Xilinx Framebuffer device
- *
- * Copyright 2007 Secret Lab Technologies Ltd.
- *
- * 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 __XILINXFB_H__
-#define __XILINXFB_H__
-
-#include <linux/types.h>
-
-/* ML300/403 reference design framebuffer driver platform data struct */
-struct xilinxfb_platform_data {
-       u32 rotate_screen;      /* Flag to rotate display 180 degrees */
-       u32 screen_height_mm;   /* Physical dimensions of screen in mm */
-       u32 screen_width_mm;
-       u32 xres, yres;         /* resolution of screen in pixels */
-       u32 xvirt, yvirt;       /* resolution of memory buffer */
-
-       /* Physical address of framebuffer memory; If non-zero, driver
-        * will use provided memory address instead of allocating one from
-        * the consistent pool. */
-       u32 fb_phys;
-};
-
-#endif  /* __XILINXFB_H__ */
index 39322091e8b0dc6355ced09aad7cb56a08588157..924cbb8d004a76b548ba6bbffcd13f863a569b5c 100644 (file)
@@ -220,6 +220,9 @@ struct adv7842_platform_data {
        unsigned sdp_free_run_cbar_en:1;
        unsigned sdp_free_run_force:1;
 
+       /* HPA manual (0) or auto (1), affects HDMI register 0x69 */
+       unsigned hpa_auto:1;
+
        struct adv7842_sdp_csc_coeff sdp_csc_coeff;
 
        struct adv7842_sdp_io_sync_adjustment sdp_io_sync_625;
diff --git a/include/media/lm3646.h b/include/media/lm3646.h
new file mode 100644 (file)
index 0000000..c6acf5a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * include/media/lm3646.h
+ *
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * Contact: Daniel Jeong <gshark.jeong@gmail.com>
+ *                     Ldd-Mlp <ldd-mlp@list.ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef __LM3646_H__
+#define __LM3646_H__
+
+#include <media/v4l2-subdev.h>
+
+#define LM3646_NAME    "lm3646"
+#define LM3646_I2C_ADDR_REV1   (0x67)
+#define LM3646_I2C_ADDR_REV0   (0x63)
+
+/*  TOTAL FLASH Brightness Max
+ *     min 93350uA, step 93750uA, max 1499600uA
+ */
+#define LM3646_TOTAL_FLASH_BRT_MIN 93350
+#define LM3646_TOTAL_FLASH_BRT_STEP 93750
+#define LM3646_TOTAL_FLASH_BRT_MAX 1499600
+#define LM3646_TOTAL_FLASH_BRT_uA_TO_REG(a)    \
+       ((a) < LM3646_TOTAL_FLASH_BRT_MIN ? 0 : \
+        ((((a) - LM3646_TOTAL_FLASH_BRT_MIN) / LM3646_TOTAL_FLASH_BRT_STEP)))
+
+/*  TOTAL TORCH Brightness Max
+ *     min 23040uA, step 23430uA, max 187100uA
+ */
+#define LM3646_TOTAL_TORCH_BRT_MIN 23040
+#define LM3646_TOTAL_TORCH_BRT_STEP 23430
+#define LM3646_TOTAL_TORCH_BRT_MAX 187100
+#define LM3646_TOTAL_TORCH_BRT_uA_TO_REG(a)    \
+       ((a) < LM3646_TOTAL_TORCH_BRT_MIN ? 0 : \
+        ((((a) - LM3646_TOTAL_TORCH_BRT_MIN) / LM3646_TOTAL_TORCH_BRT_STEP)))
+
+/*  LED1 FLASH Brightness
+ *     min 23040uA, step 11718uA, max 1499600uA
+ */
+#define LM3646_LED1_FLASH_BRT_MIN 23040
+#define LM3646_LED1_FLASH_BRT_STEP 11718
+#define LM3646_LED1_FLASH_BRT_MAX 1499600
+#define LM3646_LED1_FLASH_BRT_uA_TO_REG(a)     \
+       ((a) <= LM3646_LED1_FLASH_BRT_MIN ? 0 : \
+        ((((a) - LM3646_LED1_FLASH_BRT_MIN) / LM3646_LED1_FLASH_BRT_STEP))+1)
+
+/*  LED1 TORCH Brightness
+ *     min 2530uA, step 1460uA, max 187100uA
+ */
+#define LM3646_LED1_TORCH_BRT_MIN 2530
+#define LM3646_LED1_TORCH_BRT_STEP 1460
+#define LM3646_LED1_TORCH_BRT_MAX 187100
+#define LM3646_LED1_TORCH_BRT_uA_TO_REG(a)     \
+       ((a) <= LM3646_LED1_TORCH_BRT_MIN ? 0 : \
+        ((((a) - LM3646_LED1_TORCH_BRT_MIN) / LM3646_LED1_TORCH_BRT_STEP))+1)
+
+/*  FLASH TIMEOUT DURATION
+ *     min 50ms, step 50ms, max 400ms
+ */
+#define LM3646_FLASH_TOUT_MIN 50
+#define LM3646_FLASH_TOUT_STEP 50
+#define LM3646_FLASH_TOUT_MAX 400
+#define LM3646_FLASH_TOUT_ms_TO_REG(a) \
+       ((a) <= LM3646_FLASH_TOUT_MIN ? 0 :     \
+        (((a) - LM3646_FLASH_TOUT_MIN) / LM3646_FLASH_TOUT_STEP))
+
+/* struct lm3646_platform_data
+ *
+ * @flash_timeout: flash timeout
+ * @led1_flash_brt: led1 flash mode brightness, uA
+ * @led1_torch_brt: led1 torch mode brightness, uA
+ */
+struct lm3646_platform_data {
+
+       u32 flash_timeout;
+
+       u32 led1_flash_brt;
+       u32 led1_torch_brt;
+};
+
+#endif /* __LM3646_H__ */
index 2f6f1f78d958c5238e3f0a145c0c33c0a38b45f0..0b9f890ce43162e572b3ac55d8cd72e8166f893c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Remote Controller core header
  *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -34,6 +34,29 @@ enum rc_driver_type {
        RC_DRIVER_IR_RAW,       /* Needs a Infra-Red pulse/space decoder */
 };
 
+/**
+ * struct rc_scancode_filter - Filter scan codes.
+ * @data:      Scancode data to match.
+ * @mask:      Mask of bits of scancode to compare.
+ */
+struct rc_scancode_filter {
+       u32 data;
+       u32 mask;
+};
+
+/**
+ * enum rc_filter_type - Filter type constants.
+ * @RC_FILTER_NORMAL:  Filter for normal operation.
+ * @RC_FILTER_WAKEUP:  Filter for waking from suspend.
+ * @RC_FILTER_MAX:     Number of filter types.
+ */
+enum rc_filter_type {
+       RC_FILTER_NORMAL = 0,
+       RC_FILTER_WAKEUP,
+
+       RC_FILTER_MAX
+};
+
 /**
  * struct rc_dev - represents a remote control device
  * @dev: driver model's view of this device
@@ -50,8 +73,10 @@ enum rc_driver_type {
  * @input_dev: the input child device used to communicate events to userspace
  * @driver_type: specifies if protocol decoding is done in hardware or software
  * @idle: used to keep track of RX state
- * @allowed_protos: bitmask with the supported RC_BIT_* protocols
- * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols
+ * @allowed_protocols: bitmask with the supported RC_BIT_* protocols for each
+ *     filter type
+ * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols for each
+ *     filter type
  * @scanmask: some hardware decoders are not capable of providing the full
  *     scancode to the application. As this is a hardware limit, we can't do
  *     anything with it. Yet, as the same keycode table can be used with other
@@ -70,7 +95,10 @@ enum rc_driver_type {
  * @max_timeout: maximum timeout supported by device
  * @rx_resolution : resolution (in ns) of input sampler
  * @tx_resolution: resolution (in ns) of output sampler
+ * @scancode_filters: scancode filters (indexed by enum rc_filter_type)
  * @change_protocol: allow changing the protocol used on hardware decoders
+ * @change_wakeup_protocol: allow changing the protocol used for wakeup
+ *     filtering
  * @open: callback to allow drivers to enable polling/irq when IR input device
  *     is opened.
  * @close: callback to allow drivers to disable polling/irq when IR input device
@@ -84,6 +112,7 @@ enum rc_driver_type {
  *     device doesn't interrupt host until it sees IR pulses
  * @s_learning_mode: enable wide band receiver used for learning
  * @s_carrier_report: enable carrier reports
+ * @s_filter: set the scancode filter of a given type
  */
 struct rc_dev {
        struct device                   dev;
@@ -99,8 +128,8 @@ struct rc_dev {
        struct input_dev                *input_dev;
        enum rc_driver_type             driver_type;
        bool                            idle;
-       u64                             allowed_protos;
-       u64                             enabled_protocols;
+       u64                             allowed_protocols[RC_FILTER_MAX];
+       u64                             enabled_protocols[RC_FILTER_MAX];
        u32                             users;
        u32                             scanmask;
        void                            *priv;
@@ -116,7 +145,9 @@ struct rc_dev {
        u32                             max_timeout;
        u32                             rx_resolution;
        u32                             tx_resolution;
+       struct rc_scancode_filter       scancode_filters[RC_FILTER_MAX];
        int                             (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
+       int                             (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type);
        int                             (*open)(struct rc_dev *dev);
        void                            (*close)(struct rc_dev *dev);
        int                             (*s_tx_mask)(struct rc_dev *dev, u32 mask);
@@ -127,10 +158,49 @@ struct rc_dev {
        void                            (*s_idle)(struct rc_dev *dev, bool enable);
        int                             (*s_learning_mode)(struct rc_dev *dev, int enable);
        int                             (*s_carrier_report) (struct rc_dev *dev, int enable);
+       int                             (*s_filter)(struct rc_dev *dev,
+                                                   enum rc_filter_type type,
+                                                   struct rc_scancode_filter *filter);
 };
 
 #define to_rc_dev(d) container_of(d, struct rc_dev, dev)
 
+static inline bool rc_protocols_allowed(struct rc_dev *rdev, u64 protos)
+{
+       return rdev->allowed_protocols[RC_FILTER_NORMAL] & protos;
+}
+
+/* should be called prior to registration or with mutex held */
+static inline void rc_set_allowed_protocols(struct rc_dev *rdev, u64 protos)
+{
+       rdev->allowed_protocols[RC_FILTER_NORMAL] = protos;
+}
+
+static inline bool rc_protocols_enabled(struct rc_dev *rdev, u64 protos)
+{
+       return rdev->enabled_protocols[RC_FILTER_NORMAL] & protos;
+}
+
+/* should be called prior to registration or with mutex held */
+static inline void rc_set_enabled_protocols(struct rc_dev *rdev, u64 protos)
+{
+       rdev->enabled_protocols[RC_FILTER_NORMAL] = protos;
+}
+
+/* should be called prior to registration or with mutex held */
+static inline void rc_set_allowed_wakeup_protocols(struct rc_dev *rdev,
+                                                  u64 protos)
+{
+       rdev->allowed_protocols[RC_FILTER_WAKEUP] = protos;
+}
+
+/* should be called prior to registration or with mutex held */
+static inline void rc_set_enabled_wakeup_protocols(struct rc_dev *rdev,
+                                                  u64 protos)
+{
+       rdev->enabled_protocols[RC_FILTER_WAKEUP] = protos;
+}
+
 /*
  * From rc-main.c
  * Those functions can be used on any type of Remote Controller. They
index a20ed97d7d8a048374a20db3d8c0b65e4590b502..e5aa2409c0ea078eb51eccbed21b5bccd994fade 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rc-map.h - define RC map names used by RC drivers
  *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
  *
  * 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
@@ -30,6 +30,7 @@ enum rc_type {
        RC_TYPE_RC6_6A_24       = 15,   /* Philips RC6-6A-24 protocol */
        RC_TYPE_RC6_6A_32       = 16,   /* Philips RC6-6A-32 protocol */
        RC_TYPE_RC6_MCE         = 17,   /* MCE (Philips RC6-6A-32 subtype) protocol */
+       RC_TYPE_SHARP           = 18,   /* Sharp protocol */
 };
 
 #define RC_BIT_NONE            0
@@ -51,6 +52,7 @@ enum rc_type {
 #define RC_BIT_RC6_6A_24       (1 << RC_TYPE_RC6_6A_24)
 #define RC_BIT_RC6_6A_32       (1 << RC_TYPE_RC6_6A_32)
 #define RC_BIT_RC6_MCE         (1 << RC_TYPE_RC6_MCE)
+#define RC_BIT_SHARP           (1 << RC_TYPE_SHARP)
 
 #define RC_BIT_ALL     (RC_BIT_UNKNOWN | RC_BIT_OTHER | RC_BIT_LIRC | \
                         RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \
@@ -58,7 +60,7 @@ enum rc_type {
                         RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \
                         RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \
                         RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
-                        RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)
+                        RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP)
 
 struct rc_map_table {
        u32     scancode;
index c768c9f8abc2ca0f1125cf7c1ce9135587bbefbc..eec6e460f649ed26465f47a371af16133b3e59e7 100644 (file)
@@ -24,7 +24,8 @@
 #define VFL_TYPE_VBI           1
 #define VFL_TYPE_RADIO         2
 #define VFL_TYPE_SUBDEV                3
-#define VFL_TYPE_MAX           4
+#define VFL_TYPE_SDR           4
+#define VFL_TYPE_MAX           5
 
 /* Is this a receiver, transmitter or mem-to-mem? */
 /* Ignored for VFL_TYPE_SUBDEV. */
index e0b74a430b3aa0597b8aa86e6b906206bb34cf25..50cf7c110a70ead9197ca15928d2cd1520285889 100644 (file)
@@ -40,6 +40,8 @@ struct v4l2_ioctl_ops {
                                              struct v4l2_fmtdesc *f);
        int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh,
                                              struct v4l2_fmtdesc *f);
+       int (*vidioc_enum_fmt_sdr_cap)     (struct file *file, void *fh,
+                                           struct v4l2_fmtdesc *f);
 
        /* VIDIOC_G_FMT handlers */
        int (*vidioc_g_fmt_vid_cap)    (struct file *file, void *fh,
@@ -62,6 +64,8 @@ struct v4l2_ioctl_ops {
                                           struct v4l2_format *f);
        int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh,
                                           struct v4l2_format *f);
+       int (*vidioc_g_fmt_sdr_cap)    (struct file *file, void *fh,
+                                       struct v4l2_format *f);
 
        /* VIDIOC_S_FMT handlers */
        int (*vidioc_s_fmt_vid_cap)    (struct file *file, void *fh,
@@ -84,6 +88,8 @@ struct v4l2_ioctl_ops {
                                           struct v4l2_format *f);
        int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh,
                                           struct v4l2_format *f);
+       int (*vidioc_s_fmt_sdr_cap)    (struct file *file, void *fh,
+                                       struct v4l2_format *f);
 
        /* VIDIOC_TRY_FMT handlers */
        int (*vidioc_try_fmt_vid_cap)    (struct file *file, void *fh,
@@ -106,6 +112,8 @@ struct v4l2_ioctl_ops {
                                             struct v4l2_format *f);
        int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh,
                                             struct v4l2_format *f);
+       int (*vidioc_try_fmt_sdr_cap)    (struct file *file, void *fh,
+                                         struct v4l2_format *f);
 
        /* Buffer handlers */
        int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
@@ -265,6 +273,8 @@ struct v4l2_ioctl_ops {
                                    struct v4l2_enum_dv_timings *timings);
        int (*vidioc_dv_timings_cap) (struct file *file, void *fh,
                                    struct v4l2_dv_timings_cap *cap);
+       int (*vidioc_g_edid) (struct file *file, void *fh, struct v4l2_edid *edid);
+       int (*vidioc_s_edid) (struct file *file, void *fh, struct v4l2_edid *edid);
 
        int (*vidioc_subscribe_event)  (struct v4l2_fh *fh,
                                        const struct v4l2_event_subscription *sub);
index d67210a37ef376192dcd70e5004c4b526ea753e8..28f4d8c3cf7d4f18acacfded4f4fde98419374ea 100644 (file)
@@ -162,6 +162,10 @@ struct v4l2_subdev_core_ops {
        int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm);
        int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
        long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+#ifdef CONFIG_COMPAT
+       long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd,
+                              unsigned long arg);
+#endif
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
        int (*s_register)(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg);
@@ -192,6 +196,7 @@ struct v4l2_subdev_tuner_ops {
        int (*s_radio)(struct v4l2_subdev *sd);
        int (*s_frequency)(struct v4l2_subdev *sd, const struct v4l2_frequency *freq);
        int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
+       int (*enum_freq_bands)(struct v4l2_subdev *sd, struct v4l2_frequency_band *band);
        int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
        int (*s_tuner)(struct v4l2_subdev *sd, const struct v4l2_tuner *vt);
        int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
@@ -503,8 +508,8 @@ struct v4l2_subdev_pad_ops {
                             struct v4l2_subdev_selection *sel);
        int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
                             struct v4l2_subdev_selection *sel);
-       int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid);
-       int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid);
+       int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
+       int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
 #ifdef CONFIG_MEDIA_CONTROLLER
        int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
                             struct v4l2_subdev_format *source_fmt,
index bef53ce555d2641d9538dad2982856e9677c8dd4..af46211097269b3a47c38065f6f5567e3f615a4e 100644 (file)
@@ -34,49 +34,49 @@ struct vb2_fileio_data;
  *             usually will result in the allocator freeing the buffer (if
  *             no other users of this buffer are present); the buf_priv
  *             argument is the allocator private per-buffer structure
- *             previously returned from the alloc callback
+ *             previously returned from the alloc callback.
  * @get_userptr: acquire userspace memory for a hardware operation; used for
  *              USERPTR memory types; vaddr is the address passed to the
  *              videobuf layer when queuing a video buffer of USERPTR type;
  *              should return an allocator private per-buffer structure
  *              associated with the buffer on success, NULL on failure;
  *              the returned private structure will then be passed as buf_priv
- *              argument to other ops in this structure
+ *              argument to other ops in this structure.
  * @put_userptr: inform the allocator that a USERPTR buffer will no longer
- *              be used
+ *              be used.
  * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
  *                used for DMABUF memory types; alloc_ctx is the alloc context
  *                dbuf is the shared dma_buf; returns NULL on failure;
  *                allocator private per-buffer structure on success;
- *                this needs to be used for further accesses to the buffer
+ *                this needs to be used for further accesses to the buffer.
  * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF
  *                buffer is no longer used; the buf_priv argument is the
  *                allocator private per-buffer structure previously returned
- *                from the attach_dmabuf callback
+ *                from the attach_dmabuf callback.
  * @map_dmabuf: request for access to the dmabuf from allocator; the allocator
  *             of dmabuf is informed that this driver is going to use the
- *             dmabuf
+ *             dmabuf.
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
- *               that this driver is done using the dmabuf for now
+ *               that this driver is done using the dmabuf for now.
  * @prepare:   called every time the buffer is passed from userspace to the
- *             driver, useful for cache synchronisation, optional
+ *             driver, useful for cache synchronisation, optional.
  * @finish:    called every time the buffer is passed back from the driver
- *             to the userspace, also optional
+ *             to the userspace, also optional.
  * @vaddr:     return a kernel virtual address to a given memory buffer
  *             associated with the passed private structure or NULL if no
- *             such mapping exists
+ *             such mapping exists.
  * @cookie:    return allocator specific cookie for a given memory buffer
  *             associated with the passed private structure or NULL if not
- *             available
+ *             available.
  * @num_users: return the current number of users of a memory buffer;
  *             return 1 if the videobuf layer (or actually the driver using
- *             it) is the only user
+ *             it) is the only user.
  * @mmap:      setup a userspace mapping for a given memory buffer under
- *             the provided virtual memory region
+ *             the provided virtual memory region.
  *
  * Required ops for USERPTR types: get_userptr, put_userptr.
  * Required ops for MMAP types: alloc, put, num_users, mmap.
- * Required ops for read/write access types: alloc, put, num_users, vaddr
+ * Required ops for read/write access types: alloc, put, num_users, vaddr.
  * Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf,
  *                               unmap_dmabuf.
  */
@@ -203,6 +203,37 @@ struct vb2_buffer {
        struct list_head        done_entry;
 
        struct vb2_plane        planes[VIDEO_MAX_PLANES];
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       /*
+        * Counters for how often these buffer-related ops are
+        * called. Used to check for unbalanced ops.
+        */
+       u32             cnt_mem_alloc;
+       u32             cnt_mem_put;
+       u32             cnt_mem_get_dmabuf;
+       u32             cnt_mem_get_userptr;
+       u32             cnt_mem_put_userptr;
+       u32             cnt_mem_prepare;
+       u32             cnt_mem_finish;
+       u32             cnt_mem_attach_dmabuf;
+       u32             cnt_mem_detach_dmabuf;
+       u32             cnt_mem_map_dmabuf;
+       u32             cnt_mem_unmap_dmabuf;
+       u32             cnt_mem_vaddr;
+       u32             cnt_mem_cookie;
+       u32             cnt_mem_num_users;
+       u32             cnt_mem_mmap;
+
+       u32             cnt_buf_init;
+       u32             cnt_buf_prepare;
+       u32             cnt_buf_finish;
+       u32             cnt_buf_cleanup;
+       u32             cnt_buf_queue;
+
+       /* This counts the number of calls to vb2_buffer_done() */
+       u32             cnt_buf_done;
+#endif
 };
 
 /**
@@ -227,27 +258,35 @@ struct vb2_buffer {
  * @wait_prepare:      release any locks taken while calling vb2 functions;
  *                     it is called before an ioctl needs to wait for a new
  *                     buffer to arrive; required to avoid a deadlock in
- *                     blocking access type
+ *                     blocking access type.
  * @wait_finish:       reacquire all locks released in the previous callback;
  *                     required to continue operation after sleeping while
- *                     waiting for a new buffer to arrive
+ *                     waiting for a new buffer to arrive.
  * @buf_init:          called once after allocating a buffer (in MMAP case)
  *                     or after acquiring a new USERPTR buffer; drivers may
  *                     perform additional buffer-related initialization;
  *                     initialization failure (return != 0) will prevent
- *                     queue setup from completing successfully; optional
+ *                     queue setup from completing successfully; optional.
  * @buf_prepare:       called every time the buffer is queued from userspace
  *                     and from the VIDIOC_PREPARE_BUF ioctl; drivers may
  *                     perform any initialization required before each hardware
  *                     operation in this callback; drivers that support
  *                     VIDIOC_CREATE_BUFS must also validate the buffer size;
  *                     if an error is returned, the buffer will not be queued
- *                     in driver; optional
+ *                     in driver; optional.
  * @buf_finish:                called before every dequeue of the buffer back to
  *                     userspace; drivers may perform any operations required
- *                     before userspace accesses the buffer; optional
+ *                     before userspace accesses the buffer; optional. The
+ *                     buffer state can be one of the following: DONE and
+ *                     ERROR occur while streaming is in progress, and the
+ *                     PREPARED state occurs when the queue has been canceled
+ *                     and all pending buffers are being returned to their
+ *                     default DEQUEUED state. Typically you only have to do
+ *                     something if the state is VB2_BUF_STATE_DONE, since in
+ *                     all other cases the buffer contents will be ignored
+ *                     anyway.
  * @buf_cleanup:       called once before the buffer is freed; drivers may
- *                     perform any additional cleanup; optional
+ *                     perform any additional cleanup; optional.
  * @start_streaming:   called once to enter 'streaming' state; the driver may
  *                     receive buffers with @buf_queue callback before
  *                     @start_streaming is called; the driver gets the number
@@ -268,7 +307,7 @@ struct vb2_buffer {
  *                     the buffer back by calling vb2_buffer_done() function;
  *                     it is allways called after calling STREAMON ioctl;
  *                     might be called before start_streaming callback if user
- *                     pre-queued buffers before calling STREAMON
+ *                     pre-queued buffers before calling STREAMON.
  */
 struct vb2_ops {
        int (*queue_setup)(struct vb2_queue *q, const struct v4l2_format *fmt,
@@ -280,7 +319,7 @@ struct vb2_ops {
 
        int (*buf_init)(struct vb2_buffer *vb);
        int (*buf_prepare)(struct vb2_buffer *vb);
-       int (*buf_finish)(struct vb2_buffer *vb);
+       void (*buf_finish)(struct vb2_buffer *vb);
        void (*buf_cleanup)(struct vb2_buffer *vb);
 
        int (*start_streaming)(struct vb2_queue *q, unsigned int count);
@@ -312,23 +351,29 @@ struct v4l2_fh;
  * @buf_struct_size: size of the driver-specific buffer structure;
  *             "0" indicates the driver doesn't want to use a custom buffer
  *             structure type, so sizeof(struct vb2_buffer) will is used
+ * @timestamp_flags: Timestamp flags; V4L2_BUF_FLAGS_TIMESTAMP_* and
+ *             V4L2_BUF_FLAGS_TSTAMP_SRC_*
  * @gfp_flags: additional gfp flags used when allocating the buffers.
  *             Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32
  *             to force the buffer allocation to a specific memory zone.
+ * @min_buffers_needed: the minimum number of buffers needed before
+ *             start_streaming() can be called. Used when a DMA engine
+ *             cannot be started unless at least this number of buffers
+ *             have been queued into the driver.
  *
  * @memory:    current memory type used
  * @bufs:      videobuf buffer structures
  * @num_buffers: number of allocated/used buffers
  * @queued_list: list of buffers currently queued from userspace
- * @queued_count: number of buffers owned by the driver
+ * @queued_count: number of buffers queued and ready for streaming.
+ * @owned_by_drv_count: number of buffers owned by the driver
  * @done_list: list of buffers ready to be dequeued to userspace
  * @done_lock: lock to protect done_list list
  * @done_wq:   waitqueue for processes waiting for buffers ready to be dequeued
  * @alloc_ctx: memory type/allocator-specific contexts for each plane
  * @streaming: current streaming state
- * @retry_start_streaming: start_streaming() was called, but there were not enough
- *             buffers queued. If set, then retry calling start_streaming when
- *             queuing a new buffer.
+ * @start_streaming_called: start_streaming() was called successfully and we
+ *             started streaming.
  * @fileio:    file io emulator internal data, used only if emulator is active
  */
 struct vb2_queue {
@@ -342,8 +387,9 @@ struct vb2_queue {
        const struct vb2_mem_ops        *mem_ops;
        void                            *drv_priv;
        unsigned int                    buf_struct_size;
-       u32                             timestamp_type;
+       u32                             timestamp_flags;
        gfp_t                           gfp_flags;
+       u32                             min_buffers_needed;
 
 /* private: internal use only */
        enum v4l2_memory                memory;
@@ -351,8 +397,9 @@ struct vb2_queue {
        unsigned int                    num_buffers;
 
        struct list_head                queued_list;
+       unsigned int                    queued_count;
 
-       atomic_t                        queued_count;
+       atomic_t                        owned_by_drv_count;
        struct list_head                done_list;
        spinlock_t                      done_lock;
        wait_queue_head_t               done_wq;
@@ -361,9 +408,21 @@ struct vb2_queue {
        unsigned int                    plane_sizes[VIDEO_MAX_PLANES];
 
        unsigned int                    streaming:1;
-       unsigned int                    retry_start_streaming:1;
+       unsigned int                    start_streaming_called:1;
 
        struct vb2_fileio_data          *fileio;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       /*
+        * Counters for how often these queue-related ops are
+        * called. Used to check for unbalanced ops.
+        */
+       u32                             cnt_queue_setup;
+       u32                             cnt_wait_prepare;
+       u32                             cnt_wait_finish;
+       u32                             cnt_start_streaming;
+       u32                             cnt_stop_streaming;
+#endif
 };
 
 void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
index 3176cdc32937f4b62cbcd11e878310f1b086f15e..4ee4e30d26d9b3a9d5bccbb51348e0b876365f26 100644 (file)
@@ -21,6 +21,8 @@ struct btrfs_block_group_cache;
 struct btrfs_free_cluster;
 struct map_lookup;
 struct extent_buffer;
+struct btrfs_work;
+struct __btrfs_workqueue;
 
 #define show_ref_type(type)                                            \
        __print_symbolic(type,                                          \
@@ -982,6 +984,141 @@ TRACE_EVENT(free_extent_state,
                  (void *)__entry->ip)
 );
 
+DECLARE_EVENT_CLASS(btrfs__work,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work),
+
+       TP_STRUCT__entry(
+               __field(        void *, work                    )
+               __field(        void *, wq                      )
+               __field(        void *, func                    )
+               __field(        void *, ordered_func            )
+               __field(        void *, ordered_free            )
+       ),
+
+       TP_fast_assign(
+               __entry->work           = work;
+               __entry->wq             = work->wq;
+               __entry->func           = work->func;
+               __entry->ordered_func   = work->ordered_func;
+               __entry->ordered_free   = work->ordered_free;
+       ),
+
+       TP_printk("work=%p, wq=%p, func=%p, ordered_func=%p, ordered_free=%p",
+                 __entry->work, __entry->wq, __entry->func,
+                 __entry->ordered_func, __entry->ordered_free)
+);
+
+/* For situiations that the work is freed */
+DECLARE_EVENT_CLASS(btrfs__work__done,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work),
+
+       TP_STRUCT__entry(
+               __field(        void *, work                    )
+       ),
+
+       TP_fast_assign(
+               __entry->work           = work;
+       ),
+
+       TP_printk("work->%p", __entry->work)
+);
+
+DEFINE_EVENT(btrfs__work, btrfs_work_queued,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work)
+);
+
+DEFINE_EVENT(btrfs__work, btrfs_work_sched,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work)
+);
+
+DEFINE_EVENT(btrfs__work, btrfs_normal_work_done,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work)
+);
+
+DEFINE_EVENT(btrfs__work__done, btrfs_all_work_done,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work)
+);
+
+DEFINE_EVENT(btrfs__work, btrfs_ordered_sched,
+
+       TP_PROTO(struct btrfs_work *work),
+
+       TP_ARGS(work)
+);
+
+DECLARE_EVENT_CLASS(btrfs__workqueue,
+
+       TP_PROTO(struct __btrfs_workqueue *wq, const char *name, int high),
+
+       TP_ARGS(wq, name, high),
+
+       TP_STRUCT__entry(
+               __field(        void *, wq                      )
+               __string(       name,   name                    )
+               __field(        int ,   high                    )
+       ),
+
+       TP_fast_assign(
+               __entry->wq             = wq;
+               __assign_str(name, name);
+               __entry->high           = high;
+       ),
+
+       TP_printk("name=%s%s, wq=%p", __get_str(name),
+                 __print_flags(__entry->high, "",
+                               {(WQ_HIGHPRI),  "-high"}),
+                 __entry->wq)
+);
+
+DEFINE_EVENT(btrfs__workqueue, btrfs_workqueue_alloc,
+
+       TP_PROTO(struct __btrfs_workqueue *wq, const char *name, int high),
+
+       TP_ARGS(wq, name, high)
+);
+
+DECLARE_EVENT_CLASS(btrfs__workqueue_done,
+
+       TP_PROTO(struct __btrfs_workqueue *wq),
+
+       TP_ARGS(wq),
+
+       TP_STRUCT__entry(
+               __field(        void *, wq                      )
+       ),
+
+       TP_fast_assign(
+               __entry->wq             = wq;
+       ),
+
+       TP_printk("wq=%p", __entry->wq)
+);
+
+DEFINE_EVENT(btrfs__workqueue_done, btrfs_workqueue_destroy,
+
+       TP_PROTO(struct __btrfs_workqueue *wq),
+
+       TP_ARGS(wq)
+);
+
 #endif /* _TRACE_BTRFS_H */
 
 /* This part must be outside protection */
index 197d3125df2aff526e7a69205c5ee7393b53221a..010ea89eeb0e407a85a052e6b8905dedb6ac5991 100644 (file)
@@ -16,6 +16,15 @@ struct mpage_da_data;
 struct ext4_map_blocks;
 struct extent_status;
 
+/* shim until we merge in the xfs_collapse_range branch */
+#ifndef FALLOC_FL_COLLAPSE_RANGE
+#define FALLOC_FL_COLLAPSE_RANGE       0x08
+#endif
+
+#ifndef FALLOC_FL_ZERO_RANGE
+#define FALLOC_FL_ZERO_RANGE           0x10
+#endif
+
 #define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode))
 
 #define show_mballoc_flags(flags) __print_flags(flags, "|",    \
@@ -68,6 +77,13 @@ struct extent_status;
        { EXTENT_STATUS_DELAYED,        "D" },                  \
        { EXTENT_STATUS_HOLE,           "H" })
 
+#define show_falloc_mode(mode) __print_flags(mode, "|",                \
+       { FALLOC_FL_KEEP_SIZE,          "KEEP_SIZE"},           \
+       { FALLOC_FL_PUNCH_HOLE,         "PUNCH_HOLE"},          \
+       { FALLOC_FL_NO_HIDE_STALE,      "NO_HIDE_STALE"},       \
+       { FALLOC_FL_COLLAPSE_RANGE,     "COLLAPSE_RANGE"},      \
+       { FALLOC_FL_ZERO_RANGE,         "ZERO_RANGE"})
+
 
 TRACE_EVENT(ext4_free_inode,
        TP_PROTO(struct inode *inode),
@@ -1328,7 +1344,7 @@ TRACE_EVENT(ext4_direct_IO_exit,
                  __entry->rw, __entry->ret)
 );
 
-TRACE_EVENT(ext4_fallocate_enter,
+DECLARE_EVENT_CLASS(ext4__fallocate_mode,
        TP_PROTO(struct inode *inode, loff_t offset, loff_t len, int mode),
 
        TP_ARGS(inode, offset, len, mode),
@@ -1336,23 +1352,45 @@ TRACE_EVENT(ext4_fallocate_enter,
        TP_STRUCT__entry(
                __field(        dev_t,  dev                     )
                __field(        ino_t,  ino                     )
-               __field(        loff_t, pos                     )
-               __field(        loff_t, len                     )
+               __field(        loff_t, offset                  )
+               __field(        loff_t, len                     )
                __field(        int,    mode                    )
        ),
 
        TP_fast_assign(
                __entry->dev    = inode->i_sb->s_dev;
                __entry->ino    = inode->i_ino;
-               __entry->pos    = offset;
+               __entry->offset = offset;
                __entry->len    = len;
                __entry->mode   = mode;
        ),
 
-       TP_printk("dev %d,%d ino %lu pos %lld len %lld mode %d",
+       TP_printk("dev %d,%d ino %lu offset %lld len %lld mode %s",
                  MAJOR(__entry->dev), MINOR(__entry->dev),
-                 (unsigned long) __entry->ino, __entry->pos,
-                 __entry->len, __entry->mode)
+                 (unsigned long) __entry->ino,
+                 __entry->offset, __entry->len,
+                 show_falloc_mode(__entry->mode))
+);
+
+DEFINE_EVENT(ext4__fallocate_mode, ext4_fallocate_enter,
+
+       TP_PROTO(struct inode *inode, loff_t offset, loff_t len, int mode),
+
+       TP_ARGS(inode, offset, len, mode)
+);
+
+DEFINE_EVENT(ext4__fallocate_mode, ext4_punch_hole,
+
+       TP_PROTO(struct inode *inode, loff_t offset, loff_t len, int mode),
+
+       TP_ARGS(inode, offset, len, mode)
+);
+
+DEFINE_EVENT(ext4__fallocate_mode, ext4_zero_range,
+
+       TP_PROTO(struct inode *inode, loff_t offset, loff_t len, int mode),
+
+       TP_ARGS(inode, offset, len, mode)
 );
 
 TRACE_EVENT(ext4_fallocate_exit,
@@ -1384,31 +1422,6 @@ TRACE_EVENT(ext4_fallocate_exit,
                  __entry->ret)
 );
 
-TRACE_EVENT(ext4_punch_hole,
-       TP_PROTO(struct inode *inode, loff_t offset, loff_t len),
-
-       TP_ARGS(inode, offset, len),
-
-       TP_STRUCT__entry(
-               __field(        dev_t,  dev                     )
-               __field(        ino_t,  ino                     )
-               __field(        loff_t, offset                  )
-               __field(        loff_t, len                     )
-       ),
-
-       TP_fast_assign(
-               __entry->dev    = inode->i_sb->s_dev;
-               __entry->ino    = inode->i_ino;
-               __entry->offset = offset;
-               __entry->len    = len;
-       ),
-
-       TP_printk("dev %d,%d ino %lu offset %lld len %lld",
-                 MAJOR(__entry->dev), MINOR(__entry->dev),
-                 (unsigned long) __entry->ino,
-                 __entry->offset, __entry->len)
-);
-
 TRACE_EVENT(ext4_unlink_enter,
        TP_PROTO(struct inode *parent, struct dentry *dentry),
 
@@ -2410,6 +2423,31 @@ TRACE_EVENT(ext4_es_shrink_exit,
                  __entry->shrunk_nr, __entry->cache_cnt)
 );
 
+TRACE_EVENT(ext4_collapse_range,
+       TP_PROTO(struct inode *inode, loff_t offset, loff_t len),
+
+       TP_ARGS(inode, offset, len),
+
+       TP_STRUCT__entry(
+               __field(dev_t,  dev)
+               __field(ino_t,  ino)
+               __field(loff_t, offset)
+               __field(loff_t, len)
+       ),
+
+       TP_fast_assign(
+               __entry->dev    = inode->i_sb->s_dev;
+               __entry->ino    = inode->i_ino;
+               __entry->offset = offset;
+               __entry->len    = len;
+       ),
+
+       TP_printk("dev %d,%d ino %lu offset %lld len %lld",
+                 MAJOR(__entry->dev), MINOR(__entry->dev),
+                 (unsigned long) __entry->ino,
+                 __entry->offset, __entry->len)
+);
+
 #endif /* _TRACE_EXT4_H */
 
 /* This part must be outside protection */
index 1619327374164909b6f8aaea6a730b0821ec6ee2..11fd51b413de25a6a2415c1724dee458d3314ddc 100644 (file)
@@ -22,8 +22,10 @@ struct module;
 
 #define show_module_flags(flags) __print_flags(flags, "",      \
        { (1UL << TAINT_PROPRIETARY_MODULE),    "P" },          \
+       { (1UL << TAINT_OOT_MODULE),            "O" },          \
        { (1UL << TAINT_FORCED_MODULE),         "F" },          \
-       { (1UL << TAINT_CRAP),                  "C" })
+       { (1UL << TAINT_CRAP),                  "C" },          \
+       { (1UL << TAINT_UNSIGNED_MODULE),       "X" })
 
 TRACE_EVENT(module_load,
 
index ef94ecad1c948bcae24694e376446b3af10b1ba5..b9bb1f2046938d136996de8fd6adfb5420e28486 100644 (file)
@@ -18,6 +18,7 @@
                { V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" },\
                { V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" },\
                { V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,  "VIDEO_OUTPUT_MPLANE" }, \
+               { V4L2_BUF_TYPE_SDR_CAPTURE,          "SDR_CAPTURE" },         \
                { V4L2_BUF_TYPE_PRIVATE,              "PRIVATE" })
 
 #define show_field(field)                                              \
index 95e46c8e05f90db319b2828eb53aa93bdca0629d..a9b13f8b3595107579ca6ea20421d53a9dd15017 100644 (file)
 #define F_GETOWNER_UIDS        17
 #endif
 
+/*
+ * fd "private" POSIX locks.
+ *
+ * Usually POSIX locks held by a process are released on *any* close and are
+ * not inherited across a fork().
+ *
+ * These cmd values will set locks that conflict with normal POSIX locks, but
+ * are "owned" by the opened file, not the process. This means that they are
+ * inherited across fork() like BSD (flock) locks, and they are only released
+ * automatically when the last reference to the the open file against which
+ * they were acquired is put.
+ */
+#define F_GETLKP       36
+#define F_SETLKP       37
+#define F_SETLKPW      38
+
 #define F_OWNER_TID    0
 #define F_OWNER_PID    1
 #define F_OWNER_PGRP   2
@@ -186,8 +202,6 @@ struct flock {
 };
 #endif
 
-#ifndef CONFIG_64BIT
-
 #ifndef HAVE_ARCH_STRUCT_FLOCK64
 #ifndef __ARCH_FLOCK64_PAD
 #define __ARCH_FLOCK64_PAD
@@ -202,6 +216,5 @@ struct flock64 {
        __ARCH_FLOCK64_PAD
 };
 #endif
-#endif /* !CONFIG_64BIT */
 
 #endif /* _ASM_GENERIC_FCNTL_H */
index 990c4ccf8b61d575a6db2a787896b027e4789698..d1197ae3723ce5193b0526ea8dfa0511d39c8407 100644 (file)
@@ -5,5 +5,40 @@
 #define FALLOC_FL_PUNCH_HOLE   0x02 /* de-allocates range */
 #define FALLOC_FL_NO_HIDE_STALE        0x04 /* reserved codepoint */
 
+/*
+ * FALLOC_FL_COLLAPSE_RANGE is used to remove a range of a file
+ * without leaving a hole in the file. The contents of the file beyond
+ * the range being removed is appended to the start offset of the range
+ * being removed (i.e. the hole that was punched is "collapsed"),
+ * resulting in a file layout that looks like the range that was
+ * removed never existed. As such collapsing a range of a file changes
+ * the size of the file, reducing it by the same length of the range
+ * that has been removed by the operation.
+ *
+ * Different filesystems may implement different limitations on the
+ * granularity of the operation. Most will limit operations to
+ * filesystem block size boundaries, but this boundary may be larger or
+ * smaller depending on the filesystem and/or the configuration of the
+ * filesystem or file.
+ *
+ * Attempting to collapse a range that crosses the end of the file is
+ * considered an illegal operation - just use ftruncate(2) if you need
+ * to collapse a range that crosses EOF.
+ */
+#define FALLOC_FL_COLLAPSE_RANGE       0x08
+
+/*
+ * FALLOC_FL_ZERO_RANGE is used to convert a range of file to zeros preferably
+ * without issuing data IO. Blocks should be preallocated for the regions that
+ * span holes in the file, and the entire range is preferable converted to
+ * unwritten extents - even though file system may choose to zero out the
+ * extent or do whatever which will result in reading zeros from the range
+ * while the range remains allocated for the file.
+ *
+ * This can be also used to preallocate blocks past EOF in the same way as
+ * with fallocate. Flag FALLOC_FL_KEEP_SIZE should cause the inode
+ * size to remain the same.
+ */
+#define FALLOC_FL_ZERO_RANGE           0x10
 
 #endif /* _UAPI_FALLOC_H_ */
index 6c28b61bb69041b166b09698a05d8c0619122c1c..ca1a11bb4443a7f09c3e4b9228c48a346eadce1c 100644 (file)
@@ -35,6 +35,9 @@
 #define SEEK_HOLE      4       /* seek to the next hole */
 #define SEEK_MAX       SEEK_HOLE
 
+#define RENAME_NOREPLACE       (1 << 0)        /* Don't overwrite target */
+#define RENAME_EXCHANGE                (1 << 1)        /* Exchange source and dest */
+
 struct fstrim_range {
        __u64 start;
        __u64 len;
index 60bb2f9f7b74272ae30e9119ded495100e6934b6..cf4750e1bb4971d03a0e870d323aa3f53c683ba9 100644 (file)
@@ -93,6 +93,9 @@
  *
  * 7.22
  *  - add FUSE_ASYNC_DIO
+ *
+ * 7.23
+ *  - add FUSE_WRITEBACK_CACHE
  */
 
 #ifndef _LINUX_FUSE_H
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 22
+#define FUSE_KERNEL_MINOR_VERSION 23
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -219,6 +222,7 @@ struct fuse_file_lock {
  * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one)
  * FUSE_READDIRPLUS_AUTO: adaptive readdirplus
  * FUSE_ASYNC_DIO: asynchronous direct I/O submission
+ * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
@@ -236,6 +240,7 @@ struct fuse_file_lock {
 #define FUSE_DO_READDIRPLUS    (1 << 13)
 #define FUSE_READDIRPLUS_AUTO  (1 << 14)
 #define FUSE_ASYNC_DIO         (1 << 15)
+#define FUSE_WRITEBACK_CACHE   (1 << 16)
 
 /**
  * CUSE INIT request/reply flags
index 0f24c07aed51377b1ecc67bfcee575ca58c7a9d4..db3fdd083882a07382b03927ae32fb15e17c50c6 100644 (file)
@@ -304,7 +304,13 @@ struct gfs2_dirent {
        __be16 de_rec_len;
        __be16 de_name_len;
        __be16 de_type;
-       __u8 __pad[14];
+       union {
+               __u8 __pad[14];
+               struct {
+                       __be16 de_rahead;
+                       __u8 pad2[12];
+               };
+       };
 };
 
 /*
@@ -347,9 +353,9 @@ struct gfs2_leaf {
  * metadata header. Each inode, if it has extended attributes, will
  * have either a single block containing the extended attribute headers
  * or a single indirect block pointing to blocks containing the
- * extended attribure headers.
+ * extended attribute headers.
  *
- * The maximim size of the data part of an extended attribute is 64k
+ * The maximum size of the data part of an extended attribute is 64k
  * so the number of blocks required depends upon block size. Since the
  * block size also determines the number of pointers in an indirect
  * block, its a fairly complicated calculation to work out the maximum
index 4f0667e010dd39333ef672af24969c5c6683819a..270db8914c01d89cc7583d3f80236eba1747f61b 100644 (file)
 #define V4L2_SUBDEV_SEL_FLAG_SIZE_LE   V4L2_SEL_FLAG_LE
 #define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG
 
+struct v4l2_edid {
+       __u32 pad;
+       __u32 start_block;
+       __u32 blocks;
+       __u32 reserved[5];
+       __u8 __user *edid;
+};
+
 #endif /* __V4L2_COMMON__ */
index 2cbe605bbe04f6d510aff6ac5b70d5d5b82e29dc..2ac5597f3ee145c9660b850b4664a86fd37b5ff1 100644 (file)
@@ -60,6 +60,7 @@
 #define V4L2_CTRL_CLASS_IMAGE_PROC     0x009f0000      /* Image processing controls */
 #define V4L2_CTRL_CLASS_DV             0x00a00000      /* Digital Video controls */
 #define V4L2_CTRL_CLASS_FM_RX          0x00a10000      /* FM Receiver controls */
+#define V4L2_CTRL_CLASS_RF_TUNER       0x00a20000      /* RF tuner controls */
 
 /* User-class control IDs */
 
@@ -376,6 +377,8 @@ enum v4l2_mpeg_video_multi_slice_mode {
 #define V4L2_CID_MPEG_VIDEO_DEC_FRAME                  (V4L2_CID_MPEG_BASE+224)
 #define V4L2_CID_MPEG_VIDEO_VBV_DELAY                  (V4L2_CID_MPEG_BASE+225)
 #define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER          (V4L2_CID_MPEG_BASE+226)
+#define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE          (V4L2_CID_MPEG_BASE+227)
+#define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE          (V4L2_CID_MPEG_BASE+228)
 
 #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)
@@ -812,6 +815,9 @@ enum v4l2_flash_strobe_source {
 #define V4L2_FLASH_FAULT_SHORT_CIRCUIT         (1 << 3)
 #define V4L2_FLASH_FAULT_OVER_CURRENT          (1 << 4)
 #define V4L2_FLASH_FAULT_INDICATOR             (1 << 5)
+#define V4L2_FLASH_FAULT_UNDER_VOLTAGE         (1 << 6)
+#define V4L2_FLASH_FAULT_INPUT_VOLTAGE         (1 << 7)
+#define V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE  (1 << 8)
 
 #define V4L2_CID_FLASH_CHARGE                  (V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY                   (V4L2_CID_FLASH_CLASS_BASE + 12)
@@ -895,4 +901,17 @@ enum v4l2_deemphasis {
 
 #define V4L2_CID_RDS_RECEPTION                 (V4L2_CID_FM_RX_CLASS_BASE + 2)
 
+#define V4L2_CID_RF_TUNER_CLASS_BASE           (V4L2_CTRL_CLASS_RF_TUNER | 0x900)
+#define V4L2_CID_RF_TUNER_CLASS                        (V4L2_CTRL_CLASS_RF_TUNER | 1)
+
+#define V4L2_CID_RF_TUNER_BANDWIDTH_AUTO       (V4L2_CID_RF_TUNER_CLASS_BASE + 11)
+#define V4L2_CID_RF_TUNER_BANDWIDTH            (V4L2_CID_RF_TUNER_CLASS_BASE + 12)
+#define V4L2_CID_RF_TUNER_LNA_GAIN_AUTO                (V4L2_CID_RF_TUNER_CLASS_BASE + 41)
+#define V4L2_CID_RF_TUNER_LNA_GAIN             (V4L2_CID_RF_TUNER_CLASS_BASE + 42)
+#define V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO      (V4L2_CID_RF_TUNER_CLASS_BASE + 51)
+#define V4L2_CID_RF_TUNER_MIXER_GAIN           (V4L2_CID_RF_TUNER_CLASS_BASE + 52)
+#define V4L2_CID_RF_TUNER_IF_GAIN_AUTO         (V4L2_CID_RF_TUNER_CLASS_BASE + 61)
+#define V4L2_CID_RF_TUNER_IF_GAIN              (V4L2_CID_RF_TUNER_CLASS_BASE + 62)
+#define V4L2_CID_RF_TUNER_PLL_LOCK                     (V4L2_CID_RF_TUNER_CLASS_BASE + 91)
+
 #endif
index be709fe29552b2e4ff7b95ce49ac3109291c778c..b6a5fe00a470b9a2009f7cb22af02608dc3f0199 100644 (file)
                V4L2_DV_FL_REDUCED_BLANKING) \
 }
 
+/* 4K resolutions */
+#define V4L2_DV_BT_DMT_4096X2160P60_RB { \
+       .type = V4L2_DV_BT_656_1120, \
+       V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+               556744000, 8, 32, 40, 48, 8, 6, 0, 0, 0, \
+               V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
+               V4L2_DV_FL_REDUCED_BLANKING) \
+}
+
+#define V4L2_DV_BT_DMT_4096X2160P59_94_RB { \
+       .type = V4L2_DV_BT_656_1120, \
+       V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \
+               556188000, 8, 32, 40, 48, 8, 6, 0, 0, 0, \
+               V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
+               V4L2_DV_FL_REDUCED_BLANKING) \
+}
+
 #endif
index a33c4daadce31dbe2cc1011053fd8cab2f28ead6..87e05159f637fe0ebbca4b7a7a9d32870d5ee94a 100644 (file)
@@ -148,13 +148,8 @@ struct v4l2_subdev_selection {
        __u32 reserved[8];
 };
 
-struct v4l2_subdev_edid {
-       __u32 pad;
-       __u32 start_block;
-       __u32 blocks;
-       __u32 reserved[5];
-       __u8 __user *edid;
-};
+/* Backwards compatibility define --- to be removed */
+#define v4l2_subdev_edid v4l2_edid
 
 #define VIDIOC_SUBDEV_G_FMT    _IOWR('V',  4, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_S_FMT    _IOWR('V',  5, struct v4l2_subdev_format)
@@ -174,7 +169,8 @@ struct v4l2_subdev_edid {
        _IOWR('V', 61, struct v4l2_subdev_selection)
 #define VIDIOC_SUBDEV_S_SELECTION \
        _IOWR('V', 62, struct v4l2_subdev_selection)
-#define VIDIOC_SUBDEV_G_EDID   _IOWR('V', 40, struct v4l2_subdev_edid)
-#define VIDIOC_SUBDEV_S_EDID   _IOWR('V', 41, struct v4l2_subdev_edid)
+/* These two G/S_EDID ioctls are identical to the ioctls in videodev2.h */
+#define VIDIOC_SUBDEV_G_EDID   _IOWR('V', 40, struct v4l2_edid)
+#define VIDIOC_SUBDEV_S_EDID   _IOWR('V', 41, struct v4l2_edid)
 
 #endif
index 6ae7bbe988cce2dde1d1766a8dd0b86aafe58c9d..ea468ee8fe21a7e3ef348f994e8e8c77942d0c3e 100644 (file)
@@ -139,6 +139,7 @@ enum v4l2_buf_type {
 #endif
        V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
        V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10,
+       V4L2_BUF_TYPE_SDR_CAPTURE          = 11,
        /* Deprecated, do not use */
        V4L2_BUF_TYPE_PRIVATE              = 0x80,
 };
@@ -159,6 +160,8 @@ enum v4l2_tuner_type {
        V4L2_TUNER_RADIO             = 1,
        V4L2_TUNER_ANALOG_TV         = 2,
        V4L2_TUNER_DIGITAL_TV        = 3,
+       V4L2_TUNER_ADC               = 4,
+       V4L2_TUNER_RF                = 5,
 };
 
 enum v4l2_memory {
@@ -264,6 +267,8 @@ struct v4l2_capability {
 #define V4L2_CAP_RADIO                 0x00040000  /* is a radio device */
 #define V4L2_CAP_MODULATOR             0x00080000  /* has a modulator */
 
+#define V4L2_CAP_SDR_CAPTURE           0x00100000  /* Is a SDR capture device */
+
 #define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
 #define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
 #define V4L2_CAP_STREAMING              0x04000000  /* streaming I/O ioctls */
@@ -431,6 +436,10 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_SE401      v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */
 #define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */
 
+/* SDR formats - used only for Software Defined Radio devices */
+#define V4L2_SDR_FMT_CU8          v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
+#define V4L2_SDR_FMT_CU16LE       v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */
+
 /*
  *     F O R M A T   E N U M E R A T I O N
  */
@@ -669,24 +678,36 @@ struct v4l2_buffer {
 };
 
 /*  Flags for 'flags' field */
-#define V4L2_BUF_FLAG_MAPPED   0x0001  /* Buffer is mapped (flag) */
-#define V4L2_BUF_FLAG_QUEUED   0x0002  /* Buffer is queued for processing */
-#define V4L2_BUF_FLAG_DONE     0x0004  /* Buffer is ready */
-#define V4L2_BUF_FLAG_KEYFRAME 0x0008  /* Image is a keyframe (I-frame) */
-#define V4L2_BUF_FLAG_PFRAME   0x0010  /* Image is a P-frame */
-#define V4L2_BUF_FLAG_BFRAME   0x0020  /* Image is a B-frame */
+/* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_MAPPED                   0x00000001
+/* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_QUEUED                   0x00000002
+/* Buffer is ready */
+#define V4L2_BUF_FLAG_DONE                     0x00000004
+/* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_KEYFRAME                 0x00000008
+/* Image is a P-frame */
+#define V4L2_BUF_FLAG_PFRAME                   0x00000010
+/* Image is a B-frame */
+#define V4L2_BUF_FLAG_BFRAME                   0x00000020
 /* Buffer is ready, but the data contained within is corrupted. */
-#define V4L2_BUF_FLAG_ERROR    0x0040
-#define V4L2_BUF_FLAG_TIMECODE 0x0100  /* timecode field is valid */
-#define V4L2_BUF_FLAG_PREPARED 0x0400  /* Buffer is prepared for queuing */
+#define V4L2_BUF_FLAG_ERROR                    0x00000040
+/* timecode field is valid */
+#define V4L2_BUF_FLAG_TIMECODE                 0x00000100
+/* Buffer is prepared for queuing */
+#define V4L2_BUF_FLAG_PREPARED                 0x00000400
 /* Cache handling flags */
-#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE      0x0800
-#define V4L2_BUF_FLAG_NO_CACHE_CLEAN           0x1000
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE      0x00000800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN           0x00001000
 /* Timestamp type */
-#define V4L2_BUF_FLAG_TIMESTAMP_MASK           0xe000
-#define V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN                0x0000
-#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC      0x2000
-#define V4L2_BUF_FLAG_TIMESTAMP_COPY           0x4000
+#define V4L2_BUF_FLAG_TIMESTAMP_MASK           0x0000e000
+#define V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN                0x00000000
+#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC      0x00002000
+#define V4L2_BUF_FLAG_TIMESTAMP_COPY           0x00004000
+/* Timestamp sources. */
+#define V4L2_BUF_FLAG_TSTAMP_SRC_MASK          0x00070000
+#define V4L2_BUF_FLAG_TSTAMP_SRC_EOF           0x00000000
+#define V4L2_BUF_FLAG_TSTAMP_SRC_SOE           0x00010000
 
 /**
  * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
@@ -1059,14 +1080,14 @@ struct v4l2_bt_timings {
 
 /* A few useful defines to calculate the total blanking and frame sizes */
 #define V4L2_DV_BT_BLANKING_WIDTH(bt) \
-       (bt->hfrontporch + bt->hsync + bt->hbackporch)
+       ((bt)->hfrontporch + (bt)->hsync + (bt)->hbackporch)
 #define V4L2_DV_BT_FRAME_WIDTH(bt) \
-       (bt->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
+       ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
 #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \
-       (bt->vfrontporch + bt->vsync + bt->vbackporch + \
-        bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch)
+       ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \
+        (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch)
 #define V4L2_DV_BT_FRAME_HEIGHT(bt) \
-       (bt->height + V4L2_DV_BT_BLANKING_HEIGHT(bt))
+       ((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt))
 
 /** struct v4l2_dv_timings - DV timings
  * @type:      the type of the timings
@@ -1339,6 +1360,7 @@ struct v4l2_modulator {
 #define V4L2_TUNER_CAP_RDS_CONTROLS    0x0200
 #define V4L2_TUNER_CAP_FREQ_BANDS      0x0400
 #define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800
+#define V4L2_TUNER_CAP_1HZ             0x1000
 
 /*  Flags for the 'rxsubchans' field */
 #define V4L2_TUNER_SUB_MONO            0x0001
@@ -1691,6 +1713,15 @@ struct v4l2_pix_format_mplane {
        __u8                            reserved[11];
 } __attribute__ ((packed));
 
+/**
+ * struct v4l2_sdr_format - SDR format definition
+ * @pixelformat:       little endian four character code (fourcc)
+ */
+struct v4l2_sdr_format {
+       __u32                           pixelformat;
+       __u8                            reserved[28];
+} __attribute__ ((packed));
+
 /**
  * struct v4l2_format - stream data format
  * @type:      enum v4l2_buf_type; type of the data stream
@@ -1709,6 +1740,7 @@ struct v4l2_format {
                struct v4l2_window              win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
                struct v4l2_vbi_format          vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
                struct v4l2_sliced_vbi_format   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
+               struct v4l2_sdr_format          sdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */
                __u8    raw_data[200];                   /* user-defined */
        } fmt;
 };
@@ -1885,6 +1917,8 @@ struct v4l2_create_buffers {
 #define VIDIOC_QUERYMENU       _IOWR('V', 37, struct v4l2_querymenu)
 #define VIDIOC_G_INPUT          _IOR('V', 38, int)
 #define VIDIOC_S_INPUT         _IOWR('V', 39, int)
+#define VIDIOC_G_EDID          _IOWR('V', 40, struct v4l2_edid)
+#define VIDIOC_S_EDID          _IOWR('V', 41, struct v4l2_edid)
 #define VIDIOC_G_OUTPUT                 _IOR('V', 46, int)
 #define VIDIOC_S_OUTPUT                _IOWR('V', 47, int)
 #define VIDIOC_ENUMOUTPUT      _IOWR('V', 48, struct v4l2_output)
index 723c324590c14dad9367e416be1e2fe1984daeb2..1927b0d78a998a1e01c37314884f3531fa6e90d9 100644 (file)
  * used. A pointer to a &struct ubi_set_vol_prop_req object is expected to be
  * passed. The object describes which property should be set, and to which value
  * it should be set.
+ *
+ * Block devices on UBI volumes
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * To create a R/O block device on top of an UBI volume the %UBI_IOCVOLCRBLK
+ * should be used. A pointer to a &struct ubi_blkcreate_req object is expected
+ * to be passed, which is not used and reserved for future usage.
+ *
+ * Conversely, to remove a block device the %UBI_IOCVOLRMBLK should be used,
+ * which takes no arguments.
  */
 
 /*
 /* Set an UBI volume property */
 #define UBI_IOCSETVOLPROP _IOW(UBI_VOL_IOC_MAGIC, 6, \
                               struct ubi_set_vol_prop_req)
+/* Create a R/O block device on top of an UBI volume */
+#define UBI_IOCVOLCRBLK _IOW(UBI_VOL_IOC_MAGIC, 7, struct ubi_blkcreate_req)
+/* Remove the R/O block device */
+#define UBI_IOCVOLRMBLK _IO(UBI_VOL_IOC_MAGIC, 8)
 
 /* Maximum MTD device name length supported by UBI */
 #define MAX_UBI_MTD_NAME_LEN 127
@@ -420,4 +434,12 @@ struct ubi_set_vol_prop_req {
        __u64 value;
 }  __packed;
 
+/**
+ * struct ubi_blkcreate_req - a data structure used in block creation requests.
+ * @padding: reserved for future, not used, has to be zeroed
+ */
+struct ubi_blkcreate_req {
+       __s8  padding[128];
+}  __packed;
+
 #endif /* __UBI_USER_H__ */
index 3d7c51a6f9ff27de17f5f748afb00bc190e3d6cf..6adb445346064e815bb5fbccc030a9d56e63c6c0 100644 (file)
@@ -323,7 +323,6 @@ enum omapdss_version {
 
 /* Board specific data */
 struct omap_dss_board_info {
-       int (*get_context_loss_count)(struct device *dev);
        int num_devices;
        struct omap_dss_device **devices;
        struct omap_dss_device *default_device;
@@ -344,8 +343,8 @@ struct omap_video_timings {
        u16 x_res;
        /* Unit: pixels */
        u16 y_res;
-       /* Unit: KHz */
-       u32 pixel_clock;
+       /* Unit: Hz */
+       u32 pixelclock;
        /* Unit: pixel clocks */
        u16 hsw;        /* Horizontal synchronization pulse width */
        /* Unit: pixel clocks */
@@ -1019,4 +1018,18 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
        return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
 }
 
+struct device_node *
+omapdss_of_get_next_port(const struct device_node *parent,
+                        struct device_node *prev);
+
+struct device_node *
+omapdss_of_get_next_endpoint(const struct device_node *parent,
+                            struct device_node *prev);
+
+struct device_node *
+omapdss_of_get_first_endpoint(const struct device_node *parent);
+
+struct omap_dss_device *
+omapdss_of_find_source_for_first_ep(struct device_node *node);
+
 #endif
index deff2e693766997a259b4b3ac2fc4f789e554f1d..a9e710eef0e2543f063ee8a1c06952f2fb3e0891 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/gfp.h>
 #include <linux/suspend.h>
+#include <linux/lockdep.h>
 
 #include "smpboot.h"
 
 static DEFINE_MUTEX(cpu_add_remove_lock);
 
 /*
- * The following two API's must be used when attempting
- * to serialize the updates to cpu_online_mask, cpu_present_mask.
+ * The following two APIs (cpu_maps_update_begin/done) must be used when
+ * attempting to serialize the updates to cpu_online_mask & cpu_present_mask.
+ * The APIs cpu_notifier_register_begin/done() must be used to protect CPU
+ * hotplug callback (un)registration performed using __register_cpu_notifier()
+ * or __unregister_cpu_notifier().
  */
 void cpu_maps_update_begin(void)
 {
        mutex_lock(&cpu_add_remove_lock);
 }
+EXPORT_SYMBOL(cpu_notifier_register_begin);
 
 void cpu_maps_update_done(void)
 {
        mutex_unlock(&cpu_add_remove_lock);
 }
+EXPORT_SYMBOL(cpu_notifier_register_done);
 
 static RAW_NOTIFIER_HEAD(cpu_chain);
 
@@ -57,17 +63,30 @@ static struct {
         * an ongoing cpu hotplug operation.
         */
        int refcount;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       struct lockdep_map dep_map;
+#endif
 } cpu_hotplug = {
        .active_writer = NULL,
        .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
        .refcount = 0,
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       .dep_map = {.name = "cpu_hotplug.lock" },
+#endif
 };
 
+/* Lockdep annotations for get/put_online_cpus() and cpu_hotplug_begin/end() */
+#define cpuhp_lock_acquire_read() lock_map_acquire_read(&cpu_hotplug.dep_map)
+#define cpuhp_lock_acquire()      lock_map_acquire(&cpu_hotplug.dep_map)
+#define cpuhp_lock_release()      lock_map_release(&cpu_hotplug.dep_map)
+
 void get_online_cpus(void)
 {
        might_sleep();
        if (cpu_hotplug.active_writer == current)
                return;
+       cpuhp_lock_acquire_read();
        mutex_lock(&cpu_hotplug.lock);
        cpu_hotplug.refcount++;
        mutex_unlock(&cpu_hotplug.lock);
@@ -87,6 +106,7 @@ void put_online_cpus(void)
        if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
                wake_up_process(cpu_hotplug.active_writer);
        mutex_unlock(&cpu_hotplug.lock);
+       cpuhp_lock_release();
 
 }
 EXPORT_SYMBOL_GPL(put_online_cpus);
@@ -117,6 +137,7 @@ void cpu_hotplug_begin(void)
 {
        cpu_hotplug.active_writer = current;
 
+       cpuhp_lock_acquire();
        for (;;) {
                mutex_lock(&cpu_hotplug.lock);
                if (likely(!cpu_hotplug.refcount))
@@ -131,6 +152,7 @@ void cpu_hotplug_done(void)
 {
        cpu_hotplug.active_writer = NULL;
        mutex_unlock(&cpu_hotplug.lock);
+       cpuhp_lock_release();
 }
 
 /*
@@ -166,6 +188,11 @@ int __ref register_cpu_notifier(struct notifier_block *nb)
        return ret;
 }
 
+int __ref __register_cpu_notifier(struct notifier_block *nb)
+{
+       return raw_notifier_chain_register(&cpu_chain, nb);
+}
+
 static int __cpu_notify(unsigned long val, void *v, int nr_to_call,
                        int *nr_calls)
 {
@@ -189,6 +216,7 @@ static void cpu_notify_nofail(unsigned long val, void *v)
        BUG_ON(cpu_notify(val, v));
 }
 EXPORT_SYMBOL(register_cpu_notifier);
+EXPORT_SYMBOL(__register_cpu_notifier);
 
 void __ref unregister_cpu_notifier(struct notifier_block *nb)
 {
@@ -198,6 +226,12 @@ void __ref unregister_cpu_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL(unregister_cpu_notifier);
 
+void __ref __unregister_cpu_notifier(struct notifier_block *nb)
+{
+       raw_notifier_chain_unregister(&cpu_chain, nb);
+}
+EXPORT_SYMBOL(__unregister_cpu_notifier);
+
 /**
  * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
  * @cpu: a CPU id
index 307d87c0991a338fbc8038afc0784b1bd2a18b96..04709b66369d83d1dc883ab5eea92505d5eed410 100644 (file)
@@ -1804,6 +1804,11 @@ static bool handle_trampoline(struct pt_regs *regs)
        return true;
 }
 
+bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs)
+{
+       return false;
+}
+
 /*
  * Run handler and ask thread to singlestep.
  * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
@@ -1858,7 +1863,11 @@ static void handle_swbp(struct pt_regs *regs)
        if (!get_utask())
                goto out;
 
+       if (arch_uprobe_ignore(&uprobe->arch, regs))
+               goto out;
+
        handler_chain(uprobe, regs);
+
        if (can_skip_sstep(uprobe, regs))
                goto out;
 
index 8dc7f5e80dd8f75273ef15df03a14615de1579d4..29f7790eaa147a1b0fc7ec223c5356f44caab346 100644 (file)
@@ -1013,6 +1013,8 @@ static size_t module_flags_taint(struct module *mod, char *buf)
                buf[l++] = 'F';
        if (mod->taints & (1 << TAINT_CRAP))
                buf[l++] = 'C';
+       if (mod->taints & (1 << TAINT_UNSIGNED_MODULE))
+               buf[l++] = 'E';
        /*
         * TAINT_FORCED_RMMOD: could be added.
         * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
@@ -3218,7 +3220,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
                pr_notice_once("%s: module verification failed: signature "
                               "and/or  required key missing - tainting "
                               "kernel\n", mod->name);
-               add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_STILL_OK);
+               add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK);
        }
 #endif
 
@@ -3813,12 +3815,12 @@ void print_modules(void)
        list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
-               printk(" %s%s", mod->name, module_flags(mod, buf));
+               pr_cont(" %s%s", mod->name, module_flags(mod, buf));
        }
        preempt_enable();
        if (last_unloaded_module[0])
-               printk(" [last unloaded: %s]", last_unloaded_module);
-       printk("\n");
+               pr_cont(" [last unloaded: %s]", last_unloaded_module);
+       pr_cont("\n");
 }
 
 #ifdef CONFIG_MODVERSIONS
index cca8a913ae7c8d6314fda34a1f3853a364e32cfd..79fd820bb5e8788338c98a6df1fb45d8e5f9f477 100644 (file)
@@ -210,6 +210,7 @@ static const struct tnt tnts[] = {
        { TAINT_CRAP,                   'C', ' ' },
        { TAINT_FIRMWARE_WORKAROUND,    'I', ' ' },
        { TAINT_OOT_MODULE,             'O', ' ' },
+       { TAINT_UNSIGNED_MODULE,        'E', ' ' },
 };
 
 /**
@@ -228,6 +229,7 @@ static const struct tnt tnts[] = {
  *  'C' - modules from drivers/staging are loaded.
  *  'I' - Working around severe firmware bug.
  *  'O' - Out-of-tree module has been loaded.
+ *  'E' - Unsigned module has been loaded.
  *
  *     The string is overwritten by the next call to print_tainted().
  */
index 1b266dbe755a983e0bca02bb50ca1ab47419488d..cb980f0c731b72ef3df3ff6b9afa2f6f44d15b9c 100644 (file)
@@ -591,18 +591,28 @@ out_cleanup:
 int __ref create_proc_profile(void) /* false positive from hotcpu_notifier */
 {
        struct proc_dir_entry *entry;
+       int err = 0;
 
        if (!prof_on)
                return 0;
-       if (create_hash_tables())
-               return -ENOMEM;
+
+       cpu_notifier_register_begin();
+
+       if (create_hash_tables()) {
+               err = -ENOMEM;
+               goto out;
+       }
+
        entry = proc_create("profile", S_IWUSR | S_IRUGO,
                            NULL, &proc_profile_operations);
        if (!entry)
-               return 0;
+               goto out;
        proc_set_size(entry, (1 + prof_len) * sizeof(atomic_t));
-       hotcpu_notifier(profile_cpu_callback, 0);
-       return 0;
+       __hotcpu_notifier(profile_cpu_callback, 0);
+
+out:
+       cpu_notifier_register_done();
+       return err;
 }
 subsys_initcall(create_proc_profile);
 #endif /* CONFIG_PROC_FS */
index 1d1b87b36778abf2fffe0a53e6f380ef36bf7334..0ff3f34bc7e3289e561d7c18dde351f5bb9605bd 100644 (file)
@@ -2845,52 +2845,6 @@ int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
 }
 EXPORT_SYMBOL(default_wake_function);
 
-static long __sched
-sleep_on_common(wait_queue_head_t *q, int state, long timeout)
-{
-       unsigned long flags;
-       wait_queue_t wait;
-
-       init_waitqueue_entry(&wait, current);
-
-       __set_current_state(state);
-
-       spin_lock_irqsave(&q->lock, flags);
-       __add_wait_queue(q, &wait);
-       spin_unlock(&q->lock);
-       timeout = schedule_timeout(timeout);
-       spin_lock_irq(&q->lock);
-       __remove_wait_queue(q, &wait);
-       spin_unlock_irqrestore(&q->lock, flags);
-
-       return timeout;
-}
-
-void __sched interruptible_sleep_on(wait_queue_head_t *q)
-{
-       sleep_on_common(q, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
-}
-EXPORT_SYMBOL(interruptible_sleep_on);
-
-long __sched
-interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
-{
-       return sleep_on_common(q, TASK_INTERRUPTIBLE, timeout);
-}
-EXPORT_SYMBOL(interruptible_sleep_on_timeout);
-
-void __sched sleep_on(wait_queue_head_t *q)
-{
-       sleep_on_common(q, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
-}
-EXPORT_SYMBOL(sleep_on);
-
-long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)
-{
-       return sleep_on_common(q, TASK_UNINTERRUPTIBLE, timeout);
-}
-EXPORT_SYMBOL(sleep_on_timeout);
-
 #ifdef CONFIG_RT_MUTEXES
 
 /*
index 015f85aaca08f5f5d6eb55af1f1aab46670bb03b..8639819f6cef6a776f9f54717facd2afc67cf4c2 100644 (file)
@@ -424,6 +424,7 @@ config UPROBE_EVENT
        bool "Enable uprobes-based dynamic events"
        depends on ARCH_SUPPORTS_UPROBES
        depends on MMU
+       depends on PERF_EVENTS
        select UPROBES
        select PROBE_EVENTS
        select TRACING
index fc4da2d97f9b6e280b2e29a525e478958cb495d4..c634868c2921ca39837c3a36773c36fa4a3273d5 100644 (file)
@@ -1301,7 +1301,7 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
         * In that off case, we need to allocate for all possible cpus.
         */
 #ifdef CONFIG_HOTPLUG_CPU
-       get_online_cpus();
+       cpu_notifier_register_begin();
        cpumask_copy(buffer->cpumask, cpu_online_mask);
 #else
        cpumask_copy(buffer->cpumask, cpu_possible_mask);
@@ -1324,10 +1324,10 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
 #ifdef CONFIG_HOTPLUG_CPU
        buffer->cpu_notify.notifier_call = rb_cpu_notify;
        buffer->cpu_notify.priority = 0;
-       register_cpu_notifier(&buffer->cpu_notify);
+       __register_cpu_notifier(&buffer->cpu_notify);
+       cpu_notifier_register_done();
 #endif
 
-       put_online_cpus();
        mutex_init(&buffer->mutex);
 
        return buffer;
@@ -1341,7 +1341,9 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
 
  fail_free_cpumask:
        free_cpumask_var(buffer->cpumask);
-       put_online_cpus();
+#ifdef CONFIG_HOTPLUG_CPU
+       cpu_notifier_register_done();
+#endif
 
  fail_free_buffer:
        kfree(buffer);
@@ -1358,16 +1360,17 @@ ring_buffer_free(struct ring_buffer *buffer)
 {
        int cpu;
 
-       get_online_cpus();
-
 #ifdef CONFIG_HOTPLUG_CPU
-       unregister_cpu_notifier(&buffer->cpu_notify);
+       cpu_notifier_register_begin();
+       __unregister_cpu_notifier(&buffer->cpu_notify);
 #endif
 
        for_each_buffer_cpu(buffer, cpu)
                rb_free_cpu_buffer(buffer->buffers[cpu]);
 
-       put_online_cpus();
+#ifdef CONFIG_HOTPLUG_CPU
+       cpu_notifier_register_done();
+#endif
 
        kfree(buffer->buffers);
        free_cpumask_var(buffer->cpumask);
index 50f8329c20425decc51420f5d733b15193a56091..fb0a38a265555c6c846254859c83468d0aba0f35 100644 (file)
@@ -460,7 +460,8 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
 #ifdef CONFIG_MODULES
 bool trace_module_has_bad_taint(struct module *mod)
 {
-       return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP));
+       return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP) |
+                              (1 << TAINT_UNSIGNED_MODULE));
 }
 
 static int tracepoint_module_coming(struct module *mod)
@@ -474,7 +475,7 @@ static int tracepoint_module_coming(struct module *mod)
        /*
         * We skip modules that taint the kernel, especially those with different
         * module headers (for forced load), to make sure we don't cause a crash.
-        * Staging and out-of-tree GPL modules are fine.
+        * Staging, out-of-tree, and unsigned GPL modules are fine.
         */
        if (trace_module_has_bad_taint(mod))
                return 0;
index 39a31e7f004505991e37219bdb1e17f571efb933..7fe5354e7552c0507eb6a6b778eee42d1c2182af 100644 (file)
@@ -1407,6 +1407,11 @@ void __init_memblock memblock_set_current_limit(phys_addr_t limit)
        memblock.current_limit = limit;
 }
 
+phys_addr_t __init_memblock memblock_get_current_limit(void)
+{
+       return memblock.current_limit;
+}
+
 static void __init_memblock memblock_dump(struct memblock_type *type, char *name)
 {
        unsigned long long base, size;
index 90cea22001ef32e0ba19af3c02d70e1a2f3f1604..82c1e4cf00d16644f04f4d36fd72a008ea978ed5 100644 (file)
@@ -1705,15 +1705,6 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 
        VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET));
 
-       /* 
-        * Require read or write permissions.
-        * If FOLL_FORCE is set, we only require the "MAY" flags.
-        */
-       vm_flags  = (gup_flags & FOLL_WRITE) ?
-                       (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
-       vm_flags &= (gup_flags & FOLL_FORCE) ?
-                       (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
-
        /*
         * If FOLL_FORCE and FOLL_NUMA are both set, handle_mm_fault
         * would be called on PROT_NONE ranges. We must never invoke
@@ -1741,7 +1732,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 
                        /* user gate pages are read-only */
                        if (gup_flags & FOLL_WRITE)
-                               return i ? : -EFAULT;
+                               goto efault;
                        if (pg > TASK_SIZE)
                                pgd = pgd_offset_k(pg);
                        else
@@ -1751,12 +1742,12 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                        BUG_ON(pud_none(*pud));
                        pmd = pmd_offset(pud, pg);
                        if (pmd_none(*pmd))
-                               return i ? : -EFAULT;
+                               goto efault;
                        VM_BUG_ON(pmd_trans_huge(*pmd));
                        pte = pte_offset_map(pmd, pg);
                        if (pte_none(*pte)) {
                                pte_unmap(pte);
-                               return i ? : -EFAULT;
+                               goto efault;
                        }
                        vma = get_gate_vma(mm);
                        if (pages) {
@@ -1769,7 +1760,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                                                page = pte_page(*pte);
                                        else {
                                                pte_unmap(pte);
-                                               return i ? : -EFAULT;
+                                               goto efault;
                                        }
                                }
                                pages[i] = page;
@@ -1780,10 +1771,42 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                        goto next_page;
                }
 
-               if (!vma ||
-                   (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
-                   !(vm_flags & vma->vm_flags))
-                       return i ? : -EFAULT;
+               if (!vma)
+                       goto efault;
+               vm_flags = vma->vm_flags;
+               if (vm_flags & (VM_IO | VM_PFNMAP))
+                       goto efault;
+
+               if (gup_flags & FOLL_WRITE) {
+                       if (!(vm_flags & VM_WRITE)) {
+                               if (!(gup_flags & FOLL_FORCE))
+                                       goto efault;
+                               /*
+                                * We used to let the write,force case do COW
+                                * in a VM_MAYWRITE VM_SHARED !VM_WRITE vma, so
+                                * ptrace could set a breakpoint in a read-only
+                                * mapping of an executable, without corrupting
+                                * the file (yet only when that file had been
+                                * opened for writing!).  Anon pages in shared
+                                * mappings are surprising: now just reject it.
+                                */
+                               if (!is_cow_mapping(vm_flags)) {
+                                       WARN_ON_ONCE(vm_flags & VM_MAYWRITE);
+                                       goto efault;
+                               }
+                       }
+               } else {
+                       if (!(vm_flags & VM_READ)) {
+                               if (!(gup_flags & FOLL_FORCE))
+                                       goto efault;
+                               /*
+                                * Is there actually any vma we can reach here
+                                * which does not have VM_MAYREAD set?
+                                */
+                               if (!(vm_flags & VM_MAYREAD))
+                                       goto efault;
+                       }
+               }
 
                if (is_vm_hugetlb_page(vma)) {
                        i = follow_hugetlb_page(mm, vma, pages, vmas,
@@ -1837,7 +1860,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                                                        return -EFAULT;
                                        }
                                        if (ret & VM_FAULT_SIGBUS)
-                                               return i ? i : -EFAULT;
+                                               goto efault;
                                        BUG();
                                }
 
@@ -1895,6 +1918,8 @@ next_page:
                } while (nr_pages && start < vma->vm_end);
        } while (nr_pages);
        return i;
+efault:
+       return i ? : -EFAULT;
 }
 EXPORT_SYMBOL(__get_user_pages);
 
@@ -1962,9 +1987,8 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
  * @start:     starting user address
  * @nr_pages:  number of pages from start to pin
  * @write:     whether pages will be written to by the caller
- * @force:     whether to force write access even if user mapping is
- *             readonly. This will result in the page being COWed even
- *             in MAP_SHARED mappings. You do not want this.
+ * @force:     whether to force access even when user mapping is currently
+ *             protected (but never forces write access to shared mapping).
  * @pages:     array that receives pointers to the pages pinned.
  *             Should be at least nr_pages long. Or NULL, if caller
  *             only intends to ensure the pages are faulted in.
index ac1d6671b1ed76f68153e26218500194c96b4471..46433e137abc2ef4f22486d426d43df5c54e9589 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1299,7 +1299,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
                        /*
                         * Make sure there are no mandatory locks on the file.
                         */
-                       if (locks_verify_locked(inode))
+                       if (locks_verify_locked(file))
                                return -EAGAIN;
 
                        vm_flags |= VM_SHARED | VM_MAYSHARE;
index 8740213b1647019c9fdbaaf355da3f2e5e632d99..a554e5a451cdb4622d32ce1a5b6cacf1773f848f 100644 (file)
@@ -995,7 +995,7 @@ static int validate_mmap_request(struct file *file,
                            (file->f_mode & FMODE_WRITE))
                                return -EACCES;
 
-                       if (locks_verify_locked(file_inode(file)))
+                       if (locks_verify_locked(file))
                                return -EAGAIN;
 
                        if (!(capabilities & BDI_CAP_MAP_DIRECT))
index 197b4c4a95879832e29e7b933b70c2f4f6e01d17..302dd076b8bf47bfb13a7925166b1b1f4e0dc5eb 100644 (file)
@@ -1298,14 +1298,14 @@ static int __init setup_vmstat(void)
 #ifdef CONFIG_SMP
        int cpu;
 
-       register_cpu_notifier(&vmstat_notifier);
+       cpu_notifier_register_begin();
+       __register_cpu_notifier(&vmstat_notifier);
 
-       get_online_cpus();
        for_each_online_cpu(cpu) {
                start_cpu_timer(cpu);
                node_set_state(cpu_to_node(cpu), N_CPU);
        }
-       put_online_cpus();
+       cpu_notifier_register_done();
 #endif
 #ifdef CONFIG_PROC_FS
        proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
index c03ca5e9fe15c8b9725db0ac41b6ba78f64b0e5d..36b4591a7a2d3b2eca7111b26bee3efa19c7c5c5 100644 (file)
@@ -814,21 +814,32 @@ static void zs_exit(void)
 {
        int cpu;
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(cpu)
                zs_cpu_notifier(NULL, CPU_DEAD, (void *)(long)cpu);
-       unregister_cpu_notifier(&zs_cpu_nb);
+       __unregister_cpu_notifier(&zs_cpu_nb);
+
+       cpu_notifier_register_done();
 }
 
 static int zs_init(void)
 {
        int cpu, ret;
 
-       register_cpu_notifier(&zs_cpu_nb);
+       cpu_notifier_register_begin();
+
+       __register_cpu_notifier(&zs_cpu_nb);
        for_each_online_cpu(cpu) {
                ret = zs_cpu_notifier(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
-               if (notifier_to_errno(ret))
+               if (notifier_to_errno(ret)) {
+                       cpu_notifier_register_done();
                        goto fail;
+               }
        }
+
+       cpu_notifier_register_done();
+
        return 0;
 fail:
        zs_exit();
index e55bab9dc41f81ab1b6384710e918f3839e0c936..d7337fbf66053219ab0e72e5e9b2c0b7e17d2bb7 100644 (file)
@@ -387,18 +387,18 @@ static int zswap_cpu_init(void)
 {
        unsigned long cpu;
 
-       get_online_cpus();
+       cpu_notifier_register_begin();
        for_each_online_cpu(cpu)
                if (__zswap_cpu_notifier(CPU_UP_PREPARE, cpu) != NOTIFY_OK)
                        goto cleanup;
-       register_cpu_notifier(&zswap_cpu_notifier_block);
-       put_online_cpus();
+       __register_cpu_notifier(&zswap_cpu_notifier_block);
+       cpu_notifier_register_done();
        return 0;
 
 cleanup:
        for_each_online_cpu(cpu)
                __zswap_cpu_notifier(CPU_UP_CANCELED, cpu);
-       put_online_cpus();
+       cpu_notifier_register_done();
        return -ENOMEM;
 }
 
index b703790b4e44788e109bb91ab61f272015000654..a1ef53c044151be9df2ac4e61e0631226d59f0a8 100644 (file)
@@ -292,10 +292,12 @@ static int is_out(const struct crush_map *map,
  * @outpos: our position in that vector
  * @tries: number of attempts to make
  * @recurse_tries: number of attempts to have recursive chooseleaf make
- * @local_tries: localized retries
- * @local_fallback_tries: localized fallback retries
+ * @local_retries: localized retries
+ * @local_fallback_retries: localized fallback retries
  * @recurse_to_leaf: true if we want one device under each item of given type (chooseleaf instead of choose)
+ * @vary_r: pass r to recursive calls
  * @out2: second output vector for leaf items (if @recurse_to_leaf)
+ * @parent_r: r value passed from the parent
  */
 static int crush_choose_firstn(const struct crush_map *map,
                               struct crush_bucket *bucket,
@@ -304,10 +306,12 @@ static int crush_choose_firstn(const struct crush_map *map,
                               int *out, int outpos,
                               unsigned int tries,
                               unsigned int recurse_tries,
-                              unsigned int local_tries,
-                              unsigned int local_fallback_tries,
+                              unsigned int local_retries,
+                              unsigned int local_fallback_retries,
                               int recurse_to_leaf,
-                              int *out2)
+                              unsigned int vary_r,
+                              int *out2,
+                              int parent_r)
 {
        int rep;
        unsigned int ftotal, flocal;
@@ -319,8 +323,11 @@ static int crush_choose_firstn(const struct crush_map *map,
        int itemtype;
        int collide, reject;
 
-       dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d\n", recurse_to_leaf ? "_LEAF" : "",
-               bucket->id, x, outpos, numrep);
+       dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d tries %d recurse_tries %d local_retries %d local_fallback_retries %d parent_r %d\n",
+               recurse_to_leaf ? "_LEAF" : "",
+               bucket->id, x, outpos, numrep,
+               tries, recurse_tries, local_retries, local_fallback_retries,
+               parent_r);
 
        for (rep = outpos; rep < numrep; rep++) {
                /* keep trying until we get a non-out, non-colliding item */
@@ -335,7 +342,7 @@ static int crush_choose_firstn(const struct crush_map *map,
                        do {
                                collide = 0;
                                retry_bucket = 0;
-                               r = rep;
+                               r = rep + parent_r;
                                /* r' = r + f_total */
                                r += ftotal;
 
@@ -344,9 +351,9 @@ static int crush_choose_firstn(const struct crush_map *map,
                                        reject = 1;
                                        goto reject;
                                }
-                               if (local_fallback_tries > 0 &&
+                               if (local_fallback_retries > 0 &&
                                    flocal >= (in->size>>1) &&
-                                   flocal > local_fallback_tries)
+                                   flocal > local_fallback_retries)
                                        item = bucket_perm_choose(in, x, r);
                                else
                                        item = crush_bucket_choose(in, x, r);
@@ -387,16 +394,23 @@ static int crush_choose_firstn(const struct crush_map *map,
                                reject = 0;
                                if (!collide && recurse_to_leaf) {
                                        if (item < 0) {
+                                               int sub_r;
+                                               if (vary_r)
+                                                       sub_r = r >> (vary_r-1);
+                                               else
+                                                       sub_r = 0;
                                                if (crush_choose_firstn(map,
                                                         map->buckets[-1-item],
                                                         weight, weight_max,
                                                         x, outpos+1, 0,
                                                         out2, outpos,
                                                         recurse_tries, 0,
-                                                        local_tries,
-                                                        local_fallback_tries,
+                                                        local_retries,
+                                                        local_fallback_retries,
                                                         0,
-                                                        NULL) <= outpos)
+                                                        vary_r,
+                                                        NULL,
+                                                        sub_r) <= outpos)
                                                        /* didn't get leaf */
                                                        reject = 1;
                                        } else {
@@ -420,14 +434,14 @@ reject:
                                        ftotal++;
                                        flocal++;
 
-                                       if (collide && flocal <= local_tries)
+                                       if (collide && flocal <= local_retries)
                                                /* retry locally a few times */
                                                retry_bucket = 1;
-                                       else if (local_fallback_tries > 0 &&
-                                                flocal <= in->size + local_fallback_tries)
+                                       else if (local_fallback_retries > 0 &&
+                                                flocal <= in->size + local_fallback_retries)
                                                /* exhaustive bucket search */
                                                retry_bucket = 1;
-                                       else if (ftotal <= tries)
+                                       else if (ftotal < tries)
                                                /* then retry descent */
                                                retry_descent = 1;
                                        else
@@ -640,10 +654,20 @@ int crush_do_rule(const struct crush_map *map,
        __u32 step;
        int i, j;
        int numrep;
-       int choose_tries = map->choose_total_tries;
-       int choose_local_tries = map->choose_local_tries;
-       int choose_local_fallback_tries = map->choose_local_fallback_tries;
+       /*
+        * the original choose_total_tries value was off by one (it
+        * counted "retries" and not "tries").  add one.
+        */
+       int choose_tries = map->choose_total_tries + 1;
        int choose_leaf_tries = 0;
+       /*
+        * the local tries values were counted as "retries", though,
+        * and need no adjustment
+        */
+       int choose_local_retries = map->choose_local_tries;
+       int choose_local_fallback_retries = map->choose_local_fallback_tries;
+
+       int vary_r = map->chooseleaf_vary_r;
 
        if ((__u32)ruleno >= map->max_rules) {
                dprintk(" bad ruleno %d\n", ruleno);
@@ -676,13 +700,18 @@ int crush_do_rule(const struct crush_map *map,
                        break;
 
                case CRUSH_RULE_SET_CHOOSE_LOCAL_TRIES:
-                       if (curstep->arg1 > 0)
-                               choose_local_tries = curstep->arg1;
+                       if (curstep->arg1 >= 0)
+                               choose_local_retries = curstep->arg1;
                        break;
 
                case CRUSH_RULE_SET_CHOOSE_LOCAL_FALLBACK_TRIES:
-                       if (curstep->arg1 > 0)
-                               choose_local_fallback_tries = curstep->arg1;
+                       if (curstep->arg1 >= 0)
+                               choose_local_fallback_retries = curstep->arg1;
+                       break;
+
+               case CRUSH_RULE_SET_CHOOSELEAF_VARY_R:
+                       if (curstep->arg1 >= 0)
+                               vary_r = curstep->arg1;
                        break;
 
                case CRUSH_RULE_CHOOSELEAF_FIRSTN:
@@ -734,10 +763,12 @@ int crush_do_rule(const struct crush_map *map,
                                                o+osize, j,
                                                choose_tries,
                                                recurse_tries,
-                                               choose_local_tries,
-                                               choose_local_fallback_tries,
+                                               choose_local_retries,
+                                               choose_local_fallback_retries,
                                                recurse_to_leaf,
-                                               c+osize);
+                                               vary_r,
+                                               c+osize,
+                                               0);
                                } else {
                                        crush_choose_indep(
                                                map,
index 258a382e75ed665a597d063a1234150e47d8f5f0..10421a4b76f8710def7328e45dabf227cc3cdb3b 100644 (file)
@@ -53,34 +53,55 @@ static int osdmap_show(struct seq_file *s, void *p)
 {
        int i;
        struct ceph_client *client = s->private;
+       struct ceph_osdmap *map = client->osdc.osdmap;
        struct rb_node *n;
 
-       if (client->osdc.osdmap == NULL)
+       if (map == NULL)
                return 0;
-       seq_printf(s, "epoch %d\n", client->osdc.osdmap->epoch);
+
+       seq_printf(s, "epoch %d\n", map->epoch);
        seq_printf(s, "flags%s%s\n",
-                  (client->osdc.osdmap->flags & CEPH_OSDMAP_NEARFULL) ?
-                  " NEARFULL" : "",
-                  (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ?
-                  " FULL" : "");
-       for (n = rb_first(&client->osdc.osdmap->pg_pools); n; n = rb_next(n)) {
+                  (map->flags & CEPH_OSDMAP_NEARFULL) ?  " NEARFULL" : "",
+                  (map->flags & CEPH_OSDMAP_FULL) ?  " FULL" : "");
+
+       for (n = rb_first(&map->pg_pools); n; n = rb_next(n)) {
                struct ceph_pg_pool_info *pool =
                        rb_entry(n, struct ceph_pg_pool_info, node);
-               seq_printf(s, "pg_pool %llu pg_num %d / %d\n",
-                          (unsigned long long)pool->id, pool->pg_num,
-                          pool->pg_num_mask);
+
+               seq_printf(s, "pool %lld pg_num %u (%d) read_tier %lld write_tier %lld\n",
+                          pool->id, pool->pg_num, pool->pg_num_mask,
+                          pool->read_tier, pool->write_tier);
        }
-       for (i = 0; i < client->osdc.osdmap->max_osd; i++) {
-               struct ceph_entity_addr *addr =
-                       &client->osdc.osdmap->osd_addr[i];
-               int state = client->osdc.osdmap->osd_state[i];
+       for (i = 0; i < map->max_osd; i++) {
+               struct ceph_entity_addr *addr = &map->osd_addr[i];
+               int state = map->osd_state[i];
                char sb[64];
 
-               seq_printf(s, "\tosd%d\t%s\t%3d%%\t(%s)\n",
+               seq_printf(s, "osd%d\t%s\t%3d%%\t(%s)\t%3d%%\n",
                           i, ceph_pr_addr(&addr->in_addr),
-                          ((client->osdc.osdmap->osd_weight[i]*100) >> 16),
-                          ceph_osdmap_state_str(sb, sizeof(sb), state));
+                          ((map->osd_weight[i]*100) >> 16),
+                          ceph_osdmap_state_str(sb, sizeof(sb), state),
+                          ((ceph_get_primary_affinity(map, i)*100) >> 16));
+       }
+       for (n = rb_first(&map->pg_temp); n; n = rb_next(n)) {
+               struct ceph_pg_mapping *pg =
+                       rb_entry(n, struct ceph_pg_mapping, node);
+
+               seq_printf(s, "pg_temp %llu.%x [", pg->pgid.pool,
+                          pg->pgid.seed);
+               for (i = 0; i < pg->pg_temp.len; i++)
+                       seq_printf(s, "%s%d", (i == 0 ? "" : ","),
+                                  pg->pg_temp.osds[i]);
+               seq_printf(s, "]\n");
        }
+       for (n = rb_first(&map->primary_temp); n; n = rb_next(n)) {
+               struct ceph_pg_mapping *pg =
+                       rb_entry(n, struct ceph_pg_mapping, node);
+
+               seq_printf(s, "primary_temp %llu.%x %d\n", pg->pgid.pool,
+                          pg->pgid.seed, pg->primary_temp.osd);
+       }
+
        return 0;
 }
 
index 30efc5c186222c64ea3d7d21b194f8ce9f4e0f47..4f55f9ce63fac652f789353c6c3dc6f0e932951b 100644 (file)
@@ -919,6 +919,9 @@ static bool ceph_msg_data_pages_advance(struct ceph_msg_data_cursor *cursor,
        if (!bytes || cursor->page_offset)
                return false;   /* more bytes to process in the current page */
 
+       if (!cursor->resid)
+               return false;   /* no more data */
+
        /* Move on to the next page; offset is already at 0 */
 
        BUG_ON(cursor->page_index >= cursor->page_count);
@@ -1004,6 +1007,9 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor,
        if (!bytes || cursor->offset & ~PAGE_MASK)
                return false;   /* more bytes to process in the current page */
 
+       if (!cursor->resid)
+               return false;   /* no more data */
+
        /* Move on to the next page */
 
        BUG_ON(list_is_last(&cursor->page->lru, &pagelist->head));
index 82750f9158655225ad7dab9e903932d38f97b8a5..b0dfce77656a0ba9c43d6d6616be1d28fb4dc137 100644 (file)
@@ -436,6 +436,7 @@ static bool osd_req_opcode_valid(u16 opcode)
        case CEPH_OSD_OP_OMAPCLEAR:
        case CEPH_OSD_OP_OMAPRMKEYS:
        case CEPH_OSD_OP_OMAP_CMP:
+       case CEPH_OSD_OP_SETALLOCHINT:
        case CEPH_OSD_OP_CLONERANGE:
        case CEPH_OSD_OP_ASSERT_SRC_VERSION:
        case CEPH_OSD_OP_SRC_CMPXATTR:
@@ -591,6 +592,26 @@ void osd_req_op_watch_init(struct ceph_osd_request *osd_req,
 }
 EXPORT_SYMBOL(osd_req_op_watch_init);
 
+void osd_req_op_alloc_hint_init(struct ceph_osd_request *osd_req,
+                               unsigned int which,
+                               u64 expected_object_size,
+                               u64 expected_write_size)
+{
+       struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which,
+                                                     CEPH_OSD_OP_SETALLOCHINT);
+
+       op->alloc_hint.expected_object_size = expected_object_size;
+       op->alloc_hint.expected_write_size = expected_write_size;
+
+       /*
+        * CEPH_OSD_OP_SETALLOCHINT op is advisory and therefore deemed
+        * not worth a feature bit.  Set FAILOK per-op flag to make
+        * sure older osds don't trip over an unsupported opcode.
+        */
+       op->flags |= CEPH_OSD_OP_FLAG_FAILOK;
+}
+EXPORT_SYMBOL(osd_req_op_alloc_hint_init);
+
 static void ceph_osdc_msg_data_add(struct ceph_msg *msg,
                                struct ceph_osd_data *osd_data)
 {
@@ -681,6 +702,12 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                dst->watch.ver = cpu_to_le64(src->watch.ver);
                dst->watch.flag = src->watch.flag;
                break;
+       case CEPH_OSD_OP_SETALLOCHINT:
+               dst->alloc_hint.expected_object_size =
+                   cpu_to_le64(src->alloc_hint.expected_object_size);
+               dst->alloc_hint.expected_write_size =
+                   cpu_to_le64(src->alloc_hint.expected_write_size);
+               break;
        default:
                pr_err("unsupported osd opcode %s\n",
                        ceph_osd_op_name(src->op));
@@ -688,7 +715,9 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
 
                return 0;
        }
+
        dst->op = cpu_to_le16(src->op);
+       dst->flags = cpu_to_le32(src->flags);
        dst->payload_len = cpu_to_le32(src->payload_len);
 
        return request_data_len;
@@ -1304,7 +1333,7 @@ static int __map_request(struct ceph_osd_client *osdc,
 {
        struct ceph_pg pgid;
        int acting[CEPH_PG_MAX_SIZE];
-       int o = -1, num = 0;
+       int num, o;
        int err;
        bool was_paused;
 
@@ -1317,11 +1346,9 @@ static int __map_request(struct ceph_osd_client *osdc,
        }
        req->r_pgid = pgid;
 
-       err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting);
-       if (err > 0) {
-               o = acting[0];
-               num = err;
-       }
+       num = ceph_calc_pg_acting(osdc->osdmap, pgid, acting, &o);
+       if (num < 0)
+               num = 0;
 
        was_paused = req->r_paused;
        req->r_paused = __req_should_be_paused(osdc, req);
@@ -2033,7 +2060,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
                        int skipped_map = 0;
 
                        dout("taking full map %u len %d\n", epoch, maplen);
-                       newmap = osdmap_decode(&p, p+maplen);
+                       newmap = ceph_osdmap_decode(&p, p+maplen);
                        if (IS_ERR(newmap)) {
                                err = PTR_ERR(newmap);
                                goto bad;
index aade4a5c1c07f6ab0ca0f1ee66dfacbded110aed..e632b5a52f5b89cb2e275b64494905cc7ebfc8e7 100644 (file)
@@ -343,7 +343,7 @@ bad:
 
 /*
  * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
- * to a set of osds)
+ * to a set of osds) and primary_temp (explicit primary setting)
  */
 static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
 {
@@ -506,7 +506,7 @@ static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
        kfree(pi);
 }
 
-static int __decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
+static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
 {
        u8 ev, cv;
        unsigned len, num;
@@ -587,7 +587,7 @@ bad:
        return -EINVAL;
 }
 
-static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
+static int decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
 {
        struct ceph_pg_pool_info *pi;
        u32 num, len;
@@ -633,6 +633,13 @@ void ceph_osdmap_destroy(struct ceph_osdmap *map)
                rb_erase(&pg->node, &map->pg_temp);
                kfree(pg);
        }
+       while (!RB_EMPTY_ROOT(&map->primary_temp)) {
+               struct ceph_pg_mapping *pg =
+                       rb_entry(rb_first(&map->primary_temp),
+                                struct ceph_pg_mapping, node);
+               rb_erase(&pg->node, &map->primary_temp);
+               kfree(pg);
+       }
        while (!RB_EMPTY_ROOT(&map->pg_pools)) {
                struct ceph_pg_pool_info *pi =
                        rb_entry(rb_first(&map->pg_pools),
@@ -642,186 +649,516 @@ void ceph_osdmap_destroy(struct ceph_osdmap *map)
        kfree(map->osd_state);
        kfree(map->osd_weight);
        kfree(map->osd_addr);
+       kfree(map->osd_primary_affinity);
        kfree(map);
 }
 
 /*
- * adjust max osd value.  reallocate arrays.
+ * Adjust max_osd value, (re)allocate arrays.
+ *
+ * The new elements are properly initialized.
  */
 static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
 {
        u8 *state;
-       struct ceph_entity_addr *addr;
        u32 *weight;
+       struct ceph_entity_addr *addr;
+       int i;
 
-       state = kcalloc(max, sizeof(*state), GFP_NOFS);
-       addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
-       weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
-       if (state == NULL || addr == NULL || weight == NULL) {
+       state = krealloc(map->osd_state, max*sizeof(*state), GFP_NOFS);
+       weight = krealloc(map->osd_weight, max*sizeof(*weight), GFP_NOFS);
+       addr = krealloc(map->osd_addr, max*sizeof(*addr), GFP_NOFS);
+       if (!state || !weight || !addr) {
                kfree(state);
-               kfree(addr);
                kfree(weight);
+               kfree(addr);
+
                return -ENOMEM;
        }
 
-       /* copy old? */
-       if (map->osd_state) {
-               memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
-               memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
-               memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
-               kfree(map->osd_state);
-               kfree(map->osd_addr);
-               kfree(map->osd_weight);
+       for (i = map->max_osd; i < max; i++) {
+               state[i] = 0;
+               weight[i] = CEPH_OSD_OUT;
+               memset(addr + i, 0, sizeof(*addr));
        }
 
        map->osd_state = state;
        map->osd_weight = weight;
        map->osd_addr = addr;
+
+       if (map->osd_primary_affinity) {
+               u32 *affinity;
+
+               affinity = krealloc(map->osd_primary_affinity,
+                                   max*sizeof(*affinity), GFP_NOFS);
+               if (!affinity)
+                       return -ENOMEM;
+
+               for (i = map->max_osd; i < max; i++)
+                       affinity[i] = CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;
+
+               map->osd_primary_affinity = affinity;
+       }
+
        map->max_osd = max;
+
        return 0;
 }
 
+#define OSDMAP_WRAPPER_COMPAT_VER      7
+#define OSDMAP_CLIENT_DATA_COMPAT_VER  1
+
 /*
- * decode a full map.
+ * Return 0 or error.  On success, *v is set to 0 for old (v6) osdmaps,
+ * to struct_v of the client_data section for new (v7 and above)
+ * osdmaps.
  */
-struct ceph_osdmap *osdmap_decode(void **p, void *end)
+static int get_osdmap_client_data_v(void **p, void *end,
+                                   const char *prefix, u8 *v)
 {
-       struct ceph_osdmap *map;
-       u16 version;
-       u32 len, max, i;
-       int err = -EINVAL;
-       void *start = *p;
-       struct ceph_pg_pool_info *pi;
+       u8 struct_v;
+
+       ceph_decode_8_safe(p, end, struct_v, e_inval);
+       if (struct_v >= 7) {
+               u8 struct_compat;
+
+               ceph_decode_8_safe(p, end, struct_compat, e_inval);
+               if (struct_compat > OSDMAP_WRAPPER_COMPAT_VER) {
+                       pr_warning("got v %d cv %d > %d of %s ceph_osdmap\n",
+                                  struct_v, struct_compat,
+                                  OSDMAP_WRAPPER_COMPAT_VER, prefix);
+                       return -EINVAL;
+               }
+               *p += 4; /* ignore wrapper struct_len */
+
+               ceph_decode_8_safe(p, end, struct_v, e_inval);
+               ceph_decode_8_safe(p, end, struct_compat, e_inval);
+               if (struct_compat > OSDMAP_CLIENT_DATA_COMPAT_VER) {
+                       pr_warning("got v %d cv %d > %d of %s ceph_osdmap client data\n",
+                                  struct_v, struct_compat,
+                                  OSDMAP_CLIENT_DATA_COMPAT_VER, prefix);
+                       return -EINVAL;
+               }
+               *p += 4; /* ignore client data struct_len */
+       } else {
+               u16 version;
+
+               *p -= 1;
+               ceph_decode_16_safe(p, end, version, e_inval);
+               if (version < 6) {
+                       pr_warning("got v %d < 6 of %s ceph_osdmap\n", version,
+                                  prefix);
+                       return -EINVAL;
+               }
 
-       dout("osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+               /* old osdmap enconding */
+               struct_v = 0;
+       }
 
-       map = kzalloc(sizeof(*map), GFP_NOFS);
-       if (map == NULL)
-               return ERR_PTR(-ENOMEM);
-       map->pg_temp = RB_ROOT;
+       *v = struct_v;
+       return 0;
 
-       ceph_decode_16_safe(p, end, version, bad);
-       if (version > 6) {
-               pr_warning("got unknown v %d > 6 of osdmap\n", version);
-               goto bad;
+e_inval:
+       return -EINVAL;
+}
+
+static int __decode_pools(void **p, void *end, struct ceph_osdmap *map,
+                         bool incremental)
+{
+       u32 n;
+
+       ceph_decode_32_safe(p, end, n, e_inval);
+       while (n--) {
+               struct ceph_pg_pool_info *pi;
+               u64 pool;
+               int ret;
+
+               ceph_decode_64_safe(p, end, pool, e_inval);
+
+               pi = __lookup_pg_pool(&map->pg_pools, pool);
+               if (!incremental || !pi) {
+                       pi = kzalloc(sizeof(*pi), GFP_NOFS);
+                       if (!pi)
+                               return -ENOMEM;
+
+                       pi->id = pool;
+
+                       ret = __insert_pg_pool(&map->pg_pools, pi);
+                       if (ret) {
+                               kfree(pi);
+                               return ret;
+                       }
+               }
+
+               ret = decode_pool(p, end, pi);
+               if (ret)
+                       return ret;
        }
-       if (version < 6) {
-               pr_warning("got old v %d < 6 of osdmap\n", version);
-               goto bad;
+
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+static int decode_pools(void **p, void *end, struct ceph_osdmap *map)
+{
+       return __decode_pools(p, end, map, false);
+}
+
+static int decode_new_pools(void **p, void *end, struct ceph_osdmap *map)
+{
+       return __decode_pools(p, end, map, true);
+}
+
+static int __decode_pg_temp(void **p, void *end, struct ceph_osdmap *map,
+                           bool incremental)
+{
+       u32 n;
+
+       ceph_decode_32_safe(p, end, n, e_inval);
+       while (n--) {
+               struct ceph_pg pgid;
+               u32 len, i;
+               int ret;
+
+               ret = ceph_decode_pgid(p, end, &pgid);
+               if (ret)
+                       return ret;
+
+               ceph_decode_32_safe(p, end, len, e_inval);
+
+               ret = __remove_pg_mapping(&map->pg_temp, pgid);
+               BUG_ON(!incremental && ret != -ENOENT);
+
+               if (!incremental || len > 0) {
+                       struct ceph_pg_mapping *pg;
+
+                       ceph_decode_need(p, end, len*sizeof(u32), e_inval);
+
+                       if (len > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
+                               return -EINVAL;
+
+                       pg = kzalloc(sizeof(*pg) + len*sizeof(u32), GFP_NOFS);
+                       if (!pg)
+                               return -ENOMEM;
+
+                       pg->pgid = pgid;
+                       pg->pg_temp.len = len;
+                       for (i = 0; i < len; i++)
+                               pg->pg_temp.osds[i] = ceph_decode_32(p);
+
+                       ret = __insert_pg_mapping(pg, &map->pg_temp);
+                       if (ret) {
+                               kfree(pg);
+                               return ret;
+                       }
+               }
        }
 
-       ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad);
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+static int decode_pg_temp(void **p, void *end, struct ceph_osdmap *map)
+{
+       return __decode_pg_temp(p, end, map, false);
+}
+
+static int decode_new_pg_temp(void **p, void *end, struct ceph_osdmap *map)
+{
+       return __decode_pg_temp(p, end, map, true);
+}
+
+static int __decode_primary_temp(void **p, void *end, struct ceph_osdmap *map,
+                                bool incremental)
+{
+       u32 n;
+
+       ceph_decode_32_safe(p, end, n, e_inval);
+       while (n--) {
+               struct ceph_pg pgid;
+               u32 osd;
+               int ret;
+
+               ret = ceph_decode_pgid(p, end, &pgid);
+               if (ret)
+                       return ret;
+
+               ceph_decode_32_safe(p, end, osd, e_inval);
+
+               ret = __remove_pg_mapping(&map->primary_temp, pgid);
+               BUG_ON(!incremental && ret != -ENOENT);
+
+               if (!incremental || osd != (u32)-1) {
+                       struct ceph_pg_mapping *pg;
+
+                       pg = kzalloc(sizeof(*pg), GFP_NOFS);
+                       if (!pg)
+                               return -ENOMEM;
+
+                       pg->pgid = pgid;
+                       pg->primary_temp.osd = osd;
+
+                       ret = __insert_pg_mapping(pg, &map->primary_temp);
+                       if (ret) {
+                               kfree(pg);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+static int decode_primary_temp(void **p, void *end, struct ceph_osdmap *map)
+{
+       return __decode_primary_temp(p, end, map, false);
+}
+
+static int decode_new_primary_temp(void **p, void *end,
+                                  struct ceph_osdmap *map)
+{
+       return __decode_primary_temp(p, end, map, true);
+}
+
+u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd)
+{
+       BUG_ON(osd >= map->max_osd);
+
+       if (!map->osd_primary_affinity)
+               return CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;
+
+       return map->osd_primary_affinity[osd];
+}
+
+static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff)
+{
+       BUG_ON(osd >= map->max_osd);
+
+       if (!map->osd_primary_affinity) {
+               int i;
+
+               map->osd_primary_affinity = kmalloc(map->max_osd*sizeof(u32),
+                                                   GFP_NOFS);
+               if (!map->osd_primary_affinity)
+                       return -ENOMEM;
+
+               for (i = 0; i < map->max_osd; i++)
+                       map->osd_primary_affinity[i] =
+                           CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;
+       }
+
+       map->osd_primary_affinity[osd] = aff;
+
+       return 0;
+}
+
+static int decode_primary_affinity(void **p, void *end,
+                                  struct ceph_osdmap *map)
+{
+       u32 len, i;
+
+       ceph_decode_32_safe(p, end, len, e_inval);
+       if (len == 0) {
+               kfree(map->osd_primary_affinity);
+               map->osd_primary_affinity = NULL;
+               return 0;
+       }
+       if (len != map->max_osd)
+               goto e_inval;
+
+       ceph_decode_need(p, end, map->max_osd*sizeof(u32), e_inval);
+
+       for (i = 0; i < map->max_osd; i++) {
+               int ret;
+
+               ret = set_primary_affinity(map, i, ceph_decode_32(p));
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+static int decode_new_primary_affinity(void **p, void *end,
+                                      struct ceph_osdmap *map)
+{
+       u32 n;
+
+       ceph_decode_32_safe(p, end, n, e_inval);
+       while (n--) {
+               u32 osd, aff;
+               int ret;
+
+               ceph_decode_32_safe(p, end, osd, e_inval);
+               ceph_decode_32_safe(p, end, aff, e_inval);
+
+               ret = set_primary_affinity(map, osd, aff);
+               if (ret)
+                       return ret;
+
+               pr_info("osd%d primary-affinity 0x%x\n", osd, aff);
+       }
+
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+/*
+ * decode a full map.
+ */
+static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map)
+{
+       u8 struct_v;
+       u32 epoch = 0;
+       void *start = *p;
+       u32 max;
+       u32 len, i;
+       int err;
+
+       dout("%s %p to %p len %d\n", __func__, *p, end, (int)(end - *p));
+
+       err = get_osdmap_client_data_v(p, end, "full", &struct_v);
+       if (err)
+               goto bad;
+
+       /* fsid, epoch, created, modified */
+       ceph_decode_need(p, end, sizeof(map->fsid) + sizeof(u32) +
+                        sizeof(map->created) + sizeof(map->modified), e_inval);
        ceph_decode_copy(p, &map->fsid, sizeof(map->fsid));
-       map->epoch = ceph_decode_32(p);
+       epoch = map->epoch = ceph_decode_32(p);
        ceph_decode_copy(p, &map->created, sizeof(map->created));
        ceph_decode_copy(p, &map->modified, sizeof(map->modified));
 
-       ceph_decode_32_safe(p, end, max, bad);
-       while (max--) {
-               ceph_decode_need(p, end, 8 + 2, bad);
-               err = -ENOMEM;
-               pi = kzalloc(sizeof(*pi), GFP_NOFS);
-               if (!pi)
-                       goto bad;
-               pi->id = ceph_decode_64(p);
-               err = __decode_pool(p, end, pi);
-               if (err < 0) {
-                       kfree(pi);
-                       goto bad;
-               }
-               __insert_pg_pool(&map->pg_pools, pi);
-       }
+       /* pools */
+       err = decode_pools(p, end, map);
+       if (err)
+               goto bad;
 
-       err = __decode_pool_names(p, end, map);
-       if (err < 0) {
-               dout("fail to decode pool names");
+       /* pool_name */
+       err = decode_pool_names(p, end, map);
+       if (err)
                goto bad;
-       }
 
-       ceph_decode_32_safe(p, end, map->pool_max, bad);
+       ceph_decode_32_safe(p, end, map->pool_max, e_inval);
 
-       ceph_decode_32_safe(p, end, map->flags, bad);
+       ceph_decode_32_safe(p, end, map->flags, e_inval);
 
-       max = ceph_decode_32(p);
+       /* max_osd */
+       ceph_decode_32_safe(p, end, max, e_inval);
 
        /* (re)alloc osd arrays */
        err = osdmap_set_max_osd(map, max);
-       if (err < 0)
+       if (err)
                goto bad;
-       dout("osdmap_decode max_osd = %d\n", map->max_osd);
 
-       /* osds */
-       err = -EINVAL;
+       /* osd_state, osd_weight, osd_addrs->client_addr */
        ceph_decode_need(p, end, 3*sizeof(u32) +
                         map->max_osd*(1 + sizeof(*map->osd_weight) +
-                                      sizeof(*map->osd_addr)), bad);
-       *p += 4; /* skip length field (should match max) */
+                                      sizeof(*map->osd_addr)), e_inval);
+
+       if (ceph_decode_32(p) != map->max_osd)
+               goto e_inval;
+
        ceph_decode_copy(p, map->osd_state, map->max_osd);
 
-       *p += 4; /* skip length field (should match max) */
+       if (ceph_decode_32(p) != map->max_osd)
+               goto e_inval;
+
        for (i = 0; i < map->max_osd; i++)
                map->osd_weight[i] = ceph_decode_32(p);
 
-       *p += 4; /* skip length field (should match max) */
+       if (ceph_decode_32(p) != map->max_osd)
+               goto e_inval;
+
        ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr));
        for (i = 0; i < map->max_osd; i++)
                ceph_decode_addr(&map->osd_addr[i]);
 
        /* pg_temp */
-       ceph_decode_32_safe(p, end, len, bad);
-       for (i = 0; i < len; i++) {
-               int n, j;
-               struct ceph_pg pgid;
-               struct ceph_pg_mapping *pg;
+       err = decode_pg_temp(p, end, map);
+       if (err)
+               goto bad;
 
-               err = ceph_decode_pgid(p, end, &pgid);
+       /* primary_temp */
+       if (struct_v >= 1) {
+               err = decode_primary_temp(p, end, map);
                if (err)
                        goto bad;
-               ceph_decode_need(p, end, sizeof(u32), bad);
-               n = ceph_decode_32(p);
-               err = -EINVAL;
-               if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
-                       goto bad;
-               ceph_decode_need(p, end, n * sizeof(u32), bad);
-               err = -ENOMEM;
-               pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
-               if (!pg)
-                       goto bad;
-               pg->pgid = pgid;
-               pg->len = n;
-               for (j = 0; j < n; j++)
-                       pg->osds[j] = ceph_decode_32(p);
+       }
 
-               err = __insert_pg_mapping(pg, &map->pg_temp);
+       /* primary_affinity */
+       if (struct_v >= 2) {
+               err = decode_primary_affinity(p, end, map);
                if (err)
                        goto bad;
-               dout(" added pg_temp %lld.%x len %d\n", pgid.pool, pgid.seed,
-                    len);
+       } else {
+               /* XXX can this happen? */
+               kfree(map->osd_primary_affinity);
+               map->osd_primary_affinity = NULL;
        }
 
        /* crush */
-       ceph_decode_32_safe(p, end, len, bad);
-       dout("osdmap_decode crush len %d from off 0x%x\n", len,
-            (int)(*p - start));
-       ceph_decode_need(p, end, len, bad);
-       map->crush = crush_decode(*p, end);
-       *p += len;
+       ceph_decode_32_safe(p, end, len, e_inval);
+       map->crush = crush_decode(*p, min(*p + len, end));
        if (IS_ERR(map->crush)) {
                err = PTR_ERR(map->crush);
                map->crush = NULL;
                goto bad;
        }
+       *p += len;
 
-       /* ignore the rest of the map */
+       /* ignore the rest */
        *p = end;
 
-       dout("osdmap_decode done %p %p\n", *p, end);
-       return map;
+       dout("full osdmap epoch %d max_osd %d\n", map->epoch, map->max_osd);
+       return 0;
 
+e_inval:
+       err = -EINVAL;
 bad:
-       dout("osdmap_decode fail err %d\n", err);
-       ceph_osdmap_destroy(map);
-       return ERR_PTR(err);
+       pr_err("corrupt full osdmap (%d) epoch %d off %d (%p of %p-%p)\n",
+              err, epoch, (int)(*p - start), *p, start, end);
+       print_hex_dump(KERN_DEBUG, "osdmap: ",
+                      DUMP_PREFIX_OFFSET, 16, 1,
+                      start, end - start, true);
+       return err;
+}
+
+/*
+ * Allocate and decode a full map.
+ */
+struct ceph_osdmap *ceph_osdmap_decode(void **p, void *end)
+{
+       struct ceph_osdmap *map;
+       int ret;
+
+       map = kzalloc(sizeof(*map), GFP_NOFS);
+       if (!map)
+               return ERR_PTR(-ENOMEM);
+
+       map->pg_temp = RB_ROOT;
+       map->primary_temp = RB_ROOT;
+       mutex_init(&map->crush_scratch_mutex);
+
+       ret = osdmap_decode(p, end, map);
+       if (ret) {
+               ceph_osdmap_destroy(map);
+               return ERR_PTR(ret);
+       }
+
+       return map;
 }
 
 /*
@@ -840,17 +1177,18 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        __s64 new_pool_max;
        __s32 new_flags, max;
        void *start = *p;
-       int err = -EINVAL;
-       u16 version;
+       int err;
+       u8 struct_v;
+
+       dout("%s %p to %p len %d\n", __func__, *p, end, (int)(end - *p));
 
-       ceph_decode_16_safe(p, end, version, bad);
-       if (version != 6) {
-               pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
+       err = get_osdmap_client_data_v(p, end, "inc", &struct_v);
+       if (err)
                goto bad;
-       }
 
-       ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32),
-                        bad);
+       /* fsid, epoch, modified, new_pool_max, new_flags */
+       ceph_decode_need(p, end, sizeof(fsid) + sizeof(u32) + sizeof(modified) +
+                        sizeof(u64) + sizeof(u32), e_inval);
        ceph_decode_copy(p, &fsid, sizeof(fsid));
        epoch = ceph_decode_32(p);
        BUG_ON(epoch != map->epoch+1);
@@ -859,21 +1197,22 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        new_flags = ceph_decode_32(p);
 
        /* full map? */
-       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_32_safe(p, end, len, e_inval);
        if (len > 0) {
                dout("apply_incremental full map len %d, %p to %p\n",
                     len, *p, end);
-               return osdmap_decode(p, min(*p+len, end));
+               return ceph_osdmap_decode(p, min(*p+len, end));
        }
 
        /* new crush? */
-       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_32_safe(p, end, len, e_inval);
        if (len > 0) {
-               dout("apply_incremental new crush map len %d, %p to %p\n",
-                    len, *p, end);
                newcrush = crush_decode(*p, min(*p+len, end));
-               if (IS_ERR(newcrush))
-                       return ERR_CAST(newcrush);
+               if (IS_ERR(newcrush)) {
+                       err = PTR_ERR(newcrush);
+                       newcrush = NULL;
+                       goto bad;
+               }
                *p += len;
        }
 
@@ -883,13 +1222,11 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        if (new_pool_max >= 0)
                map->pool_max = new_pool_max;
 
-       ceph_decode_need(p, end, 5*sizeof(u32), bad);
-
        /* new max? */
-       max = ceph_decode_32(p);
+       ceph_decode_32_safe(p, end, max, e_inval);
        if (max >= 0) {
                err = osdmap_set_max_osd(map, max);
-               if (err < 0)
+               if (err)
                        goto bad;
        }
 
@@ -902,51 +1239,34 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                newcrush = NULL;
        }
 
-       /* new_pool */
-       ceph_decode_32_safe(p, end, len, bad);
-       while (len--) {
-               struct ceph_pg_pool_info *pi;
+       /* new_pools */
+       err = decode_new_pools(p, end, map);
+       if (err)
+               goto bad;
 
-               ceph_decode_64_safe(p, end, pool, bad);
-               pi = __lookup_pg_pool(&map->pg_pools, pool);
-               if (!pi) {
-                       pi = kzalloc(sizeof(*pi), GFP_NOFS);
-                       if (!pi) {
-                               err = -ENOMEM;
-                               goto bad;
-                       }
-                       pi->id = pool;
-                       __insert_pg_pool(&map->pg_pools, pi);
-               }
-               err = __decode_pool(p, end, pi);
-               if (err < 0)
-                       goto bad;
-       }
-       if (version >= 5) {
-               err = __decode_pool_names(p, end, map);
-               if (err < 0)
-                       goto bad;
-       }
+       /* new_pool_names */
+       err = decode_pool_names(p, end, map);
+       if (err)
+               goto bad;
 
        /* old_pool */
-       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_32_safe(p, end, len, e_inval);
        while (len--) {
                struct ceph_pg_pool_info *pi;
 
-               ceph_decode_64_safe(p, end, pool, bad);
+               ceph_decode_64_safe(p, end, pool, e_inval);
                pi = __lookup_pg_pool(&map->pg_pools, pool);
                if (pi)
                        __remove_pg_pool(&map->pg_pools, pi);
        }
 
        /* new_up */
-       err = -EINVAL;
-       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_32_safe(p, end, len, e_inval);
        while (len--) {
                u32 osd;
                struct ceph_entity_addr addr;
-               ceph_decode_32_safe(p, end, osd, bad);
-               ceph_decode_copy_safe(p, end, &addr, sizeof(addr), bad);
+               ceph_decode_32_safe(p, end, osd, e_inval);
+               ceph_decode_copy_safe(p, end, &addr, sizeof(addr), e_inval);
                ceph_decode_addr(&addr);
                pr_info("osd%d up\n", osd);
                BUG_ON(osd >= map->max_osd);
@@ -955,11 +1275,11 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        }
 
        /* new_state */
-       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_32_safe(p, end, len, e_inval);
        while (len--) {
                u32 osd;
                u8 xorstate;
-               ceph_decode_32_safe(p, end, osd, bad);
+               ceph_decode_32_safe(p, end, osd, e_inval);
                xorstate = **(u8 **)p;
                (*p)++;  /* clean flag */
                if (xorstate == 0)
@@ -971,10 +1291,10 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        }
 
        /* new_weight */
-       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_32_safe(p, end, len, e_inval);
        while (len--) {
                u32 osd, off;
-               ceph_decode_need(p, end, sizeof(u32)*2, bad);
+               ceph_decode_need(p, end, sizeof(u32)*2, e_inval);
                osd = ceph_decode_32(p);
                off = ceph_decode_32(p);
                pr_info("osd%d weight 0x%x %s\n", osd, off,
@@ -985,56 +1305,35 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        }
 
        /* new_pg_temp */
-       ceph_decode_32_safe(p, end, len, bad);
-       while (len--) {
-               struct ceph_pg_mapping *pg;
-               int j;
-               struct ceph_pg pgid;
-               u32 pglen;
+       err = decode_new_pg_temp(p, end, map);
+       if (err)
+               goto bad;
 
-               err = ceph_decode_pgid(p, end, &pgid);
+       /* new_primary_temp */
+       if (struct_v >= 1) {
+               err = decode_new_primary_temp(p, end, map);
                if (err)
                        goto bad;
-               ceph_decode_need(p, end, sizeof(u32), bad);
-               pglen = ceph_decode_32(p);
-               if (pglen) {
-                       ceph_decode_need(p, end, pglen*sizeof(u32), bad);
-
-                       /* removing existing (if any) */
-                       (void) __remove_pg_mapping(&map->pg_temp, pgid);
+       }
 
-                       /* insert */
-                       err = -EINVAL;
-                       if (pglen > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
-                               goto bad;
-                       err = -ENOMEM;
-                       pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
-                       if (!pg)
-                               goto bad;
-                       pg->pgid = pgid;
-                       pg->len = pglen;
-                       for (j = 0; j < pglen; j++)
-                               pg->osds[j] = ceph_decode_32(p);
-                       err = __insert_pg_mapping(pg, &map->pg_temp);
-                       if (err) {
-                               kfree(pg);
-                               goto bad;
-                       }
-                       dout(" added pg_temp %lld.%x len %d\n", pgid.pool,
-                            pgid.seed, pglen);
-               } else {
-                       /* remove */
-                       __remove_pg_mapping(&map->pg_temp, pgid);
-               }
+       /* new_primary_affinity */
+       if (struct_v >= 2) {
+               err = decode_new_primary_affinity(p, end, map);
+               if (err)
+                       goto bad;
        }
 
        /* ignore the rest */
        *p = end;
+
+       dout("inc osdmap epoch %d max_osd %d\n", map->epoch, map->max_osd);
        return map;
 
+e_inval:
+       err = -EINVAL;
 bad:
-       pr_err("corrupt inc osdmap epoch %d off %d (%p of %p-%p)\n",
-              epoch, (int)(*p - start), *p, start, end);
+       pr_err("corrupt inc osdmap (%d) epoch %d off %d (%p of %p-%p)\n",
+              err, epoch, (int)(*p - start), *p, start, end);
        print_hex_dump(KERN_DEBUG, "osdmap: ",
                       DUMP_PREFIX_OFFSET, 16, 1,
                       start, end - start, true);
@@ -1142,61 +1441,249 @@ int ceph_oloc_oid_to_pg(struct ceph_osdmap *osdmap,
 }
 EXPORT_SYMBOL(ceph_oloc_oid_to_pg);
 
-static int crush_do_rule_ary(const struct crush_map *map, int ruleno, int x,
-                            int *result, int result_max,
-                            const __u32 *weight, int weight_max)
+static int do_crush(struct ceph_osdmap *map, int ruleno, int x,
+                   int *result, int result_max,
+                   const __u32 *weight, int weight_max)
 {
-       int scratch[result_max * 3];
+       int r;
 
-       return crush_do_rule(map, ruleno, x, result, result_max,
-                            weight, weight_max, scratch);
+       BUG_ON(result_max > CEPH_PG_MAX_SIZE);
+
+       mutex_lock(&map->crush_scratch_mutex);
+       r = crush_do_rule(map->crush, ruleno, x, result, result_max,
+                         weight, weight_max, map->crush_scratch_ary);
+       mutex_unlock(&map->crush_scratch_mutex);
+
+       return r;
 }
 
 /*
- * Calculate raw osd vector for the given pgid.  Return pointer to osd
- * array, or NULL on failure.
+ * Calculate raw (crush) set for given pgid.
+ *
+ * Return raw set length, or error.
  */
-static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
-                       int *osds, int *num)
+static int pg_to_raw_osds(struct ceph_osdmap *osdmap,
+                         struct ceph_pg_pool_info *pool,
+                         struct ceph_pg pgid, u32 pps, int *osds)
 {
-       struct ceph_pg_mapping *pg;
-       struct ceph_pg_pool_info *pool;
        int ruleno;
-       int r;
-       u32 pps;
+       int len;
 
-       pool = __lookup_pg_pool(&osdmap->pg_pools, pgid.pool);
-       if (!pool)
-               return NULL;
+       /* crush */
+       ruleno = crush_find_rule(osdmap->crush, pool->crush_ruleset,
+                                pool->type, pool->size);
+       if (ruleno < 0) {
+               pr_err("no crush rule: pool %lld ruleset %d type %d size %d\n",
+                      pgid.pool, pool->crush_ruleset, pool->type,
+                      pool->size);
+               return -ENOENT;
+       }
 
-       /* pg_temp? */
+       len = do_crush(osdmap, ruleno, pps, osds,
+                      min_t(int, pool->size, CEPH_PG_MAX_SIZE),
+                      osdmap->osd_weight, osdmap->max_osd);
+       if (len < 0) {
+               pr_err("error %d from crush rule %d: pool %lld ruleset %d type %d size %d\n",
+                      len, ruleno, pgid.pool, pool->crush_ruleset,
+                      pool->type, pool->size);
+               return len;
+       }
+
+       return len;
+}
+
+/*
+ * Given raw set, calculate up set and up primary.
+ *
+ * Return up set length.  *primary is set to up primary osd id, or -1
+ * if up set is empty.
+ */
+static int raw_to_up_osds(struct ceph_osdmap *osdmap,
+                         struct ceph_pg_pool_info *pool,
+                         int *osds, int len, int *primary)
+{
+       int up_primary = -1;
+       int i;
+
+       if (ceph_can_shift_osds(pool)) {
+               int removed = 0;
+
+               for (i = 0; i < len; i++) {
+                       if (ceph_osd_is_down(osdmap, osds[i])) {
+                               removed++;
+                               continue;
+                       }
+                       if (removed)
+                               osds[i - removed] = osds[i];
+               }
+
+               len -= removed;
+               if (len > 0)
+                       up_primary = osds[0];
+       } else {
+               for (i = len - 1; i >= 0; i--) {
+                       if (ceph_osd_is_down(osdmap, osds[i]))
+                               osds[i] = CRUSH_ITEM_NONE;
+                       else
+                               up_primary = osds[i];
+               }
+       }
+
+       *primary = up_primary;
+       return len;
+}
+
+static void apply_primary_affinity(struct ceph_osdmap *osdmap, u32 pps,
+                                  struct ceph_pg_pool_info *pool,
+                                  int *osds, int len, int *primary)
+{
+       int i;
+       int pos = -1;
+
+       /*
+        * Do we have any non-default primary_affinity values for these
+        * osds?
+        */
+       if (!osdmap->osd_primary_affinity)
+               return;
+
+       for (i = 0; i < len; i++) {
+               if (osds[i] != CRUSH_ITEM_NONE &&
+                   osdmap->osd_primary_affinity[i] !=
+                                       CEPH_OSD_DEFAULT_PRIMARY_AFFINITY) {
+                       break;
+               }
+       }
+       if (i == len)
+               return;
+
+       /*
+        * Pick the primary.  Feed both the seed (for the pg) and the
+        * osd into the hash/rng so that a proportional fraction of an
+        * osd's pgs get rejected as primary.
+        */
+       for (i = 0; i < len; i++) {
+               int osd;
+               u32 aff;
+
+               osd = osds[i];
+               if (osd == CRUSH_ITEM_NONE)
+                       continue;
+
+               aff = osdmap->osd_primary_affinity[osd];
+               if (aff < CEPH_OSD_MAX_PRIMARY_AFFINITY &&
+                   (crush_hash32_2(CRUSH_HASH_RJENKINS1,
+                                   pps, osd) >> 16) >= aff) {
+                       /*
+                        * We chose not to use this primary.  Note it
+                        * anyway as a fallback in case we don't pick
+                        * anyone else, but keep looking.
+                        */
+                       if (pos < 0)
+                               pos = i;
+               } else {
+                       pos = i;
+                       break;
+               }
+       }
+       if (pos < 0)
+               return;
+
+       *primary = osds[pos];
+
+       if (ceph_can_shift_osds(pool) && pos > 0) {
+               /* move the new primary to the front */
+               for (i = pos; i > 0; i--)
+                       osds[i] = osds[i - 1];
+               osds[0] = *primary;
+       }
+}
+
+/*
+ * Given up set, apply pg_temp and primary_temp mappings.
+ *
+ * Return acting set length.  *primary is set to acting primary osd id,
+ * or -1 if acting set is empty.
+ */
+static int apply_temps(struct ceph_osdmap *osdmap,
+                      struct ceph_pg_pool_info *pool, struct ceph_pg pgid,
+                      int *osds, int len, int *primary)
+{
+       struct ceph_pg_mapping *pg;
+       int temp_len;
+       int temp_primary;
+       int i;
+
+       /* raw_pg -> pg */
        pgid.seed = ceph_stable_mod(pgid.seed, pool->pg_num,
                                    pool->pg_num_mask);
+
+       /* pg_temp? */
        pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
        if (pg) {
-               *num = pg->len;
-               return pg->osds;
+               temp_len = 0;
+               temp_primary = -1;
+
+               for (i = 0; i < pg->pg_temp.len; i++) {
+                       if (ceph_osd_is_down(osdmap, pg->pg_temp.osds[i])) {
+                               if (ceph_can_shift_osds(pool))
+                                       continue;
+                               else
+                                       osds[temp_len++] = CRUSH_ITEM_NONE;
+                       } else {
+                               osds[temp_len++] = pg->pg_temp.osds[i];
+                       }
+               }
+
+               /* apply pg_temp's primary */
+               for (i = 0; i < temp_len; i++) {
+                       if (osds[i] != CRUSH_ITEM_NONE) {
+                               temp_primary = osds[i];
+                               break;
+                       }
+               }
+       } else {
+               temp_len = len;
+               temp_primary = *primary;
        }
 
-       /* crush */
-       ruleno = crush_find_rule(osdmap->crush, pool->crush_ruleset,
-                                pool->type, pool->size);
-       if (ruleno < 0) {
-               pr_err("no crush rule pool %lld ruleset %d type %d size %d\n",
-                      pgid.pool, pool->crush_ruleset, pool->type,
-                      pool->size);
-               return NULL;
+       /* primary_temp? */
+       pg = __lookup_pg_mapping(&osdmap->primary_temp, pgid);
+       if (pg)
+               temp_primary = pg->primary_temp.osd;
+
+       *primary = temp_primary;
+       return temp_len;
+}
+
+/*
+ * Calculate acting set for given pgid.
+ *
+ * Return acting set length, or error.  *primary is set to acting
+ * primary osd id, or -1 if acting set is empty or on error.
+ */
+int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+                       int *osds, int *primary)
+{
+       struct ceph_pg_pool_info *pool;
+       u32 pps;
+       int len;
+
+       pool = __lookup_pg_pool(&osdmap->pg_pools, pgid.pool);
+       if (!pool) {
+               *primary = -1;
+               return -ENOENT;
        }
 
        if (pool->flags & CEPH_POOL_FLAG_HASHPSPOOL) {
-               /* hash pool id and seed sothat pool PGs do not overlap */
+               /* hash pool id and seed so that pool PGs do not overlap */
                pps = crush_hash32_2(CRUSH_HASH_RJENKINS1,
                                     ceph_stable_mod(pgid.seed, pool->pgp_num,
                                                     pool->pgp_num_mask),
                                     pgid.pool);
        } else {
                /*
-                * legacy ehavior: add ps and pool together.  this is
+                * legacy behavior: add ps and pool together.  this is
                 * not a great approach because the PGs from each pool
                 * will overlap on top of each other: 0.5 == 1.4 ==
                 * 2.3 == ...
@@ -1205,38 +1692,20 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
                                      pool->pgp_num_mask) +
                        (unsigned)pgid.pool;
        }
-       r = crush_do_rule_ary(osdmap->crush, ruleno, pps,
-                             osds, min_t(int, pool->size, *num),
-                             osdmap->osd_weight, osdmap->max_osd);
-       if (r < 0) {
-               pr_err("error %d from crush rule: pool %lld ruleset %d type %d"
-                      " size %d\n", r, pgid.pool, pool->crush_ruleset,
-                      pool->type, pool->size);
-               return NULL;
+
+       len = pg_to_raw_osds(osdmap, pool, pgid, pps, osds);
+       if (len < 0) {
+               *primary = -1;
+               return len;
        }
-       *num = r;
-       return osds;
-}
 
-/*
- * Return acting set for given pgid.
- */
-int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
-                       int *acting)
-{
-       int rawosds[CEPH_PG_MAX_SIZE], *osds;
-       int i, o, num = CEPH_PG_MAX_SIZE;
+       len = raw_to_up_osds(osdmap, pool, osds, len, primary);
 
-       osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
-       if (!osds)
-               return -1;
+       apply_primary_affinity(osdmap, pps, pool, osds, len, primary);
 
-       /* primary is first up osd */
-       o = 0;
-       for (i = 0; i < num; i++)
-               if (ceph_osd_is_up(osdmap, osds[i]))
-                       acting[o++] = osds[i];
-       return o;
+       len = apply_temps(osdmap, pool, pgid, osds, len, primary);
+
+       return len;
 }
 
 /*
@@ -1244,17 +1713,11 @@ int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
  */
 int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
 {
-       int rawosds[CEPH_PG_MAX_SIZE], *osds;
-       int i, num = CEPH_PG_MAX_SIZE;
+       int osds[CEPH_PG_MAX_SIZE];
+       int primary;
 
-       osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
-       if (!osds)
-               return -1;
+       ceph_calc_pg_acting(osdmap, pgid, osds, &primary);
 
-       /* primary is first up osd */
-       for (i = 0; i < num; i++)
-               if (ceph_osd_is_up(osdmap, osds[i]))
-                       return osds[i];
-       return -1;
+       return primary;
 }
 EXPORT_SYMBOL(ceph_calc_pg_primary);
index 31cfb365e0c689ffa528bf2f96072c6bcbc82799..a0348fde1fdfe89844352702565d35ef8d706f24 100644 (file)
@@ -455,6 +455,8 @@ int flow_cache_init(struct net *net)
        if (!fc->percpu)
                return -ENOMEM;
 
+       cpu_notifier_register_begin();
+
        for_each_online_cpu(i) {
                if (flow_cache_cpu_prepare(fc, i))
                        goto err;
@@ -462,7 +464,9 @@ int flow_cache_init(struct net *net)
        fc->hotcpu_notifier = (struct notifier_block){
                .notifier_call = flow_cache_cpu,
        };
-       register_hotcpu_notifier(&fc->hotcpu_notifier);
+       __register_hotcpu_notifier(&fc->hotcpu_notifier);
+
+       cpu_notifier_register_done();
 
        setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd,
                    (unsigned long) fc);
@@ -478,6 +482,8 @@ err:
                fcp->hash_table = NULL;
        }
 
+       cpu_notifier_register_done();
+
        free_percpu(fc->percpu);
        fc->percpu = NULL;
 
index cd5b8ec9be0459db10432aad57836f96b3388d63..79a0ce95799fb26e7b96402afef67f4085dd10bf 100644 (file)
@@ -621,6 +621,42 @@ static void iucv_disable(void)
        put_online_cpus();
 }
 
+static void free_iucv_data(int cpu)
+{
+       kfree(iucv_param_irq[cpu]);
+       iucv_param_irq[cpu] = NULL;
+       kfree(iucv_param[cpu]);
+       iucv_param[cpu] = NULL;
+       kfree(iucv_irq_data[cpu]);
+       iucv_irq_data[cpu] = NULL;
+}
+
+static int alloc_iucv_data(int cpu)
+{
+       /* Note: GFP_DMA used to get memory below 2G */
+       iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
+                            GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+       if (!iucv_irq_data[cpu])
+               goto out_free;
+
+       /* Allocate parameter blocks. */
+       iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
+                         GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+       if (!iucv_param[cpu])
+               goto out_free;
+
+       iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
+                         GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+       if (!iucv_param_irq[cpu])
+               goto out_free;
+
+       return 0;
+
+out_free:
+       free_iucv_data(cpu);
+       return -ENOMEM;
+}
+
 static int iucv_cpu_notify(struct notifier_block *self,
                                     unsigned long action, void *hcpu)
 {
@@ -630,38 +666,14 @@ static int iucv_cpu_notify(struct notifier_block *self,
        switch (action) {
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
-               iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
-                                       GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
-               if (!iucv_irq_data[cpu])
-                       return notifier_from_errno(-ENOMEM);
-
-               iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
-                                    GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
-               if (!iucv_param[cpu]) {
-                       kfree(iucv_irq_data[cpu]);
-                       iucv_irq_data[cpu] = NULL;
+               if (alloc_iucv_data(cpu))
                        return notifier_from_errno(-ENOMEM);
-               }
-               iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
-                                       GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
-               if (!iucv_param_irq[cpu]) {
-                       kfree(iucv_param[cpu]);
-                       iucv_param[cpu] = NULL;
-                       kfree(iucv_irq_data[cpu]);
-                       iucv_irq_data[cpu] = NULL;
-                       return notifier_from_errno(-ENOMEM);
-               }
                break;
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               kfree(iucv_param_irq[cpu]);
-               iucv_param_irq[cpu] = NULL;
-               kfree(iucv_param[cpu]);
-               iucv_param[cpu] = NULL;
-               kfree(iucv_irq_data[cpu]);
-               iucv_irq_data[cpu] = NULL;
+               free_iucv_data(cpu);
                break;
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
@@ -2025,33 +2037,20 @@ static int __init iucv_init(void)
                goto out_int;
        }
 
-       for_each_online_cpu(cpu) {
-               /* Note: GFP_DMA used to get memory below 2G */
-               iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
-                                    GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
-               if (!iucv_irq_data[cpu]) {
-                       rc = -ENOMEM;
-                       goto out_free;
-               }
+       cpu_notifier_register_begin();
 
-               /* Allocate parameter blocks. */
-               iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
-                                 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
-               if (!iucv_param[cpu]) {
-                       rc = -ENOMEM;
-                       goto out_free;
-               }
-               iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
-                                 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
-               if (!iucv_param_irq[cpu]) {
+       for_each_online_cpu(cpu) {
+               if (alloc_iucv_data(cpu)) {
                        rc = -ENOMEM;
                        goto out_free;
                }
-
        }
-       rc = register_hotcpu_notifier(&iucv_cpu_notifier);
+       rc = __register_hotcpu_notifier(&iucv_cpu_notifier);
        if (rc)
                goto out_free;
+
+       cpu_notifier_register_done();
+
        rc = register_reboot_notifier(&iucv_reboot_notifier);
        if (rc)
                goto out_cpu;
@@ -2069,16 +2068,14 @@ static int __init iucv_init(void)
 out_reboot:
        unregister_reboot_notifier(&iucv_reboot_notifier);
 out_cpu:
-       unregister_hotcpu_notifier(&iucv_cpu_notifier);
+       cpu_notifier_register_begin();
+       __unregister_hotcpu_notifier(&iucv_cpu_notifier);
 out_free:
-       for_each_possible_cpu(cpu) {
-               kfree(iucv_param_irq[cpu]);
-               iucv_param_irq[cpu] = NULL;
-               kfree(iucv_param[cpu]);
-               iucv_param[cpu] = NULL;
-               kfree(iucv_irq_data[cpu]);
-               iucv_irq_data[cpu] = NULL;
-       }
+       for_each_possible_cpu(cpu)
+               free_iucv_data(cpu);
+
+       cpu_notifier_register_done();
+
        root_device_unregister(iucv_root);
 out_int:
        unregister_external_interrupt(0x4000, iucv_external_interrupt);
@@ -2105,15 +2102,11 @@ static void __exit iucv_exit(void)
                kfree(p);
        spin_unlock_irq(&iucv_queue_lock);
        unregister_reboot_notifier(&iucv_reboot_notifier);
-       unregister_hotcpu_notifier(&iucv_cpu_notifier);
-       for_each_possible_cpu(cpu) {
-               kfree(iucv_param_irq[cpu]);
-               iucv_param_irq[cpu] = NULL;
-               kfree(iucv_param[cpu]);
-               iucv_param[cpu] = NULL;
-               kfree(iucv_irq_data[cpu]);
-               iucv_irq_data[cpu] = NULL;
-       }
+       cpu_notifier_register_begin();
+       __unregister_hotcpu_notifier(&iucv_cpu_notifier);
+       for_each_possible_cpu(cpu)
+               free_iucv_data(cpu);
+       cpu_notifier_register_done();
        root_device_unregister(iucv_root);
        bus_unregister(&iucv_bus);
        unregister_external_interrupt(0x4000, iucv_external_interrupt);
index e860d4f7ed2accd100c9ae9f715018daaae469a1..3513d559bc453d1465fda21d8860db601506bc06 100644 (file)
@@ -212,39 +212,23 @@ out:
 }
 EXPORT_SYMBOL_GPL(xprt_destroy_backchannel);
 
-/*
- * One or more rpc_rqst structure have been preallocated during the
- * backchannel setup.  Buffer space for the send and private XDR buffers
- * has been preallocated as well.  Use xprt_alloc_bc_request to allocate
- * to this request.  Use xprt_free_bc_request to return it.
- *
- * We know that we're called in soft interrupt context, grab the spin_lock
- * since there is no need to grab the bottom half spin_lock.
- *
- * Return an available rpc_rqst, otherwise NULL if non are available.
- */
-struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt)
+static struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt, __be32 xid)
 {
-       struct rpc_rqst *req;
+       struct rpc_rqst *req = NULL;
 
        dprintk("RPC:       allocate a backchannel request\n");
-       spin_lock(&xprt->bc_pa_lock);
-       if (!list_empty(&xprt->bc_pa_list)) {
-               req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst,
-                               rq_bc_pa_list);
-               list_del(&req->rq_bc_pa_list);
-       } else {
-               req = NULL;
-       }
-       spin_unlock(&xprt->bc_pa_lock);
+       if (list_empty(&xprt->bc_pa_list))
+               goto not_found;
 
-       if (req != NULL) {
-               set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
-               req->rq_reply_bytes_recvd = 0;
-               req->rq_bytes_sent = 0;
-               memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
+       req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst,
+                               rq_bc_pa_list);
+       req->rq_reply_bytes_recvd = 0;
+       req->rq_bytes_sent = 0;
+       memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
                        sizeof(req->rq_private_buf));
-       }
+       req->rq_xid = xid;
+       req->rq_connect_cookie = xprt->connect_cookie;
+not_found:
        dprintk("RPC:       backchannel req=%p\n", req);
        return req;
 }
@@ -259,6 +243,7 @@ void xprt_free_bc_request(struct rpc_rqst *req)
 
        dprintk("RPC:       free backchannel req=%p\n", req);
 
+       req->rq_connect_cookie = xprt->connect_cookie - 1;
        smp_mb__before_clear_bit();
        WARN_ON_ONCE(!test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
        clear_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
@@ -281,7 +266,57 @@ void xprt_free_bc_request(struct rpc_rqst *req)
         * may be reused by a new callback request.
         */
        spin_lock_bh(&xprt->bc_pa_lock);
-       list_add(&req->rq_bc_pa_list, &xprt->bc_pa_list);
+       list_add_tail(&req->rq_bc_pa_list, &xprt->bc_pa_list);
        spin_unlock_bh(&xprt->bc_pa_lock);
 }
 
+/*
+ * One or more rpc_rqst structure have been preallocated during the
+ * backchannel setup.  Buffer space for the send and private XDR buffers
+ * has been preallocated as well.  Use xprt_alloc_bc_request to allocate
+ * to this request.  Use xprt_free_bc_request to return it.
+ *
+ * We know that we're called in soft interrupt context, grab the spin_lock
+ * since there is no need to grab the bottom half spin_lock.
+ *
+ * Return an available rpc_rqst, otherwise NULL if non are available.
+ */
+struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid)
+{
+       struct rpc_rqst *req;
+
+       spin_lock(&xprt->bc_pa_lock);
+       list_for_each_entry(req, &xprt->bc_pa_list, rq_bc_pa_list) {
+               if (req->rq_connect_cookie != xprt->connect_cookie)
+                       continue;
+               if (req->rq_xid == xid)
+                       goto found;
+       }
+       req = xprt_alloc_bc_request(xprt, xid);
+found:
+       spin_unlock(&xprt->bc_pa_lock);
+       return req;
+}
+
+/*
+ * Add callback request to callback list.  The callback
+ * service sleeps on the sv_cb_waitq waiting for new
+ * requests.  Wake it up after adding enqueing the
+ * request.
+ */
+void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
+{
+       struct rpc_xprt *xprt = req->rq_xprt;
+       struct svc_serv *bc_serv = xprt->bc_serv;
+
+       req->rq_private_buf.len = copied;
+       set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
+
+       dprintk("RPC:       add callback request to list\n");
+       spin_lock(&bc_serv->sv_cb_lock);
+       list_del(&req->rq_bc_pa_list);
+       list_add(&req->rq_bc_list, &bc_serv->sv_cb_list);
+       wake_up(&bc_serv->sv_cb_waitq);
+       spin_unlock(&bc_serv->sv_cb_lock);
+}
+
index 0edada973434e4df883f63a85173f4a7a1de0885..f400445d1a44317ea6d9300f600c43c3bfb1e74f 100644 (file)
@@ -1363,6 +1363,7 @@ rpc_restart_call_prepare(struct rpc_task *task)
        if (RPC_ASSASSINATED(task))
                return 0;
        task->tk_action = call_start;
+       task->tk_status = 0;
        if (task->tk_ops->rpc_call_prepare != NULL)
                task->tk_action = rpc_prepare_task;
        return 1;
@@ -1379,6 +1380,7 @@ rpc_restart_call(struct rpc_task *task)
        if (RPC_ASSASSINATED(task))
                return 0;
        task->tk_action = call_start;
+       task->tk_status = 0;
        return 1;
 }
 EXPORT_SYMBOL_GPL(rpc_restart_call);
@@ -1728,9 +1730,7 @@ call_bind_status(struct rpc_task *task)
        case -EPROTONOSUPPORT:
                dprintk("RPC: %5u remote rpcbind version unavailable, retrying\n",
                                task->tk_pid);
-               task->tk_status = 0;
-               task->tk_action = call_bind;
-               return;
+               goto retry_timeout;
        case -ECONNREFUSED:             /* connection problems */
        case -ECONNRESET:
        case -ECONNABORTED:
@@ -1756,6 +1756,7 @@ call_bind_status(struct rpc_task *task)
        return;
 
 retry_timeout:
+       task->tk_status = 0;
        task->tk_action = call_timeout;
 }
 
@@ -1798,21 +1799,19 @@ call_connect_status(struct rpc_task *task)
        trace_rpc_connect_status(task, status);
        task->tk_status = 0;
        switch (status) {
-               /* if soft mounted, test if we've timed out */
-       case -ETIMEDOUT:
-               task->tk_action = call_timeout;
-               return;
        case -ECONNREFUSED:
        case -ECONNRESET:
        case -ECONNABORTED:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
-               /* retry with existing socket, after a delay */
-               rpc_delay(task, 3*HZ);
                if (RPC_IS_SOFTCONN(task))
                        break;
+               /* retry with existing socket, after a delay */
+               rpc_delay(task, 3*HZ);
        case -EAGAIN:
-               task->tk_action = call_bind;
+               /* Check for timeouts before looping back to call_bind */
+       case -ETIMEDOUT:
+               task->tk_action = call_timeout;
                return;
        case 0:
                clnt->cl_stats->netreconn++;
@@ -2007,6 +2006,10 @@ call_status(struct rpc_task *task)
        case -EHOSTDOWN:
        case -EHOSTUNREACH:
        case -ENETUNREACH:
+               if (RPC_IS_SOFTCONN(task)) {
+                       rpc_exit(task, status);
+                       break;
+               }
                /*
                 * Delay any retries for 3 seconds, then handle as if it
                 * were a timeout.
index ff3cc4bf4b24bc868088a67dd9ad92d40e42f066..25578afe15489b419409af91c97d396fdcb6404f 100644 (file)
@@ -637,7 +637,8 @@ static void __rpc_queue_timer_fn(unsigned long ptr)
 
 static void __rpc_atrun(struct rpc_task *task)
 {
-       task->tk_status = 0;
+       if (task->tk_status == -ETIMEDOUT)
+               task->tk_status = 0;
 }
 
 /*
index e03725bfe2b8d35b2e496e4836a2d126c4f8b989..96ead526b1255d278c47cb8591065f4ad393814f 100644 (file)
@@ -649,9 +649,7 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
                                break;
                        page_base = 0;
                }
-               rqst->rq_rcv_buf.page_len = olen - copy_len;
-       } else
-               rqst->rq_rcv_buf.page_len = 0;
+       }
 
        if (copy_len && rqst->rq_rcv_buf.tail[0].iov_len) {
                curlen = copy_len;
index 285dc08841159e609524897e6efcce564a1d25c7..1eb9c468d0c9b9db32895fa4e0f07366db135b63 100644 (file)
@@ -733,7 +733,7 @@ static void __exit xprt_rdma_cleanup(void)
 {
        int rc;
 
-       dprintk(KERN_INFO "RPCRDMA Module Removed, deregister RPC RDMA transport\n");
+       dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
 #ifdef RPC_DEBUG
        if (sunrpc_table_header) {
                unregister_sysctl_table(sunrpc_table_header);
@@ -755,14 +755,14 @@ static int __init xprt_rdma_init(void)
        if (rc)
                return rc;
 
-       dprintk(KERN_INFO "RPCRDMA Module Init, register RPC RDMA transport\n");
+       dprintk("RPCRDMA Module Init, register RPC RDMA transport\n");
 
-       dprintk(KERN_INFO "Defaults:\n");
-       dprintk(KERN_INFO "\tSlots %d\n"
+       dprintk("Defaults:\n");
+       dprintk("\tSlots %d\n"
                "\tMaxInlineRead %d\n\tMaxInlineWrite %d\n",
                xprt_rdma_slot_table_entries,
                xprt_rdma_max_inline_read, xprt_rdma_max_inline_write);
-       dprintk(KERN_INFO "\tPadding %d\n\tMemreg %d\n",
+       dprintk("\tPadding %d\n\tMemreg %d\n",
                xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
 
 #ifdef RPC_DEBUG
index 0addefca8e7757d78571928580d6f7473a1354ae..966763d735e9f34164a32d85b15ae9d8c0081f1a 100644 (file)
@@ -1306,41 +1306,29 @@ static inline int xs_tcp_read_reply(struct rpc_xprt *xprt,
  * If we're unable to obtain the rpc_rqst we schedule the closing of the
  * connection and return -1.
  */
-static inline int xs_tcp_read_callback(struct rpc_xprt *xprt,
+static int xs_tcp_read_callback(struct rpc_xprt *xprt,
                                       struct xdr_skb_reader *desc)
 {
        struct sock_xprt *transport =
                                container_of(xprt, struct sock_xprt, xprt);
        struct rpc_rqst *req;
 
-       req = xprt_alloc_bc_request(xprt);
+       /* Look up and lock the request corresponding to the given XID */
+       spin_lock(&xprt->transport_lock);
+       req = xprt_lookup_bc_request(xprt, transport->tcp_xid);
        if (req == NULL) {
+               spin_unlock(&xprt->transport_lock);
                printk(KERN_WARNING "Callback slot table overflowed\n");
                xprt_force_disconnect(xprt);
                return -1;
        }
 
-       req->rq_xid = transport->tcp_xid;
        dprintk("RPC:       read callback  XID %08x\n", ntohl(req->rq_xid));
        xs_tcp_read_common(xprt, desc, req);
 
-       if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) {
-               struct svc_serv *bc_serv = xprt->bc_serv;
-
-               /*
-                * Add callback request to callback list.  The callback
-                * service sleeps on the sv_cb_waitq waiting for new
-                * requests.  Wake it up after adding enqueing the
-                * request.
-                */
-               dprintk("RPC:       add callback request to list\n");
-               spin_lock(&bc_serv->sv_cb_lock);
-               list_add(&req->rq_bc_list, &bc_serv->sv_cb_list);
-               spin_unlock(&bc_serv->sv_cb_lock);
-               wake_up(&bc_serv->sv_cb_waitq);
-       }
-
-       req->rq_private_buf.len = transport->tcp_copied;
+       if (!(transport->tcp_flags & TCP_RCV_COPY_DATA))
+               xprt_complete_bc_request(req, transport->tcp_copied);
+       spin_unlock(&xprt->transport_lock);
 
        return 0;
 }
index 10085de886fef49b78a12746a2e0a593545d56e0..1237dd7fb4cac7c2f863b413399df17a9e0c8beb 100644 (file)
@@ -36,13 +36,13 @@ struct sym_entry {
        unsigned char *sym;
 };
 
-struct text_range {
-       const char *stext, *etext;
+struct addr_range {
+       const char *start_sym, *end_sym;
        unsigned long long start, end;
 };
 
 static unsigned long long _text;
-static struct text_range text_ranges[] = {
+static struct addr_range text_ranges[] = {
        { "_stext",     "_etext"     },
        { "_sinittext", "_einittext" },
        { "_stext_l1",  "_etext_l1"  }, /* Blackfin on-chip L1 inst SRAM */
@@ -51,9 +51,14 @@ static struct text_range text_ranges[] = {
 #define text_range_text     (&text_ranges[0])
 #define text_range_inittext (&text_ranges[1])
 
+static struct addr_range percpu_range = {
+       "__per_cpu_start", "__per_cpu_end", -1ULL, 0
+};
+
 static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
 static int all_symbols = 0;
+static int absolute_percpu = 0;
 static char symbol_prefix_char = '\0';
 static unsigned long long kernel_start_addr = 0;
 
@@ -83,19 +88,20 @@ static inline int is_arm_mapping_symbol(const char *str)
               && (str[2] == '\0' || str[2] == '.');
 }
 
-static int read_symbol_tr(const char *sym, unsigned long long addr)
+static int check_symbol_range(const char *sym, unsigned long long addr,
+                             struct addr_range *ranges, int entries)
 {
        size_t i;
-       struct text_range *tr;
+       struct addr_range *ar;
 
-       for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) {
-               tr = &text_ranges[i];
+       for (i = 0; i < entries; ++i) {
+               ar = &ranges[i];
 
-               if (strcmp(sym, tr->stext) == 0) {
-                       tr->start = addr;
+               if (strcmp(sym, ar->start_sym) == 0) {
+                       ar->start = addr;
                        return 0;
-               } else if (strcmp(sym, tr->etext) == 0) {
-                       tr->end = addr;
+               } else if (strcmp(sym, ar->end_sym) == 0) {
+                       ar->end = addr;
                        return 0;
                }
        }
@@ -130,7 +136,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
        /* Ignore most absolute/undefined (?) symbols. */
        if (strcmp(sym, "_text") == 0)
                _text = s->addr;
-       else if (read_symbol_tr(sym, s->addr) == 0)
+       else if (check_symbol_range(sym, s->addr, text_ranges,
+                                   ARRAY_SIZE(text_ranges)) == 0)
                /* nothing to do */;
        else if (toupper(stype) == 'A')
        {
@@ -164,18 +171,22 @@ static int read_symbol(FILE *in, struct sym_entry *s)
        strcpy((char *)s->sym + 1, str);
        s->sym[0] = stype;
 
+       /* Record if we've found __per_cpu_start/end. */
+       check_symbol_range(sym, s->addr, &percpu_range, 1);
+
        return 0;
 }
 
-static int symbol_valid_tr(struct sym_entry *s)
+static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges,
+                          int entries)
 {
        size_t i;
-       struct text_range *tr;
+       struct addr_range *ar;
 
-       for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) {
-               tr = &text_ranges[i];
+       for (i = 0; i < entries; ++i) {
+               ar = &ranges[i];
 
-               if (s->addr >= tr->start && s->addr <= tr->end)
+               if (s->addr >= ar->start && s->addr <= ar->end)
                        return 1;
        }
 
@@ -214,7 +225,8 @@ static int symbol_valid(struct sym_entry *s)
        /* if --all-symbols is not specified, then symbols outside the text
         * and inittext sections are discarded */
        if (!all_symbols) {
-               if (symbol_valid_tr(s) == 0)
+               if (symbol_in_range(s, text_ranges,
+                                   ARRAY_SIZE(text_ranges)) == 0)
                        return 0;
                /* Corner case.  Discard any symbols with the same value as
                 * _etext _einittext; they can move between pass 1 and 2 when
@@ -223,9 +235,11 @@ static int symbol_valid(struct sym_entry *s)
                 * rules.
                 */
                if ((s->addr == text_range_text->end &&
-                               strcmp((char *)s->sym + offset, text_range_text->etext)) ||
+                               strcmp((char *)s->sym + offset,
+                                      text_range_text->end_sym)) ||
                    (s->addr == text_range_inittext->end &&
-                               strcmp((char *)s->sym + offset, text_range_inittext->etext)))
+                               strcmp((char *)s->sym + offset,
+                                      text_range_inittext->end_sym)))
                        return 0;
        }
 
@@ -298,6 +312,11 @@ static int expand_symbol(unsigned char *data, int len, char *result)
        return total;
 }
 
+static int symbol_absolute(struct sym_entry *s)
+{
+       return toupper(s->sym[0]) == 'A';
+}
+
 static void write_src(void)
 {
        unsigned int i, k, off;
@@ -325,7 +344,7 @@ static void write_src(void)
         */
        output_label("kallsyms_addresses");
        for (i = 0; i < table_cnt; i++) {
-               if (toupper(table[i].sym[0]) != 'A') {
+               if (!symbol_absolute(&table[i])) {
                        if (_text <= table[i].addr)
                                printf("\tPTR\t_text + %#llx\n",
                                        table[i].addr - _text);
@@ -646,6 +665,15 @@ static void sort_symbols(void)
        qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols);
 }
 
+static void make_percpus_absolute(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < table_cnt; i++)
+               if (symbol_in_range(&table[i], &percpu_range, 1))
+                       table[i].sym[0] = 'A';
+}
+
 int main(int argc, char **argv)
 {
        if (argc >= 2) {
@@ -653,6 +681,8 @@ int main(int argc, char **argv)
                for (i = 1; i < argc; i++) {
                        if(strcmp(argv[i], "--all-symbols") == 0)
                                all_symbols = 1;
+                       else if (strcmp(argv[i], "--absolute-percpu") == 0)
+                               absolute_percpu = 1;
                        else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
                                char *p = &argv[i][16];
                                /* skip quote */
@@ -669,6 +699,8 @@ int main(int argc, char **argv)
                usage();
 
        read_map(stdin);
+       if (absolute_percpu)
+               make_percpus_absolute();
        sort_symbols();
        optimize_token_table();
        write_src();
index 2dcb37736d8469a0e18e4c1ba262281e3fd8cf37..86a4fe75f453735936e3b218f885dcd887216659 100644 (file)
@@ -86,6 +86,10 @@ kallsyms()
                kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
        fi
 
+       if [ -n "${CONFIG_X86_64}" ]; then
+               kallsymopt="${kallsymopt} --absolute-percpu"
+       fi
+
        local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \
                      ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
 
index 25f6f5970552224f07145f5bc2f093a7f8e925c9..1924990a737f36c61820bd35470c9adf90f49888 100644 (file)
@@ -42,7 +42,7 @@ typedef unsigned char __u8;
 
 /* This array collects all instances that use the generic do_table */
 struct devtable {
-       const char *device_id; /* name of table, __mod_<name>_device_table. */
+       const char *device_id; /* name of table, __mod_<name>__*_device_table. */
        unsigned long id_size;
        void *function;
 };
@@ -146,7 +146,8 @@ static void device_id_check(const char *modname, const char *device_id,
 
        if (size % id_size || size < id_size) {
                fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
-                     "of the size of section __mod_%s_device_table=%lu.\n"
+                     "of the size of "
+                     "section __mod_%s__<identifier>_device_table=%lu.\n"
                      "Fix definition of struct %s_device_id "
                      "in mod_devicetable.h\n",
                      modname, device_id, id_size, device_id, size, device_id);
@@ -1216,7 +1217,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 {
        void *symval;
        char *zeros = NULL;
-       const char *name;
+       const char *name, *identifier;
        unsigned int namelen;
 
        /* We're looking for a section relative symbol */
@@ -1227,7 +1228,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
        if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
                return;
 
-       /* All our symbols are of form <prefix>__mod_XXX_device_table. */
+       /* All our symbols are of form <prefix>__mod_<name>__<identifier>_device_table. */
        name = strstr(symname, "__mod_");
        if (!name)
                return;
@@ -1237,7 +1238,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                return;
        if (strcmp(name + namelen - strlen("_device_table"), "_device_table"))
                return;
-       namelen -= strlen("_device_table");
+       identifier = strstr(name, "__");
+       if (!identifier)
+               return;
+       namelen = identifier - name;
 
        /* Handle all-NULL symbols allocated into .bss */
        if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
index 919cad93ac82fa2fa7c017b5c85353ca8ac6818e..8b774f362a3d4ed252f626c8e6de5634a5820148 100644 (file)
@@ -433,11 +433,20 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
 }
 
 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
-                        struct path *new_dir, struct dentry *new_dentry)
+                        struct path *new_dir, struct dentry *new_dentry,
+                        unsigned int flags)
 {
        if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
                     (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
                return 0;
+
+       if (flags & RENAME_EXCHANGE) {
+               int err = security_ops->path_rename(new_dir, new_dentry,
+                                                   old_dir, old_dentry);
+               if (err)
+                       return err;
+       }
+
        return security_ops->path_rename(old_dir, old_dentry, new_dir,
                                         new_dentry);
 }
@@ -524,11 +533,20 @@ int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 }
 
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-                          struct inode *new_dir, struct dentry *new_dentry)
+                          struct inode *new_dir, struct dentry *new_dentry,
+                          unsigned int flags)
 {
         if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
             (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
                return 0;
+
+       if (flags & RENAME_EXCHANGE) {
+               int err = security_ops->inode_rename(new_dir, new_dentry,
+                                                    old_dir, old_dentry);
+               if (err)
+                       return err;
+       }
+
        return security_ops->inode_rename(old_dir, old_dentry,
                                           new_dir, new_dentry);
 }
index 869c2f1e0da187f9f406798f3afba3df90cd98ad..b4beb77967b17949daf46623a822cb7e960e8829 100644 (file)
@@ -3317,6 +3317,9 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
        case F_GETLK:
        case F_SETLK:
        case F_SETLKW:
+       case F_GETLKP:
+       case F_SETLKP:
+       case F_SETLKPW:
 #if BITS_PER_LONG == 32
        case F_GETLK64:
        case F_SETLK64:
index 49f8437665dea5d326833a4aff3ad506c6c02d56..06f4e8aa93ae71675190901eb0005fc5cd86fd87 100644 (file)
@@ -1,6 +1,6 @@
 config SND_KIRKWOOD_SOC
        tristate "SoC Audio for the Marvell Kirkwood and Dove chips"
-       depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST
+       depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU || MACH_KIRKWOOD || COMPILE_TEST
        help
          Say Y or M if you want to add support for codecs attached to
          the Kirkwood I2S interface. You will also need to select the
index fef8ae922800ddd1131205deabc4f15b0940e90a..4b06719ee984618c6154fa0bfbadd78977a4861e 100644 (file)
@@ -5,7 +5,8 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
                                   -e s/arm.*/arm/ -e s/sa110/arm/ \
                                   -e s/s390x/s390/ -e s/parisc64/parisc/ \
                                   -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-                                  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+                                  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
+                                  -e s/tile.*/tile/ )
 
 # Additional ARCH settings for x86
 ifeq ($(ARCH),i386)
index e18a8b5e69531cca4e1fbf889098d779ff14cf4d..5c11ecad02a9623c4324ca4aeefdb6fa1135c9f4 100644 (file)
 #define CPUINFO_PROC   "core ID"
 #endif
 
+#ifdef __tile__
+#define mb()           asm volatile ("mf" ::: "memory")
+#define wmb()          asm volatile ("mf" ::: "memory")
+#define rmb()          asm volatile ("mf" ::: "memory")
+#define cpu_relax()    asm volatile ("mfspr zero, PASS" ::: "memory")
+#define CPUINFO_PROC    "model name"
+#endif
+
 #define barrier() asm volatile ("" ::: "memory")
 
 #ifndef cpu_relax
index 831c7c5395f1c8b269e216afa2e6b13fbe63b6ac..fbc134f9ac6edfb60f30202e85cfa6fc07a0d075 100644 (file)
@@ -10,6 +10,10 @@ MACHINE = Guest
 # Use virsh to read the serial console of the guest
 CONSOLE =  virsh console ${MACHINE}
 
+# Use SIGKILL to terminate virsh console. We can't kill virsh console
+# by the default signal, SIGINT.
+CLOSE_CONSOLE_SIGNAL = KILL
+
 #*************************************#
 # This part is the same as test.conf  #
 #*************************************#